shape memory

shape-memory alloy now also increases 100% heal power ups when "ON"

smelting makes multiple harpoons that fire in a quick succession
  instead of at different angles
  costs 2 less ammo
harpoon tech filament gives +20% longer rope per ammo
ground state: 66->50% less passive energy generation

grenadier mobs have a much longer delay before they explode on death
level based lasers now damage mobs
  but don't trick mobs into touching the laser, it's rude

bug fixes
This commit is contained in:
landgreen
2022-06-25 20:57:06 -07:00
parent 784c933260
commit a0ff668571
10 changed files with 175 additions and 121 deletions

View File

@@ -1820,8 +1820,9 @@ const b = {
} else { //&& simulation.cycle % 2 } else { //&& simulation.cycle % 2
for (let i = 0, len = powerUp.length; i < len; ++i) { for (let i = 0, len = powerUp.length; i < len; ++i) {
const radius = powerUp[i].circleRadius + 50 const radius = powerUp[i].circleRadius + 50
if (Vector.magnitudeSquared(Vector.sub(this.vertices[2], powerUp[i].position)) < radius * radius) { if (Vector.magnitudeSquared(Vector.sub(this.vertices[2], powerUp[i].position)) < radius * radius && !powerUp[i].isGrabbed) {
if (powerUp[i].name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal) { if (powerUp[i].name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal) {
powerUp[i].isGrabbed = true
this.caughtPowerUp = powerUp[i] this.caughtPowerUp = powerUp[i]
Matter.Body.setVelocity(powerUp[i], { x: 0, y: 0 }) Matter.Body.setVelocity(powerUp[i], { x: 0, y: 0 })
Matter.Body.setPosition(powerUp[i], this.vertices[2]) Matter.Body.setPosition(powerUp[i], this.vertices[2])
@@ -6543,11 +6544,11 @@ const b = {
x: m.pos.x + harpoonSize * 40 * Math.cos(m.angle), x: m.pos.x + harpoonSize * 40 * Math.cos(m.angle),
y: m.pos.y + harpoonSize * 40 * Math.sin(m.angle) y: m.pos.y + harpoonSize * 40 * Math.sin(m.angle)
} }
if (tech.extraHarpoons && !input.down) { //multiple harpoons const num = Math.min(this.ammo, tech.extraHarpoons + 1)
if (!input.down && num > 1) { //multiple harpoons
const SPREAD = 0.06 const SPREAD = 0.06
const len = tech.extraHarpoons + 1 let angle = m.angle - SPREAD * num / 2;
let angle = m.angle - SPREAD * len / 2; for (let i = 0; i < num; i++) {
for (let i = 0; i < len; i++) {
if (this.ammo > 0) { if (this.ammo > 0) {
this.ammo-- this.ammo--
b.grapple(where, angle, true, harpoonSize) b.grapple(where, angle, true, harpoonSize)
@@ -6576,13 +6577,13 @@ const b = {
} }
//look for closest mob in player's LoS //look for closest mob in player's LoS
const harpoonSize = (tech.isLargeHarpoon ? 1 + 0.1 * Math.sqrt(this.ammo) : 1) //* (input.down ? 0.7 : 1) const harpoonSize = (tech.isLargeHarpoon ? 1 + 0.1 * Math.sqrt(this.ammo) : 1) //* (input.down ? 0.7 : 1)
const totalCycles = 6 * (tech.isFilament ? 1 + 0.01 * Math.min(110, this.ammo) : 1) * Math.sqrt(harpoonSize) const totalCycles = 6 * (tech.isFilament ? 1 + 0.012 * Math.min(110, this.ammo) : 1) * Math.sqrt(harpoonSize)
if (tech.extraHarpoons && !input.down) { //multiple harpoons if (tech.extraHarpoons && !input.down) { //multiple harpoons
const SPREAD = 0.1 const SPREAD = 0.1
let angle = m.angle - SPREAD * tech.extraHarpoons / 2; let angle = m.angle - SPREAD * tech.extraHarpoons / 2;
const dir = { x: Math.cos(angle), y: Math.sin(angle) }; //make a vector for the player's direction of length 1; used in dot product const dir = { x: Math.cos(angle), y: Math.sin(angle) }; //make a vector for the player's direction of length 1; used in dot product
const range = 450 * (tech.isFilament ? 1 + 0.005 * Math.min(110, this.ammo) : 1) const range = 450 * (tech.isFilament ? 1 + 0.006 * Math.min(110, this.ammo) : 1)
let targetCount = 0 let targetCount = 0
for (let i = 0, len = mob.length; i < len; ++i) { for (let i = 0, len = mob.length; i < len; ++i) {
if (mob[i].alive && !mob[i].isBadTarget && !mob[i].shield && Matter.Query.ray(map, m.pos, mob[i].position).length === 0 && !mob[i].isInvulnerable) { if (mob[i].alive && !mob[i].isBadTarget && !mob[i].shield && Matter.Query.ray(map, m.pos, mob[i].position).length === 0 && !mob[i].isInvulnerable) {
@@ -6601,14 +6602,23 @@ const b = {
} }
//if more harpoons and no targets left //if more harpoons and no targets left
if (targetCount < tech.extraHarpoons + 1) { if (targetCount < tech.extraHarpoons + 1) {
const num = tech.extraHarpoons + 1 - targetCount const num = tech.extraHarpoons - targetCount
for (let i = 0; i < num; i++) { const delay = 7 //Math.floor(Math.max(4, 8 - 0.5 * tech.extraHarpoons))
if (this.ammo > 0) { let count = -1
this.ammo-- let harpoonDelay = () => {
b.harpoon(where, null, angle, harpoonSize, true, totalCycles) //Vector.angle(Vector.sub(where, mob[i].position), { x: 0, y: 0 }) if (simulation.paused) { requestAnimationFrame(harpoonDelay) } else {
angle += SPREAD count++
if (!(count % delay) && this.ammo > 0) {
this.ammo--
b.harpoon({
x: m.pos.x + 30 * Math.cos(m.angle),
y: m.pos.y + 30 * Math.sin(m.angle)
}, null, m.angle, harpoonSize, true, totalCycles)
}
if (count < num * delay && m.alive) requestAnimationFrame(harpoonDelay);
} }
} }
requestAnimationFrame(harpoonDelay)
} }
this.ammo++ //make up for the ammo used up in fire() this.ammo++ //make up for the ammo used up in fire()
simulation.updateGunHUD(); simulation.updateGunHUD();

View File

@@ -125,7 +125,17 @@ function collisionChecks(event) {
m.eyeFillColor = m.fieldMeterColor //'#0cf' m.eyeFillColor = m.fieldMeterColor //'#0cf'
if (!tech.isFlipFlopHarm) m.damage(dmg); if (!tech.isFlipFlopHarm) m.damage(dmg);
} }
if (tech.isFlipFlopHealth) m.setMaxHealth(); if (tech.isFlipFlopHealth) {
m.setMaxHealth();
for (let i = 0; i < powerUp.length; i++) {
if (powerUp[i].name === "heal") {
const oldSize = powerUp[i].size
powerUp[i].size = powerUps.heal.size() //update current heals
const scale = powerUp[i].size / oldSize
Matter.Body.scale(powerUp[i], scale, scale); //grow
}
}
}
} else { } else {
m.damage(dmg); //normal damage m.damage(dmg); //normal damage
} }

View File

@@ -17,17 +17,18 @@ const level = {
if (level.levelsCleared === 0) { //this code only runs on the first level if (level.levelsCleared === 0) { //this code only runs on the first level
// simulation.isHorizontalFlipped = true // simulation.isHorizontalFlipped = true
// m.addHealth(Infinity) // m.addHealth(Infinity)
// m.setField("time dilation") // m.setField("wormhole")
// b.giveGuns("nail gun") // b.giveGuns("nail gun")
// b.guns[0].ammo = 10000
// b.giveGuns("mine") // b.giveGuns("mine")
// tech.giveTech("cross disciplinary") // tech.giveTech("alternator")
// tech.giveTech("determinism") // for (let i = 0; i < 3; ++i) tech.giveTech("smelting")
// tech.giveTech("pseudoscience") // for (let i = 0; i < 9; ++i) tech.giveTech("propagator")
// for (let i = 0; i < 100; ++i) tech.giveTech("nail-bot") // for (let i = 0; i < 100; ++i) tech.giveTech("nail-bot")
// for (let i = 0; i < 9; ++i) tech.giveTech("emergence") // for (let i = 0; i < 9; ++i) tech.giveTech("emergence")
// tech.giveTech("decoherence") // tech.giveTech("decoherence")
// tech.giveTech("brainstorming") // tech.giveTech("adiabatic healing")
// tech.giveTech("path integral") // tech.giveTech("shape-memory alloy")
// m.maxHealth = 100 // m.maxHealth = 100
// m.health = m.maxHealth // m.health = m.maxHealth
// for (let i = 0; i < 10; i++) tech.giveTech("tungsten carbide") // for (let i = 0; i < 10; i++) tech.giveTech("tungsten carbide")
@@ -38,17 +39,17 @@ const level = {
// powerUps.research.changeRerolls(100000) // powerUps.research.changeRerolls(100000)
// tech.tech[297].frequency = 100 // tech.tech[297].frequency = 100
// m.immuneCycle = Infinity //you can't take damage // m.immuneCycle = Infinity //you can't take damage
// level.difficultyIncrease(40) //30 is near max on hard //60 is near max on why
// simulation.enableConstructMode() //used to build maps in testing mode // simulation.enableConstructMode() //used to build maps in testing mode
// level.testChamber2(); // level.testChamber2();
// spawn.cellBossCulture(1900, -500) // spawn.cellBossCulture(1900, -500)
// level.testing(); //not in rotation, used for testing
// for (let i = 0; i < 4; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
// for (let i = 0; i < 7; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research");
// powerUps.research.changeRerolls(100) // powerUps.research.changeRerolls(100)
// spawn.starter(1900, -500, 300) // spawn.starter(1900, -500, 100)
// for (let i = 0; i < 50; ++i) spawn.starter(1900, -500) // for (let i = 0; i < 20; ++i) spawn.exploder(1900, -500)
// spawn.powerUpBoss(1900, -500) // spawn.grenadierBoss(1900, -500)
// level.difficultyIncrease(20) //30 is near max on hard //60 is near max on why
// level.testing(); //not in rotation, used for testing
// for (let i = 0; i < 7; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research");
// for (let i = 0; i < 4; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************ if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************
// powerUps.research.changeRerolls(3000) // powerUps.research.changeRerolls(3000)
@@ -110,7 +111,7 @@ const level = {
powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "tech", false); powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "tech", false);
} }
if (tech.isHealLowHealth) { if (tech.isHealLowHealth) {
const len = Math.ceil((m.maxHealth - m.health) / 0.26) const len = Math.ceil((m.maxHealth - m.health) / 0.29)
for (let i = 0; i < len; i++) powerUps.spawn(player.position.x + 90 * (Math.random() - 0.5), player.position.y + 90 * (Math.random() - 0.5), "heal", false); for (let i = 0; i < len; i++) powerUps.spawn(player.position.x + 90 * (Math.random() - 0.5), player.position.y + 90 * (Math.random() - 0.5), "heal", false);
} }
if (tech.isMACHO) spawn.MACHO() if (tech.isMACHO) spawn.MACHO()
@@ -1324,6 +1325,17 @@ const level = {
}); });
} }
} }
//collision with mobs
if (!(simulation.cycle % 5) && !m.isBodiesAsleep) {
query = Matter.Query.region(mob, this)
for (let i = 0; i < query.length; i++) query[i].damage(5 * damage)
}
// for (let i = 0, len = mob.length; i < len; i++) {
// if ( !mob[i].isBoss) {
// mob[i].damage(0.1 * damage)
// }
// }
} }
}, },
query() { query() {
@@ -2615,6 +2627,7 @@ const level = {
spawn.mapRect(475, -25, 25, 50); //edge shelf spawn.mapRect(475, -25, 25, 50); //edge shelf
}, },
testing() { testing() {
const hazard = level.hazard(6000, -1000, 5, 1000, 0.4) //laser
const button = level.button(1000, 0) const button = level.button(1000, 0)
spawn.bodyRect(1000, -50, 50, 50); spawn.bodyRect(1000, -50, 50, 50);
@@ -2628,6 +2641,7 @@ const level = {
level.enter.draw(); level.enter.draw();
}; };
level.customTopLayer = () => { level.customTopLayer = () => {
hazard.opticalQuery();
button.query(); button.query();
button.draw(); button.draw();
ctx.fillStyle = "rgba(0,0,0,0.1)" ctx.fillStyle = "rgba(0,0,0,0.1)"

View File

@@ -1162,9 +1162,9 @@ const mobs = {
} }
} }
if (tech.isDeathSkipTime && !m.isBodiesAsleep) { if (tech.deathSkipTime && !m.isBodiesAsleep) {
requestAnimationFrame(() => { requestAnimationFrame(() => {
simulation.timePlayerSkip(this.isBoss ? 45 : 25) simulation.timePlayerSkip((this.isBoss ? 45 : 25) * tech.deathSkipTime)
simulation.loop(); //ending with a wipe and normal loop fixes some very minor graphical issues where things are draw in the wrong locations simulation.loop(); //ending with a wipe and normal loop fixes some very minor graphical issues where things are draw in the wrong locations
}); //wrapping in animation frame prevents errors, probably }); //wrapping in animation frame prevents errors, probably

View File

@@ -500,7 +500,7 @@ const m = {
}, },
baseHealth: 1, baseHealth: 1,
setMaxHealth() { setMaxHealth() {
m.maxHealth = m.baseHealth + tech.extraMaxHealth + tech.isFallingDamage + 2 * tech.isFlipFlop * tech.isFlipFlopOn * tech.isFlipFlopHealth m.maxHealth = m.baseHealth + tech.extraMaxHealth + tech.isFallingDamage + 4 * tech.isFlipFlop * tech.isFlipFlopOn * tech.isFlipFlopHealth
document.getElementById("health-bg").style.width = `${Math.floor(300 * m.maxHealth)}px` document.getElementById("health-bg").style.width = `${Math.floor(300 * m.maxHealth)}px`
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-h'>maxHealth</span> <span class='color-symbol'>=</span> ${m.maxHealth.toFixed(2)}`) 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; if (m.health > m.maxHealth) m.health = m.maxHealth;
@@ -512,6 +512,7 @@ const m = {
harmReduction() { harmReduction() {
let dmg = 1 let dmg = 1
dmg *= m.fieldHarmReduction dmg *= m.fieldHarmReduction
// if (!tech.isFlipFlopOn && tech.isFlipFlopHealth) dmg *= 0.5
if (tech.isZeno) dmg *= 0.15 if (tech.isZeno) dmg *= 0.15
if (tech.isFieldHarmReduction) dmg *= 0.5 if (tech.isFieldHarmReduction) dmg *= 0.5
if (tech.isHarmMACHO) dmg *= 0.4 if (tech.isHarmMACHO) dmg *= 0.4
@@ -2153,6 +2154,8 @@ const m = {
description: "use <strong class='color-f'>energy</strong> to emit short range <strong class='color-plasma'>plasma</strong><br><strong class='color-d'>damages</strong> and <strong>pushes</strong> mobs away<br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second", description: "use <strong class='color-f'>energy</strong> to emit short range <strong class='color-plasma'>plasma</strong><br><strong class='color-d'>damages</strong> and <strong>pushes</strong> mobs away<br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second",
set() { set() {
b.isExtruderOn = false b.isExtruderOn = false
// m.fieldCDcycleAlternate = 0
if (m.plasmaBall) { if (m.plasmaBall) {
m.plasmaBall.reset() m.plasmaBall.reset()
Matter.Composite.remove(engine.world, m.plasmaBall); Matter.Composite.remove(engine.world, m.plasmaBall);

View File

@@ -248,7 +248,8 @@ const powerUps = {
} else if (type === "field") { } else if (type === "field") {
m.setField(index) m.setField(index)
} else if (type === "tech") { } else if (type === "tech") {
if (tech.isBanish && tech.tech[index].isBanished) tech.tech[index].isBanished = false // if (tech.isBanish && tech.tech[index].isBanished) tech.tech[index].isBanished = false
powerUps.tech.banishList
setTimeout(() => { powerUps.lastTechIndex = index }, 10); setTimeout(() => { powerUps.lastTechIndex = index }, 10);
simulation.makeTextLog(`<span class='color-var'>tech</span>.giveTech("<span class='color-text'>${tech.tech[index].name}</span>")`); simulation.makeTextLog(`<span class='color-var'>tech</span>.giveTech("<span class='color-text'>${tech.tech[index].name}</span>")`);
tech.giveTech(index) tech.giveTech(index)
@@ -446,48 +447,21 @@ const powerUps = {
name: "heal", name: "heal",
color: "#0eb", color: "#0eb",
size() { size() {
return 40 * (simulation.healScale ** 0.25) * Math.sqrt(tech.largerHeals) * Math.sqrt(0.1 + Math.random() * 0.5); //(simulation.healScale ** 0.25) gives a smaller radius as heal scale goes down return Math.sqrt(0.1 + 0.25) * 40 * (simulation.healScale ** 0.25) * Math.sqrt(tech.largerHeals) * (tech.isFlipFlopOn && tech.isFlipFlopHealth ? Math.sqrt(2) : 1); //(simulation.healScale ** 0.25) gives a smaller radius as heal scale goes down
},
calculateHeal(size) {
return tech.largerHeals * (size / 40 / Math.sqrt(tech.largerHeals) / (simulation.healScale ** 0.25)) ** 2 //heal scale is undone here because heal scale is properly affected on m.addHealth()
}, },
effect() { effect() {
// if (!tech.isEnergyHealth && m.alive) {
// const heal = powerUps.heal.calculateHeal(this.size)
// if (heal > 0) {
// if (tech.isOverHeal && m.health === m.maxHealth) { //tech quenching
// m.damage(heal * simulation.healScale);
// //draw damage
// simulation.drawList.push({ //add dmg to draw queue
// x: m.pos.x,
// y: m.pos.y,
// radius: heal * 500 * simulation.healScale,
// color: simulation.mobDmgColor,
// time: simulation.drawTime
// });
// tech.extraMaxHealth += heal * simulation.healScale //increase max health
// m.setMaxHealth();
// } else {
// const healOutput = Math.min(m.maxHealth - m.health, heal) * simulation.healScale
// m.addHealth(heal);
// simulation.makeTextLog(`<span class='color-var'>m</span>.health <span class='color-symbol'>+=</span> ${(healOutput).toFixed(3)}`) // <br>${m.health.toFixed(3)}
// }
// }
// }
if (!tech.isEnergyHealth && m.alive && !tech.isNoHeals) { if (!tech.isEnergyHealth && m.alive && !tech.isNoHeals) {
const heal = powerUps.heal.calculateHeal(this.size) const heal = (this.size / 40 / (simulation.healScale ** 0.25)) ** 2 //simulation.healScale is undone here because heal scale is already properly affected on m.addHealth()
// console.log("size = " + this.size, "heal = " + heal)
if (heal > 0) { if (heal > 0) {
const overHeal = m.health + heal * simulation.healScale - m.maxHealth //used with tech.isOverHeal const overHeal = m.health + heal * simulation.healScale - m.maxHealth //used with tech.isOverHeal
const healOutput = Math.min(m.maxHealth - m.health, heal) * simulation.healScale const healOutput = Math.min(m.maxHealth - m.health, heal) * simulation.healScale
m.addHealth(heal); m.addHealth(heal);
simulation.makeTextLog(`<span class='color-var'>m</span>.health <span class='color-symbol'>+=</span> ${(healOutput).toFixed(3)}`) // <br>${m.health.toFixed(3)} simulation.makeTextLog(`<span class='color-var'>m</span>.health <span class='color-symbol'>+=</span> ${(healOutput).toFixed(3)}`) // <br>${m.health.toFixed(3)}
if (tech.isOverHeal && overHeal > 0) { //tech quenching if (tech.isOverHeal && overHeal > 0) { //tech quenching
const scaledOverHeal = overHeal * 0.7 const scaledOverHeal = overHeal * 0.7
m.damage(scaledOverHeal); m.damage(scaledOverHeal);
simulation.makeTextLog(`<span class='color-var'>m</span>.health <span class='color-symbol'>-=</span> ${(scaledOverHeal).toFixed(3)}`) // <br>${m.health.toFixed(3)} simulation.makeTextLog(`<span class='color-var'>m</span>.health <span class='color-symbol'>-=</span> ${(scaledOverHeal).toFixed(3)}`) // <br>${m.health.toFixed(3)}
//draw damage
simulation.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
x: m.pos.x, x: m.pos.x,
y: m.pos.y, y: m.pos.y,
@@ -500,7 +474,6 @@ const powerUps = {
} }
} }
} }
if (tech.healGiveMaxEnergy) { if (tech.healGiveMaxEnergy) {
tech.healMaxEnergyBonus += 0.1 tech.healMaxEnergyBonus += 0.1
m.setMaxEnergy(); m.setMaxEnergy();
@@ -900,17 +873,19 @@ const powerUps = {
for (let i = 0; i < tech.tech.length; i++) tech.tech[i].isRecentlyShown = false //reset recently shown back to zero for (let i = 0; i < tech.tech.length; i++) tech.tech[i].isRecentlyShown = false //reset recently shown back to zero
// powerUps.tech.lastTotalChoices = options.length //this is recorded so that banish can know how many tech were available // powerUps.tech.lastTotalChoices = options.length //this is recorded so that banish can know how many tech were available
// console.log(optionLengthNoDuplicates, options.length) // console.log(optionLengthNoDuplicates, options.length)
powerUps.tech.banishList = []
if (options.length > 0) { if (options.length > 0) {
for (let i = 0; i < totalChoices; i++) { for (let i = 0; i < totalChoices; i++) {
if (options.length < 1) break if (options.length < 1) break
const choose = options[Math.floor(Math.seededRandom(0, options.length))] //pick an element from the array of options const choose = options[Math.floor(Math.seededRandom(0, options.length))] //pick an element from the array of options
if (tech.isBanish) { if (tech.isBanish) {
tech.tech[choose].isBanished = true tech.tech[choose].isBanished = true
if (i === 0) simulation.makeTextLog(`options.length = ${optionLengthNoDuplicates}`) if (i === 0) simulation.makeTextLog(`options.length = ${optionLengthNoDuplicates}`)
} }
//avoid displaying repeated tech options at the same time
removeOption(choose) removeOption(choose) //move from future options pool to avoid repeats on this selection
tech.tech[choose].isRecentlyShown = true tech.tech[choose].isRecentlyShown = true //this flag prevents this option from being shown the next time you pick up a tech power up
const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : ""; const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
if (tech.tech[choose].isFieldTech) { if (tech.tech[choose].isFieldTech) {

View File

@@ -114,6 +114,7 @@ const simulation = {
simulation.checks(); simulation.checks();
mobs.loop(); mobs.loop();
} }
m.hold();
b.bulletRemove(); b.bulletRemove();
if (!m.isBodiesAsleep) b.bulletDo(); if (!m.isBodiesAsleep) b.bulletDo();
} }

View File

@@ -3875,12 +3875,8 @@ const spawn = {
// this.isInvulnerable = true // this.isInvulnerable = true
// this.damageReduction = 0 // this.damageReduction = 0
} else { } else {
if (Math.abs(this.velocity.y) < 15) { if (Math.abs(this.velocity.y) < 15) Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.03 });
Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.03 }); if (Math.abs(this.velocity.x) < 11) Matter.Body.setVelocity(this, { x: this.velocity.x * 1.03, y: this.velocity.y });
}
if (Math.abs(this.velocity.x) < 11) {
Matter.Body.setVelocity(this, { x: this.velocity.x * 1.03, y: this.velocity.y });
}
} }
if (this.isInvulnerable) { if (this.isInvulnerable) {
@@ -4956,24 +4952,26 @@ const spawn = {
spawn.spawnOrbitals(me, radius + 200, 1); spawn.spawnOrbitals(me, radius + 200, 1);
Matter.Body.setDensity(me, 0.004 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.004 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.onDeath = function() { //helps collisions functions work better after vertex have been changed me.onDeath = function() { //helps collisions functions work better after vertex have been changed
for (let i = 0; i < 6; i++) { setTimeout(() => { //fix mob in place, but allow rotation
spawn.grenade(this.position.x, this.position.y, 75 * simulation.CDScale); for (let i = 0, len = 6; i < len; i++) {
const who = mob[mob.length - 1] const speed = 2.25 * simulation.accelScale;
const speed = 4 * simulation.accelScale; const angle = 2 * Math.PI * i / len
const angle = 2 * Math.PI * i / 6 spawn.grenade(this.position.x, this.position.y, 170 * simulation.CDScale);
Matter.Body.setVelocity(who, { const who = mob[mob.length - 1]
x: speed * Math.cos(angle), Matter.Body.setVelocity(who, {
y: speed * Math.sin(angle) x: speed * Math.cos(angle),
}); y: speed * Math.sin(angle)
} });
}
}, 200);
powerUps.spawnBossPowerUp(this.position.x, this.position.y) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
} }
me.grenadeLimiter = 0 me.grenadeLimiter = 0
me.onDamage = function() { me.onDamage = function() {
if (this.grenadeLimiter < 240) { if (this.grenadeLimiter < 240 && this.health > 0) {
this.grenadeLimiter += 60 this.grenadeLimiter += 60
spawn.grenade(this.position.x, this.position.y, 80 + Math.floor(60 * Math.random())); spawn.grenade(this.position.x, this.position.y, 80 + Math.floor(60 * Math.random()));
const who = mob[mob.length - 1] who = mob[mob.length - 1]
const velocity = Vector.mult(Vector.normalise(Vector.sub(player.position, who.position)), 3 * Math.sqrt(simulation.accelScale) + 4 * Math.random()) const velocity = Vector.mult(Vector.normalise(Vector.sub(player.position, who.position)), 3 * Math.sqrt(simulation.accelScale) + 4 * Math.random())
Matter.Body.setVelocity(who, { Matter.Body.setVelocity(who, {
x: this.velocity.x + velocity.x, x: this.velocity.x + velocity.x,
@@ -5011,7 +5009,7 @@ const spawn = {
y: 0 y: 0
}; };
me.onDeath = function() { //helps collisions functions work better after vertex have been changed me.onDeath = function() { //helps collisions functions work better after vertex have been changed
spawn.grenade(this.position.x, this.position.y, 75 * simulation.CDScale); spawn.grenade(this.position.x, this.position.y, 200 * simulation.CDScale);
// mob[mob.length - 1].collisionFilter.category = 0 // mob[mob.length - 1].collisionFilter.category = 0
mob[mob.length - 1].collisionFilter.mask = cat.player | cat.map; mob[mob.length - 1].collisionFilter.mask = cat.player | cat.map;
} }

View File

@@ -224,7 +224,7 @@ const tech = {
}, },
damageFromTech() { damageFromTech() {
let dmg = 1 //m.fieldDamage let dmg = 1 //m.fieldDamage
if (tech.isDeathSkipTime) dmg *= 1.67 if (tech.deathSkipTime) dmg *= 1 + 0.6 * tech.deathSkipTime
if (tech.isNoDraftPause) dmg *= 1.34 if (tech.isNoDraftPause) dmg *= 1.34
if (tech.isCloakingDamage) dmg *= 1.35 if (tech.isCloakingDamage) dmg *= 1.35
if (tech.isTechDamage) dmg *= 1.9 if (tech.isTechDamage) dmg *= 1.9
@@ -964,8 +964,8 @@ const tech = {
}, },
{ {
name: "propagator", name: "propagator",
description: "after mobs <strong>die</strong> advance time <strong>0.5</strong> seconds<br><strong>+67%</strong> <strong class='color-d'>damage</strong>", description: "after mobs <strong>die</strong> advance time <strong>0.5</strong> seconds<br><strong>+60%</strong> <strong class='color-d'>damage</strong>",
maxCount: 1, maxCount: 3,
count: 0, count: 0,
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
@@ -974,10 +974,10 @@ const tech = {
}, },
requires: "", requires: "",
effect() { effect() {
tech.isDeathSkipTime = true tech.deathSkipTime++
}, },
remove() { remove() {
tech.isDeathSkipTime = false tech.deathSkipTime = 0
} }
}, },
{ {
@@ -1720,7 +1720,7 @@ const tech = {
}, },
{ {
name: "shape-memory alloy", name: "shape-memory alloy",
description: "if <strong>flip-flop</strong> is <strong class='color-flop'>ON</strong><br><strong>+200</strong> maximum <strong class='color-h'>health</strong>", description: `if <strong>flip-flop</strong> is <strong class='color-flop'>ON</strong><br><strong>+400</strong> maximum <strong class='color-h'>health</strong> and <strong>+100%</strong> ${powerUps.orb.heal()} effect`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 4, frequency: 4,
@@ -1732,10 +1732,26 @@ const tech = {
effect() { effect() {
tech.isFlipFlopHealth = true; tech.isFlipFlopHealth = true;
m.setMaxHealth(); m.setMaxHealth();
for (let i = 0; i < powerUp.length; i++) {
if (powerUp[i].name === "heal") {
const oldSize = powerUp[i].size
powerUp[i].size = powerUps.heal.size() //update current heals
const scale = powerUp[i].size / oldSize
Matter.Body.scale(powerUp[i], scale, scale); //grow
}
}
}, },
remove() { remove() {
tech.isFlipFlopHealth = false; tech.isFlipFlopHealth = false;
m.setMaxHealth(); m.setMaxHealth();
for (let i = 0; i < powerUp.length; i++) {
if (powerUp[i].name === "heal") {
const oldSize = powerUp[i].size
powerUp[i].size = powerUps.heal.size() //update current heals
const scale = powerUp[i].size / oldSize
Matter.Body.scale(powerUp[i], scale, scale); //grow
}
}
} }
}, },
{ {
@@ -2233,7 +2249,7 @@ const tech = {
}, },
{ {
name: "ground state", name: "ground state",
description: "<strong>+200</strong> maximum <strong class='color-f'>energy</strong><br><strong>66%</strong> passive <strong class='color-f'>energy</strong> generation", description: "<strong>+200</strong> maximum <strong class='color-f'>energy</strong><br><strong>50%</strong> passive <strong class='color-f'>energy</strong> generation",
// description: "reduce <strong class='color-defense'>defense</strong> by <strong>66%</strong><br>you <strong>no longer</strong> passively regenerate <strong class='color-f'>energy</strong>", // description: "reduce <strong class='color-defense'>defense</strong> by <strong>66%</strong><br>you <strong>no longer</strong> passively regenerate <strong class='color-f'>energy</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -2244,7 +2260,7 @@ const tech = {
}, },
requires: "not time crystals", requires: "not time crystals",
effect: () => { effect: () => {
m.fieldRegen = 0.00033 m.fieldRegen = 0.0005
tech.isGroundState = true tech.isGroundState = true
m.setMaxEnergy() m.setMaxEnergy()
}, },
@@ -2581,16 +2597,16 @@ const tech = {
}, },
{ {
name: "negative entropy", name: "negative entropy",
description: `at the start of each <strong>level</strong><br>for every <strong>26</strong> missing <strong class='color-h'>health</strong> spawn ${powerUps.orb.heal()}`, description: `at the start of each <strong>level</strong><br>for every <strong>29</strong> missing <strong class='color-h'>health</strong> spawn ${powerUps.orb.heal()}`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
isHealTech: true, isHealTech: true,
allowed() { allowed() {
return m.health > 0.1 && !tech.isNoHeals return !tech.isNoHeals
}, },
requires: "has some health, not ergodicity", requires: "not ergodicity",
effect() { effect() {
tech.isHealLowHealth = true; tech.isHealLowHealth = true;
}, },
@@ -2612,15 +2628,27 @@ const tech = {
requires: "under 70% health, not mass-energy equivalence, ergodicity", requires: "under 70% health, not mass-energy equivalence, ergodicity",
effect() { effect() {
tech.largerHeals++; tech.largerHeals++;
this.refundAmount += tech.addJunkTechToPool(0.05)
//update current heals
for (let i = 0; i < powerUp.length; i++) { for (let i = 0; i < powerUp.length; i++) {
if (powerUp[i].name === "heal") powerUp[i].size = powerUps.heal.size() if (powerUp[i].name === "heal") {
const oldSize = powerUp[i].size
powerUp[i].size = powerUps.heal.size() //update current heals
const scale = powerUp[i].size / oldSize
Matter.Body.scale(powerUp[i], scale, scale); //grow
}
} }
this.refundAmount += tech.addJunkTechToPool(0.05)
}, },
refundAmount: 0, refundAmount: 0,
remove() { remove() {
tech.largerHeals = 1; tech.largerHeals = 1;
for (let i = 0; i < powerUp.length; i++) {
if (powerUp[i].name === "heal") {
const oldSize = powerUp[i].size
powerUp[i].size = powerUps.heal.size() //update current heals
const scale = powerUp[i].size / oldSize
Matter.Body.scale(powerUp[i], scale, scale); //grow
}
}
if (this.count > 0 && this.refundAmount > 0) { if (this.count > 0 && this.refundAmount > 0) {
tech.removeJunkTechFromPool(this.refundAmount) tech.removeJunkTechFromPool(this.refundAmount)
this.refundAmount = 0 this.refundAmount = 0
@@ -2814,7 +2842,7 @@ const tech = {
}, },
{ {
name: "decoherence", name: "decoherence",
description: `<strong class='color-r'>researched</strong> or <strong>canceled</strong> <strong class='color-m'>tech</strong> won't <strong>reoccur</strong> <br>spawn ${powerUps.orb.research(7)}`, description: `<strong class='color-m'>tech</strong> options you don't <strong>choose</strong> won't <strong>reoccur</strong><br>spawn ${powerUps.orb.research(7)}`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -5917,7 +5945,7 @@ const tech = {
{ {
name: "smelting", name: "smelting",
// description: `forge <strong>3</strong> <strong class='color-ammo'>ammo</strong> into a new harpoon<br>fire <strong>+1</strong> <strong>harpoon</strong> with each shot`, // description: `forge <strong>3</strong> <strong class='color-ammo'>ammo</strong> into a new harpoon<br>fire <strong>+1</strong> <strong>harpoon</strong> with each shot`,
descriptionFunction() { return `forge <strong>${(tech.isRailGun ?5:3)*(2+this.count)}</strong> <strong class='color-ammo'>ammo</strong> into a new harpoon<br>fire <strong>+1</strong> <strong>harpoon</strong> with each shot` }, descriptionFunction() { return `forge <strong>${(tech.isRailGun ? 2 : 1) * (4 + 2 * this.count)}</strong> <strong class='color-ammo'>ammo</strong> into a new harpoon<br>fire <strong>+1</strong> <strong>harpoon</strong> with each shot` },
// descriptionFunction() { return `forge <strong>${tech.isRailGun? 10: 2}</strong> <strong class='color-ammo'>ammo</strong> into a new harpoon<br>fire <strong>+1</strong> <strong>harpoon</strong> with each shot` }, // descriptionFunction() { return `forge <strong>${tech.isRailGun? 10: 2}</strong> <strong class='color-ammo'>ammo</strong> into a new harpoon<br>fire <strong>+1</strong> <strong>harpoon</strong> with each shot` },
isGunTech: true, isGunTech: true,
maxCount: 9, maxCount: 9,
@@ -5931,7 +5959,7 @@ const tech = {
effect() { effect() {
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "harpoon") { if (b.guns[i].name === "harpoon") {
b.guns[i].ammo -= (tech.isRailGun ? 5 : 3) * (1 + this.count) b.guns[i].ammo -= (tech.isRailGun ? 5 : 2) * (1 + this.count)
// console.log(3 + this.count * 3) // console.log(3 + this.count * 3)
if (b.guns[i].ammo < 0) b.guns[i].ammo = 0 if (b.guns[i].ammo < 0) b.guns[i].ammo = 0
simulation.updateGunHUD(); simulation.updateGunHUD();
@@ -5958,7 +5986,7 @@ const tech = {
{ {
name: "UHMWPE", name: "UHMWPE",
descriptionFunction() { descriptionFunction() {
return `+${(b.guns[9].ammo).toFixed(0)}% <strong>harpoon</strong> <strong>rope</strong> <strong>length</strong><br><em>(1/100 of harpoon <strong class='color-ammo'>ammo</strong>)</em>` return `+${(b.guns[9].ammo).toFixed(0)}% <strong>harpoon</strong> <strong>rope</strong> <strong>length</strong><br><em>(1/80 of harpoon <strong class='color-ammo'>ammo</strong>)</em>`
}, },
// description: "increase the <strong>length</strong> of your <strong>harpoon</strong>'s <strong>rope</strong><br>by <strong>1%</strong> per harpoon <strong class='color-ammo'>ammo</strong>", // description: "increase the <strong>length</strong> of your <strong>harpoon</strong>'s <strong>rope</strong><br>by <strong>1%</strong> per harpoon <strong class='color-ammo'>ammo</strong>",
isGunTech: true, isGunTech: true,
@@ -7437,6 +7465,7 @@ const tech = {
tech.isWormHolePause = true tech.isWormHolePause = true
}, },
remove() { remove() {
if (tech.isWormHolePause && m.isBodiesAsleep) m.wakeCheck();
tech.isWormHolePause = false tech.isWormHolePause = false
} }
}, },
@@ -10303,7 +10332,7 @@ const tech = {
isClusterExplode: null, isClusterExplode: null,
isCircleExplode: null, isCircleExplode: null,
isPetalsExplode: null, isPetalsExplode: null,
isDeathSkipTime: null, deathSkipTime: null,
isIceMaxHealthLoss: null, isIceMaxHealthLoss: null,
isIceKill: null, isIceKill: null,
isCritKill: null isCritKill: null

View File

@@ -1,20 +1,41 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
rewrite of the tech,gun,field selection code shape-memory alloy now also increases 100% heal power ups when "ON"
odds of new bugs is pretty high, but the code is shorter and faster, so easier to fix
path integral is no longer a JUNK tech
lets you choose from every option on next tech
emergence is stackable
+2 power up choices per stack
tech: integrated circuit - if ON +7 power up choices if OFF -1 smelting makes multiple harpoons that fire in a quick succession
instead of at different angles
costs 2 less ammo
harpoon tech filament gives +20% longer rope per ammo
ground state: 66->50% less passive energy generation
update matter.js engine 0.17.1 -> 0.18.0 grenadier mobs have a much longer delay before they explode on death
shouldn't change anything level based lasers now damage mobs
big fixes but don't trick mobs into touching the laser, it's rude
bug fixes
*********************************************************** TODO ***************************************************** *********************************************************** TODO *****************************************************
improve mob invincible graphic
opacity oscillates from 100% to 0%?
hopBossMom
spawns lots of small hopBullets
drops eggs, that hatch into hopBullets
like sporangium
normally runs away from player, but goes closer to drop eggs
make plasma ball pick up still work when you have no no energy
make a unique CD var for plasma ball?
give laser gun _____ if you fire in an angle range
draw angle range as a slowly rotation circle arc around player
effect:
bonus damage
extra beams
extra reflections
wormhole tech: entropic gravity - gain defense for each research wormhole tech: entropic gravity - gain defense for each research
requires wormhole or negative mass field or pilot wave requires wormhole or negative mass field or pilot wave
@@ -77,13 +98,6 @@ cloaking field
just delay setting the m.isCloak for a couple seconds just delay setting the m.isCloak for a couple seconds
and also set all active bots to remember player in the de-cloaked stop and also set all active bots to remember player in the de-cloaked stop
give laser gun _____ if you fire in an angle range
draw angle range as a slowly rotation circle arc around player
effect:
bonus damage
extra beams
extra reflections
scrap bots can't move? scrap bots can't move?
only works for nail, foam, laser only works for nail, foam, laser
might be tricky code? might be tricky code?