jump off mobs

you can now jump off mobs while invulnerable
  includes time dilated
pause display text updated with details menus
difficulty parameters
  0.82->0.84x damage done per level
  1.25->1.23x damage taken per level
tungsten carbide 300->400 health, but 0.08->0.02 seconds of coyote time and longer crouch time
nitinol 0.08->0.17 seconds of coyote time and much less crouching on hard landings, but 0.8->1 damage taken
mass-energy equivalence no longer costs 2 research
long power up spawns, like from interest or supply chain:
  will pause new spawns until total power ups are below 300 to reduce lag
  stop spawning if you take damage

bug fixes
This commit is contained in:
landgreen
2024-06-08 13:49:13 -07:00
parent 63bfaba4a1
commit eabd146ea5
10 changed files with 234 additions and 221 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

@@ -35,10 +35,10 @@ 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 > tech.hardLanding) {
if (momentum > m.hardLanding) {
m.doCrouch();
m.yOff = m.yOffWhen.jump;
m.hardLandCD = m.cycle + Math.min(momentum / 6.5 - 6, 40)
m.hardLandCD = m.cycle + m.hardLandCDScale * Math.min(momentum / 6.5 - 6, 40)
//falling damage
if (tech.isFallingDamage && m.immuneCycle < m.cycle && momentum > 150) {
m.damage(Math.min(Math.sqrt(momentum - 133) * 0.01, 0.25));
@@ -56,10 +56,10 @@ function playerOnGroundCheck(event) {
let pair = pairs[i];
if (pair.bodyA === jumpSensor) {
m.standingOn = pair.bodyB; //keeping track to correctly provide recoil on jump
if (m.standingOn.alive !== true) enter();
if (m.standingOn.alive !== true || m.immuneCycle > m.cycle) enter();
} else if (pair.bodyB === jumpSensor) {
m.standingOn = pair.bodyA; //keeping track to correctly provide recoil on jump
if (m.standingOn.alive !== true) enter();
if (m.standingOn.alive !== true || m.immuneCycle > m.cycle) enter();
}
}
m.numTouching = 0;

View File

@@ -462,58 +462,64 @@ const build = {
if (tech.plasmaBotCount) botText += `<br>plasma-bots: ${tech.plasmaBotCount}`
if (tech.missileBotCount) botText += `<br>missile-bots: ${tech.missileBotCount}`
let text = `<div class="pause-grid-module" style = "padding: 10px; line-height: 110%;">
<span style = "font-size: 0.87em;">
<span style="font-size:1.5em;font-weight: 600; float: left;">PAUSED</span>
let text = `<div class="pause-grid-module" style="padding: 8px;">
<span style="font-size:1.4em;font-weight: 600; float: left;">PAUSED</span>
<span style="float: right;">press ${input.key.pause} to resume</span>
<br>
<br>
<button onclick="build.shareURL(false)" class='sort-button' style="font-size:1em;float: right;">copy build url</button>
<input onclick="build.showImages('pause')" type="checkbox" id="hide-images-pause" name="hide-images-pause" ${localSettings.isHideImages ? "checked" : ""}>
<label for="hide-images-pause" title="hide images for fields, guns, and tech" style="font-size:1.15em;" >hide images</label>
<br>
<button onclick="build.shareURL(false)" class='sort-button' style="font-size:1em;float: right;">copy build url</button>
<input onclick="build.hideHUD('settings')" type="checkbox" id="hide-hud" name="hide-hud" ${localSettings.isHideHUD ? "checked" : ""}>
<label for="hide-hud" title="hide: tech, damage taken, damage, in game console" style="font-size:1.15em;">minimal HUD</label>
<br>
</div>
<details> <summary>difficulty</summary>
<div style="display: ${simulation.difficultyMode === 1 ? "block" : "none"};"><strong>+6</strong> initial <strong>power ups</strong><br><strong>5%</strong> chance for mobs to a drop <strong class='color-m'>tech</strong></div>
<div style="display: ${simulation.difficultyMode > 1 ? "block" : "none"};"><strong>10%</strong> chance for <strong>shielded</strong> mobs<br><strong>0.5x</strong> <strong class='color-h'>heal</strong> power ups</div>
<div style="display: ${simulation.difficultyMode > 2 ? "block" : "none"};"><strong>1.5x</strong> mob movement and reactions<br><strong>0.5x</strong> <strong class='color-d'>damage</strong></div>
<div style="display: ${simulation.difficultyMode > 3 ? "block" : "none"};"><strong>+1</strong> boss per level, <strong>-1</strong> <strong class='color-m'>tech</strong> per boss<br><strong>2x</strong> <strong class='color-defense'>damage taken</strong></div>
<div style="display: ${simulation.difficultyMode > 4 ? "block" : "none"};"><strong>-3</strong> initial power ups<br><strong>0.5x</strong> <strong class='color-d'>damage</strong></div>
<div style="display: ${simulation.difficultyMode > 5 ? "block" : "none"};"><strong>10%</strong> chance for <strong>shielded</strong> mobs<br><strong>2x</strong> <strong class='color-defense'>damage taken</strong></div>
</details>
<br><strong class='color-d'>damage</strong>: ${((tech.damageFromTech())).toPrecision(4)}x <span style="float: right;"><strong class='color-d'>difficulty:</strong> ${((m.dmgScale)).toPrecision(4)}x</span>
<div class="pause-grid-module">
<details id = "simulation-variables-details" style="padding: 0 8px;line-height: 140%;">
<summary>simulation variables</summary>
<div class="pause-details">
<strong class='color-d'>damage</strong>: ${((tech.damageFromTech())).toPrecision(4)}x <span style="float: right;"><strong class='color-d'>difficulty:</strong> ${((m.dmgScale)).toPrecision(4)}x</span>
<br><strong class='color-defense'>damage taken</strong>: ${(m.defense()).toPrecision(4)}x <span style="float: right;"><strong class='color-defense'>difficulty:</strong> ${(simulation.dmgScale).toPrecision(4)}x</span>
<br><strong><em>fire rate</em></strong>: ${(1 / b.fireCDscale).toFixed(2)}x
${tech.duplicationChance() ? `<br><strong class='color-dup'>duplication</strong>: ${(tech.duplicationChance() * 100).toFixed(0)}%` : ""}
${m.coupling ? `<br><span style = 'font-size:90%;'>` + m.couplingDescription(m.coupling) + `</span> from ${(m.coupling).toFixed(0)} ${powerUps.orb.coupling(1)}` : ""}
${botText}
<br>
<br><strong class='color-h'>health</strong>: (${(m.health * 100).toFixed(0)} / ${(m.maxHealth * 100).toFixed(0)})
<span style="float: right;">mass: ${player.mass.toFixed(1)}</span>
<br><strong class='color-f'>energy</strong>: (${(m.energy * 100).toFixed(0)} / ${(m.maxEnergy * 100).toFixed(0)}) + (${(m.fieldRegen * 6000).toFixed(0)}/s)
<span style="float: right;">position: (${player.position.x.toFixed(1)}, ${player.position.y.toFixed(1)})</span>
<span style="float: right;">position: (${player.position.x.toFixed(0)}, ${player.position.y.toFixed(0)})</span>
<br><strong class='color-g'>gun</strong>: ${b.activeGun === null || b.activeGun === undefined ? "undefined" : b.guns[b.activeGun].name} &nbsp; <strong class='color-g'>ammo</strong>: ${b.activeGun === null || b.activeGun === undefined ? "0" : b.guns[b.activeGun].ammo}
<span style="float: right;">mouse: (${simulation.mouseInGame.x.toFixed(1)}, ${simulation.mouseInGame.y.toFixed(1)})</span>
<span style="float: right;">mouse: (${simulation.mouseInGame.x.toFixed(0)}, ${simulation.mouseInGame.y.toFixed(0)})</span>
<br><strong class='color-m'>tech</strong>: ${tech.totalCount} &nbsp; <strong class='color-r'>research</strong>: ${powerUps.research.count}
<span style="float: right;">velocity: (${player.velocity.x.toFixed(3)}, ${player.velocity.y.toFixed(3)})</span>
<span style="float: right;">velocity: (${player.velocity.x.toFixed(2)}, ${player.velocity.y.toFixed(2)})</span>
${tech.junkChance ? `<br><strong class='color-junk'>JUNK</strong>: ${(100 * tech.junkChance).toFixed(1)}% ` : ""}
<br>
<br>mobs: ${spawn.pickList[0]}, ${spawn.pickList[0]}
<br>seed: ${Math.initialSeed} &nbsp; ${m.cycle} cycles
<br>mobs: ${mob.length} &nbsp; blocks: ${body.length} &nbsp; bullets: ${bullet.length} &nbsp; power ups: ${powerUp.length} ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}</span></div>`;
// deaths: ${mobs.mobDeaths} &nbsp;
// if (tech.isPauseSwitchField && !simulation.isChoosing) {
// const style = localSettings.isHideImages ? `style="height:auto;"` : `style="background-image: url('img/field/${m.fieldUpgrades[m.fieldMode].name}${m.fieldMode === 0 ? m.fieldUpgrades[0].imageNumber : ""}.webp');"`
// text += `<div class="pause-grid-module card-background" id="pause-field" ${style} >
// <div class="card-text" style="animation: fieldColorCycle 1s linear infinite alternate;">
// <div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)}</div>
// ${m.fieldUpgrades[m.fieldMode].description}</div> </div>`
<br>mobs: ${mob.length} &nbsp; blocks: ${body.length} &nbsp; bullets: ${bullet.length} &nbsp; power ups: ${powerUp.length} ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
</div>
</details>
</div>`
text += `<div class="pause-grid-module card-background" style="height:auto;">
<details id="difficulty-parameters-details" style="padding: 0 8px;">
<summary>difficulty parameters</summary>
<div class="pause-details">
${simulation.difficultyMode > 0 ? `<div class="pause-difficulty-row"><strong>0.84x</strong> <strong class='color-d'>damage</strong> done per level<br><strong>1.23x</strong> <strong class='color-defense'>damage taken</strong> per level</div>` : " "}
${simulation.difficultyMode > 1 ? `<div class="pause-difficulty-row"><strong>-5</strong> initial <strong>power ups</strong><br><strong>faster</strong> and <strong>more</strong> mobs per level</div>` : " "}
${simulation.difficultyMode > 2 ? `<div class="pause-difficulty-row"><strong>0.84x</strong> <strong class='color-d'>damage</strong> done per level<br><strong>1.23x</strong> <strong class='color-defense'>damage taken</strong> per level</div>` : " "}
${simulation.difficultyMode > 3 ? `<div class="pause-difficulty-row"><strong>+1</strong> boss per level, <strong>-1</strong> <strong class='color-m'>tech</strong> per boss<br><strong>-1</strong> ${powerUps.orb.research()} per level</div>` : " "}
${simulation.difficultyMode > 4 ? `<div class="pause-difficulty-row"><strong>0.84x</strong> <strong class='color-d'>damage</strong> done per level<br><strong>1.23x</strong> <strong class='color-defense'>damage taken</strong> per level</div>` : " "}
${simulation.difficultyMode > 5 ? `<div class="pause-difficulty-row"><strong>3x</strong> chance for <strong>shielded</strong> mobs<br><strong>-3</strong> initial power ups</div>` : " "}
</div>
</details>
</div>`
if (!localSettings.isHideHUD) text += `<div class="pause-grid-module card-background" style="height:auto;">
<details id = "console-log-details" style="padding: 0 8px;">
<summary>console messages</summary>
<div class="pause-details">
<div class="pause-grid-module" style="background-color: rgba(255,255,255,0.3);font-size: 0.8em;">${document.getElementById("text-log").innerHTML}</div>
</div>
</details>
</div>`
if ((tech.isPauseSwitchField || simulation.testing)) { //&& !simulation.isChoosing
// const fieldNameP = m.fieldUpgrades[m.fieldMode > 1 ? m.fieldMode - 1 : m.fieldUpgrades.length - 1].name
// const fieldNameN = m.fieldUpgrades[m.fieldMode === m.fieldUpgrades.length - 2 ? 1 : m.fieldMode + 1].name
@@ -548,10 +554,16 @@ const build = {
<div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${build.nameLink(b.guns[b.inventory[i]].name)} - <span style="font-size:100%;font-weight: 100;">${b.guns[b.inventory[i]].ammo}</span></div>
${b.guns[b.inventory[i]].descriptionFunction()}</div> </div>`
}
if (!localSettings.isHideHUD) text += `<div class="pause-grid-module pause-console" style="background-color: rgba(255,255,255,0.3);">${document.getElementById("text-log").innerHTML}</div>` //show last in game console message
let el = document.getElementById("pause-grid-left")
el.style.display = "grid"
el.innerHTML = text
requestAnimationFrame(() => {
if (localSettings.isAllowed) {
document.getElementById("simulation-variables-details").open = localSettings.pauseMenuDetailsOpen[0]
document.getElementById("difficulty-parameters-details").open = localSettings.pauseMenuDetailsOpen[1]
document.getElementById("console-log-details").open = localSettings.pauseMenuDetailsOpen[2]
}
});
},
generatePauseRight() {
let text = `<div class="sort">
@@ -561,7 +573,7 @@ const build = {
<button onclick="build.sortTech('heal')" class='sort-button'><strong class='color-h'>heal</strong></button>
<button onclick="build.sortTech('damage taken')" class='sort-button'><strong style="letter-spacing: 1px;font-weight: 100;">damage taken</strong></button>
<button onclick="build.sortTech('energy')" class='sort-button'><strong class='color-f'>energy</strong></button>
<input type="search" id="sort-input" style="width: 8em;font-size: 0.6em;color:#000;" placeholder="sort by" />
<input type="search" id="sort-input" style="width: 5em;font-size: 0.6em;color:#000;" placeholder="sort by" />
<button onclick="build.sortTech('input')" class='sort-button' style="border-radius: 0em;border: 1.5px #000 solid;font-size: 0.6em;" value="damage">sort</button>
</div>`;
const ejectClass = (tech.isPauseEjectTech && !simulation.isChoosing) ? 'pause-eject' : ''
@@ -710,6 +722,14 @@ const build = {
simulation.updateTechHUD();
},
unPauseGrid() {
if (localSettings.isAllowed) {
//save details open/close state
if (document.getElementById("simulation-variables-details")) localSettings.pauseMenuDetailsOpen[0] = document.getElementById("simulation-variables-details").open
if (document.getElementById("difficulty-parameters-details")) localSettings.pauseMenuDetailsOpen[1] = document.getElementById("difficulty-parameters-details").open
if (document.getElementById("console-log-details")) localSettings.pauseMenuDetailsOpen[2] = document.getElementById("console-log-details").open
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
}
document.getElementById("guns").style.display = "inline"
document.getElementById("field").style.display = "inline"
if (tech.isEnergyHealth) {
@@ -1802,6 +1822,11 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
if (localSettings.difficultyMode === undefined) localSettings.difficultyMode = "2"
simulation.difficultyMode = localSettings.difficultyMode
lore.setTechGoal()
if (localSettings.pauseMenuDetailsOpen === undefined) {
localSettings.pauseMenuDetailsOpen = [true, false, false]
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
}
} else {
console.log('setting default localSettings')
const isAllowed = localSettings.isAllowed //don't overwrite isAllowed value
@@ -1823,6 +1848,7 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
key: undefined,
isHideImages: true, //default to hide images
isHideHUD: false,
pauseMenuDetailsOpen: [true, false, false]
};
input.setDefault()
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage

View File

@@ -26,7 +26,7 @@ const level = {
// tech.tech[297].frequency = 100
// tech.addJunkTechToPool(0.5)
// m.couplingChange(10)
// m.setField("plasma torch") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook
// m.setField("molecular assembler") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook
// m.energy = 0
// powerUps.research.count = 3
// tech.isHookWire = true
@@ -45,19 +45,19 @@ const level = {
// 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("modified Newtonian dynamics")
// for (let i = 0; i < 1; ++i) tech.giveTech("Newtons 1st law")
// for (let i = 0; i < 1; ++i) tech.giveTech("entropic gravity")
// 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")
// 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")
// m.lastKillCycle = m.cycle
// for (let i = 0; i < 1; ++i) tech.giveTech("plasma-bot")
// for (let i = 0; i < 1; ++i) tech.giveTech("compression engine")
// for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech");
// 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.testing();
// level.yingYang();
// for (let i = 0; i < 1; ++i) spawn.laserLayer(1400, -500)
// Matter.Body.setPosition(player, { x: -200, y: -3330 });
@@ -21353,8 +21353,8 @@ const level = {
},
choose(index) {
if (index == 1) {
tech.squirrelFx += 0.25;
tech.squirrelJump += 0.1;
m.squirrelFx += 0.25;
m.squirrelJump += 0.1;
m.setMovement();
powerUps.endDraft("buff");
} else if (index == 2) {
@@ -30504,6 +30504,7 @@ const level = {
level.enter.draw();
};
level.customTopLayer = () => { };
},
unchartedCave() {
simulation.makeTextLog(`<strong>unchartedCave</strong> by <span class='color-var'>3xionDev</span>`);
@@ -30914,6 +30915,7 @@ const level = {
level.enter.draw();
};
level.customTopLayer = () => { };
},
dojo() { // By weird_pusheen
simulation.makeTextLog(`<strong>dojo</strong> by <span class='color-var'>werid_pusheen</span>, fixed by <span class='color-var'>Cornbread 2100</span>`)

View File

@@ -83,16 +83,20 @@ const m = {
Fx: 0.016, //run Force on ground //
jumpForce: 0.42,
setMovement() {
// m.Fx = 0.08 / mass * tech.squirrelFx
// console.log(player.mass)
// m.FxAir = 0.4 / mass / mass
m.Fx = tech.baseFx * m.fieldFx * tech.squirrelFx * (tech.isFastTime ? 1.5 : 1) / player.mass //base player mass is 5
m.jumpForce = tech.baseJumpForce * m.fieldJump * tech.squirrelJump * (tech.isFastTime ? 1.13 : 1) / player.mass / player.mass //base player mass is 5
m.Fx = tech.baseFx * m.fieldFx * m.squirrelFx * (tech.isFastTime ? 1.5 : 1) / player.mass //base player mass is 5
m.jumpForce = tech.baseJumpForce * m.fieldJump * m.squirrelJump * (tech.isFastTime ? 1.13 : 1) / player.mass / player.mass //base player mass is 5
},
FxAir: 0.016, // 0.4/5/5 run Force in Air
yOff: 70,
yOffGoal: 70,
onGround: false, //checks if on ground or in air
lastOnGroundCycle: 0, //use to calculate coyote time
coyoteCycles: 5,
hardLanding: 130,
squirrelFx: 1,
squirrelJump: 1,
standingOn: undefined,
numTouching: 0,
crouch: false,
@@ -210,10 +214,7 @@ const m = {
m.crouch = true;
m.yOffGoal = m.yOffWhen.crouch;
if ((playerHead.position.y - player.position.y) < 0) {
Matter.Body.setPosition(playerHead, {
x: player.position.x,
y: player.position.y + 9.1740767
})
Matter.Body.setPosition(playerHead, { x: player.position.x, y: player.position.y + 9.1740767 })
}
}
},
@@ -222,14 +223,12 @@ const m = {
m.crouch = false;
m.yOffGoal = m.yOffWhen.stand;
if ((playerHead.position.y - player.position.y) > 0) {
Matter.Body.setPosition(playerHead, {
x: player.position.x,
y: player.position.y - 30.28592321
})
Matter.Body.setPosition(playerHead, { x: player.position.x, y: player.position.y - 30.28592321 })
}
}
},
hardLandCD: 0,
hardLandCDScale: 1,
checkHeadClear() {
if (Matter.Query.collides(headSensor, map).length > 0) {
return false
@@ -239,7 +238,6 @@ const m = {
},
buttonCD_jump: 0, //cool down for player buttons
jump() {
// if (!m.onGround) m.lastOnGroundCycle = 0 //m.cycle - tech.coyoteTime
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, {
@@ -260,7 +258,7 @@ const m = {
if (!(input.down) && m.checkHeadClear() && m.hardLandCD < m.cycle) m.undoCrouch();
} else if (input.down || m.hardLandCD > m.cycle) {
m.doCrouch(); //on ground && not crouched and pressing s or down
} else if (input.up && m.buttonCD_jump + 20 < m.cycle && m.yOffWhen.stand > 23) {
} else if (input.up && m.buttonCD_jump + 20 < m.cycle) {
m.jump()
}
const moveX = player.velocity.x - m.moverX //account for mover platforms
@@ -290,8 +288,7 @@ const m = {
},
airControl() {
//check for coyote time jump
// if (input.up && m.buttonCD_jump + 20 + tech.coyoteTime < m.cycle && m.yOffWhen.stand > 23 && m.lastOnGroundCycle + tech.coyoteTime > m.cycle) m.jump()
if (input.up && m.buttonCD_jump + 20 < m.cycle && m.yOffWhen.stand > 23 && m.lastOnGroundCycle + 5 > m.cycle) m.jump()
if (input.up && m.buttonCD_jump + 20 < m.cycle && m.lastOnGroundCycle + m.coyoteCycles > m.cycle) m.jump()
//check for short jumps //moving up //recently pressed jump //but not pressing jump key now
if (m.buttonCD_jump + 60 > m.cycle && !(input.up) && m.Vy < 0) {
@@ -545,7 +542,7 @@ const m = {
},
baseHealth: 1,
setMaxHealth(isMessage) {
m.maxHealth = m.baseHealth + tech.extraMaxHealth + 3 * tech.isFallingDamage
m.maxHealth = m.baseHealth + tech.extraMaxHealth + 4 * tech.isFallingDamage
document.getElementById("health-bg").style.width = `${Math.floor(300 * m.maxHealth)}px`
if (isMessage) simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-h'>maxHealth</span> <span class='color-symbol'>=</span> ${m.maxHealth.toFixed(2)}`)
if (m.health > m.maxHealth) m.health = m.maxHealth;
@@ -565,7 +562,6 @@ const m = {
if (m.fieldMode === 0 || m.fieldMode === 3) dmg *= 0.973 ** 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.3
if (tech.squirrelFx !== 1) dmg *= 0.8//Math.pow(0.78, (tech.squirrelFx - 1) / 0.4)
if (tech.isAddBlockMass && m.isHolding) dmg *= 0.1
if (tech.isSpeedHarm && (tech.speedAdded + player.speed) > 0.1) dmg *= 1 - Math.min((tech.speedAdded + player.speed) * 0.0193, 0.8) //capped at speed of 55
if (tech.isHarmReduce && input.field) dmg *= 0.1
@@ -841,10 +837,17 @@ const m = {
isAltSkin: false,
resetSkin() {
simulation.isAutoZoom = true;
m.hardLandCDScale = 1
m.yOffWhen.jump = 70
m.yOffWhen.stand = 49
m.yOffWhen.crouch = 22
m.isAltSkin = false
m.coyoteCycles = 5
m.hardLanding = 130
m.squirrelFx = 1;
m.squirrelJump = 1;
requestAnimationFrame(() => { m.setMovement() })
m.color = {
hue: 0,
sat: 0,
@@ -966,6 +969,15 @@ const m = {
m.isAltSkin = true
m.yOffWhen.stand = 52
m.yOffWhen.jump = 72
m.coyoteCycles = 11
m.hardLandCDScale = 0.5
m.hardLanding = 160
m.squirrelFx = 1.4;
m.squirrelJump = 1.16;
m.setMovement()
// m.yOffWhen.jump = 70
// m.yOffWhen.stand = 49
// m.yOffWhen.crouch = 22
// m.color = {
// hue: 184,
@@ -992,7 +1004,7 @@ const m = {
ctx.lineWidth = 2;
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
m.yOff = m.yOff * 0.75 + m.yOffGoal * 0.25; //smoothly move leg height towards height goal
powerUps.boost.draw()
}
m.drawLeg = function (stroke) {
@@ -1325,6 +1337,9 @@ const m = {
}
},
tungsten() {
m.hardLandCDScale = 2
m.hardLanding = 60
m.coyoteCycles = 0
m.isAltSkin = true
m.color = {
hue: 210,
@@ -1384,7 +1399,7 @@ const m = {
ctx.fill();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
m.yOff = m.yOff * 0.9 + m.yOffGoal * 0.1; //smoothly move leg height towards height goal
powerUps.boost.draw()
}
m.drawLeg = function (stroke) {
@@ -1923,6 +1938,7 @@ const m = {
},
cat() {
m.isAltSkin = true
m.coyoteCycles = 10
m.draw = function () {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
@@ -2275,8 +2291,6 @@ const m = {
Matter.Body.setMass(player, mass);
//reduce air and ground move forces
m.setMovement()
// m.Fx = 0.08 / mass * tech.squirrelFx //base player mass is 5
// m.FxAir = 0.4 / mass / mass //base player mass is 5
//make player stand a bit lower when holding heavy masses
m.yOffWhen.stand = Math.max(m.yOffWhen.crouch, Math.min(49, 49 - (mass - 5) * 6))
if (m.onGround && !m.crouch) m.yOffGoal = m.yOffWhen.stand;
@@ -3478,6 +3492,7 @@ const m = {
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`
},
doubleJumpPhase: 0,
effect: () => {
m.fieldMeterColor = "#ff0"
m.eyeFillColor = m.fieldMeterColor
@@ -3588,6 +3603,21 @@ const m = {
m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
}
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
}
}
}
}
},
@@ -4060,7 +4090,7 @@ const m = {
m.setMovement();
b.setFireCD()
const timeStop = () => {
m.immuneCycle = m.cycle + 10; //immune to harm while time is stopped, this also disables regen
m.immuneCycle = m.cycle + 10; //invulnerable to harm while time is stopped, this also disables regen
//draw field everywhere
ctx.globalCompositeOperation = "saturation"
ctx.fillStyle = "#ccc";
@@ -5371,8 +5401,8 @@ const m = {
y: drag * player.velocity.y
});
if (input.up) { //forward thrust
player.force.x += thrust * Math.cos(m.angle) * tech.squirrelJump
player.force.y += thrust * Math.sin(m.angle) * tech.squirrelJump
player.force.x += thrust * Math.cos(m.angle) * m.squirrelJump
player.force.y += thrust * Math.sin(m.angle) * m.squirrelJump
} else if (input.down) {
player.force.x -= 0.6 * thrust * Math.cos(m.angle)
player.force.y -= 0.6 * thrust * Math.sin(m.angle)

View File

@@ -314,10 +314,7 @@ const powerUps = {
ctx.fillStyle = `rgba(150,150,150,0.9)`; //`rgba(221,221,221,0.6)`;
ctx.fillRect(0, 0, canvas.width, canvas.height);
});
// document.getElementById("pause-grid-right").style.opacity = "0.7"
// document.getElementById("pause-grid-left").style.opacity = "0.7"
}
// build.pauseGrid()
},
endDraft(type, isCanceled = false) { //type should be a gun, tech, or field
if (isCanceled) {
@@ -413,7 +410,7 @@ const powerUps = {
let text = `<div>
<div class="grid-container">
<div class="left-column">
<input type="range" id="difficulty-slider" name="temp" type="range" step="1" value="1" min="1" max="6" list="values" />
<input type="range" id="difficulty-slider" name="temp" type="range" step="1" value="1" min="1" max="6" list="values" dir="ltr"/>
<datalist id="values">
<option value="1"></option>
<option value="2"></option>
@@ -424,18 +421,12 @@ const powerUps = {
</datalist>
</div>
<div class="right-column">
<div class="row" id="constraint-1"><strong>0.82x</strong> <strong class='color-d'>damage</strong> done per level
<br><strong>1.25x</strong> <strong class='color-defense'>damage taken</strong> per level</div>
<div class="row" id="constraint-2"><strong>-5</strong> initial <strong>power ups</strong>
<br><strong>faster</strong> and <strong>more</strong> mobs per level</div>
<div class="row" id="constraint-3"><strong>0.82x</strong> <strong class='color-d'>damage</strong> done per level
<br><strong>1.25x</strong> <strong class='color-defense'>damage taken</strong> per level</div>
<div class="row" id="constraint-4"><strong>+1</strong> boss per level, <strong>-1</strong> <strong class='color-m'>tech</strong> per boss
<br><strong>-1</strong> ${powerUps.orb.research()} per level</div>
<div class="row" id="constraint-5"><strong>0.82x</strong> <strong class='color-d'>damage</strong> done per level
<br><strong>1.25x</strong> <strong class='color-defense'>damage taken</strong> per level</div>
<div class="row" id="constraint-6"><strong>3x</strong> chance for <strong>shielded</strong> mobs
<br><strong>-3</strong> initial power ups</div>
<div class="row" id="constraint-1"><strong>0.84x</strong> <strong class='color-d'>damage</strong> done per level<br><strong>1.23x</strong> <strong class='color-defense'>damage taken</strong> per level</div>
<div class="row" id="constraint-2"><strong>-5</strong> initial <strong>power ups</strong><br><strong>faster</strong> and <strong>more</strong> mobs per level</div>
<div class="row" id="constraint-3"><strong>0.84x</strong> <strong class='color-d'>damage</strong> done per level<br><strong>1.23x</strong> <strong class='color-defense'>damage taken</strong> per level</div>
<div class="row" id="constraint-4"><strong>+1</strong> boss per level, <strong>-1</strong> <strong class='color-m'>tech</strong> per boss<br><strong>-1</strong> ${powerUps.orb.research()} per level</div>
<div class="row" id="constraint-5"><strong>0.84x</strong> <strong class='color-d'>damage</strong> done per level<br><strong>1.23x</strong> <strong class='color-defense'>damage taken</strong> per level</div>
<div class="row" id="constraint-6"><strong>3x</strong> chance for <strong>shielded</strong> mobs<br><strong>-3</strong> initial power ups</div>
</div>
<div class="far-right-column">
<div id = "constraint-1-record">${localSettings.difficultyCompleted[1] ? "⚆" : " "}</div>
@@ -1446,18 +1437,16 @@ const powerUps = {
},
},
spawnDelay(type, count, delay = 2) {
const lastHarmCycle = m.lastHarmCycle //stop releasing power ups if you take damage
count *= delay
// let totalSpawned = 0
let cycle = () => {
if (count > 0) {
if (m.alive) requestAnimationFrame(cycle);
if (!simulation.paused && !simulation.isChoosing) { //&& !(simulation.cycle % 2)
if (m.alive && lastHarmCycle === m.lastHarmCycle) requestAnimationFrame(cycle);
if (!simulation.paused && !simulation.isChoosing && powerUp.length < 300) { //&& !(simulation.cycle % 2)
count--
if (!(count % delay)) {
const where = { x: m.pos.x + 50 * (Math.random() - 0.5), y: m.pos.y + 50 * (Math.random() - 0.5) }
powerUps.spawn(where.x, where.y, type);
// totalSpawned++
// if (!(totalSpawned % 10)) delay++
}
}
}

View File

@@ -5915,7 +5915,6 @@ const spawn = {
me.memory = 900;
me.delay = 60
me.cd = 0;
spawn.shield(me, x, y, 1); // bad for stealth
me.onHit = function () {
if (this.cd < simulation.cycle) {
this.cd = simulation.cycle + this.delay;

View File

@@ -281,7 +281,7 @@ const tech = {
},
tech: [{
name: "tungsten carbide",
description: "<strong>+300</strong> maximum <strong class='color-h'>health</strong><br><strong>lose</strong> <strong class='color-h'>health</strong> after hard <strong>landings</strong>",
description: "<strong>+400</strong> maximum <strong class='color-h'>health</strong><br><strong>lose</strong> <strong class='color-h'>health</strong> after hard <strong>landings</strong>",
maxCount: 1,
count: 0,
frequency: 1,
@@ -292,14 +292,12 @@ const tech = {
},
requires: "not skin",
effect() {
tech.hardLanding = 70
tech.isFallingDamage = true;
m.setMaxHealth();
m.addHealth(3 / simulation.healScale)
m.skin.tungsten()
},
remove() {
tech.hardLanding = 130
tech.isFallingDamage = false;
m.setMaxHealth();
if (this.count) m.resetSkin();
@@ -307,7 +305,7 @@ const tech = {
},
{
name: "nitinol",
description: "<strong>1.3x</strong> <strong>movement</strong> and <strong>jumping</strong><br><strong>0.8x</strong> <strong class='color-defense'>damage taken</strong>",
description: "<strong>1.3x</strong> <strong>movement</strong> and <strong>jumping</strong><br><strong>0.17</strong> seconds of <strong>coyote time</strong>",
maxCount: 1,
count: 0,
frequency: 1,
@@ -319,16 +317,9 @@ const tech = {
requires: "not skinned",
effect() {
m.skin.mech();
tech.hardLanding = 110
tech.squirrelFx += 0.4;
tech.squirrelJump += 0.16;
m.setMovement()
},
remove() {
tech.hardLanding = 130
tech.squirrelFx = 1;
tech.squirrelJump = 1;
m.setMovement()
if (this.count) m.resetSkin();
}
},
@@ -431,14 +422,14 @@ const tech = {
},
{
name: "mass-energy equivalence",
description: `use ${powerUps.orb.research(2)}<br><strong class='color-f'>energy</strong> protects you instead of <strong class='color-h'>health</strong>`,
description: `<strong class='color-f'>energy</strong> protects you instead of <strong class='color-h'>health</strong>`,
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
isSkin: true,
allowed() {
return (powerUps.research.count > 1 || build.isExperimentSelection) && !m.isAltSkin && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isAnnihilation //&& !tech.isAmmoFromHealth && !tech.isRewindGun
return !m.isAltSkin && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isAnnihilation //&& !tech.isAmmoFromHealth && !tech.isRewindGun
},
requires: "not piezoelectricity, CPT, annihilation",
effect() {
@@ -451,13 +442,9 @@ const tech = {
m.displayHealth();
m.lastCalculatedDefense = 0 //this triggers a redraw of the defense bar
m.skin.energy();
for (let i = 0; i < 2; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
},
remove() {
if (this.count > 0) {
powerUps.research.changeRerolls(2)
tech.isEnergyHealth = false;
document.getElementById("health").style.display = "inline"
document.getElementById("health-bg").style.display = "inline"
@@ -840,7 +827,7 @@ const tech = {
{
name: "supply chain",
descriptionFunction() {
return `spawn a <strong class='color-g'>gun</strong><br>spawn ${powerUps.orb.ammo(1)} equal to current <strong class='color-ammo'>ammo</strong>`
return `spawn a <strong class='color-g'>gun</strong><br>spawn ${powerUps.orb.ammo(1)} equal to all your active <strong class='color-g'>gun's</strong> <strong class='color-ammo'>ammo</strong>`
},
maxCount: 9,
count: 0,
@@ -852,36 +839,14 @@ const tech = {
},
requires: "",
effect() {
//count ammo
let ammoCount = 0
for (let i = 0; i < b.guns.length; i++) {
if (b.guns[i].have && b.guns[i].ammo !== Infinity) ammoCount += b.guns[i].ammo / b.guns[i].ammoPack
let ammoCount = 0 //count ammo
if (b.activeGun && b.activeGun !== undefined && b.guns[b.activeGun].have && b.guns[b.activeGun].ammo !== Infinity) {
ammoCount += b.guns[b.activeGun].ammo / b.guns[b.activeGun].ammoPack
}
powerUps.spawnDelay("ammo", Math.ceil(ammoCount))
powerUps.spawn(m.pos.x, m.pos.y, "gun");
// powerUps.spawnDelay("coupling", m.coupling * 2)
// for (let i = 0; i < b.guns.length; i++) {
// if (b.guns[i].have) b.guns[i].ammo = Math.floor(2 * b.guns[i].ammo)
// }
// simulation.makeGunHUD();
// for (let i = 0, len = tech.tech.length; i < len; i++) {
// if (tech.tech[i].name === "applied science") tech.tech[i].frequency *= 4
// }
},
remove() {
// if (this.count) {
// m.couplingChange(-this.count * 10)
// for (let j = 0; j < this.count; j++) {
// for (let i = 0; i < b.guns.length; i++) {
// if (b.guns[i].have) b.guns[i].ammo = Math.floor(0.5 * b.guns[i].ammo)
// }
// }
// simulation.makeGunHUD();
// for (let i = 0, len = tech.tech.length; i < len; i++) {
// if (tech.tech[i].name === "applied science") tech.tech[i].frequency = 2
// }
// }
}
remove() { }
},
{
name: "marginal utility",
@@ -1082,35 +1047,6 @@ const tech = {
tech.restDamage = 1;
}
},
// {
// name: "coyote",
// description: "",
// maxCount: 1,
// count: 0,
// frequency: 1,
// frequencyDefault: 1,
// allowed() { return true },
// requires: "",
// effect() { // good with melee builds, content skipping builds
// tech.coyoteTime = 120
// // simulation.gravity = function() {
// // function addGravity(bodies, magnitude) {
// // for (var i = 0; i < bodies.length; i++) {
// // bodies[i].force.y += bodies[i].mass * magnitude;
// // }
// // }
// // if (!m.isBodiesAsleep) {
// // addGravity(powerUp, simulation.g);
// // addGravity(body, simulation.g);
// // }
// // player.force.y += player.mass * simulation.g
// // }
// },
// remove() {
// tech.coyoteTime = 5
// }
// },
{
name: "Newtons 1st law",
descriptionFunction() {
@@ -3756,6 +3692,7 @@ const tech = {
count: 0,
frequency: 1,
frequencyDefault: 1,
isBadRandomOption: true,
allowed() {
return true
},
@@ -7964,6 +7901,26 @@ 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>",
@@ -10981,9 +10938,9 @@ const tech = {
isInstant: true,
isJunk: true,
allowed() {
return level.levelsCleared < 6
return (level.levelsCleared < 5)
},
requires: "before level 6",
requires: "before level 5",
effect() {
powerUps.spawn(m.pos.x, m.pos.y, "difficulty");
},
@@ -11559,7 +11516,6 @@ const tech = {
isAcidDmg: null,
isAnnihilation: null,
largerHeals: null,
squirrelFx: null,
isCrit: null,
isLowHealthDmg: null,
isLowHealthDefense: null,
@@ -11623,7 +11579,6 @@ const tech = {
isNailShot: null,
slowFire: null,
fastTime: null,
squirrelJump: null,
isFastRadiation: null,
isAmmoForGun: null,
isRapidPulse: null,
@@ -11825,13 +11780,10 @@ const tech = {
isTimeCrystals: null,
isGroundState: null,
isRailGun: null,
// isGrapple: null,
// isImmuneGrapple: null,
isDronesTravel: null,
isTechDebt: null,
isPlasmaBall: null,
plasmaDischarge: null,
coyoteTime: null,
missileFireCD: null,
isBotField: null,
isFoamBall: null,
@@ -11871,7 +11823,6 @@ const tech = {
collidePowerUps: null,
isDilate: null,
isDiaphragm: null,
hardLanding: null,
isNoGroundDamage: null,
isSuperBounce: null,
isDivisor: null,
@@ -11897,4 +11848,5 @@ const tech = {
interestRate: null,
isImmunityDamage: null,
isMobDeathImmunity: null,
isDoubleJump: null,
}

View File

@@ -282,11 +282,15 @@ summary {
/* Firefox */
}
.pause-console {
padding: 10px;
margin: 5px;
border-radius: 10px;
}
/* .pause-console { */
/* padding: 10px; */
/* margin: 10px; */
/* border-radius: 10px; */
/* line-height: 140%; */
/* font-size: 1em; */
/* padding: 10px; */
/* margin: -5px 0; */
/* } */
#pause-grid-left::-webkit-scrollbar {
display: none;
@@ -1544,6 +1548,7 @@ summary {
height: 26.3rem;
width: 2rem;
writing-mode: vertical-lr;
direction: ltr;
}
.left-column {
@@ -1564,6 +1569,13 @@ summary {
padding: 10px;
}
.pause-difficulty-row {
line-height: 140%;
font-size: 1em;
padding: 10px;
margin: -5px 0;
}
#constraint-1 {
background-color: hsl(240, 18%, 95%);
border-radius: 7px 7px 0 0;
@@ -1634,3 +1646,11 @@ summary {
color: #333;
border-radius: 5px;
}
.pause-details {
background-color: hsl(240, 18%, 93%);
border: 1px solid #333;
border-radius: 5px;
padding: 5px;
margin-bottom: 10px;
}

View File

@@ -1,22 +1,17 @@
******************************************************** NEXT PATCH **************************************************
difficulty rework
difficulty adjusted through a power up on the initial level
difficulty parameters are more precisely explained
JUNK tech: difficulty - spawns a difficulty power up (only works before level 6)
bots no longer benefit from increased fireRate
shields have a chance spawn on almost all mobs (but not stealth mobs)
level exit door animation is 33% faster
power ups have fewer sides. It might improve game performance, but I can't tell the difference.
1.15x base wave bullets damage (bots, particles, and phonon)
metamaterial absorber 25->30% chance to get power ups from mobs left alive
apomixis is now a JUNK tech, and it requires duplication > 99%
pilot wave field 2->3 extra choices
plasma torch slows mobs more, and don't push mobs back as much
fixed bug where plasma torch didn't get tech degenerate matter
laserLayerBoss and layerLayer do 33% less damage
mines aren't triggered by invulnerable mobs
you can now jump off mobs while invulnerable
includes time dilated
pause display text updated with details menus
difficulty parameters
0.82->0.84x damage done per level
1.25->1.23x damage taken per level
tungsten carbide 300->400 health, but 0.08->0.02 seconds of coyote time and longer crouch time
nitinol 0.08->0.17 seconds of coyote time and much less crouching on hard landings, but 0.8->1 damage taken
mass-energy equivalence no longer costs 2 research
long power up spawns, like from interest or supply chain:
will pause new spawns until total power ups are below 300 to reduce lag
stop spawning if you take damage
bug fixes
@@ -34,7 +29,7 @@ add more randomize sub level map content
left/right sides of lock
small lab rooms
powerful synergies
list of powerful synergies
CPT + high energy regen
research + bot fabrication + ersatz bots + various bot upgrades
harpoon + high fire rate + alternator + time dilation
@@ -46,34 +41,33 @@ powerful synergies
*********************************************************** 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)
difficulty rework: explicit changes to the game to increase difficulty
UI -
add difficulty display to pause menu
update pause menu text to match opening screen menu
just make it a square like field or gun on left pause column
add a wire attached to difficulty power up
like the one attached to player, but thinner
add new difficulty to game code
todo
check for any undocumented side effects
heal power ups (small effect)
(remove, keep, or add to parameters)
balance testing log:
difficultyMode=5 died on level 5 with a good drone build, seemed similar balance to old why mode, maybe slightly harder...
difficultyMode=2 won with a good spore build, seemed similar balance to old normal mode
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
but energy drains
after getting a new tech,gun,field draw that tech where it would be in a pause menu for a second seconds
this makes it easier for people to see what's going on
bullets should trigger shrinking platforms level element?
level element - player activated elevators
could be fast and throw player
could just rise up slow (slow might have a bad jerky animation)
tech: super balls split after 3 seconds, but they fire with less speed
tech: super balls split after 3 seconds
but they lost 50% less time
buff plasma torch
buff plasma tech?
@@ -1305,6 +1299,7 @@ possible names for tech
equivalence principle - gravity and acceleration are the same
Casimir effect - attractive force between two close conductive plates
difference engine - early calculator/computer
cyanoacrylate - superglue use for a slowing effect?
******************************************************** IMAGES ********************************************************