double jump

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
This commit is contained in:
landgreen
2024-06-13 12:05:40 -07:00
parent 438c16699e
commit 1903b9e938
11 changed files with 268 additions and 154 deletions

BIN
img/working mass.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -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)

View File

@@ -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)]);

View File

@@ -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);

View File

@@ -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 <strong class='color-f'>energy</strong> used to print ${simulation.molecularMode === 0 ? "<strong class='color-p' style='letter-spacing: 2px;'>spores" : simulation.molecularMode === 1 ? "<strong>missiles" : simulation.molecularMode === 2 ? "<strong class='color-s'>ice IX" : "<strong>drones"}</strong><br>use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br><strong>12</strong> <strong class='color-f'>energy</strong> per second`,
description: `excess <strong class='color-f'>energy</strong> used to <strong class='color-print'>print</strong> ${simulation.molecularMode === 0 ? "<strong class='color-p' style='letter-spacing: 2px;'>spores" : simulation.molecularMode === 1 ? "<strong>missiles" : simulation.molecularMode === 2 ? "<strong class='color-s'>ice IX" : "<strong>drones"}</strong><br>use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br><strong>12</strong> <strong class='color-f'>energy</strong> per second`,
setDescription() {
return `excess <strong class='color-f'>energy</strong> used to print ${simulation.molecularMode === 0 ? "<strong class='color-p' style='letter-spacing: 2px;'>spores" : simulation.molecularMode === 1 ? "<strong>missiles" : simulation.molecularMode === 2 ? "<strong class='color-s'>ice IX" : "<strong>drones"}</strong><br>use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br><strong>12</strong> <strong class='color-f'>energy</strong> per second`
return `excess <strong class='color-f'>energy</strong> used to <strong class='color-print'>print</strong> ${simulation.molecularMode === 0 ? "<strong class='color-p' style='letter-spacing: 2px;'>spores" : simulation.molecularMode === 1 ? "<strong>missiles" : simulation.molecularMode === 2 ? "<strong class='color-s'>ice IX" : "<strong>drones"}</strong><br>use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br><strong>12</strong> <strong class='color-f'>energy</strong> 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) {
} else { //reset
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
}
}
// 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"

View File

@@ -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();

View File

@@ -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<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.up}</span>", "<span class='color-text'>ArrowUp</span>"]`);
// simulation.makeTextLog(`input.key.left<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.left}</span>", "<span class='color-text'>ArrowLeft</span>"]`);
// simulation.makeTextLog(`input.key.down<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.down}</span>", "<span class='color-text'>ArrowDown</span>"]`);
// simulation.makeTextLog(`input.key.right<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.right}</span>", "<span class='color-text'>ArrowRight</span>"]`);
simulation.makeTextLog(`Math.seed <span class='color-symbol'>=</span> ${Math.initialSeed}`);
simulation.makeTextLog(`<span class='color-var'>const</span> engine <span class='color-symbol'>=</span> Engine.create(); <em>//simulation begin</em>`);
simulation.makeTextLog(`engine.timing.timeScale <span class='color-symbol'>=</span> 1`);
// simulation.makeTextLog(`input.key.field<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.field}</span>", "<span class='color-text'>MouseRight</span>"]`);
// 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}<strong style='font-size:30px;'> ${m.fieldUpgrades[m.fieldMode].name}</strong><br><span class='faded'></span><br>${m.fieldUpgrades[m.fieldMode].description}`, 600);
// simulation.makeTextLog(`
// input.key.up <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.up}</span>", "<span class='color-text'>ArrowUp</span>"]
// <br>input.key.left <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.left}</span>", "<span class='color-text'>ArrowLeft</span>"]
// <br>input.key.down <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.down}</span>", "<span class='color-text'>ArrowDown</span>"]
// <br>input.key.right <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.right}</span>", "<span class='color-text'>ArrowRight</span>"]
// <br>
// <br><span class='color-var'>m</span>.fieldMode <span class='color-symbol'>=</span> "<span class='color-text'>${m.fieldUpgrades[m.fieldMode].name}</span>"
// <br>input.key.field <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.field}</span>", "<span class='color-text'>right mouse</span>"]
// <br><span class='color-var'>m</span>.field.description <span class='color-symbol'>=</span> "<span class='color-text'>${m.fieldUpgrades[m.fieldMode].description}</span>"
// `, 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;

View File

@@ -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

View File

