restitution

several new junk tech

unified field theory: now cycles fields after you click the field box when paused

tech: restitution - mobs killed by blocks spawn power ups
tech: inelastic collision - 60% harm reduction when holding a block
This commit is contained in:
landgreen
2021-02-09 05:46:43 -08:00
parent dc94bf871d
commit 045039171e
11 changed files with 201 additions and 75 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -3674,7 +3674,7 @@ const b = {
bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 20, 4.5, b.fireAttributes(dir, false)); bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 20, 4.5, b.fireAttributes(dir, false));
b.fireProps(m.crouch ? 45 : 25, m.crouch ? 30 : 16, dir, me); //cd , speed b.fireProps(m.crouch ? 45 : 25, m.crouch ? 30 : 16, dir, me); //cd , speed
Matter.Body.setDensity(bullet[me], 0.000001); Matter.Body.setDensity(bullet[me], 0.000001);
bullet[me].endCycle = Infinity; bullet[me].endCycle = simulation.cycle + 600;
bullet[me].frictionAir = 0; bullet[me].frictionAir = 0;
bullet[me].friction = 0.5; bullet[me].friction = 0.5;
bullet[me].radius = 4.5; bullet[me].radius = 4.5;

View File

@@ -169,6 +169,17 @@ function collisionChecks(event) {
let dmg = 0.05 * b.dmgScale * v * obj.mass * tech.throwChargeRate; let dmg = 0.05 * b.dmgScale * v * obj.mass * tech.throwChargeRate;
if (mob[k].isShielded) dmg *= 0.35 if (mob[k].isShielded) dmg *= 0.35
mob[k].damage(dmg, true); 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) const stunTime = dmg / Math.sqrt(obj.mass)
if (stunTime > 0.5) mobs.statusStun(mob[k], 30 + 60 * Math.sqrt(stunTime)) if (stunTime > 0.5) mobs.statusStun(mob[k], 30 + 60 * Math.sqrt(stunTime))
if (mob[k].distanceToPlayer2() < 1000000 && !m.isCloak) mob[k].foundPlayer(); if (mob[k].distanceToPlayer2() < 1000000 && !m.isCloak) mob[k].foundPlayer();

View File

