diff --git a/.DS_Store b/.DS_Store
index f7316f4..addbf77 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/js/bullet.js b/js/bullet.js
index 5d78c0d..9969664 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -3876,7 +3876,7 @@ const b = {
y: position.y,
radius: 5,
color: "rgba(0,0,0,0.1)",
- time: 21 * tech.foamFutureFire
+ time: 18 * tech.foamFutureFire
});
setTimeout(() => {
@@ -3884,7 +3884,7 @@ const b = {
b.foam(position, velocity, radius)
bullet[bullet.length - 1].damage = (1 + 1.53 * tech.foamFutureFire) * (tech.isFastFoam ? 0.048 : 0.012) //double damage
}
- }, 350 * tech.foamFutureFire);
+ }, 300 * tech.foamFutureFire);
} else {
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 15 : 5) * b.fireCD); // cool down
@@ -3993,7 +3993,8 @@ const b = {
//draw magnetic field
const X = m.pos.x
const Y = m.pos.y
- const unitVector = Vector.normalise(Vector.sub(simulation.mouseInGame, m.pos))
+ // const unitVector = Vector.normalise(Vector.sub(simulation.mouseInGame, m.pos))
+ const unitVector = { x: Math.cos(m.angle), y: Math.sin(m.angle) }
const unitVectorPerp = Vector.perp(unitVector)
function magField(mag, arc) {
@@ -4218,7 +4219,8 @@ const b = {
//draw magnetic field
const X = m.pos.x
const Y = m.pos.y
- const unitVector = Vector.normalise(Vector.sub(simulation.mouseInGame, m.pos))
+ const unitVector = { x: Math.cos(m.angle), y: Math.sin(m.angle) }
+ //Vector.normalise(Vector.sub(simulation.mouseInGame, m.pos))
const unitVectorPerp = Vector.perp(unitVector)
function magField(mag, arc) {
diff --git a/js/engine.js b/js/engine.js
index f74a265..9be8869 100644
--- a/js/engine.js
+++ b/js/engine.js
@@ -99,6 +99,7 @@ function collisionChecks(event) {
if (
m.immuneCycle < m.cycle &&
(obj === playerBody || obj === playerHead) &&
+ // (obj === player) &&
!(tech.isFreezeHarmImmune && (mob[k].isSlowed || mob[k].isStunned))
) {
mob[k].foundPlayer();
diff --git a/js/index.js b/js/index.js
index d009870..a40ce79 100644
--- a/js/index.js
+++ b/js/index.js
@@ -318,6 +318,9 @@ const build = {
${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 {
techID.innerHTML = ` ${tech.tech[i].name} ${isCount}
${tech.tech[i].description}`
}
@@ -741,11 +744,6 @@ window.addEventListener("keydown", function(event) {
if (simulation.testing) {
-
-
-
-
-
}
}
}
@@ -785,6 +783,10 @@ window.addEventListener("keydown", function(event) {
| H |
+ infinite health |
+
+
+ | N |
fill health, energy |
@@ -795,6 +797,10 @@ window.addEventListener("keydown", function(event) {
| U |
next level |
+
+ | J |
+ clear mobs |
+
| I/O |
zoom in / out |
@@ -866,8 +872,14 @@ window.addEventListener("keydown", function(event) {
b.giveGuns("all", 1000)
break
case "h":
+ m.health = Infinity
+ // m.energy = Infinity
+ document.getElementById("health").style.display = "none"
+ document.getElementById("health-bg").style.display = "none"
+ break
+ case "n":
m.addHealth(Infinity)
- m.energy = m.maxEnergy;
+ m.energy = m.maxEnergy
break
case "y":
tech.giveTech()
@@ -896,6 +908,11 @@ window.addEventListener("keydown", function(event) {
case "u":
level.nextLevel();
break
+ case "j":
+ for (let i = 0, len = mob.length; i < len; ++i) mob[i].damage(Infinity, true)
+ setTimeout(() => { for (let i = 0, len = mob.length; i < len; ++i) mob[i].damage(Infinity, true) }, 100);
+ setTimeout(() => { for (let i = 0, len = mob.length; i < len; ++i) mob[i].damage(Infinity, true) }, 200);
+ break
}
}
});
diff --git a/js/level.js b/js/level.js
index c27da10..f938918 100644
--- a/js/level.js
+++ b/js/level.js
@@ -32,6 +32,7 @@ const level = {
// tech.giveTech("nail-bot")
// for (let i = 0; i < 15; i++) tech.giveTech("plasma jet")
// tech.isBlockPowerUps = true;
+ // m.shipMode()
level.intro(); //starting level
// level.testing(); //not in rotation
@@ -57,8 +58,8 @@ const level = {
// tech.giveTech("undefined")
// lore.techCount = 10
// localSettings.loreCount = 1;
- // simulation.isCheating = true;
- // localSettings.loreCount = undefined;
+ // simulation.isCheating = false //true;
+ // localSettings.loreCount = 1;
// localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
// level.null()
} else {
@@ -1085,7 +1086,7 @@ const level = {
// spawn.striker(1600, -500)
// spawn.shooter(1700, -120)
// spawn.bomberBoss(1400, -500)
- spawn.sniper(1800, -120)
+ // spawn.sniper(1800, -120)
// spawn.streamBoss(1600, -500)
// spawn.cellBossCulture(1600, -500)
// spawn.cellBossCulture(1600, -500)
@@ -1419,11 +1420,13 @@ const level = {
powerUps.spawn(2050, -150, "heal", false); //starting gun
// powerUps.spawn(2050, -150, "field", false); //starting gun
if (localSettings.levelsClearedLastGame < 6) {
- spawn.wireFoot();
- spawn.wireFootLeft();
- spawn.wireKnee();
- spawn.wireKneeLeft();
- spawn.wireHead();
+ if (!simulation.isCheating) {
+ spawn.wireFoot();
+ spawn.wireFootLeft();
+ spawn.wireKnee();
+ spawn.wireKneeLeft();
+ spawn.wireHead();
+ }
} else {
// const say = []
// if (localSettings.runCount > 200) { //experienced
@@ -2590,7 +2593,7 @@ const level = {
color: "rgba(0,0,0,0.2)"
});
level.fill.push({
- x: 3600,
+ x: 3800,
y: -110,
width: 400,
height: 110,
@@ -2614,7 +2617,7 @@ const level = {
});
level.fillBG.push({
x: 3350,
- y: -1325,
+ y: -1300,
width: 50,
height: 1325,
color: "#d4d4d7"
@@ -2627,7 +2630,7 @@ const level = {
color: "#d4f4f4"
});
- spawn.mapRect(-300, 0, 5000, 300); //***********ground
+ spawn.mapRect(-300, 0, 5100, 300); //***********ground
spawn.mapRect(-300, -350, 50, 400); //far left starting left wall
spawn.mapRect(-300, -10, 500, 50); //far left starting ground
spawn.mapRect(-300, -350, 500, 50); //far left starting ceiling
@@ -2638,7 +2641,7 @@ const level = {
spawn.mapRect(1600, -400, 1500, 500); //long center building
spawn.mapRect(1345, -1100, 250, 25); //left platform
spawn.mapRect(1755, -1100, 250, 25); //right platform
- spawn.mapRect(1300, -1850, 780, 50); //left higher platform
+ spawn.mapRect(1300, -1850, 800, 50); //left higher platform
spawn.mapRect(1300, -2150, 50, 350); //left higher platform left edge wall
spawn.mapRect(1300, -2150, 450, 50); //left higher platform roof
spawn.mapRect(1500, -1860, 100, 50); //ground bump wall
@@ -2647,10 +2650,10 @@ const level = {
spawn.mapRect(2500, -1450, 450, 350); //higher center floating large square
spawn.mapRect(2500, -1675, 50, 300); //left wall on higher center floating large square
spawn.mapRect(2500, -1700, 300, 50); //roof on higher center floating large square
- spawn.mapRect(3300, -850, 150, 25); //ledge by far right building
- spawn.mapRect(3300, -1350, 150, 25); //higher ledge by far right building
- spawn.mapRect(3600, -1100, 400, 990); //far right building
- spawn.boost(4150, 0, 1300);
+ spawn.mapRect(3275, -750, 200, 25); //ledge by far right building
+ spawn.mapRect(3275, -1300, 200, 25); //higher ledge by far right building
+ spawn.mapRect(3800, -1100, 400, 990); //far right building
+ spawn.boost(4450, 0, 1300);
spawn.bodyRect(3200, -1375, 300, 25, 0.9);
spawn.bodyRect(1825, -1875, 400, 25, 0.9);
diff --git a/js/lore.js b/js/lore.js
index 7b3c52b..c553a4e 100644
--- a/js/lore.js
+++ b/js/lore.js
@@ -4,9 +4,11 @@ const lore = {
anand: {
color: "#e0c",
text: function(say, isSpeech = false) {
- simulation.makeTextLog(`input.audio(${Date.now()} ms): "${say}"`, Infinity);
- lore.talkingColor = this.color
- if (isSpeech) this.speech(say)
+ if (level.levels[level.onLevel] === undefined) { //only talk if on the lore level (which is undefined because it is popped out of the level.levels array)
+ simulation.makeTextLog(`input.audio(${Date.now()} ms): "${say}"`, Infinity);
+ lore.talkingColor = this.color
+ if (isSpeech) this.speech(say)
+ }
},
speech: function(say) {
var utterance = new SpeechSynthesisUtterance(say);
@@ -18,9 +20,11 @@ const lore = {
miriam: {
color: "#f20",
text: function(say, isSpeech = false) {
- simulation.makeTextLog(`input.audio(${Date.now()} ms): "${say}"`, Infinity);
- lore.talkingColor = this.color
- if (isSpeech) this.speech(say)
+ if (level.levels[level.onLevel] === undefined) { //only talk if on the lore level (which is undefined because it is popped out of the level.levels array)
+ simulation.makeTextLog(`input.audio(${Date.now()} ms): "${say}"`, Infinity);
+ lore.talkingColor = this.color
+ if (isSpeech) this.speech(say)
+ }
},
speech: function(say) {
var utterance = new SpeechSynthesisUtterance(say);
@@ -58,9 +62,14 @@ const lore = {
delay += 3700
setTimeout(() => { lore.talkingColor = "#dff" }, delay); //set color of graphic on level.null when no one is talking
delay += 25000
- setTimeout(() => { lore.miriam.text("Poor thing... I hope it figures out how to escape.", true) }, delay);
- delay += 3500
- setTimeout(() => { lore.talkingColor = "#dff" }, delay); //set color of graphic on level.null when no one is talking
+ setTimeout(() => {
+ if (!simulation.isCheating) {
+ lore.miriam.text("Poor thing... I hope it figures out how to escape.", true)
+ delay += 3500
+ setTimeout(() => { lore.talkingColor = "#dff" }, delay); //set color of graphic on level.null when no one is talking
+ }
+ }, delay);
+
},
() => {
if (localSettings.loreCount < 2) {
@@ -129,9 +138,9 @@ const lore = {
}, delay);
},
() => {
- let delay = 6000
- setTimeout(() => { lore.miriam.text("I've never seen it generate this level before.", true) }, delay);
- delay += 2700
+ // let delay = 6000
+ // setTimeout(() => { lore.miriam.text("I've never seen it generate this level before.", true) }, delay);
+ // delay += 2700
},
],
diff --git a/js/player.js b/js/player.js
index 763e4ce..f953fac 100644
--- a/js/player.js
+++ b/js/player.js
@@ -57,8 +57,8 @@ const m = {
lastHarmCycle: 0,
width: 50,
radius: 30,
- fillColor: "#fff",
- fillColorDark: "#ccc",
+ fillColor: null, //set by setFillColors
+ fillColorDark: null, //set by setFillColors
color: {
hue: 0,
sat: 0,
@@ -66,7 +66,7 @@ const m = {
},
setFillColors() {
this.fillColor = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light}%)`
- this.fillColorDark = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light-20}%)`
+ this.fillColorDark = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light-25}%)`
},
height: 42,
yOffWhen: {
@@ -236,20 +236,7 @@ const m = {
x: player.position.x,
y: player.position.y - 30.28592321
})
- // Matter.Body.translate(playerHead, {
- // x: 0,
- // y: -40
- // });
}
-
- // playerHead.collisionFilter = {
- // group: 0,
- // category: cat.player,
- // mask: cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield
- // }
- // playerHead.isSensor = false;
- // playerHead.collisionFilter.category = cat.player
- // playerHead.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield
}
},
hardLandCD: 0,
@@ -803,12 +790,13 @@ const m = {
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5
ctx.translate(m.pos.x, m.pos.y);
+
m.calcLeg(Math.PI, -3);
m.drawLeg("#4a4a4a");
m.calcLeg(0, 0);
m.drawLeg("#333");
- ctx.rotate(m.angle);
+ ctx.rotate(m.angle);
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
let grd = ctx.createLinearGradient(-30, 0, 30, 0);
@@ -2586,4 +2574,304 @@ const m = {
},
},
],
+ isShipMode: false,
+ shipMode() {
+ if (!m.isShipMode) {
+ m.isShipMode = true
+ simulation.isCheating = true
+ const points = [
+ { x: 29.979168754143455, y: 4.748337243898336 },
+ { x: 27.04503734408824, y: 13.7801138209198 },
+ { x: 21.462582474874278, y: 21.462582475257523 },
+ { x: 13.780113820536943, y: 27.045037344471485 },
+ { x: 4.74833724351507, y: 29.979168754526473 },
+ { x: -4.748337245049098, y: 29.979168754526473 },
+ { x: -13.780113822071026, y: 27.045037344471485 },
+ { x: -21.46258247640829, y: 21.462582475257523 },
+ { x: -27.045037345621797, y: 13.7801138209198 },
+ { x: -29.979168755677012, y: 4.748337243898336 },
+ { x: -29.979168755677012, y: -4.7483372446656045 },
+ { x: -27.045037345621797, y: -13.78011382168726 },
+ { x: -21.46258247640829, y: -21.462582476024817 },
+ { x: -13.780113822071026, y: -27.045037345239006 },
+ { x: -4.748337245049098, y: -29.97916875529422 },
+ { x: 4.74833724351507, y: -29.97916875529422 },
+ { x: 13.780113820536943, y: -27.045037345239006 },
+ { x: 21.462582474874278, y: -21.462582476024817 },
+ { x: 27.04503734408824, y: -13.78011382168726 },
+ { x: 29.979168754143455, y: -4.7483372446656045 }
+ ]
+ //
+ Matter.Body.setVertices(player, Matter.Vertices.create(points, player))
+ // console.log(circle)
+ player.parts.pop()
+ player.parts.pop()
+ player.parts.pop()
+ player.parts.pop()
+ // Matter.Body.setDensity(player, 0.01); //extra dense //normal is 0.001 //makes effective life much larger
+ m.defaultMass = 30
+ Matter.Body.setMass(player, m.defaultMass);
+ player.friction = 0.07
+ // player.frictionStatic = 0.1
+ // Matter.Body.setInertia(player, Infinity); //disable rotation
+
+ // const circle = Bodies.polygon(player.position.x, player.position.x, 30, 30)
+ // player.parts[0] = circle
+ // console.log(player.parts[0])
+ // Matter.Body.setVertices(player.parts[0], Matter.Vertices.create(points, player.parts[0]))
+ // console.log(player.parts[0].vertices)
+
+ level.playerExitCheck = () => {
+ if (
+ player.position.x > level.exit.x &&
+ player.position.x < level.exit.x + 100 &&
+ player.position.y > level.exit.y - 150 &&
+ player.position.y < level.exit.y - 40 &&
+ player.speed < 4
+ ) {
+ level.nextLevel()
+ }
+ }
+ m.move = () => {
+ m.pos.x = player.position.x;
+ m.pos.y = player.position.y;
+ m.Vx = player.velocity.x;
+ m.Vy = player.velocity.y;
+
+ //tracks the last 10s of player information
+ // console.log(m.history)
+ m.history.splice(m.cycle % 600, 1, {
+ position: {
+ x: player.position.x,
+ y: player.position.y,
+ },
+ velocity: {
+ x: player.velocity.x,
+ y: player.velocity.y
+ },
+ yOff: m.yOff,
+ angle: m.angle,
+ health: m.health,
+ energy: m.energy,
+ activeGun: b.activeGun
+ });
+ }
+
+ m.look = () => { //disable mouse aiming
+ //always on mouse look
+ // m.angle = Math.atan2(
+ // simulation.mouseInGame.y - m.pos.y,
+ // simulation.mouseInGame.x - m.pos.x
+ // );
+ //smoothed mouse look translations
+ const scale = 0.8;
+ m.transSmoothX = canvas.width2 - m.pos.x - (simulation.mouse.x - canvas.width2) * scale;
+ m.transSmoothY = canvas.height2 - m.pos.y - (simulation.mouse.y - canvas.height2) * scale;
+
+ m.transX += (m.transSmoothX - m.transX) * 0.07;
+ m.transY += (m.transSmoothY - m.transY) * 0.07;
+ }
+
+ simulation.camera = () => {
+ const dx = simulation.mouse.x / window.innerWidth - 0.5 //x distance from mouse to window center scaled by window width
+ const dy = simulation.mouse.y / window.innerHeight - 0.5 //y distance from mouse to window center scaled by window height
+ const d = Math.max(dx * dx, dy * dy)
+ simulation.edgeZoomOutSmooth = (1 + 4 * d * d) * 0.04 + simulation.edgeZoomOutSmooth * 0.96
+
+
+ ctx.save();
+ ctx.translate(canvas.width2, canvas.height2); //center
+ ctx.scale(simulation.zoom / simulation.edgeZoomOutSmooth, simulation.zoom / simulation.edgeZoomOutSmooth); //zoom in once centered
+ ctx.translate(-canvas.width2 + m.transX, -canvas.height2 + m.transY); //translate
+ //calculate in game mouse position by undoing the zoom and translations
+ simulation.mouseInGame.x = (simulation.mouse.x - canvas.width2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.width2 - m.transX;
+ simulation.mouseInGame.y = (simulation.mouse.y - canvas.height2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.height2 - m.transY;
+ }
+
+ m.draw = () => { //just draw the circle
+ ctx.save();
+ ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5
+ ctx.translate(player.position.x, player.position.y);
+ ctx.rotate(player.angle);
+
+ ctx.beginPath();
+ ctx.arc(0, 0, 30, 0, 2 * Math.PI);
+ let grd = ctx.createLinearGradient(-30, 0, 30, 0);
+ grd.addColorStop(0, m.fillColorDark);
+ grd.addColorStop(1, m.fillColor);
+ ctx.fillStyle = grd;
+ ctx.fill();
+ ctx.arc(15, 0, 4, 0, 2 * Math.PI);
+ ctx.strokeStyle = "#333";
+ ctx.lineWidth = 2;
+ ctx.stroke();
+ ctx.restore();
+ }
+ m.spin = 0
+ // m.groundControl = () => {} //disable entering ground
+ m.onGround = false
+ playerOnGroundCheck = () => {}
+ m.airControl = () => { //tank controls
+ player.force.y -= player.mass * simulation.g; //undo gravity
+ const thrust = 0.03 * tech.squirrelJump //Math.max(0.1 / (0.01 + player.speed), 0.03) * tech.squirrelJump
+ // console.log(player.speed, thrust)
+ if (input.up) { //thrust
+ player.force.x += thrust * Math.cos(m.angle)
+ player.force.y += thrust * Math.sin(m.angle)
+
+ const friction = 0.99
+ Matter.Body.setVelocity(player, {
+ x: friction * player.velocity.x,
+ y: friction * player.velocity.y
+ });
+ } else if (input.down) {
+ player.force.x -= 0.7 * thrust * Math.cos(m.angle)
+ player.force.y -= 0.7 * thrust * Math.sin(m.angle)
+
+ const friction = 0.96
+ Matter.Body.setVelocity(player, {
+ x: friction * player.velocity.x,
+ y: friction * player.velocity.y
+ });
+ }
+ const spinChange = 1.1
+ if (input.right) {
+ player.torque += spinChange
+ // m.spin += spinChange
+ } else if (input.left) {
+ // m.spin -= spinChange
+ player.torque -= spinChange
+ }
+ Matter.Body.setAngularVelocity(player, player.angularVelocity * 0.9)
+ // m.spin *= 0.88 //spin friction
+ m.angle += m.spin //
+ m.angle = player.angle
+ }
+ //fix collisions
+
+ collisionChecks = (event) => {
+ const pairs = event.pairs;
+ for (let i = 0, j = pairs.length; i != j; i++) {
+ //mob + (player,bullet,body) collisions
+ for (let k = 0; k < mob.length; k++) {
+ if (mob[k].alive && m.alive) {
+ if (pairs[i].bodyA === mob[k]) {
+ collideMob(pairs[i].bodyB);
+ break;
+ } else if (pairs[i].bodyB === mob[k]) {
+ collideMob(pairs[i].bodyA);
+ break;
+ }
+
+ function collideMob(obj) {
+ //player + mob collision
+ if (
+ m.immuneCycle < m.cycle &&
+ // (obj === playerBody || obj === playerHead) &&
+ (obj === player) &&
+ !(tech.isFreezeHarmImmune && (mob[k].isSlowed || mob[k].isStunned))
+ ) {
+ mob[k].foundPlayer();
+ let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * simulation.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0
+ if (tech.isRewindAvoidDeath && m.energy > 0.66) { //CPT reversal runs in m.damage, but it stops the rest of the collision code here too
+ m.damage(dmg);
+ return
+ }
+ m.damage(dmg);
+ if (tech.isPiezo) m.energy += 4;
+ if (tech.isBayesian) powerUps.ejectTech()
+ if (mob[k].onHit) mob[k].onHit(k);
+ m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to collision 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)
+ });
+
+ if (tech.isAnnihilation && !mob[k].shield && !mob[k].isShielded && mob[k].dropPowerUp && m.energy > 0.34 * m.maxEnergy) {
+ m.energy -= 0.33 * m.maxEnergy
+ m.immuneCycle = 0; //player doesn't go immune to collision damage
+ mob[k].death();
+ simulation.drawList.push({ //add dmg to draw queue
+ x: pairs[i].activeContacts[0].vertex.x,
+ y: pairs[i].activeContacts[0].vertex.y,
+ radius: dmg * 2000,
+ color: "rgba(255,0,255,0.2)",
+ time: simulation.drawTime
+ });
+ } else {
+ simulation.drawList.push({ //add dmg to draw queue
+ x: pairs[i].activeContacts[0].vertex.x,
+ y: pairs[i].activeContacts[0].vertex.y,
+ radius: dmg * 500,
+ color: simulation.mobDmgColor,
+ time: simulation.drawTime
+ });
+ }
+ return;
+ // }
+ }
+ //mob + bullet collisions
+ if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) {
+ obj.beforeDmg(mob[k]); //some bullets do actions when they hits things, like despawn //forces don't seem to work here
+ let dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)))
+ if (tech.isCrit && mob[k].isStunned) dmg *= 4
+ mob[k].foundPlayer();
+ mob[k].damage(dmg);
+ simulation.drawList.push({ //add dmg to draw queue
+ x: pairs[i].activeContacts[0].vertex.x,
+ y: pairs[i].activeContacts[0].vertex.y,
+ radius: Math.log(2 * dmg + 1.1) * 40,
+ color: simulation.playerDmgColor,
+ time: simulation.drawTime
+ });
+ return;
+ }
+ //mob + body collisions
+ if (obj.classType === "body" && obj.speed > 6) {
+ const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity));
+ if (v > 9) {
+ let dmg = 0.05 * b.dmgScale * v * obj.mass * tech.throwChargeRate;
+ if (mob[k].isShielded) dmg *= 0.35
+ mob[k].damage(dmg, true);
+ if (tech.isBlockPowerUps && !mob[k].alive && mob[k].dropPowerUp) {
+ let type = tech.isEnergyNoAmmo ? "heal" : "ammo"
+ if (Math.random() < 0.4) {
+ type = "heal"
+ } else if (Math.random() < 0.3 && !tech.isSuperDeterminism) {
+ type = "research"
+ }
+ powerUps.spawn(mob[k].position.x, mob[k].position.y, type);
+ // for (let i = 0, len = Math.ceil(2 * Math.random()); i < len; i++) {}
+ }
+
+ const stunTime = dmg / Math.sqrt(obj.mass)
+ if (stunTime > 0.5) mobs.statusStun(mob[k], 30 + 60 * Math.sqrt(stunTime))
+ if (mob[k].distanceToPlayer2() < 1000000 && !m.isCloak) mob[k].foundPlayer();
+ if (tech.fragments && obj.speed > 10 && !obj.hasFragmented) {
+ obj.hasFragmented = true;
+ b.targetedNail(obj.position, tech.fragments * 4)
+ }
+ simulation.drawList.push({
+ x: pairs[i].activeContacts[0].vertex.x,
+ y: pairs[i].activeContacts[0].vertex.y,
+ radius: Math.log(2 * dmg + 1.1) * 40,
+ color: simulation.playerDmgColor,
+ time: simulation.drawTime
+ });
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
};
\ No newline at end of file
diff --git a/js/spawn.js b/js/spawn.js
index 313794d..be151aa 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -103,9 +103,8 @@ const spawn = {
level.levels.push("null")
level.exit.x = 5500;
level.exit.y = -330;
- simulation.makeTextLog(`level.levels.push("null")`) //
${powerUps.research.count}
-
- //remove block map element
+ simulation.makeTextLog(`undecided = ${lore.techCount}/10
level.levels.push("null")`);
+ //remove block map element so exit is clear
Matter.World.remove(engine.world, map[map.length - 1]);
map.splice(map.length - 1, 1);
simulation.draw.setPaths(); //redraw map draw path
@@ -113,8 +112,8 @@ const spawn = {
//reset game
setTimeout(() => {
simulation.makeTextLog(`simulation.complete()`);
- let delay = 1000
- for (let i = 0; i < 1.01; i += 0.01 + 0.1 * Math.random()) {
+ let delay = 2000
+ for (let i = 0; i < 1; i += 0.01 + 0.2 * Math.random() * Math.random()) {
setTimeout(function() {
simulation.makeTextLog(`simulation.analysis = ${(i).toFixed(3)}`);
}, delay);
@@ -122,13 +121,15 @@ const spawn = {
}
setTimeout(function() {
simulation.makeTextLog(`simulation.analysis = 1`);
- }, delay);
- delay += 2000
- setTimeout(() => {
- if (!simulation.paused && !simulation.testing) {
- simulation.makeTextLog(`World.clear(engine.world)`);
- setTimeout(() => { m.death() }, 2000);
- }
+ setTimeout(() => {
+ simulation.makeTextLog(`undecided = ${lore.techCount}/10`);
+ setTimeout(() => {
+ if (!simulation.paused && !simulation.testing) {
+ simulation.makeTextLog(`World.clear(engine.world)`);
+ setTimeout(() => { m.death() }, 4000);
+ }
+ }, 3000);
+ }, 2000);
}, delay);
}, 5000);
}
@@ -161,8 +162,10 @@ const spawn = {
//push away mobs
for (let i = 0, len = mob.length; i < len; ++i) {
if (mob[i] !== this) {
- const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, mob[i].position)), -65)
- Matter.Body.setVelocity(mob[i], Vector.add(mob[i].velocity, velocity));
+ mob[i].damage(Infinity, true);
+
+ // const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, mob[i].position)), -65)
+ // Matter.Body.setVelocity(mob[i], Vector.add(mob[i].velocity, velocity));
}
}
diff --git a/js/tech.js b/js/tech.js
index 588ef76..1121144 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -3220,7 +3220,7 @@ const tech = {
},
{
name: "quantum foam",
- description: "foam gun fires 0.35 seconds into the future
increase foam gun damage by 153%",
+ description: "foam gun fires 0.3 seconds into the future
increase foam gun damage by 153%",
isGunTech: true,
maxCount: 9,
count: 0,
@@ -4216,7 +4216,7 @@ const tech = {
this.count--
},
remove() {}
- }
+ },
],
addLoreTechToPool() { //adds lore tech to tech pool
if (!simulation.isCheating) {
@@ -4268,6 +4268,43 @@ const tech = {
// },
// remove() {}
// },
+ {
+ name: "banish",
+ description: "erase all junk tech from the possible pool
probably...",
+ maxCount: 1,
+ count: 0,
+ numberInPool: 0,
+ isNonRefundable: true,
+ isCustomHide: true,
+ isJunk: true,
+ allowed() {
+ return true
+ },
+ requires: "",
+ effect() {
+ tech.removeJunkTechFromPool()
+ },
+ remove() {}
+ },
+ {
+ name: "ship",
+ description: "fly around with no legs
reduce combat difficulty by 1 level",
+ maxCount: 1,
+ count: 0,
+ numberInPool: 0,
+ isNonRefundable: true,
+ isCustomHide: true,
+ isJunk: true,
+ allowed() {
+ return !m.isShipMode
+ },
+ requires: "",
+ effect() {
+ m.shipMode()
+ level.difficultyDecrease(simulation.difficultyMode)
+ },
+ remove() {}
+ },
{
name: "lubrication",
description: "reduce block density and friction for this level",
@@ -4544,7 +4581,7 @@ const tech = {
isCustomHide: true,
isJunk: true,
allowed() {
- return true
+ return !m.isShipMode
},
requires: "",
effect() {
@@ -4593,7 +4630,7 @@ const tech = {
isCustomHide: true,
isJunk: true,
allowed() {
- return true
+ return !m.isShipMode
},
requires: "",
effect() {
@@ -4637,7 +4674,7 @@ const tech = {
isCustomHide: true,
isJunk: true,
allowed() {
- return true
+ return !m.isShipMode
},
requires: "",
effect() {
@@ -4833,7 +4870,7 @@ const tech = {
},
requires: "at least 1 gun",
effect() {
- for (let i = 0; i < b.inventory.length; i++) powerUps.spawn(m.pos.x, m.pos.y, "gun");
+ for (let i = 0; i < b.inventory.length; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "gun");
//removes guns and ammo
b.inventory = [];
@@ -4861,7 +4898,7 @@ const tech = {
},
requires: "at least 4 research",
effect() {
- for (let i = 0; i < powerUps.research.count; i++) powerUps.spawn(m.pos.x, m.pos.y, "research");
+ for (let i = 0; i < powerUps.research.count; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "research");
powerUps.research.count = 0
},
remove() {}
diff --git a/todo.txt b/todo.txt
index c3393ab..f7c6f6c 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,11 +1,8 @@
******************************************************** NEXT PATCH ********************************************************
-all mobs that move through walls and blocks now have a transparent fill
-player and power ups float in hazards
-
-tech: apomixis - after reaching 100% duplication spawn 4 level bosses
-tech: quantum foam - +153% foam damage, fire 0.35s into the future
-bullets are bigger, and easier to see
+added 2 new testing keys: J = clear mobs, H = infinity health
+added junk tech: ship (it's hard to control, but you get better with practice)
+ m.shipMode() in console
******************************************************** BUGS ********************************************************
@@ -35,7 +32,23 @@ use the floor of portal sensor on the player? to unstuck player
******************************************************** TODO ********************************************************
-increase bullet size, but don't increase bullet damage
+tech: health becomes drones
+ requires mass-energy?
+ junk tech?
+
+tech: 1/3 of the time foam fires 1 extra backwards foam
+
+make a secret only accessible to the ship (very small + flying)
+
+map: laboratory
+ rooms with switches that change physics
+ gravity room
+ portal room
+ laser room
+ radiation room
+ portal + rotor + falling blocks = perpetual motion room
+ a button that spawns a heal.
+
final boss: hide boss after spawning mobs
reduce health by 1/3?
@@ -264,14 +277,6 @@ give mobs more animal-like behaviors like rain world
this might be hard to code
isolated mobs try to group up
-map: laboratory
- rooms with switches that change physics
- gravity room
- portal room
- laser room
- radiation room
- a button that spawns a heal.
-
mob: wall mounted guns / lasers
not part of randomized mob pool, customized to each level