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:
landgreen
2021-01-29 05:13:44 -08:00
parent e4acaca31c
commit 66f2cce2b7
8 changed files with 289 additions and 109 deletions

View File

@@ -1713,7 +1713,7 @@ const b = {
friction: 0, friction: 0,
frictionAir: 0.025, frictionAir: 0.025,
thrust: (tech.isFastSpores ? 0.001 : 0.0004) * (1 + 0.3 * (Math.random() - 0.5)), 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()), lookFrequency: 100 + Math.floor(117 * Math.random()),
classType: "bullet", classType: "bullet",
collisionFilter: { collisionFilter: {
@@ -1722,7 +1722,7 @@ const b = {
}, },
endCycle: simulation.cycle + Math.floor((600 + Math.floor(Math.random() * 420)) * tech.isBulletsLastLonger), endCycle: simulation.cycle + Math.floor((600 + Math.floor(Math.random() * 420)) * tech.isBulletsLastLonger),
minDmgSpeed: 0, 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), x: 100 * (Math.random() - 0.5),
y: 100 * (Math.random() - 0.5) y: 100 * (Math.random() - 0.5)
}, },
@@ -2223,6 +2223,7 @@ const b = {
// ************************************************************************************************** // **************************************************************************************************
// ************************************************************************************************** // **************************************************************************************************
respawnBots() { 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.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.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) 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) { 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) b.laserBot(where)
if (isKeep) tech.laserBotCount++; if (isKeep) tech.laserBotCount++;
} else if (Math.random() < 0.25 && isAll) { } else if (Math.random() < 0.25 && isAll) {
@@ -2254,6 +2258,113 @@ const b = {
if (isKeep) tech.boomBotCount++; 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) { 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()`); if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.nailBot()`);
const me = bullet.length; const me = bullet.length;
@@ -2435,7 +2546,7 @@ const b = {
drainThreshold: tech.isEnergyHealth ? 0.5 : 0.33, drainThreshold: tech.isEnergyHealth ? 0.5 : 0.33,
acceleration: 0.0015 * (1 + 0.3 * Math.random()), acceleration: 0.0015 * (1 + 0.3 * Math.random()),
range: 700 * (1 + 0.1 * Math.random()) + 300 * tech.isLaserBotUpgrade, 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: { offPlayer: {
x: 0, x: 0,
y: 0, y: 0,
@@ -2453,7 +2564,7 @@ const b = {
onEnd() {}, onEnd() {},
do() { 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 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 const mag = Math.min(farAway, 4) * this.mass * this.acceleration
this.force = Vector.mult(Vector.normalise(Vector.sub(playerPos, this.position)), mag) this.force = Vector.mult(Vector.normalise(Vector.sub(playerPos, this.position)), mag)
//manual friction to not lose rotational velocity //manual friction to not lose rotational velocity
@@ -3520,13 +3631,13 @@ const b = {
name: "spores", 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", 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, ammo: 0,
ammoPack: 3, ammoPack: 3.5,
have: false, have: false,
fire() { fire() {
const me = bullet.length; const me = bullet.length;
const dir = m.angle; 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)); 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); Matter.Body.setDensity(bullet[me], 0.000001);
bullet[me].endCycle = Infinity; bullet[me].endCycle = Infinity;
bullet[me].frictionAir = 0; bullet[me].frictionAir = 0;
@@ -3683,10 +3794,10 @@ const b = {
name: "foam", 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", 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, ammo: 0,
ammoPack: 35, ammoPack: 36,
have: false, have: false,
fire() { 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 radius = (m.crouch ? 10 + 5 * Math.random() : 4 + 6 * Math.random()) + (tech.isAmmoFoamSize && this.ammo < 300) * 12
const SPEED = 18 - radius * 0.4; const SPEED = 18 - radius * 0.4;
const dir = m.angle + 0.2 * (Math.random() - 0.5) const dir = m.angle + 0.2 * (Math.random() - 0.5)

View File

@@ -857,7 +857,7 @@ window.addEventListener("keydown", function(event) {
x: 0, x: 0,
y: 0 y: 0
}); });
// move bots to follow player // move bots to player
for (let i = 0; i < bullet.length; i++) { for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType) { if (bullet[i].botType) {
Matter.Body.setPosition(bullet[i], Vector.add(player.position, { Matter.Body.setPosition(bullet[i], Vector.add(player.position, {

View File

@@ -19,7 +19,7 @@ const level = {
// m.setField("plasma torch") // m.setField("plasma torch")
// b.giveGuns("nail gun") // b.giveGuns("nail gun")
// tech.isExplodeRadio = true // tech.isExplodeRadio = true
// tech.giveTech("needle gun") for (let i = 0; i < 1; i++) tech.giveTech("dynamo-bot")
// tech.giveTech("supercritical fission") // tech.giveTech("supercritical fission")
// tech.giveTech("irradiated nails") // tech.giveTech("irradiated nails")
// tech.giveTech("cardinality") // tech.giveTech("cardinality")
@@ -299,9 +299,10 @@ const level = {
// spawn.laserTargetingBoss(1600, -400) // spawn.laserTargetingBoss(1600, -400)
// spawn.striker(1600, -500) // spawn.striker(1600, -500)
// spawn.shooter(1700, -120) // spawn.shooter(1700, -120)
spawn.bomberBoss(1400, -500) // spawn.bomberBoss(1400, -500)
// spawn.sniper(1800, -120) // spawn.sniper(1800, -120)
// spawn.cellBossCulture(1600, -500) // spawn.cellBossCulture(1600, -500)
// spawn.cellBossCulture(1600, -500)
// spawn.streamBoss(1600, -500) // spawn.streamBoss(1600, -500)
// spawn.beamer(1200, -500) // spawn.beamer(1200, -500)
// spawn.shield(mob[mob.length - 1], 1800, -120, 1); // spawn.shield(mob[mob.length - 1], 1800, -120, 1);
@@ -348,6 +349,7 @@ const level = {
// spawn.randomBoss(1700, -900, 0.4); // spawn.randomBoss(1700, -900, 0.4);
// if (simulation.difficulty > 3) spawn.randomLevelBoss(2200, -1300); // if (simulation.difficulty > 3) spawn.randomLevelBoss(2200, -1300);
powerUps.addRerollToLevel() //needs to run after mobs are spawned powerUps.addRerollToLevel() //needs to run after mobs are spawned
// if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(4800, -500);
}, },
final() { final() {
level.bossKilled = false; // if a boss needs to be killed 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(5700, -3300, 1800, 5100); //right wall
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
spawn.mapRect(5425, -650, 375, 450); //blocking exit spawn.mapRect(5425, -650, 375, 450); //blocking exit
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(4800, -500);
}, },
gauntlet() { gauntlet() {
level.bossKilled = true; //if there is no boss this needs to be true to increase levels 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 powerUps.addRerollToLevel() //needs to run after mobs are spawned
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(4125, -350);
}, },
intro() { intro() {
level.bossKilled = true; //if there is no boss this needs to be true to increase levels 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.wireKneeLeft();
spawn.wireHead(); spawn.wireHead();
} else { } else {
const say = [] // const say = []
if (localSettings.runCount > 200) { //experienced // if (localSettings.runCount > 200) { //experienced
say.push( // say.push(
"I've been here before...", // "I've been here before...",
"How many times have I done this?", // "How many times have I done this?",
) // )
} else if (localSettings.runCount < 20) { //new // } else if (localSettings.runCount < 20) { //new
say.push( // say.push(
"Am I still alive?", // "Am I still alive?",
"And I'm back here again...", // "And I'm back here again...",
"Is this another simulation?", // "Is this another simulation?",
"I'm alive...", // "I'm alive...",
"Last time was a simulation. Is this one a simulation too?", // "Last time was a simulation. Is this one a simulation too?",
) // )
} // }
if (simulation.difficultyMode < 4 && localSettings.levelsClearedLastGame > 10) { //too easy // if (simulation.difficultyMode < 4 && localSettings.levelsClearedLastGame > 10) { //too easy
say.push( // say.push(
"That felt too easy.<br>Maybe I should increase the difficulty of the simulation.", // "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.", // "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.", // "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 // } else if (simulation.difficultyMode > 3 && localSettings.levelsClearedLastGame > 10) { //great run on a hard or why
say.push( // say.push(
"What do I do after I escape?", // "What do I do after I escape?",
"I'm almost ready to stop these simulations and actually escape.", // "I'm almost ready to stop these simulations and actually escape.",
"I think I'm getting closer to something, but what?", // "I think I'm getting closer to something, but what?",
"I'm getting stronger.", // "I'm getting stronger.",
"What happens after I escape?", // "What happens after I escape?",
"I found a good combination of technology last time." // "I found a good combination of technology last time."
) // )
} else { //resolve // } else { //resolve
say.push( // say.push(
"I'll try some different techs this time.", // "I'll try some different techs this time.",
"I've got to escape.", // "I've got to escape.",
"I'll find a way out.", // "I'll find a way out.",
"I keep forgetting that these are just simulated escapes." // "I keep forgetting that these are just simulated escapes."
) // )
} // }
simulation.makeTextLog(say[Math.floor(say.length * Math.random())], 1000) // simulation.makeTextLog(say[Math.floor(say.length * Math.random())], 1000)
const swapPeriod = 150 const swapPeriod = 150
const len = 30 const len = 30
@@ -695,6 +699,7 @@ const level = {
} }
} }
powerUps.spawnStartingPowerUps(2300, -150); powerUps.spawnStartingPowerUps(2300, -150);
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(1900, -675);
}, },
testChamber() { testChamber() {
level.setPosToSpawn(0, -50); //lower start level.setPosToSpawn(0, -50); //lower start
@@ -768,7 +773,6 @@ const level = {
} }
} }
buttonDoor.query(); buttonDoor.query();
buttonDoor.draw(); buttonDoor.draw();
if (buttonDoor.isUp) { if (buttonDoor.isUp) {
@@ -961,6 +965,7 @@ const level = {
} }
} }
powerUps.addRerollToLevel() //needs to run after mobs are spawned powerUps.addRerollToLevel() //needs to run after mobs are spawned
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(1925, -1250);
}, },
sewers() { sewers() {
level.bossKilled = false; // if a boss needs to be killed level.bossKilled = false; // if a boss needs to be killed
@@ -1106,6 +1111,7 @@ const level = {
spawn.randomMob(2825, 400, 0.9); spawn.randomMob(2825, 400, 0.9);
if (simulation.difficulty > 3) spawn.randomLevelBoss(6000, 2300, ["spiderBoss", "launcherBoss", "laserTargetingBoss", "streamBoss"]); if (simulation.difficulty > 3) spawn.randomLevelBoss(6000, 2300, ["spiderBoss", "launcherBoss", "laserTargetingBoss", "streamBoss"]);
powerUps.addRerollToLevel() //needs to run after mobs are spawned powerUps.addRerollToLevel() //needs to run after mobs are spawned
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(7725, 2275);
}, },
satellite() { satellite() {
level.bossKilled = false; // if a boss needs to be killed 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 powerUps.addRerollToLevel() //needs to run after mobs are spawned
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(3950, -850);
}, },
rooftops() { rooftops() {
level.bossKilled = false; // if a boss needs to be killed level.bossKilled = false; // if a boss needs to be killed
@@ -1535,6 +1542,7 @@ const level = {
spawn.randomBoss(4900, -1200, 0); spawn.randomBoss(4900, -1200, 0);
if (simulation.difficulty > 3) spawn.randomLevelBoss(3200, -2050); if (simulation.difficulty > 3) spawn.randomLevelBoss(3200, -2050);
powerUps.addRerollToLevel() //needs to run after mobs are spawned powerUps.addRerollToLevel() //needs to run after mobs are spawned
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(2175, -2425);
}, },
aerie() { aerie() {
level.bossKilled = false; // if a boss needs to be killed 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 powerUps.addRerollToLevel() //needs to run after mobs are spawned
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(5350, -325);
}, },
skyscrapers() { skyscrapers() {
level.bossKilled = false; // if a boss needs to be killed level.bossKilled = false; // if a boss needs to be killed
@@ -1905,6 +1914,7 @@ const level = {
spawn.randomBoss(1700, -900, 0.4); spawn.randomBoss(1700, -900, 0.4);
if (simulation.difficulty > 3) spawn.randomLevelBoss(2600, -2300); if (simulation.difficulty > 3) spawn.randomLevelBoss(2600, -2300);
powerUps.addRerollToLevel() //needs to run after mobs are spawned powerUps.addRerollToLevel() //needs to run after mobs are spawned
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(3075, -2050);
}, },
highrise() { highrise() {
level.bossKilled = false; // if a boss needs to be killed level.bossKilled = false; // if a boss needs to be killed
@@ -2104,6 +2114,7 @@ const level = {
if (simulation.difficulty > 3) spawn.randomLevelBoss(-2400, -3000); if (simulation.difficulty > 3) spawn.randomLevelBoss(-2400, -3000);
powerUps.addRerollToLevel() //needs to run after mobs are spawned powerUps.addRerollToLevel() //needs to run after mobs are spawned
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(-1825, -1975);
}, },
warehouse() { warehouse() {
level.bossKilled = false; // if a boss needs to be killed level.bossKilled = false; // if a boss needs to be killed
@@ -2275,10 +2286,12 @@ const level = {
if (Math.random() < 0.25) { if (Math.random() < 0.25) {
spawn.randomLevelBoss(-800, -1300) spawn.randomLevelBoss(-800, -1300)
} else { } 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 powerUps.addRerollToLevel() //needs to run after mobs are spawned
if (tech.isDuplicateBoss && Math.random() < 3 * tech.duplicationChance()) spawn.randomLevelBoss(300, -800);
}, },
office() { office() {
let button, door let button, door
@@ -2478,6 +2491,7 @@ const level = {
} }
} }
powerUps.addRerollToLevel() //needs to run after mobs are spawned 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 stronghold() { // player made level by Francois 👑 from discord
level.custom = () => { level.custom = () => {
@@ -4452,7 +4466,7 @@ const level = {
} }
let v = Vector.mult(this.portalPair.unit, mag) let v = Vector.mult(this.portalPair.unit, mag)
Matter.Body.setVelocity(player, v); Matter.Body.setVelocity(player, v);
// move bots to follow player // move bots to player
for (let i = 0; i < bullet.length; i++) { for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType) { if (bullet[i].botType) {
// Matter.Body.setPosition(bullet[i], this.portalPair.portal.position); // Matter.Body.setPosition(bullet[i], this.portalPair.portal.position);

View File

@@ -52,7 +52,7 @@ const m = {
}); });
World.add(engine.world, m.holdConstraint); 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, lastKillCycle: 0,
lastHarmCycle: 0, lastHarmCycle: 0,
width: 50, width: 50,
@@ -467,7 +467,7 @@ const m = {
}, },
displayHealth() { displayHealth() {
id = document.getElementById("health"); 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"; id.style.width = Math.floor(300 * m.maxHealth * Math.pow(m.health / m.maxHealth, 1.4)) + "px";
//css animation blink if health is low //css animation blink if health is low
if (m.health < 0.3) { if (m.health < 0.3) {
@@ -556,7 +556,7 @@ const m = {
// simulation.updateGunHUD(); // simulation.updateGunHUD();
// simulation.boldActiveGunHUD(); // simulation.boldActiveGunHUD();
// move bots to follow player // move bots to player
for (let i = 0; i < bullet.length; i++) { for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType) { if (bullet[i].botType) {
Matter.Body.setPosition(bullet[i], Vector.add(player.position, { 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 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 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++) { for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType) { if (bullet[i].botType) {
Matter.Body.setPosition(bullet[i], Vector.add(player.position, { Matter.Body.setPosition(bullet[i], Vector.add(player.position, {

View File

@@ -530,9 +530,10 @@ const simulation = {
if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod() if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod()
if (b.guns[i].name === "nail gun") 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.laserBotCount = 0;
tech.orbitBotCount = 0; tech.orbitBotCount = 0;
tech.nailBotCount = 0;
tech.foamBotCount = 0; tech.foamBotCount = 0;
tech.boomBotCount = 0; tech.boomBotCount = 0;
tech.plasmaBotCount = 0; tech.plasmaBotCount = 0;

View File

@@ -507,15 +507,17 @@ const spawn = {
}; };
}, },
cellBossCulture(x, y, radius = 20, num = 5) { cellBossCulture(x, y, radius = 20, num = 5) {
const cellID = Math.random()
for (let i = 0; i < num; i++) { 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)"); 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]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
me.isCell = true; me.isCell = true;
me.cellID = cellID
me.accelMag = 0.00015 * simulation.accelScale; me.accelMag = 0.00015 * simulation.accelScale;
me.memory = 40; me.memory = 40;
me.isVerticesChange = true me.isVerticesChange = true
@@ -531,7 +533,7 @@ const spawn = {
me.split = function() { me.split = function() {
Matter.Body.scale(this, 0.4, 0.4); Matter.Body.scale(this, 0.4, 0.4);
this.radius = Math.sqrt(this.mass * k / Math.PI) 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 mob[mob.length - 1].health = this.health
} }
me.onHit = function() { //run this function on hitting player me.onHit = function() { //run this function on hitting player
@@ -571,9 +573,10 @@ const spawn = {
}; };
me.onDeath = function() { me.onDeath = function() {
this.isCell = false; 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++) { 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 if (count < 1) { //only drop a power up if this is the last cell
powerUps.spawnBossPowerUp(this.position.x, this.position.y) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
@@ -2420,7 +2423,6 @@ const spawn = {
stiffness: 0.05 stiffness: 0.05
}); });
World.add(engine.world, consBB[consBB.length - 1]); World.add(engine.world, consBB[consBB.length - 1]);
}, },
snakeBody(x, y, radius = 20) { snakeBody(x, y, radius = 20) {
mobs.spawn(x, y, 4, radius, "rgb(55,170,170)"); mobs.spawn(x, y, 4, radius, "rgb(55,170,170)");

View File

@@ -9,12 +9,6 @@ const tech = {
lore.techCount = 0; lore.techCount = 0;
tech.removeLoreTechFromPool(); tech.removeLoreTechFromPool();
tech.addLoreTechToPool(); tech.addLoreTechToPool();
// tech.nailBotCount = 0;
// tech.foamBotCount = 0;
// tech.boomBotCount = 0;
// tech.laserBotCount = 0;
// tech.orbitalBotCount = 0;
// tech.plasmaBotCount = 0;
tech.armorFromPowerUps = 0; tech.armorFromPowerUps = 0;
tech.totalCount = 0; tech.totalCount = 0;
simulation.updateTechHUD(); simulation.updateTechHUD();
@@ -116,7 +110,7 @@ const tech = {
return (tech.isBayesian ? 0.2 : 0) + tech.cancelCount * 0.04 + tech.duplicateChance + m.duplicateChance return (tech.isBayesian ? 0.2 : 0) + tech.cancelCount * 0.04 + tech.duplicateChance + m.duplicateChance
}, },
totalBots() { 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: [{ tech: [{
name: "integrated armament", 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", 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>", 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: "", requires: "",
effect() { effect() {
tech.cyclicImmunity += 60 - this.count * 6; tech.cyclicImmunity += 60;
}, },
remove() { remove() {
tech.cyclicImmunity = 0; tech.cyclicImmunity = 0;
@@ -1759,6 +1792,22 @@ const tech = {
tech.isDupDamage = false; 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", 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", 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() b.nailBot()
tech.nailBotCount++; tech.nailBotCount++;
} }
simulation.makeTextLog(`tech.isNailBotUpgrade = true`)
}) })
if (!tech.isFoamBotUpgrade) notUpgradedBots.push(() => { if (!tech.isFoamBotUpgrade) notUpgradedBots.push(() => {
tech.giveTech("foam-bot upgrade") tech.giveTech("foam-bot upgrade")
@@ -3543,6 +3593,7 @@ const tech = {
b.foamBot() b.foamBot()
tech.foamBotCount++; tech.foamBotCount++;
} }
simulation.makeTextLog(`tech.isFoamBotUpgrade = true`)
}) })
if (!tech.isBoomBotUpgrade) notUpgradedBots.push(() => { if (!tech.isBoomBotUpgrade) notUpgradedBots.push(() => {
tech.giveTech("boom-bot upgrade") tech.giveTech("boom-bot upgrade")
@@ -3551,6 +3602,7 @@ const tech = {
b.boomBot() b.boomBot()
tech.boomBotCount++; tech.boomBotCount++;
} }
simulation.makeTextLog(`tech.isBoomBotUpgrade = true`)
}) })
if (!tech.isLaserBotUpgrade) notUpgradedBots.push(() => { if (!tech.isLaserBotUpgrade) notUpgradedBots.push(() => {
tech.giveTech("laser-bot upgrade") tech.giveTech("laser-bot upgrade")
@@ -3559,6 +3611,7 @@ const tech = {
b.laserBot() b.laserBot()
tech.laserBotCount++; tech.laserBotCount++;
} }
simulation.makeTextLog(`tech.isLaserBotUpgrade = true`)
}) })
if (!tech.isOrbitBotUpgrade) notUpgradedBots.push(() => { if (!tech.isOrbitBotUpgrade) notUpgradedBots.push(() => {
tech.giveTech("orbital-bot upgrade") tech.giveTech("orbital-bot upgrade")
@@ -3567,6 +3620,26 @@ const tech = {
b.orbitBot() b.orbitBot()
tech.orbitBotCount++; 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 //choose random function from the array and run it
notUpgradedBots[Math.floor(Math.random() * notUpgradedBots.length)]() notUpgradedBots[Math.floor(Math.random() * notUpgradedBots.length)]()
@@ -4093,6 +4166,7 @@ const tech = {
isMassEnergy: null, isMassEnergy: null,
isExtraChoice: null, isExtraChoice: null,
laserBotCount: null, laserBotCount: null,
dynamoBotCount: null,
nailBotCount: null, nailBotCount: null,
foamBotCount: null, foamBotCount: null,
boomBotCount: null, boomBotCount: null,
@@ -4261,5 +4335,7 @@ const tech = {
isNeedles: null, isNeedles: null,
isExplodeRadio: null, isExplodeRadio: null,
isGunSwitchField: null, isGunSwitchField: null,
isNeedleShieldPierce: null isNeedleShieldPierce: null,
isDuplicateBoss: null,
isDynamoBotUpgrade: null
} }

View File

@@ -1,11 +1,18 @@
******************************************************** NEXT PATCH ******************************************************** ******************************************************** 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 ******************************************************** ******************************************************** 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 (a few times) wormhole teleportation can leave the player in a stuck jump state
seems to be easily fixed, by porting, firing or something seems to be easily fixed, by porting, firing or something
@@ -24,7 +31,7 @@ game resets after beating final boss (in 20s)
******************************************************** TODO ******************************************************** ******************************************************** 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 give undefined tech different effects at different localSettings.loreCount values
or just random effects 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 3. 1/1: reduce max energy and take more harm
4. 1/1: add 5? more levels 4. 1/1: add 5? more levels
lore add console command for unlocking testing mode
rename ? rename ?
health -> integrity, unity health -> integrity, unity
heal -> also 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 trigger damage immunity for 3 seconds, but drain ammo
push away nearby mobs, but drain energy push away nearby mobs, but drain energy
produce ammo, but take 1 damage produce ammo, but take 1 damage
rewind, still uses energy
bot: ice blast, long CD AOE freeze bot: ice blast, long CD AOE freeze
RPG default or tech: grenades detonate on your cursor / where your cursor was when they were fired 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 set your duplication chance to zero
requires 5 rerolls and 20% duplication chance requires 5 rerolls and 20% duplication chance
might want to use a single variable for all duplication 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 tech: dodge chance for cloaking, harmonic fields, also pilot wave
20% chance up to 3 stacks, not additive 20% chance up to 3 stacks, not additive
0.8^count 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 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 mechanic: technological dead end - add tech to the tech pool with a dumb effect
don't show up in custom? don't show up in custom?
negative effect (one time effects are better to avoid code clutter) 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) remove your bots (requires you to have some bots)
your bots are changed to random 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 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. 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 be able to open up custom mode in the normal game