neutronium

tech: neutronium - 90% harm reduce while field is active, 33% slower move speed
  (requires negative mass field)
tech: charmed baryon - 0 cost wormhole, 33% slower move speed
harpoon tech: reticulum now always fires extra harpoons even if there are no targets

tech.removeTech() method has been improved
bug fixes
This commit is contained in:
landgreen
2021-10-24 18:28:33 -07:00
parent bac02c35f6
commit 34b1a02981
8 changed files with 250 additions and 165 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -1133,7 +1133,10 @@ const b = {
who.isShielded = false who.isShielded = false
requestAnimationFrame(() => { who.isShielded = true }); requestAnimationFrame(() => { who.isShielded = true });
} }
if (tech.fragments) b.targetedNail(this.vertices[2], tech.fragments * 3) if (tech.fragments) {
b.targetedNail(this.vertices[2], tech.fragments * 4)
if (!isReturn) this.endCycle = 0;
}
if (!who.isBadTarget) { if (!who.isBadTarget) {
if (isReturn) { if (isReturn) {
this.do = this.returnToPlayer this.do = this.returnToPlayer
@@ -4049,11 +4052,11 @@ const b = {
this.nextFireCycle = m.cycle + CD * b.fireCDscale //predict next fire cycle if the fire button is held down this.nextFireCycle = m.cycle + CD * b.fireCDscale //predict next fire cycle if the fire button is held down
m.fireCDcycle = m.cycle + Math.floor(CD * b.fireCDscale); // cool down m.fireCDcycle = m.cycle + Math.floor(CD * b.fireCDscale); // cool down
this.baseFire(m.angle + (Math.random() - 0.5) * (input.down ? 0.05 : 0.1) / CD, 43 + 8 * Math.random()) this.baseFire(m.angle + (Math.random() - 0.5) * (input.down ? 0.1 : 0.13) / CD, 45 + 6 * Math.random())
//very complex recoil system //very complex recoil system
if (m.onGround) { if (m.onGround) {
if (input.down) { if (input.down) {
const KNOCK = 0.01 const KNOCK = 0.006
player.force.x -= KNOCK * Math.cos(m.angle) player.force.x -= KNOCK * Math.cos(m.angle)
player.force.y -= KNOCK * Math.sin(m.angle) //reduce knock back in vertical direction to stop super jumps player.force.y -= KNOCK * Math.sin(m.angle) //reduce knock back in vertical direction to stop super jumps
Matter.Body.setVelocity(player, { Matter.Body.setVelocity(player, {
@@ -4061,7 +4064,7 @@ const b = {
y: player.velocity.y * 0.5 y: player.velocity.y * 0.5
}); });
} else { } else {
const KNOCK = 0.05 const KNOCK = 0.03
player.force.x -= KNOCK * Math.cos(m.angle) player.force.x -= KNOCK * Math.cos(m.angle)
player.force.y -= KNOCK * Math.sin(m.angle) //reduce knock back in vertical direction to stop super jumps player.force.y -= KNOCK * Math.sin(m.angle) //reduce knock back in vertical direction to stop super jumps
Matter.Body.setVelocity(player, { Matter.Body.setVelocity(player, {
@@ -4070,8 +4073,8 @@ const b = {
}); });
} }
} else { } else {
if (Math.abs(player.velocity.x) < 12) player.force.x -= 0.04 * Math.cos(m.angle) if (Math.abs(player.velocity.x) < 12) player.force.x -= 0.025 * Math.cos(m.angle)
player.force.y -= 0.01 * Math.sin(m.angle) //reduce knock back in vertical direction to stop super jumps player.force.y -= 0.006 * Math.sin(m.angle) //reduce knock back in vertical direction to stop super jumps
} }
}, },
fireNormal() { fireNormal() {
@@ -4173,7 +4176,7 @@ const b = {
fireRecoilRivets() { fireRecoilRivets() {
// m.fireCDcycle = m.cycle + Math.floor((input.down ? 25 : 17) * b.fireCDscale); // cool down // m.fireCDcycle = m.cycle + Math.floor((input.down ? 25 : 17) * b.fireCDscale); // cool down
if (this.nextFireCycle + 1 < m.cycle) this.startingHoldCycle = m.cycle //reset if not constantly firing if (this.nextFireCycle + 1 < m.cycle) this.startingHoldCycle = m.cycle //reset if not constantly firing
const CD = Math.max(30 - 0.15 * (m.cycle - this.startingHoldCycle), 8) //CD scales with cycles fire is held down const CD = Math.max(25 - 0.14 * (m.cycle - this.startingHoldCycle), 6) //CD scales with cycles fire is held down
this.nextFireCycle = m.cycle + CD * b.fireCDscale //predict next fire cycle if the fire button is held down this.nextFireCycle = m.cycle + CD * b.fireCDscale //predict next fire cycle if the fire button is held down
m.fireCDcycle = m.cycle + Math.floor(CD * b.fireCDscale); // cool down m.fireCDcycle = m.cycle + Math.floor(CD * b.fireCDscale); // cool down
@@ -4219,7 +4222,7 @@ const b = {
//very complex recoil system //very complex recoil system
if (m.onGround) { if (m.onGround) {
if (input.down) { if (input.down) {
const KNOCK = 0.05 const KNOCK = 0.03
player.force.x -= KNOCK * Math.cos(m.angle) player.force.x -= KNOCK * Math.cos(m.angle)
player.force.y -= KNOCK * Math.sin(m.angle) //reduce knock back in vertical direction to stop super jumps player.force.y -= KNOCK * Math.sin(m.angle) //reduce knock back in vertical direction to stop super jumps
Matter.Body.setVelocity(player, { Matter.Body.setVelocity(player, {
@@ -4227,7 +4230,7 @@ const b = {
y: player.velocity.y * 0.4 y: player.velocity.y * 0.4
}); });
} else { } else {
const KNOCK = 0.15 const KNOCK = 0.1
player.force.x -= KNOCK * Math.cos(m.angle) player.force.x -= KNOCK * Math.cos(m.angle)
player.force.y -= KNOCK * Math.sin(m.angle) //reduce knock back in vertical direction to stop super jumps player.force.y -= KNOCK * Math.sin(m.angle) //reduce knock back in vertical direction to stop super jumps
Matter.Body.setVelocity(player, { Matter.Body.setVelocity(player, {
@@ -4236,8 +4239,8 @@ const b = {
}); });
} }
} else { } else {
if (Math.abs(player.velocity.x) < 12) player.force.x -= 0.1 * Math.cos(m.angle) if (Math.abs(player.velocity.x) < 12) player.force.x -= 0.06 * Math.cos(m.angle)
player.force.y -= 0.03 * Math.sin(m.angle) //reduce knock back in vertical direction to stop super jumps player.force.y -= 0.02 * Math.sin(m.angle) //reduce knock back in vertical direction to stop super jumps
} }
}, },
fireInstantFireRate() { fireInstantFireRate() {
@@ -5330,29 +5333,39 @@ const b = {
m.fireCDcycle = m.cycle + 50 * b.fireCDscale; // cool down m.fireCDcycle = m.cycle + 50 * b.fireCDscale; // cool down
// } // }
} else if (tech.extraHarpoons) { } else if (tech.extraHarpoons) {
const harpoons = tech.extraHarpoons + 1
const range = 450 * (tech.isFilament ? 1 + 0.005 * Math.min(110, this.ammo) : 1) const range = 450 * (tech.isFilament ? 1 + 0.005 * 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) { if (mob[i].alive && !mob[i].isBadTarget && !mob[i].shield && Matter.Query.ray(map, m.pos, mob[i].position).length === 0) {
const dot = Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, m.pos))) //the dot product of diff and dir will return how much over lap between the vectors const dot = Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, m.pos))) //the dot product of diff and dir will return how much over lap between the vectors
const dist = Vector.magnitude(Vector.sub(where, mob[i].position)) const dist = Vector.magnitude(Vector.sub(where, mob[i].position))
if (dist < range && dot > 0.7) { //target closest mob that player is looking at and isn't too close to target if (dist < range && dot > 0.7) { //lower dot product threshold for targeting then if you only have one harpoon //target closest mob that player is looking at and isn't too close to target
if (this.ammo > 0) { if (this.ammo > 0) {
this.ammo-- this.ammo--
b.harpoon(where, mob[i], m.angle, length, true, totalCycles) //Vector.angle(Vector.sub(where, mob[i].position), { x: 0, y: 0 }) b.harpoon(where, mob[i], m.angle, length, true, totalCycles) //Vector.angle(Vector.sub(where, mob[i].position), { x: 0, y: 0 })
targetCount++ targetCount++
if (targetCount > tech.extraHarpoons) break if (targetCount > harpoons) break
} }
} }
} }
} }
if (!targetCount) { //if more harpoons and no targets left
b.harpoon(where, null, m.angle, length, true, totalCycles) //if no target if (targetCount < harpoons) {
} else if (targetCount > 0) { const SPREAD = 0.1
this.ammo++ //make up for the ammo used up in fire() const num = harpoons - targetCount
simulation.updateGunHUD(); let dir = m.angle - SPREAD * (num - 1) / 2;
for (let i = 0; i < num; i++) {
if (this.ammo > 0) {
this.ammo--
b.harpoon(where, null, dir, length, true, totalCycles) //Vector.angle(Vector.sub(where, mob[i].position), { x: 0, y: 0 })
dir += SPREAD
}
}
} }
m.fireCDcycle = m.cycle + 90 //Infinity; // cool down this.ammo++ //make up for the ammo used up in fire()
simulation.updateGunHUD();
m.fireCDcycle = m.cycle + 90 // cool down
} else { } else {
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 && Matter.Query.ray(map, m.pos, mob[i].position).length === 0) { if (mob[i].alive && !mob[i].isBadTarget && Matter.Query.ray(map, m.pos, mob[i].position).length === 0) {

View File

@@ -15,14 +15,14 @@ const level = {
// localSettings.levelsClearedLastGame = 10 // localSettings.levelsClearedLastGame = 10
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
// simulation.isHorizontalFlipped = true // simulation.isHorizontalFlipped = true
// m.setField("plasma torch") // m.setField("negative mass")
// b.giveGuns("nail gun") // b.giveGuns("harpoon")
// tech.giveTech("rotary cannon") // tech.giveTech("rotary cannon")
// tech.giveTech("pneumatic actuator") // tech.giveTech("fragmentation")
// tech.giveTech("rivet gun") // tech.giveTech("rivet gun")
// for (let i = 0; i < 2; i++) tech.giveTech("refractory metal") // for (let i = 0; i < 2; i++) tech.giveTech("refractory metal")
// tech.giveTech("all-stars") // tech.giveTech("all-stars")
// for (let i = 0; i < 3; i++) tech.giveTech("overcharge") // for (let i = 0; i < 9; i++) tech.giveTech("reticulum")
// for (let i = 0; i < 2; i++) tech.giveTech("laser-bot") // for (let i = 0; i < 2; i++) tech.giveTech("laser-bot")
// tech.isCancelDuplication = true // tech.isCancelDuplication = true
@@ -2309,14 +2309,14 @@ const level = {
spawn.mapRect(5300, -275, 50, 175); spawn.mapRect(5300, -275, 50, 175);
spawn.mapRect(5050, -100, 50, 150); spawn.mapRect(5050, -100, 50, 150);
spawn.mapRect(4850, -275, 50, 175); spawn.mapRect(4850, -275, 50, 175);
level.difficultyIncrease(40) //30 is near max on hard //60 is near max on why // level.difficultyIncrease(40) //30 is near max on hard //60 is near max on why
spawn.starter(1900, -500, 200) //big boy // spawn.starter(1900, -500, 200) //big boy
// spawn.blockGroup(1900, -500) // spawn.blockGroup(1900, -500)
// for (let i = 0; i < 10; ++i) spawn.bodyRect(1600 + 5, -500, 30, 40); // for (let i = 0; i < 10; ++i) spawn.bodyRect(1600 + 5, -500, 30, 40);
// spawn.laserBombingBoss(1900, -500) // spawn.laserBombingBoss(1900, -500)
// for (let i = 0; i < 5; i++) spawn.focuser(1900, -500) // for (let i = 0; i < 5; i++) spawn.focuser(1900, -500)
// spawn.slashBoss(1900, -500) // spawn.slashBoss(1900, -500)
// spawn.slasher(1900, -500) spawn.sucker(1900, -500)
// spawn.shield(mob[mob.length - 1], 1900, -500, 1); // spawn.shield(mob[mob.length - 1], 1900, -500, 1);
// mob[mob.length - 1].isShielded = true // mob[mob.length - 1].isShielded = true
// spawn.growBossCulture(1200, -500) // spawn.growBossCulture(1200, -500)

View File

@@ -75,8 +75,10 @@ const m = {
Fx: 0.016, //run Force on ground // Fx: 0.016, //run Force on ground //
jumpForce: 0.42, jumpForce: 0.42,
setMovement() { setMovement() {
m.Fx = 0.016 * tech.squirrelFx * (tech.isFastTime ? 1.5 : 1); // m.Fx = 0.08 / mass * tech.squirrelFx
m.jumpForce = 0.42 * tech.squirrelJump * (tech.isFastTime ? 1.13 : 1) // m.FxAir = 0.4 / mass / mass
m.Fx = tech.baseFx * tech.squirrelFx * (tech.isFastTime ? 1.5 : 1) / player.mass //base player mass is 5
m.jumpForce = tech.baseJumpForce * tech.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 FxAir: 0.016, // 0.4/5/5 run Force in Air
yOff: 70, yOff: 70,
@@ -431,6 +433,7 @@ const m = {
} }
simulation.isTextLogOpen = true; simulation.isTextLogOpen = true;
simulation.makeTextLog("simulation.amplitude <span class='color-symbol'>=</span> null"); simulation.makeTextLog("simulation.amplitude <span class='color-symbol'>=</span> null");
tech.isImmortal = false //disable future immortality
}, 6 * swapPeriod); }, 6 * swapPeriod);
} else if (m.alive) { //normal death code here } else if (m.alive) { //normal death code here
m.alive = false; m.alive = false;
@@ -504,8 +507,8 @@ const m = {
if (tech.isBlockHarm && m.isHolding) dmg *= 0.15 if (tech.isBlockHarm && m.isHolding) dmg *= 0.15
if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0165, 0.66) if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0165, 0.66)
if (tech.isSlowFPS) dmg *= 0.8 if (tech.isSlowFPS) dmg *= 0.8
// if (tech.isPiezo) dmg *= 0.85
if (tech.isHarmReduce && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.4 if (tech.isHarmReduce && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.4
if (tech.isNeutronium && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.1
if (tech.isBotArmor) dmg *= 0.92 ** b.totalBots() if (tech.isBotArmor) dmg *= 0.92 ** b.totalBots()
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33; if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33;
if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.3 if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.3
@@ -945,6 +948,14 @@ const m = {
m.fieldThreshold = Math.cos(m.fieldArc * Math.PI) m.fieldThreshold = Math.cos(m.fieldArc * Math.PI)
}, },
setHoldDefaults() { setHoldDefaults() {
if (tech.isFreeWormHole && m.fieldUpgrades[m.fieldMode].name !== "wormhole") {
tech.removeTech("charmed baryon") //neutronum can get player stuck so it has to be removed if player has wrong field
powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
}
if (tech.isNeutronium && m.fieldUpgrades[m.fieldMode].name !== "negative mass") {
tech.removeTech("neutronium") //neutronum can get player stuck so it has to be removed if player has wrong field
powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
}
if (m.energy < m.maxEnergy) m.energy = m.maxEnergy; if (m.energy < m.maxEnergy) m.energy = m.maxEnergy;
m.fieldRegen = tech.energyRegen; //0.001 m.fieldRegen = tech.energyRegen; //0.001
m.fieldMeterColor = "#0cf" m.fieldMeterColor = "#0cf"
@@ -1038,11 +1049,17 @@ const m = {
m.holdingTarget = null; m.holdingTarget = null;
} }
}, },
// setMovement() {
// console.log('hi')
// m.Fx = tech.baseFx * tech.squirrelFx * (tech.isFastTime ? 1.5 : 1);
// m.jumpForce = tech.baseJumpForce * tech.squirrelJump * (tech.isFastTime ? 1.13 : 1)
// },
definePlayerMass(mass = m.defaultMass) { definePlayerMass(mass = m.defaultMass) {
Matter.Body.setMass(player, mass); Matter.Body.setMass(player, mass);
//reduce air and ground move forces //reduce air and ground move forces
m.Fx = 0.08 / mass * tech.squirrelFx //base player mass is 5 m.setMovement()
m.FxAir = 0.4 / mass / mass //base player mass is 5 // 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 //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)) 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; if (m.onGround && !m.crouch) m.yOffGoal = m.yOffWhen.stand;
@@ -2878,7 +2895,7 @@ const m = {
) { ) {
const sub = Vector.sub(simulation.mouseInGame, m.pos) const sub = Vector.sub(simulation.mouseInGame, m.pos)
const mag = Vector.magnitude(sub) const mag = Vector.magnitude(sub)
const drain = 0.06 + 0.006 * Math.sqrt(mag) const drain = tech.isFreeWormHole ? 0 : 0.06 + 0.006 * Math.sqrt(mag)
if (m.energy > drain && mag > 300) { if (m.energy > drain && mag > 300) {
m.energy -= drain m.energy -= drain
m.hole.isReady = false; m.hole.isReady = false;

View File

@@ -979,23 +979,23 @@ const powerUps = {
m.fieldCDcycle = m.cycle + 30; //disable field so you can't pick up the ejected tech m.fieldCDcycle = m.cycle + 30; //disable field so you can't pick up the ejected tech
} }
}, },
removeRandomTech() { // removeRandomTech() {
const have = [] //find which tech you have // const have = [] //find which tech you have
for (let i = 0; i < tech.tech.length; i++) { // for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count > 0) have.push(i) // if (tech.tech[i].count > 0) have.push(i)
} // }
if (have.length) { // if (have.length) {
const choose = have[Math.floor(Math.random() * have.length)] // const choose = have[Math.floor(Math.random() * have.length)]
simulation.makeTextLog(`<span class='color-var'>tech</span>.remove("<span class='color-text'>${tech.tech[choose].name}</span>")`) // simulation.makeTextLog(`<span class='color-var'>tech</span>.removeTech("<span class='color-text'>${tech.tech[choose].name}</span>")`)
const totalRemoved = tech.tech[choose].count // const totalRemoved = tech.tech[choose].count
tech.tech[choose].count = 0; // tech.tech[choose].count = 0;
tech.tech[choose].remove(); // remove a random tech form the list of tech you have // tech.tech[choose].remove(); // remove a random tech form the list of tech you have
tech.tech[choose].isLost = true // tech.tech[choose].isLost = true
simulation.updateTechHUD(); // simulation.updateTechHUD();
return totalRemoved // return totalRemoved
} // }
return 0 // return 0
}, // },
directSpawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) { directSpawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) {
let index = powerUp.length; let index = powerUp.length;
target = powerUps[target]; target = powerUps[target];

View File

@@ -1501,52 +1501,52 @@ const spawn = {
// } // }
// } // }
this.checkStatus(); this.checkStatus();
if (this.seePlayer.recall) { // if (this.seePlayer.recall) {
//eventHorizon waves in and out //eventHorizon waves in and out
const eventHorizon = this.eventHorizon * (0.93 + 0.17 * Math.sin(simulation.cycle * 0.011)) const eventHorizon = this.eventHorizon * (0.93 + 0.17 * Math.sin(simulation.cycle * 0.011))
//accelerate towards the player //accelerate towards the player
const forceMag = this.accelMag * this.mass; const forceMag = this.accelMag * this.mass;
const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x); const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x);
this.force.x += forceMag * Math.cos(angle); this.force.x += forceMag * Math.cos(angle);
this.force.y += forceMag * Math.sin(angle); this.force.y += forceMag * Math.sin(angle);
//draw darkness //draw darkness
ctx.beginPath(); ctx.beginPath();
ctx.arc(this.position.x, this.position.y, eventHorizon * 0.25, 0, 2 * Math.PI); ctx.arc(this.position.x, this.position.y, eventHorizon * 0.25, 0, 2 * Math.PI);
ctx.fillStyle = "rgba(0,0,0,0.9)"; ctx.fillStyle = "rgba(0,0,0,0.9)";
ctx.fill(); ctx.fill();
ctx.beginPath(); ctx.beginPath();
ctx.arc(this.position.x, this.position.y, eventHorizon * 0.55, 0, 2 * Math.PI); ctx.arc(this.position.x, this.position.y, eventHorizon * 0.55, 0, 2 * Math.PI);
ctx.fillStyle = "rgba(0,0,0,0.5)"; ctx.fillStyle = "rgba(0,0,0,0.5)";
ctx.fill(); ctx.fill();
ctx.beginPath(); ctx.beginPath();
ctx.arc(this.position.x, this.position.y, eventHorizon, 0, 2 * Math.PI); ctx.arc(this.position.x, this.position.y, eventHorizon, 0, 2 * Math.PI);
ctx.fillStyle = "rgba(0,0,0,0.1)"; ctx.fillStyle = "rgba(0,0,0,0.1)";
ctx.fill(); ctx.fill();
//when player is inside event horizon //when player is inside event horizon
if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) { if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) {
if (m.immuneCycle < m.cycle) { if (m.immuneCycle < m.cycle) {
if (m.energy > 0) m.energy -= 0.004 if (m.energy > 0) m.energy -= 0.004
if (m.energy < 0.1) m.damage(0.00015 * simulation.dmgScale); if (m.energy < 0.1) m.damage(0.00015 * simulation.dmgScale);
}
const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x);
player.force.x -= 0.00125 * player.mass * Math.cos(angle) * (m.onGround ? 1.8 : 1);
player.force.y -= 0.0001 * player.mass * Math.sin(angle);
//draw line to player
ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y);
ctx.lineTo(m.pos.x, m.pos.y);
ctx.lineWidth = Math.min(60, this.radius * 2);
ctx.strokeStyle = "rgba(0,0,0,0.5)";
ctx.stroke();
ctx.beginPath();
ctx.arc(m.pos.x, m.pos.y, 40, 0, 2 * Math.PI);
ctx.fillStyle = "rgba(0,0,0,0.3)";
ctx.fill();
} }
const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x);
player.force.x -= 0.00125 * player.mass * Math.cos(angle) * (m.onGround ? 1.8 : 1);
player.force.y -= 0.0001 * player.mass * Math.sin(angle);
//draw line to player
ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y);
ctx.lineTo(m.pos.x, m.pos.y);
ctx.lineWidth = Math.min(60, this.radius * 2);
ctx.strokeStyle = "rgba(0,0,0,0.5)";
ctx.stroke();
ctx.beginPath();
ctx.arc(m.pos.x, m.pos.y, 40, 0, 2 * Math.PI);
ctx.fillStyle = "rgba(0,0,0,0.3)";
ctx.fill();
} }
// }
} }
}, },
suckerBoss(x, y, radius = 25) { suckerBoss(x, y, radius = 25) {

View File

@@ -29,8 +29,18 @@
tech.totalCount = 0; tech.totalCount = 0;
simulation.updateTechHUD(); simulation.updateTechHUD();
}, },
removeTech(index) { removeTech(index = 'random') {
if (isNaN(index)) { //find index by name if (index === 'random') {
const have = [] //find which tech you have
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable) have.push(i)
}
if (have.length) {
index = have[Math.floor(Math.random() * have.length)]
} else {
return 0 //if none found don't remove any tech
}
} else if (isNaN(index)) { //find index by name
let found = false; let found = false;
for (let i = 0; i < tech.tech.length; i++) { for (let i = 0; i < tech.tech.length; i++) {
if (index === tech.tech[i].name) { if (index === tech.tech[i].name) {
@@ -39,11 +49,16 @@
break; break;
} }
} }
if (!found) return //if name not found don't remove any tech if (!found) return 0 //if name not found don't remove any tech
} }
tech.tech[index].remove(); const totalRemoved = tech.tech[index].count
simulation.makeTextLog(`<span class='color-var'>tech</span>.removeTech("<span class='color-text'>${tech.tech[index].name}</span>")`)
tech.tech[index].count = 0; tech.tech[index].count = 0;
tech.tech[index].remove();
simulation.updateTechHUD(); simulation.updateTechHUD();
tech.tech[index].isLost = true
simulation.updateTechHUD();
return totalRemoved //return the total number of tech removed
}, },
// onclick="tech.removeTechPaused(${i}, this)" //add this to tech elements in pause menu // onclick="tech.removeTechPaused(${i}, this)" //add this to tech elements in pause menu
// removeTechPaused(index, who) { // removeTechPaused(index, who) {
@@ -590,7 +605,7 @@
}, },
{ {
name: "squirrel-cage rotor", name: "squirrel-cage rotor",
description: "<strong>move</strong> and <strong>jump</strong> about <strong>30%</strong> faster<br>take <strong>5%</strong> more <strong class='color-harm'>harm</strong>", description: "<strong>move</strong> and <strong>jump</strong> <strong>30%</strong> faster<br>take <strong>5%</strong> more <strong class='color-harm'>harm</strong>",
maxCount: 9, maxCount: 9,
count: 0, count: 0,
frequency: 2, frequency: 2,
@@ -3338,7 +3353,7 @@
}, },
requires: "NOT EXPERIMENT MODE, at least 4 tech, a chance to duplicate power ups, not superdeterminism", requires: "NOT EXPERIMENT MODE, at least 4 tech, a chance to duplicate power ups, not superdeterminism",
effect: () => { effect: () => {
const removeTotal = powerUps.removeRandomTech() const removeTotal = tech.removeTech()
for (let i = 0; i < removeTotal + 1; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "tech"); for (let i = 0; i < removeTotal + 1; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "tech");
}, },
remove() {} remove() {}
@@ -3529,7 +3544,7 @@
if (tech.isDeterminism) { if (tech.isDeterminism) {
tech.isDeterminism = false; tech.isDeterminism = false;
for (let i = 0; i < 5; i++) { for (let i = 0; i < 5; i++) {
const numberRemoved = powerUps.removeRandomTech() const numberRemoved = tech.removeTech()
if (numberRemoved === 0) { //if the player didn't remove a power up then remove 1 tech for the map if (numberRemoved === 0) { //if the player didn't remove a power up then remove 1 tech for the map
for (let i = 0; i < powerUp.length; i++) { for (let i = 0; i < powerUp.length; i++) {
if (powerUp[i].name === "tech") { if (powerUp[i].name === "tech") {
@@ -3562,7 +3577,9 @@
}, },
remove() { remove() {
tech.isSuperDeterminism = false; tech.isSuperDeterminism = false;
for (let i = 0; i < 5; i++) powerUps.removeRandomTech() if (this.count) {
for (let i = 0; i < 5; i++) tech.removeTech()
}
} }
}, },
{ {
@@ -5207,7 +5224,7 @@
}, },
{ {
name: "reticulum", name: "reticulum",
description: "fire <strong>+1</strong> harpoon<br>when there are multiple targets in range", description: "fire <strong>+1</strong> <strong>harpoon</strong>, but <strong class='color-f'>energy</strong> cost<br>to <strong>retract</strong> also increases",
isGunTech: true, isGunTech: true,
maxCount: 9, maxCount: 9,
count: 0, count: 0,
@@ -5760,22 +5777,31 @@
} }
}, },
{ {
name: "degenerate matter", name: "neutronium",
description: "reduce <strong class='color-harm'>harm</strong> by <strong>60%</strong> while your <strong class='color-f'>field</strong> is active", description: `reduce <strong class='color-harm'>harm</strong> by <strong>90%</strong> while your <strong class='color-f'>field</strong> is active<br><strong>move</strong> and <strong>jump</strong> <strong>33%</strong> <strong>slower</strong>`,
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return (m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "negative mass") && !tech.isEnergyHealth return m.fieldUpgrades[m.fieldMode].name === "negative mass" && !tech.isEnergyHealth && !tech.isFreeWormHole
}, },
requires: "field: perfect, negative mass, pilot wave, plasma, not mass-energy", requires: "wormhole or negative mass, not mass-energy, charmed baryon",
effect() { effect() {
tech.isHarmReduce = true tech.isNeutronium = true
tech.baseFx *= 0.66
tech.baseJumpForce *= 0.66
m.setMovement()
}, },
//also removed in m.setHoldDefaults() if player switches into a bad field
remove() { remove() {
tech.isHarmReduce = false; tech.isNeutronium = false
if (!tech.isFreeWormHole) {
tech.baseFx = 0.08
tech.baseJumpForce = 10.5
m.setMovement()
}
} }
}, },
{ {
@@ -6057,6 +6083,25 @@
// tech.isPlasmaRange = 1; // tech.isPlasmaRange = 1;
// } // }
// }, // },
{
name: "degenerate matter",
description: "reduce <strong class='color-harm'>harm</strong> by <strong>60%</strong> while your <strong class='color-f'>field</strong> is active",
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return (m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && !tech.isEnergyHealth
},
requires: "perfect diamagnetism, pilot wave, plasma, not mass-energy",
effect() {
tech.isHarmReduce = true
},
remove() {
tech.isHarmReduce = false;
}
},
{ {
name: "tokamak", name: "tokamak",
description: "throwing a <strong class='color-block'>block</strong> converts it into <strong class='color-f'>energy</strong><br>and a pulsed fusion <strong class='color-e'>explosion</strong>", description: "throwing a <strong class='color-block'>block</strong> converts it into <strong class='color-f'>energy</strong><br>and a pulsed fusion <strong class='color-e'>explosion</strong>",
@@ -6590,6 +6635,34 @@
} }
} }
}, },
{
name: "charmed baryons",
description: `<strong>wormhole</strong> field uses no <strong class='color-f'>energy</strong><br><strong>move</strong> and <strong>jump</strong> <strong>33%</strong> <strong>slower</strong>`,
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "wormhole" && !tech.isNeutronium
},
requires: "wormhole, not neutronium",
effect() {
tech.isFreeWormHole = true
tech.baseFx *= 0.66
tech.baseJumpForce *= 0.66
m.setMovement()
},
//also removed in m.setHoldDefaults() if player switches into a bad field
remove() {
tech.isFreeWormHole = false
if (!tech.isNeutronium) {
tech.baseFx = 0.08
tech.baseJumpForce = 10.5
m.setMovement()
}
}
},
//************************************************** //**************************************************
//************************************************** experimental //************************************************** experimental
//************************************************** modes //************************************************** modes
@@ -7324,30 +7397,30 @@
}, },
remove() {} remove() {}
}, },
{ // {
name: "inverted mouse", // name: "inverted mouse",
description: "your mouse is scrambled<br>it's fine, just rotate it 90 degrees", // description: "your mouse is scrambled<br>it's fine, just rotate it 90 degrees",
maxCount: 1, // maxCount: 1,
count: 0, // count: 0,
frequency: 0, // frequency: 0,
isExperimentHide: true, // isExperimentHide: true,
isNonRefundable: true, // isNonRefundable: true,
isJunk: true, // isJunk: true,
allowed() { // allowed() {
return !m.isShipMode // return !m.isShipMode
}, // },
requires: "not ship", // requires: "not ship",
effect() { // effect() {
document.body.addEventListener("mousemove", (e) => { // document.body.addEventListener("mousemove", (e) => {
const ratio = window.innerWidth / window.innerHeight // const ratio = window.innerWidth / window.innerHeight
simulation.mouse.x = e.clientY * ratio // simulation.mouse.x = e.clientY * ratio
simulation.mouse.y = e.clientX / ratio; // simulation.mouse.y = e.clientX / ratio;
}); // });
}, // },
remove() { // remove() {
// m.look = m.lookDefault // // m.look = m.lookDefault
} // }
}, // },
{ {
name: "Fourier analysis", name: "Fourier analysis",
description: "your aiming is now controlled by this equation:<br>2sin(0.0133t) + sin(0.013t) + 0.5sin(0.031t)+ 0.33sin(0.03t)", description: "your aiming is now controlled by this equation:<br>2sin(0.0133t) + sin(0.013t) + 0.5sin(0.031t)+ 0.33sin(0.03t)",
@@ -7514,7 +7587,7 @@
setInterval(() => { setInterval(() => {
let score = Math.ceil(1000 * Math.random() * Math.random() * Math.random() * Math.random() * Math.random()) let score = Math.ceil(1000 * Math.random() * Math.random() * Math.random() * Math.random() * Math.random())
simulation.makeTextLog(`simulation.score <span class='color-symbol'>=</span> ${score.toFixed(0)}`); simulation.makeTextLog(`simulation.score <span class='color-symbol'>=</span> ${score.toFixed(0)}`);
}, 1000); //every 10 seconds }, 10000); //every 10 seconds
}, },
remove() {} remove() {}
}, },
@@ -8645,5 +8718,9 @@
isRodAreaDamage: null, isRodAreaDamage: null,
isForeverDrones: null, isForeverDrones: null,
isMoreMobs: null, isMoreMobs: null,
nailRecoil: null nailRecoil: null,
baseJumpForce: null,
baseFx: null,
isNeutronium: null,
isFreeWormHole: null
} }

