diff --git a/img/diaphragm.webp b/img/diaphragm.webp new file mode 100644 index 0000000..10a8bc2 Binary files /dev/null and b/img/diaphragm.webp differ diff --git a/img/elasticity.webp b/img/elasticity.webp new file mode 100644 index 0000000..a2081d7 Binary files /dev/null and b/img/elasticity.webp differ diff --git a/img/squirrel-cage rotor.webp b/img/squirrel-cage rotor.webp deleted file mode 100644 index 63c2c81..0000000 Binary files a/img/squirrel-cage rotor.webp and /dev/null differ diff --git a/js/bullet.js b/js/bullet.js index aef31f6..63dd2d9 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -3751,7 +3751,7 @@ const b = { bullet[me] = Bodies.polygon(where.x, where.y, 12, radius, b.fireAttributes(dir, false)); Composite.add(engine.world, bullet[me]); //add bullet to world Matter.Body.setVelocity(bullet[me], velocity); - Matter.Body.setDensity(bullet[me], 0.0008 + 0.0008 * tech.superHarm); + Matter.Body.setDensity(bullet[me], 0.0008 + 0.0009 * tech.superHarm); bullet[me].endCycle = simulation.cycle + Math.floor(300 + 90 * Math.random()); bullet[me].minDmgSpeed = 0; bullet[me].restitution = 1; @@ -3761,7 +3761,7 @@ const b = { this.force.y += this.mass * 0.0012; if (Matter.Query.collides(this, [player]).length) { this.endCycle = 0 - let dmg = 0.02 * this.mass * tech.superHarm + let dmg = 0.015 * this.mass * tech.superHarm m.damage(dmg); simulation.drawList.push({ //add dmg to draw queue x: this.position.x, diff --git a/js/engine.js b/js/engine.js index 04536f0..04772f8 100644 --- a/js/engine.js +++ b/js/engine.js @@ -35,7 +35,7 @@ function playerOnGroundCheck(event) { //sets a hard land where player stays in a crouch for a bit and can't jump //crouch is forced in groundControl below const momentum = player.velocity.y * player.mass //player mass is 5 so this triggers at 26 down velocity, unless the player is holding something - if (momentum > 130) { + if (momentum > tech.hardLanding) { m.doCrouch(); m.yOff = m.yOffWhen.jump; m.hardLandCD = m.cycle + Math.min(momentum / 6.5 - 6, 40) diff --git a/js/index.js b/js/index.js index 82b7dae..aaa3cab 100644 --- a/js/index.js +++ b/js/index.js @@ -380,7 +380,7 @@ ${simulation.isCheating ? "

lore disabled": ""}
  ${build.nameLink(b.guns[b.inventory[i]].name)} - ${b.guns[b.inventory[i]].ammo}
${b.guns[b.inventory[i]].description} ` } - + text += `
${document.getElementById("text-log").innerHTML}
` //show last in game console message let el = document.getElementById("pause-grid-left") el.style.display = "grid" el.innerHTML = text @@ -441,6 +441,11 @@ ${simulation.isCheating ? "

lore disabled": ""} document.getElementById("field").style.display = "none" document.getElementById("health").style.display = "none" document.getElementById("health-bg").style.display = "none" + + //show in game console + // document.getElementById("text-log").style.display = "inline" + simulation.lastLogTime = m.cycle //hide in game console + }, unPauseGrid() { document.getElementById("tech").style.display = "inline" diff --git a/js/level.js b/js/level.js index 84db4b3..4686fc7 100644 --- a/js/level.js +++ b/js/level.js @@ -33,12 +33,12 @@ const level = { // b.giveGuns("laser") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser // b.giveGuns("wave") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser // b.guns[0].ammo = 10000 - // tech.giveTech("tungsten carbide") - // tech.giveTech("ship") + // tech.giveTech("aperture") + // tech.giveTech("diaphragm") // for (let i = 0; i < 1; ++i) tech.giveTech("mass-energy equivalence") - // for (let i = 0; i < 1; ++i) tech.giveTech("squirrel-cage rotor") + // for (let i = 0; i < 1; ++i) tech.giveTech("tungsten carbide") // for (let i = 0; i < 1; i++) tech.giveTech("CPT symmetry") - // for (let i = 0; i < 1; i++) tech.giveTech("Meissner effect") + // for (let i = 0; i < 1; i++) tech.giveTech("elasticity") // for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "boost"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling"); @@ -57,9 +57,13 @@ const level = { // for (let i = 0; i < 40; ++i) tech.giveTech() // for (let i = 0; i < 13; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research"); + //a for loop that produces Fibinochi numbers + + + level[simulation.isTraining ? "walk" : "intro"]() //normal starting level ************************************************ - // simulation.isAutoZoom = false; + // simulation.isAutoZoom = false; //look in close // simulation.zoomScale *= 0.5; // simulation.setZoom(); @@ -259,7 +263,7 @@ const level = { level.disableExit = true document.getElementById("health").style.display = "none" document.getElementById("health-bg").style.display = "none" - document.getElementById("text-log").style.opacity = 0; //fade out any active text logs + document.getElementById("text-log").style.display = "none" document.getElementById("fade-out").style.opacity = 1; //slowly fades out setTimeout(function() { simulation.paused = true; @@ -314,6 +318,7 @@ const level = { } if (simulation.isTraining) { + simulation.isHorizontalFlipped = false level.levels = level.trainingLevels.slice(0) //copy array, not by just by assignment } else { //add remove and shuffle levels for the normal game (not training levels) level.levels = level.playableLevels.slice(0) //copy array, not by just by assignment diff --git a/js/player.js b/js/player.js index 36e85dd..6ba2676 100644 --- a/js/player.js +++ b/js/player.js @@ -464,7 +464,7 @@ const m = { simulation.paused = true; m.health = 0; m.displayHealth(); - document.getElementById("text-log").style.opacity = 0; //fade out any active text logs + 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() { @@ -533,7 +533,7 @@ const m = { }, baseHealth: 1, setMaxHealth() { - m.maxHealth = m.baseHealth + tech.extraMaxHealth + 1.5 * tech.isFallingDamage + 4 * tech.isFlipFlop * tech.isFlipFlopOn * tech.isFlipFlopHealth //+ (m.fieldMode === 0 || m.fieldMode === 5) * 0.5 * m.coupling + m.maxHealth = m.baseHealth + tech.extraMaxHealth + 2 * tech.isFallingDamage + 4 * tech.isFlipFlop * tech.isFlipFlopOn * tech.isFlipFlopHealth //+ (m.fieldMode === 0 || m.fieldMode === 5) * 0.5 * m.coupling document.getElementById("health-bg").style.width = `${Math.floor(300 * m.maxHealth)}px` simulation.makeTextLog(`m.maxHealth = ${m.maxHealth.toFixed(2)}`) if (m.health > m.maxHealth) m.health = m.maxHealth; @@ -546,6 +546,8 @@ const m = { let dmg = 1 dmg *= m.fieldHarmReduction // if (!tech.isFlipFlopOn && tech.isFlipFlopHealth) dmg *= 0.5 + // 1.25 + Math.sin(m.cycle * 0.01) + if (tech.isDiaphragm) dmg *= 0.66 + 0.66 * Math.sin(m.cycle * 0.01); if (tech.isZeno) dmg *= 0.15 if (tech.isFieldHarmReduction) dmg *= 0.5 if (tech.isHarmMACHO) dmg *= 0.4 @@ -556,7 +558,7 @@ const m = { if (m.fieldMode === 0 || m.fieldMode === 3) dmg *= 0.73 ** m.coupling if (tech.isLowHealthDefense) dmg *= 1 - Math.max(0, 1 - m.health) * 0.8 if (tech.isHarmReduceNoKill && m.lastKillCycle + 300 < m.cycle) dmg *= 0.33 - if (tech.squirrelFx !== 1) dmg *= 1 + (tech.squirrelFx - 1) / 5 //cause more damage + if (tech.squirrelFx !== 1) dmg *= 1 - 3 * (tech.squirrelFx - 1) / 5 //cause more damage if (tech.isAddBlockMass && m.isHolding) dmg *= 0.15 if (tech.isSpeedHarm && player.speed > 0.1) dmg *= 1 - Math.min(player.speed * 0.0165, 0.66) if (tech.isHarmReduce && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.25 @@ -836,6 +838,9 @@ const m = { draw() {}, isAltSkin: false, resetSkin() { + m.yOffWhen.jump = 70 + m.yOffWhen.stand = 49 + m.yOffWhen.crouch = 22 m.isAltSkin = false m.color = { hue: 0, @@ -912,6 +917,94 @@ const m = { none() { m.isAltSkin = true }, + mech() { + m.isAltSkin = true + m.yOffWhen.stand = 52 + m.yOffWhen.jump = 72 + // m.yOffWhen.crouch = 22 + // m.color = { + // hue: 184, + // sat: 0, + // light: 55, + // } + // m.setFillColors(); + m.draw = function() { + m.walk_cycle += m.flipLegs * m.Vx; + ctx.save(); + ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20) + ctx.translate(m.pos.x, m.pos.y); + m.calcLeg(Math.PI, -1.25); + m.drawLeg("#606060"); + m.calcLeg(0, 0); + m.drawLeg("#444"); + ctx.rotate(m.angle); + ctx.beginPath(); + ctx.arc(0, 0, 30, 0, 2 * Math.PI); + ctx.fillStyle = m.bodyGradient + ctx.fill(); + ctx.arc(15, 0, 4, 0, 2 * Math.PI); + ctx.strokeStyle = "#333"; + ctx.lineWidth = 2; + ctx.stroke(); + ctx.restore(); + m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal + powerUps.boost.draw() + } + m.drawLeg = function(stroke) { + if (m.angle > -Math.PI / 2 && m.angle < Math.PI / 2) { + m.flipLegs = 1; + } else { + m.flipLegs = -1; + } + const hip = { x: m.hip.x - 5, y: m.hip.y + 5 } + const sub = Vector.sub(m.knee, hip) + const off = Vector.mult(Vector.rotate(Vector.normalise(sub), Math.PI / 2), 8) + const kneeBraceHigh = Vector.add(hip, off) + const kneeBraceLow = Vector.add(kneeBraceHigh, Vector.mult(sub, 0.9)) + const foot = { x: m.foot.x - 10, y: m.foot.y - 15 } + ctx.save(); + ctx.scale(m.flipLegs, 1); //leg lines + ctx.beginPath(); + ctx.moveTo(hip.x, hip.y); + ctx.lineTo(m.knee.x, m.knee.y); + ctx.lineTo(foot.x, foot.y); + //extra upper leg brace + ctx.moveTo(kneeBraceHigh.x, kneeBraceHigh.y); + ctx.lineTo(kneeBraceLow.x, kneeBraceLow.y); + ctx.lineTo(m.knee.x, m.knee.y); + + ctx.strokeStyle = stroke; + ctx.lineWidth = 3; + ctx.stroke(); + //foot + ctx.beginPath(); + ctx.moveTo(foot.x, foot.y); + ctx.quadraticCurveTo(m.foot.x - 30, m.foot.y + 12, m.foot.x + 13, m.foot.y + 3); + ctx.lineWidth = 1.5; + ctx.stroke(); + + //hip joint + ctx.beginPath(); + ctx.arc(m.hip.x, m.hip.y - 1, 11, 0, 2 * Math.PI); + //knee joint + ctx.moveTo(m.knee.x + 3, m.knee.y); + ctx.arc(m.knee.x, m.knee.y, 3, 0, 2 * Math.PI); + //knee brace + // ctx.moveTo(kneeBraceHigh.x + 4, kneeBraceHigh.y); + // ctx.arc(kneeBraceHigh.x, kneeBraceHigh.y, 4, 0, 2 * Math.PI); + ctx.moveTo(kneeBraceLow.x + 2.5, kneeBraceLow.y); + ctx.arc(kneeBraceLow.x, kneeBraceLow.y, 2.5, 0, 2 * Math.PI); + //foot joint + ctx.moveTo(foot.x + 2.5, foot.y); + ctx.arc(foot.x, foot.y, 2.5, 0, 2 * Math.PI); + ctx.fillStyle = m.fillColor; + ctx.fill(); + ctx.lineWidth = 1; + // ctx.strokeStyle = "#333" + ctx.stroke(); + ctx.restore(); + } + }, energy() { m.isAltSkin = true m.color = { @@ -1231,19 +1324,90 @@ const m = { ctx.fill(); ctx.strokeStyle = "#333"; ctx.lineWidth = 2; + ctx.arc(12, 0, 8 + 4 * Math.sin(m.cycle * 0.01), 0, 2 * Math.PI); //big eye ctx.stroke(); ctx.beginPath(); ctx.arc(12, 0, 8 + 4 * Math.sin(m.cycle * 0.01), 0, 2 * Math.PI); //big eye ctx.fillStyle = `hsl(${150+100*Math.sin(m.cycle * 0.01)},100%,50%)` ctx.fill(); - ctx.strokeStyle = "#333"; - ctx.lineWidth = 2; ctx.stroke(); ctx.restore(); m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal powerUps.boost.draw() } }, + dilate2() { + m.isAltSkin = true + m.draw = function() { + ctx.fillStyle = m.fillColor; + m.walk_cycle += m.flipLegs * m.Vx; + ctx.save(); + ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20) + ctx.translate(m.pos.x, m.pos.y); + m.calcLeg(Math.PI, -3); + m.drawLeg("#5f5f5f"); + m.calcLeg(0, 0); + m.drawLeg("#444"); + ctx.rotate(m.angle); + ctx.beginPath(); + ctx.arc(0, 0, 30, 0, 2 * Math.PI); + ctx.fillStyle = m.bodyGradient + ctx.fill(); + ctx.strokeStyle = "#444"; + ctx.lineWidth = 3 + 3 * Math.sin(m.cycle * 0.01 + Math.PI); + ctx.arc(12, 0, 6 + 3 * Math.sin(m.cycle * 0.01), 0, 2 * Math.PI); //big eye + ctx.stroke(); + ctx.beginPath(); + ctx.arc(12, 0, 6 + 3 * Math.sin(m.cycle * 0.01), 0, 2 * Math.PI); //big eye + ctx.fillStyle = `hsl(${150+100*Math.sin(m.cycle * 0.01)},100%,50%)` + ctx.fill(); + ctx.stroke(); + ctx.restore(); + m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal + powerUps.boost.draw() + } + m.drawLeg = function(stroke) { + // if (simulation.mouseInGame.x > m.pos.x) { + if (m.angle > -Math.PI / 2 && m.angle < Math.PI / 2) { + m.flipLegs = 1; + } else { + m.flipLegs = -1; + } + ctx.save(); + ctx.scale(m.flipLegs, 1); //leg lines + ctx.beginPath(); + ctx.moveTo(m.hip.x, m.hip.y); + ctx.lineTo(m.knee.x, m.knee.y); + ctx.lineTo(m.foot.x, m.foot.y); + ctx.strokeStyle = stroke; + ctx.lineWidth = 7; + ctx.stroke(); + + //toe lines + ctx.beginPath(); + ctx.moveTo(m.foot.x, m.foot.y); + ctx.lineTo(m.foot.x - 15, m.foot.y + 5); + ctx.moveTo(m.foot.x, m.foot.y); + ctx.lineTo(m.foot.x + 15, m.foot.y + 5); + ctx.lineWidth = 4; + ctx.stroke(); + + //hip joint + ctx.beginPath(); + ctx.arc(m.hip.x, m.hip.y, 11, 0, 2 * Math.PI); + //knee joint + ctx.moveTo(m.knee.x + 7, m.knee.y); + ctx.arc(m.knee.x, m.knee.y, 7, 0, 2 * Math.PI); + //foot joint + ctx.moveTo(m.foot.x + 6, m.foot.y); + ctx.arc(m.foot.x, m.foot.y, 6, 0, 2 * Math.PI); + ctx.fillStyle = m.fillColor; + ctx.fill(); + ctx.lineWidth = 3 + 3 * Math.sin(m.cycle * 0.01 + Math.PI); + ctx.stroke(); + ctx.restore(); + } + }, CPT() { m.isAltSkin = true m.color = { diff --git a/js/simulation.js b/js/simulation.js index 384db5b..513060b 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -379,17 +379,34 @@ const simulation = { } requestAnimationFrame(loop) }, - // lastLogTimeBig: 0, boldActiveGunHUD() { if (b.inventory.length > 0) { - for (let i = 0, len = b.inventory.length; i < len; ++i) document.getElementById(b.inventory[i]).style.opacity = "0.3"; - // document.getElementById(b.activeGun).style.fontSize = "30px"; - if (document.getElementById(b.activeGun)) document.getElementById(b.activeGun).style.opacity = "1"; + for (let i = 0, len = b.inventory.length; i < len; ++i) { + if (b.inventory[i] === b.activeGun && document.getElementById(b.activeGun)) { + document.getElementById(b.inventory[i]).style.opacity = "1"; + } else { + document.getElementById(b.inventory[i]).style.opacity = "0.3"; + } + } } + + // if (b.inventory.length > 0) { + // for (let i = 0, len = b.inventory.length; i < len; ++i) document.getElementById(b.inventory[i]).style.opacity = "0.3"; + // // document.getElementById(b.activeGun).style.fontSize = "30px"; + // if (document.getElementById(b.activeGun)) document.getElementById(b.activeGun).style.opacity = "1"; + // } }, updateGunHUD() { + // for (let i = 0, len = b.inventory.length; i < len; ++i) { + // if (flashIndex === i) { + // document.getElementById(b.inventory[i]).innerHTML = b.guns[b.inventory[i]].name + " - " + b.guns[b.inventory[i]].ammo; + // } else { + // document.getElementById(b.inventory[i]).innerHTML = b.guns[b.inventory[i]].name + " - " + b.guns[b.inventory[i]].ammo; + // } + // } for (let i = 0, len = b.inventory.length; i < len; ++i) { - document.getElementById(b.inventory[i]).innerHTML = b.guns[b.inventory[i]].name + " - " + b.guns[b.inventory[i]].ammo; + // document.getElementById(b.inventory[i]).innerHTML = b.guns[b.inventory[i]].name + " - " + b.guns[b.inventory[i]].ammo; + document.getElementById(b.inventory[i]).innerHTML = `${b.guns[b.inventory[i]].name} - ${b.guns[b.inventory[i]].ammo}` } }, makeGunHUD() { @@ -402,8 +419,8 @@ const simulation = { for (let i = 0, len = b.inventory.length; i < len; ++i) { const node = document.createElement("div"); node.setAttribute("id", b.inventory[i]); - let textnode = document.createTextNode(b.guns[b.inventory[i]].name + " - " + b.guns[b.inventory[i]].ammo); - node.appendChild(textnode); + const textNode = document.createTextNode(`${b.guns[b.inventory[i]].name} - ${b.guns[b.inventory[i]].ammo}`); //b.guns[b.inventory[i]].name + " - " + b.guns[b.inventory[i]].ammo); + node.appendChild(textNode); document.getElementById("guns").appendChild(node); } simulation.boldActiveGunHUD(); @@ -439,7 +456,7 @@ const simulation = { simulation.lastLogTime = m.cycle + time; } else { document.getElementById("text-log").innerHTML = text; - document.getElementById("text-log").style.opacity = 1; + document.getElementById("text-log").style.display = "inline"; simulation.lastLogTime = m.cycle + time; } } @@ -448,7 +465,7 @@ const simulation = { if (simulation.lastLogTime && simulation.lastLogTime < m.cycle) { simulation.lastLogTime = 0; // document.getElementById("text-log").innerHTML = " "; - document.getElementById("text-log").style.opacity = 0; + document.getElementById("text-log").style.display = "none"; } }, nextGun() { @@ -790,7 +807,7 @@ const simulation = { simulation.difficultyMode = Number(document.getElementById("difficulty-select").value) simulation.clearNow = true; - document.getElementById("text-log").style.opacity = 0; + 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"]`); diff --git a/js/spawn.js b/js/spawn.js index 56a0b71..0628c51 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -976,7 +976,7 @@ const spawn = { // m.displayHealth(); document.getElementById("health").style.display = "none" document.getElementById("health-bg").style.display = "none" - document.getElementById("text-log").style.opacity = 0; //fade out any active text logs + document.getElementById("text-log").style.display = "none" document.getElementById("fade-out").style.opacity = 1; //slowly fades out // build.shareURL(false) setTimeout(function() { @@ -2688,13 +2688,13 @@ const spawn = { mobs.spawn(x, y, 6, radius, "transparent"); let me = mob[mob.length - 1]; me.stroke = "transparent"; //used for drawSneaker - me.eventHorizon = radius * 27; //required for blackhole + me.eventHorizon = radius * 30; //required for blackhole 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.memory = Infinity; - Matter.Body.setDensity(me, 0.01); //extra dense //normal is 0.001 //makes effective life much larger + Matter.Body.setDensity(me, 0.015); //extra dense //normal is 0.001 //makes effective life much larger me.do = function() { //keep it slow, to stop issues from explosion knock backs if (this.speed > 5) { @@ -2825,7 +2825,7 @@ const spawn = { me.collisionFilter.mask = cat.player | cat.bullet //| cat.body // me.frictionAir = 0.005; me.memory = 1600; - Matter.Body.setDensity(me, 0.04); //extra dense //normal is 0.001 //makes effective life much larger + Matter.Body.setDensity(me, 0.06); //extra dense //normal is 0.001 //makes effective life much larger me.onDeath = function() { //applying forces to player doesn't seem to work inside this method, not sure why powerUps.spawnBossPowerUp(this.position.x, this.position.y) diff --git a/js/tech.js b/js/tech.js index d7cc875..942aeb1 100644 --- a/js/tech.js +++ b/js/tech.js @@ -299,6 +299,234 @@ const tech = { } }, tech: [{ + name: "tungsten carbide", + description: "+200 maximum health
lose health after hard landings", + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + isSkin: true, + allowed() { + return !m.isAltSkin + }, + requires: "not skin", + effect() { + tech.hardLanding = 40 + tech.isFallingDamage = true; + m.setMaxHealth(); + m.addHealth(1 / simulation.healScale) + m.skin.tungsten() + }, + remove() { + tech.hardLanding = 130 + tech.isFallingDamage = false; + m.setMaxHealth(); + m.resetSkin(); + } + }, + { + name: "elasticity", + description: "+33% movement and jumping
+15% defense", + maxCount: 3, + count: 0, + frequency: 1, + frequencyDefault: 1, + allowed() { + return !m.isAltSkin + }, + requires: "not skinned", + effect() { + m.skin.mech(); + tech.hardLanding = 80 + tech.squirrelFx += 0.4; + tech.squirrelJump += 0.16; + m.setMovement() + }, + remove() { + tech.hardLanding = 130 + tech.squirrelFx = 1; + tech.squirrelJump = 1; + m.setMovement() + m.resetSkin(); + } + }, + { + name: "aperture", + description: "your damage cycles every 6 seconds
between -75% and +125% damage", + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + isSkin: true, + allowed() { + return !m.isAltSkin + }, + requires: "not skinned", + effect() { + tech.isDilate = true + m.skin.dilate() + }, + remove() { + tech.isDilate = false + m.resetSkin(); + } + }, + { + name: "diaphragm", + description: "your defense cycles every 6 seconds
between +100% and -33% defense", + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + isSkin: true, + allowed() { + return tech.isDilate + }, + requires: "aperture", + effect() { + tech.isDiaphragm = true + m.resetSkin(); + m.skin.dilate2() + }, + remove() { + tech.isDiaphragm = false + m.resetSkin(); + } + }, + { + name: "mass-energy equivalence", + // description: "energy protects you instead of health
√ of defense reduction reduces max energy", + description: "energy protects you instead of health
exponentially reduced defense (~ x^0.12)", + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + isSkin: true, + allowed() { + return !m.isAltSkin && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isAnnihilation //&& !tech.isAmmoFromHealth && !tech.isRewindGun + }, + requires: "not piezoelectricity, CPT, annihilation", + effect() { + m.health = 0 + document.getElementById("health").style.display = "none" + document.getElementById("health-bg").style.display = "none" + document.getElementById("dmg").style.backgroundColor = "#0cf"; + tech.isEnergyHealth = true; + simulation.mobDmgColor = "rgba(0, 255, 255,0.6)" //"#0cf" + m.displayHealth(); + m.skin.energy(); + }, + remove() { + if (tech.isEnergyHealth) { + tech.isEnergyHealth = false; + document.getElementById("health").style.display = "inline" + document.getElementById("health-bg").style.display = "inline" + document.getElementById("dmg").style.backgroundColor = "#f67"; + m.health = Math.max(Math.min(m.maxHealth, m.energy), 0.1); + simulation.mobDmgColor = "rgba(255,0,0,0.7)" + m.displayHealth(); + } + tech.isEnergyHealth = false; + m.resetSkin(); + } + }, + { + name: "1st ionization energy", + link: `1st ionization energy`, + // description: `after you collect ${powerUps.orb.heal()}
+${0.1 * tech.largerHeals} maximum energy`, + // descriptionFunction: `convert current and future ${powerUps.orb.heal()} into

give +${10 * tech.largerHeals} maximum energy`, + descriptionFunction() { + return `convert current and future
into

give +${8 * tech.largerHeals * (tech.isHalfHeals ? 0.5 : 1)} maximum energy` + }, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return tech.isEnergyHealth + }, + requires: "mass-energy equivalence", + effect() { + powerUps.healGiveMaxEnergy = true; //tech.healMaxEnergyBonus given from heal power up + powerUps.heal.color = "#ff0" //"#0ae" + for (let i = 0; i < powerUp.length; i++) { //find active heal power ups and adjust color live + if (powerUp[i].name === "heal") powerUp[i].color = powerUps.heal.color + } + }, + remove() { + powerUps.healGiveMaxEnergy = false; + // tech.healMaxEnergyBonus = 0 + powerUps.heal.color = "#0eb" + for (let i = 0; i < powerUp.length; i++) { //find active heal power ups and adjust color live + if (powerUp[i].name === "heal") powerUp[i].color = powerUps.heal.color + } + } + }, + { + name: "CPT symmetry", + // description: "charge, parity, and time invert to undo defense
rewind (1.5—5) seconds for (66—220) energy", + // description: "after losing health, if you have full energy
rewind time for 44 energy per second", + descriptionFunction() { + return `after losing health, if you have ${(100*Math.min(100,m.maxEnergy)).toFixed(0)} energy
rewind time for 40 energy per second` + }, + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + isSkin: true, + allowed() { + return !m.isAltSkin && m.fieldUpgrades[m.fieldMode].name !== "standing wave" && !tech.isRewindField && !tech.isEnergyHealth + }, + requires: "not skinned, standing wave, max energy reduction, retrocausality, mass-energy", + effect() { + tech.isRewindAvoidDeath = true; + m.skin.CPT() + }, + remove() { + tech.isRewindAvoidDeath = false; + m.resetSkin(); + } + }, + { + name: "causality bots", + link: `causality bots`, + description: "when you rewind build scrap bots
that protect you for about 9 seconds", + maxCount: 3, + count: 0, + frequency: 2, + frequencyDefault: 2, + isBotTech: true, + allowed() { + return tech.isRewindAvoidDeath || tech.isRewindField + }, + requires: "CPT, retrocausality", + effect() { + tech.isRewindBot++; + }, + remove() { + tech.isRewindBot = 0; + } + }, + { + name: "causality bombs", + link: `causality bombs`, + description: "when you rewind drop several grenades
become invulnerable until they explode", + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return tech.isRewindAvoidDeath || tech.isRewindField + }, + requires: "CPT, retrocausality", + effect() { + tech.isRewindGrenade = true; + }, + remove() { + tech.isRewindGrenade = false; + } + }, + { name: "ordnance", description: "double the frequency of finding guntech
spawn a gun and +7% JUNK to tech pool", maxCount: 1, @@ -726,28 +954,7 @@ const tech = { } } }, - { - name: "squirrel-cage rotor", - description: "+30% movement and jumping
–5% defense", - maxCount: 9, - count: 0, - frequency: 1, - frequencyDefault: 1, - allowed() { - return this.count > 0 - }, - requires: "", - effect() { - tech.squirrelFx += 0.25; - tech.squirrelJump += 0.1; - m.setMovement() - }, - remove() { - tech.squirrelFx = 1; - tech.squirrelJump = 1; - m.setMovement() - } - }, + // { // name: "coyote", // description: "", @@ -1913,9 +2120,9 @@ const tech = { } } } - if (!m.isShipMode) { - m.skin.flipFlop() - } + // if (!m.isShipMode) { + // m.skin.flipFlop() + // } }, remove() { tech.isFlipFlop = false @@ -1929,7 +2136,7 @@ const tech = { } } m.eyeFillColor = 'transparent' - m.resetSkin(); + // m.resetSkin(); } }, { @@ -2067,9 +2274,9 @@ const tech = { } } } - if (!m.isShipMode) { - m.skin.flipFlop() - } + // if (!m.isShipMode) { + // m.skin.flipFlop() + // } }, remove() { tech.isRelay = false @@ -2083,7 +2290,7 @@ const tech = { } } m.eyeFillColor = 'transparent' - m.resetSkin(); + // m.resetSkin(); } }, { @@ -2294,70 +2501,7 @@ const tech = { tech.isSlowFPS = false; } }, - { - name: "CPT symmetry", - // description: "charge, parity, and time invert to undo defense
rewind (1.5—5) seconds for (66—220) energy", - // description: "after losing health, if you have full energy
rewind time for 44 energy per second", - descriptionFunction() { - return `after losing health, if you have ${(100*Math.min(100,m.maxEnergy)).toFixed(0)} energy
rewind time for 40 energy per second` - }, - maxCount: 1, - count: 0, - frequency: 1, - frequencyDefault: 1, - isSkin: true, - allowed() { - return !m.isAltSkin && m.fieldUpgrades[m.fieldMode].name !== "standing wave" && !tech.isRewindField && !tech.isEnergyHealth - }, - requires: "not skinned, standing wave, max energy reduction, retrocausality, mass-energy", - effect() { - tech.isRewindAvoidDeath = true; - m.skin.CPT() - }, - remove() { - tech.isRewindAvoidDeath = false; - m.resetSkin(); - } - }, - { - name: "causality bots", - link: `causality bots`, - description: "when you rewind build scrap bots
that protect you for about 9 seconds", - maxCount: 3, - count: 0, - frequency: 2, - frequencyDefault: 2, - isBotTech: true, - allowed() { - return tech.isRewindAvoidDeath || tech.isRewindField - }, - requires: "CPT, retrocausality", - effect() { - tech.isRewindBot++; - }, - remove() { - tech.isRewindBot = 0; - } - }, - { - name: "causality bombs", - link: `causality bombs`, - description: "when you rewind drop several grenades
become invulnerable until they explode", - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return tech.isRewindAvoidDeath || tech.isRewindField - }, - requires: "CPT, retrocausality", - effect() { - tech.isRewindGrenade = true; - }, - remove() { - tech.isRewindGrenade = false; - } - }, + { name: "piezoelectricity", description: "if you collide with a mob
generate +2048 energy", //
reduce defense by 15% @@ -2377,75 +2521,6 @@ const tech = { tech.isPiezo = false; } }, - { - name: "mass-energy equivalence", - // description: "energy protects you instead of health
√ of defense reduction reduces max energy", - description: "energy protects you instead of health
exponentially reduced defense (~ x^0.12)", - maxCount: 1, - count: 0, - frequency: 1, - frequencyDefault: 1, - isSkin: true, - allowed() { - return !m.isAltSkin && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isAnnihilation //&& !tech.isAmmoFromHealth && !tech.isRewindGun - }, - requires: "not piezoelectricity, CPT, annihilation", - effect() { - m.health = 0 - document.getElementById("health").style.display = "none" - document.getElementById("health-bg").style.display = "none" - document.getElementById("dmg").style.backgroundColor = "#0cf"; - tech.isEnergyHealth = true; - simulation.mobDmgColor = "rgba(0, 255, 255,0.6)" //"#0cf" - m.displayHealth(); - m.skin.energy(); - }, - remove() { - if (tech.isEnergyHealth) { - tech.isEnergyHealth = false; - document.getElementById("health").style.display = "inline" - document.getElementById("health-bg").style.display = "inline" - document.getElementById("dmg").style.backgroundColor = "#f67"; - m.health = Math.max(Math.min(m.maxHealth, m.energy), 0.1); - simulation.mobDmgColor = "rgba(255,0,0,0.7)" - m.displayHealth(); - } - tech.isEnergyHealth = false; - m.resetSkin(); - } - }, - { - name: "1st ionization energy", - link: `1st ionization energy`, - // description: `after you collect ${powerUps.orb.heal()}
+${0.1 * tech.largerHeals} maximum energy`, - // descriptionFunction: `convert current and future ${powerUps.orb.heal()} into

give +${10 * tech.largerHeals} maximum energy`, - descriptionFunction() { - return `convert current and future
into

give +${8 * tech.largerHeals * (tech.isHalfHeals ? 0.5 : 1)} maximum energy` - }, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return tech.isEnergyHealth - }, - requires: "mass-energy equivalence", - effect() { - powerUps.healGiveMaxEnergy = true; //tech.healMaxEnergyBonus given from heal power up - powerUps.heal.color = "#ff0" //"#0ae" - for (let i = 0; i < powerUp.length; i++) { //find active heal power ups and adjust color live - if (powerUp[i].name === "heal") powerUp[i].color = powerUps.heal.color - } - }, - remove() { - powerUps.healGiveMaxEnergy = false; - // tech.healMaxEnergyBonus = 0 - powerUps.heal.color = "#0eb" - for (let i = 0; i < powerUp.length; i++) { //find active heal power ups and adjust color live - if (powerUp[i].name === "heal") powerUp[i].color = powerUps.heal.color - } - } - }, { name: "electronegativity", descriptionFunction() { @@ -2860,30 +2935,7 @@ const tech = { tech.isAcidDmg = false; } }, - { - name: "tungsten carbide", - description: "+150 maximum health
lose health after hard landings", - maxCount: 1, - count: 0, - frequency: 1, - frequencyDefault: 1, - isSkin: true, - allowed() { - return !m.isAltSkin - }, - requires: "not skin", - effect() { - tech.isFallingDamage = true; - m.setMaxHealth(); - m.addHealth(1 / simulation.healScale) - m.skin.tungsten() - }, - remove() { - tech.isFallingDamage = false; - m.setMaxHealth(); - m.resetSkin(); - } - }, + { name: "adiabatic healing", descriptionFunction() { @@ -3510,27 +3562,6 @@ const tech = { } } }, - { - name: "aperture", - description: "your damage cycles every 6 seconds
between -75% and +125% damage", - maxCount: 1, - count: 0, - frequency: 1, - frequencyDefault: 1, - isSkin: true, - allowed() { - return !m.isAltSkin - }, - requires: "not skinned", - effect() { - tech.isDilate = true - m.skin.dilate() - }, - remove() { - tech.isDilate = false - m.resetSkin(); - } - }, { name: "exciton", descriptionFunction() { @@ -4781,7 +4812,7 @@ const tech = { }, { name: "Zectron", - description: `+80% super ball density and damage, but
after colliding with super balls lose health`, + description: `+100% super ball density and damage, but
after colliding with super balls lose health`, isGunTech: true, maxCount: 9, count: 0, @@ -11292,4 +11323,6 @@ const tech = { sentryAmmo: null, collidePowerUps: null, isDilate: null, + isDiaphragm: null, + hardLanding: null, } \ No newline at end of file diff --git a/style.css b/style.css index 7a6e97b..753d009 100644 --- a/style.css +++ b/style.css @@ -239,6 +239,11 @@ summary { -ms-overflow-style: none; /* IE and Edge */ scrollbar-width: none; /* Firefox */ } +.pause-console { + padding: 10px; + margin: 5px; + border-radius: 10px; +} #pause-grid-left::-webkit-scrollbar { display: none; @@ -623,12 +628,18 @@ summary { font-size: 1.15em; color: #555; background-color: rgba(255, 255, 255, 0.5); - transition: opacity 0.25s; + /* transition: opacity 0.15s; */ pointer-events: none; user-select: none; } /* color for in game console output */ +/* .ammo-flash { + color: #f33; + transition: color 2s; +} */ + + .color-text { color: #000; } diff --git a/todo.txt b/todo.txt index 38752c3..98145e5 100644 --- a/todo.txt +++ b/todo.txt @@ -1,26 +1,41 @@ ******************************************************** NEXT PATCH ************************************************** -some tech come with a skin - but only 1 at a time - tech aperture - skin, damage cycles between -25% and +125% - tungsten carbide - skin, +100->150 max health - mass-energy equivalence - skin, gets a bit more benefit from defense - CPT symmetry - skin, costs a bit less energy - flip-flop, and relay switch and a few JUNK tech are also skins +tech: elasticity - skin, does "crouch landings" a tiny bit more + jump and move faster, +15% defense + (replaces squirrel cage rotor) + +tech: diaphragm - skin, defense cycles between -33% and +100% + requires aperture + +tungsten carbide 150->200 maximum health + but now does "crouch landings" a more +Zectron damage 80->100% and it does a bit less harm to player +flip-flop, relay switch are no longer skins + +pause brings up the most recent in game console message + in game console no longer fades out it just instantly goes on and off -some new images bug fixes + *********************************************************** TODO ***************************************************** +Tech: Von Neuman probes - Drones will consume blocks to replicate themselves + it's a little too similar to the drone repair tech, but I kinda like it better. drones that eat blocks and spit out more drones is cool + +when gaining ammo have the ammo test quickly count up by Math.floor(1/20x) of the total ammo given + maybe bold, flash the text for a second after + +tech: parry - immune to harm for 0.25-0.5 seconds after pressing field button + needs a 5 second CD? + tech: if a needle hits 2 mobs reset your fire CD - and maybe to 2x damage for each consecutive mob hit? + maybe to 2x damage for each consecutive mob hit? + maybe after a needle hits a mob the needle splits into 3 needles tech for lens - you can only fire through the lens and some buff? damage or energy? this was in todo.txt on GitHub. I think it should be 'laser never drains energy, but you can only fire through lens and +90° lens arc, +100% damage (also you can not gain compound lens with this upgrade) -Tech: Von Neuman probes - Drones will consume blocks to replicate themselves - it's a little too similar to the drone repair tech, but I kinda like it better. drones that eat blocks and spit out more drones is cool - new boss level like reactor with a very very big boss mechanics around a very big boss? maybe the boss moves into rooms so you have to do platforming to clear the room before the boss enters the room