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

BIN
.DS_Store vendored

Binary file not shown.

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,

View File

@@ -1,6 +1,7 @@
******************************************************** NEXT PATCH ********************************************************
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
******************************************************** BUGS ********************************************************
@@ -38,6 +39,14 @@ is there a way to check if the player is stuck inside the map or block
******************************************************** TODO ********************************************************
make wave packets a tech
use the tech that makes the wave packets longer?
default wave can be two oscillating waves
make beating the final boss without undefined feel like winning, not like dieing
try making more things const to change the color to purple in simulation loop
power ups disappear after 3-5 seconds
only apply to drops from killing mobs
+duplication 20%