@@ -214,7 +214,7 @@ const build = {
el.style.display = "grid" el.style.display = "grid"
el.innerHTML = text el.innerHTML = text
text = ""; text = "";
text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[m.fieldMode].name}</div> ${m.fieldUpgrades[m.fieldMode].description}</div>` text += `<div class="pause-grid-module" id ="pause-field"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[m.fieldMode].name}</div> ${m.fieldUpgrades[m.fieldMode].description}</div>`
let countTech = 0 let countTech = 0
for (let i = 0, len = tech.tech.length; i < len; i++) { for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count > 0) { if (tech.tech[i].count > 0) {
@@ -729,6 +729,24 @@ window.addEventListener("keydown", function(event) {
simulation.paused = true; simulation.paused = true;
build.pauseGrid() build.pauseGrid()
document.body.style.cursor = "auto"; document.body.style.cursor = "auto";
if (tech.isGunSwitchField || simulation.testing) {
document.getElementById("pause-field").addEventListener("click", () => {
const energy = m.energy
m.setField((m.fieldMode === m.fieldUpgrades.length - 1) ? 1 : m.fieldMode + 1) //cycle to next field
m.energy = energy
document.getElementById("pause-field").innerHTML = `<div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${m.fieldUpgrades[m.fieldMode].name}</div> ${m.fieldUpgrades[m.fieldMode].description}`
});
}
if (simulation.testing) {
}
} }
} }
break break
@@ -876,7 +894,6 @@ window.addEventListener("keydown", function(event) {
} }
break break
case "u": case "u":
simulation.clearTimeouts();
level.nextLevel(); level.nextLevel();
break break
} }

View File

@@ -20,7 +20,8 @@ const level = {
// tech.isExplodeRadio = true // tech.isExplodeRadio = true
// for (let i = 0; i < 1; i++) tech.giveTech("dynamo-bot") // for (let i = 0; i < 1; i++) tech.giveTech("dynamo-bot")
// tech.giveTech("supercritical fission") // tech.giveTech("supercritical fission")
// tech.giveTech("irradiated nails") // tech.giveTech("CPT reversal")
// tech.giveTech("causality bombs")
// tech.giveTech("cardinality") // tech.giveTech("cardinality")
// tech.giveTech("Bayesian statistics") // tech.giveTech("Bayesian statistics")
// tech.isExplodeRadio = true; // tech.isExplodeRadio = true;
@@ -30,6 +31,7 @@ const level = {
// tech.giveTech("missile-bot") // tech.giveTech("missile-bot")
// tech.giveTech("nail-bot") // tech.giveTech("nail-bot")
// for (let i = 0; i < 15; i++) tech.giveTech("plasma jet") // for (let i = 0; i < 15; i++) tech.giveTech("plasma jet")
// tech.isBlockPowerUps = true;
level.intro(); //starting level level.intro(); //starting level
// level.testing(); //not in rotation // level.testing(); //not in rotation
@@ -1052,7 +1054,8 @@ const level = {
// spawn.boost(1500, 0, 900); // spawn.boost(1500, 0, 900);
// spawn.starter(1900, -500, 200) //big boy // spawn.starter(1900, -500, 200) //big boy
spawn.historyBoss(1900, -500) spawn.starter(1900, -500)
// spawn.historyBoss(1900, -500)
// spawn.sneaker(2900, -500) // spawn.sneaker(2900, -500)
// spawn.launcherBoss(1200, -500) // spawn.launcherBoss(1200, -500)
// spawn.laserTargetingBoss(1600, -400) // spawn.laserTargetingBoss(1600, -400)

View File

@@ -1038,9 +1038,7 @@ const mobs = {
m.lastKillCycle = m.cycle; //tracks the last time a kill was made, mostly used in simulation.checks() m.lastKillCycle = m.cycle; //tracks the last time a kill was made, mostly used in simulation.checks()
if (Math.random() < tech.sporesOnDeath) { if (Math.random() < tech.sporesOnDeath) {
const len = Math.min(25, Math.floor(2 + this.mass * (0.5 + 0.5 * Math.random()))) const len = Math.min(25, Math.floor(2 + this.mass * (0.5 + 0.5 * Math.random())))
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) b.spore(this.position)
b.spore(this.position)
}
} else if (tech.isExplodeMob) { } else if (tech.isExplodeMob) {
b.explosion(this.position, Math.min(600, Math.sqrt(this.mass + 2.75) * 55)) b.explosion(this.position, Math.min(600, Math.sqrt(this.mass + 2.75) * 55))
} else if (tech.nailsDeathMob) { } else if (tech.nailsDeathMob) {

View File

@@ -497,6 +497,7 @@ const m = {
harmReduction() { harmReduction() {
let dmg = 1 let dmg = 1
dmg *= m.fieldHarmReduction dmg *= m.fieldHarmReduction
if (tech.isBlockHarm && m.isHolding) dmg *= 0.4
if (tech.squirrelFx !== 1) dmg *= 1 + (tech.squirrelFx - 1) / 5 //cause more damage if (tech.squirrelFx !== 1) dmg *= 1 + (tech.squirrelFx - 1) / 5 //cause more damage
if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0185, 0.55) if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0185, 0.55)
if (tech.isSlowFPS) dmg *= 0.8 if (tech.isSlowFPS) dmg *= 0.8
@@ -606,13 +607,14 @@ const m = {
m.defaultFPSCycle = m.cycle m.defaultFPSCycle = m.cycle
if (tech.isRewindBot) { if (tech.isRewindBot) {
const len = steps * 0.052 * tech.isRewindBot const len = steps * 0.052 * tech.isRewindBot
const botStep = Math.floor(steps / len)
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
const where = m.history[Math.abs(m.cycle - i * 40) % 600].position //spread out spawn locations along past history const where = m.history[Math.abs(m.cycle - i * botStep) % 600].position //spread out spawn locations along past history
b.randomBot({ b.randomBot({
x: where.x + 100 * (Math.random() - 0.5), x: where.x + 20 * (Math.random() - 0.5),
y: where.y + 100 * (Math.random() - 0.5) y: where.y + 20 * (Math.random() - 0.5)
}, false, false) }, false, false)
bullet[bullet.length - 1].endCycle = simulation.cycle + 360 + Math.floor(180 * Math.random()) //6-9 seconds bullet[bullet.length - 1].endCycle = simulation.cycle + 480 + Math.floor(120 * Math.random()) //8-10 seconds
} }
} }
}, },

View File

@@ -358,21 +358,6 @@ const simulation = {
} }
}, },
switchGun() { switchGun() {
if (tech.isGunSwitchField) {
// const energy = m.energy
// m.energy = energy //field swap sets energy to max, this undoes that
m.setField((m.fieldMode === m.fieldUpgrades.length - 1) ? 1 : m.fieldMode + 1) //cycle to next field
//update text to show next field
for (let i = tech.tech.length - 1; i > 0; i--) {
if (tech.tech[i].name === "unified field theory") {
const index = (m.fieldMode === m.fieldUpgrades.length - 1) ? 1 : m.fieldMode + 1
tech.tech[i].description = `switching <strong class='color-g'>guns</strong> also cycles your <strong class='color-f'>field</strong>
<br>(next <strong class='color-f'>field</strong>: ${m.fieldUpgrades[index].name})`
break
}
}
}
if (tech.isCrouchAmmo) tech.isCrouchAmmo = 1 //this prevents hacking the tech by switching guns if (tech.isCrouchAmmo) tech.isCrouchAmmo = 1 //this prevents hacking the tech by switching guns
b.activeGun = b.inventory[b.inventoryGun]; b.activeGun = b.inventory[b.inventoryGun];
simulation.updateGunHUD(); simulation.updateGunHUD();

View File

@@ -99,8 +99,6 @@ const spawn = {
// spawn.shield(me, x, y, 1); // spawn.shield(me, x, y, 1);
me.onDeath = function() { me.onDeath = function() {
//add lore level as next level if player took lore tech earlier in the game //add lore level as next level if player took lore tech earlier in the game
simulation.makeTextLog(`simulation.end()`);
if (lore.techCount > 9 && !simulation.isCheating) { if (lore.techCount > 9 && !simulation.isCheating) {
level.levels.push("null") level.levels.push("null")
level.exit.x = 5500; level.exit.x = 5500;
@@ -113,18 +111,21 @@ const spawn = {
simulation.draw.setPaths(); //redraw map draw path simulation.draw.setPaths(); //redraw map draw path
} else { } else {
//reset game //reset game
let delay = 1000 setTimeout(() => {
for (let i = 20; i > 0; i--) { simulation.makeTextLog(`simulation.end()`);
setTimeout(function() { let delay = 1000
simulation.makeTextLog(`delay = ${i*1000}`); for (let i = 20; i > 0; i--) {
}, delay); setTimeout(function() {
simulation.makeTextLog(`delay = ${i*1000}`);
}, delay);
delay += 1000
}
delay += 1000 delay += 1000
} setTimeout(() => {
delay += 1000 simulation.makeTextLog(`World.clear(engine.world)`);
setTimeout(function() { setTimeout(() => { m.death() }, 1000);
simulation.makeTextLog(`World.clear(engine.world)`); }, delay);
setTimeout(function() { m.death() }, 1000); }, 5000);
}, delay);
} }
//ramp up damage //ramp up damage
for (let i = 0; i < 3; i++) level.difficultyIncrease(simulation.difficultyMode) for (let i = 0; i < 3; i++) level.difficultyIncrease(simulation.difficultyMode)

View File

@@ -19,6 +19,14 @@ const tech = {
tech.tech[index].count = 0; tech.tech[index].count = 0;
simulation.updateTechHUD(); simulation.updateTechHUD();
}, },
// onclick="tech.removeTechPaused(${i}, this)" //add this to tech elements in pause menu
// removeTechPaused(index, who) {
// tech.tech[index].remove();
// tech.tech[index].count = 0;
// simulation.updateTechHUD();
// who.innerHTML = "removed"
// // who.style.display = "none"
// },
removeLoreTechFromPool() { removeLoreTechFromPool() {
for (let i = tech.tech.length - 1; i > 0; i--) { for (let i = tech.tech.length - 1; i > 0; i--) {
if (tech.tech[i].isLore && tech.tech[i].count === 0) tech.tech.splice(i, 1) if (tech.tech[i].isLore && tech.tech[i].count === 0) tech.tech.splice(i, 1)
@@ -1089,6 +1097,38 @@ const tech = {
tech.throwChargeRate = 1 tech.throwChargeRate = 1
} }
}, },
{
name: "restitution",
description: "mobs killed by collisions with <strong>blocks</strong><br>spawn a <strong class='color-h'>heal</strong>, <strong class='color-g'>ammo</strong>, or <strong class='color-r'>research</strong>",
maxCount: 1,
count: 0,
allowed() {
return tech.throwChargeRate > 1
},
requires: "mass driver",
effect() {
tech.isBlockPowerUps = true
},
remove() {
tech.isBlockPowerUps = false
}
},
{
name: "inelastic collision",
description: "while you are <strong>holding</strong> a <strong>block</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>60%</strong>",
maxCount: 1,
count: 0,
allowed() {
return tech.throwChargeRate > 1
},
requires: "mass driver",
effect() {
tech.isBlockHarm = true
},
remove() {
tech.isBlockHarm = false
}
},
{ {
name: "perpetual stun", name: "perpetual stun",
description: "<strong>stun</strong> all mobs for up to <strong>12</strong> seconds<br>at the start of each <strong>level</strong>", description: "<strong>stun</strong> all mobs for up to <strong>12</strong> seconds<br>at the start of each <strong>level</strong>",
@@ -1255,7 +1295,7 @@ const tech = {
}, },
{ {
name: "causality bots", name: "causality bots",
description: "when you <strong class='color-rewind'>rewind</strong>, build some <strong>bots</strong><br>that protect you for about <strong>7</strong> seconds", description: "when you <strong class='color-rewind'>rewind</strong>, build several <strong>bots</strong><br>that protect you for about <strong>9</strong> seconds",
maxCount: 3, maxCount: 3,
count: 0, count: 0,
allowed() { allowed() {
@@ -1271,7 +1311,7 @@ const tech = {
}, },
{ {
name: "causality bombs", name: "causality bombs",
description: "before you <strong class='color-rewind'>rewind</strong> drop some <strong>grenades</strong>", description: "before you <strong class='color-rewind'>rewind</strong> drop several <strong>grenades</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
@@ -1782,7 +1822,7 @@ const tech = {
}, },
{ {
name: "replication", name: "replication",
description: "<strong>8%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>add <strong>10</strong> junk <strong class='color-m'>tech</strong> to the potential pool", description: "<strong>7.5%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>add <strong>16</strong> junk <strong class='color-m'>tech</strong> to the potential pool",
maxCount: 9, maxCount: 9,
count: 0, count: 0,
allowed() { allowed() {
@@ -1790,9 +1830,9 @@ const tech = {
}, },
requires: "below 100% duplication chance", requires: "below 100% duplication chance",
effect() { effect() {
tech.duplicateChance += 0.08 tech.duplicateChance += 0.075
simulation.draw.powerUp = simulation.draw.powerUpBonus //change power up draw simulation.draw.powerUp = simulation.draw.powerUpBonus //change power up draw
tech.addJunkTechToPool(10) tech.addJunkTechToPool(16)
}, },
remove() { remove() {
tech.duplicateChance = 0 tech.duplicateChance = 0
@@ -1965,7 +2005,7 @@ const tech = {
}, },
{ {
name: "unified field theory", name: "unified field theory",
description: "", description: `in the pause menu, change your <strong class='color-f'>field</strong><br>by <strong>clicking</strong> on your <strong class='color-f'>field's</strong> box`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
@@ -1974,25 +2014,9 @@ const tech = {
requires: "at least 2 guns, not superdeterminism", requires: "at least 2 guns, not superdeterminism",
effect() { effect() {
tech.isGunSwitchField = true; tech.isGunSwitchField = true;
for (let i = tech.tech.length - 1; i > 0; i--) {
if (tech.tech[i].name === "unified field theory") {
const index = (m.fieldMode === m.fieldUpgrades.length - 1) ? 1 : m.fieldMode + 1
tech.tech[i].description = `switching <strong class='color-g'>guns</strong> also cycles your <strong class='color-f'>field</strong>
<br>(next <strong class='color-f'>field</strong>: ${m.fieldUpgrades[index].name})`
break
}
}
}, },
remove() { remove() {
tech.isGunSwitchField = false; tech.isGunSwitchField = false;
for (let i = tech.tech.length - 1; i > 0; i--) {
if (tech.tech[i].name === "unified field theory") {
const index = (m.fieldMode === m.fieldUpgrades.length - 1) ? 1 : m.fieldMode + 1
tech.tech[i].description = `switching <strong class='color-g'>guns</strong> also cycles your <strong class='color-f'>field</strong>
<br>(next <strong class='color-f'>field</strong>: ${m.fieldUpgrades[index].name})`
break
}
}
} }
}, },
{ {
@@ -3155,7 +3179,7 @@ const tech = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
return tech.haveGunCheck("foam") || tech.foamBotCount > 2 return tech.haveGunCheck("foam")
}, },
requires: "foam", requires: "foam",
effect() { effect() {
@@ -4197,6 +4221,81 @@ const tech = {
// }, // },
// remove() {} // remove() {}
// }, // },
{
name: "pitch",
description: "oscillate the pitch of your world",
maxCount: 9,
count: 0,
numberInPool: 0,
isNonRefundable: true,
isCustomHide: true,
isJunk: true,
allowed() {
return true
},
requires: "",
effect() {
setInterval(() => { if (!simulation.paused) ctx.rotate(0.001 * Math.sin(simulation.cycle * 0.01)) }, 16);
},
remove() {}
},
{
name: "umbra",
description: "produce a blue glow around everything<br>and probably some simulation lag",
maxCount: 9,
count: 0,
numberInPool: 0,
isNonRefundable: true,
isCustomHide: true,
isJunk: true,
allowed() {
return true
},
requires: "",
effect() {
ctx.shadowColor = '#06f';
ctx.shadowBlur = 25;
},
remove() {}
},
{
name: "lighter",
description: `ctx.globalCompositeOperation = "lighter"`,
maxCount: 9,
count: 0,
numberInPool: 0,
isNonRefundable: true,
isCustomHide: true,
isJunk: true,
allowed() {
return m.fieldUpgrades[m.fieldMode].name !== "negative mass field"
},
requires: "",
effect() {
ctx.globalCompositeOperation = "lighter";
},
remove() {}
},
{
name: "rewind",
description: "every 5 seconds <strong class='color-rewind'>rewind</strong> <strong>2</strong> seconds<br>lasts 120 seconds",
maxCount: 9,
count: 0,
numberInPool: 0,
isNonRefundable: true,
isCustomHide: true,
isJunk: true,
allowed() {
return true
},
requires: "",
effect() {
for (let i = 0; i < 24; i++) {
setTimeout(() => { m.rewind(120) }, i * 5000);
}
},
remove() {}
},
{ {
name: "energy to mass conversion", name: "energy to mass conversion",
description: "convert your <strong class='color-f'>energy</strong> into blocks", description: "convert your <strong class='color-f'>energy</strong> into blocks",
@@ -4229,7 +4328,7 @@ const tech = {
}, },
{ {
name: "level.nextLevel()", name: "level.nextLevel()",
description: "teleport to the start of the next level", description: "advance to the next level",
maxCount: 9, maxCount: 9,
count: 0, count: 0,
numberInPool: 0, numberInPool: 0,
@@ -4241,7 +4340,6 @@ const tech = {
}, },
requires: "", requires: "",
effect() { effect() {
simulation.clearTimeouts();
level.nextLevel(); level.nextLevel();
}, },
remove() {} remove() {}
@@ -4941,4 +5039,6 @@ const tech = {
isNeedleShieldPierce: null, isNeedleShieldPierce: null,
isDuplicateBoss: null, isDuplicateBoss: null,
isDynamoBotUpgrade: null, isDynamoBotUpgrade: null,
isBlockPowerUps: null,
isBlockHarm: null
} }

View File

@@ -1,10 +1,10 @@
******************************************************** NEXT PATCH ******************************************************** ******************************************************** NEXT PATCH ********************************************************
several new junk tech
tech change: commodities exchange 6 -> 8 power ups on cancel unified field theory: now cycles fields after you click the field box when paused
tech change: MIRV - doesn't reduce the missile size as much, has a better missile spread, and a very short fire delay
tech: replication - gain 8% duplication, but add in 10 junk tech to the pool tech: restitution - mobs killed by blocks spawn power ups
added several new junk tech (18 possible junk tech now) tech: inelastic collision - 60% harm reduction when holding a block
******************************************************** BUGS ******************************************************** ******************************************************** BUGS ********************************************************
@@ -34,6 +34,21 @@ use the floor of portal sensor on the player? to unstuck player
******************************************************** TODO ******************************************************** ******************************************************** TODO ********************************************************
holding a block gives some defense
can still block?
just make the block more transparent so it's clear you can't block
When you beat the boss without lore the output thing should read simulation complete, processing results, terminating simulation
shutdown progress: 0%
And count up by ten to 100% before you die, so that players know they won and don't think theyre stuck or something, and so its not surprising when you die
Additionally, a stats screen would be nice. Like when you die, and it fades to white, output reads simulation result: failure (or success if you beat the boss)
Then reads some stats like kills, tech picked up, research picked up, damage dealt/taken, etc
tech fire gun in the future tech fire gun in the future
laser doesn't work because of draw, needs to be a bullet laser doesn't work because of draw, needs to be a bullet
foam? shotgun? foam? shotgun?
@@ -44,12 +59,6 @@ tech fire gun in the future
setTimeout(() => { setTimeout(() => {
}, 1000); }, 1000);
historyBoss needs legs?
unified field theory is too weak
fill energy make immune to damage on swap?
tech: when you switch guns switch a random bot to a different bot. If the bot you had was upgraded the new one will be too. tech: when you switch guns switch a random bot to a different bot. If the bot you had was upgraded the new one will be too.
or switch all bots or switch all bots