cloning
tech: cloning - chance to spawn another level boss = 3x your duplication chance tech: dynamo-bot: a bot follows your history, damages mobs, and regens energy when it gets close tech: dynamo upgrade: more energy regen
This commit is contained in:
129
js/bullet.js
129
js/bullet.js
@@ -1713,7 +1713,7 @@ const b = {
|
||||
friction: 0,
|
||||
frictionAir: 0.025,
|
||||
thrust: (tech.isFastSpores ? 0.001 : 0.0004) * (1 + 0.3 * (Math.random() - 0.5)),
|
||||
dmg: tech.isMutualism ? 10 : 4, //2x bonus damage from tech.isMutualism
|
||||
dmg: tech.isMutualism ? 12 : 5, //bonus damage from tech.isMutualism
|
||||
lookFrequency: 100 + Math.floor(117 * Math.random()),
|
||||
classType: "bullet",
|
||||
collisionFilter: {
|
||||
@@ -1722,7 +1722,7 @@ const b = {
|
||||
},
|
||||
endCycle: simulation.cycle + Math.floor((600 + Math.floor(Math.random() * 420)) * tech.isBulletsLastLonger),
|
||||
minDmgSpeed: 0,
|
||||
playerOffPosition: { //used when following player to keep spores separate
|
||||
playerOffPosition: { //used when moving towards player to keep spores separate
|
||||
x: 100 * (Math.random() - 0.5),
|
||||
y: 100 * (Math.random() - 0.5)
|
||||
},
|
||||
@@ -2223,6 +2223,7 @@ const b = {
|
||||
// **************************************************************************************************
|
||||
// **************************************************************************************************
|
||||
respawnBots() {
|
||||
for (let i = 0; i < tech.dynamoBotCount; i++) b.dynamoBot({ x: m.pos.x + 50 * (Math.random() - 0.5), y: m.pos.y + 50 * (Math.random() - 0.5) }, false)
|
||||
for (let i = 0; i < tech.laserBotCount; i++) b.laserBot({ x: m.pos.x + 50 * (Math.random() - 0.5), y: m.pos.y + 50 * (Math.random() - 0.5) }, false)
|
||||
for (let i = 0; i < tech.nailBotCount; i++) b.nailBot({ x: m.pos.x + 50 * (Math.random() - 0.5), y: m.pos.y + 50 * (Math.random() - 0.5) }, false)
|
||||
for (let i = 0; i < tech.foamBotCount; i++) b.foamBot({ x: m.pos.x + 50 * (Math.random() - 0.5), y: m.pos.y + 50 * (Math.random() - 0.5) }, false)
|
||||
@@ -2237,7 +2238,10 @@ const b = {
|
||||
}
|
||||
},
|
||||
randomBot(where = m.pos, isKeep = true, isAll = true) {
|
||||
if (Math.random() < 0.2 && isAll) {
|
||||
if (Math.random() < 0.167 && isAll) {
|
||||
b.dynamoBot(where)
|
||||
if (isKeep) tech.dynamoBotCount++;
|
||||
} else if (Math.random() < 0.25 && isAll) {
|
||||
b.laserBot(where)
|
||||
if (isKeep) tech.laserBotCount++;
|
||||
} else if (Math.random() < 0.25 && isAll) {
|
||||
@@ -2254,6 +2258,113 @@ const b = {
|
||||
if (isKeep) tech.boomBotCount++;
|
||||
}
|
||||
},
|
||||
setDynamoBotDelay() {
|
||||
//reorder orbital bot positions around a circle
|
||||
let total = 0
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType === 'dynamo') total++
|
||||
}
|
||||
let count = 0
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType === 'dynamo') {
|
||||
count++
|
||||
const step = Math.max(60 - 3 * total, 20)
|
||||
bullet[i].followDelay = (step * count) % 600
|
||||
}
|
||||
}
|
||||
},
|
||||
dynamoBot(position = m.pos, isConsole = true) {
|
||||
if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.dynamoBot()`);
|
||||
const me = bullet.length;
|
||||
bullet[me] = Bodies.polygon(position.x, position.y, 5, 10, {
|
||||
isUpgraded: tech.isDynamoBotUpgrade,
|
||||
botType: "dynamo",
|
||||
friction: 0,
|
||||
frictionStatic: 0,
|
||||
frictionAir: 1,
|
||||
isStatic: true,
|
||||
isSensor: true,
|
||||
restitution: 0,
|
||||
dmg: 0, // 0.14 //damage done in addition to the damage from momentum
|
||||
minDmgSpeed: 0,
|
||||
endCycle: Infinity,
|
||||
classType: "bullet",
|
||||
collisionFilter: {
|
||||
category: cat.bullet,
|
||||
mask: 0 //cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield
|
||||
},
|
||||
beforeDmg() {},
|
||||
onEnd() {
|
||||
b.setDynamoBotDelay()
|
||||
},
|
||||
followDelay: 0,
|
||||
phase: Math.floor(60 * Math.random()),
|
||||
do() {
|
||||
// if (Vector.magnitude(Vector.sub(this.position, m.pos)) < 150) {
|
||||
// ctx.fillStyle = "rgba(0,0,0,0.06)";
|
||||
// ctx.beginPath();
|
||||
// ctx.arc(this.position.x, this.position.y, 150, 0, 2 * Math.PI);
|
||||
// ctx.fill();
|
||||
// }
|
||||
if (!((m.cycle + this.phase) % 30)) { //twice a second
|
||||
if (Vector.magnitude(Vector.sub(this.position, m.pos)) < 250) { //give energy
|
||||
// Matter.Body.setAngularVelocity(this, 10)
|
||||
if (this.isUpgraded) {
|
||||
m.energy += 0.06
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: this.position.x,
|
||||
y: this.position.y,
|
||||
radius: 8,
|
||||
color: m.fieldMeterColor,
|
||||
time: simulation.drawTime
|
||||
});
|
||||
} else {
|
||||
m.energy += 0.02
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: this.position.x,
|
||||
y: this.position.y,
|
||||
radius: 5,
|
||||
color: m.fieldMeterColor,
|
||||
time: simulation.drawTime
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
//check for damage
|
||||
if (!m.isCloak && !m.isBodiesAsleep) { //if time dilation isn't active
|
||||
const size = 33
|
||||
q = Matter.Query.region(mob, {
|
||||
min: {
|
||||
x: this.position.x - size,
|
||||
y: this.position.y - size
|
||||
},
|
||||
max: {
|
||||
x: this.position.x + size,
|
||||
y: this.position.y + size
|
||||
}
|
||||
})
|
||||
for (let i = 0; i < q.length; i++) {
|
||||
// mobs.statusStun(q[i], 180)
|
||||
// const dmg = 0.5 * b.dmgScale * (this.isUpgraded ? 2.5 : 1)
|
||||
const dmg = 0.5 * b.dmgScale
|
||||
q[i].damage(dmg);
|
||||
q[i].foundPlayer();
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: this.position.x,
|
||||
y: this.position.y,
|
||||
radius: Math.log(2 * dmg + 1.1) * 40,
|
||||
color: 'rgba(0,0,0,0.4)',
|
||||
time: simulation.drawTime
|
||||
});
|
||||
}
|
||||
}
|
||||
let history = m.history[(m.cycle - this.followDelay) % 600]
|
||||
Matter.Body.setPosition(this, { x: history.position.x, y: history.position.y - history.yOff + 24.2859 }) //bullets move with player
|
||||
}
|
||||
})
|
||||
World.add(engine.world, bullet[me]); //add bullet to world
|
||||
b.setDynamoBotDelay()
|
||||
},
|
||||
nailBot(position = { x: m.pos.x + 50 * (Math.random() - 0.5), y: m.pos.y + 50 * (Math.random() - 0.5) }, isConsole = true) {
|
||||
if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.nailBot()`);
|
||||
const me = bullet.length;
|
||||
@@ -2435,7 +2546,7 @@ const b = {
|
||||
drainThreshold: tech.isEnergyHealth ? 0.5 : 0.33,
|
||||
acceleration: 0.0015 * (1 + 0.3 * Math.random()),
|
||||
range: 700 * (1 + 0.1 * Math.random()) + 300 * tech.isLaserBotUpgrade,
|
||||
followRange: 150 + Math.floor(30 * Math.random()),
|
||||
playerRange: 150 + Math.floor(30 * Math.random()),
|
||||
offPlayer: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
@@ -2453,7 +2564,7 @@ const b = {
|
||||
onEnd() {},
|
||||
do() {
|
||||
const playerPos = Vector.add(Vector.add(this.offPlayer, m.pos), Vector.mult(player.velocity, 20)) //also include an offset unique to this bot to keep many bots spread out
|
||||
const farAway = Math.max(0, (Vector.magnitude(Vector.sub(this.position, playerPos))) / this.followRange) //linear bounding well
|
||||
const farAway = Math.max(0, (Vector.magnitude(Vector.sub(this.position, playerPos))) / this.playerRange) //linear bounding well
|
||||
const mag = Math.min(farAway, 4) * this.mass * this.acceleration
|
||||
this.force = Vector.mult(Vector.normalise(Vector.sub(playerPos, this.position)), mag)
|
||||
//manual friction to not lose rotational velocity
|
||||
@@ -3520,13 +3631,13 @@ const b = {
|
||||
name: "spores",
|
||||
description: "fire a <strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> that discharges <strong class='color-p' style='letter-spacing: 2px;'>spores</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> seek out nearby mobs",
|
||||
ammo: 0,
|
||||
ammoPack: 3,
|
||||
ammoPack: 3.5,
|
||||
have: false,
|
||||
fire() {
|
||||
const me = bullet.length;
|
||||
const dir = m.angle;
|
||||
bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 20, 4.5, b.fireAttributes(dir, false));
|
||||
b.fireProps(m.crouch ? 50 : 30, m.crouch ? 30 : 16, dir, me); //cd , speed
|
||||
b.fireProps(m.crouch ? 45 : 25, m.crouch ? 30 : 16, dir, me); //cd , speed
|
||||
Matter.Body.setDensity(bullet[me], 0.000001);
|
||||
bullet[me].endCycle = Infinity;
|
||||
bullet[me].frictionAir = 0;
|
||||
@@ -3683,10 +3794,10 @@ const b = {
|
||||
name: "foam",
|
||||
description: "spray bubbly foam that <strong>sticks</strong> to mobs<br><strong class='color-s'>slows</strong> mobs and does <strong class='color-d'>damage</strong> over time",
|
||||
ammo: 0,
|
||||
ammoPack: 35,
|
||||
ammoPack: 36,
|
||||
have: false,
|
||||
fire() {
|
||||
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 20 : 6) * b.fireCD); // cool down
|
||||
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 15 : 5) * b.fireCD); // cool down
|
||||
const radius = (m.crouch ? 10 + 5 * Math.random() : 4 + 6 * Math.random()) + (tech.isAmmoFoamSize && this.ammo < 300) * 12
|
||||
const SPEED = 18 - radius * 0.4;
|
||||
const dir = m.angle + 0.2 * (Math.random() - 0.5)
|
||||
|
||||
@@ -857,7 +857,7 @@ window.addEventListener("keydown", function(event) {
|
||||
x: 0,
|
||||
y: 0
|
||||
});
|
||||
// move bots to follow player
|
||||
// move bots to player
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType) {
|
||||
Matter.Body.setPosition(bullet[i], Vector.add(player.position, {
|
||||
|
||||
102
js/level.js
102
js/level.js
@@ -19,7 +19,7 @@ const level = {
|
||||
// m.setField("plasma torch")
|
||||
// b.giveGuns("nail gun")
|
||||
// tech.isExplodeRadio = true
|
||||
// tech.giveTech("needle gun")
|
||||
for (let i = 0; i < 1; i++) tech.giveTech("dynamo-bot")
|
||||
// tech.giveTech("supercritical fission")
|
||||
// tech.giveTech("irradiated nails")
|
||||
// tech.giveTech("cardinality")
|
||||
@@ -299,9 +299,10 @@ const level = {
|
||||
// spawn.laserTargetingBoss(1600, -400)
|
||||
// spawn.striker(1600, -500)
|
||||
// spawn.shooter(1700, -120)
|
||||
spawn.bomberBoss(1400, -500)
|
||||
// spawn.bomberBoss(1400, -500)
|
||||
// spawn.sniper(1800, -120)
|
||||
// spawn.cellBossCulture(1600, -500)
|
||||
// spawn.cellBossCulture(1600, -500)
|
||||
// spawn.streamBoss(1600, -500)
|
||||
// spawn.beamer(1200, -500)
|
||||
// spawn.shield(mob[mob.length - 1], 1800, -120, 1);
|
||||
@@ -348,6 +349,7 @@ const level = {
|
||||
// spawn.randomBoss(1700, -900, 0.4);
|
||||
// if (simulation.difficulty > 3) spawn.randomLevelBoss(2200, -1300);
|
||||
powerUps.addRerollToLevel() //needs to run after mobs are spawned
|
||||
// if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(4800, -500);
|
||||
},
|
||||
final() {
|
||||
level.bossKilled = false; // if a boss needs to be killed
|
||||
@@ -398,6 +400,7 @@ const level = {
|
||||
spawn.mapRect(5700, -3300, 1800, 5100); //right wall
|
||||
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
|
||||
spawn.mapRect(5425, -650, 375, 450); //blocking exit
|
||||
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(4800, -500);
|
||||
},
|
||||
gauntlet() {
|
||||
level.bossKilled = true; //if there is no boss this needs to be true to increase levels
|
||||
@@ -460,6 +463,7 @@ const level = {
|
||||
}
|
||||
}
|
||||
powerUps.addRerollToLevel() //needs to run after mobs are spawned
|
||||
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(4125, -350);
|
||||
},
|
||||
intro() {
|
||||
level.bossKilled = true; //if there is no boss this needs to be true to increase levels
|
||||
@@ -636,45 +640,45 @@ const level = {
|
||||
spawn.wireKneeLeft();
|
||||
spawn.wireHead();
|
||||
} else {
|
||||
const say = []
|
||||
if (localSettings.runCount > 200) { //experienced
|
||||
say.push(
|
||||
"I've been here before...",
|
||||
"How many times have I done this?",
|
||||
)
|
||||
} else if (localSettings.runCount < 20) { //new
|
||||
say.push(
|
||||
"Am I still alive?",
|
||||
"And I'm back here again...",
|
||||
"Is this another simulation?",
|
||||
"I'm alive...",
|
||||
"Last time was a simulation. Is this one a simulation too?",
|
||||
)
|
||||
}
|
||||
if (simulation.difficultyMode < 4 && localSettings.levelsClearedLastGame > 10) { //too easy
|
||||
say.push(
|
||||
"That felt too easy.<br>Maybe I should increase the difficulty of the simulation.",
|
||||
"That was fun, but maybe I should increase the difficulty of the simulation.",
|
||||
"I should increase the difficulty of the simulation, that didn't feel realistic.",
|
||||
)
|
||||
} else if (simulation.difficultyMode > 3 && localSettings.levelsClearedLastGame > 10) { //great run on a hard or why
|
||||
say.push(
|
||||
"What do I do after I escape?",
|
||||
"I'm almost ready to stop these simulations and actually escape.",
|
||||
"I think I'm getting closer to something, but what?",
|
||||
"I'm getting stronger.",
|
||||
"What happens after I escape?",
|
||||
"I found a good combination of technology last time."
|
||||
)
|
||||
} else { //resolve
|
||||
say.push(
|
||||
"I'll try some different techs this time.",
|
||||
"I've got to escape.",
|
||||
"I'll find a way out.",
|
||||
"I keep forgetting that these are just simulated escapes."
|
||||
)
|
||||
}
|
||||
simulation.makeTextLog(say[Math.floor(say.length * Math.random())], 1000)
|
||||
// const say = []
|
||||
// if (localSettings.runCount > 200) { //experienced
|
||||
// say.push(
|
||||
// "I've been here before...",
|
||||
// "How many times have I done this?",
|
||||
// )
|
||||
// } else if (localSettings.runCount < 20) { //new
|
||||
// say.push(
|
||||
// "Am I still alive?",
|
||||
// "And I'm back here again...",
|
||||
// "Is this another simulation?",
|
||||
// "I'm alive...",
|
||||
// "Last time was a simulation. Is this one a simulation too?",
|
||||
// )
|
||||
// }
|
||||
// if (simulation.difficultyMode < 4 && localSettings.levelsClearedLastGame > 10) { //too easy
|
||||
// say.push(
|
||||
// "That felt too easy.<br>Maybe I should increase the difficulty of the simulation.",
|
||||
// "That was fun, but maybe I should increase the difficulty of the simulation.",
|
||||
// "I should increase the difficulty of the simulation, that didn't feel realistic.",
|
||||
// )
|
||||
// } else if (simulation.difficultyMode > 3 && localSettings.levelsClearedLastGame > 10) { //great run on a hard or why
|
||||
// say.push(
|
||||
// "What do I do after I escape?",
|
||||
// "I'm almost ready to stop these simulations and actually escape.",
|
||||
// "I think I'm getting closer to something, but what?",
|
||||
// "I'm getting stronger.",
|
||||
// "What happens after I escape?",
|
||||
// "I found a good combination of technology last time."
|
||||
// )
|
||||
// } else { //resolve
|
||||
// say.push(
|
||||
// "I'll try some different techs this time.",
|
||||
// "I've got to escape.",
|
||||
// "I'll find a way out.",
|
||||
// "I keep forgetting that these are just simulated escapes."
|
||||
// )
|
||||
// }
|
||||
// simulation.makeTextLog(say[Math.floor(say.length * Math.random())], 1000)
|
||||
|
||||
const swapPeriod = 150
|
||||
const len = 30
|
||||
@@ -695,6 +699,7 @@ const level = {
|
||||
}
|
||||
}
|
||||
powerUps.spawnStartingPowerUps(2300, -150);
|
||||
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(1900, -675);
|
||||
},
|
||||
testChamber() {
|
||||
level.setPosToSpawn(0, -50); //lower start
|
||||
@@ -768,7 +773,6 @@ const level = {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
buttonDoor.query();
|
||||
buttonDoor.draw();
|
||||
if (buttonDoor.isUp) {
|
||||
@@ -961,6 +965,7 @@ const level = {
|
||||
}
|
||||
}
|
||||
powerUps.addRerollToLevel() //needs to run after mobs are spawned
|
||||
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(1925, -1250);
|
||||
},
|
||||
sewers() {
|
||||
level.bossKilled = false; // if a boss needs to be killed
|
||||
@@ -1106,6 +1111,7 @@ const level = {
|
||||
spawn.randomMob(2825, 400, 0.9);
|
||||
if (simulation.difficulty > 3) spawn.randomLevelBoss(6000, 2300, ["spiderBoss", "launcherBoss", "laserTargetingBoss", "streamBoss"]);
|
||||
powerUps.addRerollToLevel() //needs to run after mobs are spawned
|
||||
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(7725, 2275);
|
||||
},
|
||||
satellite() {
|
||||
level.bossKilled = false; // if a boss needs to be killed
|
||||
@@ -1312,6 +1318,7 @@ const level = {
|
||||
}
|
||||
}
|
||||
powerUps.addRerollToLevel() //needs to run after mobs are spawned
|
||||
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(3950, -850);
|
||||
},
|
||||
rooftops() {
|
||||
level.bossKilled = false; // if a boss needs to be killed
|
||||
@@ -1535,6 +1542,7 @@ const level = {
|
||||
spawn.randomBoss(4900, -1200, 0);
|
||||
if (simulation.difficulty > 3) spawn.randomLevelBoss(3200, -2050);
|
||||
powerUps.addRerollToLevel() //needs to run after mobs are spawned
|
||||
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(2175, -2425);
|
||||
},
|
||||
aerie() {
|
||||
level.bossKilled = false; // if a boss needs to be killed
|
||||
@@ -1744,6 +1752,7 @@ const level = {
|
||||
}
|
||||
}
|
||||
powerUps.addRerollToLevel() //needs to run after mobs are spawned
|
||||
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(5350, -325);
|
||||
},
|
||||
skyscrapers() {
|
||||
level.bossKilled = false; // if a boss needs to be killed
|
||||
@@ -1905,6 +1914,7 @@ const level = {
|
||||
spawn.randomBoss(1700, -900, 0.4);
|
||||
if (simulation.difficulty > 3) spawn.randomLevelBoss(2600, -2300);
|
||||
powerUps.addRerollToLevel() //needs to run after mobs are spawned
|
||||
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(3075, -2050);
|
||||
},
|
||||
highrise() {
|
||||
level.bossKilled = false; // if a boss needs to be killed
|
||||
@@ -2104,6 +2114,7 @@ const level = {
|
||||
|
||||
if (simulation.difficulty > 3) spawn.randomLevelBoss(-2400, -3000);
|
||||
powerUps.addRerollToLevel() //needs to run after mobs are spawned
|
||||
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(-1825, -1975);
|
||||
},
|
||||
warehouse() {
|
||||
level.bossKilled = false; // if a boss needs to be killed
|
||||
@@ -2275,10 +2286,12 @@ const level = {
|
||||
if (Math.random() < 0.25) {
|
||||
spawn.randomLevelBoss(-800, -1300)
|
||||
} else {
|
||||
spawn.snakeBoss(-1000 + Math.random() * 1500, -2200); //boss snake with head
|
||||
spawn.snakeBoss(-1000 + Math.random() * 2500, -1300); //boss snake with head
|
||||
}
|
||||
}
|
||||
powerUps.addRerollToLevel() //needs to run after mobs are spawned
|
||||
|
||||
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(300, -800);
|
||||
},
|
||||
office() {
|
||||
let button, door
|
||||
@@ -2478,6 +2491,7 @@ const level = {
|
||||
}
|
||||
}
|
||||
powerUps.addRerollToLevel() //needs to run after mobs are spawned
|
||||
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(1875, -675);
|
||||
},
|
||||
stronghold() { // player made level by Francois 👑 from discord
|
||||
level.custom = () => {
|
||||
@@ -4452,7 +4466,7 @@ const level = {
|
||||
}
|
||||
let v = Vector.mult(this.portalPair.unit, mag)
|
||||
Matter.Body.setVelocity(player, v);
|
||||
// move bots to follow player
|
||||
// move bots to player
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType) {
|
||||
// Matter.Body.setPosition(bullet[i], this.portalPair.portal.position);
|
||||
|
||||
@@ -52,7 +52,7 @@ const m = {
|
||||
});
|
||||
World.add(engine.world, m.holdConstraint);
|
||||
},
|
||||
cycle: 300, //starts at 300 cycles instead of 0 to prevent bugs with m.history
|
||||
cycle: 600, //starts at 600 cycles instead of 0 to prevent bugs with m.history
|
||||
lastKillCycle: 0,
|
||||
lastHarmCycle: 0,
|
||||
width: 50,
|
||||
@@ -467,7 +467,7 @@ const m = {
|
||||
},
|
||||
displayHealth() {
|
||||
id = document.getElementById("health");
|
||||
// health display follows a x^1.5 rule to make it seem like the player has lower health, this makes the player feel more excitement
|
||||
// health display is a x^1.5 rule to make it seem like the player has lower health, this makes the player feel more excitement
|
||||
id.style.width = Math.floor(300 * m.maxHealth * Math.pow(m.health / m.maxHealth, 1.4)) + "px";
|
||||
//css animation blink if health is low
|
||||
if (m.health < 0.3) {
|
||||
@@ -556,7 +556,7 @@ const m = {
|
||||
// simulation.updateGunHUD();
|
||||
// simulation.boldActiveGunHUD();
|
||||
|
||||
// move bots to follow player
|
||||
// move bots to player
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType) {
|
||||
Matter.Body.setPosition(bullet[i], Vector.add(player.position, {
|
||||
@@ -2540,7 +2540,7 @@ const m = {
|
||||
y: velocity.y - 4 //an extra vertical kick so the player hangs in place longer
|
||||
});
|
||||
m.immuneCycle = m.cycle + 15; //player is immune to collision damage
|
||||
// move bots to follow player
|
||||
// move bots to player
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType) {
|
||||
Matter.Body.setPosition(bullet[i], Vector.add(player.position, {
|
||||
|
||||
@@ -530,9 +530,10 @@ const simulation = {
|
||||
if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod()
|
||||
if (b.guns[i].name === "nail gun") b.guns[i].chooseFireMethod()
|
||||
}
|
||||
tech.dynamoBotCount = 0;
|
||||
tech.nailBotCount = 0;
|
||||
tech.laserBotCount = 0;
|
||||
tech.orbitBotCount = 0;
|
||||
tech.nailBotCount = 0;
|
||||
tech.foamBotCount = 0;
|
||||
tech.boomBotCount = 0;
|
||||
tech.plasmaBotCount = 0;
|
||||
|
||||
14
js/spawn.js
14
js/spawn.js
@@ -507,15 +507,17 @@ const spawn = {
|
||||
};
|
||||
},
|
||||
cellBossCulture(x, y, radius = 20, num = 5) {
|
||||
const cellID = Math.random()
|
||||
for (let i = 0; i < num; i++) {
|
||||
spawn.cellBoss(x, y, radius)
|
||||
spawn.cellBoss(x, y, radius, cellID)
|
||||
}
|
||||
},
|
||||
cellBoss(x, y, radius = 20) {
|
||||
cellBoss(x, y, radius = 20, cellID) {
|
||||
mobs.spawn(x + Math.random(), y + Math.random(), 20, radius * (1 + 1.2 * Math.random()), "rgba(0,150,155,0.7)");
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.isCell = true;
|
||||
me.cellID = cellID
|
||||
me.accelMag = 0.00015 * simulation.accelScale;
|
||||
me.memory = 40;
|
||||
me.isVerticesChange = true
|
||||
@@ -531,7 +533,7 @@ const spawn = {
|
||||
me.split = function() {
|
||||
Matter.Body.scale(this, 0.4, 0.4);
|
||||
this.radius = Math.sqrt(this.mass * k / Math.PI)
|
||||
spawn.cellBoss(this.position.x, this.position.y, this.radius);
|
||||
spawn.cellBoss(this.position.x, this.position.y, this.radius, this.cellID);
|
||||
mob[mob.length - 1].health = this.health
|
||||
}
|
||||
me.onHit = function() { //run this function on hitting player
|
||||
@@ -571,9 +573,10 @@ const spawn = {
|
||||
};
|
||||
me.onDeath = function() {
|
||||
this.isCell = false;
|
||||
let count = 0 //count other cells
|
||||
let count = 0 //count other cells by id
|
||||
// console.log(this.cellID)
|
||||
for (let i = 0, len = mob.length; i < len; i++) {
|
||||
if (mob[i].isCell) count++
|
||||
if (mob[i].isCell && mob[i].cellID === this.cellID) count++
|
||||
}
|
||||
if (count < 1) { //only drop a power up if this is the last cell
|
||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||
@@ -2420,7 +2423,6 @@ const spawn = {
|
||||
stiffness: 0.05
|
||||
});
|
||||
World.add(engine.world, consBB[consBB.length - 1]);
|
||||
|
||||
},
|
||||
snakeBody(x, y, radius = 20) {
|
||||
mobs.spawn(x, y, 4, radius, "rgb(55,170,170)");
|
||||
|
||||
94
js/tech.js
94
js/tech.js
@@ -9,12 +9,6 @@ const tech = {
|
||||
lore.techCount = 0;
|
||||
tech.removeLoreTechFromPool();
|
||||
tech.addLoreTechToPool();
|
||||
// tech.nailBotCount = 0;
|
||||
// tech.foamBotCount = 0;
|
||||
// tech.boomBotCount = 0;
|
||||
// tech.laserBotCount = 0;
|
||||
// tech.orbitalBotCount = 0;
|
||||
// tech.plasmaBotCount = 0;
|
||||
tech.armorFromPowerUps = 0;
|
||||
tech.totalCount = 0;
|
||||
simulation.updateTechHUD();
|
||||
@@ -116,7 +110,7 @@ const tech = {
|
||||
return (tech.isBayesian ? 0.2 : 0) + tech.cancelCount * 0.04 + tech.duplicateChance + m.duplicateChance
|
||||
},
|
||||
totalBots() {
|
||||
return tech.foamBotCount + tech.nailBotCount + tech.laserBotCount + tech.boomBotCount + tech.orbitBotCount + tech.plasmaBotCount + tech.missileBotCount
|
||||
return tech.dynamoBotCount + tech.foamBotCount + tech.nailBotCount + tech.laserBotCount + tech.boomBotCount + tech.orbitBotCount + tech.plasmaBotCount + tech.missileBotCount
|
||||
},
|
||||
tech: [{
|
||||
name: "integrated armament",
|
||||
@@ -922,6 +916,45 @@ const tech = {
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "dynamo-bot",
|
||||
description: "a bot <strong class='color-d'>damages</strong> mobs while it <strong>traces</strong> your path<br>regen <strong>4</strong> <strong class='color-f'>energy</strong> per second when it's near",
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
allowed() {
|
||||
return true
|
||||
},
|
||||
requires: "",
|
||||
effect() {
|
||||
tech.dynamoBotCount++;
|
||||
b.dynamoBot();
|
||||
},
|
||||
remove() {
|
||||
tech.dynamoBotCount -= this.count;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "dynamo-bot upgrade",
|
||||
description: "dynamo-bots <strong>regen</strong> <strong>12</strong> <strong class='color-f'>energy</strong> per second<br><em>applies to all current and future orbit-bots</em>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
return tech.dynamoBotCount > 1
|
||||
},
|
||||
requires: "2 or more dynamo bots",
|
||||
effect() {
|
||||
tech.isDynamoBotUpgrade = true
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType === 'dynamo') bullet[i].isUpgraded = true
|
||||
}
|
||||
},
|
||||
remove() {
|
||||
tech.isDynamoBotUpgrade = false
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType === 'dynamo') bullet[i].isUpgraded = false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "bot fabrication",
|
||||
description: "anytime you collect <strong>5</strong> <strong class='color-r'>research</strong><br>use them to build a <strong>random bot</strong>",
|
||||
@@ -1076,7 +1109,7 @@ const tech = {
|
||||
},
|
||||
requires: "",
|
||||
effect() {
|
||||
tech.cyclicImmunity += 60 - this.count * 6;
|
||||
tech.cyclicImmunity += 60;
|
||||
},
|
||||
remove() {
|
||||
tech.cyclicImmunity = 0;
|
||||
@@ -1759,6 +1792,22 @@ const tech = {
|
||||
tech.isDupDamage = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "cloning",
|
||||
description: "each level has a chance to spawn a <strong>level boss</strong><br>equal to <strong>triple</strong> your <strong class='color-dup'>duplication</strong> chance",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
return tech.duplicationChance() > 0
|
||||
},
|
||||
requires: "some duplication chance",
|
||||
effect() {
|
||||
tech.isDuplicateBoss = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isDuplicateBoss = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "futures exchange",
|
||||
description: "clicking <strong style = 'font-size:150%;'>×</strong> to cancel a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>adds <strong>4%</strong> power up <strong class='color-dup'>duplication</strong> chance",
|
||||
@@ -3535,6 +3584,7 @@ const tech = {
|
||||
b.nailBot()
|
||||
tech.nailBotCount++;
|
||||
}
|
||||
simulation.makeTextLog(`tech.isNailBotUpgrade = true`)
|
||||
})
|
||||
if (!tech.isFoamBotUpgrade) notUpgradedBots.push(() => {
|
||||
tech.giveTech("foam-bot upgrade")
|
||||
@@ -3543,6 +3593,7 @@ const tech = {
|
||||
b.foamBot()
|
||||
tech.foamBotCount++;
|
||||
}
|
||||
simulation.makeTextLog(`tech.isFoamBotUpgrade = true`)
|
||||
})
|
||||
if (!tech.isBoomBotUpgrade) notUpgradedBots.push(() => {
|
||||
tech.giveTech("boom-bot upgrade")
|
||||
@@ -3551,6 +3602,7 @@ const tech = {
|
||||
b.boomBot()
|
||||
tech.boomBotCount++;
|
||||
}
|
||||
simulation.makeTextLog(`tech.isBoomBotUpgrade = true`)
|
||||
})
|
||||
if (!tech.isLaserBotUpgrade) notUpgradedBots.push(() => {
|
||||
tech.giveTech("laser-bot upgrade")
|
||||
@@ -3559,6 +3611,7 @@ const tech = {
|
||||
b.laserBot()
|
||||
tech.laserBotCount++;
|
||||
}
|
||||
simulation.makeTextLog(`tech.isLaserBotUpgrade = true`)
|
||||
})
|
||||
if (!tech.isOrbitBotUpgrade) notUpgradedBots.push(() => {
|
||||
tech.giveTech("orbital-bot upgrade")
|
||||
@@ -3567,6 +3620,26 @@ const tech = {
|
||||
b.orbitBot()
|
||||
tech.orbitBotCount++;
|
||||
}
|
||||
simulation.makeTextLog(`tech.isOrbitalBotUpgrade = true`)
|
||||
})
|
||||
if (!tech.isDynamoBotUpgrade) notUpgradedBots.push(() => {
|
||||
tech.giveTech("dynamo-bot upgrade")
|
||||
tech.setTechoNonRefundable("dynamo-bot upgrade")
|
||||
for (let i = 0; i < 2; i++) {
|
||||
b.orbitBot()
|
||||
tech.dynamoBotCount++;
|
||||
}
|
||||
simulation.makeTextLog(`tech.isDynamoBotUpgrade = true`)
|
||||
})
|
||||
//double chance for dynamo-bot, since it's very good for nano-scale
|
||||
if (!tech.isDynamoBotUpgrade) notUpgradedBots.push(() => {
|
||||
tech.giveTech("dynamo-bot upgrade")
|
||||
tech.setTechoNonRefundable("dynamo-bot upgrade")
|
||||
for (let i = 0; i < 2; i++) {
|
||||
b.orbitBot()
|
||||
tech.dynamoBotCount++;
|
||||
}
|
||||
simulation.makeTextLog(`tech.isDynamoBotUpgrade = true`)
|
||||
})
|
||||
//choose random function from the array and run it
|
||||
notUpgradedBots[Math.floor(Math.random() * notUpgradedBots.length)]()
|
||||
@@ -4093,6 +4166,7 @@ const tech = {
|
||||
isMassEnergy: null,
|
||||
isExtraChoice: null,
|
||||
laserBotCount: null,
|
||||
dynamoBotCount: null,
|
||||
nailBotCount: null,
|
||||
foamBotCount: null,
|
||||
boomBotCount: null,
|
||||
@@ -4261,5 +4335,7 @@ const tech = {
|
||||
isNeedles: null,
|
||||
isExplodeRadio: null,
|
||||
isGunSwitchField: null,
|
||||
isNeedleShieldPierce: null
|
||||
isNeedleShieldPierce: null,
|
||||
isDuplicateBoss: null,
|
||||
isDynamoBotUpgrade: null
|
||||
}
|
||||
46
todo.txt
46
todo.txt
@@ -1,11 +1,18 @@
|
||||
******************************************************** NEXT PATCH ********************************************************
|
||||
|
||||
unified field theory doesn't require research to cycle fields
|
||||
tech: cloning - chance to spawn another level boss = 3x your duplication chance
|
||||
|
||||
game resets after beating final boss (in 20s)
|
||||
tech: dynamo-bot: a bot follows your history, damages mobs, and regens energy when it gets close
|
||||
tech: dynamo upgrade: more energy regen
|
||||
|
||||
******************************************************** BUGS ********************************************************
|
||||
|
||||
(only once on my computer) once every 7 second check isn't running code
|
||||
power ups don't teleport to exit
|
||||
complex spin statistics isn't activating
|
||||
wasn't able to understand bug after extensive testing
|
||||
had tech: complex spin statistics
|
||||
|
||||
(a few times) wormhole teleportation can leave the player in a stuck jump state
|
||||
seems to be easily fixed, by porting, firing or something
|
||||
|
||||
@@ -24,7 +31,7 @@ game resets after beating final boss (in 20s)
|
||||
|
||||
******************************************************** TODO ********************************************************
|
||||
|
||||
exiting the final boss room without 10/10 takes you to the start menu
|
||||
smooth history following for dynamo-bot?
|
||||
|
||||
give undefined tech different effects at different localSettings.loreCount values
|
||||
or just random effects
|
||||
@@ -34,8 +41,6 @@ give undefined tech different effects at different localSettings.loreCount value
|
||||
3. 1/1: reduce max energy and take more harm
|
||||
4. 1/1: add 5? more levels
|
||||
|
||||
lore add console command for unlocking testing mode
|
||||
|
||||
rename ?
|
||||
health -> integrity, unity
|
||||
heal -> also integrity, unity
|
||||
@@ -46,28 +51,16 @@ mechanic: use gun swap as an active ability
|
||||
trigger damage immunity for 3 seconds, but drain ammo
|
||||
push away nearby mobs, but drain energy
|
||||
produce ammo, but take 1 damage
|
||||
rewind, still uses energy
|
||||
|
||||
bot: ice blast, long CD AOE freeze
|
||||
|
||||
RPG default or tech: grenades detonate on your cursor / where your cursor was when they were fired
|
||||
|
||||
tech: double your rerolls
|
||||
tech: double your research
|
||||
set your duplication chance to zero
|
||||
requires 5 rerolls and 20% duplication chance
|
||||
might want to use a single variable for all duplication
|
||||
|
||||
bot that follows the players history
|
||||
could have the same shape as the m circle head
|
||||
1st bot is at 5s, 2nd is at 4.5s, ...
|
||||
bots don't get too close to player
|
||||
run smoothing on position update, don't update if close to player, based on ordering
|
||||
effect: (one of these can be the upgrade effect)
|
||||
give player energy overfill
|
||||
AOE damage to mobs
|
||||
push away mobs
|
||||
when close to player: damage bonus damage reduction
|
||||
|
||||
tech: dodge chance for cloaking, harmonic fields, also pilot wave
|
||||
20% chance up to 3 stacks, not additive
|
||||
0.8^count
|
||||
@@ -85,8 +78,6 @@ tech: time dilation - when you exit time dilation rewind to the state you entere
|
||||
|
||||
mob ability bombs/bullets that suck in player
|
||||
|
||||
tech where you can't stop firing, how to code?
|
||||
|
||||
mechanic: technological dead end - add tech to the tech pool with a dumb effect
|
||||
don't show up in custom?
|
||||
negative effect (one time effects are better to avoid code clutter)
|
||||
@@ -106,23 +97,8 @@ mechanic: technological dead end - add tech to the tech pool with a dumb effect
|
||||
remove your bots (requires you to have some bots)
|
||||
your bots are changed to random bots
|
||||
|
||||
tech "Expansion Formula": Permanently increase the size of Negative Mass field by 16%(Max 96%)
|
||||
|
||||
|
||||
tech "High Risk": Spawn two bosses per level.
|
||||
maybe limit to just the power up boss and spawn it at the exit every time to keep it simple
|
||||
also weaken the player
|
||||
remove a tech?
|
||||
lower harm reduction?
|
||||
increase game difficulty by one level
|
||||
|
||||
tech that requires integrated armament
|
||||
|
||||
tech- reset level
|
||||
you trade a tech for a chance at killing a new level boss and farming more ammo
|
||||
resets health, ammo (but not tech, fields, guns, ... ?)
|
||||
scramble level order? or same level
|
||||
|
||||
mechanic - Your energy regen is only active when field and gun have not been used for 5 seconds.
|
||||
|
||||
be able to open up custom mode in the normal game
|
||||
|
||||
Reference in New Issue
Block a user