diff --git a/n-gon/img/working mass.webp b/n-gon/img/working mass.webp
new file mode 100644
index 00000000..d98237bc
Binary files /dev/null and b/n-gon/img/working mass.webp differ
diff --git a/n-gon/js/bullet.js b/n-gon/js/bullet.js
index 65e48913..cceb11c1 100644
--- a/n-gon/js/bullet.js
+++ b/n-gon/js/bullet.js
@@ -3312,8 +3312,8 @@ const b = {
const distB = Vector.magnitude(Vector.sub(this.position, b.position))
return distA < distB ? a : b
})
- if (found && m.energy > 0.05) {
- m.energy -= 0.05
+ if (found && m.energy > 0.041) {
+ m.energy -= 0.04
//remove the body and spawn a new drone
Composite.remove(engine.world, found)
body.splice(body.indexOf(found), 1)
@@ -3552,8 +3552,8 @@ const b = {
const distB = Vector.magnitude(Vector.sub(this.position, b.position))
return distA < distB ? a : b
})
- if (found && m.energy > 0.05) {
- m.energy -= 0.1
+ if (found && m.energy > 0.091) {
+ m.energy -= 0.09
//remove the body and spawn a new drone
Composite.remove(engine.world, found)
body.splice(body.indexOf(found), 1)
diff --git a/n-gon/js/engine.js b/n-gon/js/engine.js
index f7c6865d..fb7c481c 100644
--- a/n-gon/js/engine.js
+++ b/n-gon/js/engine.js
@@ -174,15 +174,8 @@ function collisionChecks(event) {
if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + m.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...
let angle = Math.atan2(player.position.y - mob[k].position.y, player.position.x - mob[k].position.x);
- Matter.Body.setVelocity(player, {
- x: player.velocity.x + 8 * Math.cos(angle),
- y: player.velocity.y + 8 * Math.sin(angle)
- });
- Matter.Body.setVelocity(mob[k], {
- x: mob[k].velocity.x - 8 * Math.cos(angle),
- y: mob[k].velocity.y - 8 * Math.sin(angle)
- });
-
+ Matter.Body.setVelocity(player, { x: player.velocity.x + 8 * Math.cos(angle), y: player.velocity.y + 8 * Math.sin(angle) });
+ Matter.Body.setVelocity(mob[k], { x: mob[k].velocity.x - 8 * Math.cos(angle), y: mob[k].velocity.y - 8 * Math.sin(angle) });
if (tech.isAnnihilation && !mob[k].shield && !mob[k].isShielded && !mob[k].isBoss && mob[k].isDropPowerUp && m.energy > 0.1 && mob[k].damageReduction > 0) {
m.energy -= 0.1 //* Math.max(m.maxEnergy, m.energy) //0.33 * m.energy
if (m.immuneCycle === m.cycle + m.collisionImmuneCycles) m.immuneCycle = 0; //player doesn't go immune to collision damage
@@ -250,7 +243,7 @@ function collisionChecks(event) {
if (mob[k].isShielded) dmg *= 0.7
mob[k].damage(dmg, true);
- if (tech.isBlockPowerUps && !mob[k].alive && mob[k].isDropPowerUp && m.throwCycle > m.cycle) {
+ if (tech.isBlockPowerUps && !mob[k].alive && mob[k].isDropPowerUp && Math.random() < 0.5) {
options = ["coupling", "boost", "heal", "research"]
if (!tech.isEnergyNoAmmo) options.push("ammo")
powerUps.spawn(mob[k].position.x, mob[k].position.y, options[Math.floor(Math.random() * options.length)]);
diff --git a/n-gon/js/level.js b/n-gon/js/level.js
index fa739a57..51e091b1 100644
--- a/n-gon/js/level.js
+++ b/n-gon/js/level.js
@@ -44,10 +44,9 @@ const level = {
// requestAnimationFrame(() => { tech.giveTech("optical amplifier") });
// for (let i = 0; i < 1; ++i) tech.giveTech("combinatorial optimization")
// tech.giveTech("Newtons 2nd law")
- // for (let i = 0; i < 1; ++i) tech.giveTech("lens")
// for (let i = 0; i < 1; ++i) tech.giveTech("tungsten carbide")
- // for (let i = 0; i < 1; ++i) tech.giveTech("nitinol")
- // for (let i = 0; i < 1; ++i) tech.giveTech("reaction mass")
+ // for (let i = 0; i < 1; ++i) tech.giveTech("working mass")
+ // for (let i = 0; i < 1; ++i) tech.giveTech("buckling")
// requestAnimationFrame(() => { for (let i = 0; i < 10; i++) b.orbitBot(m.pos, false) });
// requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("ersatz bots") });
// for (let i = 0; i < 1; i++) tech.giveTech("tungsten carbide")
@@ -57,11 +56,11 @@ const level = {
// for (let i = 0; i < 1; i++) powerUps.directSpawn(-50, -70, "difficulty", false);
// for (let i = 0; i < 100; i++) powerUps.directSpawn(1750, -500, "coupling");
// spawn.mapRect(575, -700, 25, 425); //block mob line of site on testing
- // level.yingYang();
+ // level.testing();
- // for (let i = 0; i < 1; ++i) spawn.laserLayer(1400, -500)
+ // for (let i = 0; i < 1; ++i) spawn.snakeSpitBoss(1400, -500)
// Matter.Body.setPosition(player, { x: -200, y: -3330 });
- // for (let i = 0; i < 4; ++i) spawn.ghoster(1300, -500 + 100 * Math.random())
+ // for (let i = 0; i < 4; ++i) spawn.sucker(1300, -500 + 100 * Math.random())
// spawn.hopper(1900, -500)
// spawn.zombie(-3000, -500 + 300 * Math.random(), 30, 5, "white") // zombie(x, y, radius, sides, color)
// for (let i = 0; i < 5; ++i) spawn.starter(1000 + 1000 * Math.random(), -500 + 300 * Math.random())
@@ -4235,7 +4234,6 @@ const level = {
powerUps.addResearchToLevel() //needs to run after mobs are spawned
},
towers() {
- // simulation.enableConstructMode() //remove this!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// simulation.isHorizontalFlipped = true
level.announceMobTypes()
const isFlipped = (simulation.isHorizontalFlipped && Math.random() < 0.33) ? true : false
@@ -4448,6 +4446,12 @@ const level = {
spawn.bodyRect(8975, -1575, 50, 50, 0.2);
spawn.bodyRect(5725, -1700, 125, 175, 0.2);
spawn.bodyRect(6850, -1725, 150, 200, 0.2);
+ spawn.bodyRect(500, -400, 100, 50, 0.3);
+ spawn.bodyRect(6025, 1050, 100, 50, 0.2);
+ spawn.bodyRect(6000, -800, 75, 200, 0.2);
+ spawn.bodyRect(6775, -75, 125, 75, 0.5);
+ spawn.bodyRect(7200, 1300, 50, 200, 0.5);
+
//mobs
spawn.randomMob(5700, -75, 0);
diff --git a/n-gon/js/player.js b/n-gon/js/player.js
index 5cfaed38..6e83d3a7 100644
--- a/n-gon/js/player.js
+++ b/n-gon/js/player.js
@@ -240,11 +240,7 @@ const m = {
jump() {
m.buttonCD_jump = m.cycle; //can't jump again until 20 cycles pass
//apply a fraction of the jump force to the body the player is jumping off of
- Matter.Body.applyForce(m.standingOn, m.pos, {
- x: 0,
- y: m.jumpForce * 0.12 * Math.min(m.standingOn.mass, 5)
- });
-
+ Matter.Body.applyForce(m.standingOn, m.pos, { x: 0, y: m.jumpForce * 0.12 * Math.min(m.standingOn.mass, 5) });
player.force.y = -m.jumpForce; //player jump force
Matter.Body.setVelocity(player, { //zero player y-velocity for consistent jumps
x: player.velocity.x,
@@ -473,13 +469,10 @@ const m = {
m.displayHealth();
document.getElementById("text-log").style.display = "none"
document.getElementById("fade-out").style.opacity = 0.9; //slowly fade to 90% white on top of canvas
- // build.shareURL(false)
setTimeout(function () {
Composite.clear(engine.world);
Engine.clear(engine);
simulation.splashReturn();
- //if you die after clearing fewer than 4 levels the difficulty settings automatically opens
- if ((level.levelsCleared < 4 || level.levelsCleared > 12) && !simulation.isTraining && !simulation.isCheating) document.getElementById("constraint-details").open = true;
}, 5000);
}
},
@@ -3488,11 +3481,11 @@ const m = {
},
{
name: "molecular assembler",
- description: `excess energy used to print ${simulation.molecularMode === 0 ? "spores" : simulation.molecularMode === 1 ? "missiles" : simulation.molecularMode === 2 ? "ice IX" : "drones"}
use energy to deflect mobs
12 energy per second`,
+ description: `excess energy used to print ${simulation.molecularMode === 0 ? "spores" : simulation.molecularMode === 1 ? "missiles" : simulation.molecularMode === 2 ? "ice IX" : "drones"}
use energy to deflect mobs
12 energy per second`,
setDescription() {
- return `excess energy used to print ${simulation.molecularMode === 0 ? "spores" : simulation.molecularMode === 1 ? "missiles" : simulation.molecularMode === 2 ? "ice IX" : "drones"}
use energy to deflect mobs
12 energy per second`
+ return `excess energy used to print ${simulation.molecularMode === 0 ? "spores" : simulation.molecularMode === 1 ? "missiles" : simulation.molecularMode === 2 ? "ice IX" : "drones"}
use energy to deflect mobs
12 energy per second`
},
- doubleJumpPhase: 0,
+ blockJumpPhase: 0,
effect: () => {
m.fieldMeterColor = "#ff0"
m.eyeFillColor = m.fieldMeterColor
@@ -3604,20 +3597,106 @@ const m = {
}
m.drawRegenEnergy()
- if (tech.isDoubleJump) {
-
-
- // if (input.up && m.buttonCD_jump + 20 < m.cycle && m.yOffWhen.stand > 23 && m.lastOnGroundCycle + 5 > m.cycle) m.jump()
-
- if (this.doubleJumpPhase === 0 && input.up) { //1st jump
-
- } else if (this.doubleJumpPhase === 0 && input.up) {
+ if (tech.isBlockJump) {
+ if (m.onGround && m.buttonCD_jump + 10 < m.cycle) this.blockJumpPhase = 0 //reset after touching ground or block
+ if (this.blockJumpPhase === 0 && !m.onGround) { //1st jump or fall
+ this.blockJumpPhase = 1
+ } else if (this.blockJumpPhase === 1 && !input.up && m.buttonCD_jump + 10 < m.cycle) { //not pressing jump
+ this.blockJumpPhase = 2
+ } else if (this.blockJumpPhase === 2 && input.up && m.buttonCD_jump + 10 < m.cycle) { //2nd jump
+ this.blockJumpPhase = 3
+
+ //make a block
+ const radius = 25 + Math.floor(15 * Math.random())
+ body[body.length] = Matter.Bodies.polygon(m.pos.x, m.pos.y + 65 + radius, 4, radius, {
+ friction: 0.05,
+ frictionAir: 0.001,
+ collisionFilter: {
+ category: cat.body,
+ mask: cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet
+ },
+ classType: "body",
+ });
+ const block = body[body.length - 1]
+ //mess with the block shape (this code is horrible)
+ Composite.add(engine.world, block); //add to world
+ const r1 = radius * (1 + 0.4 * Math.random())
+ const r2 = radius * (1 + 0.4 * Math.random())
+ let angle = 0
+ const vertices = []
+ for (let i = 0, len = block.vertices.length; i < len; i++) {
+ angle += 2 * Math.PI / len
+ vertices.push({ x: block.position.x + r1 * Math.cos(angle), y: block.position.y + r2 * Math.sin(angle) })
+ }
+ Matter.Body.setVertices(block, vertices)
+ Matter.Body.setAngle(block, Math.PI / 4)
+ Matter.Body.setVelocity(block, { x: 0.9 * player.velocity.x, y: 10 });
+ Matter.Body.applyForce(block, m.pos, { x: 0, y: m.jumpForce * 0.12 * Math.min(m.standingOn.mass, 5) });
+ if (tech.isBlockRestitution) {
+ block.restitution = 0.999 //extra bouncy
+ block.friction = block.frictionStatic = block.frictionAir = 0.001
+ }
+ if (tech.isAddBlockMass) {
+ const expand = function (that, massLimit) {
+ if (that.mass < massLimit) {
+ const scale = 1.04;
+ Matter.Body.scale(that, scale, scale);
+ setTimeout(expand, 20, that, massLimit);
+ }
+ };
+ expand(block, Math.min(20, block.mass * 3))
+ }
+ //jump
+ m.buttonCD_jump = m.cycle; //can't jump again until 20 cycles pass
+ let horizontalVelocity = 8 * (- input.left + input.right)
+ Matter.Body.setVelocity(player, { x: player.velocity.x + horizontalVelocity, y: -7.5 + 0.25 * player.velocity.y });
+ player.force.y = -m.jumpForce; //player jump force
+ } else if (this.blockJumpPhase === 3 && m.onGround && m.buttonCD_jump + 10 < m.cycle) {
+ //reset
+ this.blockJumpPhase = 0 //reset
+ }
+ }
- } else { //reset
- }
+ // if (tech.isBlockJump) {
+ // //make sure only 1 ephemera is running
+ // simulation.ephemera.push({
+ // name: "2 jump",
+ // mode: 0,
+ // do() {
+ // // console.log('hi')
+ // if (m.buttonCD_jump + 20 < m.cycle && m.onGround) simulation.removeEphemera(this.name)
+ // if (this.mode === 0) {
+ // if (!input.up) this.mode = 1
+ // } else if (this.mode === 1) {
+ // if (input.up && m.buttonCD_jump + 20 < m.cycle) {
+ // simulation.removeEphemera(this.name)
+ // //make a block
+ // body[body.length] = Matter.Bodies.polygon(m.pos.x, m.pos.y + 80, 4, 30 + Math.floor(10 * Math.random()), {
+ // friction: 0.05,
+ // frictionAir: 0.001,
+ // collisionFilter: {
+ // category: cat.body,
+ // mask: cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet
+ // },
+ // classType: "body",
+ // // isPrinted: true,
+ // });
+ // const who = body[body.length - 1]
+ // Composite.add(engine.world, who); //add to world
+ // Matter.Body.setVelocity(who, { x: player.velocity.x * 0.5, y: +30 });
+ // Matter.Body.applyForce(who, m.pos, { x: 0, y: m.jumpForce * 0.12 * Math.min(m.standingOn.mass, 5) });
+
+ // //jump again
+ // m.buttonCD_jump = m.cycle; //can't jump again until 20 cycles pass
+ // player.force.y = -m.jumpForce; //player jump force
+ // Matter.Body.setVelocity(player, { x: player.velocity.x, y: -7.5 + 0.25 * player.velocity.y });
+ // }
+ // }
+ // },
+ // })
- }
+ // }
}
}
},
@@ -4663,6 +4742,66 @@ const m = {
m.fieldRadius = 0
}
m.drawRegenEnergy("rgba(0,0,0,0.2)")
+
+ if (tech.isBlockJump) {
+ if (m.onGround && m.buttonCD_jump + 10 < m.cycle) this.blockJumpPhase = 0 //reset after touching ground or block
+ if (this.blockJumpPhase === 0 && !m.onGround) { //1st jump or fall
+ this.blockJumpPhase = 1
+ } else if (this.blockJumpPhase === 1 && !input.up && m.buttonCD_jump + 10 < m.cycle) { //not pressing jump
+ this.blockJumpPhase = 2
+ } else if (this.blockJumpPhase === 2 && input.up && m.buttonCD_jump + 10 < m.cycle) { //2nd jump
+ this.blockJumpPhase = 3
+
+ //make a block
+ const radius = 25 + Math.floor(15 * Math.random())
+ body[body.length] = Matter.Bodies.polygon(m.pos.x, m.pos.y + 60 + radius, 4, radius, {
+ friction: 0.05,
+ frictionAir: 0.001,
+ collisionFilter: {
+ category: cat.body,
+ mask: cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet
+ },
+ classType: "body",
+ });
+ const block = body[body.length - 1]
+ //mess with the block shape (this code is horrible)
+ Composite.add(engine.world, block); //add to world
+ const r1 = radius * (1 + 0.4 * Math.random())
+ const r2 = radius * (1 + 0.4 * Math.random())
+ let angle = 0
+ const vertices = []
+ for (let i = 0, len = block.vertices.length; i < len; i++) {
+ angle += 2 * Math.PI / len
+ vertices.push({ x: block.position.x + r1 * Math.cos(angle), y: block.position.y + r2 * Math.sin(angle) })
+ }
+ Matter.Body.setVertices(block, vertices)
+ Matter.Body.setAngle(block, Math.PI / 4)
+ Matter.Body.setVelocity(block, { x: 0.9 * player.velocity.x, y: 10 });
+ Matter.Body.applyForce(block, m.pos, { x: 0, y: m.jumpForce * 0.12 * Math.min(m.standingOn.mass, 5) });
+ if (tech.isBlockRestitution) {
+ block.restitution = 0.999 //extra bouncy
+ block.friction = block.frictionStatic = block.frictionAir = 0.001
+ }
+ if (tech.isAddBlockMass) {
+ const expand = function (that, massLimit) {
+ if (that.mass < massLimit) {
+ const scale = 1.04;
+ Matter.Body.scale(that, scale, scale);
+ setTimeout(expand, 20, that, massLimit);
+ }
+ };
+ expand(block, Math.min(20, block.mass * 3))
+ }
+ //jump
+ m.buttonCD_jump = m.cycle; //can't jump again until 20 cycles pass
+ let horizontalVelocity = 8 * (- input.left + input.right)
+ Matter.Body.setVelocity(player, { x: player.velocity.x + horizontalVelocity, y: -7.5 + 0.25 * player.velocity.y });
+ player.force.y = -m.jumpForce; //player jump force
+ } else if (this.blockJumpPhase === 3 && m.onGround && m.buttonCD_jump + 10 < m.cycle) {
+ //reset
+ this.blockJumpPhase = 0 //reset
+ }
+ }
}
}
},
@@ -5619,7 +5758,7 @@ const m = {
let dmg = tech.blockDamage * m.dmgScale * v * obj.mass * (tech.isMobBlockFling ? 2 : 1);
if (mob[k].isShielded) dmg *= 0.7
mob[k].damage(dmg, true);
- if (tech.isBlockPowerUps && !mob[k].alive && mob[k].isDropPowerUp && m.throwCycle > m.cycle) {
+ if (tech.isBlockPowerUps && !mob[k].alive && mob[k].isDropPowerUp && Math.random() < 0.5) {
let type = tech.isEnergyNoAmmo ? "heal" : "ammo"
if (Math.random() < 0.4) {
type = "heal"
diff --git a/n-gon/js/powerup.js b/n-gon/js/powerup.js
index a6414da8..d96f70e6 100644
--- a/n-gon/js/powerup.js
+++ b/n-gon/js/powerup.js
@@ -1437,11 +1437,10 @@ const powerUps = {
},
},
spawnDelay(type, count, delay = 2) {
- const lastHarmCycle = m.lastHarmCycle //stop releasing power ups if you take damage
count *= delay
let cycle = () => {
if (count > 0) {
- if (m.alive && lastHarmCycle === m.lastHarmCycle) requestAnimationFrame(cycle);
+ if (m.alive) requestAnimationFrame(cycle);
if (!simulation.paused && !simulation.isChoosing && powerUp.length < 300) { //&& !(simulation.cycle % 2)
count--
if (!(count % delay)) {
@@ -1622,7 +1621,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].isDuplicated = true
+ // powerUp[powerUp.length - 1].isDuplicated = true
}
// remove a random tech from the list of tech you have
tech.tech[choose].remove();
diff --git a/n-gon/js/simulation.js b/n-gon/js/simulation.js
index 61aeffc1..0ae161f0 100644
--- a/n-gon/js/simulation.js
+++ b/n-gon/js/simulation.js
@@ -814,7 +814,6 @@ const simulation = {
simulation.isChoosing = false;
b.setFireMethod()
b.setFireCD();
- // simulation.updateTechHUD();
for (let i = 0; i < b.guns.length; i++) b.guns[i].isRecentlyShown = false //reset recently shown back to zero
for (let i = 0; i < m.fieldUpgrades.length; i++) m.fieldUpgrades[i].isRecentlyShown = false //reset recently shown back to zero
for (let i = 0; i < tech.tech.length; i++) tech.tech[i].isRecentlyShown = false //reset recently shown back to zero
@@ -827,17 +826,12 @@ const simulation = {
powerUps.boost.endCycle = 0
powerUps.isFieldSpawned = false
m.setFillColors();
- // m.maxHealth = 1
- // m.maxEnergy = 1
- // m.energy = 1
input.isPauseKeyReady = true
simulation.wipe = function () { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
m.hole.isOn = false
simulation.paused = false;
- // simulation.cycle = 0
- // m.cycle = 0
engine.timing.timeScale = 1;
simulation.fpsCap = simulation.fpsCapDefault;
simulation.isAutoZoom = true;
@@ -853,18 +847,11 @@ const simulation = {
document.getElementById("text-log").style.display = "none"
document.getElementById("fade-out").style.opacity = 0;
document.title = "n-gon";
- // simulation.makeTextLog(`input.key.up: ["${input.key.up}", "ArrowUp"]`);
- // simulation.makeTextLog(`input.key.left: ["${input.key.left}", "ArrowLeft"]`);
- // simulation.makeTextLog(`input.key.down: ["${input.key.down}", "ArrowDown"]`);
- // simulation.makeTextLog(`input.key.right: ["${input.key.right}", "ArrowRight"]`);
simulation.makeTextLog(`Math.seed = ${Math.initialSeed}`);
simulation.makeTextLog(`const engine = Engine.create(); //simulation begin`);
simulation.makeTextLog(`engine.timing.timeScale = 1`);
- // simulation.makeTextLog(`input.key.field: ["${input.key.field}", "MouseRight"]`);
-
- // document.getElementById("health").style.display = "inline"
- // document.getElementById("health-bg").style.display = "inline"
m.alive = true;
+ m.definePlayerMass();
m.onGround = false
m.lastOnGroundCycle = 0
m.health = 0;
@@ -874,23 +861,10 @@ const simulation = {
//set to default field
tech.healMaxEnergyBonus = 0
- // m.setMaxEnergy();
m.energy = 0
m.immuneCycle = 0;
- // simulation.makeTextLog(`${simulation.SVGrightMouse} ${m.fieldUpgrades[m.fieldMode].name}
${m.fieldUpgrades[m.fieldMode].description}`, 600);
- // simulation.makeTextLog(`
- // input.key.up = ["${input.key.up}", "ArrowUp"]
- //
input.key.left = ["${input.key.left}", "ArrowLeft"]
- //
input.key.down = ["${input.key.down}", "ArrowDown"]
- //
input.key.right = ["${input.key.right}", "ArrowRight"]
- //
- //
m.fieldMode = "${m.fieldUpgrades[m.fieldMode].name}"
- //
input.key.field = ["${input.key.field}", "right mouse"]
- //
m.field.description = "${m.fieldUpgrades[m.fieldMode].description}"
- // `, 800);
m.coupling = 0
m.setField(0) //this calls m.couplingChange(), which sets max health and max energy
- // m.energy = 0;
//exit testing
if (simulation.testing) {
simulation.testing = false;
diff --git a/n-gon/js/spawn.js b/n-gon/js/spawn.js
index 1e3c9acc..5759357f 100644
--- a/n-gon/js/spawn.js
+++ b/n-gon/js/spawn.js
@@ -1427,7 +1427,7 @@ const spawn = {
me.seePlayerFreq = Math.floor(11 + 7 * Math.random())
me.seeAtDistance2 = 1400000;
me.cellMassMax = 70
- me.collisionFilter.mask = cat.player | cat.bullet //| cat.body | cat.map
+ me.collisionFilter.mask = cat.player | cat.bullet | cat.body// | cat.map
Matter.Body.setDensity(me, 0.0001 + 0.00002 * simulation.difficulty) // normal density is 0.001
me.damageReduction = 0.17
@@ -1755,7 +1755,7 @@ const spawn = {
me.seeAtDistance2 = 1000000;
me.accelMag = 0.0002 + 0.0004 * simulation.accelScale;
Matter.Body.setDensity(me, 0.0003); //normal is 0.001
- me.collisionFilter.mask = cat.bullet | cat.player //| cat.body
+ me.collisionFilter.mask = cat.bullet | cat.player | cat.body
me.memory = Infinity;
me.seePlayerFreq = 30
me.lockedOn = null;
@@ -2314,7 +2314,7 @@ const spawn = {
me.seeAtDistance2 = (me.eventHorizon + 400) * (me.eventHorizon + 400); //vision limit is event horizon
me.accelMag = 0.00012 * simulation.accelScale;
me.frictionAir = 0.025;
- me.collisionFilter.mask = cat.player | cat.bullet //| cat.body
+ me.collisionFilter.mask = cat.player | cat.bullet | cat.body
me.memory = Infinity;
Matter.Body.setDensity(me, 0.015); //extra dense //normal is 0.001 //makes effective life much larger
me.do = function () {
@@ -4263,7 +4263,7 @@ const spawn = {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
};
Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger
- me.damageReduction = 0.25
+ me.damageReduction = 0.33
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
me.nextHealthThreshold = 0.75
@@ -4279,7 +4279,7 @@ const spawn = {
}
};
me.lasers = [] //keeps track of static laser beams
- me.laserLimit = 2 + (simulation.difficultyMode < 3 ? 1 : 2)
+ me.laserLimit = 2 + (simulation.difficultyMode > 2) + (simulation.difficultyMode > 4)
me.fireDelay = Math.max(75, 140 - simulation.difficulty * 0.5)
me.cycle = 0
me.laserDelay = 210
@@ -5910,7 +5910,7 @@ const spawn = {
me.alpha = 1; //used in drawGhost
me.isNotCloaked = false; //used in drawGhost
me.isBadTarget = true;
- me.collisionFilter.mask = cat.bullet //| cat.body
+ me.collisionFilter.mask = cat.bullet | cat.body
me.showHealthBar = false;
me.memory = 900;
me.delay = 60
@@ -5961,7 +5961,7 @@ const spawn = {
if (!this.isNotCloaked) {
this.isNotCloaked = true;
this.isBadTarget = false;
- this.collisionFilter.mask = cat.player | cat.bullet
+ this.collisionFilter.mask = cat.player | cat.bullet | cat.body
}
}
//draw body
@@ -5976,7 +5976,7 @@ const spawn = {
} else if (this.isNotCloaked) {
this.isNotCloaked = false;
this.isBadTarget = true;
- this.collisionFilter.mask = cat.bullet; //can't touch player or walls
+ this.collisionFilter.mask = cat.bullet | cat.body; //can't touch player or walls
}
};
},
@@ -7392,7 +7392,7 @@ const spawn = {
snakeBody(x, y, radius = 10) {
mobs.spawn(x, y, 8, radius, "rgba(0,180,180,0.4)");
let me = mob[mob.length - 1];
- me.collisionFilter.mask = cat.bullet | cat.player //| cat.mob //| cat.body
+ me.collisionFilter.mask = cat.bullet | cat.player | cat.body //| cat.mob
me.damageReduction = 0.028
Matter.Body.setDensity(me, 0.0001); //normal is 0.001
diff --git a/n-gon/js/tech.js b/n-gon/js/tech.js
index e956a7b6..e5014ea1 100644
--- a/n-gon/js/tech.js
+++ b/n-gon/js/tech.js
@@ -108,20 +108,8 @@ const tech = {
if (tech.junkChance < 0.001 || tech.junkChance === undefined) tech.junkChance = 0
}
},
- giveRandomJUNK() {
- const list = []
- for (let i = 0; i < tech.tech.length; i++) {
- if (tech.tech[i].isJunk) list.push(tech.tech[i].name)
- }
- let name = list[Math.floor(Math.random() * list.length)]
- simulation.makeTextLog(`tech.giveTech("${name}")`);
- tech.giveTech(name)
- },
+
giveTech(index = 'random') {
- // if (Math.random() < tech.junkChance) {
- // tech.giveRandomJUNK();
- // return
- // }
if (index === 'random') {
let options = [];
for (let i = 0; i < tech.tech.length; i++) {
@@ -2342,7 +2330,7 @@ const tech = {
{
name: "buckling",
descriptionFunction() {
- return `if a block you threw kills a mob
spawn either ${powerUps.orb.coupling(1)}, ${powerUps.orb.boost(1)}, ${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, or ${powerUps.orb.research(1)}`
+ return `if a block kills a mob there's a 50% chance
to spawn either ${powerUps.orb.coupling(1)}, ${powerUps.orb.boost(1)}, ${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, or ${powerUps.orb.research(1)}`
},
maxCount: 1,
count: 0,
@@ -4291,7 +4279,7 @@ const tech = {
remove() {
if (this.count > 0 && m.alive) {
tech.damage /= this.damage
- powerUps.spawnDelay("research", 15)
+ requestAnimationFrame(() => { powerUps.spawnDelay("research", 15) });
this.frequency = 0
}
}
@@ -4349,16 +4337,16 @@ const tech = {
remove() {
if (this.count > 0 && m.alive) {
tech.damage /= this.damage
- powerUps.spawnDelay("ammo", this.ammo)
this.frequency = 0
+ requestAnimationFrame(() => { powerUps.spawnDelay("ammo", this.ammo) });
}
}
},
{
name: "deprecated",
- scale: 0.05,
+ scale: 0.07,
descriptionFunction() {
- return `after removing this gain
1.05x damage per removed tech(${(1 + this.scale * ((this.frequency === 0 ? 0 : 1) + tech.removeCount)).toFixed(2)}x)`
+ return `after removing this gain
${1 + this.scale}x damage per removed tech(${(1 + this.scale * ((this.frequency === 0 ? 0 : 1) + tech.removeCount)).toFixed(2)}x)`
},
maxCount: 1,
count: 0,
@@ -6453,7 +6441,7 @@ const tech = {
},
{
name: "von Neumann probe", //"drone repair",
- description: "after a drone expires it will use -5 energy
and a nearby block to replicate itself",
+ description: "after a drone expires it will use -4 energy
and a nearby block to replicate itself",
// description: "broken drones repair if the drone gun is active
repairing has a 25% chance to use 1 drone",
isGunTech: true,
maxCount: 1,
@@ -6461,7 +6449,7 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
- return tech.haveGunCheck("drones")
+ return tech.haveGunCheck("drones") || (m.fieldMode === 4 && simulation.molecularMode === 3)
},
requires: "drones",
effect() {
@@ -7862,8 +7850,7 @@ const tech = {
// },
{
name: "additive manufacturing",
- description: "hold crouch and use your field to print a block
with 1.8x density, damage, and launch speed",
- // description: "simultaneously fire and activate your field to make
molecular assembler print a throwable block
+80% block throwing speed",
+ description: "hold crouch and use your field to print a block
with 1.8x density, damage, and launch speed",
isFieldTech: true,
maxCount: 1,
count: 0,
@@ -7881,6 +7868,29 @@ const tech = {
tech.isPrinter = false;
}
},
+ {
+ name: "working mass",
+ // description: "molecular assembler prints one block
to jump off while midair",
+ descriptionFunction() {
+ const fieldName = m.fieldMode === 8 ? "pilot wave" : "molecular assembler"
+ return `${fieldName} prints a block
to jump off while midair a second time`
+ },
+ isFieldTech: true,
+ maxCount: 1,
+ count: 0,
+ frequency: 2,
+ frequencyDefault: 2,
+ allowed() {
+ return (m.fieldMode === 4 || m.fieldMode === 8)
+ },
+ requires: "molecular assembler, pilot wave",
+ effect() {
+ tech.isBlockJump = true
+ },
+ remove() {
+ tech.isBlockJump = false
+ }
+ },
{
name: "pair production",
description: "after picking up a power up
+200 energy",
@@ -7901,26 +7911,6 @@ const tech = {
tech.isMassEnergy = false;
}
},
- // {
- // name: "working mass",
- // // description: "after jumping jump again in midair
double jumping requires 50% of current energy
double jumping boosts speed",
- // description: "",
- // isFieldTech: true,
- // maxCount: 1,
- // count: 0,
- // frequency: 2,
- // frequencyDefault: 2,
- // allowed() {
- // return m.fieldMode === 4
- // },
- // requires: "molecular assembler",
- // effect() {
- // tech.isDoubleJump = true
- // },
- // remove() {
- // tech.isDoubleJump = false
- // }
- // },
{
name: "electric generator",
description: "after deflecting mobs
molecular assembler generates +50 energy",
@@ -8195,7 +8185,7 @@ const tech = {
},
{
name: "Lorentz transformation",
- description: `use ${powerUps.orb.research(3)}
1.5x movement, jumping, and fire rate`,
+ description: `use ${powerUps.orb.research(3)}
1.5x movement, jumping, and fire rate`,
isFieldTech: true,
maxCount: 1,
count: 0,
@@ -9271,9 +9261,15 @@ const tech = {
allowed: () => true,
requires: "",
effect() {
- tech.giveRandomJUNK()
- tech.giveRandomJUNK()
- tech.giveRandomJUNK()
+ for (let i = 0; i < 3; i++) {
+ const list = []
+ for (let i = 0; i < tech.tech.length; i++) {
+ if (tech.tech[i].isJunk) list.push(tech.tech[i].name)
+ }
+ let name = list[Math.floor(Math.random() * list.length)]
+ simulation.makeTextLog(`tech.giveTech("${name}")`);
+ tech.giveTech(name)
+ }
},
remove() { }
},
@@ -11848,5 +11844,5 @@ const tech = {
interestRate: null,
isImmunityDamage: null,
isMobDeathImmunity: null,
- isDoubleJump: null,
+ isBlockJump: null,
}
\ No newline at end of file
diff --git a/n-gon/style.css b/n-gon/style.css
index 1146a258..7855b461 100644
--- a/n-gon/style.css
+++ b/n-gon/style.css
@@ -935,6 +935,11 @@ summary {
text-shadow: 1px 0px 2px #234;
}
+.color-print {
+ color: #567;
+ font-family: 'Courier New', Courier, monospace;
+}
+
.color-defense {
background-color: hsla(227, 9%, 71%, 0.279);
padding: 2px;
diff --git a/n-gon/todo.txt b/n-gon/todo.txt
index f4bd3569..74d161df 100644
--- a/n-gon/todo.txt
+++ b/n-gon/todo.txt
@@ -1,19 +1,17 @@
******************************************************** NEXT PATCH **************************************************
-you can now jump off mobs while invulnerable
- includes time dilated
-pause display text updated with details menus
-difficulty parameters
- 0.82->0.84x damage done per level
- 1.25->1.23x damage taken per level
-tungsten carbide 300->400 health, but 0.08->0.02 seconds of coyote time and longer crouch time
-nitinol 0.08->0.17 seconds of coyote time and much less crouching on hard landings, but 0.8->1 damage taken
-mass-energy equivalence no longer costs 2 research
-long power up spawns, like from interest or supply chain:
- will pause new spawns until total power ups are below 300 to reduce lag
- stop spawning if you take damage
-
-bug fixes
+tech: working mass - in midair molecular assembler or pilot wave prints a block to jump off
+
+buckling: 100%->50% chance to spawn a power up from any block that kills a mob
+ no longer requires the block to be thrown
+mobs: powerUpBoss, snakeBoss tails, cellBoss, ghoster, sucker - all collide with blocks now
+added a few more blocks to towers level
+deprecated: 1.05->1.07 damage per removed tech
+laserLayerBoss has 33% less health and has fewer lasers at higher difficulties
+
+bugfix
+ disabled spawnDelay stopping on damage because it had too many negative tech interactions
+ metastability + paradigm shift no longer makes all ejected tech explode
******************************************************* DESIGN ******************************************************
@@ -36,22 +34,33 @@ list of powerful synergies
duplication 100%
interest + coupling, research + (peer review? or Bayesian statistics)
electronegativity and high energy?
- electronegativity + anyon + duplication + Maxwells demon + interest
+ electronegativity + anyon + duplication + Maxwells demon + interest + pair production
chain reaction + invulnerable + Abelian group + parasitism = clear all mobs on level
*********************************************************** TODO *****************************************************
-tech: working mass - double jump
- cost flat energy not a %
- field Tech for molecular assembler and print and throw a block down on 2nd jump
- remove block after time or keep it around?
- credit to TNTiger17 (although I'm not looking for more code contributions)
+make player mass an adjustable var in the skin
+ does this mess with jump height or air control?
+increase mass and movement speed at the same time
+ increase jump differently because it scales extra with mass
+ m.defaultMass = 4.5
+ m.definePlayerMass()
+ possible player.mass bad interactions
+ grapple
+
+JUNK tech - player takes damage from block collisions
+ is this gonna contribute to lag?
+
+player damage seems low
+player damage taken seems fine, or maybe increase
difficulty rework: explicit changes to the game to increase difficulty
UI -
add a wire attached to difficulty power up
like the one attached to player, but thinner
+laser: slow light is the least fun laser tech, make it more fun
+
tokamak synergy tech
tech: stellarator - after firing a block with tokamak, heal (scale heal amount with block mass?)
tech: inertial confinement - while charging tokamak you can fly, and invulnerable
@@ -823,11 +832,6 @@ intro map: diegeticly draw a mouse with field highlighted
also indicate space?
dynamically adjust drawing after picking up a gun
-increase mass and movement speed at the same time
- increase jump differently because it scales extra with mass
- m.defaultMass = 4.5
- m.definePlayerMass()
-
give history boss legs?
field tech - disable blocking, but does high damage to mobs inside field