explosion damage

all explosions do 33% more damage to mobs
  and 75% more damage to player
  boom bot explosions are 16% smaller

laser-bot does 15% more damage
missile bot fires 15% quicker
tech: phase velocity  also adds 15% wave damage  (because it disables phonon is was a bad choice)
many duplication tech add less duplication
Maxwell's demon now requires current energy above your max to unlock

power ups in the intro tube get pushed around a bit, this might stop them from sliding on the walls
mines when they are stuck to walls no longer collide with blocks  (to not block elevator)
more bug fixes
This commit is contained in:
landgreen
2021-09-04 18:45:13 -07:00
parent 13cc190211
commit 7f3fb1c214
11 changed files with 270 additions and 196 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -96,7 +96,7 @@ const b = {
outOfAmmo() { //triggers after firing when you have NO ammo outOfAmmo() { //triggers after firing when you have NO ammo
simulation.makeTextLog(`${b.guns[b.activeGun].name}.<span class='color-g'>ammo</span><span class='color-symbol'>:</span> 0`); simulation.makeTextLog(`${b.guns[b.activeGun].name}.<span class='color-g'>ammo</span><span class='color-symbol'>:</span> 0`);
m.fireCDcycle = m.cycle + 30; //fire cooldown m.fireCDcycle = m.cycle + 30; //fire cooldown
if (tech.isAmmoFromHealth && m.maxHealth > 0.01) { if (tech.isAmmoFromHealth && m.health > 0.01) {
tech.extraMaxHealth -= 0.01 //decrease max health tech.extraMaxHealth -= 0.01 //decrease max health
m.setMaxHealth(); m.setMaxHealth();
for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + 50 * (Math.random() - 0.5), m.pos.y + 50 * (Math.random() - 0.5), "ammo"); for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + 50 * (Math.random() - 0.5), m.pos.y + 50 * (Math.random() - 0.5), "ammo");
@@ -312,7 +312,7 @@ const b = {
explosion(where, radius, color = "rgba(255,25,0,0.6)") { // typically explode is used for some bullets with .onEnd explosion(where, radius, color = "rgba(255,25,0,0.6)") { // typically explode is used for some bullets with .onEnd
radius *= tech.explosiveRadius radius *= tech.explosiveRadius
let dist, sub, knock; let dist, sub, knock;
let dmg = radius * 0.013 * (tech.isExplosionStun ? 0.7 : 1); let dmg = radius * 0.017 * (tech.isExplosionStun ? 0.7 : 1); //* 0.013 * (tech.isExplosionStun ? 0.7 : 1);
if (tech.isExplosionHarm) radius *= 1.8 // 1/sqrt(2) radius -> area if (tech.isExplosionHarm) radius *= 1.8 // 1/sqrt(2) radius -> area
if (tech.isSmallExplosion) { if (tech.isSmallExplosion) {
color = "rgba(255,0,30,0.7)" color = "rgba(255,0,30,0.7)"
@@ -333,7 +333,7 @@ const b = {
//player damage //player damage
if (Vector.magnitude(Vector.sub(where, player.position)) < radius) { if (Vector.magnitude(Vector.sub(where, player.position)) < radius) {
const DRAIN = (tech.isExplosionHarm ? 0.7 : 0.25) * (tech.isRadioactiveResistance ? 0.25 : 1) const DRAIN = (tech.isExplosionHarm ? 1.2 : 0.45) * (tech.isRadioactiveResistance ? 0.25 : 1)
// * (tech.isImmuneExplosion ? Math.min(1, Math.max(1 - m.energy * 0.7, 0)) : 1) // * (tech.isImmuneExplosion ? Math.min(1, Math.max(1 - m.energy * 0.7, 0)) : 1)
if (m.immuneCycle < m.cycle) m.energy -= DRAIN if (m.immuneCycle < m.cycle) m.energy -= DRAIN
if (m.energy < 0) { if (m.energy < 0) {
@@ -381,11 +381,12 @@ const b = {
dist = Vector.magnitude(sub); dist = Vector.magnitude(sub);
if (dist < radius) { if (dist < radius) {
const harm = radius * (tech.isExplosionHarm ? 0.00055 : 0.00018)
if (tech.isImmuneExplosion) { if (tech.isImmuneExplosion) {
const mitigate = Math.min(1, Math.max(1 - m.energy * 0.7, 0)) const mitigate = Math.min(1, Math.max(1 - m.energy * 0.5, 0))
m.damage(mitigate * radius * (tech.isExplosionHarm ? 0.0003 : 0.0001)); m.damage(mitigate * harm);
} else { } else {
m.damage(radius * (tech.isExplosionHarm ? 0.0004 : 0.0001)); m.damage(harm);
} }
knock = Vector.mult(Vector.normalise(sub), -Math.sqrt(dmg) * player.mass * 0.013); knock = Vector.mult(Vector.normalise(sub), -Math.sqrt(dmg) * player.mass * 0.013);
player.force.x += knock.x; player.force.x += knock.x;
@@ -1713,7 +1714,8 @@ const b = {
if (angle > -0.2 || angle < -1.5) { //don't stick to level ground if (angle > -0.2 || angle < -1.5) { //don't stick to level ground
Matter.Body.setVelocity(this, { x: 0, y: 0 }); Matter.Body.setVelocity(this, { x: 0, y: 0 });
Matter.Body.setStatic(this, true) //don't set to static if not touching map Matter.Body.setStatic(this, true) //don't set to static if not touching map
this.collisionFilter.mask = cat.map | cat.bullet this.collisionFilter.category = 0
this.collisionFilter.mask = 0 //cat.map | cat.bullet
} else { } else {
Matter.Body.setVelocity(this, { x: 0, y: 0 }); Matter.Body.setVelocity(this, { x: 0, y: 0 });
Matter.Body.setAngularVelocity(this, 0) Matter.Body.setAngularVelocity(this, 0)
@@ -3219,7 +3221,7 @@ const b = {
range: (700 + 400 * tech.isLaserBotUpgrade) * (1 + 0.1 * Math.random()), range: (700 + 400 * tech.isLaserBotUpgrade) * (1 + 0.1 * Math.random()),
drainThreshold: tech.isEnergyHealth ? 0.6 : 0.4, drainThreshold: tech.isEnergyHealth ? 0.6 : 0.4,
drain: (0.56 - 0.42 * tech.isLaserBotUpgrade) * tech.laserFieldDrain * tech.isLaserDiode, drain: (0.56 - 0.42 * tech.isLaserBotUpgrade) * tech.laserFieldDrain * tech.isLaserDiode,
laserDamage: 0.7 + 0.5 * tech.isLaserBotUpgrade, laserDamage: 0.85 + 0.65 * tech.isLaserBotUpgrade,
endCycle: Infinity, endCycle: Infinity,
classType: "bullet", classType: "bullet",
collisionFilter: { collisionFilter: {
@@ -3312,7 +3314,7 @@ const b = {
explode: 0, explode: 0,
beforeDmg() { beforeDmg() {
if (this.lockedOn) { if (this.lockedOn) {
const explosionRadius = Math.min(170 + 220 * this.isUpgraded, Vector.magnitude(Vector.sub(this.position, m.pos)) - 30) const explosionRadius = Math.min(136 + 180 * this.isUpgraded, Vector.magnitude(Vector.sub(this.position, m.pos)) - 30)
if (explosionRadius > 60) { if (explosionRadius > 60) {
this.explode = explosionRadius this.explode = explosionRadius
// //
@@ -3399,12 +3401,10 @@ const b = {
onEnd() {}, onEnd() {},
do() { do() {
const distanceToPlayer = Vector.magnitude(Vector.sub(this.position, m.pos)) const distanceToPlayer = Vector.magnitude(Vector.sub(this.position, m.pos))
if (distanceToPlayer > 150) { //if far away move towards player if (distanceToPlayer > 150) this.force = Vector.mult(Vector.normalise(Vector.sub(m.pos, this.position)), this.mass * this.acceleration) //if far away move towards player
this.force = Vector.mult(Vector.normalise(Vector.sub(m.pos, this.position)), this.mass * this.acceleration)
}
Matter.Body.setVelocity(this, Vector.add(Vector.mult(this.velocity, 0.90), Vector.mult(player.velocity, 0.17))); //add player's velocity Matter.Body.setVelocity(this, Vector.add(Vector.mult(this.velocity, 0.90), Vector.mult(player.velocity, 0.17))); //add player's velocity
//find closest
if (!(simulation.cycle % this.lookFrequency)) { if (!(simulation.cycle % this.lookFrequency)) { //find closest
this.lockedOn = null; this.lockedOn = null;
if (!m.isCloak) { if (!m.isCloak) {
let closeDist = tech.isPlasmaRange * 1000; let closeDist = tech.isPlasmaRange * 1000;
@@ -3426,7 +3426,7 @@ const b = {
const DIST = Vector.magnitude(sub); const DIST = Vector.magnitude(sub);
const unit = Vector.normalise(sub) const unit = Vector.normalise(sub)
if (DIST < tech.isPlasmaRange * 450 && m.energy > this.drainThreshold) { if (DIST < tech.isPlasmaRange * 450 && m.energy > this.drainThreshold) {
m.energy -= 0.0003 + m.fieldRegen //0.004; //normal plasma field is 0.00008 + m.fieldRegen = 0.00108 m.energy -= 0.00035 + m.fieldRegen //0.004; //normal plasma field is 0.00008 + m.fieldRegen = 0.00108
// if (m.energy < 0) { // if (m.energy < 0) {
// m.fieldCDcycle = m.cycle + 120; // m.fieldCDcycle = m.cycle + 120;
// m.energy = 0; // m.energy = 0;
@@ -3501,7 +3501,7 @@ const b = {
y: best.y y: best.y
}; };
if (best.who.alive) { if (best.who.alive) {
const dmg = 0.65 * b.dmgScale; //********** SCALE DAMAGE HERE ********************* const dmg = 0.6 * b.dmgScale; //********** SCALE DAMAGE HERE *********************
best.who.damage(dmg); best.who.damage(dmg);
best.who.locatePlayer(); best.who.locatePlayer();
//push mobs away //push mobs away
@@ -3593,26 +3593,16 @@ const b = {
orbitalSpeed: 0, orbitalSpeed: 0,
phase: 2 * Math.PI * Math.random(), phase: 2 * Math.PI * Math.random(),
do() { do() {
//check for damage
if (!m.isCloak && !m.isBodiesAsleep) { //if time dilation isn't active if (!m.isCloak && !m.isBodiesAsleep) { //if time dilation isn't active
// q = Matter.Query.point(mob, this.position)
// q = Matter.Query.collides(this, mob)
const size = 33 const size = 33
q = Matter.Query.region(mob, { q = Matter.Query.region(mob, {
min: { min: { x: this.position.x - size, y: this.position.y - size },
x: this.position.x - size, max: { x: this.position.x + size, y: this.position.y + 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++) { for (let i = 0; i < q.length; i++) {
if (!q[i].isShielded) { if (!q[i].isShielded) {
mobs.statusStun(q[i], 180) mobs.statusStun(q[i], 180)
const dmg = 0.5 * b.dmgScale * (this.isUpgraded ? 3.5 : 1) * (tech.isCrit ? 4 : 1) const dmg = 0.4 * b.dmgScale * (this.isUpgraded ? 3.5 : 1) * (tech.isCrit ? 4 : 1)
q[i].damage(dmg); q[i].damage(dmg);
if (q[i].alive) q[i].foundPlayer(); if (q[i].alive) q[i].foundPlayer();
simulation.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
@@ -4401,6 +4391,7 @@ const b = {
if (tech.isPhaseVelocity) { if (tech.isPhaseVelocity) {
waveSpeedMap = 3 waveSpeedMap = 3
waveSpeedBody = 1.9 waveSpeedBody = 1.9
bullet[me].dmg *= 1.15
} }
if (tech.waveReflections) { if (tech.waveReflections) {
bullet[me].reflectCycle = totalCycles / tech.waveReflections //tech.waveLengthRange bullet[me].reflectCycle = totalCycles / tech.waveReflections //tech.waveLengthRange

View File

@@ -82,7 +82,6 @@ function getUrlVars() {
return vars; return vars;
} }
window.addEventListener('load', () => { window.addEventListener('load', () => {
const set = getUrlVars() const set = getUrlVars()
if (Object.keys(set).length !== 0) { if (Object.keys(set).length !== 0) {
build.populateGrid() //trying to solve a bug with this, but maybe it doesn't help build.populateGrid() //trying to solve a bug with this, but maybe it doesn't help
@@ -290,6 +289,7 @@ const build = {
window.scrollTo(0, 0); window.scrollTo(0, 0);
}, },
isExperimentSelection: false, isExperimentSelection: false,
isExperimentRun: false,
choosePowerUp(who, index, type, isAllowed = false) { choosePowerUp(who, index, type, isAllowed = false) {
if (type === "gun") { if (type === "gun") {
let isDeselect = false let isDeselect = false
@@ -360,24 +360,32 @@ const build = {
const isCount = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : ""; const isCount = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
// <div class="circle-grid-small research" style="position:absolute; top:13px; left:30px;opacity:0.85;"></div> // <div class="circle-grid-small research" style="position:absolute; top:13px; left:30px;opacity:0.85;"></div>
if (tech.tech[i].isFieldTech) { // if (tech.tech[i].isFieldTech) {
techID.innerHTML = ` <div class="grid-title"> // techID.classList.remove('experiment-grid-hide');
<span style="position:relative;">
<div class="circle-grid tech" style="position:absolute; top:0; left:0;opacity:0.8;"></div> // techID.innerHTML = `
<div class="circle-grid field" style="position:absolute; top:0; left:10px;opacity:0.65;"></div> // <div class="grid-title">
</span> // <span style="position:relative;">
&nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div>` // <div class="circle-grid tech" style="position:absolute; top:0; left:0;opacity:0.8;"></div>
// <div class="circle-grid gun" style="position:absolute; top:-3px; left:-3px; opacity:1; height: 33px; width:33px;"></div> // <div class="circle-grid field" style="position:absolute; top:0; left:10px;opacity:0.65;"></div>
// <div class="circle-grid tech" style="position:absolute; top:5px; left:5px;opacity:1;height: 20px; width:20px;border: #fff solid 2px;"></div> // </span>
// border: #fff solid 0px; // &nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}
} else if (tech.tech[i].isGunTech) { // </div>`
techID.innerHTML = ` <div class="grid-title"> // // <div class="circle-grid gun" style="position:absolute; top:-3px; left:-3px; opacity:1; height: 33px; width:33px;"></div>
<span style="position:relative;"> // // <div class="circle-grid tech" style="position:absolute; top:5px; left:5px;opacity:1;height: 20px; width:20px;border: #fff solid 2px;"></div>
<div class="circle-grid tech" style="position:absolute; top:0; left:0;opacity:0.8;"></div> // // border: #fff solid 0px;
<div class="circle-grid gun" style="position:absolute; top:0; left:10px; opacity:0.65;"></div> // } else if (tech.tech[i].isGunTech) {
</span> // techID.classList.remove('experiment-grid-hide');
&nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div>` // techID.innerHTML = `
} else if (tech.tech[i].isJunk) { // <div class="grid-title">
// <span style="position:relative;">
// <div class="circle-grid tech" style="position:absolute; top:0; left:0;opacity:0.8;"></div>
// <div class="circle-grid gun" style="position:absolute; top:0; left:10px; opacity:0.65;"></div>
// </span>
// &nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}
// </div>`
// } else
if (tech.tech[i].isJunk) {
// text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid junk"></div> &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div></div>` // text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid junk"></div> &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div></div>`
techID.innerHTML = `<div class="grid-title"><div class="circle-grid junk"></div> &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div>` techID.innerHTML = `<div class="grid-title"><div class="circle-grid junk"></div> &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div>`
} else if (tech.tech[i].isExperimentalMode) { } else if (tech.tech[i].isExperimentalMode) {
@@ -394,6 +402,8 @@ const build = {
techID.classList.remove("experiment-grid-disabled"); techID.classList.remove("experiment-grid-disabled");
techID.setAttribute("onClick", `javascript: build.choosePowerUp(this,${i},'tech')`); techID.setAttribute("onClick", `javascript: build.choosePowerUp(this,${i},'tech')`);
} }
// } else if (tech.tech[i].isGunTech || tech.tech[i].isFieldTech) {
// techID.classList.add('experiment-grid-hide');
} else { //disabled color } else { //disabled color
// techID.innerHTML = `<div class="grid-title"> ${tech.tech[i].name}</div><span style="color:#666;">requires: ${tech.tech[i].requires}</span></div>` // techID.innerHTML = `<div class="grid-title"> ${tech.tech[i].name}</div><span style="color:#666;">requires: ${tech.tech[i].requires}</span></div>`
// techID.innerHTML = `<div class="grid-title"> ${tech.tech[i].name}</div><span style="color:#666;">requires: ${tech.tech[i].requires}</span></div>` // techID.innerHTML = `<div class="grid-title"> ${tech.tech[i].name}</div><span style="color:#666;">requires: ${tech.tech[i].requires}</span></div>`
@@ -459,8 +469,15 @@ const build = {
text += `<div id="tech-${i}" class="experiment-grid-module" onclick="build.choosePowerUp(this,${i},'tech')"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[i].name}</div> ${tech.tech[i].description}</div>` text += `<div id="tech-${i}" class="experiment-grid-module" onclick="build.choosePowerUp(this,${i},'tech')"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[i].name}</div> ${tech.tech[i].description}</div>`
} }
} else { } else {
// text += `<div id="tech-${i}" class="experiment-grid-module "><div class="grid-title">${tech.tech[i].name}</div><span style="color:#666;">requires: ${tech.tech[i].requires}</span></div>`
text += `<div id="tech-${i}" class="experiment-grid-module experiment-grid-disabled"><div class="grid-title"> ${tech.tech[i].name}</div> ${tech.tech[i].description}</div>` text += `<div id="tech-${i}" class="experiment-grid-module experiment-grid-disabled"><div class="grid-title"> ${tech.tech[i].name}</div> ${tech.tech[i].description}</div>`
// if (tech.tech[i].isGunTech || tech.tech[i].isFieldTech) {
// text += `<div id="tech-${i}" class="experiment-grid-module experiment-grid-disabled experiment-grid-hide"></div>` //built but hidden
// } else {
// text += `<div id="tech-${i}" class="experiment-grid-module experiment-grid-disabled"><div class="grid-title"> ${tech.tech[i].name}</div> ${tech.tech[i].description}</div>`
// }
// } else if (!tech.tech[i].isGunTech && !tech.tech[i].isFieldTech) {
// text += `<div id="tech-${i}" class="experiment-grid-module "><div class="grid-title">${tech.tech[i].name}</div><span style="color:#666;">requires: ${tech.tech[i].requires}</span></div>`
} }
} }
} }
@@ -483,6 +500,7 @@ const build = {
reset() { reset() {
simulation.startGame(true); //starts game, but pauses it simulation.startGame(true); //starts game, but pauses it
build.isExperimentSelection = true; build.isExperimentSelection = true;
build.isExperimentRun = true;
simulation.paused = true; simulation.paused = true;
m.setField(0) m.setField(0)
b.inventory = []; //removes guns and ammo b.inventory = []; //removes guns and ammo

View File

@@ -62,7 +62,7 @@ const level = {
spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
// spawn.pickList = ["focuser", "focuser"] // spawn.pickList = ["focuser", "focuser"]
level[level.levels[level.onLevel]](); //picks the current map from the the levels array level[level.levels[level.onLevel]](); //picks the current map from the the levels array
if (!simulation.isCheating) { if (!simulation.isCheating && !build.isExperimentRun) {
localSettings.runCount += level.levelsCleared //track the number of total runs locally localSettings.runCount += level.levelsCleared //track the number of total runs locally
localSettings.levelsClearedLastGame = level.levelsCleared localSettings.levelsClearedLastGame = level.levelsCleared
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
@@ -2273,12 +2273,12 @@ const level = {
spawn.mapRect(4850, -275, 50, 175); spawn.mapRect(4850, -275, 50, 175);
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
// spawn.starter(1900, -500, 200) //big boy // spawn.starter(1900, -500, 200) //big boy
spawn.necroBoss(1900, -500) spawn.blockBoss(1900, -500)
// for (let i = 0; i < 10; ++i) spawn.bodyRect(1600 + 5, -500, 30, 40); // for (let i = 0; i < 10; ++i) spawn.bodyRect(1600 + 5, -500, 30, 40);
// spawn.laserBombingBoss(1900, -500) // spawn.laserBombingBoss(1900, -500)
// for (let i = 0; i < 5; i++) spawn.focuser(1900, -500) // for (let i = 0; i < 5; i++) spawn.focuser(1900, -500)
// spawn.blockGroup(1900, -500) // spawn.snakeSuckBoss(1900, -500)
// spawn.grenadier(1900, -500) // spawn.grenadier(1900, -500)
// spawn.sneaker(1900, -500) // spawn.sneaker(1900, -500)
// spawn.shield(mob[mob.length - 1], 1900, -500, 1); // spawn.shield(mob[mob.length - 1], 1900, -500, 1);
@@ -2469,7 +2469,7 @@ const level = {
powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070 - 75, "heal", false); powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070 - 75, "heal", false);
powerUps.spawnStartingPowerUps(2095 + 15 * (Math.random() - 0.5), -2070 - 125); powerUps.spawnStartingPowerUps(2095 + 15 * (Math.random() - 0.5), -2070 - 125);
if (localSettings.levelsClearedLastGame < 3) { if (localSettings.levelsClearedLastGame < 3) {
if (!simulation.isCheating && !m.isShipMode) { if (!simulation.isCheating && !m.isShipMode && !build.isExperimentRun) {
spawn.wireFoot(); spawn.wireFoot();
spawn.wireFootLeft(); spawn.wireFootLeft();
spawn.wireKnee(); spawn.wireKnee();
@@ -2478,7 +2478,7 @@ const level = {
// for (let i = 0; i < 3; i++) powerUps.spawn(2095, -1220 - 50 * i, "tech", false); //unavailable tech spawns // for (let i = 0; i < 3; i++) powerUps.spawn(2095, -1220 - 50 * i, "tech", false); //unavailable tech spawns
// spawn.mapRect(2000, -1025, 200, 25); // spawn.mapRect(2000, -1025, 200, 25);
} }
} else { } else if (!build.isExperimentRun) {
simulation.trails() simulation.trails()
//bonus power ups for clearing runs in the last game //bonus power ups for clearing runs in the last game
if (!simulation.isCheating && localSettings.levelsClearedLastGame > 1) { if (!simulation.isCheating && localSettings.levelsClearedLastGame > 1) {
@@ -2489,13 +2489,103 @@ const level = {
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
} }
} }
spawn.mapRect(2025, 0, 150, 50); //lid to floor hole
} else { } else {
for (let i = 0; i < 60; i++) { for (let i = 0; i < 60; i++) {
setTimeout(() => { spawn.sneaker(2100, -1500 - 50 * i); }, 2000 + 500 * i); setTimeout(() => { spawn.sneaker(2100, -1500 - 50 * i); }, 2000 + 500 * i);
} }
} }
const wires = new Path2D() //pre-draw the complex lighting path to save processing
wires.moveTo(-150, -275)
wires.lineTo(80, -275)
wires.lineTo(80, -1000)
wires.moveTo(-150, -265)
wires.lineTo(90, -265)
wires.lineTo(90, -1000)
wires.moveTo(-150, -255)
wires.lineTo(100, -255)
wires.lineTo(100, -1000)
wires.moveTo(-150, -245)
wires.lineTo(1145, -245)
wires.lineTo(1145, 0)
wires.moveTo(-150, -235)
wires.lineTo(1135, -235)
wires.lineTo(1135, 0)
wires.moveTo(-150, -225)
wires.lineTo(1125, -225)
wires.lineTo(1125, 0)
wires.moveTo(-150, -215)
wires.lineTo(460, -215)
wires.lineTo(460, 0)
wires.moveTo(-150, -205)
wires.lineTo(450, -205)
wires.lineTo(450, 0)
wires.moveTo(-150, -195)
wires.lineTo(440, -195)
wires.lineTo(440, 0)
wires.moveTo(1155, 0)
wires.lineTo(1155, -450)
wires.lineTo(1000, -450)
wires.lineTo(1000, -1000)
wires.moveTo(1165, 0)
wires.lineTo(1165, -460)
wires.lineTo(1010, -460)
wires.lineTo(1010, -1000)
wires.moveTo(1175, 0)
wires.lineTo(1175, -470)
wires.lineTo(1020, -470)
wires.lineTo(1020, -1000)
wires.moveTo(1185, 0)
wires.lineTo(1185, -480)
wires.lineTo(1030, -480)
wires.lineTo(1030, -1000)
wires.moveTo(1195, 0)
wires.lineTo(1195, -490)
wires.lineTo(1040, -490)
wires.lineTo(1040, -1000)
wires.moveTo(1625, -1000)
wires.lineTo(1625, 0)
wires.moveTo(1635, -1000)
wires.lineTo(1635, 0)
wires.moveTo(1645, -1000)
wires.lineTo(1645, 0)
wires.moveTo(1655, -1000)
wires.lineTo(1655, 0)
wires.moveTo(1665, -1000)
wires.lineTo(1665, 0)
wires.moveTo(1675, -465)
wires.lineTo(2325, -465)
wires.lineTo(2325, 0)
wires.moveTo(1675, -455)
wires.lineTo(2315, -455)
wires.lineTo(2315, 0)
wires.moveTo(1675, -445)
wires.lineTo(2305, -445)
wires.lineTo(2305, 0)
wires.moveTo(1675, -435)
wires.lineTo(2295, -435)
wires.lineTo(2295, 0)
wires.moveTo(2335, 0)
wires.lineTo(2335, -710)
wires.lineTo(2600, -710)
wires.moveTo(2345, 0)
wires.lineTo(2345, -700)
wires.lineTo(2600, -700)
wires.moveTo(2355, 0)
wires.lineTo(2355, -690)
wires.lineTo(2600, -690)
level.custom = () => { level.custom = () => {
//push around power ups stuck in the tube wall
if (!(simulation.cycle % 30)) {
for (let i = 0, len = powerUp.length; i < len; i++) {
if (powerUp[i].position.y < -1000) powerUp[i].force.x += 0.01 * (Math.random() - 0.5) * powerUp[i].mass
}
}
//draw binary number //draw binary number
const binary = (localSettings.runCount >>> 0).toString(2) const binary = (localSettings.runCount >>> 0).toString(2)
const height = 20 const height = 20
@@ -2521,93 +2611,10 @@ const level = {
} }
ctx.stroke(); ctx.stroke();
//wires
ctx.beginPath() ctx.beginPath()
ctx.moveTo(-150, -275)
ctx.lineTo(80, -275)
ctx.lineTo(80, -1000)
ctx.moveTo(-150, -265)
ctx.lineTo(90, -265)
ctx.lineTo(90, -1000)
ctx.moveTo(-150, -255)
ctx.lineTo(100, -255)
ctx.lineTo(100, -1000)
ctx.moveTo(-150, -245)
ctx.lineTo(1145, -245)
ctx.lineTo(1145, 0)
ctx.moveTo(-150, -235)
ctx.lineTo(1135, -235)
ctx.lineTo(1135, 0)
ctx.moveTo(-150, -225)
ctx.lineTo(1125, -225)
ctx.lineTo(1125, 0)
ctx.moveTo(-150, -215)
ctx.lineTo(460, -215)
ctx.lineTo(460, 0)
ctx.moveTo(-150, -205)
ctx.lineTo(450, -205)
ctx.lineTo(450, 0)
ctx.moveTo(-150, -195)
ctx.lineTo(440, -195)
ctx.lineTo(440, 0)
ctx.moveTo(1155, 0)
ctx.lineTo(1155, -450)
ctx.lineTo(1000, -450)
ctx.lineTo(1000, -1000)
ctx.moveTo(1165, 0)
ctx.lineTo(1165, -460)
ctx.lineTo(1010, -460)
ctx.lineTo(1010, -1000)
ctx.moveTo(1175, 0)
ctx.lineTo(1175, -470)
ctx.lineTo(1020, -470)
ctx.lineTo(1020, -1000)
ctx.moveTo(1185, 0)
ctx.lineTo(1185, -480)
ctx.lineTo(1030, -480)
ctx.lineTo(1030, -1000)
ctx.moveTo(1195, 0)
ctx.lineTo(1195, -490)
ctx.lineTo(1040, -490)
ctx.lineTo(1040, -1000)
ctx.moveTo(1625, -1000)
ctx.lineTo(1625, 0)
ctx.moveTo(1635, -1000)
ctx.lineTo(1635, 0)
ctx.moveTo(1645, -1000)
ctx.lineTo(1645, 0)
ctx.moveTo(1655, -1000)
ctx.lineTo(1655, 0)
ctx.moveTo(1665, -1000)
ctx.lineTo(1665, 0)
ctx.moveTo(1675, -465)
ctx.lineTo(2325, -465)
ctx.lineTo(2325, 0)
ctx.moveTo(1675, -455)
ctx.lineTo(2315, -455)
ctx.lineTo(2315, 0)
ctx.moveTo(1675, -445)
ctx.lineTo(2305, -445)
ctx.lineTo(2305, 0)
ctx.moveTo(1675, -435)
ctx.lineTo(2295, -435)
ctx.lineTo(2295, 0)
ctx.moveTo(2335, 0)
ctx.lineTo(2335, -710)
ctx.lineTo(2600, -710)
ctx.moveTo(2345, 0)
ctx.lineTo(2345, -700)
ctx.lineTo(2600, -700)
ctx.moveTo(2355, 0)
ctx.lineTo(2355, -690)
ctx.lineTo(2600, -690)
ctx.strokeStyle = "#ccc" ctx.strokeStyle = "#ccc"
ctx.lineWidth = 5; ctx.lineWidth = 5;
ctx.stroke(); ctx.stroke(wires);
//squares that look like they keep the wires in place //squares that look like they keep the wires in place
ctx.beginPath() ctx.beginPath()
@@ -2677,7 +2684,6 @@ const level = {
spawn.mapRect(2150, 0, 1200, 1800); //split roof spawn.mapRect(2150, 0, 1200, 1800); //split roof
spawn.mapRect(2025, -3, 25, 15); //lip on power up chamber spawn.mapRect(2025, -3, 25, 15); //lip on power up chamber
spawn.mapRect(2150, -3, 25, 15); //lip on power up chamber spawn.mapRect(2150, -3, 25, 15); //lip on power up chamber
spawn.mapRect(2025, 0, 150, 50);
// spawn.mapRect(-250, -2800, 3600, 1800); //roof // spawn.mapRect(-250, -2800, 3600, 1800); //roof
spawn.mapRect(-250, -2800, 2300, 1800); //split roof spawn.mapRect(-250, -2800, 2300, 1800); //split roof

View File

@@ -2587,9 +2587,9 @@ const m = {
}, },
{ {
name: "wormhole", name: "wormhole",
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 <strong class='color-block'>blocks</strong> and power ups<br><strong>8%</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> 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 <strong class='color-block'>blocks</strong> 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() { effect: function() {
m.duplicateChance = 0.08 m.duplicateChance = 0.07
powerUps.setDo(); //needed after adjusting duplication chance powerUps.setDo(); //needed after adjusting duplication chance
m.hold = function() { m.hold = function() {

View File

@@ -260,11 +260,11 @@ const powerUps = {
tech.maxDuplicationEvent() tech.maxDuplicationEvent()
} }
if (tech.isCancelRerolls) { if (tech.isCancelRerolls) {
for (let i = 0; i < 9; i++) { for (let i = 0, len = 5 + 5 * Math.random(); i < len; i++) {
let spawnType = ((m.health < 0.25 && !tech.isEnergyHealth) || tech.isEnergyNoAmmo) ? "heal" : "ammo" let spawnType = ((m.health < 0.25 && !tech.isEnergyHealth) || tech.isEnergyNoAmmo) ? "heal" : "ammo"
if (Math.random() < 0.33) { if (Math.random() < 0.36) {
spawnType = "heal" spawnType = "heal"
} else if (Math.random() < 0.5 && !tech.isSuperDeterminism) { } else if (Math.random() < 0.4 && !tech.isSuperDeterminism) {
spawnType = "research" spawnType = "research"
} }
powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), spawnType, false); powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), spawnType, false);

View File

@@ -644,6 +644,7 @@ const simulation = {
simulation.difficultyMode = Number(document.getElementById("difficulty-select").value) simulation.difficultyMode = Number(document.getElementById("difficulty-select").value)
build.isExperimentSelection = false; build.isExperimentSelection = false;
build.isExperimentRun = false;
simulation.clearNow = true; simulation.clearNow = true;
document.getElementById("text-log").style.opacity = 0; document.getElementById("text-log").style.opacity = 0;
document.getElementById("fade-out").style.opacity = 0; document.getElementById("fade-out").style.opacity = 0;

View File

@@ -1,7 +1,7 @@
//main object for spawning things in a level //main object for spawning things in a level
const spawn = { const spawn = {
nonCollideBossList: ["cellBossCulture", "bomberBoss", "powerUpBoss", "orbitalBoss", "spawnerBossCulture", "growBossCulture"], nonCollideBossList: ["cellBossCulture", "bomberBoss", "powerUpBoss", "orbitalBoss", "spawnerBossCulture", "growBossCulture"],
randomLevelBoss(x, y, options = ["shieldingBoss", "orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss", "snakeBoss", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss", "snakeSpitBoss", "laserBombingBoss", "blockBoss", "blockBoss", "blockBoss"]) { randomLevelBoss(x, y, options = ["shieldingBoss", "orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss", "snakeBoss", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss", "snakeSpitBoss", "laserBombingBoss", "blockBoss", "blockBoss"]) {
// other bosses: suckerBoss, laserBoss, tetherBoss, //these need a particular level to work so they are not included in the random pool // 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) spawn[options[Math.floor(Math.random() * options.length)]](x, y)
}, },
@@ -726,14 +726,14 @@ const spawn = {
} }
} }
}, },
blockBoss(x, y, radius = 30) { blockBoss(x, y, radius = 60) {
const activeBeams = []; // used to draw beams when converting const activeBeams = []; // used to draw beams when converting
const beamTotalDuration = 60 const beamTotalDuration = 60
mobs.spawn(x, y, 4, radius, "#999"); //#54291d mobs.spawn(x, y, 4, radius, "#999"); //#54291d
const me = mob[mob.length - 1]; const me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
// Matter.Body.setDensity(me, 0.001); //normal density even though its a boss Matter.Body.setDensity(me, 0.002); //normal density even though its a boss
me.damageReduction = 0.06; //extra reduction for a boss, because normal density me.damageReduction = 0.05; //extra reduction for a boss, because normal density
me.frictionAir = 0.01; me.frictionAir = 0.01;
me.accelMag = 0.0002; me.accelMag = 0.0002;
me.onDeath = function() { me.onDeath = function() {
@@ -786,14 +786,19 @@ const spawn = {
} }
//randomly spawn new mobs from nothing //randomly spawn new mobs from nothing
if (!(simulation.cycle % 120)) { if (!(simulation.cycle % 90)) {
let count = 0 let count = 0
for (let i = 0, len = mob.length; i < len; i++) { for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].isNecroMob) count++ if (mob[i].isNecroMob) count++
} }
if (count < 12 * Math.random() * Math.random()) { //limit number of spawns if there are already too many blockMobs if (count < 20 * Math.random() * Math.random()) { //limit number of spawns if there are already too many blockMobs
const unit = Vector.normalise(Vector.sub(player.position, this.position)) const unit = Vector.normalise(Vector.sub(player.position, this.position))
for (let i = 0, len = 3 * Math.random(); i < len; i++) { for (let i = 0, len = 3 * Math.random(); i < len; i++) {
this.damageReduction += 0.001; //0.05 is starting value
const scale = 0.99; //if 120 use 1.02
Matter.Body.scale(this, scale, scale);
this.radius *= scale;
const where = Vector.add(Vector.mult(unit, radius + 200 * Math.random()), this.position) const where = Vector.add(Vector.mult(unit, radius + 200 * Math.random()), this.position)
spawn.blockMob(where.x + 100 * (Math.random() - 0.5), where.y + 100 * (Math.random() - 0.5), null); spawn.blockMob(where.x + 100 * (Math.random() - 0.5), where.y + 100 * (Math.random() - 0.5), null);
this.torque += 0.000035 * this.inertia; //spin after spawning this.torque += 0.000035 * this.inertia; //spin after spawning
@@ -1836,7 +1841,7 @@ const spawn = {
mobs.spawn(x, y, 0, radius, "transparent"); mobs.spawn(x, y, 0, radius, "transparent");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
Matter.Body.setDensity(me, 0.21); //extra dense //normal is 0.001 Matter.Body.setDensity(me, 0.21); //extra dense //normal is 0.001
me.laserRange = 300; me.laserRange = 350;
me.seeAtDistance2 = 2000000; me.seeAtDistance2 = 2000000;
me.isBoss = true; me.isBoss = true;
@@ -1849,7 +1854,7 @@ const spawn = {
me.onDeath = function() { me.onDeath = function() {
powerUps.spawnBossPowerUp(this.position.x, this.position.y) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
}; };
me.damageReduction = 0.25 // me.damageReductionGoal me.damageReduction = 0.35 // me.damageReductionGoal
me.awake = function() { me.awake = function() {
// this.armor(); // this.armor();
this.checkStatus(); this.checkStatus();
@@ -1879,9 +1884,9 @@ const spawn = {
if (this.distanceToPlayer() < this.laserRange) { if (this.distanceToPlayer() < this.laserRange) {
if (m.immuneCycle < m.cycle) { if (m.immuneCycle < m.cycle) {
if (m.energy > 0.002) { if (m.energy > 0.002) {
m.energy -= 0.0035 m.energy -= 0.004
} else { } else {
m.damage(0.0003 * simulation.dmgScale) m.damage(0.0004 * simulation.dmgScale)
} }
} }
ctx.beginPath(); ctx.beginPath();

View File

@@ -193,7 +193,7 @@
return dmg * tech.slowFire * tech.aimDamage return dmg * tech.slowFire * tech.aimDamage
}, },
duplicationChance() { duplicationChance() {
return (tech.isPowerUpsVanish ? 0.15 : 0) + (tech.isStimulatedEmission ? 0.2 : 0) + tech.cancelCount * 0.047 + tech.duplicateChance + m.duplicateChance + tech.wormDuplicate + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0) return (tech.isPowerUpsVanish ? 0.13 : 0) + (tech.isStimulatedEmission ? 0.17 : 0) + tech.cancelCount * 0.045 + tech.duplicateChance + m.duplicateChance + tech.wormDuplicate + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0)
}, },
maxDuplicationEvent() { maxDuplicationEvent() {
if (tech.is100Duplicate && tech.duplicationChance() > 0.99) { if (tech.is100Duplicate && tech.duplicationChance() > 0.99) {
@@ -849,7 +849,6 @@
{ {
name: "shock wave", name: "shock wave",
description: "<strong class='color-e'>explosions</strong> <strong>stun</strong> mobs for <strong>1-2</strong> seconds<br>decrease <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong> by <strong>30%</strong>", description: "<strong class='color-e'>explosions</strong> <strong>stun</strong> mobs for <strong>1-2</strong> seconds<br>decrease <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong> by <strong>30%</strong>",
isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -868,7 +867,7 @@
{ {
name: "electric reactive armor", 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-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>6%</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>5%</strong> for every <strong>10</strong> stored <strong class='color-f'>energy</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
@@ -892,7 +891,7 @@
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return ((m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isDroneTeleport || tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isDroneRadioactive && !tech.isDroneTeleport) || tech.haveGunCheck("super balls") || tech.haveGunCheck("shotgun")) && !tech.isNailShot && !tech.isIceShot && !tech.isFoamShot && !tech.isWormShot return ((m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isDroneTeleport || tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isDroneRadioactive && !tech.isDroneTeleport) || tech.haveGunCheck("super balls") || tech.haveGunCheck("shotgun")) && !tech.isNailShot && !tech.isIceShot && !tech.isFoamShot && !tech.isWormShot && !tech.isNeedles
}, },
requires: "super balls, basic or slug shotgun, drones, not irradiated drones or burst drones", requires: "super balls, basic or slug shotgun, drones, not irradiated drones or burst drones",
effect() { effect() {
@@ -1590,7 +1589,7 @@
frequency: 3, frequency: 3,
frequencyDefault: 3, frequencyDefault: 3,
allowed() { allowed() {
return tech.throwChargeRate > 1 && m.fieldUpgrades[m.fieldMode].name === "pilot wave" && !tech.isTokamak return tech.throwChargeRate > 1 && m.fieldUpgrades[m.fieldMode].name !== "pilot wave" && m.fieldUpgrades[m.fieldMode].name !== "wormhole" && !tech.isTokamak
}, },
requires: "mass driver, not pilot wave not tokamak", requires: "mass driver, not pilot wave not tokamak",
effect() { effect() {
@@ -1608,7 +1607,7 @@
frequency: 3, frequency: 3,
frequencyDefault: 3, frequencyDefault: 3,
allowed() { allowed() {
return tech.throwChargeRate > 1 && m.fieldUpgrades[m.fieldMode].name === "pilot wave" && !tech.isTokamak return tech.throwChargeRate > 1 && m.fieldUpgrades[m.fieldMode].name !== "pilot wave" && m.fieldUpgrades[m.fieldMode].name !== "wormhole" && !tech.isTokamak
}, },
requires: "mass driver, not pilot wave not tokamak", requires: "mass driver, not pilot wave not tokamak",
effect() { effect() {
@@ -1662,7 +1661,7 @@
frequency: 3, frequency: 3,
frequencyDefault: 3, frequencyDefault: 3,
allowed() { allowed() {
return tech.throwChargeRate > 1 && m.fieldUpgrades[m.fieldMode].name === "pilot wave" && m.fieldUpgrades[m.fieldMode].name !== "wormhole" && !tech.isEnergyHealth return tech.throwChargeRate > 1 && m.fieldUpgrades[m.fieldMode].name !== "pilot wave" && m.fieldUpgrades[m.fieldMode].name !== "wormhole" && !tech.isEnergyHealth
}, },
requires: "mass driver, a field that can hold things, not mass-energy", requires: "mass driver, a field that can hold things, not mass-energy",
effect() { effect() {
@@ -2182,7 +2181,7 @@
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return !tech.isZeno && !tech.isNoHeals && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isRewindGun && !tech.isTechDamage && !tech.isMutualism return !tech.isZeno && !tech.isNoHeals && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isRewindGun && !tech.isTechDamage && !tech.isMutualism //&& !tech.isAmmoFromHealth
}, },
requires: "not Zeno, ergodicity, piezoelectricity, CPT, rewind gun, antiscience, mutualism", requires: "not Zeno, ergodicity, piezoelectricity, CPT, rewind gun, antiscience, mutualism",
effect: () => { effect: () => {
@@ -2391,9 +2390,9 @@
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.isEnergyRecovery || tech.isPiezo || tech.energySiphon > 0 || tech.isRailEnergyGain || tech.isWormholeEnergy || tech.iceEnergy > 0 || tech.isMassEnergy || tech.isTokamak return m.energy > m.maxEnergy || build.isExperimentSelection
}, },
requires: "a source of overfilled energy", requires: "energy above your max",
effect() { effect() {
tech.overfillDrain = 0.85 //70% = 1-(1-0.75)/(1-0.15) //92% = 1-(1-0.75)/(1-0.87) tech.overfillDrain = 0.85 //70% = 1-(1-0.75)/(1-0.15) //92% = 1-(1-0.75)/(1-0.87)
tech.addJunkTechToPool(18) tech.addJunkTechToPool(18)
@@ -3057,7 +3056,7 @@
}, },
{ {
name: "stimulated emission", name: "stimulated emission",
description: "<strong>20%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>but, after a <strong>collision</strong> eject <strong>1</strong> <strong class='color-m'>tech</strong>", description: "<strong>17%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>but, after a <strong>collision</strong> eject <strong>1</strong> <strong class='color-m'>tech</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -3077,7 +3076,7 @@
}, },
{ {
name: "metastability", name: "metastability",
description: "<strong>15%</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 <strong>half-life</strong> ", description: "<strong>13%</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 <strong>half-life</strong> ",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -3097,7 +3096,7 @@
}, },
{ {
name: "futures exchange", name: "futures exchange",
description: "clicking <strong style = 'font-size:150%;'>×</strong> to <strong>cancel</strong> a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>adds <strong>4.7%</strong> power up <strong class='color-dup'>duplication</strong> chance", description: "clicking <strong style = 'font-size:150%;'>×</strong> to <strong>cancel</strong> a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>adds <strong>4.5%</strong> power up <strong class='color-dup'>duplication</strong> chance",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -3117,7 +3116,7 @@
}, },
{ {
name: "commodities exchange", name: "commodities exchange",
description: `clicking <strong style = 'font-size:150%;'>×</strong> to cancel a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>spawns <strong>9</strong> ${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, or ${powerUps.orb.research(1)}`, description: `clicking <strong style = 'font-size:150%;'>×</strong> to cancel a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>spawns <strong>5-10</strong> ${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, or ${powerUps.orb.research(1)}`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -3632,9 +3631,9 @@
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return (tech.isNeedles || tech.isNeedleShot) && !tech.isNailRadiation return (tech.isNeedles || tech.isNeedleShot)
}, },
requires: "needle gun, needle-shot, not irradiated nails", requires: "needle gun, needle-shot",
effect() { effect() {
tech.isNeedleShieldPierce = true tech.isNeedleShieldPierce = true
}, },
@@ -3864,7 +3863,7 @@
}, },
{ {
name: "shotgun spin-statistics", name: "shotgun spin-statistics",
description: "<strong>immune</strong> to <strong class='color-harm'>harm</strong> while firing the <strong>shotgun</strong><br>shotgun has gives <strong>50%</strong> fewer shots", description: "<strong>immune</strong> to <strong class='color-harm'>harm</strong> while firing the <strong>shotgun</strong><br>shotgun has <strong>50%</strong> fewer shots",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -4129,7 +4128,8 @@
}, },
{ {
name: "phase velocity", name: "phase velocity",
description: "wave beam <strong>propagates</strong> faster through <strong>solids</strong><br>up by <strong>3000%</strong> in the map and <strong>760%</strong> in <strong class='color-block'>blocks</strong>", description: "wave beam <strong>propagates</strong> faster through <strong>solids</strong><br>increase wave beam <strong class='color-d'>damage</strong> by <strong>15%</strong>",
// description: "wave beam <strong>propagates</strong> faster through <strong>solids</strong><br>up by <strong>3000%</strong> in the map and <strong>760%</strong> in <strong class='color-block'>blocks</strong>",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -4709,7 +4709,8 @@
}, },
{ {
name: "drone repair", name: "drone repair",
description: "broken <strong>drones</strong> <strong>repair</strong> if the drone <strong class='color-g'>gun</strong> is active<br><strong>repairing</strong> has a <strong>25%</strong> chance to use <strong>1</strong> <strong>drone</strong>", description: "after a <strong>drone</strong> ends it <strong>redeploys</strong><br>for a <strong>25%</strong> chance to use <strong>1</strong> <strong>drone</strong> <strong class='color-ammo'>ammo</strong>",
// description: "broken <strong>drones</strong> <strong>repair</strong> if the drone <strong class='color-g'>gun</strong> is active<br><strong>repairing</strong> has a <strong>25%</strong> chance to use <strong>1</strong> <strong>drone</strong>",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -6077,7 +6078,7 @@
}, },
{ {
name: "virtual particles", name: "virtual particles",
description: `use ${powerUps.orb.research(4)}to exploit your <strong>wormhole</strong> for a<br><strong>16%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>`, description: `use ${powerUps.orb.research(4)}to exploit your <strong>wormhole</strong> for a<br><strong>14%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>`,
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -6088,7 +6089,7 @@
}, },
requires: "wormhole,below 100% duplication chance", requires: "wormhole,below 100% duplication chance",
effect() { effect() {
tech.wormDuplicate = 0.16 tech.wormDuplicate = 0.14
powerUps.setDo(); //needed after adjusting duplication chance powerUps.setDo(); //needed after adjusting duplication chance
for (let i = 0; i < 4; i++) { for (let i = 0; i < 4; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
@@ -6809,6 +6810,27 @@
}, },
remove() {} remove() {}
}, },
{
name: "score",
description: "Add a score to n-gon!",
maxCount: 1,
count: 0,
frequency: 0,
isNonRefundable: true,
isExperimentHide: true,
isJunk: true,
allowed() {
return true
},
requires: "",
effect() {
setInterval(() => {
let score = Math.ceil(1000 * Math.random() * Math.random() * Math.random() * Math.random() * Math.random())
simulation.makeTextLog(`simulation.score <span class='color-symbol'>=</span> ${score.toFixed(0)}`);
}, 1000); //every 10 seconds
},
remove() {}
},
{ {
name: "pop-ups", name: "pop-ups",
description: "sign up to learn endless easy ways to win n-gon<br>that Landgreen doesn't want you to know!!!1!!", description: "sign up to learn endless easy ways to win n-gon<br>that Landgreen doesn't want you to know!!!1!!",

View File

@@ -272,6 +272,22 @@ summary {
font-size: 0.65em; font-size: 0.65em;
} }
/* .experiment-grid-module-field {
background-color: #eff;
opacity: 1;
transition: opacity 0.5s ease;
}
.experiment-grid-module-gun {
background-color: #eef;
opacity: 1;
transition: opacity 0.5s ease;
} */
.experiment-grid-hide {
display: none;
}
.grid-title { .grid-title {
padding-bottom: 6px; padding-bottom: 6px;
font-size: 1.4em; font-size: 1.4em;
@@ -306,6 +322,10 @@ summary {
background-color: hsl(253, 100%, 81%); background-color: hsl(253, 100%, 81%);
} }
/* .experiment-grid-show {
display: inline;
} */
.experiment-grid-disabled { .experiment-grid-disabled {
/* opacity: 0.5; */ /* opacity: 0.5; */
background-color: var(--build-bg-color); background-color: var(--build-bg-color);

View File

@@ -1,21 +1,42 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
blockBoss: new boss based on work by TheShwarma all explosions do 33% more damage to mobs
(3x chance to randomly see blockBoss until next patch) and 75% more damage to player
it's over powered, I'll probably nerf it next patch, but I want to get some feedback first on how to nerf it boom bot explosions are 16% smaller
hint: if you kill the boss all the mobBlocks turn back into blocks
very very small blocks are slightly limited in how fast they can be thrown laser-bot does 15% more damage
they were moving so fast they would miss their target sometimes missile bot fires 15% quicker
tech: phase velocity also adds 15% wave damage (because it disables phonon is was a bad choice)
many duplication tech add less duplication
Maxwell's demon now requires current energy above your max to unlock
tech: energy conservation gives 5% energy back (was 6%) power ups in the intro tube get pushed around a bit, this might stop them from sliding on the walls
tech: arsenal requires at least 3 guns in your inventory mines when they are stuck to walls no longer collide with blocks (to not block elevator)
tech: active cooling requires at least 2 guns in your inventory more bug fixes
several bug fixes
******************************************************** TODO ******************************************************** ******************************************************** TODO ********************************************************
JUNK tech: add a score to in game console every 10 seconds
tech - explode after getting hit, but while you are immune to harm
on mouse down wormhole shows a possible wormhole
on mouse up the wormhole becomes real
make the player get a buff after using wormhole
while energy lasts: drain energy and give damage buff
using wormhole makes you immune to harm and drains energy until you run out
disable incoming energy, by saving current energy and just setting energy in the next cycle to be lower then the saved value
make a boss with a tail
but the tail is made of interesting mobs
stabbers maybe
suckers maybe
set blockBoss frequency to 1x not 3x
block groups should look for player, so the player doesn't step on them?
remove heath bar?
fix simulation.CDScale // it's always zero so it does nothing fix simulation.CDScale // it's always zero so it does nothing
some mobs can't see player... some mobs can't see player...
3 laser boss isn't rotating... 3 laser boss isn't rotating...
@@ -33,11 +54,6 @@ tech missiles - move faster and more accurately, turn sharper
experiment and understand vibe more obvious experiment and understand vibe more obvious
mostly in early game or first time players mostly in early game or first time players
work on blockBoss from TheShwarma
make spawned blocks in the direction of the player
make it search the level for blocks, but also kinda avoid the player
falling particle rain falling particle rain
what causes it? what causes it?
after taking damage after taking damage
@@ -68,11 +84,6 @@ make non moving bosses not move after getting hit
buff rail gun buff rail gun
make the player get a buff after using wormhole
while energy lasts: drain energy and give damage buff
using wormhole makes you immune to harm and drains energy until you run out
disable incoming energy, by saving current energy and just setting energy in the next cycle to be lower then the saved value
block shattering block shattering
get code from planetesimals get code from planetesimals
https://codepen.io/lilgreenland/pen/jrMvaB?editors=0010 https://codepen.io/lilgreenland/pen/jrMvaB?editors=0010