metastability

tech: metastability - 20% dup chance, but duplicated powers up eventually explode
nerfed tech: electric reactive armor 6% (was 7%) explosion damage reduction for every 10 energy you currently have
This commit is contained in:
landgreen
2021-05-10 06:20:19 -07:00
parent ce169ba860
commit 0019143124
12 changed files with 253 additions and 128 deletions

View File

@@ -319,11 +319,8 @@ const b = {
time: simulation.drawTime * 2
});
//player damage and knock back
sub = Vector.sub(where, player.position);
dist = Vector.magnitude(sub);
if (dist < radius) {
//player damage
if (Vector.magnitude(Vector.sub(where, player.position)) < 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) {
@@ -389,6 +386,7 @@ const b = {
//body knock backs
for (let i = 0, len = body.length; i < len; ++i) {
if (body[i].isNotHoldable) continue
sub = Vector.sub(where, body[i].position);
dist = Vector.magnitude(sub);
if (dist < radius) {
@@ -560,11 +558,11 @@ const b = {
for (let i = 0, len = Math.floor(mag * 0.0005 * charge); i < len; i++) {
const dist = Math.random()
simulation.drawList.push({
x: path[0].x + sub.x * dist + 13 * (Math.random() - 0.5),
y: path[0].y + sub.y * dist + 13 * (Math.random() - 0.5),
radius: 1 + 4 * Math.random(),
x: path[0].x + sub.x * dist + 10 * (Math.random() - 0.5),
y: path[0].y + sub.y * dist + 10 * (Math.random() - 0.5),
radius: 1.5 + 5 * Math.random(),
color: "rgba(255,0,0,0.5)",
time: Math.floor(2 + 33 * Math.random() * Math.random())
time: Math.floor(9 + 25 * Math.random() * Math.random())
});
}
},
@@ -3625,7 +3623,6 @@ const b = {
damage: 1,
fire() {
totalCycles = Math.floor(4.3 * tech.wavePacketLength * tech.waveReflections * tech.isBulletsLastLonger)
// for (let i = 0; i < 2; i++) {
const me = bullet.length;
bullet[me] = Bodies.polygon(m.pos.x + 25 * Math.cos(m.angle), m.pos.y + 25 * Math.sin(m.angle), 5, 4, {
angle: m.angle,
@@ -3634,7 +3631,7 @@ const b = {
inertia: Infinity,
frictionAir: 0,
slow: 0,
amplitude: (m.crouch ? 5 : 10) * Math.sin(this.wavePacketCycle * tech.wavePacketFrequency) * ((this.wavePacketCycle % 2) ? -1 : 1),
amplitude: (m.crouch ? 5 : 10) * ((this.wavePacketCycle % 2) ? -1 : 1) * Math.sin((this.wavePacketCycle + 1) * tech.wavePacketFrequency), //
minDmgSpeed: 0,
dmg: b.dmgScale * tech.waveBeamDamage * tech.wavePacketDamage, //also control damage when you divide by mob.mass
classType: "bullet",
@@ -3716,8 +3713,7 @@ const b = {
y: tech.waveBeamSpeed * Math.sin(m.angle)
});
const transverse = Vector.normalise(Vector.perp(bullet[me].velocity))
// }
//fire some of bullets then delay for a while
//fire a packet of bullets then delay for a while
this.wavePacketCycle++
if (this.wavePacketCycle > tech.wavePacketLength) {
m.fireCDcycle = m.cycle + Math.floor(this.delay * b.fireCD); // cool down
@@ -4487,28 +4483,30 @@ const b = {
}
}
if (tech.historyLaser) {
const len = 1 + tech.historyLaser
const spacing = Math.ceil(30 - 2 * tech.historyLaser)
this.do = () => {
const len = 1 + 2 * tech.historyLaser
const spacing = Math.ceil(40 - 9 * tech.historyLaser)
if (this.charge > 0) {
//draw charge level
ctx.fillStyle = `rgba(255,0,0,${0.09 * Math.sqrt(this.charge)})`;
const mag = 4.1 * Math.sqrt(this.charge)
ctx.beginPath();
const mag = 4.5 * Math.sqrt(this.charge)
for (let i = 0; i < len; i++) {
const history = m.history[(m.cycle - i * spacing) % 600]
const off = history.yOff - 24.2859
ctx.moveTo(history.position.x, history.position.y - off);
ctx.ellipse(history.position.x, history.position.y - off, mag, mag * 0.5, history.angle, 0, 2 * Math.PI)
ctx.ellipse(history.position.x, history.position.y - off, mag, mag * 0.65, history.angle, 0, 2 * Math.PI)
}
ctx.fillStyle = `rgba(255,0,0,${0.09 * Math.sqrt(this.charge)})`;
ctx.fill();
//fire
if (!input.fire) {
m.fireCDcycle = m.cycle + 10; // cool down
for (let i = 1; i < len; i++) {
const history = m.history[(m.cycle - i * spacing) % 600]
const off = history.yOff - 24.2859
b.pulse(1.4 * this.charge, history.angle, { x: history.position.x, y: history.position.y - off })
if (this.charge > 5) {
m.fireCDcycle = m.cycle + 40; // cool down
for (let i = 0; i < len; i++) {
const history = m.history[(m.cycle - i * spacing) % 600]
const off = history.yOff - 24.2859
b.pulse(1.65 * this.charge, history.angle, { x: history.position.x, y: history.position.y - off })
}
}
this.charge = 0;
}
@@ -4518,19 +4516,21 @@ const b = {
this.do = () => {
if (this.charge > 0) {
//draw charge level
ctx.fillStyle = `rgba(255,0,0,${0.09 * Math.sqrt(this.charge)})`;
ctx.beginPath();
ctx.arc(m.pos.x, m.pos.y, 4.2 * Math.sqrt(this.charge), 0, 2 * Math.PI);
ctx.fillStyle = `rgba(255,0,0,${0.09 * Math.sqrt(this.charge)})`;
ctx.fill();
//fire
if (!input.fire) {
m.fireCDcycle = m.cycle + 10; // cool down
if (tech.beamSplitter) {
const divergence = m.crouch ? 0.2 : 0.5
const angle = m.angle - tech.beamSplitter * divergence / 2
for (let i = 0; i < 1 + tech.beamSplitter; i++) b.pulse(this.charge, angle + i * divergence)
} else {
b.pulse(1.75 * this.charge, m.angle)
if (this.charge > 5) {
m.fireCDcycle = m.cycle + 35; // cool down
if (tech.beamSplitter) {
const divergence = m.crouch ? 0.2 : 0.5
const angle = m.angle - tech.beamSplitter * divergence / 2
for (let i = 0; i < 1 + tech.beamSplitter; i++) b.pulse(this.charge, angle + i * divergence)
} else {
b.pulse(1.8 * this.charge, m.angle)
}
}
this.charge = 0;
}

View File

@@ -130,7 +130,7 @@ function collisionChecks(event) {
simulation.makeTextLog(`simulation.amplitude <span class='color-symbol'>=</span> ${Math.random()}`);
}
if (tech.isPiezo) m.energy += 20.48;
if (tech.isBayesian) powerUps.ejectTech()
if (tech.isStimulatedEmission) powerUps.ejectTech()
if (mob[k].onHit) mob[k].onHit(k);
m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles
//extra kick between player and mob //this section would be better with forces but they don't work...

View File

@@ -117,7 +117,7 @@ window.addEventListener('load', () => {
//**********************************************************************
//set up canvas
//**********************************************************************
var canvas = document.getElementById("canvas");
const canvas = document.getElementById("canvas");
//using "const" causes problems in safari when an ID shares the same name.
const ctx = canvas.getContext("2d");
document.body.style.backgroundColor = "#fff";

View File

@@ -16,15 +16,16 @@ const level = {
// simulation.zoomScale = 1000;
// simulation.setZoom();
// m.setField("metamaterial cloaking")
// b.giveGuns("wave beam")
b.giveGuns("wave beam")
// b.giveGuns("laser")
// tech.isExplodeRadio = true
// tech.giveTech("pulse")
// for (let i = 0; i < 1; i++) tech.giveTech("crystallizer")
// for (let i = 0; i < 3; i++) tech.giveTech("packet length")
// for (let i = 0; i < 3; i++) tech.giveTech("bound state")
// for (let i = 0; i < 3; i++) tech.giveTech("propagation")
// for (let i = 0; i < 3; i++) tech.giveTech("bound state")
// for (let i = 0; i < 9; i++) tech.giveTech("slow light")
tech.giveTech("metastability")
level.intro(); //starting level
// level.testing(); //not in rotation

View File

@@ -155,10 +155,10 @@ const mobs = {
}
},
statusDoT(who, tickDamage, cycles = 180) {
if (!who.isShielded && !m.isBodiesAsleep && who.alive) {
if (!who.isShielded && who.alive) {
who.status.push({
effect() {
if ((simulation.cycle - this.startCycle) % 30 === 0) {
if ((simulation.cycle - this.startCycle) % 30 === 0 && !m.isBodiesAsleep) {
let dmg = b.dmgScale * this.dmg
who.damage(dmg);
simulation.drawList.push({ //add dmg to draw queue
@@ -169,10 +169,6 @@ const mobs = {
time: simulation.drawTime
});
}
// if (true) {
// //check for nearby mobs
// }
},
endEffect() {},
dmg: tickDamage,
@@ -1090,7 +1086,7 @@ const mobs = {
bullet[bullet.length - 1].endCycle = simulation.cycle + 660 //10 seconds and 1 extra second for fun
this.leaveBody = false; // no body since it turned into the bot
}
} else if (tech.isShieldAmmo && this.shield && !this.isBonusShield) {
} else if (tech.isShieldAmmo && this.shield && !this.isExtraShield) {
let type = tech.isEnergyNoAmmo ? "heal" : "ammo"
if (Math.random() < 0.4) {
type = "heal"

View File

@@ -976,7 +976,7 @@ const m = {
m.fieldHarmReduction = 1;
m.fieldDamage = 1
m.duplicateChance = 0
if (tech.duplicationChance() === 0) simulation.draw.powerUp = simulation.draw.powerUpNormal
powerUps.setDo();
m.grabPowerUpRange2 = 156000;
m.fieldRange = 155;
m.fieldFire = false;
@@ -2370,7 +2370,7 @@ const m = {
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong class='color-worm'>wormholes</strong> attract blocks and power ups<br><strong>7%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
effect: function() {
m.duplicateChance = 0.07
simulation.draw.powerUp = simulation.draw.powerUpBonus //change power up draw
powerUps.setDo(); //needed after adjusting duplication chance
m.hold = function() {
// m.hole = { //this is reset with each new field, but I'm leaving it here for reference
@@ -2922,7 +2922,7 @@ const m = {
}
m.damage(dmg);
if (tech.isPiezo) m.energy += 20.48;
if (tech.isBayesian) powerUps.ejectTech()
if (tech.isStimulatedEmission) powerUps.ejectTech()
if (mob[k].onHit) mob[k].onHit(k);
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles
//extra kick between player and mob //this section would be better with forces but they don't work...

View File

@@ -3,6 +3,107 @@ let powerUp = [];
const powerUps = {
totalPowerUps: 0, //used for tech that count power ups at the end of a level
lastTechIndex: null,
do() {},
setDo() {
if (tech.duplicationChance() > 0) {
if (tech.isPowerUpsVanish) {
powerUps.do = powerUps.doDuplicatesVanish
} else {
powerUps.do = powerUps.doDuplicates
}
tech.maxDuplicationEvent() //check to see if hitting 100% duplication
} else {
powerUps.do = powerUps.doDefault
}
},
doDefault() { //draw power ups
ctx.globalAlpha = 0.4 * Math.sin(m.cycle * 0.15) + 0.6;
for (let i = 0, len = powerUp.length; i < len; ++i) {
ctx.beginPath();
ctx.arc(powerUp[i].position.x, powerUp[i].position.y, powerUp[i].size, 0, 2 * Math.PI);
ctx.fillStyle = powerUp[i].color;
ctx.fill();
}
ctx.globalAlpha = 1;
},
doDuplicates() { //draw power ups but give duplicates some electricity
ctx.globalAlpha = 0.4 * Math.sin(m.cycle * 0.15) + 0.6;
for (let i = 0, len = powerUp.length; i < len; ++i) {
ctx.beginPath();
ctx.arc(powerUp[i].position.x, powerUp[i].position.y, powerUp[i].size, 0, 2 * Math.PI);
ctx.fillStyle = powerUp[i].color;
ctx.fill();
}
ctx.globalAlpha = 1;
for (let i = 0, len = powerUp.length; i < len; ++i) {
if (powerUp[i].isDuplicated && Math.random() < 0.1) {
//draw electricity
const mag = 5 + powerUp[i].size / 5
let unit = Vector.rotate({
x: mag,
y: mag
}, 2 * Math.PI * Math.random())
let path = {
x: powerUp[i].position.x + unit.x,
y: powerUp[i].position.y + unit.y
}
ctx.beginPath();
ctx.moveTo(path.x, path.y);
for (let i = 0; i < 6; i++) {
unit = Vector.rotate(unit, 3 * (Math.random() - 0.5))
path = Vector.add(path, unit)
ctx.lineTo(path.x, path.y);
}
ctx.lineWidth = 0.5 + 2 * Math.random();
ctx.strokeStyle = "#000"
ctx.stroke();
}
}
},
doDuplicatesVanish() { //draw power ups but give duplicates some electricity
//remove power ups after 3 seconds
for (let i = 0, len = powerUp.length; i < len; ++i) {
if (powerUp[i].isDuplicated && Math.random() < 0.004) { // (1-0.004)^150 = chance to be removed after 3 seconds
b.explosion(powerUp[i].position, (10 + 3 * Math.random()) * powerUp[i].size);
Matter.World.remove(engine.world, powerUp[i]);
powerUp.splice(i, 1);
break
}
}
ctx.globalAlpha = 0.4 * Math.sin(m.cycle * 0.25) + 0.6
for (let i = 0, len = powerUp.length; i < len; ++i) {
ctx.beginPath();
ctx.arc(powerUp[i].position.x, powerUp[i].position.y, powerUp[i].size, 0, 2 * Math.PI);
ctx.fillStyle = powerUp[i].color;
ctx.fill();
}
ctx.globalAlpha = 1;
for (let i = 0, len = powerUp.length; i < len; ++i) {
if (powerUp[i].isDuplicated && Math.random() < 0.3) {
//draw electricity
const mag = 5 + powerUp[i].size / 5
let unit = Vector.rotate({
x: mag,
y: mag
}, 2 * Math.PI * Math.random())
let path = {
x: powerUp[i].position.x + unit.x,
y: powerUp[i].position.y + unit.y
}
ctx.beginPath();
ctx.moveTo(path.x, path.y);
for (let i = 0; i < 6; i++) {
unit = Vector.rotate(unit, 3 * (Math.random() - 0.5))
path = Vector.add(path, unit)
ctx.lineTo(path.x, path.y);
}
ctx.lineWidth = 0.5 + 2 * Math.random();
ctx.strokeStyle = "#000"
ctx.stroke();
}
}
},
choose(type, index) {
if (type === "gun") {
b.giveGuns(index)
@@ -175,7 +276,7 @@ const powerUps = {
powerUps.directSpawn(x, y, "heal", false, null, size)
if (Math.random() < tech.duplicationChance()) {
powerUps.directSpawn(x, y, "heal", false, null, size)
powerUp[powerUp.length - 1].isBonus = true
powerUp[powerUp.length - 1].isDuplicated = true
}
}
},
@@ -640,7 +741,7 @@ const powerUps = {
for (let i = 0; i < tech.tech[choose].count; i++) {
powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
powerUp[powerUp.length - 1].isBonus = true
powerUp[powerUp.length - 1].isDuplicated = true
}
// remove a random tech from the list of tech you have
tech.tech[choose].remove();
@@ -655,7 +756,7 @@ const powerUps = {
for (let i = 0; i < tech.tech[choose].count; i++) {
powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
powerUp[powerUp.length - 1].isBonus = true
powerUp[powerUp.length - 1].isDuplicated = true
}
// remove a random tech from the list of tech you have
tech.tech[choose].remove();
@@ -720,7 +821,8 @@ const powerUps = {
powerUps.directSpawn(x, y, target, moving, mode, size)
if (Math.random() < tech.duplicationChance()) {
powerUps.directSpawn(x, y, target, moving, mode, size)
powerUp[powerUp.length - 1].isBonus = true
powerUp[powerUp.length - 1].isDuplicated = true
// if (tech.isPowerUpsVanish) powerUp[powerUp.length - 1].endCycle = simulation.cycle + 300
}
}
},

View File

@@ -20,7 +20,7 @@ const simulation = {
ctx.save();
simulation.camera();
level.custom();
simulation.draw.powerUp();
powerUps.do();
mobs.draw();
simulation.draw.cons();
simulation.draw.body();
@@ -900,61 +900,60 @@ const simulation = {
ctx.fillText(`(${simulation.mouseInGame.x.toFixed(1)}, ${simulation.mouseInGame.y.toFixed(1)})`, simulation.mouse.x, simulation.mouse.y - 20);
},
draw: {
powerUp() { //is set by Bayesian tech
// ctx.globalAlpha = 0.4 * Math.sin(m.cycle * 0.15) + 0.6;
// for (let i = 0, len = powerUp.length; i < len; ++i) {
// ctx.beginPath();
// ctx.arc(powerUp[i].position.x, powerUp[i].position.y, powerUp[i].size, 0, 2 * Math.PI);
// ctx.fillStyle = powerUp[i].color;
// ctx.fill();
// }
// ctx.globalAlpha = 1;
},
powerUpNormal() { //back up in case power up draw gets changed
ctx.globalAlpha = 0.4 * Math.sin(m.cycle * 0.15) + 0.6;
for (let i = 0, len = powerUp.length; i < len; ++i) {
ctx.beginPath();
ctx.arc(powerUp[i].position.x, powerUp[i].position.y, powerUp[i].size, 0, 2 * Math.PI);
ctx.fillStyle = powerUp[i].color;
ctx.fill();
}
ctx.globalAlpha = 1;
},
powerUpBonus() { //draws crackle effect for bonus power ups
ctx.globalAlpha = 0.4 * Math.sin(m.cycle * 0.15) + 0.6;
for (let i = 0, len = powerUp.length; i < len; ++i) {
ctx.beginPath();
ctx.arc(powerUp[i].position.x, powerUp[i].position.y, powerUp[i].size, 0, 2 * Math.PI);
ctx.fillStyle = powerUp[i].color;
ctx.fill();
}
ctx.globalAlpha = 1;
for (let i = 0, len = powerUp.length; i < len; ++i) {
if (powerUp[i].isBonus && Math.random() < 0.1) {
//draw electricity
const mag = 5 + powerUp[i].size / 5
let unit = Vector.rotate({
x: mag,
y: mag
}, 2 * Math.PI * Math.random())
let path = {
x: powerUp[i].position.x + unit.x,
y: powerUp[i].position.y + unit.y
}
ctx.beginPath();
ctx.moveTo(path.x, path.y);
for (let i = 0; i < 6; i++) {
unit = Vector.rotate(unit, 3 * (Math.random() - 0.5))
path = Vector.add(path, unit)
ctx.lineTo(path.x, path.y);
}
ctx.lineWidth = 0.5 + 2 * Math.random();
ctx.strokeStyle = "#000"
ctx.stroke();
}
}
// ctx.globalAlpha = 1;
},
// powerUp() { //is set by Bayesian tech
// // ctx.globalAlpha = 0.4 * Math.sin(m.cycle * 0.15) + 0.6;
// // for (let i = 0, len = powerUp.length; i < len; ++i) {
// // ctx.beginPath();
// // ctx.arc(powerUp[i].position.x, powerUp[i].position.y, powerUp[i].size, 0, 2 * Math.PI);
// // ctx.fillStyle = powerUp[i].color;
// // ctx.fill();
// // }
// // ctx.globalAlpha = 1;
// },
// powerUpNormal() { //back up in case power up draw gets changed
// ctx.globalAlpha = 0.4 * Math.sin(m.cycle * 0.15) + 0.6;
// for (let i = 0, len = powerUp.length; i < len; ++i) {
// ctx.beginPath();
// ctx.arc(powerUp[i].position.x, powerUp[i].position.y, powerUp[i].size, 0, 2 * Math.PI);
// ctx.fillStyle = powerUp[i].color;
// ctx.fill();
// }
// ctx.globalAlpha = 1;
// },
// powerUpBonus() { //draws crackle effect for bonus power ups
// ctx.globalAlpha = 0.4 * Math.sin(m.cycle * 0.15) + 0.6;
// for (let i = 0, len = powerUp.length; i < len; ++i) {
// ctx.beginPath();
// ctx.arc(powerUp[i].position.x, powerUp[i].position.y, powerUp[i].size, 0, 2 * Math.PI);
// ctx.fillStyle = powerUp[i].color;
// ctx.fill();
// }
// ctx.globalAlpha = 1;
// for (let i = 0, len = powerUp.length; i < len; ++i) {
// if (powerUp[i].isDuplicated && Math.random() < 0.1) {
// //draw electricity
// const mag = 5 + powerUp[i].size / 5
// let unit = Vector.rotate({
// x: mag,
// y: mag
// }, 2 * Math.PI * Math.random())
// let path = {
// x: powerUp[i].position.x + unit.x,
// y: powerUp[i].position.y + unit.y
// }
// ctx.beginPath();
// ctx.moveTo(path.x, path.y);
// for (let i = 0; i < 6; i++) {
// unit = Vector.rotate(unit, 3 * (Math.random() - 0.5))
// path = Vector.add(path, unit)
// ctx.lineTo(path.x, path.y);
// }
// ctx.lineWidth = 0.5 + 2 * Math.random();
// ctx.strokeStyle = "#000"
// ctx.stroke();
// }
// }
// },
// map: function() {
// ctx.beginPath();

View File

@@ -3025,14 +3025,14 @@ const spawn = {
this.attraction();
};
},
shield(target, x, y, chance = Math.min(0.02 + simulation.difficulty * 0.005, 0.2), isBonusShield = false) {
shield(target, x, y, chance = Math.min(0.02 + simulation.difficulty * 0.005, 0.2), isExtraShield = false) {
if (this.allowShields && Math.random() < chance) {
mobs.spawn(x, y, 9, target.radius + 30, "rgba(220,220,255,0.9)");
let me = mob[mob.length - 1];
me.stroke = "rgb(220,220,255)";
Matter.Body.setDensity(me, 0.00001) //very low density to not mess with the original mob's motion
me.shield = true;
me.isBonusShield = isBonusShield //this prevents spamming with tech.isShieldAmmo
me.isExtraShield = isExtraShield //this prevents spamming with tech.isShieldAmmo
me.collisionFilter.category = cat.mobShield
me.collisionFilter.mask = cat.bullet;
consBB[consBB.length] = Constraint.create({

View File

@@ -170,7 +170,7 @@
return dmg * tech.slowFire * tech.aimDamage
},
duplicationChance() {
return (tech.isBayesian ? 0.2 : 0) + tech.cancelCount * 0.043 + tech.duplicateChance + m.duplicateChance
return (tech.isPowerUpsVanish ? 0.2 : 0) + (tech.isStimulatedEmission ? 0.2 : 0) + tech.cancelCount * 0.043 + tech.duplicateChance + m.duplicateChance
},
maxDuplicationEvent() {
if (tech.is100Duplicate && tech.duplicationChance() > 0.99) {
@@ -821,7 +821,7 @@
{
name: "electric reactive armor",
// description: "<strong class='color-e'>explosions</strong> do no <strong class='color-harm'>harm</strong><br> while your <strong class='color-f'>energy</strong> is above <strong>98%</strong>",
description: "<strong class='color-harm'>harm</strong> from <strong class='color-e'>explosions</strong> is passively reduced<br>by <strong>7%</strong> for every <strong>10</strong> stored <strong class='color-f'>energy</strong>",
description: "<strong class='color-harm'>harm</strong> from <strong class='color-e'>explosions</strong> is passively reduced<br>by <strong>6%</strong> for every <strong>10</strong> stored <strong class='color-f'>energy</strong>",
maxCount: 1,
count: 0,
frequency: 2,
@@ -1790,7 +1790,7 @@
count: 0,
frequency: 2,
allowed() {
return tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.relayIce || tech.blockingIce > 1
return tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.relayIce || tech.blockingIce > 1 || tech.iceIXOnDeath
},
requires: "a localized freeze effect",
effect() {
@@ -1807,7 +1807,7 @@
count: 0,
frequency: 2,
allowed() {
return tech.isStunField || tech.isExplosionStun || tech.oneSuperBall || tech.isHarmFreeze || tech.isIceField || tech.relayIce || tech.isIceCrystals || tech.isSporeFreeze || tech.isAoESlow || tech.isFreezeMobs || tech.isCloakStun || tech.orbitBotCount > 1 || tech.isWormholeDamage || tech.blockingIce > 1
return tech.isStunField || tech.isExplosionStun || tech.oneSuperBall || tech.isHarmFreeze || tech.isIceField || tech.relayIce || tech.isIceCrystals || tech.isSporeFreeze || tech.isAoESlow || tech.isFreezeMobs || tech.isCloakStun || tech.orbitBotCount > 1 || tech.isWormholeDamage || tech.blockingIce > 1 || tech.iceIXOnDeath
},
requires: "a freezing or stunning effect",
effect() {
@@ -2762,13 +2762,12 @@
requires: "below 100% duplication chance",
effect() {
tech.duplicateChance += 0.075
tech.maxDuplicationEvent()
simulation.draw.powerUp = simulation.draw.powerUpBonus //change power up draw
powerUps.setDo(); //needed after adjusting duplication chance
tech.addJunkTechToPool(12)
},
remove() {
tech.duplicateChance = 0
if (tech.duplicationChance() === 0) simulation.draw.powerUp = simulation.draw.powerUpNormal
powerUps.setDo(); //needed after adjusting duplication chance
if (this.count > 1) tech.removeJunkTechFromPool(12)
}
},
@@ -2780,17 +2779,36 @@
frequency: 1,
frequencyDefault: 1,
allowed() {
return tech.duplicationChance() < 1 && level.levelsCleared < 6
return tech.duplicationChance() < 1
},
requires: "below 100% duplication chance",
effect: () => {
tech.isBayesian = true
simulation.draw.powerUp = simulation.draw.powerUpBonus //change power up draw
tech.maxDuplicationEvent()
tech.isStimulatedEmission = true
powerUps.setDo(); //needed after adjusting duplication chance
},
remove() {
tech.isBayesian = false
if (tech.duplicationChance() === 0) simulation.draw.powerUp = simulation.draw.powerUpNormal
tech.isStimulatedEmission = false
powerUps.setDo(); //needed after adjusting duplication chance
}
},
{
name: "metastability",
description: "<strong>20%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br><strong class='color-dup'>duplicates</strong> <strong class='color-e'>explode</strong> with a <strong>3</strong> second half-life",
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return tech.duplicationChance() < 1
},
requires: "below 100% duplication chance",
effect: () => {
tech.isPowerUpsVanish = true
powerUps.setDo(); //needed after adjusting duplication chance
},
remove() {
tech.isPowerUpsVanish = false
powerUps.setDo(); //needed after adjusting duplication chance
}
},
{
@@ -2801,18 +2819,18 @@
frequency: 1,
frequencyDefault: 1,
allowed() {
return tech.duplicationChance() < 1 && !tech.isDeterminism && level.levelsCleared < 4
return tech.duplicationChance() < 1 && !tech.isDeterminism
},
requires: "below 100% duplication chance, below level 5, not determinism",
effect() {
// tech.cancelCount = 0
tech.isCancelDuplication = true
simulation.draw.powerUp = simulation.draw.powerUpBonus //change power up draw
powerUps.setDo(); //needed after adjusting duplication chance
},
remove() {
// tech.cancelCount = 0
tech.isCancelDuplication = false
if (tech.duplicationChance() === 0) simulation.draw.powerUp = simulation.draw.powerUpNormal
powerUps.setDo(); //needed after adjusting duplication chance
}
},
{
@@ -2953,7 +2971,7 @@
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span> <span class='color-symbol'>-=</span> 2
<br>${powerUps.research.count}`)
const chanceStore = tech.duplicateChance
tech.duplicateChance = (tech.isBayesian ? 0.2 : 0) + tech.cancelCount * 0.045 + m.duplicateChance + tech.duplicateChance * 2 //increase duplication chance to simulate doubling all 3 sources of duplication chance
tech.duplicateChance = (tech.isStimulatedEmission ? 0.2 : 0) + tech.cancelCount * 0.045 + m.duplicateChance + tech.duplicateChance * 2 //increase duplication chance to simulate doubling all 3 sources of duplication chance
powerUps.spawn(m.pos.x, m.pos.y, "tech");
tech.duplicateChance = chanceStore
},
@@ -3703,7 +3721,7 @@
},
remove() {
tech.wavePacketFrequency = 0.088 //0.0968 //0.1012 //0.11 //0.088 //shorten wave packet
tech.wavePacketLength = 36 //32.7 //31.3 //28.8 //36 //how many wave packets are released // double this to emit 2 packets
tech.wavePacketLength = 34 //32.7 //31.3 //28.8 //36 //how many wave packets are released // double this to emit 2 packets
tech.waveLengthRange = 130;
}
},
@@ -4818,7 +4836,7 @@
count: 0,
frequency: 2,
allowed() {
return tech.isIceField || tech.relayIce || tech.blockingIce
return tech.isIceField || tech.relayIce || tech.blockingIce || tech.iceIXOnDeath
},
requires: "ice IX",
effect() {
@@ -6528,7 +6546,7 @@
isGunCycle: null,
isFastFoam: null,
isSporeGrowth: null,
isBayesian: null,
isStimulatedEmission: null,
nailGun: null,
nailInstantFireRate: null,
isCapacitor: null,