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,
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)

View File

@@ -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, {

View File

@@ -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);

View File

@@ -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, {

View File

@@ -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;

View File

@@ -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)");

View File

@@ -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
}

View File

@@ -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