View File

@@ -1,14 +1,20 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
tech: neutronium - 90% harm reduce while field is active, 33% slower move speed
(requires negative mass field)
tech: charmed baryon - 0 cost wormhole, 33% slower move speed
harpoon tech: reticulum now always fires extra harpoons even if there are no targets
tech: rotary cannon - nail gun (and rivet gun) have increased fire rate, muzzle speed, recoil, and accuracy tech.removeTech() method has been improved
experiment -parthenocarpy- spawn about 50% more mobs bug fixes
******************************************************** TODO ******************************************************** ******************************************************** TODO ********************************************************
minigun: tech for nail gun - Its ramp-up time must not be removable. Recoil should be intense, enough that the player cannot walk forward quickly while using it. bug - death while paused crashes game?
nail gun gains: accuracy, bullet speed, huge recoil, fire rate
alternative to pnumatic that stops ramp up tech: aerodynamic heating - railgun rods super heat the air around it doing AoE damage
maybe try to also apply to rivets?
tech rocket jump - jumping produces an explosion at your feet that lets you jump extra high, but does some damage
require electric reactive armor?
animate going to next level? animate going to next level?
door fills in with color that climbs up vertically through the door graphic the longer you stand on door door fills in with color that climbs up vertically through the door graphic the longer you stand on door
@@ -17,14 +23,6 @@ animate going to next level?
Plasma Burner: upgrade for plasma torch, basically just a jet engine. does high damage, but short range, mostly for player movement. Plasma Burner: upgrade for plasma torch, basically just a jet engine. does high damage, but short range, mostly for player movement.
maybe reduce gravity to really low then apply a vector away from mouse direction maybe reduce gravity to really low then apply a vector away from mouse direction
no passive energy regen, but regen energy after doing damage
tech or just default?
modify conservation of energy tech
Tech: Schrödingers cat (or superposition)
Requires: Metamaterial Cloaking and Dazzler
Upon decloaking, all mobs nearby (same range as Dazzler) are irradiated. Increase energy drain by 15%.
game idea - auto battler with n-gon mob AI and tech game idea - auto battler with n-gon mob AI and tech
name: auto-gon name: auto-gon
you build a group of mobs and bosses from n-gon you build a group of mobs and bosses from n-gon
@@ -32,30 +30,14 @@ game idea - auto battler with n-gon mob AI and tech
similar research and tech system to n-gon similar research and tech system to n-gon
some mobs can fire player weapons some mobs can fire player weapons
junk tech negative air friction on player
remove foam gun get 2 foam bots and upgrade
need a new way of checking if have gun, that doesn't care if it's not active gun
apply to missile gun?
and 10 drone tech
tech rocket jump - jumping produces an explosion at your feet that lets you jump extra high, but does some damage
require electric reactive armor?
harpoon tech: dash - press down and fire to go immune to harm for 1 second and dash forward with your harpoon acting like a lance
after you fire harpoon replace it's this.do() with just being in front of player
harpoon grappling hook - basic effect is working, but needs work before it becomes fun harpoon grappling hook - basic effect is working, but needs work before it becomes fun
tech: aerodynamic heating - railgun rods super heat the air around it doing AoE damage
tech: relativistic jets: tech: relativistic jets:
small particles that shot out from front and back poles and end up in a wide variety of spirals small particles that shot out from front and back poles and end up in a wide variety of spirals
slow trickle when charging and several more when firing slow trickle when charging and several more when firing
Tech: Make player smol Tech: Make player smol
adapt the cloaking graphics to make a flashlight cone visual effect adapt the cloaking graphics to make a flashlight cone visual effect
put code in level.do? put code in level.do?
@@ -64,10 +46,6 @@ be nice if block throwing had a projected path
JUNK tech: planetesimals game inside n-gon JUNK tech: planetesimals game inside n-gon
https://codepen.io/lilgreenland/pen/jrMvaB?editors=0010 https://codepen.io/lilgreenland/pen/jrMvaB?editors=0010
disable zoom progress when paused
"Interstellar Disturbance": Cosmic String applies to mobs who cross the wormhole's path, even after initial wormholing, but at reduced damage and stun time.
on mouse down wormhole shows a possible wormhole on mouse down wormhole shows a possible wormhole
on mouse up the wormhole becomes real on mouse up the wormhole becomes real
make the player get a buff after using wormhole make the player get a buff after using wormhole