diff --git a/.DS_Store b/.DS_Store
index 9c8cac0..2273425 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/js/bullet.js b/js/bullet.js
index 434cc8f..302e2bd 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -96,7 +96,7 @@ const b = {
outOfAmmo() { //triggers after firing when you have NO ammo
simulation.makeTextLog(`${b.guns[b.activeGun].name}.ammo: 0`);
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
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");
@@ -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
radius *= tech.explosiveRadius
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.isSmallExplosion) {
color = "rgba(255,0,30,0.7)"
@@ -333,7 +333,7 @@ const b = {
//player damage
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)
if (m.immuneCycle < m.cycle) m.energy -= DRAIN
if (m.energy < 0) {
@@ -381,11 +381,12 @@ const b = {
dist = Vector.magnitude(sub);
if (dist < radius) {
+ const harm = radius * (tech.isExplosionHarm ? 0.00055 : 0.00018)
if (tech.isImmuneExplosion) {
- const mitigate = Math.min(1, Math.max(1 - m.energy * 0.7, 0))
- m.damage(mitigate * radius * (tech.isExplosionHarm ? 0.0003 : 0.0001));
+ const mitigate = Math.min(1, Math.max(1 - m.energy * 0.5, 0))
+ m.damage(mitigate * harm);
} 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);
player.force.x += knock.x;
@@ -1713,7 +1714,8 @@ const b = {
if (angle > -0.2 || angle < -1.5) { //don't stick to level ground
Matter.Body.setVelocity(this, { x: 0, y: 0 });
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 {
Matter.Body.setVelocity(this, { x: 0, y: 0 });
Matter.Body.setAngularVelocity(this, 0)
@@ -3219,7 +3221,7 @@ const b = {
range: (700 + 400 * tech.isLaserBotUpgrade) * (1 + 0.1 * Math.random()),
drainThreshold: tech.isEnergyHealth ? 0.6 : 0.4,
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,
classType: "bullet",
collisionFilter: {
@@ -3312,7 +3314,7 @@ const b = {
explode: 0,
beforeDmg() {
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) {
this.explode = explosionRadius
//
@@ -3399,12 +3401,10 @@ const b = {
onEnd() {},
do() {
const distanceToPlayer = Vector.magnitude(Vector.sub(this.position, m.pos))
- if (distanceToPlayer > 150) { //if far away move towards player
- this.force = Vector.mult(Vector.normalise(Vector.sub(m.pos, this.position)), this.mass * this.acceleration)
- }
+ 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
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;
if (!m.isCloak) {
let closeDist = tech.isPlasmaRange * 1000;
@@ -3426,7 +3426,7 @@ const b = {
const DIST = Vector.magnitude(sub);
const unit = Vector.normalise(sub)
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) {
// m.fieldCDcycle = m.cycle + 120;
// m.energy = 0;
@@ -3501,7 +3501,7 @@ const b = {
y: best.y
};
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.locatePlayer();
//push mobs away
@@ -3593,26 +3593,16 @@ const b = {
orbitalSpeed: 0,
phase: 2 * Math.PI * Math.random(),
do() {
-
- //check for damage
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
q = Matter.Query.region(mob, {
- min: {
- x: this.position.x - size,
- y: this.position.y - size
- },
- max: {
- x: this.position.x + size,
- y: this.position.y + size
- }
+ min: { x: this.position.x - size, y: this.position.y - size },
+ max: { x: this.position.x + size, y: this.position.y + size }
})
for (let i = 0; i < q.length; i++) {
if (!q[i].isShielded) {
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);
if (q[i].alive) q[i].foundPlayer();
simulation.drawList.push({ //add dmg to draw queue
@@ -4401,6 +4391,7 @@ const b = {
if (tech.isPhaseVelocity) {
waveSpeedMap = 3
waveSpeedBody = 1.9
+ bullet[me].dmg *= 1.15
}
if (tech.waveReflections) {
bullet[me].reflectCycle = totalCycles / tech.waveReflections //tech.waveLengthRange
diff --git a/js/index.js b/js/index.js
index c2d3741..9941215 100644
--- a/js/index.js
+++ b/js/index.js
@@ -82,7 +82,6 @@ function getUrlVars() {
return vars;
}
window.addEventListener('load', () => {
-
const set = getUrlVars()
if (Object.keys(set).length !== 0) {
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);
},
isExperimentSelection: false,
+ isExperimentRun: false,
choosePowerUp(who, index, type, isAllowed = false) {
if (type === "gun") {
let isDeselect = false
@@ -360,24 +360,32 @@ const build = {
const isCount = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
//
- if (tech.tech[i].isFieldTech) {
- techID.innerHTML = `
-
-
-
-
- ${tech.tech[i].name} ${isCount}
${tech.tech[i].description}`
- //
- //
- // border: #fff solid 0px;
- } else if (tech.tech[i].isGunTech) {
- techID.innerHTML = `
-
-
-
-
- ${tech.tech[i].name} ${isCount}
${tech.tech[i].description}`
- } else if (tech.tech[i].isJunk) {
+ // if (tech.tech[i].isFieldTech) {
+ // techID.classList.remove('experiment-grid-hide');
+
+ // techID.innerHTML = `
+ //
+ //
+ //
+ //
+ //
+ // ${tech.tech[i].name} ${isCount}
${tech.tech[i].description}
+ // `
+ // //
+ // //
+ // // border: #fff solid 0px;
+ // } else if (tech.tech[i].isGunTech) {
+ // techID.classList.remove('experiment-grid-hide');
+ // techID.innerHTML = `
+ //
+ //
+ //
+ //
+ //
+ // ${tech.tech[i].name} ${isCount}
${tech.tech[i].description}
+ // `
+ // } else
+ if (tech.tech[i].isJunk) {
// text += ` ${tech.tech[i].name} ${isCount}
${tech.tech[i].description}
`
techID.innerHTML = ` ${tech.tech[i].name} ${isCount}
${tech.tech[i].description}`
} else if (tech.tech[i].isExperimentalMode) {
@@ -394,6 +402,8 @@ const build = {
techID.classList.remove("experiment-grid-disabled");
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
// techID.innerHTML = ` ${tech.tech[i].name}
requires: ${tech.tech[i].requires}`
// techID.innerHTML = ` ${tech.tech[i].name}
requires: ${tech.tech[i].requires}`
@@ -459,8 +469,15 @@ const build = {
text += ` ${tech.tech[i].description}
`
}
} else {
- // text += `${tech.tech[i].name}
requires: ${tech.tech[i].requires} `
text += ` ${tech.tech[i].name}
${tech.tech[i].description}
`
+ // if (tech.tech[i].isGunTech || tech.tech[i].isFieldTech) {
+ // text += `` //built but hidden
+ // } else {
+ // text += ` ${tech.tech[i].name}
${tech.tech[i].description}
`
+ // }
+ // } else if (!tech.tech[i].isGunTech && !tech.tech[i].isFieldTech) {
+ // text += `${tech.tech[i].name}
requires: ${tech.tech[i].requires} `
+
}
}
}
@@ -483,6 +500,7 @@ const build = {
reset() {
simulation.startGame(true); //starts game, but pauses it
build.isExperimentSelection = true;
+ build.isExperimentRun = true;
simulation.paused = true;
m.setField(0)
b.inventory = []; //removes guns and ammo
diff --git a/js/level.js b/js/level.js
index ec7504f..800be9a 100644
--- a/js/level.js
+++ b/js/level.js
@@ -62,7 +62,7 @@ const level = {
spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
// spawn.pickList = ["focuser", "focuser"]
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.levelsClearedLastGame = level.levelsCleared
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
@@ -2273,12 +2273,12 @@ const level = {
spawn.mapRect(4850, -275, 50, 175);
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
// 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);
// spawn.laserBombingBoss(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.sneaker(1900, -500)
// 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.spawnStartingPowerUps(2095 + 15 * (Math.random() - 0.5), -2070 - 125);
if (localSettings.levelsClearedLastGame < 3) {
- if (!simulation.isCheating && !m.isShipMode) {
+ if (!simulation.isCheating && !m.isShipMode && !build.isExperimentRun) {
spawn.wireFoot();
spawn.wireFootLeft();
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
// spawn.mapRect(2000, -1025, 200, 25);
}
- } else {
+ } else if (!build.isExperimentRun) {
simulation.trails()
//bonus power ups for clearing runs in the last game
if (!simulation.isCheating && localSettings.levelsClearedLastGame > 1) {
@@ -2489,13 +2489,103 @@ const level = {
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
}
}
+ spawn.mapRect(2025, 0, 150, 50); //lid to floor hole
} else {
for (let i = 0; i < 60; 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 = () => {
+ //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
const binary = (localSettings.runCount >>> 0).toString(2)
const height = 20
@@ -2521,93 +2611,10 @@ const level = {
}
ctx.stroke();
- //wires
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.lineWidth = 5;
- ctx.stroke();
+ ctx.stroke(wires);
//squares that look like they keep the wires in place
ctx.beginPath()
@@ -2677,7 +2684,6 @@ const level = {
spawn.mapRect(2150, 0, 1200, 1800); //split roof
spawn.mapRect(2025, -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, 2300, 1800); //split roof
diff --git a/js/player.js b/js/player.js
index 32a7ee0..fa6a7b2 100644
--- a/js/player.js
+++ b/js/player.js
@@ -2587,9 +2587,9 @@ const m = {
},
{
name: "wormhole",
- description: "use energy to tunnel through a wormhole
wormholes attract blocks and power ups
8% chance to duplicate spawned power ups", //
bullets may also traverse wormholes
+ description: "use energy to tunnel through a wormhole
wormholes attract blocks and power ups
7% chance to duplicate spawned power ups", //
bullets may also traverse wormholes
effect: function() {
- m.duplicateChance = 0.08
+ m.duplicateChance = 0.07
powerUps.setDo(); //needed after adjusting duplication chance
m.hold = function() {
diff --git a/js/powerup.js b/js/powerup.js
index bc9d96b..9c281c9 100644
--- a/js/powerup.js
+++ b/js/powerup.js
@@ -260,11 +260,11 @@ const powerUps = {
tech.maxDuplicationEvent()
}
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"
- if (Math.random() < 0.33) {
+ if (Math.random() < 0.36) {
spawnType = "heal"
- } else if (Math.random() < 0.5 && !tech.isSuperDeterminism) {
+ } else if (Math.random() < 0.4 && !tech.isSuperDeterminism) {
spawnType = "research"
}
powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), spawnType, false);
diff --git a/js/simulation.js b/js/simulation.js
index d95b481..bb4519a 100644
--- a/js/simulation.js
+++ b/js/simulation.js
@@ -644,6 +644,7 @@ const simulation = {
simulation.difficultyMode = Number(document.getElementById("difficulty-select").value)
build.isExperimentSelection = false;
+ build.isExperimentRun = false;
simulation.clearNow = true;
document.getElementById("text-log").style.opacity = 0;
document.getElementById("fade-out").style.opacity = 0;
diff --git a/js/spawn.js b/js/spawn.js
index c1bfab5..372db82 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -1,7 +1,7 @@
//main object for spawning things in a level
const spawn = {
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
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 beamTotalDuration = 60
mobs.spawn(x, y, 4, radius, "#999"); //#54291d
const me = mob[mob.length - 1];
me.isBoss = true;
- // Matter.Body.setDensity(me, 0.001); //normal density even though its a boss
- me.damageReduction = 0.06; //extra reduction for a boss, because normal density
+ Matter.Body.setDensity(me, 0.002); //normal density even though its a boss
+ me.damageReduction = 0.05; //extra reduction for a boss, because normal density
me.frictionAir = 0.01;
me.accelMag = 0.0002;
me.onDeath = function() {
@@ -786,14 +786,19 @@ const spawn = {
}
//randomly spawn new mobs from nothing
- if (!(simulation.cycle % 120)) {
+ if (!(simulation.cycle % 90)) {
let count = 0
for (let i = 0, len = mob.length; i < len; i++) {
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))
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)
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
@@ -1836,7 +1841,7 @@ const spawn = {
mobs.spawn(x, y, 0, radius, "transparent");
let me = mob[mob.length - 1];
Matter.Body.setDensity(me, 0.21); //extra dense //normal is 0.001
- me.laserRange = 300;
+ me.laserRange = 350;
me.seeAtDistance2 = 2000000;
me.isBoss = true;
@@ -1849,7 +1854,7 @@ const spawn = {
me.onDeath = function() {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
};
- me.damageReduction = 0.25 // me.damageReductionGoal
+ me.damageReduction = 0.35 // me.damageReductionGoal
me.awake = function() {
// this.armor();
this.checkStatus();
@@ -1879,9 +1884,9 @@ const spawn = {
if (this.distanceToPlayer() < this.laserRange) {
if (m.immuneCycle < m.cycle) {
if (m.energy > 0.002) {
- m.energy -= 0.0035
+ m.energy -= 0.004
} else {
- m.damage(0.0003 * simulation.dmgScale)
+ m.damage(0.0004 * simulation.dmgScale)
}
}
ctx.beginPath();
diff --git a/js/tech.js b/js/tech.js
index 0d39a1e..4f7bcbd 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -193,7 +193,7 @@
return dmg * tech.slowFire * tech.aimDamage
},
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() {
if (tech.is100Duplicate && tech.duplicationChance() > 0.99) {
@@ -849,7 +849,6 @@
{
name: "shock wave",
description: "explosions stun mobs for 1-2 seconds
decrease explosive damage by 30%",
- isGunTech: true,
maxCount: 1,
count: 0,
frequency: 1,
@@ -868,7 +867,7 @@
{
name: "electric reactive armor",
// description: "explosions do no harm
while your energy is above 98%",
- description: "harm from explosions is passively reduced
by 6% for every 10 stored energy",
+ description: "harm from explosions is passively reduced
by 5% for every 10 stored energy",
maxCount: 1,
count: 0,
frequency: 2,
@@ -892,7 +891,7 @@
frequency: 1,
frequencyDefault: 1,
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",
effect() {
@@ -1590,7 +1589,7 @@
frequency: 3,
frequencyDefault: 3,
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",
effect() {
@@ -1608,7 +1607,7 @@
frequency: 3,
frequencyDefault: 3,
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",
effect() {
@@ -1662,7 +1661,7 @@
frequency: 3,
frequencyDefault: 3,
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",
effect() {
@@ -2182,7 +2181,7 @@
frequency: 1,
frequencyDefault: 1,
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",
effect: () => {
@@ -2391,9 +2390,9 @@
frequency: 2,
frequencyDefault: 2,
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() {
tech.overfillDrain = 0.85 //70% = 1-(1-0.75)/(1-0.15) //92% = 1-(1-0.75)/(1-0.87)
tech.addJunkTechToPool(18)
@@ -3057,7 +3056,7 @@
},
{
name: "stimulated emission",
- description: "20% chance to duplicate spawned power ups
but, after a collision eject 1 tech",
+ description: "17% chance to duplicate spawned power ups
but, after a collision eject 1 tech",
maxCount: 1,
count: 0,
frequency: 1,
@@ -3077,7 +3076,7 @@
},
{
name: "metastability",
- description: "15% chance to duplicate spawned power ups
duplicates explode with a 3 second half-life ",
+ description: "13% chance to duplicate spawned power ups
duplicates explode with a 3 second half-life ",
maxCount: 1,
count: 0,
frequency: 1,
@@ -3097,7 +3096,7 @@
},
{
name: "futures exchange",
- description: "clicking × to cancel a field, tech, or gun
adds 4.7% power up duplication chance",
+ description: "clicking × to cancel a field, tech, or gun
adds 4.5% power up duplication chance",
maxCount: 1,
count: 0,
frequency: 1,
@@ -3117,7 +3116,7 @@
},
{
name: "commodities exchange",
- description: `clicking × to cancel a field, tech, or gun
spawns 9 ${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, or ${powerUps.orb.research(1)}`,
+ description: `clicking × to cancel a field, tech, or gun
spawns 5-10 ${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, or ${powerUps.orb.research(1)}`,
maxCount: 1,
count: 0,
frequency: 1,
@@ -3632,9 +3631,9 @@
frequency: 2,
frequencyDefault: 2,
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() {
tech.isNeedleShieldPierce = true
},
@@ -3864,7 +3863,7 @@
},
{
name: "shotgun spin-statistics",
- description: "immune to harm while firing the shotgun
shotgun has gives 50% fewer shots",
+ description: "immune to harm while firing the shotgun
shotgun has 50% fewer shots",
isGunTech: true,
maxCount: 1,
count: 0,
@@ -4129,7 +4128,8 @@
},
{
name: "phase velocity",
- description: "wave beam propagates faster through solids
up by 3000% in the map and 760% in blocks",
+ description: "wave beam propagates faster through solids
increase wave beam damage by 15%",
+ // description: "wave beam propagates faster through solids
up by 3000% in the map and 760% in blocks",
isGunTech: true,
maxCount: 1,
count: 0,
@@ -4709,7 +4709,8 @@
},
{
name: "drone repair",
- description: "broken drones repair if the drone gun is active
repairing has a 25% chance to use 1 drone",
+ description: "after a drone ends it redeploys
for a 25% chance to use 1 drone ammo",
+ // description: "broken drones repair if the drone gun is active
repairing has a 25% chance to use 1 drone",
isGunTech: true,
maxCount: 1,
count: 0,
@@ -6077,7 +6078,7 @@
},
{
name: "virtual particles",
- description: `use ${powerUps.orb.research(4)}to exploit your wormhole for a
16% chance to duplicate spawned power ups`,
+ description: `use ${powerUps.orb.research(4)}to exploit your wormhole for a
14% chance to duplicate spawned power ups`,
isFieldTech: true,
maxCount: 1,
count: 0,
@@ -6088,7 +6089,7 @@
},
requires: "wormhole,below 100% duplication chance",
effect() {
- tech.wormDuplicate = 0.16
+ tech.wormDuplicate = 0.14
powerUps.setDo(); //needed after adjusting duplication chance
for (let i = 0; i < 4; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
@@ -6809,6 +6810,27 @@
},
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 = ${score.toFixed(0)}`);
+ }, 1000); //every 10 seconds
+ },
+ remove() {}
+ },
{
name: "pop-ups",
description: "sign up to learn endless easy ways to win n-gon
that Landgreen doesn't want you to know!!!1!!",
diff --git a/style.css b/style.css
index b099a4a..0ce7060 100644
--- a/style.css
+++ b/style.css
@@ -272,6 +272,22 @@ summary {
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 {
padding-bottom: 6px;
font-size: 1.4em;
@@ -306,6 +322,10 @@ summary {
background-color: hsl(253, 100%, 81%);
}
+/* .experiment-grid-show {
+ display: inline;
+} */
+
.experiment-grid-disabled {
/* opacity: 0.5; */
background-color: var(--build-bg-color);
diff --git a/todo.txt b/todo.txt
index cf4b697..8a8ecf8 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,21 +1,42 @@
******************************************************** NEXT PATCH **************************************************
-blockBoss: new boss based on work by TheShwarma
- (3x chance to randomly see blockBoss until next patch)
- it's over powered, I'll probably nerf it next patch, but I want to get some feedback first on how to nerf it
- hint: if you kill the boss all the mobBlocks turn back into blocks
+all explosions do 33% more damage to mobs
+ and 75% more damage to player
+ boom bot explosions are 16% smaller
-very very small blocks are slightly limited in how fast they can be thrown
- they were moving so fast they would miss their target sometimes
+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
-tech: energy conservation gives 5% energy back (was 6%)
-tech: arsenal requires at least 3 guns in your inventory
-tech: active cooling requires at least 2 guns in your inventory
-
-several bug fixes
+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
******************************************************** 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
some mobs can't see player...
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
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
what causes it?
after taking damage
@@ -68,11 +84,6 @@ make non moving bosses not move after getting hit
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
get code from planetesimals
https://codepen.io/lilgreenland/pen/jrMvaB?editors=0010