quantum eraser

tech: quantum eraser - for each mob left alive after you exit a level
  kill a spawning mob with 100% duplication
symbiosis: bosses spawn a tech and also an ammo, research, and heal
  when mobs dies lose 0.45 -> 0.5 max health
boson composite - when you move through mobs they drain a little bit of energy

incendiary ammunition makes bullets explode on impact with map
polyurethane foam now works for harpoons
reactor level: timeBoss is much faster, mineBoss does 50% mine more damage
  all bosses spawn fewer numbers
  spawning all 4 bosses spawns much fewer numbers

bug fixes
  loaded a patch to matter.js physics engine 0.18 to fix issues with time dilation
This commit is contained in:
landgreen
2022-06-28 07:43:02 -07:00
parent 3cb4a649c7
commit 5f098c3d1e
11 changed files with 1047 additions and 122 deletions

View File

@@ -1438,9 +1438,13 @@ const b = {
if (tech.fragments) {
b.targetedNail(this.vertices[2], tech.fragments * Math.floor(2 + Math.random()))
}
// if (!who.isBadTarget) {
// this.do = this.returnToPlayer
// }
if (tech.isFoamBall) {
const radius = 5 + 8 * Math.random()
const velocity = { x: Math.max(2, 10 - radius * 0.25), y: 0 }
for (let i = 0, len = 2 * this.mass; i < len; i++) {
b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
}
}
},
caughtPowerUp: null,
dropCaughtPowerUp() {
@@ -1714,7 +1718,14 @@ const b = {
this.draw();
}
}
}
if (tech.isFoamBall) {
const radius = 5 + 8 * Math.random()
const velocity = { x: Math.max(2, 10 - radius * 0.25), y: 0 }
for (let i = 0, len = 2 * this.mass; i < len; i++) {
b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
}
}
},
caughtPowerUp: null,
@@ -5118,10 +5129,7 @@ const b = {
bullet[me].minDmgSpeed = 10
bullet[me].frictionAir = 0.006;
bullet[me].do = function() {
this.force.y += this.mass * 0.0008
//rotates bullet to face current velocity?
bullet[me].rotateToVelocity = function() { //rotates bullet to face current velocity?
if (this.speed > 7) {
const facing = {
x: Math.cos(this.angle),
@@ -5135,6 +5143,22 @@ const b = {
}
}
};
if (tech.isIncendiary) {
bullet[me].do = function() {
this.force.y += this.mass * 0.0008
this.rotateToVelocity()
//collide with map
if (Matter.Query.collides(this, map).length) { //penetrate walls
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
b.explosion(this.position, 300 + 40 * Math.random()); //makes bullet do explosive damage at end
}
};
} else {
bullet[me].do = function() {
this.force.y += this.mass * 0.0008
this.rotateToVelocity()
};
}
b.muzzleFlash(30);
//very complex recoil system
if (m.onGround) {
@@ -5192,10 +5216,7 @@ const b = {
bullet[me].minDmgSpeed = 10
bullet[me].frictionAir = 0.006;
bullet[me].do = function() {
this.force.y += this.mass * 0.0008
//rotates bullet to face current velocity?
bullet[me].rotateToVelocity = function() { //rotates bullet to face current velocity?
if (this.speed > 7) {
const facing = {
x: Math.cos(this.angle),
@@ -5209,6 +5230,23 @@ const b = {
}
}
};
if (tech.isIncendiary) {
bullet[me].do = function() {
this.force.y += this.mass * 0.0008
this.rotateToVelocity()
//collide with map
if (Matter.Query.collides(this, map).length) { //penetrate walls
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
b.explosion(this.position, 100 + (Math.random() - 0.5) * 20); //makes bullet do explosive damage at end
}
};
} else {
bullet[me].do = function() {
this.force.y += this.mass * 0.0008
this.rotateToVelocity()
};
}
b.muzzleFlash(30);
//very complex recoil system
if (m.onGround) {
@@ -5339,6 +5377,9 @@ const b = {
this.torque -= this.turnMag
}
}
if (tech.isIncendiary && Matter.Query.collides(this, map).length) {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
}
};
bullet[me].beforeDmg = function(who) {
if (this.speed > 4) {
@@ -5373,7 +5414,9 @@ const b = {
bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
};
bullet[me].do = function() {}
bullet[me].do = function() {
if (Matter.Query.collides(this, map).length) this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
}
Composite.add(engine.world, bullet[me]); //add bullet to world
}
} else if (tech.isNailShot) {
@@ -5500,6 +5543,19 @@ const b = {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
};
if (tech.isIncendiary) {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
if (Matter.Query.collides(this, map).length) {
b.explosion(this.position, this.mass * 280); //makes bullet do explosive damage at end
this.endCycle = 0
}
};
} else {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
};
}
bullet[me].beforeDmg = function(who) {
mobs.statusStun(who, 180) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds)
if (tech.isIncendiary) {
@@ -5513,7 +5569,6 @@ const b = {
b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
}
this.endCycle = 0
// this.mass = 0 //prevent damage
}
};
},
@@ -5537,9 +5592,19 @@ const b = {
bullet[me].minDmgSpeed = 0;
bullet[me].restitution = 0.99;
bullet[me].friction = 0;
bullet[me].do = function() {
this.force.y += this.mass * 0.001;
};
if (tech.isIncendiary) {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
if (Matter.Query.collides(this, map).length) {
b.explosion(this.position, this.mass * 280); //makes bullet do explosive damage at end
this.endCycle = 0
}
};
} else {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
};
}
bullet[me].beforeDmg = function() {
if (tech.isIncendiary) {
b.explosion(this.position, this.mass * 320 + 70 * Math.random()); //makes bullet do explosive damage at end
@@ -5579,9 +5644,19 @@ const b = {
bullet[me].minDmgSpeed = 0;
bullet[me].restitution = 0.99;
bullet[me].friction = 0;
bullet[me].do = function() {
this.force.y += this.mass * 0.001;
};
if (tech.isIncendiary) {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
if (Matter.Query.collides(this, map).length) {
b.explosion(this.position, this.mass * 280); //makes bullet do explosive damage at end
this.endCycle = 0
}
};
} else {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
};
}
bullet[me].beforeDmg = function() {
if (tech.isIncendiary) {
b.explosion(this.position, this.mass * 320 + 70 * Math.random()); //makes bullet do explosive damage at end

View File

@@ -17,18 +17,19 @@ const level = {
if (level.levelsCleared === 0) { //this code only runs on the first level
// simulation.isHorizontalFlipped = true
// m.addHealth(Infinity)
// m.setField("wormhole")
// b.giveGuns("nail gun")
// m.setField("metamaterial cloaking")
// b.giveGuns("harpoon")
// b.giveGuns("shotgun")
// b.guns[0].ammo = 10000
// b.giveGuns("mine")
// tech.giveTech("alternator")
// // b.giveGuns("mine")
// tech.giveTech("boson composite")
// for (let i = 0; i < 3; ++i) tech.giveTech("smelting")
// for (let i = 0; i < 9; ++i) tech.giveTech("propagator")
// for (let i = 0; i < 100; ++i) tech.giveTech("nail-bot")
// for (let i = 0; i < 9; ++i) tech.giveTech("emergence")
// tech.giveTech("decoherence")
// tech.giveTech("adiabatic healing")
// tech.giveTech("shape-memory alloy")
// tech.giveTech("polyurethane foam")
// tech.giveTech("quantum eraser")
// tech.giveTech("MACHO")
// m.maxHealth = 100
// m.health = m.maxHealth
// for (let i = 0; i < 10; i++) tech.giveTech("tungsten carbide")
@@ -45,7 +46,7 @@ const level = {
// powerUps.research.changeRerolls(100)
// spawn.starter(1900, -500, 100)
// for (let i = 0; i < 20; ++i) spawn.exploder(1900, -500)
// spawn.grenadierBoss(1900, -500)
// spawn.timeSkipBoss(1900, -500)
// level.difficultyIncrease(20) //30 is near max on hard //60 is near max on why
// level.testing(); //not in rotation, used for testing
// for (let i = 0; i < 7; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research");
@@ -80,6 +81,7 @@ const level = {
simulation.draw.setPaths();
b.respawnBots();
m.resetHistory();
spawn.quantumEraserCheck(); //remove mobs from tech: quantum eraser
if (tech.isForeverDrones) {
if (tech.isDroneRadioactive) {
@@ -2796,21 +2798,21 @@ const level = {
isDoorsLocked = true
for (let i = 0; i < 9; ++i) powerUps.spawn(-1800 + 550 * Math.random(), -1700, "ammo")
for (let i = 0; i < 3; ++i) powerUps.spawn(-1800 + 550 * Math.random(), -1700, "heal");
const scale = Math.pow(simulation.difficulty, 0.73) //hard around 30, why around 54
if (Math.random() < 0.07 && simulation.difficulty > 24) {
for (let i = 0, len = scale * 0.25 / 4; i < len; ++i) spawn.timeBoss(-1327 - 200 * i, -1525, 60, false); //spawn 1-2 at difficulty 15
for (let i = 0, len = scale * 0.1 / 4; i < len; ++i) spawn.bounceBoss(-1327 - 200 * i, -1525, 80, false);
for (let i = 0, len = scale * 0.16 / 4; i < len; ++i) spawn.sprayBoss(-1327 - 200 * i, -1525, 30, false)
for (let i = 0, len = scale * 0.23 / 4; i < len; ++i) spawn.mineBoss(-1327 - 200 * i, -1525, 50, false);
const scale = Math.pow(simulation.difficulty, 0.7) //hard around 30, why around 54
if (Math.random() < 0.07 && simulation.difficulty > 30) {
for (let i = 0, len = scale * 0.25 / 5; i < len; ++i) spawn.timeBoss(-1327 - 200 * i, -1525, 60, false); //spawn 1-2 at difficulty 15
for (let i = 0, len = scale * 0.1 / 5; i < len; ++i) spawn.bounceBoss(-1327 - 200 * i, -1525, 80, false);
for (let i = 0, len = scale * 0.15 / 5; i < len; ++i) spawn.sprayBoss(-1327 - 200 * i, -1525, 30, false)
for (let i = 0, len = scale * 0.26 / 5; i < len; ++i) spawn.mineBoss(-1327 - 200 * i, -1525, 50, false);
} else {
if (Math.random() < 0.25) {
for (let i = 0, len = scale * 0.25; i < len; ++i) spawn.timeBoss(-1327 - 200 * i, -1525, 80, false); //spawn 1-2 at difficulty 15
} else if (Math.random() < 0.33) {
for (let i = 0, len = scale * 0.1; i < len; ++i) spawn.bounceBoss(-1327 - 200 * i, -1525, 80, false); //spawn 1-2 at difficulty 15
} else if (Math.random() < 0.5) {
for (let i = 0, len = scale * 0.16; i < len; ++i) spawn.sprayBoss(-1327 - 200 * i, -1525, 30, false) //spawn 2-3 at difficulty 15
for (let i = 0, len = scale * 0.15; i < len; ++i) spawn.sprayBoss(-1327 - 200 * i, -1525, 30, false) //spawn 2-3 at difficulty 15
} else {
for (let i = 0, len = scale * 0.23; i < len; ++i) spawn.mineBoss(-1327 - 200 * i, -1525, 50, false); //spawn 3-4 at difficulty 15
for (let i = 0, len = scale * 0.26; i < len; ++i) spawn.mineBoss(-1327 - 200 * i, -1525, 50, false); //spawn 3-4 at difficulty 15
}
}
spawn.secondaryBossChance(-2300, -800)
@@ -2876,21 +2878,21 @@ const level = {
isDoorsLocked = true
for (let i = 0; i < 9; ++i) powerUps.spawn(1200 + 550 * Math.random(), -1700, "ammo")
for (let i = 0; i < 3; ++i) powerUps.spawn(1200 + 550 * Math.random(), -1700, "heal");
const scale = Math.pow(simulation.difficulty, 0.73) //hard around 30, why around 54
if (Math.random() < 0.07 && simulation.difficulty > 24) {
for (let i = 0, len = scale * 0.25 / 4; i < len; ++i) spawn.timeBoss(1487 + 200 * i, -1525, 60, false); //spawn 1-2 at difficulty 15
for (let i = 0, len = scale * 0.1 / 4; i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false);
for (let i = 0, len = scale * 0.16 / 4; i < len; ++i) spawn.sprayBoss(1487 + 200 * i, -1525, 30, false)
for (let i = 0, len = scale * 0.23 / 4; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false);
const scale = Math.pow(simulation.difficulty, 0.7) //hard around 30, why around 54
if (Math.random() < 0.07 && simulation.difficulty > 30) {
for (let i = 0, len = scale * 0.25 / 5; i < len; ++i) spawn.timeBoss(1487 + 200 * i, -1525, 60, false); //spawn 1-2 at difficulty 15
for (let i = 0, len = scale * 0.1 / 5; i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false);
for (let i = 0, len = scale * 0.15 / 5; i < len; ++i) spawn.sprayBoss(1487 + 200 * i, -1525, 30, false)
for (let i = 0, len = scale * 0.26 / 5; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false);
} else {
if (Math.random() < 0.25) {
for (let i = 0, len = scale * 0.25; i < len; ++i) spawn.timeBoss(1487 + 200 * i, -1525, 80, false); //spawn 1-2 at difficulty 15
} else if (Math.random() < 0.33) {
for (let i = 0, len = scale * 0.1; i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false); //spawn 1-2 at difficulty 15
} else if (Math.random() < 0.5) {
for (let i = 0, len = scale * 0.16; i < len; ++i) spawn.sprayBoss(1487 + 200 * i, -1525, 30, false) //spawn 2-3 at difficulty 15
for (let i = 0, len = scale * 0.15; i < len; ++i) spawn.sprayBoss(1487 + 200 * i, -1525, 30, false) //spawn 2-3 at difficulty 15
} else {
for (let i = 0, len = scale * 0.23; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false); //spawn 3-4 at difficulty 15
for (let i = 0, len = scale * 0.26; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false); //spawn 3-4 at difficulty 15
}
}
spawn.secondaryBossChance(2200, -800)

View File

@@ -1205,10 +1205,12 @@ const mobs = {
}
if (tech.isAddRemoveMaxHealth) {
if (this.isBoss && this.isDropPowerUp) {
powerUps.spawn(this.position.x, this.position.y, "tech", false)
// if (0.5 < Math.random()) powerUps.spawn(this.position.x, this.position.y, "tech", false)
powerUps.spawn(this.position.x + 20, this.position.y, "tech", false)
powerUps.spawn(this.position.x - 20, this.position.y, "ammo", false)
powerUps.spawn(this.position.x, this.position.y + 20, "research", false)
powerUps.spawn(this.position.x, this.position.y - 20, "heal", false)
} else {
const amount = 0.0045
const amount = 0.005
if (tech.isEnergyHealth) {
if (m.maxEnergy > amount) {
tech.healMaxEnergyBonus -= amount

View File

@@ -2772,7 +2772,7 @@ const m = {
if (tech.isCloakStun) { //stun nearby mobs after exiting cloak
let isMobsAround = false
const stunRange = m.fieldDrawRadius * 1.5
const drain = 0.15
const drain = 0.1
const stunTime = 240
if (m.energy > drain) {
for (let i = 0, len = mob.length; i < len; ++i) {
@@ -2828,7 +2828,10 @@ const m = {
let inPlayer = Matter.Query.region(mob, player.bounds)
if (inPlayer.length > 0) {
for (let i = 0; i < inPlayer.length; i++) {
if (m.energy > 0 && inPlayer[i].shield) m.energy -= 0.014;
if (m.energy > 0) {
if (inPlayer[i].isUnblockable) m.energy -= 0.003;
if (inPlayer[i].shield) m.energy -= 0.014;
}
}
}
} else {

View File

@@ -1293,7 +1293,7 @@ const powerUps = {
if ((tech.isPauseEjectTech || simulation.testing) && !simulation.isChoosing && !tech.tech[index].isNonRefundable) {
if (Math.random() < 0.16 || tech.tech[index].isFromAppliedScience || (tech.tech[index].bonusResearch !== undefined && tech.tech[index].bonusResearch > powerUps.research.count)) {
tech.removeTech(index)
powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
// powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
} else {
powerUps.ejectTech(index)
}

View File

@@ -114,7 +114,7 @@ const simulation = {
simulation.checks();
mobs.loop();
}
m.hold();
if (m.fieldMode !== 7) m.hold();
b.bulletRemove();
if (!m.isBodiesAsleep) b.bulletDo();
}
@@ -922,6 +922,13 @@ const simulation = {
requestAnimationFrame(respawnWorms);
}
if (tech.isQuantumEraser) {
// tech.quantumEraserCount = 0
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].isDropPowerUp && mob[i].alive) tech.quantumEraserCount++
}
}
function removeAll(array) {
// for (let i = 0; i < array.length; ++i) Matter.Composite.remove(engine.world, array[i]);
for (let i = 0; i < array.length; ++i) Matter.Composite.remove(engine.world, array[i]);

View File

@@ -16,6 +16,7 @@ const spawn = {
} else {
spawn[options[Math.floor(Math.random() * options.length)]](x, y)
}
spawn.quantumEraserCheck(); //remove mobs from tech: quantum eraser
},
pickList: ["starter", "starter"],
fullPickList: [
@@ -45,16 +46,55 @@ const spawn = {
spawnChance(chance) {
return Math.random() < chance + 0.07 * simulation.difficulty && mob.length < -1 + 16 * Math.log10(simulation.difficulty + 1)
},
quantumEraserCheck() { //remove mobs from tech: quantum eraser
if (tech.isQuantumEraser && tech.quantumEraserCount > 0) {
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].isDropPowerUp && mob[i].alive) { //&& !mob[i].isBoss
tech.isQuantumEraserDuplication = true
mob[i].death()
tech.isQuantumEraserDuplication = false
//graphics
const color = 'rgba(255,255,255, 0.8)'
simulation.drawList.push({
x: mob[i].position.x,
y: mob[i].position.y,
radius: mob[i].radius * 2,
color: color, //"rgba(0,0,0,0.6)",
time: 60
});
simulation.drawList.push({
x: mob[i].position.x,
y: mob[i].position.y,
radius: mob[i].radius * 1,
color: color, //"rgba(0,0,0,0.85)",
time: 90
});
simulation.drawList.push({
x: mob[i].position.x,
y: mob[i].position.y,
radius: mob[i].radius * 0.5,
color: color, //"rgb(0,0,0)",
time: 120
});
tech.quantumEraserCount--
simulation.makeTextLog(`<span class='color-var'>tech</span>.quantumEraserCount <span class='color-symbol'>=</span> ${tech.quantumEraserCount}`)
if (tech.quantumEraserCount < 1) break
}
}
}
},
randomMob(x, y, chance = 1) {
if (spawn.spawnChance(chance) || chance === Infinity) {
const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
spawn[pick](x, y);
}
if (tech.isMoreMobs || (tech.isDuplicateBoss && Math.random() < tech.duplicationChance())) {
const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
spawn[pick](x, y);
}
spawn.quantumEraserCheck(); //remove mobs from tech: quantum eraser
},
randomSmallMob(x, y,
num = Math.max(Math.min(Math.round(Math.random() * simulation.difficulty * 0.2), 4), 0),
@@ -72,6 +112,7 @@ const spawn = {
spawn[pick](x + Math.round((Math.random() - 0.5) * 20) + i * size * 2.5, y + Math.round((Math.random() - 0.5) * 20), size);
}
}
spawn.quantumEraserCheck(); //remove mobs from tech: quantum eraser
},
randomGroup(x, y, chance = 1) {
if (spawn.spawnChance(chance) && simulation.difficulty > 2 || chance === Infinity) {
@@ -106,6 +147,7 @@ const spawn = {
}
}
}
spawn.quantumEraserCheck(); //remove mobs from tech: quantum eraser
}
},
secondaryBossChance(x, y) {
@@ -2400,7 +2442,9 @@ const spawn = {
me.memory = Infinity
me.onDeath = function() {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
ctx.setLineDash([]);
requestAnimationFrame(() => {
requestAnimationFrame(() => { ctx.setLineDash([]) })
})
};
me.damageReduction = 0.35 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) // me.damageReductionGoal
me.awake = function() {
@@ -3812,8 +3856,8 @@ const spawn = {
this.death();
//hit player
if (Vector.magnitude(Vector.sub(this.position, player.position)) < this.explodeRange && m.immuneCycle < m.cycle) {
m.damage(0.01 * simulation.dmgScale * (tech.isRadioactiveResistance ? 0.25 : 1));
m.energy -= 0.1 * (tech.isRadioactiveResistance ? 0.25 : 1)
m.damage(0.015 * simulation.dmgScale * (tech.isRadioactiveResistance ? 0.25 : 1));
m.energy -= 0.15 * (tech.isRadioactiveResistance ? 0.25 : 1)
if (m.energy < 0) m.energy = 0
}
// mob[i].isInvulnerable = false //make mineBoss not invulnerable ?
@@ -3931,7 +3975,7 @@ const spawn = {
me.collisionFilter.mask = cat.bullet | cat.player | cat.body | cat.map | cat.mob
Matter.Body.setVelocity(me, { x: 10 * (Math.random() - 0.5), y: 10 * (Math.random() - 0.5) });
me.seePlayer.recall = 1;
spawn.spawnOrbitals(me, radius + 15, 1)
spawn.spawnOrbitals(me, radius + 25, 1)
// me.skipRate = 1 + Math.floor(simulation.difficulty*0.02)
// spawn.shield(me, x, y, 1);
@@ -3940,7 +3984,7 @@ const spawn = {
if (this.health < this.nextHealthThreshold) {
this.health = this.nextHealthThreshold - 0.01
this.nextHealthThreshold = Math.floor(this.health * 4) / 4 //0.75,0.5,0.25
this.invulnerableCount = 360 + simulation.difficulty * 4 //how long does invulnerable time last
this.invulnerableCount = 300 + simulation.difficulty * 4 //how long does invulnerable time last
this.isInvulnerable = true
this.damageReduction = 0
// requestAnimationFrame(() => { simulation.timePlayerSkip(300) }); //wrapping in animation frame prevents errors, probably
@@ -3948,7 +3992,7 @@ const spawn = {
};
me.onDeath = function() {
if (isSpawnBossPowerUp) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
requestAnimationFrame(() => { simulation.timePlayerSkip(30) }); //wrapping in animation frame prevents errors, probably
requestAnimationFrame(() => { simulation.timePlayerSkip(60) }); //wrapping in animation frame prevents errors, probably
};
me.cycle = Math.floor(360 * Math.random())
@@ -3977,7 +4021,7 @@ const spawn = {
}
//time dilation
if (!simulation.isTimeSkipping) {
requestAnimationFrame(() => { simulation.timePlayerSkip(1) }); //wrapping in animation frame prevents errors, probably
requestAnimationFrame(() => { simulation.timePlayerSkip(3) }); //wrapping in animation frame prevents errors, probably
// if (!(simulation.cycle % 10))
//draw invulnerable

View File

@@ -255,7 +255,7 @@ const tech = {
return dmg * tech.slowFire * tech.aimDamage
},
duplicationChance() {
return Math.max(0, (tech.isPowerUpsVanish ? 0.12 : 0) + (tech.isStimulatedEmission ? 0.15 : 0) + tech.cancelCount * 0.045 + tech.duplicateChance + m.duplicateChance + tech.fieldDuplicate + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0))
return Math.max(0, (tech.isPowerUpsVanish ? 0.12 : 0) + (tech.isStimulatedEmission ? 0.15 : 0) + tech.cancelCount * 0.045 + tech.duplicateChance + m.duplicateChance + tech.fieldDuplicate + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0) + tech.isQuantumEraserDuplication)
},
isScaleMobsWithDuplication: false,
maxDuplicationEvent() {
@@ -3152,7 +3152,7 @@ const tech = {
{
name: "paradigm shift",
description: `<strong>clicking</strong> <strong class='color-m'>tech</strong> while paused <strong>ejects</strong> them<br><strong>16%</strong> chance to convert that <strong class='color-m'>tech</strong> into ${powerUps.orb.research(1)}`,
description: `<strong>clicking</strong> <strong class='color-m'>tech</strong> while paused <strong>ejects</strong> them<br><strong>16%</strong> chance to fail`,
maxCount: 1,
count: 0,
frequency: 1,
@@ -4402,16 +4402,16 @@ const tech = {
},
{
name: "polyurethane foam",
description: "<strong>super balls</strong> colliding with <strong>mobs</strong> catalyzes<br>a reaction that yields <strong>foam</strong> bubbles",
description: "<strong>super balls</strong> and <strong>harpoons</strong> colliding with <strong>mobs</strong><br>catalyzes a reaction that yields <strong>foam</strong> bubbles",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("super balls")
return tech.haveGunCheck("super balls") || (tech.haveGunCheck("harpoon") && !tech.fragments)
},
requires: "super balls",
requires: "super balls, harpoon, not fragmentation",
effect() {
tech.isFoamBall = true;
},
@@ -4706,9 +4706,9 @@ const tech = {
frequency: 1,
frequencyDefault: 1,
allowed() {
return !tech.isExplodeRadio && (tech.haveGunCheck("harpoon") || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("missiles") || tech.missileBotCount || tech.isRivets || tech.blockDamage > 0.075)
return !tech.isExplodeRadio && ((tech.haveGunCheck("harpoon") && !tech.isFoamBall) || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("missiles") || tech.missileBotCount || tech.isRivets || tech.blockDamage > 0.075)
},
requires: "grenades, missiles, rivets, harpoon, or mass driver, not iridium-192",
requires: "grenades, missiles, rivets, harpoon, or mass driver, not iridium-192, not polyurethane foam",
effect() {
tech.fragments++
},
@@ -5536,7 +5536,7 @@ const tech = {
},
{
name: "fault tolerance",
description: "remove your <strong>drone gun</strong><br>spawn <strong>6</strong> <strong>drones</strong> that last <strong>forever</strong>",
description: "remove your <strong>drone gun</strong><br>spawn <strong>4</strong> <strong>drones</strong> that last <strong>forever</strong>",
isGunTech: true,
isRemoveGun: true,
maxCount: 1,
@@ -5548,7 +5548,7 @@ const tech = {
},
requires: "drones, not drone repair, anti-shear topology, autonomous navigation",
effect() {
const num = 6
const num = 4
tech.isForeverDrones += num
if (tech.haveGunCheck("drones", false)) b.removeGun("drones")
//spawn drones
@@ -5847,7 +5847,7 @@ const tech = {
allowed() {
return tech.haveGunCheck("harpoon") && !tech.isFilament && !tech.isHarpoonPowerUp && !tech.isRailGun && !tech.isFireMoveLock
},
requires: "harpoon, not railgun, filament, toggling harpoon, Higgs mechanism",
requires: "harpoon, not railgun, UHMWPE, toggling harpoon, Higgs mechanism",
effect() {
tech.isGrapple = true;
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
@@ -5865,7 +5865,7 @@ const tech = {
},
{
name: "bulk modulus",
description: `become <strong>immune</strong> to <strong class='color-defense'>defense</strong> while <strong>grappling</strong><br>drains <strong class='color-f'>energy</strong> and prevents <strong>generation</strong>`,
description: `while <strong>grappling</strong> become <strong>invulnerable</strong><br>drain <strong class='color-f'>energy</strong>`,
isGunTech: true,
maxCount: 1,
count: 0,
@@ -7104,7 +7104,7 @@ const tech = {
},
{
name: "Lorentz transformation",
description: `use ${powerUps.orb.research(3)}<br><strong>+50%</strong> <strong>movement</strong>, <strong>jumping</strong>, and <strong>fire rate</strong>`,
description: `use ${powerUps.orb.research(3)}<br><strong>+50%</strong> <strong>movement</strong>, <strong>jumping</strong>, and <strong><em>fire rate</em></strong>`,
isFieldTech: true,
maxCount: 1,
count: 0,
@@ -7152,6 +7152,7 @@ const tech = {
},
{
name: "no-cloning theorem",
// descriptionFunction() { return `<strong>+45%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>after a mob <strong>dies</strong> <strong>2%</strong> <strong class='color-dup'>duplication</strong> <em>(${tech.duplicationChance()})</em>` },
description: `<strong>+45%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>after a mob <strong>dies</strong> <strong>2%</strong> <strong class='color-dup'>duplication</strong>`,
isFieldTech: true,
maxCount: 1,
@@ -7159,7 +7160,7 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
return (m.fieldUpgrades[m.fieldMode].name === "time dilation" || m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking")
return (m.fieldUpgrades[m.fieldMode].name === "time dilation" || m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking") && !tech.isQuantumEraser
},
requires: "cloaking, time dilation",
effect() {
@@ -7173,15 +7174,38 @@ const tech = {
}
},
{
name: "symbiosis",
description: "<strong>bosses</strong> spawn <strong>+1</strong> <strong class='color-m'>tech</strong> after they <strong>die</strong><br>after a <strong>mob</strong> <strong>dies</strong> <strong>0.45</strong> maximum <strong class='color-h'>health</strong>",
name: "quantum eraser",
description: `<span style = 'font-size:90%;'>for each mob left <strong>alive</strong> after you exit a <strong>level</strong><br><strong>kill</strong> a mob as they spawn at <strong>100%</strong> <strong class='color-dup'>duplication</strong></span>`,
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking" || m.fieldUpgrades[m.fieldMode].name === "time dilation"
return (m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking" || m.fieldUpgrades[m.fieldMode].name === "time dilation") && !tech.cloakDuplication
},
requires: "cloaking or time dilation",
effect() {
tech.quantumEraserCount = 0
tech.isQuantumEraserDuplication = 0
tech.isQuantumEraser = true
},
remove() {
tech.quantumEraserCount = 0
tech.isQuantumEraserDuplication = 0
tech.isQuantumEraser = false
}
},
{
name: "symbiosis",
description: `after a <strong>boss</strong> <strong>dies</strong> spawn a <strong class='color-m'>tech</strong>, ${powerUps.orb.ammo(1)}, ${powerUps.orb.research(1)}, and ${powerUps.orb.heal(1)}<br>after a <strong>mob</strong> <strong>dies</strong> <strong>0.5</strong> maximum <strong class='color-h'>health</strong>`,
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking" //|| m.fieldUpgrades[m.fieldMode].name === "time dilation"
},
requires: "cloaking or time dilation",
effect() {
@@ -7194,7 +7218,7 @@ const tech = {
{
name: "boson composite",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Boson' class="link">boson composite</a>`,
description: "while <strong class='color-cloaked'>cloaked</strong> you are <strong>intangible</strong><br>to <strong class='color-block'>blocks</strong> and mobs, but <strong>shields</strong> drains <strong class='color-f'>energy</strong>",
description: "while <strong class='color-cloaked'>cloaked</strong> you are <strong>intangible</strong><br>to <strong class='color-block'>blocks</strong> and mobs, but <strong>mobs</strong> drain <strong class='color-f'>energy</strong>",
isFieldTech: true,
maxCount: 1,
count: 0,
@@ -7216,7 +7240,7 @@ const tech = {
},
{
name: "dazzler",
description: "after <strong class='color-cloaked'>decloaking</strong> <strong>stun</strong> nearby mobs<br>and <strong>10</strong> <strong class='color-f'>energy</strong>",
description: "after <strong class='color-cloaked'>decloaking</strong> <strong>stun</strong> nearby mobs<br>for <strong>10</strong> <strong class='color-f'>energy</strong>",
isFieldTech: true,
maxCount: 1,
count: 0,
@@ -7285,7 +7309,7 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "molecular assembler"
return m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "time dilation" || m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "molecular assembler"
},
requires: "cloaking, molecular assembler, plasma torch, pilot wave",
effect() {
@@ -7325,7 +7349,7 @@ const tech = {
frequency: 1,
frequencyDefault: 1,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "wormhole" || m.fieldUpgrades[m.fieldMode].name === "pilot wave"
return m.fieldUpgrades[m.fieldMode].name === "wormhole" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "time dilation"
},
requires: "wormhole or pilot wave",
effect: () => {
@@ -7739,6 +7763,32 @@ const tech = {
// requires: "",
// effect() {
// },
// remove() {}
// },
// {
// name: "swap meet",
// description: "normal <strong class='color-m'>tech</strong> become <strong class='color-j'>JUNK</strong><br>and <strong class='color-j'>JUNK</strong> become normal <strong class='color-m'>tech</strong>",
// maxCount: 1,
// count: 0,
// frequency: 0,
// isJunk: true,
// isNonRefundable: true,
// allowed() {
// return true
// },
// requires: "",
// effect() {
// for (let i = 0, len = tech.tech.length; i < len; i++) {
// tech.tech[i].isJunk = !tech.tech[i].isJunk
// if (tech.tech[i].isJunk) {} else {}
// if (tech.tech[i].frequency > 0) {
// tech.tech[i].frequency = 0
// } else {
// tech.tech[i].frequency = 2
// }
// }
// },
// remove() {}
// },
@@ -8287,6 +8337,7 @@ const tech = {
count: 0,
frequency: 0,
isJunk: true,
isNonRefundable: true,
allowed() { return true },
requires: "",
effect() {
@@ -8322,35 +8373,35 @@ const tech = {
}
},
remove() {
const colors = ["#f7b", "#0eb", "#467", "#0cf", "hsl(246,100%,77%)", "#26a"] //no shuffle
powerUps.research.color = colors[0]
powerUps.heal.color = colors[1]
powerUps.ammo.color = colors[2]
powerUps.field.color = colors[3]
powerUps.tech.color = colors[4]
powerUps.gun.color = colors[5]
for (let i = 0; i < powerUp.length; i++) {
switch (powerUp[i].name) {
case "research":
powerUp[i].color = colors[0]
break;
case "heal":
powerUp[i].color = colors[1]
break;
case "ammo":
powerUp[i].color = colors[2]
break;
case "field":
powerUp[i].color = colors[3]
break;
case "tech":
powerUp[i].color = colors[4]
break;
case "gun":
powerUp[i].color = colors[5]
break;
}
}
// const colors = ["#f7b", "#0eb", "#467", "#0cf", "hsl(246,100%,77%)", "#26a"] //no shuffle
// powerUps.research.color = colors[0]
// powerUps.heal.color = colors[1]
// powerUps.ammo.color = colors[2]
// powerUps.field.color = colors[3]
// powerUps.tech.color = colors[4]
// powerUps.gun.color = colors[5]
// for (let i = 0; i < powerUp.length; i++) {
// switch (powerUp[i].name) {
// case "research":
// powerUp[i].color = colors[0]
// break;
// case "heal":
// powerUp[i].color = colors[1]
// break;
// case "ammo":
// powerUp[i].color = colors[2]
// break;
// case "field":
// powerUp[i].color = colors[3]
// break;
// case "tech":
// powerUp[i].color = colors[4]
// break;
// case "gun":
// powerUp[i].color = colors[5]
// break;
// }
// }
}
},
{
@@ -10335,5 +10386,8 @@ const tech = {
deathSkipTime: null,
isIceMaxHealthLoss: null,
isIceKill: null,
isCritKill: null
isCritKill: null,
isQuantumEraser: null,
isQuantumEraserDuplication: null,
quantumEraserCount: null
}