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
}