diff --git a/.DS_Store b/.DS_Store
index d4ddd7c..906e7a9 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/js/bullet.js b/js/bullet.js
index 2edbfa6..98fd86f 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -1089,18 +1089,18 @@ const b = {
m.energy = 0;
}
b.isExtruderOn = true
- const SPEED = 10
+ const SPEED = 8
const me = bullet.length;
const where = Vector.add(m.pos, player.velocity)
bullet[me] = Bodies.polygon(where.x + 20 * Math.cos(m.angle), where.y + 20 * Math.sin(m.angle), 4, 0.01, {
cycle: -0.5,
isWave: true,
- endCycle: simulation.cycle + 10 + 40 * tech.isPlasmaRange,
+ endCycle: simulation.cycle + 35 + 45 * tech.isPlasmaRange,
inertia: Infinity,
frictionAir: 0,
isInHole: true, //this keeps the bullet from entering wormholes
minDmgSpeed: 0,
- dmg: b.dmgScale * 1.35, //damage also changes when you divide by mob.mass on in .do()
+ dmg: b.dmgScale * 1.2, //damage also changes when you divide by mob.mass on in .do()
classType: "bullet",
isBranch: false,
restitution: 0,
@@ -1121,8 +1121,8 @@ const b = {
const q = Matter.Query.point(mob, this.position)
for (let i = 0; i < q.length; i++) {
Matter.Body.setVelocity(q[i], {
- x: q[i].velocity.x * 0.6,
- y: q[i].velocity.y * 0.6
+ x: q[i].velocity.x * 0.2,
+ y: q[i].velocity.y * 0.2
});
Matter.Body.setPosition(this, Vector.add(this.position, q[i].velocity)) //move with the medium
let dmg = this.dmg / Math.min(10, q[i].mass)
@@ -2226,6 +2226,55 @@ const b = {
// ******************************** Bots *********************************************
// **************************************************************************************************
// **************************************************************************************************
+ totalBots() {
+ return tech.dynamoBotCount + tech.foamBotCount + tech.nailBotCount + tech.laserBotCount + tech.boomBotCount + tech.orbitBotCount + tech.plasmaBotCount + tech.missileBotCount
+ },
+ hasBotUpgrade() {
+ return tech.isNailBotUpgrade + tech.isFoamBotUpgrade + tech.isBoomBotUpgrade + tech.isLaserBotUpgrade + tech.isOrbitBotUpgrade + tech.isDynamoBotUpgrade
+ },
+ convertBotsTo(type) { //type can be a string like "dynamoBotCount"
+ //count all bots
+ const totalBots = b.totalBots()
+ //remove all bots techs and convert them to the new type so that tech refunds work correctly
+ let totalTechToConvert = 0 //count how many tech need to be converted
+ for (let i = 0; i < tech.tech.length; i++) {
+ if (tech.tech[i].count && tech.tech[i].isBotTech) {
+ totalTechToConvert += tech.tech[i].count
+ tech.removeTech(i)
+ }
+ }
+ console.log(totalTechToConvert)
+
+ let name = ""
+ if (type === "nailBotCount") name = "nail-bot"
+ if (type === "orbitBotCount") name = "orbital-bot"
+ if (type === "boomBotCount") name = "boom-bot"
+ if (type === "laserBotCount") name = "laser-bot"
+ if (type === "foamBotCount") name = "foam-bot"
+ if (type === "dynamoBotCount") name = "dynamo-bot"
+ if (type === "plasmaBotCount") name = "plasma-bot"
+ if (type === "missileBotCount") name = "missile-bot"
+ //spawn tech for the correct bot type
+ for (let i = 0; i < totalTechToConvert; i++) tech.giveTech(name)
+
+ //remove all bots
+ b.zeroBotCount()
+ for (let i = 0; i < bullet.length; i++) {
+ if (bullet[i].botType && bullet[i].endCycle === Infinity) bullet[i].endCycle = 0 //don't remove temp bots
+ }
+ //set all bots to type
+ tech[type] = totalBots
+ //respawn all bots
+ b.respawnBots();
+ },
+ zeroBotCount() { //remove all bots
+ tech.dynamoBotCount = 0
+ tech.laserBotCount = 0
+ tech.nailBotCount = 0
+ tech.foamBotCount = 0
+ tech.boomBotCount = 0
+ tech.orbitBotCount = 0
+ },
respawnBots() {
for (let i = 0; i < tech.dynamoBotCount; i++) b.dynamoBot({ x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, false)
for (let i = 0; i < tech.laserBotCount; i++) b.laserBot({ x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, false)
@@ -2311,61 +2360,65 @@ const b = {
// 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, player.position)) < 250) { //give energy
- Matter.Body.setAngularVelocity(this, this.spin)
- if (this.isUpgraded) {
- m.energy += 0.12
- 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.03
- 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
+ if (!m.isBodiesAsleep) {
+ if (!((m.cycle + this.phase) % 30)) { //twice a second
+ if (Vector.magnitude(Vector.sub(this.position, player.position)) < 250) { //give energy
+ Matter.Body.setAngularVelocity(this, this.spin)
+ if (this.isUpgraded) {
+ m.energy += 0.12
+ 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.03
+ simulation.drawList.push({ //add dmg to draw queue
+ x: this.position.x,
+ y: this.position.y,
+ radius: 5,
+ color: m.fieldMeterColor,
+ time: simulation.drawTime
+ });
+ }
}
- })
- for (let i = 0; i < q.length; i++) {
- Matter.Body.setAngularVelocity(this, this.spin)
- // 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
- });
}
+
+ if (!m.isCloak) { //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++) {
+ Matter.Body.setAngularVelocity(this, this.spin)
+ // 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
}
- 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
@@ -2605,7 +2658,7 @@ const b = {
}
//hit target with laser
if (this.lockedOn && this.lockedOn.alive && m.energy > this.drainThreshold) {
- m.energy -= tech.laserFieldDrain * tech.isLaserDiode
+ m.energy -= tech.laserFieldDrain * tech.isLaserDiode * 0.7
b.laser(this.vertices[0], this.lockedOn.position, b.dmgScale * (0.38 * tech.laserDamage + this.isUpgraded * 0.25), tech.laserReflections, false, 0.4) //tech.laserDamage = 0.16
// laser(where = {
// x: m.pos.x + 20 * Math.cos(m.angle),
diff --git a/js/level.js b/js/level.js
index 51e1d06..665b89f 100644
--- a/js/level.js
+++ b/js/level.js
@@ -20,7 +20,7 @@ const level = {
// tech.isExplodeRadio = true
// for (let i = 0; i < 1; i++) tech.giveTech("dynamo-bot")
// tech.giveTech("supercritical fission")
- // tech.giveTech("CPT reversal")
+ // tech.giveTech("micro-extruder")
// tech.giveTech("causality bombs")
// tech.giveTech("cardinality")
// tech.giveTech("Bayesian statistics")
@@ -110,6 +110,11 @@ const level = {
if (b.inventoryGun > b.inventory.length - 1) b.inventoryGun = 0;
simulation.switchGun();
}
+ if (tech.isSwitchReality) {
+ simulation.makeTextLog(`simulation.amplitude = ${Math.random()}`);
+ m.switchWorlds()
+ for (let i = 0; i < 2; i++) powerUps.spawn(m.pos.x + Math.random() * 10, m.pos.y + Math.random() * 10, "tech", false);
+ }
},
custom() {},
customTopLayer() {},
@@ -2503,13 +2508,14 @@ const level = {
spawn.randomMob(1725, 125, 0.5);
if (simulation.difficulty > 3) {
if (Math.random() < 0.1) { // tether ball
+ const index = mob.length
spawn.tetherBoss(4250, 0)
cons[cons.length] = Constraint.create({
pointA: {
x: 4250,
y: -675
},
- bodyB: mob[mob.length - 1],
+ bodyB: mob[index],
stiffness: 0.00007
});
World.add(engine.world, cons[cons.length - 1]);
diff --git a/js/player.js b/js/player.js
index 21eea8f..06bde88 100644
--- a/js/player.js
+++ b/js/player.js
@@ -303,106 +303,117 @@ const m = {
}
},
alive: false,
+ switchWorlds() {
+ //count tech
+ const totalGuns = b.inventory.length - tech.isRewindGun //count guns, but not CPT gun
+ simulation.isTextLogOpen = false; //prevent console spam
+ //remove all tech and count current tech total
+ let totalTech = 0;
+ for (let i = 0, len = tech.tech.length; i < len; i++) {
+ if (!tech.tech[i].isNonRefundable && tech.tech[i].name !== "quantum immortality" && tech.tech[i].name !== "many-worlds") {
+ totalTech += tech.tech[i].count
+ tech.tech[i].remove();
+ tech.tech[i].isLost = false
+ tech.tech[i].count = 0
+ }
+ }
+ lore.techCount = 0;
+ tech.removeJunkTechFromPool();
+ tech.removeLoreTechFromPool();
+ tech.addLoreTechToPool();
+ tech.armorFromPowerUps = 0;
+ tech.totalCount = 0;
+
+ //randomize health
+ m.health = 0.7 + Math.random()
+ if (m.health > 1) m.health = 1;
+ m.displayHealth();
+
+ //randomize field
+ m.setField(Math.ceil(Math.random() * (m.fieldUpgrades.length - 1)))
+
+
+ //track how ammo/ ammoPack count
+ let ammoCount = 0
+ for (let i = 0, len = b.inventory.length; i < len; i++) {
+ if (b.guns[b.inventory[i]].ammo !== Infinity) ammoCount += b.guns[b.inventory[i]].ammo / b.guns[b.inventory[i]].ammoPack
+ }
+
+ //remove all bullets
+ for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
+ bullet = [];
+ //removes guns and ammo
+ b.inventory = [];
+ b.activeGun = null;
+ b.inventoryGun = 0;
+ for (let i = 0, len = b.guns.length; i < len; ++i) {
+ b.guns[i].have = false;
+ if (b.guns[i].ammo !== Infinity) b.guns[i].ammo = 0;
+ }
+ //give random guns
+ for (let i = 0; i < totalGuns; i++) b.giveGuns()
+
+ //randomize ammo based on ammo/ammopack count
+ for (let i = 0, len = b.inventory.length; i < len; i++) {
+ if (b.guns[b.inventory[i]].ammo !== Infinity) b.guns[b.inventory[i]].ammo = Math.max(0, Math.floor(ammoCount / b.inventory.length * b.guns[b.inventory[i]].ammoPack * (1.05 + 0.5 * (Math.random() - 0.5))))
+ }
+
+ //randomize tech
+ for (let i = 0; i < totalTech; i++) {
+ //find what tech I could get
+ let options = [];
+ for (let i = 0, len = tech.tech.length; i < len; i++) {
+ if (tech.tech[i].count < tech.tech[i].maxCount &&
+ !tech.tech[i].isNonRefundable &&
+ tech.tech[i].name !== "quantum immortality" &&
+ tech.tech[i].name !== "many-worlds" &&
+ tech.tech[i].name !== "Born rule" &&
+ tech.tech[i].name !== "determinism" &&
+ tech.tech[i].allowed()
+ ) options.push(i);
+ }
+ //add a new tech from options pool
+ if (options.length > 0) tech.giveTech(options[Math.floor(Math.random() * options.length)])
+ }
+
+ simulation.makeGunHUD(); //update gun HUD
+ simulation.updateTechHUD();
+ simulation.isTextLogOpen = true;
+ },
death() {
if (tech.isImmortal) { //if player has the immortality buff, spawn on the same level with randomized damage
- simulation.isTextLogOpen = false;
- //count tech
- let totalTech = 0;
+
+ //remove immortality tech
for (let i = 0; i < tech.tech.length; i++) {
- if (!tech.tech[i].isNonRefundable) totalTech += tech.tech[i].count
- }
- if (tech.isDeterminism) totalTech -= 3 //remove the bonus tech
- if (tech.isSuperDeterminism) totalTech -= 2 //remove the bonus tech
- totalTech = totalTech * 1.15 + 1 // a few extra to make it stronger
- const totalGuns = b.inventory.length //count guns
-
- function randomizeTech() {
- for (let i = 0; i < totalTech; i++) {
- //find what tech I don't have
- let options = [];
- for (let i = 0, len = tech.tech.length; i < len; i++) {
- if (tech.tech[i].count < tech.tech[i].maxCount &&
- !tech.tech[i].isNonRefundable &&
- tech.tech[i].name !== "quantum immortality" &&
- tech.tech[i].name !== "Born rule" &&
- tech.tech[i].allowed()
- ) options.push(i);
- }
- //add a new tech
- if (options.length > 0) {
- const choose = Math.floor(Math.random() * options.length)
- let newTech = options[choose]
- tech.giveTech(newTech)
- options.splice(choose, 1);
- }
- }
- simulation.updateTechHUD();
- }
-
- function randomizeField() {
- m.setField(Math.ceil(Math.random() * (m.fieldUpgrades.length - 1)))
- }
-
- function randomizeHealth() {
- m.health = 0.7 + Math.random()
- if (m.health > 1) m.health = 1;
- m.displayHealth();
- }
-
- function randomizeGuns() {
- //removes guns and ammo
- b.inventory = [];
- b.activeGun = null;
- b.inventoryGun = 0;
- for (let i = 0, len = b.guns.length; i < len; ++i) {
- b.guns[i].have = false;
- if (b.guns[i].ammo !== Infinity) b.guns[i].ammo = 0;
- }
- //give random guns
- for (let i = 0; i < totalGuns; i++) b.giveGuns()
- //randomize ammo
- for (let i = 0, len = b.inventory.length; i < len; i++) {
- if (b.guns[b.inventory[i]].ammo !== Infinity) {
- b.guns[b.inventory[i]].ammo = Math.max(0, Math.floor(6 * b.guns[b.inventory[i]].ammo * Math.sqrt(Math.random())))
- }
- }
- simulation.makeGunHUD(); //update gun HUD
+ if (tech.tech[i].name === "quantum immortality") tech.removeTech(i)
}
simulation.wipe = function() { //set wipe to have trails
ctx.fillStyle = "rgba(255,255,255,0)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
-
- function randomizeEverything() {
- spawn.setSpawnList(); //new mob types
- simulation.clearNow = true; //triggers a map reset
-
- tech.setupAllTech(); //remove all tech
- for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
- bullet = []; //remove all bullets
- randomizeHealth()
- randomizeField()
- randomizeGuns()
- randomizeTech()
- }
-
- randomizeEverything()
+ spawn.setSpawnList(); //new mob types
+ simulation.clearNow = true; //triggers a map reset
+ m.switchWorlds()
const swapPeriod = 1000
for (let i = 0, len = 5; i < len; i++) {
setTimeout(function() {
- randomizeEverything()
+ simulation.wipe = function() { //set wipe to have trails
+ ctx.fillStyle = "rgba(255,255,255,0)";
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+ }
+ spawn.setSpawnList(); //new mob types
+ simulation.clearNow = true; //triggers a map reset
+ m.switchWorlds()
simulation.isTextLogOpen = true;
simulation.makeTextLog(`simulation.amplitude = 0.${len-i-1}`, swapPeriod);
simulation.isTextLogOpen = false;
simulation.wipe = function() { //set wipe to have trails
ctx.fillStyle = `rgba(255,255,255,${(i+1)*(i+1)*0.006})`;
ctx.fillRect(0, 0, canvas.width, canvas.height);
- // pixelWindows()
}
}, (i + 1) * swapPeriod);
}
-
setTimeout(function() {
simulation.wipe = function() { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
@@ -410,7 +421,6 @@ const m = {
simulation.isTextLogOpen = true;
simulation.makeTextLog("simulation.amplitude = null");
}, 6 * swapPeriod);
-
} else if (m.alive) { //normal death code here
m.alive = false;
simulation.paused = true;
@@ -482,7 +492,7 @@ const m = {
if (tech.isSlowFPS) dmg *= 0.8
if (tech.isPiezo) dmg *= 0.85
if (tech.isHarmReduce && m.fieldUpgrades[m.fieldMode].name === "negative mass field" && m.isFieldActive) dmg *= 0.5
- if (tech.isBotArmor) dmg *= 0.94 ** tech.totalBots()
+ if (tech.isBotArmor) dmg *= 0.94 ** b.totalBots()
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33;
if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.34
if (tech.energyRegen === 0) dmg *= 0.34
@@ -1163,7 +1173,7 @@ const m = {
//draw electricity
const step = 40
ctx.beginPath();
- for (let i = 0, len = 2.5 * tech.blockDmg; i < len; i++) {
+ for (let i = 0, len = 1.5 * tech.blockDmg; i < len; i++) {
let x = m.pos.x - 20 * unit.x;
let y = m.pos.y - 20 * unit.y;
ctx.moveTo(x, y);
@@ -1180,7 +1190,7 @@ const m = {
m.drawHold(who);
}
// if (tech.isFreezeMobs) mobs.statusSlow(who, 60) //this works but doesn't have a fun effect
-
+ if (tech.isStunField) mobs.statusStun(who, tech.isStunField)
// m.holdingTarget = null
//knock backs
if (m.fieldShieldingScale > 0) {
@@ -1202,7 +1212,6 @@ const m = {
});
}
} else {
- if (tech.isStunField && m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism") mobs.statusStun(who, tech.isStunField)
// mobs.statusSlow(who, tech.isStunField)
const massRoot = Math.sqrt(Math.max(0.15, who.mass)); // masses above 12 can start to overcome the push back
Matter.Body.setVelocity(who, {
diff --git a/js/powerup.js b/js/powerup.js
index 0115435..cdb0839 100644
--- a/js/powerup.js
+++ b/js/powerup.js
@@ -94,7 +94,7 @@ const powerUps = {
}
}
if (tech.isRerollBots) {
- const limit = 5
+ const limit = 4
for (; powerUps.research.count > limit - 1; powerUps.research.count -= limit) {
b.randomBot()
if (tech.renormalization) {
@@ -462,7 +462,7 @@ const powerUps = {
}
// console.log(powerUps.gun.choiceLog)
// console.log(choice1, choice2, choice3)
- if (tech.isOneGun) text += `
replaces your current gun
`
+ if (tech.isOneGun && b.inventory.length > 0) text += `replaces your current gun
`
document.getElementById("choose-grid").innerHTML = text
powerUps.showDraft();
} else {
diff --git a/js/simulation.js b/js/simulation.js
index 2f11300..f13a1cc 100644
--- a/js/simulation.js
+++ b/js/simulation.js
@@ -362,26 +362,6 @@ const simulation = {
b.activeGun = b.inventory[b.inventoryGun];
simulation.updateGunHUD();
simulation.boldActiveGunHUD();
- if (tech.isBotSwap) {
- //get total count
- const countPermanent = tech.dynamoBotCount + tech.laserBotCount + tech.nailBotCount + tech.foamBotCount + tech.boomBotCount + tech.orbitBotCount
- //remove all bots
- tech.dynamoBotCount = 0
- tech.laserBotCount = 0
- tech.nailBotCount = 0
- tech.foamBotCount = 0
- tech.boomBotCount = 0
- tech.orbitBotCount = 0
- for (let i = 0; i < bullet.length; i++) {
- if (bullet[i].botType && bullet[i].endCycle === Infinity) bullet[i].endCycle = 0 //don't remove temp bots
- }
- //set to a new type
- options = [() => { tech.laserBotCount = countPermanent }, () => { tech.nailBotCount = countPermanent }, () => { tech.foamBotCount = countPermanent }, () => { tech.boomBotCount = countPermanent }, () => { tech.orbitBotCount = countPermanent }, () => { tech.dynamoBotCount = countPermanent }, ]
- options[tech.botSwapCycleIndex]()
- tech.botSwapCycleIndex++
- if (tech.botSwapCycleIndex > options.length - 1) tech.botSwapCycleIndex = 0
- b.respawnBots()
- }
},
zoom: null,
zoomScale: 1000,
diff --git a/js/spawn.js b/js/spawn.js
index f42f68c..3a6c6ea 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -82,6 +82,7 @@ const spawn = {
}
}
},
+
randomLevelBoss(x, y, options = ["orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss", "snakeBoss", "streamBoss"]) {
// other bosses: suckerBoss, laserBoss, tetherBoss, //these need a particular level to work so they are not included in the random pool
spawn[options[Math.floor(Math.random() * options.length)]](x, y)
@@ -1355,7 +1356,7 @@ const spawn = {
me.isBoss = true;
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
Matter.Body.rotate(me, Math.random() * Math.PI * 2);
- me.accelMag = 0.00022 * Math.sqrt(simulation.accelScale);
+ me.accelMag = 0.00018 * Math.sqrt(simulation.accelScale);
me.seePlayerFreq = Math.floor(30 * simulation.lookFreqScale);
me.memory = 420;
me.restitution = 1;
@@ -1467,7 +1468,7 @@ const spawn = {
// hitting player
if (best.who === player) {
if (m.immuneCycle < m.cycle) {
- const dmg = 0.001 * simulation.dmgScale;
+ const dmg = 0.002 * simulation.dmgScale;
m.damage(dmg);
//draw damage
ctx.fillStyle = color;
@@ -1477,9 +1478,7 @@ const spawn = {
}
}
//draw beam
- if (best.dist2 === Infinity) {
- best = look;
- }
+ if (best.dist2 === Infinity) best = look;
ctx.beginPath();
ctx.moveTo(this.vertices[1].x, this.vertices[1].y);
ctx.lineTo(best.x, best.y);
@@ -1948,11 +1947,20 @@ const spawn = {
me.frictionStatic = 0;
me.friction = 0;
me.frictionAir = 0.01;
+ me.memory = Infinity;
// me.memory = 300;
// Matter.Body.setDensity(me, 0.0015); //extra dense //normal is 0.001
me.collisionFilter.mask = cat.player | cat.bullet
spawn.shield(me, x, y, 1);
- spawn.spawnOrbitals(me, radius + 150 + 250 * Math.random(), 1)
+
+
+ const len = Math.floor(Math.min(15, 3 + Math.sqrt(simulation.difficulty))) // simulation.difficulty = 40 on hard mode level 10
+ const speed = (0.007 + 0.003 * Math.random() + 0.004 * Math.sqrt(simulation.difficulty))
+ let radiusOrbitals = radius + 125 + 350 * Math.random()
+ for (let i = 0; i < len; i++) spawn.orbital(me, radiusOrbitals, i / len * 2 * Math.PI, speed)
+ radiusOrbitals = radius + 125 + 350 * Math.random()
+ for (let i = 0; i < len; i++) spawn.orbital(me, radiusOrbitals, i / len * 2 * Math.PI, -speed)
+
me.onDeath = function() {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
};
@@ -2570,8 +2578,8 @@ const spawn = {
me.memory = 20;
Matter.Body.setDensity(me, 0.001 + 0.0005 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
spawn.shield(me, x, y, 1);
- spawn.spawnOrbitals(me, radius + 50 + 200 * Math.random())
+ setTimeout(() => { spawn.spawnOrbitals(me, radius + 50 + 200 * Math.random()) }, 100); //have to wait a sec so the tether constraint doesn't attach to an orbital
me.onDeath = function() {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
this.removeCons(); //remove constraint
@@ -2677,7 +2685,7 @@ const spawn = {
},
orbital(who, radius, phase, speed) {
// for (let i = 0, len = 7; i < len; i++) spawn.orbital(me, radius + 250, 2 * Math.PI / len * i)
- mobs.spawn(0, 0, 8, 12, "rgb(255,0,150)");
+ mobs.spawn(who.position.x, who.position.y, 8, 12, "rgb(255,0,150)");
let me = mob[mob.length - 1];
me.stroke = "transparent";
// Matter.Body.setDensity(me, 0.00004); //normal is 0.001
@@ -2701,11 +2709,10 @@ const spawn = {
}
Matter.Body.setPosition(this, Vector.add(who.position, Vector.mult(orbit, radius))) //bullets move with player
//damage player
- if (Matter.Query.collides(this, [player]).length > 0) {
- m.damage(0.1 * simulation.dmgScale);
+ if (Matter.Query.collides(this, [player]).length > 0 && !m.isCloak) {
+ m.damage(0.035 * simulation.dmgScale);
this.death();
}
-
};
},
orbitalBoss(x, y, radius = 88) {
diff --git a/js/tech.js b/js/tech.js
index fbdc75d..4c7c1f5 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -46,7 +46,7 @@
tech.junk[index].numberInPool++
tech.tech.push(Object.assign({}, tech.junk[index])) // push a "clone" of the tech.junk into the pool
- if (tech.junk[index].numberInPool > 1) tech.tech[tech.tech.length - 1].name += `(${tech.junk[index].numberInPool})` //give it a unique name so it can be found
+ if (tech.junk[index].numberInPool > 1) tech.tech[tech.tech.length - 1].name += ` - ${(tech.junk[index].numberInPool + 9).toString(36)}` //give it a unique name so it can be found
}
},
removeJunkTechFromPool() {
@@ -127,7 +127,7 @@
if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.25
if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2
if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.4, player.speed * 0.013)
- if (tech.isBotDamage) dmg *= 1 + 0.06 * tech.totalBots()
+ if (tech.isBotDamage) dmg *= 1 + 0.06 * b.totalBots()
return dmg * tech.slowFire * tech.aimDamage
},
duplicationChance() {
@@ -144,9 +144,6 @@
spawn.randomLevelBoss(m.pos.x, m.pos.y - range, bossOptions);
}
},
- 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`,
@@ -158,7 +155,6 @@
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
replaces your current gun
`
}
@@ -710,7 +706,7 @@
maxCount: 1,
count: 0,
allowed() {
- return (tech.totalBots() > 1 || tech.haveGunCheck("drones") || tech.haveGunCheck("mine") || tech.haveGunCheck("spores") || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing") && !tech.isEnergyHealth
+ return (b.totalBots() > 1 || tech.haveGunCheck("drones") || tech.haveGunCheck("mine") || tech.haveGunCheck("spores") || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing") && !tech.isEnergyHealth
},
requires: "drones, spores, mines, or bots",
effect() {
@@ -742,7 +738,7 @@
maxCount: 3,
count: 0,
allowed() {
- return tech.totalBots() > 0 && !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.isExplodeMob
+ return b.totalBots() > 0 && !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.isExplodeMob
},
requires: "a bot and no other mob death tech",
effect() {
@@ -757,6 +753,7 @@
description: "a bot fires nails at mobs in line of sight",
maxCount: 9,
count: 0,
+ isBotTech: true,
allowed() {
return true
},
@@ -771,15 +768,16 @@
},
{
name: "nail-bot upgrade",
- description: "500% increased fire rate
applies to all current and future nail-bots",
+ description: "convert all your permanent bots to nail-bots
500% increased nail-bot fire rate",
maxCount: 1,
count: 0,
allowed() {
- return tech.nailBotCount > 1
+ return tech.nailBotCount > 1 && !b.hasBotUpgrade()
},
- requires: "2 or more nail bots",
+ requires: "2 or more nail bots and only 1 bot upgrade",
effect() {
tech.isNailBotUpgrade = true
+ b.convertBotsTo("nailBotCount")
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'nail') bullet[i].isUpgraded = true
}
@@ -796,6 +794,7 @@
description: "a bot fires foam at nearby mobs",
maxCount: 9,
count: 0,
+ isBotTech: true,
allowed() {
return true
},
@@ -810,15 +809,16 @@
},
{
name: "foam-bot upgrade",
- description: "250% increased foam size and fire rate
applies to all current and future foam-bots",
+ description: "convert all your permanent bots to foam-bots
250% increased foam-bot size and fire rate",
maxCount: 1,
count: 0,
allowed() {
- return tech.foamBotCount > 1
+ return tech.foamBotCount > 1 && !b.hasBotUpgrade()
},
- requires: "2 or more foam bots",
+ requires: "2 or more foam bots and only 1 bot upgrade",
effect() {
tech.isFoamBotUpgrade = true
+ b.convertBotsTo("foamBotCount")
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'foam') bullet[i].isUpgraded = true
}
@@ -835,6 +835,7 @@
description: "a bot defends the space around you
ignites an explosion after hitting a mob",
maxCount: 9,
count: 0,
+ isBotTech: true,
allowed() {
return true
},
@@ -849,15 +850,16 @@
},
{
name: "boom-bot upgrade",
- description: "250% increased explosion damage and size
applies to all current and future boom-bots",
+ description: "convert all your permanent bots to boom-bots
250% increased explosion damage and size",
maxCount: 1,
count: 0,
allowed() {
- return tech.boomBotCount > 1
+ return tech.boomBotCount > 1 && !b.hasBotUpgrade()
},
- requires: "2 or more boom bots",
+ requires: "2 or more boom bots and only 1 bot upgrade",
effect() {
tech.isBoomBotUpgrade = true
+ b.convertBotsTo("boomBotCount")
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'boom') bullet[i].isUpgraded = true
}
@@ -874,6 +876,7 @@
description: "a bot uses energy to emit a laser beam
that targets nearby mobs",
maxCount: 9,
count: 0,
+ isBotTech: true,
allowed() {
return m.maxEnergy > 0.5
},
@@ -888,15 +891,16 @@
},
{
name: "laser-bot upgrade",
- description: "400% increased laser damage
applies to all current and future laser-bots",
+ description: "convert all your permanent bots to laser-bots
400% increased laser-bot laser damage",
maxCount: 1,
count: 0,
allowed() {
- return tech.laserBotCount > 1
+ return tech.laserBotCount > 1 && !b.hasBotUpgrade()
},
- requires: "2 or more laser bots",
+ requires: "2 or more laser bots and only 1 bot upgrade",
effect() {
tech.isLaserBotUpgrade = true
+ b.convertBotsTo("laserBotCount")
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'laser') bullet[i].isUpgraded = true
}
@@ -913,6 +917,7 @@
description: "a bot is locked in orbit around you
stuns and damages mobs on contact",
maxCount: 9,
count: 0,
+ isBotTech: true,
allowed() {
return true
},
@@ -927,15 +932,16 @@
},
{
name: "orbital-bot upgrade",
- description: "increase damage by 200% and radius by 30%
applies to all current and future orbit-bots",
+ description: "convert all your permanent bots to orbital-bots
increase damage by 200% and radius by 30%",
maxCount: 1,
count: 0,
allowed() {
- return tech.orbitBotCount > 1
+ return tech.orbitBotCount > 1 && !b.hasBotUpgrade()
},
- requires: "2 or more orbital bots",
+ requires: "2 or more orbital bots and only 1 bot upgrade",
effect() {
tech.isOrbitBotUpgrade = true
+ b.convertBotsTo("orbitBotCount")
const range = 190 + 60 * tech.isOrbitBotUpgrade
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'orbit') {
@@ -962,6 +968,7 @@
description: "a bot damages mobs while it traces your path
regen 6 energy per second when it's near",
maxCount: 9,
count: 0,
+ isBotTech: true,
allowed() {
return true
},
@@ -976,15 +983,16 @@
},
{
name: "dynamo-bot upgrade",
- description: "dynamo-bots regen 24 energy per second
applies to all current and future dynamo-bots",
+ description: "convert your permanent bots to dynamo-bots
dynamo-bots regen 24 energy per second",
maxCount: 1,
count: 0,
allowed() {
- return tech.dynamoBotCount > 1
+ return tech.dynamoBotCount > 1 && !b.hasBotUpgrade()
},
- requires: "2 or more dynamo bots",
+ requires: "2 or more dynamo bots and only 1 bot upgrade",
effect() {
tech.isDynamoBotUpgrade = true
+ b.convertBotsTo("dynamoBotCount")
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'dynamo') bullet[i].isUpgraded = true
}
@@ -1014,33 +1022,13 @@
tech.isRerollBots = false;
}
},
- {
- name: "electroactive polymers",
- description: "build 2 random bots
switching guns cycles bots to the same type",
- maxCount: 1,
- isNonRefundable: true,
- count: 0,
- allowed() {
- return tech.totalBots() > 2 && b.inventory.length > 1
- },
- requires: "at least 3 bots and 2 guns",
- effect() {
- tech.isBotSwap = true
- b.randomBot()
- b.randomBot()
- },
- remove() {
- tech.isBotSwap = false
- tech.botSwapCycleIndex = 0
- }
- },
{
name: "perimeter defense",
description: "reduce harm by 6%
for each of your permanent bots",
maxCount: 1,
count: 0,
allowed() {
- return tech.totalBots() > 3 && !tech.isEnergyHealth
+ return b.totalBots() > 3 && !tech.isEnergyHealth
},
requires: "at least 4 bots",
effect() {
@@ -1055,7 +1043,7 @@
maxCount: 1,
count: 0,
allowed() {
- return tech.totalBots() > 3
+ return b.totalBots() > 3
},
requires: "at least 4 bots",
effect() {
@@ -1073,7 +1061,7 @@
isNonRefundable: true,
isExperimentHide: true,
allowed() {
- return tech.totalBots() > 3
+ return b.totalBots() > 3
},
requires: "at least 4 bots",
effect() {
@@ -1836,6 +1824,22 @@
tech.isImmortal = false;
}
},
+ {
+ name: "many-worlds",
+ description: "on each new level enter an alternate reality
find 2 tech power ups in that reality",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return tech.isImmortal
+ },
+ requires: "quantum immortality",
+ effect() {
+ tech.isSwitchReality = true;
+ },
+ remove() {
+ tech.isSwitchReality = false;
+ }
+ },
{
name: "bubble fusion",
description: "after destroying a mob's shield
spawn 1-2 heals, ammo, or research",
@@ -2096,9 +2100,9 @@
isExperimentHide: true,
count: 0,
allowed() {
- return powerUps.research.count === 0 && level.onLevel < 6
+ return level.onLevel < 8 && level.onLevel > 0
},
- requires: "no research, and in the first 5 levels",
+ requires: "between levels 1 and 7",
effect() {
level.difficultyDecrease(simulation.difficultyMode)
simulation.makeTextLog(`simulation.difficultyMode--`)
@@ -2183,7 +2187,7 @@
}
},
{
- name: "many-worlds",
+ name: "ansatz",
description: "after choosing a field, tech, or gun
if you have no research spawn 2",
maxCount: 1,
count: 0,
@@ -2306,7 +2310,7 @@
maxCount: 1,
count: 0,
allowed() {
- return (tech.totalBots() > 5 || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" || m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && !tech.isEnergyHealth && !tech.isRewindAvoidDeath //build.isExperimentSelection ||
+ return (b.totalBots() > 5 || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" || m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && !tech.isEnergyHealth && !tech.isRewindAvoidDeath //build.isExperimentSelection ||
},
requires: "bots > 5, plasma torch, nano-scale, pilot wave, not mass-energy equivalence, CPT",
effect() {
@@ -2933,6 +2937,7 @@
isGunTech: true,
maxCount: 1,
count: 0,
+ isBotTech: true,
allowed() {
return tech.haveGunCheck("missiles")
},
@@ -3597,7 +3602,7 @@
},
requires: "standing wave harmonics",
effect() {
- tech.blockDmg += 0.75 //if you change this value also update the for loop in the electricity graphics in m.pushMass
+ tech.blockDmg += 1.25 //if you change this value also update the for loop in the electricity graphics in m.pushMass
},
remove() {
tech.blockDmg = 0;
@@ -3605,7 +3610,7 @@
},
{
name: "frequency resonance",
- description: "standing wave harmonics shield is retuned
increase size and blocking efficiency by 40%",
+ description: "standing wave harmonics shield is retuned
increase size and blocking efficiency by 50%",
isFieldTech: true,
maxCount: 9,
count: 0,
@@ -3614,8 +3619,8 @@
},
requires: "standing wave harmonics",
effect() {
- m.fieldRange += 175 * 0.2
- m.fieldShieldingScale *= 0.55
+ m.fieldRange += 175 * 0.25
+ m.fieldShieldingScale *= 0.5
},
remove() {
m.fieldRange = 175;
@@ -3624,38 +3629,21 @@
},
{
name: "flux pinning",
- description: "blocking with perfect diamagnetism
stuns mobs for +1 second",
+ description: "blocking with your field
stuns mobs for +2 second",
isFieldTech: true,
maxCount: 9,
count: 0,
allowed() {
- return m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism"
+ return m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism" || m.fieldUpgrades[m.fieldMode].name === "standing wave harmonics" || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing"
},
- requires: "perfect diamagnetism",
+ requires: "a field that can block",
effect() {
- tech.isStunField += 60;
+ tech.isStunField += 120;
},
remove() {
tech.isStunField = 0;
}
},
- {
- name: "eddy current brake",
- description: "your stored energy projects a field that
limits the top speed of mobs",
- isFieldTech: true,
- maxCount: 1,
- count: 0,
- allowed() {
- return m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism"
- },
- requires: "perfect diamagnetism",
- effect() {
- tech.isPerfectBrake = true;
- },
- remove() {
- tech.isPerfectBrake = false;
- }
- },
{
name: "fracture analysis",
description: "bullet impacts do 400% damage
to stunned mobs",
@@ -3673,6 +3661,23 @@
tech.isCrit = false;
}
},
+ {
+ name: "eddy current brake",
+ description: "your stored energy projects a field that
limits the top speed of mobs",
+ isFieldTech: true,
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism"
+ },
+ requires: "perfect diamagnetism",
+ effect() {
+ tech.isPerfectBrake = true;
+ },
+ remove() {
+ tech.isPerfectBrake = false;
+ }
+ },
{
name: "pair production",
description: "picking up a power up gives you 250 energy",
@@ -3955,6 +3960,7 @@
isFieldTech: true,
maxCount: 1,
count: 0,
+ isBotTech: true,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "plasma torch"
},
@@ -4323,6 +4329,46 @@
// },
// remove() {}
// },
+ {
+ name: "sliders",
+ description: "become an alternate version of yourself
every 20 seconds",
+ maxCount: 1,
+ count: 0,
+ numberInPool: 0,
+ isNonRefundable: true,
+ isExperimentHide: true,
+ isJunk: true,
+ allowed() {
+ return true
+ },
+ requires: "",
+ effect() {
+ setInterval(() => {
+ m.switchWorlds()
+ }, 20000); //every 30 sections
+ },
+ remove() {}
+ },
+ {
+ name: "pop-ups",
+ description: "sign up to learn endless easy ways to win n-gon
that landgreen doesn't want you to know about!!!1!!",
+ maxCount: 1,
+ count: 0,
+ numberInPool: 0,
+ isNonRefundable: true,
+ isExperimentHide: true,
+ isJunk: true,
+ allowed() {
+ return true
+ },
+ requires: "",
+ effect() {
+ setInterval(() => {
+ alert(`The best combo is ${tech.tech[Math.floor(Math.random() * tech.tech.length)].name} with ${tech.tech[Math.floor(Math.random() * tech.tech.length)].name}!`);
+ }, 30000); //every 30 sections
+ },
+ remove() {}
+ },
{
name: "music",
description: "add music to n-gon",
@@ -4882,11 +4928,11 @@
isExperimentHide: true,
isJunk: true,
allowed() {
- return tech.totalBots() > 2
+ return b.totalBots() > 2
},
requires: "at least 3 bots",
effect() {
- const total = tech.totalBots();
+ const total = b.totalBots();
tech.dynamoBotCount = 0;
tech.nailBotCount = 0;
tech.laserBotCount = 0;
@@ -5258,8 +5304,7 @@
isBlockPowerUps: null,
isBlockHarm: null,
foamFutureFire: null,
- isBotSwap: null,
- botSwapCycleIndex: null,
isDamageAfterKill: null,
- isHarmReduceAfterKill: null
+ isHarmReduceAfterKill: null,
+ isSwitchReality: null
}
\ No newline at end of file
diff --git a/todo.txt b/todo.txt
index c9ad888..e0d07ed 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,13 +1,11 @@
******************************************************** NEXT PATCH ********************************************************
-mob effect: freeze - now only slows mobs down
- all freeze effects are about 50% longer
+many worlds renamed to ansatz
+new tech many-worlds: at the start of each new level switch realities
-junk tech: music - adds background music to n-gon
-junk tech: performance - adds fps tracker to n-gon
-
-tech: dormancy - if a mob has died in the last 5 seconds increase damage by 50% else decrease damage by 50%
-tech: torpor - if a mob has died in the last 5 seconds reduce harm by 66% else increase harm by 33%
+removed tech: electroactive polymers - convert bots to the same type on weapon swap
+all bot upgrades convert current bots to the upgraded type
+ only one bot upgrade allowed
******************************************************** BUGS ********************************************************
@@ -37,7 +35,6 @@ use the floor of portal sensor on the player? to unstuck player
******************************************************** TODO ********************************************************
-
decrease healing effects by 50%
decrease level scaling healing reduction
net effect: healing at difficulty 40 (level 10 hard) should be 25% higher then current levels
@@ -373,7 +370,7 @@ n-gon outreach ideas
******************************************************** LORE ********************************************************
cool names for tech
- strange loop, ansatz, perturbation theory
+ strange loop, perturbation theory
voice singing with pitch?