@@ -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(`<span class='color-var'>tech</span>.giveTech("<span class='color-text'>${name}</span>")<em>`);
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 <strong class='color-block'>block</strong> you threw kills a mob<br>spawn either ${powerUps.orb.coupling(1)}, ${powerUps.orb.boost(1)}, ${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, or ${powerUps.orb.research(1)}`
return `if a <strong class='color-block'>block</strong> kills a mob there's a <strong>50%</strong> chance<br>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 <span class='color-remove'>removing</span> this gain<br><strong>1.05x</strong> <strong class='color-d'>damage</strong> per <span class='color-remove'>removed</span> <strong class='color-m'>tech</strong><em>(${(1 + this.scale * ((this.frequency === 0 ? 0 : 1) + tech.removeCount)).toFixed(2)}x)</em>`
return `after <span class='color-remove'>removing</span> this gain<br><strong>${1 + this.scale}x</strong> <strong class='color-d'>damage</strong> per <span class='color-remove'>removed</span> <strong class='color-m'>tech</strong><em>(${(1 + this.scale * ((this.frequency === 0 ? 0 : 1) + tech.removeCount)).toFixed(2)}x)</em>`
},
maxCount: 1,
count: 0,
@@ -6453,7 +6441,7 @@ const tech = {
},
{
name: "von Neumann probe", //"drone repair",
description: "after a <strong>drone</strong> expires it will use <strong>-5</strong> <strong class='color-f'>energy</strong><br>and a nearby <strong class='color-block'>block</strong> to <strong>replicate</strong> itself",
description: "after a <strong>drone</strong> expires it will use <strong>-4</strong> <strong class='color-f'>energy</strong><br>and a nearby <strong class='color-block'>block</strong> to <strong>replicate</strong> itself",
// 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,
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 <strong>crouch</strong> and use your <strong class='color-f'>field</strong> to <strong>print</strong> a <strong class='color-block'>block</strong><br> with <strong>1.8x</strong> density, <strong class='color-d'>damage</strong>, and launch speed",
// description: "simultaneously <strong>fire</strong> and activate your <strong class='color-f'>field</strong> to make<br>molecular assembler <strong>print</strong> a throwable <strong class='color-block'>block</strong><br><strong>+80%</strong> <strong class='color-block'>block</strong> throwing speed",
description: "hold <strong>crouch</strong> and use your <strong class='color-f'>field</strong> to <strong class='color-print'>print</strong> a <strong class='color-block'>block</strong><br> with <strong>1.8x</strong> density, <strong class='color-d'>damage</strong>, and launch speed",
isFieldTech: true,
maxCount: 1,
count: 0,
@@ -7881,6 +7868,29 @@ const tech = {
tech.isPrinter = false;
}
},
{
name: "working mass",
// description: "molecular assembler <strong class='color-print'>prints</strong> one <strong class='color-block'>block</strong><br>to <strong>jump</strong> off while midair",
descriptionFunction() {
const fieldName = m.fieldMode === 8 ? "pilot wave" : "molecular assembler"
return `${fieldName} <strong class='color-print'>prints</strong> a <strong class='color-block'>block</strong><br>to <strong>jump</strong> 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 <strong>power up</strong><br><strong>+200</strong> <strong class='color-f'>energy</strong>",
@@ -7901,26 +7911,6 @@ const tech = {
tech.isMassEnergy = false;
}
},
// {
// name: "working mass",
// // description: "after jumping jump again in <strong>midair</strong><br><strong>double jumping</strong> requires <strong>50%</strong> of current <strong class='color-f'>energy</strong><br><strong>double jumping</strong> boosts <strong class='color-speed'>speed</strong>",
// 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 <strong>deflecting</strong> mobs<br><strong>molecular assembler</strong> generates <strong>+50</strong> <strong class='color-f'>energy</strong>",
@@ -8195,7 +8185,7 @@ const tech = {
},
{
name: "Lorentz transformation",
description: `use ${powerUps.orb.research(3)}<br><strong>1.5x</strong> <strong>movement</strong>, <strong>jumping</strong>, and <em>fire rate</em>`,
description: `use ${powerUps.orb.research(3)}<br><strong>1.5x</strong> movement, jumping, and <em>fire rate</em>`,
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(`<span class='color-var'>tech</span>.giveTech("<span class='color-text'>${name}</span>")<em>`);
tech.giveTech(name)
}
},
remove() { }
},
@@ -11848,5 +11844,5 @@ const tech = {
interestRate: null,
isImmunityDamage: null,
isMobDeathImmunity: null,
isDoubleJump: null,
isBlockJump: null,
}

View File

@@ -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;

View File

@@ -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
tech: working mass - in midair molecular assembler or pilot wave prints a block to jump off
bug fixes
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