diff --git a/.DS_Store b/.DS_Store
index 6a7a2b0..e8e965f 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/index.html b/index.html
index 48f0060..19afb94 100644
--- a/index.html
+++ b/index.html
@@ -114,14 +114,14 @@
diff --git a/js/bullet.js b/js/bullet.js
index 7c6497f..ed1ac9b 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -315,11 +315,11 @@ const b = {
}
if (tech.isExplodeRadio) { //radiation explosion
- const alertRange = 100 + radius * 2; //alert range
+ radius *= 1.25; //alert range
simulation.drawList.push({ //add dmg to draw queue
x: where.x,
y: where.y,
- radius: alertRange,
+ radius: radius,
color: "rgba(25,139,170,0.25)",
time: simulation.drawTime * 2
});
@@ -328,9 +328,13 @@ const b = {
sub = Vector.sub(where, player.position);
dist = Vector.magnitude(sub);
- if (dist < alertRange) {
- m.energy -= 0.23 * (tech.isImmuneExplosion ? Math.min(1, Math.max(1 - m.energy * 0.7, 0)) : 1)
- if (m.energy < 0) m.energy = 0
+ if (dist < radius) {
+ const drain = (tech.isExplosionHarm ? 0.5 : 0.25) * (tech.isImmuneExplosion ? Math.min(1, Math.max(1 - m.energy * 0.7, 0)) : 1)
+ m.energy -= drain
+ if (m.energy < 0) {
+ m.energy = 0
+ m.damage(0.03);
+ }
}
//mob damage and knock back with alert
@@ -339,10 +343,10 @@ const b = {
if (mob[i].alive && !mob[i].isShielded) {
sub = Vector.sub(where, mob[i].position);
dist = Vector.magnitude(sub) - mob[i].radius;
- if (dist < alertRange) {
+ if (dist < radius) {
if (mob[i].shield) dmg *= 2.5 //balancing explosion dmg to shields
if (Matter.Query.ray(map, mob[i].position, where).length > 0) dmg *= 0.5 //reduce damage if a wall is in the way
- mobs.statusDoT(mob[i], dmg * damageScale * 0.2, 240) //apply radiation damage status effect on direct hits
+ mobs.statusDoT(mob[i], dmg * damageScale * 0.25, 240) //apply radiation damage status effect on direct hits
mob[i].locatePlayer();
damageScale *= 0.87 //reduced damage for each additional explosion target
}
@@ -1077,7 +1081,7 @@ const b = {
didExtruderDrain: false,
canExtruderFire: true,
extruder() {
- const DRAIN = 0.0007 + m.fieldRegen
+ const DRAIN = 0.0006 + m.fieldRegen
if (m.energy > DRAIN && b.canExtruderFire) {
m.energy -= DRAIN
if (m.energy < 0) {
@@ -1096,7 +1100,7 @@ const b = {
frictionAir: 0,
isInHole: true, //this keeps the bullet from entering wormholes
minDmgSpeed: 0,
- dmg: b.dmgScale * 1.25, //damage also changes when you divide by mob.mass on in .do()
+ dmg: b.dmgScale * 1.35, //damage also changes when you divide by mob.mass on in .do()
classType: "bullet",
isBranch: false,
restitution: 0,
@@ -2545,7 +2549,7 @@ const b = {
dmg: 0, // 0.14 //damage done in addition to the damage from momentum
minDmgSpeed: 2,
lookFrequency: 40 + Math.floor(7 * Math.random()),
- drainThreshold: tech.isEnergyHealth ? 0.5 : 0.33,
+ drainThreshold: tech.isEnergyHealth ? 0.6 : 0.4,
acceleration: 0.0015 * (1 + 0.3 * Math.random()),
range: 700 * (1 + 0.1 * Math.random()) + 300 * tech.isLaserBotUpgrade,
playerRange: 150 + Math.floor(30 * Math.random()),
@@ -2711,7 +2715,7 @@ const b = {
cd: 0,
acceleration: 0.009,
endCycle: Infinity,
- drainThreshold: tech.isEnergyHealth ? 0.4 : 0.2,
+ drainThreshold: tech.isEnergyHealth ? 0.5 : 0.33,
classType: "bullet",
collisionFilter: {
category: cat.bullet,
diff --git a/js/index.js b/js/index.js
index a580807..605689f 100644
--- a/js/index.js
+++ b/js/index.js
@@ -196,6 +196,7 @@ const build = {
level: ${level.levels[level.onLevel]} (${level.difficultyText()}) ${m.cycle} cycles
${mob.length} mobs, ${body.length} blocks, ${bullet.length} bullets, ${powerUp.length} power ups
+
damage difficulty scale: ${(b.dmgScale*100).toFixed(2) }%
harm difficulty scale: ${(simulation.dmgScale*100).toFixed(0)}%
heal difficulty scale: ${(simulation.healScale*100).toFixed(1)}%
diff --git a/js/level.js b/js/level.js
index d9e475c..32fcdec 100644
--- a/js/level.js
+++ b/js/level.js
@@ -7,7 +7,6 @@ const level = {
defaultZoom: 1400,
onLevel: -1,
levelsCleared: 0,
- bossKilled: false,
playableLevels: ["skyscrapers", "rooftops", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber"],
levels: [],
start() {
@@ -111,26 +110,26 @@ const level = {
difficultyIncrease(num = 1) {
for (let i = 0; i < num; i++) {
simulation.difficulty++
- b.dmgScale *= 0.93; //damage done by player decreases each level
+ b.dmgScale *= 0.94; //damage done by player decreases each level
if (simulation.accelScale < 5) simulation.accelScale *= 1.02 //mob acceleration increases each level
if (simulation.lookFreqScale > 0.2) simulation.lookFreqScale *= 0.98 //mob cycles between looks decreases each level
if (simulation.CDScale > 0.2) simulation.CDScale *= 0.97 //mob CD time decreases each level
}
- simulation.dmgScale = 0.378 * simulation.difficulty //damage done by mobs increases each level
- simulation.healScale = 1 / (1 + simulation.difficulty * 0.06) //a higher denominator makes for lower heals // m.health += heal * simulation.healScale;
+ simulation.dmgScale = 0.36 * simulation.difficulty //damage done by mobs increases each level
+ simulation.healScale = 1 / (1 + simulation.difficulty * 0.055) //a higher denominator makes for lower heals // m.health += heal * simulation.healScale;
},
difficultyDecrease(num = 1) { //used in easy mode for simulation.reset()
for (let i = 0; i < num; i++) {
simulation.difficulty--
- b.dmgScale /= 0.93; //damage done by player decreases each level
+ b.dmgScale /= 0.94; //damage done by player decreases each level
if (simulation.accelScale > 0.2) simulation.accelScale /= 1.02 //mob acceleration increases each level
if (simulation.lookFreqScale < 5) simulation.lookFreqScale /= 0.98 //mob cycles between looks decreases each level
if (simulation.CDScale < 5) simulation.CDScale /= 0.97 //mob CD time decreases each level
}
if (simulation.difficulty < 1) simulation.difficulty = 0;
- simulation.dmgScale = 0.378 * simulation.difficulty //damage done by mobs increases each level
+ simulation.dmgScale = 0.36 * simulation.difficulty //damage done by mobs increases each level
if (simulation.dmgScale < 0.1) simulation.dmgScale = 0.1;
- simulation.healScale = 1 / (1 + simulation.difficulty * 0.06)
+ simulation.healScale = 1 / (1 + simulation.difficulty * 0.055)
},
difficultyText() {
if (simulation.difficultyMode === 1) {
@@ -1052,7 +1051,8 @@ const level = {
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
// spawn.boost(1500, 0, 900);
- spawn.starter(1900, -500, 200) //big boy
+ // spawn.starter(1900, -500, 200) //big boy
+ spawn.historyBoss(1900, -500)
// spawn.sneaker(2900, -500)
// spawn.launcherBoss(1200, -500)
// spawn.laserTargetingBoss(1600, -400)
@@ -1066,7 +1066,7 @@ const level = {
// spawn.beamer(1200, -500)
// spawn.shield(mob[mob.length - 1], 1800, -120, 1);
- // spawn.nodeBoss(1200, -500, "launcher")
+ // spawn.nodeGroup(1200, -500, "launcher")
// spawn.snakeBoss(1200, -500)
// spawn.powerUpBoss(2900, -500)
// spawn.randomMob(1600, -500)
@@ -1105,13 +1105,12 @@ const level = {
// spawn.boost(4150, 0, 1300);
// spawn.randomSmallMob(1300, -70);
// spawn.randomMob(2650, -975, 0.8);
- // spawn.randomBoss(1700, -900, 0.4);
+ // spawn.randomGroup(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() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(4800, -500);
},
final() {
- level.bossKilled = false; // if a boss needs to be killed
level.custom = () => {
level.playerExitCheck();
};
@@ -1162,7 +1161,6 @@ const level = {
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(4800, -500);
},
gauntlet() {
- level.bossKilled = true; //if there is no boss this needs to be true to increase levels
level.custom = () => {
level.playerExitCheck();
};
@@ -1199,12 +1197,12 @@ const level = {
spawn.blockDoor(2585, -210)
spawn.mapRect(2500, -200, 200, 300); //right wall
- spawn.nodeBoss(3500, -200, spawn.allowedBossList[Math.floor(Math.random() * spawn.allowedBossList.length)]);
+ spawn.nodeGroup(3500, -200, spawn.allowedGroupList[Math.floor(Math.random() * spawn.allowedGroupList.length)]);
spawn.mapRect(4500, -1200, 200, 750); //right wall
spawn.blockDoor(4585, -210)
spawn.mapRect(4500, -200, 200, 300); //right wall
- spawn.lineBoss(5000, -200, spawn.allowedBossList[Math.floor(Math.random() * spawn.allowedBossList.length)]);
+ spawn.lineGroup(5000, -200, spawn.allowedGroupList[Math.floor(Math.random() * spawn.allowedGroupList.length)]);
spawn.mapRect(6400, -1200, 400, 750); //right wall
spawn.mapRect(6400, -200, 400, 300); //right wall
spawn.mapRect(6700, -1800, 800, 2600); //right wall
@@ -1212,20 +1210,19 @@ const level = {
for (let i = 0; i < 3; ++i) {
if (simulation.difficulty * Math.random() > 15 * i) {
- spawn.randomBoss(2000 + 500 * (Math.random() - 0.5), -800 + 200 * (Math.random() - 0.5), Infinity);
+ spawn.randomGroup(2000 + 500 * (Math.random() - 0.5), -800 + 200 * (Math.random() - 0.5), Infinity);
}
if (simulation.difficulty * Math.random() > 10 * i) {
- spawn.randomBoss(3500 + 500 * (Math.random() - 0.5), -800 + 200 * (Math.random() - 0.5), Infinity);
+ spawn.randomGroup(3500 + 500 * (Math.random() - 0.5), -800 + 200 * (Math.random() - 0.5), Infinity);
}
if (simulation.difficulty * Math.random() > 7 * i) {
- spawn.randomBoss(5000 + 500 * (Math.random() - 0.5), -800 + 200 * (Math.random() - 0.5), Infinity);
+ spawn.randomGroup(5000 + 500 * (Math.random() - 0.5), -800 + 200 * (Math.random() - 0.5), Infinity);
}
}
powerUps.addRerollToLevel() //needs to run after mobs are spawned
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(4125, -350);
},
intro() {
- level.bossKilled = true; //if there is no boss this needs to be true to increase levels
level.custom = () => {
level.playerExitCheck();
};
@@ -1709,7 +1706,7 @@ const level = {
spawn.randomMob(1550, -2750, -0.5);
spawn.randomMob(1350, -1150, -0.5);
spawn.randomMob(-75, -1475, 0);
- spawn.randomBoss(600, -2600, 0);
+ spawn.randomGroup(600, -2600, 0);
}
if (simulation.difficulty < 25) {
spawn.randomMob(700, -1650, 0);
@@ -1727,7 +1724,6 @@ const level = {
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(1925, -1250);
},
sewers() {
- level.bossKilled = false; // if a boss needs to be killed
const rotor = level.rotor(5100, 2475, -0.001)
const button = level.button(6600, 2675)
const hazard = level.hazard(4550, 2750, 4550, 150)
@@ -1844,7 +1840,7 @@ const level = {
spawn.mapRect(9300, 2590, 650, 25);
spawn.mapRect(9700, 2580, 100, 50);
- spawn.randomBoss(1300, 2100, 0.1);
+ spawn.randomGroup(1300, 2100, 0.1);
spawn.randomMob(8300, 2100, 0.1);
spawn.randomSmallMob(2575, -75, 0.1); //entrance
spawn.randomMob(8125, 2450, 0.1);
@@ -1855,7 +1851,7 @@ const level = {
spawn.randomSmallMob(1100, -300, 0.2); //entrance
spawn.randomMob(4450, 2500, 0.2);
spawn.randomMob(6350, 2525, 0.2);
- spawn.randomBoss(9200, 2400, 0.3);
+ spawn.randomGroup(9200, 2400, 0.3);
spawn.randomSmallMob(1900, -250, 0.3); //entrance
spawn.randomMob(1500, 2100, 0.4);
spawn.randomSmallMob(1700, -150, 0.4); //entrance
@@ -1868,12 +1864,11 @@ const level = {
spawn.randomMob(3600, 1725, 0.9);
spawn.randomMob(4100, 1225, 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", "historyBoss"]);
powerUps.addRerollToLevel() //needs to run after mobs are spawned
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(7725, 2275);
},
satellite() {
- level.bossKilled = false; // if a boss needs to be killed
const elevator = level.platform(4210, -1325, 380, 30, -10)
level.custom = () => {
level.playerExitCheck();
@@ -2058,13 +2053,13 @@ const level = {
spawn.randomMob(2000, -2800, 0.4);
spawn.randomMob(2200, -500, 0.4);
spawn.randomMob(4475, -3550, 0.3);
- spawn.randomBoss(5000, -2150, 1);
- spawn.randomBoss(3700, -4100, 0.3);
- spawn.randomBoss(2700, -1600, 0.1);
- spawn.randomBoss(1600, -100, 0);
- spawn.randomBoss(5000, -3900, -0.3);
+ spawn.randomGroup(5000, -2150, 1);
+ spawn.randomGroup(3700, -4100, 0.3);
+ spawn.randomGroup(2700, -1600, 0.1);
+ spawn.randomGroup(1600, -100, 0);
+ spawn.randomGroup(5000, -3900, -0.3);
if (simulation.difficulty > 3) {
- if (Math.random() < 0.1) {
+ if (Math.random() < 0.2) {
spawn.randomLevelBoss(2800, -1400);
} else if (Math.random() < 0.25) {
spawn.laserBoss(2900 + 300 * Math.random(), -2950 + 150 * Math.random());
@@ -2080,7 +2075,6 @@ const level = {
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(3950, -850);
},
rooftops() {
- level.bossKilled = false; // if a boss needs to be killed
const elevator = level.platform(1450, -1000, 235, 30, -2)
level.custom = () => {
ctx.fillStyle = "#ccc"
@@ -2296,15 +2290,14 @@ const level = {
spawn.randomMob(5200, -100, 0.3);
spawn.randomMob(5275, -900, 0.2);
spawn.randomMob(900, -2125, 0.3);
- spawn.randomBoss(600, -1575, 0);
- spawn.randomBoss(2225, -1325, 0.4);
- spawn.randomBoss(4900, -1200, 0);
+ spawn.randomGroup(600, -1575, 0);
+ spawn.randomGroup(2225, -1325, 0.4);
+ spawn.randomGroup(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() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(2175, -2425);
},
aerie() {
- level.bossKilled = false; // if a boss needs to be killed
// const elevator = level.platform(4112, -2300, 280, 50)
// simulation.g = 0.0012 //0.0024
level.custom = () => {
@@ -2446,7 +2439,7 @@ const level = {
spawn.mapRect(4250, -3700, 50, 300);
spawn.mapRect(3700, -3250, 1100, 100);
- spawn.randomBoss(350, -500, 1)
+ spawn.randomGroup(350, -500, 1)
spawn.randomSmallMob(-225, 25);
spawn.randomSmallMob(1000, -1100);
spawn.randomSmallMob(4000, -250);
@@ -2465,8 +2458,8 @@ const level = {
spawn.randomMob(1700, -50, 0.3)
spawn.randomMob(2350, -900, 0.3)
spawn.randomMob(4700, -150, 0.2);
- spawn.randomBoss(4000, -350, 0.6);
- spawn.randomBoss(2750, -550, 0.1);
+ spawn.randomGroup(4000, -350, 0.6);
+ spawn.randomGroup(2750, -550, 0.1);
spawn.randomMob(2175, -925, 0.5);
spawn.randomMob(2750, 100, 0.5);
spawn.randomMob(4250, -1725, 0.5);
@@ -2486,8 +2479,8 @@ const level = {
});
World.add(engine.world, cons[cons.length - 1]);
- if (simulation.difficulty > 4) spawn.nodeBoss(4250, 0, "spawns", 8, 20, 105); //chance to spawn a ring of exploding mobs around this boss
- } else if (Math.random() < 0.15) {
+ if (simulation.difficulty > 4) spawn.nodeGroup(4250, 0, "spawns", 8, 20, 105); //chance to spawn a ring of exploding mobs around this boss
+ } else if (Math.random() < 0.2) {
spawn.randomLevelBoss(4250, -250);
spawn.debris(-250, 50, 1650, 2); //16 debris per level
spawn.debris(2475, 0, 750, 2); //16 debris per level
@@ -2514,7 +2507,6 @@ const level = {
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(5350, -325);
},
skyscrapers() {
- level.bossKilled = false; // if a boss needs to be killed
level.custom = () => {
level.playerExitCheck();
};
@@ -2669,14 +2661,13 @@ const level = {
spawn.randomMob(2200, -600, 0.2);
spawn.randomMob(850, -1300, 0.25);
spawn.randomMob(-100, -900, -0.2);
- spawn.randomBoss(3700, -1500, 0.4);
- spawn.randomBoss(1700, -900, 0.4);
+ spawn.randomGroup(3700, -1500, 0.4);
+ spawn.randomGroup(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() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(3075, -2050);
},
highrise() {
- level.bossKilled = false; // if a boss needs to be killed
level.custom = () => {
level.playerExitCheck();
};
@@ -2868,15 +2859,14 @@ const level = {
spawn.randomMob(-125, -1500, -0.1);
spawn.randomMob(-325, -1900, -0.1);
spawn.randomMob(-550, -100, -0.1);
- spawn.randomBoss(-3250, -2700, 0.2);
- spawn.randomBoss(-2450, -1100, 0);
+ spawn.randomGroup(-3250, -2700, 0.2);
+ spawn.randomGroup(-2450, -1100, 0);
if (simulation.difficulty > 3) spawn.randomLevelBoss(-2400, -3000);
powerUps.addRerollToLevel() //needs to run after mobs are spawned
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(-1825, -1975);
},
warehouse() {
- level.bossKilled = false; // if a boss needs to be killed
level.custom = () => {
level.playerExitCheck();
};
@@ -3037,9 +3027,9 @@ const level = {
spawn.randomMob(475, 300, 0);
spawn.randomMob(-75, -700, 0);
spawn.randomMob(900, -200, -0.1);
- spawn.randomBoss(-125, 275, -0.2);
- spawn.randomBoss(-825, 1000, 0.2);
- spawn.randomBoss(-1300, -1100, -0.3);
+ spawn.randomGroup(-125, 275, -0.2);
+ spawn.randomGroup(-825, 1000, 0.2);
+ spawn.randomGroup(-1300, -1100, -0.3);
if (simulation.difficulty > 3) {
if (Math.random() < 0.25) {
@@ -3069,7 +3059,7 @@ const level = {
color: "#dff"
});
} else { //reverse direction, start in bottom right
- button = level.button(4300, 0)
+ button = level.button(3800, 0)
door = level.door(3012, -200, 25, 200, 195)
level.setPosToSpawn(3250, -550); //normal spawn
level.exit.x = 1375;
@@ -3220,11 +3210,11 @@ const level = {
spawn.randomMob(450, -225, 0.15);
spawn.randomMob(100, -1200, 1);
spawn.randomMob(950, -1150, -0.1);
- spawn.randomBoss(1800, -800, -0.2);
- spawn.randomBoss(4150, -1000, 0.6);
+ spawn.randomGroup(1800, -800, -0.2);
+ spawn.randomGroup(4150, -1000, 0.6);
if (simulation.difficulty > 3) {
- if (Math.random() < 0.65) {
+ if (Math.random() < 0.5) {
// tether ball
level.fillBG.push({
x: 2495,
@@ -3244,7 +3234,7 @@ const level = {
});
World.add(engine.world, cons[cons.length - 1]);
//chance to spawn a ring of exploding mobs around this boss
- if (simulation.difficulty > 6) spawn.nodeBoss(2850, -80, "spawns", 8, 20, 105);
+ if (simulation.difficulty > 6) spawn.nodeGroup(2850, -80, "spawns", 8, 20, 105);
} else {
spawn.randomLevelBoss(2200, -450)
}
@@ -3483,9 +3473,9 @@ const level = {
spawn.randomMob(3050, -1650, 0.8);
spawn.randomMob(3350, -600, 0.8);
spawn.randomMob(4400, -50, 1);
- spawn.randomBoss(1500, -1900, 0.5);
- spawn.randomBoss(2350, -850, 1);
- spawn.randomBoss(100, -450, 0.9);
+ spawn.randomGroup(1500, -1900, 0.5);
+ spawn.randomGroup(2350, -850, 1);
+ spawn.randomGroup(100, -450, 0.9);
if (simulation.difficulty > 3) spawn.randomLevelBoss(1850, -1400);
powerUps.addRerollToLevel() //needs to run after mobs are spawned
@@ -3719,7 +3709,7 @@ const level = {
stiffness: 0.00006
});
World.add(engine.world, cons[cons.length - 1]);
- if (simulation.difficulty > 4) spawn.nodeBoss(7000, -3300, "spawns", 8, 20, 105);
+ if (simulation.difficulty > 4) spawn.nodeGroup(7000, -3300, "spawns", 8, 20, 105);
} else if (simulation.difficulty > 3) {
spawn.randomLevelBoss(6100, -3600, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss"]);
}
@@ -3738,7 +3728,7 @@ const level = {
stiffness: 0.00036
});
World.add(engine.world, cons[cons.length - 1]);
- if (simulation.difficulty > 4) spawn.nodeBoss(2350, -1300, "spawns", 8, 20, 105);
+ if (simulation.difficulty > 4) spawn.nodeGroup(2350, -1300, "spawns", 8, 20, 105);
} else if (simulation.difficulty > 3) {
spawn.randomLevelBoss(2300, -1400, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "snakeBoss"]);
}
@@ -3765,10 +3755,10 @@ const level = {
spawn.randomMob(800, 1200, 0.3);
spawn.randomMob(7200, -4000, 0.3);
spawn.randomMob(250, -1550, 0.3);
- spawn.randomBoss(900, -1450, 0.3);
- spawn.randomBoss(2980, -400, 0.3);
- spawn.randomBoss(5750, -3860, 0.4);
- spawn.randomBoss(1130, 1300, 0.1);
+ spawn.randomGroup(900, -1450, 0.3);
+ spawn.randomGroup(2980, -400, 0.3);
+ spawn.randomGroup(5750, -3860, 0.4);
+ spawn.randomGroup(1130, 1300, 0.1);
powerUps.addRerollToLevel() //needs to run after mobs are spawned
powerUps.spawn(1900, -940, "heal");
powerUps.spawn(3000, -230, "heal");
@@ -3815,7 +3805,7 @@ const level = {
});
World.add(engine.world, cons[cons.length - 1]);
//chance to spawn a ring of exploding mobs around this boss
- if (simulation.difficulty > 4) spawn.nodeBoss(2330, 1850, "spawns", 8, 20, 105);
+ if (simulation.difficulty > 4) spawn.nodeGroup(2330, 1850, "spawns", 8, 20, 105);
powerUps.chooseRandomPowerUp(3100, 1630);
},
detours() {
@@ -3958,7 +3948,7 @@ const level = {
spawn.randomSmallMob(2800, -1620, 0.7);
spawn.randomMob(2400, -1370, 0.5);
spawn.randomMob(3725, -1320, 0.3);
- spawn.randomBoss(2115, -2020, 0.1)
+ spawn.randomGroup(2115, -2020, 0.1)
powerUps.spawn(5000, -1275, "heal");
@@ -4078,7 +4068,7 @@ const level = {
spawn.randomMob(1500, -270, 0.2);
spawn.randomMob(1250, 55, 0.2);
spawn.randomMob(8800, -45, 0.2);
- spawn.randomBoss(8025, -845, 0.2);
+ spawn.randomGroup(8025, -845, 0.2);
if (simulation.difficulty > 2) {
if (Math.random() < 0.2) {
@@ -4099,7 +4089,7 @@ const level = {
stiffness: 0.00015
});
World.add(engine.world, cons[cons.length - 1]);
- if (simulation.difficulty > 4) spawn.nodeBoss(8000, 630, "spawns", 8, 20, 105);
+ if (simulation.difficulty > 4) spawn.nodeGroup(8000, 630, "spawns", 8, 20, 105);
} else {
spawn.randomLevelBoss(8000, 630, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "bomberBoss"]);
let me = mob[mob.length - 1];
@@ -4664,16 +4654,16 @@ const level = {
spawn.randomMob(3965, -1650, 0.6)
spawn.randomMob(4650, -1750, 0.6);
spawn.randomMob(830, -1170, 0.5);
- spawn.randomBoss(3730, -1100, 0.5);
+ spawn.randomGroup(3730, -1100, 0.5);
spawn.randomMob(2650, -2250, 0.3);
spawn.randomMob(1615, -2270, 0.3);
spawn.randomMob(1380, -1280, 0.25);
spawn.randomMob(2280, -650, 0.2);
- spawn.randomBoss(2450, -2650, 0.2);
+ spawn.randomGroup(2450, -2650, 0.2);
spawn.randomMob(3800, -580, 0.2);
spawn.randomMob(4630, -425, 0.1);
- spawn.randomBoss(630, -1300, -0.1);
- spawn.randomBoss(3450, -2880, -0.2)
+ spawn.randomGroup(630, -1300, -0.1);
+ spawn.randomGroup(3450, -2880, -0.2)
if (simulation.difficulty > 3) {
if (Math.random() < 0.16) {
@@ -4687,7 +4677,7 @@ const level = {
stiffness: 0.00018 + 0.000007 * level.levelsCleared
});
World.add(engine.world, cons[cons.length - 1]);
- if (simulation.difficulty > 4) spawn.nodeBoss(3380, -1775, "spawns", 8, 20, 105); //chance to spawn a ring of exploding mobs around this boss
+ if (simulation.difficulty > 4) spawn.nodeGroup(3380, -1775, "spawns", 8, 20, 105); //chance to spawn a ring of exploding mobs around this boss
} else {
spawn.randomLevelBoss(3100, -1850, ["shooterBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "snakeBoss", "laserBoss"]);
diff --git a/js/lore.js b/js/lore.js
index ea4a360..7b3c52b 100644
--- a/js/lore.js
+++ b/js/lore.js
@@ -128,14 +128,12 @@ const lore = {
requestAnimationFrame(cycle);
}, delay);
},
- // () => {
- // let delay = 2000
- // setTimeout(() => { lore.miriam.text("testing speech generation for lore level", true) }, delay);
- // delay += 2200
- // setTimeout(() => { lore.anand.text("well, I'm also testing speech synthesis. Do you think it sounds good?", true) }, delay);
- // delay += 4600
- // setTimeout(() => { lore.miriam.text("I guess it's fine.", true) }, delay);
- // },
+ () => {
+ let delay = 6000
+ setTimeout(() => { lore.miriam.text("I've never seen it generate this level before.", true) }, delay);
+ delay += 2700
+
+ },
],
dialogue: [
``,
diff --git a/js/mob.js b/js/mob.js
index 4f33077..9f33f1b 100644
--- a/js/mob.js
+++ b/js/mob.js
@@ -410,7 +410,7 @@ const mobs = {
// }
// },
laserBeam() {
- if (simulation.cycle % 7 && this.seePlayer.yes) {
+ if (this.seePlayer.yes) {
ctx.setLineDash([125 * Math.random(), 125 * Math.random()]);
// ctx.lineDashOffset = 6*(simulation.cycle % 215);
if (this.distanceToPlayer() < this.laserRange) {
diff --git a/js/player.js b/js/player.js
index 54ec8d5..a168577 100644
--- a/js/player.js
+++ b/js/player.js
@@ -638,9 +638,7 @@ const m = {
tech.isDeathAvoidedThisLevel = true
powerUps.research.changeRerolls(-1)
simulation.makeTextLog(`m.research--
${powerUps.research.count}`)
- for (let i = 0; i < 6; i++) {
- powerUps.spawn(m.pos.x, m.pos.y, "heal", false);
- }
+ for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x, m.pos.y, "heal", false);
m.energy = m.maxEnergy
m.immuneCycle = m.cycle + 360 //disable this.immuneCycle bonus seconds
simulation.wipe = function() { //set wipe to have trails
@@ -1170,14 +1168,12 @@ const m = {
},
pushMass(who) {
const speed = Vector.magnitude(Vector.sub(who.velocity, player.velocity))
- const fieldBlockCost = (0.03 + Math.sqrt(who.mass) * speed * 0.003) * m.fieldShieldingScale;
+ const fieldBlockCost = (0.025 + Math.sqrt(who.mass) * speed * 0.002) * m.fieldShieldingScale;
const unit = Vector.normalise(Vector.sub(player.position, who.position))
if (m.energy > fieldBlockCost * 0.2) { //shield needs at least some of the cost to block
m.energy -= fieldBlockCost
- if (m.energy < 0) {
- m.energy = 0;
- }
+ if (m.energy < 0) m.energy = 0;
// if (m.energy > m.maxEnergy) m.energy = m.maxEnergy;
if (tech.blockDmg) {
@@ -1396,11 +1392,11 @@ const m = {
},
{
name: "standing wave harmonics",
- description: "3 oscillating shields are permanently active
blocking drains energy with no cool down
reduce harm by 15%",
+ description: "3 oscillating shields are permanently active
blocking drains energy with no cool down
reduce harm by 20%",
effect: () => {
// m.fieldHarmReduction = 0.80;
m.fieldBlockCD = 0;
- m.fieldHarmReduction = 0.85;
+ m.fieldHarmReduction = 0.8;
m.hold = function() {
if (m.isHolding) {
m.drawHold(m.holdingTarget);
@@ -1554,13 +1550,13 @@ const m = {
},
{
name: "negative mass field",
- description: "use energy to nullify gravity
reduce harm by 45%
blocks held by the field have a lower mass",
+ description: "use energy to nullify gravity
reduce harm by 50%
blocks held by the field have a lower mass",
fieldDrawRadius: 0,
effect: () => {
m.fieldFire = true;
m.holdingMassScale = 0.03; //can hold heavier blocks with lower cost to jumping
m.fieldMeterColor = "#000"
- m.fieldHarmReduction = 0.55;
+ m.fieldHarmReduction = 0.5;
m.fieldDrawRadius = 0;
m.hold = function() {
diff --git a/js/powerup.js b/js/powerup.js
index e9037b1..ac81a12 100644
--- a/js/powerup.js
+++ b/js/powerup.js
@@ -38,13 +38,15 @@ const powerUps = {
if (isCanceled) {
if (tech.isCancelDuplication) tech.cancelCount++
if (tech.isCancelRerolls) {
- let spawnType = (m.health < 0.25 || tech.isEnergyNoAmmo) ? "heal" : "ammo"
- if (Math.random() < 0.33) {
- spawnType = "heal"
- } else if (Math.random() < 0.5 && !tech.isSuperDeterminism) {
- spawnType = "research"
+ for (let i = 0; i < 6; i++) {
+ let spawnType = (m.health < 0.25 || tech.isEnergyNoAmmo) ? "heal" : "ammo"
+ if (Math.random() < 0.33) {
+ spawnType = "heal"
+ } else if (Math.random() < 0.5 && !tech.isSuperDeterminism) {
+ spawnType = "research"
+ }
+ powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), spawnType, false);
}
- for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), spawnType, false);
}
if (tech.isBanish && type === 'tech') { // banish researched tech by adding them to the list of banished tech
const banishLength = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
@@ -469,7 +471,7 @@ const powerUps = {
if (tech.isTechDamage && who.name === "tech") m.damage(0.11)
if (tech.isMassEnergy) m.energy += 2.5;
if (tech.isMineDrop) {
- if (tech.isLaserMine) { //laser mine
+ if (tech.isLaserMine) {
b.laserMine(who.position)
} else {
b.mine(who.position, { x: 0, y: 0 }, 0, tech.isMineAmmoBack)
@@ -498,7 +500,7 @@ const powerUps = {
powerUps.spawn(x, y, "gun");
return;
}
- if (Math.random() < 0.0027 * (25 - tech.totalCount)) { //a new tech has a low chance for each not acquired tech up to 15
+ if (Math.random() < 0.0027 * (25 - tech.totalCount)) { //a new tech has a low chance for each not acquired tech up to 25
powerUps.spawn(x, y, "tech");
return;
}
@@ -559,10 +561,8 @@ const powerUps = {
if (level.levelsCleared > 1) powerUps.spawn(x, y, "tech")
//bonus power ups for clearing runs in the last game
- if (level.levelsCleared === 0 && !simulation.isCheating) {
- for (let i = 0; i < localSettings.levelsClearedLastGame / 4 - 1; i++) {
- powerUps.spawn(m.pos.x, m.pos.y, "tech", false); //spawn a tech for levels cleared in last game
- }
+ if (level.levelsCleared === 0 && !simulation.isCheating && localSettings.levelsClearedLastGame > 1) {
+ for (let i = 0; i < localSettings.levelsClearedLastGame / 3; i++) powerUps.spawn(m.pos.x, m.pos.y, "tech", false); //spawn a tech for levels cleared in last game
localSettings.levelsClearedLastGame = 0 //after getting bonus power ups reset run history
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
}
diff --git a/js/spawn.js b/js/spawn.js
index 9ea18ce..faff7a6 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -21,7 +21,7 @@ const spawn = {
"ghoster",
"sneaker",
],
- allowedBossList: ["chaser", "spinner", "striker", "springer", "laser", "focuser", "beamer", "exploder", "spawner", "shooter", "launcher", "stabber", "sniper"],
+ allowedGroupList: ["chaser", "spinner", "striker", "springer", "laser", "focuser", "beamer", "exploder", "spawner", "shooter", "launcher", "stabber", "sniper"],
setSpawnList() { //this is run at the start of each new level to determine the possible mobs for the level
//each level has 2 mobs: one new mob and one from the last level
spawn.pickList.splice(0, 1);
@@ -47,41 +47,41 @@ const spawn = {
}
}
},
- randomBoss(x, y, chance = 1) {
+ randomGroup(x, y, chance = 1) {
if (spawn.spawnChance(chance) && simulation.difficulty > 2 || chance == Infinity) {
//choose from the possible picklist
let pick = this.pickList[Math.floor(Math.random() * this.pickList.length)];
- //is the pick able to be a boss?
- let canBeBoss = false;
- for (let i = 0, len = this.allowedBossList.length; i < len; ++i) {
- if (this.allowedBossList[i] === pick) {
- canBeBoss = true;
+ //is the pick able to be a group?
+ let canBeGroup = false;
+ for (let i = 0, len = this.allowedGroupList.length; i < len; ++i) {
+ if (this.allowedGroupList[i] === pick) {
+ canBeGroup = true;
break;
}
}
- if (canBeBoss) {
+ if (canBeGroup) {
if (Math.random() < 0.55) {
- this.nodeBoss(x, y, pick);
+ this.nodeGroup(x, y, pick);
} else {
- this.lineBoss(x, y, pick);
+ this.lineGroup(x, y, pick);
}
} else {
if (Math.random() < 0.07) {
this[pick](x, y, 90 + Math.random() * 40); //one extra large mob
} else if (Math.random() < 0.35) {
- this.groupBoss(x, y) //hidden grouping blocks
+ this.blockGroup(x, y) //hidden grouping blocks
} else {
pick = (Math.random() < 0.5) ? "randomList" : "random";
if (Math.random() < 0.55) {
- this.nodeBoss(x, y, pick);
+ this.nodeGroup(x, y, pick);
} else {
- this.lineBoss(x, y, pick);
+ this.lineGroup(x, y, pick);
}
}
}
}
},
- randomLevelBoss(x, y, options = ["shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss", "snakeBoss", "streamBoss"]) {
+ randomLevelBoss(x, y, options = ["historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss", "snakeBoss", "streamBoss"]) {
// other bosses: suckerBoss, laserBoss, tetherBoss, //all need a particular level to work so they are not included
spawn[options[Math.floor(Math.random() * options.length)]](x, y)
},
@@ -297,7 +297,7 @@ const spawn = {
//when player is inside event horizon
if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) {
if (m.energy > 0) m.energy -= 0.01
- if (m.energy < 0.15) {
+ if (m.energy < 0.15 && m.immuneCycle < m.cycle) {
m.damage(0.0004 * simulation.dmgScale);
}
const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x);
@@ -443,7 +443,7 @@ const spawn = {
}
}
},
- groupBoss(x, y, num = 3 + Math.random() * 8) {
+ blockGroup(x, y, num = 3 + Math.random() * 8) {
for (let i = 0; i < num; i++) {
const radius = 25 + Math.floor(Math.random() * 20)
spawn.grouper(x + Math.random() * radius, y + Math.random() * radius, radius);
@@ -875,7 +875,7 @@ const spawn = {
//when player is inside event horizon
if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) {
if (m.energy > 0) m.energy -= 0.004
- if (m.energy < 0.1) {
+ if (m.energy < 0.1 && m.immuneCycle < m.cycle) {
m.damage(0.00015 * simulation.dmgScale);
}
const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x);
@@ -981,7 +981,7 @@ const spawn = {
//when player is inside event horizon
if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) {
if (m.energy > 0) m.energy -= 0.006
- if (m.energy < 0.1) {
+ if (m.energy < 0.1 && m.immuneCycle < m.cycle) {
m.damage(0.0002 * simulation.dmgScale);
}
const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x);
@@ -1065,7 +1065,7 @@ const spawn = {
const nodes = 6
const angle = 2 * Math.PI / nodes
- spawn.allowShields = false; //don't want shields on individual boss mobs
+ spawn.allowShields = false; //don't want shields on individual mobs
for (let i = 0; i < nodes; ++i) {
spawn.stabber(x + sideLength * Math.sin(i * angle), y + sideLength * Math.cos(i * angle), radius, 12);
@@ -1086,7 +1086,7 @@ const spawn = {
World.add(engine.world, consBB[consBB.length - 1]);
}
//spawn shield around all nodes
- spawn.bossShield(targets, x, y, sideLength + 1 * radius + nodes * 5 - 25);
+ spawn.groupShield(targets, x, y, sideLength + 1 * radius + nodes * 5 - 25);
spawn.allowShields = true;
},
timeSkipBoss(x, y, radius = 55) {
@@ -1185,10 +1185,96 @@ const spawn = {
this.checkStatus();
this.attraction();
this.repulsion();
- //laser beam
this.laserBeam();
};
},
+ historyBoss(x, y, radius = 30) {
+ if (tech.dynamoBotCount > 0) {
+ spawn.randomLevelBoss(x, y, ["cellBossCulture", "bomberBoss", "powerUpBoss"])
+ return
+ }
+ mobs.spawn(x, y, 0, radius, "transparent");
+ let me = mob[mob.length - 1];
+ Matter.Body.setDensity(me, 0.3); //extra dense //normal is 0.001
+ me.laserRange = 550;
+ me.seeAtDistance2 = 2000000;
+ me.showHealthBar = false; //drawn in this.awake
+ me.delayLimit = 60 + Math.floor(60 * Math.random());
+ me.followDelay = 600 - Math.floor(60 * Math.random())
+ me.stroke = "transparent"; //used for drawGhost
+ me.collisionFilter.mask = cat.bullet
+ me.memory = Infinity
+ me.onDeath = function() {
+ powerUps.spawnBossPowerUp(this.position.x, this.position.y)
+ };
+ me.awake = function() {
+ this.checkStatus();
+
+ //health bar needs to be here because the position is being set
+ const h = this.radius * 0.3;
+ const w = this.radius * 2;
+ const x = this.position.x - w / 2;
+ const y = this.position.y - w * 0.7;
+ ctx.fillStyle = "rgba(100, 100, 100, 0.3)";
+ ctx.fillRect(x, y, w, h);
+ ctx.fillStyle = "rgba(150,0,255,0.7)";
+ ctx.fillRect(x, y, w * this.health, h);
+
+ //draw eye
+ const unit = Vector.normalise(Vector.sub(m.pos, this.position))
+ const eye = Vector.add(Vector.mult(unit, 15), this.position)
+ ctx.beginPath();
+ ctx.arc(eye.x, eye.y, 4, 0, 2 * Math.PI);
+ ctx.moveTo(this.position.x + 20 * unit.x, this.position.y + 20 * unit.y);
+ ctx.lineTo(this.position.x + 30 * unit.x, this.position.y + 30 * unit.y);
+ ctx.strokeStyle = this.stroke;
+ ctx.lineWidth = 2;
+ ctx.stroke();
+
+ ctx.setLineDash([125 * Math.random(), 125 * Math.random()]);
+ // ctx.lineDashOffset = 6*(simulation.cycle % 215);
+ if (this.distanceToPlayer() < this.laserRange) {
+ if (m.energy > 0.003) m.energy -= 0.003
+ if (m.immuneCycle < m.cycle && m.energy < 0.1) m.damage(0.0003 * simulation.dmgScale);
+ ctx.beginPath();
+ ctx.moveTo(eye.x, eye.y);
+ ctx.lineTo(m.pos.x, m.pos.y);
+ ctx.lineTo(m.pos.x + (Math.random() - 0.5) * 3000, m.pos.y + (Math.random() - 0.5) * 3000);
+ ctx.lineWidth = 2;
+ ctx.strokeStyle = "rgb(150,0,255)";
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.arc(m.pos.x, m.pos.y, 40, 0, 2 * Math.PI);
+ ctx.fillStyle = "rgba(150,0,255,0.15)";
+ ctx.fill();
+ }
+ ctx.beginPath();
+ ctx.arc(this.position.x, this.position.y, this.laserRange * 0.9, 0, 2 * Math.PI);
+ ctx.strokeStyle = "rgba(150,0,255,0.5)";
+ ctx.lineWidth = 1;
+ ctx.stroke();
+ ctx.setLineDash([]);
+ ctx.fillStyle = "rgba(150,0,255,0.03)";
+ ctx.fill();
+ if (!m.isBodiesAsleep && !this.isStunned && !this.isSlowed) {
+ if (this.followDelay > this.delayLimit) this.followDelay -= 0.2;
+ let history = m.history[(m.cycle - Math.floor(this.followDelay)) % 600]
+ Matter.Body.setPosition(this, { x: history.position.x, y: history.position.y - history.yOff + 24.2859 }) //bullets move with player
+ }
+ }
+
+ me.do = function() {
+ if (this.seePlayer.recall || (!(simulation.cycle % this.seePlayerFreq) && this.distanceToPlayer2() < this.seeAtDistance2 && !m.isCloak)) {
+ setTimeout(() => {
+ this.do = this.awake
+ this.stroke = "rgba(205,0,255,0.5)"
+ this.fill = "rgba(205,0,255,0.1)"
+ this.seePlayer.yes = true
+ }, 2000);
+ }
+ this.checkStatus();
+ };
+ },
focuser(x, y, radius = 30 + Math.ceil(Math.random() * 10)) {
radius = Math.ceil(radius * 0.7);
mobs.spawn(x, y, 4, radius, "rgb(0,0,255)");
@@ -2403,8 +2489,8 @@ const spawn = {
//snake tail
const nodes = Math.min(8 + Math.ceil(0.5 * simulation.difficulty), 40)
- spawn.lineBoss(x + 105, y, "snakeBody", nodes);
- //constraint boss with first 3 mobs in lineboss
+ spawn.lineGroup(x + 105, y, "snakeBody", nodes);
+ //constraint with first 3 mobs in line
consBB[consBB.length] = Constraint.create({
bodyA: mob[mob.length - nodes],
bodyB: mob[mob.length - 1 - nodes],
@@ -2520,7 +2606,7 @@ const spawn = {
};
}
},
- bossShield(targets, x, y, radius, stiffness = 0.4) {
+ groupShield(targets, x, y, radius, stiffness = 0.4) {
const nodes = targets.length
mobs.spawn(x, y, 9, radius, "rgba(220,220,255,0.9)");
let me = mob[mob.length - 1];
@@ -2532,7 +2618,7 @@ const spawn = {
me.collisionFilter.mask = cat.bullet;
for (let i = 0; i < nodes; ++i) {
mob[mob.length - i - 2].isShielded = true;
- //constrain to all mob nodes in boss
+ //constrain to all mob nodes in group
consBB[consBB.length] = Constraint.create({
bodyA: me,
bodyB: mob[mob.length - i - 2],
@@ -2567,7 +2653,7 @@ const spawn = {
//complex constrained mob templates**********************************************************************
//*******************************************************************************************************
allowShields: true,
- nodeBoss(
+ nodeGroup(
x,
y,
spawn = "striker",
@@ -2577,7 +2663,7 @@ const spawn = {
sideLength = Math.ceil(Math.random() * 100) + 70, // distance between each node mob
stiffness = Math.random() * 0.03 + 0.005
) {
- this.allowShields = false; //don't want shields on individual boss mobs
+ this.allowShields = false; //don't want shields on individual group mobs
const angle = 2 * Math.PI / nodes
let targets = []
for (let i = 0; i < nodes; ++i) {
@@ -2588,20 +2674,20 @@ const spawn = {
whoSpawn = this.pickList[Math.floor(Math.random() * this.pickList.length)];
}
this[whoSpawn](x + sideLength * Math.sin(i * angle), y + sideLength * Math.cos(i * angle), radius);
- targets.push(mob[mob.length - 1].id) //track who is in the node boss, for shields
+ targets.push(mob[mob.length - 1].id) //track who is in the group, for shields
}
if (Math.random() < 0.3) {
this.constrain2AdjacentMobs(nodes, stiffness * 2, true);
} else {
this.constrainAllMobCombos(nodes, stiffness);
}
- //spawn shield for entire boss
+ //spawn shield for entire group
if (nodes > 2 && Math.random() < 0.998) {
- this.bossShield(targets, x, y, sideLength + 2.5 * radius + nodes * 6 - 25);
+ this.groupShield(targets, x, y, sideLength + 2.5 * radius + nodes * 6 - 25);
}
this.allowShields = true;
},
- lineBoss(
+ lineGroup(
x,
y,
spawn = "striker",
@@ -2611,7 +2697,7 @@ const spawn = {
l = Math.ceil(Math.random() * 80) + 30,
stiffness = Math.random() * 0.06 + 0.01
) {
- this.allowShields = false; //don't want shields on individual boss mobs
+ this.allowShields = false; //don't want shields on individual group mobs
for (let i = 0; i < nodes; ++i) {
let whoSpawn = spawn;
if (spawn === "random") {
diff --git a/js/tech.js b/js/tech.js
index 00dd0d5..eaca70b 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -105,14 +105,14 @@ const tech = {
return dmg * tech.slowFire * tech.aimDamage
},
duplicationChance() {
- return (tech.isBayesian ? 0.2 : 0) + tech.cancelCount * 0.04 + tech.duplicateChance + m.duplicateChance
+ return (tech.isBayesian ? 0.2 : 0) + tech.cancelCount * 0.045 + tech.duplicateChance + m.duplicateChance
},
totalBots() {
return tech.dynamoBotCount + tech.foamBotCount + tech.nailBotCount + tech.laserBotCount + tech.boomBotCount + tech.orbitBotCount + tech.plasmaBotCount + tech.missileBotCount
},
tech: [{
name: "integrated armament",
- description: "increase damage by 25%
your inventory can only hold 1 gun",
+ description: `increase damage by 25%
your inventory can only hold 1 gun`,
maxCount: 1,
count: 0,
allowed() {
@@ -121,9 +121,17 @@ const tech = {
requires: "no more than 1 gun",
effect() {
tech.isOneGun = true;
+ //
+ for (let i = 0; i < tech.tech.length; i++) {
+ if (tech.tech[i].name === "CPT gun") tech.tech[i].description = `adds the CPT gun to your inventory
it rewinds your health, velocity, and position