time dilation rework

time dilation field rework
  2x energy regen, but pausing time now uses much more energy
  you are immune to harm while time is paused
    but this stops energy regen
    tech timelike is removed

eternalism gives 50% damage instead of ammo
  also disables the pause button, and other pause effects

tech: polyurethane foam - super balls turn into foam after hitting a mob
supertemporal renamed autocannon
  now gives +1 ball, and has a shorter delay between balls

harpoon and grapple no longer lose ammo when you run out of energy
  they just trigger a 2 second fire CD
slashBoss doesn't slash as often at higher difficulty levels
field descriptions rewritten

bug fixes
This commit is contained in:
landgreen
2022-05-01 05:56:08 -07:00
parent 38d356e592
commit 936741a4e7
9 changed files with 624 additions and 545 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -1437,7 +1437,14 @@ const b = {
returnToPlayer() {
if (Vector.magnitude(Vector.sub(this.position, m.pos)) < returnRadius) { //near player
this.endCycle = 0;
if (m.cycle + 25 * b.fireCDscale < m.fireCDcycle) m.fireCDcycle = m.cycle + 35 * b.fireCDscale //lower cd to 25 if it is above 25
if (m.energy < 0.05) {
m.fireCDcycle = m.cycle + 120; //fire cooldown
} else if (m.cycle + 25 * b.fireCDscale < m.fireCDcycle) {
m.fireCDcycle = m.cycle + 35 * b.fireCDscale //lower cd to 25 if it is above 25
}
if (m.energy < 0.05) this.dropCaughtPowerUp()
//recoil on catching
const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (input.down ? 0.00015 : 0.0003))
player.force.x += momentum.x
@@ -1488,31 +1495,31 @@ const b = {
this.grabPowerUp()
if (this.endCycle < simulation.cycle + 1) { //if at end of lifespan, but player is holding down fire, force retraction
this.endCycle = simulation.cycle + 60
m.fireCDcycle = m.cycle + 20 // cool down
m.fireCDcycle = m.cycle + 120 // cool down
this.do = this.returnToPlayer
Matter.Body.setDensity(this, 0.0005); //reduce density on return
if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1)
this.collisionFilter.mask = cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body
}
} else {
//snap rope if not enough energy
if (m.energy < 0.05) {
const returnForce = Vector.mult(Vector.normalise(Vector.sub(this.position, m.pos)), 3 * this.thrustMag * this.mass)
this.force.x -= returnForce.x
this.force.y -= returnForce.y
this.frictionAir = 0.002
this.do = () => {
if (this.speed < 20) this.force.y += 0.0005 * this.mass;
}
this.dropCaughtPowerUp()
} else {
//if not enough energy
if (m.energy < 0.05) this.dropCaughtPowerUp()
// const returnForce = Vector.mult(Vector.normalise(Vector.sub(this.position, m.pos)), 3 * this.thrustMag * this.mass)
// this.force.x -= returnForce.x
// this.force.y -= returnForce.y
// this.frictionAir = 0.002
// this.do = () => {
// if (this.speed < 20) this.force.y += 0.0005 * this.mass;
// }
// } else {
//return to player
this.do = this.returnToPlayer
this.endCycle = simulation.cycle + 60
Matter.Body.setDensity(this, 0.0005); //reduce density on return
if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1)
this.collisionFilter.mask = cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body
}
// }
}
//grappling hook
if (input.fire && Matter.Query.collides(this, map).length) {
@@ -1562,12 +1569,13 @@ const b = {
m.immuneCycle = m.cycle + 10;
if (m.energy > 0.001) {
m.energy -= 0.001
} else {
} else { //out of energy
Matter.Sleeping.set(this, false)
this.collisionFilter.category = 0
this.collisionFilter.mask = 0
this.do = this.returnToPlayer
this.endCycle = simulation.cycle + 60
m.fireCDcycle = m.cycle + 120; //fire cooldown
}
}
} else {
@@ -1697,7 +1705,12 @@ const b = {
returnToPlayer() {
if (Vector.magnitude(Vector.sub(this.position, m.pos)) < returnRadius) { //near player
this.endCycle = 0;
if (m.cycle + 25 * b.fireCDscale < m.fireCDcycle) m.fireCDcycle = m.cycle + 35 * b.fireCDscale //lower cd to 25 if it is above 25
if (m.energy < 0.05) {
m.fireCDcycle = m.cycle + 120; //fire cooldown
} else if (m.cycle + 25 * b.fireCDscale < m.fireCDcycle) {
m.fireCDcycle = m.cycle + 35 * b.fireCDscale //lower cd to 25 if it is above 25
}
//recoil on catching
const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (input.down ? 0.00015 : 0.0003))
player.force.x += momentum.x
@@ -1749,24 +1762,13 @@ const b = {
this.cycle++
if (isReturn || target) {
if (isReturn) {
if (this.cycle > totalCycles) {
//snap rope if not enough energy
if (m.energy < 0.05) {
const returnForce = Vector.mult(Vector.normalise(Vector.sub(this.position, m.pos)), 3 * this.thrustMag * this.mass)
this.force.x -= returnForce.x
this.force.y -= returnForce.y
this.frictionAir = 0.002
this.do = () => {
if (this.speed < 20) this.force.y += 0.0005 * this.mass;
}
this.dropCaughtPowerUp()
} else {
//return to player
if (this.cycle > totalCycles || m.energy < 0.05) { //return to player
this.do = this.returnToPlayer
Matter.Body.setDensity(this, 0.0005); //reduce density on return
if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1)
this.collisionFilter.mask = cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body
}
Matter.Sleeping.set(this, false)
this.collisionFilter.category = 0
this.collisionFilter.mask = 0
this.endCycle = simulation.cycle + 60
} else {
this.grabPowerUp()
}
@@ -5307,6 +5309,9 @@ const b = {
have: false,
// num: 5,
do() {},
foamBall() {
},
fireOne() {
const SPEED = input.down ? 43 : 36
m.fireCDcycle = m.cycle + Math.floor((input.down ? 23 : 15) * b.fireCDscale); // cool down
@@ -5332,6 +5337,15 @@ const b = {
b.explosion(this.position, this.mass * 280); //makes bullet do explosive damage at end
this.endCycle = 0
}
if (tech.isFoamBall) {
const radius = 5 + 8 * Math.random()
const velocity = { x: Math.max(2, 10 - radius * 0.25), y: 0 }
for (let i = 0, len = 6 * this.mass; i < len; i++) {
b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
}
this.endCycle = 0
// this.mass = 0 //prevent damage
}
};
},
fireMulti() {
@@ -5362,26 +5376,35 @@ const b = {
b.explosion(this.position, this.mass * 320 + 70 * Math.random()); //makes bullet do explosive damage at end
this.endCycle = 0
}
if (tech.isFoamBall) {
const radius = 5 + 8 * Math.random()
const velocity = { x: Math.max(2, 10 - radius * 0.25), y: 0 }
for (let i = 0, len = 6 * this.mass; i < len; i++) {
b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
}
this.endCycle = 0
// this.mass = 0 //prevent damage
}
};
dir += SPREAD;
}
},
fireQueue() {
// const dir = m.angle
// const x = m.pos.x
// const y = m.pos.y
const SPEED = input.down ? 43 : 36
const dir = m.angle
const x = m.pos.x
const y = m.pos.y
const num = 3 + Math.floor(tech.extraSuperBalls * Math.random())
const num = 1 + 3 + Math.floor(tech.extraSuperBalls * Math.random()) //1 extra
const delay = Math.floor((input.down ? 18 : 12) * b.fireCDscale)
m.fireCDcycle = m.cycle + delay; // cool down
const fireBall = () => {
const me = bullet.length;
bullet[me] = Bodies.polygon(x, y, 12, 11 * tech.bulletSize, b.fireAttributes(dir, false));
bullet[me] = Bodies.polygon(m.pos.x, m.pos.y, 12, 11 * tech.bulletSize, b.fireAttributes(m.angle, false));
Composite.add(engine.world, bullet[me]); //add bullet to world
Matter.Body.setVelocity(bullet[me], {
x: SPEED * Math.cos(dir),
y: SPEED * Math.sin(dir)
x: SPEED * Math.cos(m.angle),
y: SPEED * Math.sin(m.angle)
});
bullet[me].endCycle = simulation.cycle + Math.floor(330 * tech.isBulletsLastLonger);
bullet[me].minDmgSpeed = 0;
@@ -5395,16 +5418,28 @@ const b = {
b.explosion(this.position, this.mass * 320 + 70 * Math.random()); //makes bullet do explosive damage at end
this.endCycle = 0
}
if (tech.isFoamBall) {
const radius = 5 + 8 * Math.random()
const velocity = { x: Math.max(2, 10 - radius * 0.25), y: 0 }
for (let i = 0, len = 6 * this.mass; i < len; i++) {
b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
}
this.endCycle = 0
// this.mass = 0 //prevent damage
}
};
m.fireCDcycle = m.cycle + delay; // cool down
}
function cycle() {
if (simulation.paused || m.isBodiesAsleep) { requestAnimationFrame(cycle) } else {
// if (simulation.paused || m.isBodiesAsleep) {
// requestAnimationFrame(cycle)
// } else {
count++
if (count % 2) fireBall()
if (count < num * 2 && m.alive) requestAnimationFrame(cycle);
}
// if (count % 2)
fireBall()
if (count < num && m.alive) requestAnimationFrame(cycle);
// }
}
let count = 0
requestAnimationFrame(cycle);
@@ -5449,6 +5484,7 @@ const b = {
},
do() {},
do360Longitudinal() {
if (!m.isBodiesAsleep) {
ctx.strokeStyle = "rgba(0,0,0,0.6)" //"000";
ctx.lineWidth = 2 * tech.wavePacketDamage
ctx.beginPath();
@@ -5522,6 +5558,7 @@ const b = {
}
}
ctx.stroke();
}
},
fire360Longitudinal() {
m.fireCDcycle = m.cycle + Math.floor((input.down ? 3 : 8) * b.fireCDscale); // cool down
@@ -5533,6 +5570,7 @@ const b = {
})
},
doLongitudinal() {
if (!m.isBodiesAsleep) {
ctx.strokeStyle = "rgba(0,0,0,0.6)" //"000";
ctx.lineWidth = 2 * tech.wavePacketDamage
ctx.beginPath();
@@ -5614,6 +5652,7 @@ const b = {
}
}
ctx.stroke();
}
},
fireLongitudinal() {
m.fireCDcycle = m.cycle + Math.floor((input.down ? 3 : 8) * b.fireCDscale); // cool down

View File

@@ -904,7 +904,7 @@ window.addEventListener("keydown", function(event) {
// level.levelAnnounce();
document.body.style.cursor = "none";
requestAnimationFrame(cycle);
} else {
} else if (!tech.isNoDraftPause) {
simulation.paused = true;
build.pauseGrid()
document.body.style.cursor = "auto";

View File

@@ -16,12 +16,12 @@ const level = {
start() {
if (level.levelsCleared === 0) { //this code only runs on the first level
// simulation.isHorizontalFlipped = true
// m.setField("standing wave")
// b.giveGuns("laser")
// tech.giveTech("scrap-bot manufacturing")
// m.setField("time dilation")
// b.giveGuns("matter wave")
// tech.giveTech("phonon")
// tech.giveTech("eternalism")
// tech.giveTech("options exchange")
// tech.giveTech("ICBM")
// tech.giveTech("isotropic radiator")
// tech.giveTech("polyurethane balls")
// tech.giveTech("grappling hook")
// tech.giveTech("paradigm shift")
// for (let i = 0; i < 1; i++) powerUps.directSpawn(450, -50, "tech");
@@ -37,7 +37,7 @@ const level = {
// m.immuneCycle = Infinity //you can't take damage
// level.difficultyIncrease(15) //30 is near max on hard //60 is near max on why
// simulation.enableConstructMode() //used to build maps in testing mode
// level.testChamber();
// level.labs();
// level.testing(); //not in rotation, used for testing
if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************
// powerUps.research.changeRerolls(3000)
@@ -972,19 +972,19 @@ const level = {
}
}
//delete any overlapping mobs
const mobsHits = Matter.Query.collides(this, mob)
for (let i = 0; i < mobsHits.length; i++) {
if (mobsHits[i].bodyB !== this && mobsHits[i].bodyB !== m.holdingTarget) { //dont' delete yourself <----- bug here maybe...
Matter.Composite.remove(engine.world, mobsHits[i].bodyB);
mobsHits[i].bodyB.isRemoveMeNow = true
for (let i = 1; i < mob.length; i++) { //find which index in body array it is and remove from array
if (mob[i].isRemoveMeNow) {
mob.splice(i, 1);
break
}
}
}
}
// const mobsHits = Matter.Query.collides(this, mob)
// for (let i = 0; i < mobsHits.length; i++) {
// if (mobsHits[i].bodyB !== this && mobsHits[i].bodyB !== m.holdingTarget) { //dont' delete yourself <----- bug here maybe...
// Matter.Composite.remove(engine.world, mobsHits[i].bodyB);
// mobsHits[i].bodyB.isRemoveMeNow = true
// for (let i = 1; i < mob.length; i++) { //find which index in body array it is and remove from array
// if (mob[i].isRemoveMeNow) {
// mob.splice(i, 1);
// break
// }
// }
// }
// }
}
}
}
@@ -1444,15 +1444,15 @@ const level = {
spawn.bodyRect(x + 1460, y - 900, 30, 150); //entrance door
spawn.mapRect(x + 1600, y - 350, 500, 100); //toggle shelf
const toggle = level.toggle(x + 1650, y - 350, true) //(x,y,isOn,isLockOn = true/false)
let hazard
let hazard1
if (Math.random() > 0.5) {
spawn.mapRect(x + 550, y - 750, 1500, 50); //entrance shelf
hazard = level.hazard(x + 850, y - 920, 600, 10, 0.4) //laser
hazard1 = level.hazard(x + 850, y - 920, 600, 10, 0.4) //laser
spawn.mapRect(x + 860, y - 925, 10, 20); //laser nose
spawn.mapRect(x + 660, y - 975, 200, 120); //laser body
} else {
spawn.mapRect(x + 1350, y - 750, 700, 50); //entrance shelf
hazard = level.hazard(x + 1040, y - 660, 1000, 10, 0.4) //laser
hazard1 = level.hazard(x + 1040, y - 660, 1000, 10, 0.4) //laser
spawn.mapRect(x + 1050, y - 665, 10, 20); //laser nose
spawn.mapRect(x + 650, y - 705, 400, 100); //laser body
}
@@ -1476,14 +1476,17 @@ const level = {
doCustomTopLayer.push(
() => {
toggle.query();
hazard.isOn = toggle.isOn
hazard1.isOn = toggle.isOn
hazard2.isOn = toggle.isOn
hazard3.isOn = toggle.isOn
hazard4.isOn = toggle.isOn
hazard.opticalQuery();
if ((simulation.cycle % 120) > 60) {
hazard1.opticalQuery();
hazard2.opticalQuery();
} else {
hazard3.opticalQuery();
hazard4.opticalQuery();
}
// if (!isSpawnedMobs && !toggle.isOn) {
// isSpawnedMobs = true
// spawn.randomMob(x + 150, y + -1100, mobSpawnChance);
@@ -2173,15 +2176,22 @@ const level = {
// },
(x = offset.x, y = offset.y) => {
const toggle = level.toggle(x + 950, y + 0, false, true) // toggle(x, y, isOn = false, isLockOn = false) {
toggle.isAddedElements = false
// const toggle = level.toggle(x + 950, y + 0, false, true) // toggle(x, y, isOn = false, isLockOn = false) {
// toggle.isAddedElements = false
const button = level.button(x + 950, y + 0)
button.isUp = true
spawn.mapVertex(x + 5, y + -1318, "0 0 0 -250 125 -250"); //left ledges
spawn.mapVertex(x + 1995, y + -1318, "0 0 0 -250 -125 -250"); // right ledges
doCustomTopLayer.push(
() => {
toggle.query();
if (toggle.isOn && !toggle.isAddedElements) { //this code runs once after the toggle is triggered
toggle.isAddedElements = true //only do this once
button.draw();
if (button.isUp) {
button.query();
if (!button.isUp) {
// toggle.isAddedElements = true //only do this once
addMapToLevelInProgress = (who) => { //adds new map elements to the level while the level is already running //don't forget to run simulation.draw.setPaths() after you all the the elements so they show up visually
who.collisionFilter.category = cat.map;
who.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet;
@@ -2250,12 +2260,18 @@ const level = {
spawn.secondaryBossChance(x + 1250, y + -2300)
}
}
// toggle.query();
// if (toggle.isOn && !toggle.isAddedElements) { //this code runs once after the toggle is triggered
// }
}
)
},
(x = offset.x, y = offset.y) => {
const toggle = level.toggle(x + 950, y + 0, false, true) // toggle(x, y, isOn = false, isLockOn = false) {
toggle.isAddedElements = false
// const toggle = level.toggle(x + 950, y + 0, false, true) // toggle(x, y, isOn = false, isLockOn = false) {
// toggle.isAddedElements = false
const button = level.button(x + 950, y + 0)
button.isUp = true
//left ledges
spawn.mapVertex(x + 5, y + -1868, "0 0 0 -250 125 -250");
spawn.mapVertex(x + 5, y + -1318, "0 0 0 -250 125 -250"); //door
@@ -2267,9 +2283,10 @@ const level = {
doCustomTopLayer.push(
() => {
toggle.query();
if (toggle.isOn && !toggle.isAddedElements) { //this code runs once after the toggle is triggered
toggle.isAddedElements = true //only do this once
button.draw();
if (button.isUp) {
button.query();
if (!button.isUp) {
addMapToLevelInProgress = (who) => { //adds new map elements to the level while the level is already running //don't forget to run simulation.draw.setPaths() after you all the the elements so they show up visually
who.collisionFilter.category = cat.map;
who.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet;
@@ -2318,6 +2335,7 @@ const level = {
simulation.draw.setPaths() //update map graphics
}
}
}
)
},
// (x = offset.x, y = offset.y) => {
@@ -2654,7 +2672,7 @@ const level = {
// spawn.shieldingBoss(1700, -500)
// for (let i = 0; i < 10; ++i) spawn.bodyRect(1600 + 5, -500, 30, 40);
for (let i = 0; i < 1; i++) spawn.stabber(1900, -500)
for (let i = 0; i < 4; i++) spawn.starter(1900, -500)
// spawn.pulsar(1900, -500)
// spawn.shield(mob[mob.length - 1], 1900, -500, 1);
// mob[mob.length - 1].isShielded = true

View File

@@ -522,7 +522,7 @@ const m = {
if (tech.isAddBlockMass && m.isHolding) dmg *= 0.15
if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0165, 0.66)
if (tech.isSlowFPS) dmg *= 0.8
if (tech.isHarmReduce && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.34
if (tech.isHarmReduce && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.25
if (tech.isNeutronium && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.1
if (tech.isBotArmor) dmg *= 0.94 ** b.totalBots()
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33;
@@ -1501,8 +1501,9 @@ const m = {
},
fieldUpgrades: [{
name: "field emitter",
description: "regen <strong>6</strong> <strong class='color-f'>energy</strong> per second<br>use it to <strong>deflect</strong> mobs and <strong>throw</strong> <strong class='color-block'>blocks</strong><br><strong class='color-f'>energy</strong> regen disabled if immune to <strong class='color-harm'>harm</strong>",
// description: "use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs,<br><strong>grab</strong> power ups, and <strong>throw</strong> <strong class='color-block'>blocks</strong><br>regen <strong>6</strong> <strong class='color-f'>energy</strong>/s, when not immune to <strong class='color-harm'>harm</strong>",
//<br><strong class='color-f'>energy</strong> regen disabled if immune to <strong class='color-harm'>harm</strong>
description: "use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br>store up to <strong>100</strong> <strong class='color-f'>energy</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong>/second",
// description: "use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs,<br><strong>grab</strong> power ups, and <strong>throw</strong> <strong class='color-block'>blocks</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong>/s, when not immune to <strong class='color-harm'>harm</strong>",
effect: () => {
m.hold = function() {
if (m.isHolding) {
@@ -1527,7 +1528,8 @@ const m = {
},
{
name: "standing wave",
description: "<strong>3</strong> oscillating <strong>shields</strong> are permanently active<br><strong>deflecting</strong> protects you in every <strong>direction</strong><br>increase your <strong>max</strong> <strong class='color-f'>energy</strong> by <strong>60</strong>", //drains <strong class='color-f'>energy</strong> //<strong>deflecting</strong> has <strong>50%</strong> less <strong>recoil</strong>
//<strong>deflecting</strong> protects you in every <strong>direction</strong>
description: "<strong>3</strong> oscillating <strong>shields</strong> are permanently active<br>increase your <strong>max</strong> <strong class='color-f'>energy</strong> by <strong>60</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong>/second", //drains <strong class='color-f'>energy</strong> //<strong>deflecting</strong> has <strong>50%</strong> less <strong>recoil</strong>
drainCD: 0,
effect: () => {
m.fieldBlockCD = 0;
@@ -1540,7 +1542,7 @@ const m = {
const fieldRange2 = (0.68 + 0.37 * Math.sin(m.cycle / 37)) * m.fieldRange * m.harmonicRadius
const fieldRange3 = (0.7 + 0.35 * Math.sin(m.cycle / 47)) * m.fieldRange * m.harmonicRadius
const netfieldRange = Math.max(fieldRange1, fieldRange2, fieldRange3)
ctx.fillStyle = "rgba(110,170,200," + Math.min(0.65, (0.04 + m.energy * (0.11 + 0.13 * Math.random()))) + ")";
ctx.fillStyle = "rgba(110,170,200," + Math.min(0.6, (0.04 + m.energy * (0.1 + 0.11 * Math.random()))) + ")";
ctx.beginPath();
ctx.arc(m.pos.x, m.pos.y, fieldRange1, 0, 2 * Math.PI);
ctx.fill();
@@ -1571,7 +1573,7 @@ const m = {
const radius = m.fieldRange * m.harmonicRadius
ctx.lineWidth = 1;
ctx.strokeStyle = "rgba(110,170,200,0.8)"
ctx.fillStyle = "rgba(110,170,200," + Math.min(0.65, m.energy * (0.13 + 0.1 * Math.random()) * (3 / tech.harmonics)) + ")";
ctx.fillStyle = "rgba(110,170,200," + Math.min(0.6, m.energy * (0.11 + 0.1 * Math.random()) * (3 / tech.harmonics)) + ")";
// ctx.fillStyle = "rgba(110,170,200," + Math.min(0.7, m.energy * (0.22 - 0.01 * tech.harmonics) * (0.5 + 0.5 * Math.random())) + ")";
for (let i = 0; i < tech.harmonics; i++) {
ctx.beginPath();
@@ -1628,7 +1630,8 @@ const m = {
},
{
name: "perfect diamagnetism",
description: "<strong>attract</strong> power ups from <strong>far away</strong><br><strong>deflecting</strong> does not drain <strong class='color-f'>energy</strong><br>maintains <strong>functionality</strong> while <strong>inactive</strong>",
description: "<strong>deflecting</strong> does not drain <strong class='color-f'>energy</strong><br>maintains <strong>functionality</strong> while <strong>inactive</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong>/second",
// <br><strong>attract</strong> power ups from <strong>far away</strong>
// description: "<strong>attract</strong> power ups from <strong>far away</strong><br><strong>deflecting</strong> doesn't drain <strong class='color-f'>energy</strong><br>thrown <strong class='color-block'>blocks</strong> have",
// description: "gain <strong class='color-f'>energy</strong> when <strong>blocking</strong><br>no <strong>recoil</strong> when <strong>blocking</strong>",
effect: () => {
@@ -1810,7 +1813,8 @@ const m = {
},
{
name: "negative mass",
description: "use <strong class='color-f'>energy</strong> to nullify &nbsp;<strong style='letter-spacing: 7px;'>gravity</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>55%</strong><br>hold <strong class='color-block'>blocks</strong> as if they have a lower <strong>mass</strong>",
//<br>hold <strong class='color-block'>blocks</strong> as if they have a lower <strong>mass</strong>
description: "use <strong class='color-f'>energy</strong> to nullify &nbsp;<strong style='letter-spacing: 7px;'>gravity</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>55%</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong>/second",
fieldDrawRadius: 0,
effect: () => {
m.fieldFire = true;
@@ -1960,7 +1964,8 @@ const m = {
},
{
name: "molecular assembler",
description: "excess <strong class='color-f'>energy</strong> used to build <strong>drones</strong><br>use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br><strong>double</strong> your default <strong class='color-f'>energy</strong> regeneration",
description: "excess <strong class='color-f'>energy</strong> used to build <strong>drones</strong><br>use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br>generate <strong>12</strong> <strong class='color-f'>energy</strong>/second",
//<strong>double</strong> your default <strong class='color-f'>energy</strong> regeneration
effect: () => {
// m.fieldMeterColor = "#0c5"
// m.eyeFillColor = m.fieldMeterColor
@@ -2095,7 +2100,7 @@ const m = {
// },
{
name: "plasma torch",
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",
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>/second",
set() {
b.isExtruderOn = false
if (m.plasmaBall) {
@@ -2472,7 +2477,7 @@ const m = {
{
name: "time dilation",
// description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 1px;'>stop time</strong><br>while time is stopped you can <strong>move</strong> and <strong>fire</strong><br>and <strong>collisions</strong> do <strong>50%</strong> less <strong class='color-harm'>harm</strong>",
description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 1px;'>stop time</strong><br><strong>move</strong> and <strong>fire</strong> while time is stopped<br>but, <strong>collisions</strong> still do <strong class='color-harm'>harm</strong>",
description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 2px;'>stop time</strong><br>for everything except you<br>generate <strong>12</strong> <strong class='color-f'>energy</strong>/second",
set() {
if (tech.isRewindField) {
this.rewindCount = 0
@@ -2488,7 +2493,7 @@ const m = {
if (!m.holdingTarget) {
this.rewindCount += 6;
const DRAIN = 0.001
const DRAIN = 0.003
let history = m.history[(m.cycle - this.rewindCount) % 600]
if (this.rewindCount > 599 || m.energy < DRAIN) {
this.rewindCount = 0;
@@ -2538,34 +2543,10 @@ const m = {
bullet[bullet.length - 1].endCycle = simulation.cycle + 480 + Math.floor(120 * Math.random()) //8-9 seconds
}
}
if (tech.isRewindGrenade) {
b.grenade(m.pos, this.rewindCount) //Math.PI / 2
const who = bullet[bullet.length - 1]
// Matter.Body.setVelocity(who, {
// x: 0,
// y: 0
// });
who.endCycle = simulation.cycle + 60
// if (tech.isVacuumBomb) {
// Matter.Body.setVelocity(who, {
// x: who.velocity.x * 0.5,
// y: who.velocity.y * 0.5
// });
// } else if (tech.isRPG) {
// who.endCycle = simulation.cycle + 10
// } else if (tech.isNeutronBomb) {
// Matter.Body.setVelocity(who, {
// x: who.velocity.x * 0.3,
// y: who.velocity.y * 0.3
// });
// } else {
// Matter.Body.setVelocity(who, {
// x: who.velocity.x * 0.5,
// y: who.velocity.y * 0.5
// });
// who.endCycle = simulation.cycle + 30
// }
}
@@ -2579,74 +2560,13 @@ 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)
this.rewindCount = 0;
}
m.drawFieldMeter()
// // console.log(this.rewindCount)
// if (input.field && m.fieldCDcycle < m.cycle) { //button has been held down
// if (m.isHolding) {
// m.drawHold(m.holdingTarget);
// m.holding();
// m.throwBlock();
// } else {
// m.grabPowerUp();
// m.lookForPickUp();
// if (!m.holdingTarget) {
// this.rewindCount += 8;
// const DRAIN = 0.001
// let history = m.history[(m.cycle - this.rewindCount) % 600]
// if (this.rewindCount > 599 || m.energy < DRAIN) {
// this.rewindCount = 0;
// m.resetHistory();
// } else {
// // m.grabPowerUp(); //a second grab power up to make the power ups easier to grab, and they more fast which matches the time theme
// m.energy -= DRAIN
// if (m.immuneCycle < m.cycle + 30) m.immuneCycle = m.cycle + 30; //player is immune to damage for 30 cycles
// Matter.Body.setPosition(player, history.position);
// Matter.Body.setVelocity(player, { x: history.velocity.x, y: history.velocity.y });
// if (m.health < history.health) {
// m.health = history.health
// m.displayHealth();
// }
// m.yOff = history.yOff
// if (m.yOff < 48) {
// m.doCrouch()
// } else {
// m.undoCrouch()
// }
// //grab power ups
// for (let i = 0, len = powerUp.length; i < len; ++i) {
// if (
// Vector.magnitudeSquared(Vector.sub(m.pos, powerUp[i].position)) < 100000 &&
// !simulation.isChoosing &&
// (powerUp[i].name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal)
// ) {
// powerUps.onPickUp(powerUp[i]);
// powerUp[i].effect();
// Matter.Composite.remove(engine.world, powerUp[i]);
// powerUp.splice(i, 1);
// break; //because the array order is messed up after splice
// }
// }
// }
// }
// }
// } else { //button is held the first time
// this.rewindCount = 0;
// if (m.holdingTarget && m.fieldCDcycle < m.cycle) {
// m.pickUp();
// } else {
// 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)
// }
// }
if (m.energy < m.maxEnergy) m.regenEnergy(); //extra energy regen
m.drawFieldMeter() // this calls m.regenEnergy(); also
}
} else {
m.fieldFire = true;
m.isBodiesAsleep = false;
m.drain = 0.0003
m.drain = 0.003
m.hold = function() {
if (m.isHolding) {
m.wakeCheck();
@@ -2656,8 +2576,6 @@ const m = {
} else if (input.field && m.fieldCDcycle < m.cycle) {
m.grabPowerUp();
m.lookForPickUp();
m.drain += 0.000002 //also increases inside tech.isTimeSkip
if (m.energy > m.drain) {
m.energy -= m.drain;
if (m.energy < m.drain) {
@@ -2665,6 +2583,7 @@ const m = {
m.energy = 0;
m.wakeCheck();
}
m.immuneCycle = m.cycle + 10; //immune to harm while time is stopped, this also disables regen
//draw field everywhere
ctx.globalCompositeOperation = "saturation"
ctx.fillStyle = "#ccc";
@@ -2687,26 +2606,26 @@ const m = {
sleep(bullet);
simulation.cycle--; //pause all functions that depend on game cycle increasing
if (tech.isTimeSkip) {
m.immuneCycle = 0;
m.drain += 0.0000025
m.regenEnergy(); //immunity disables normal regen, so turn off immunity for just this function
m.immuneCycle = m.cycle + 10;
simulation.isTimeSkipping = true;
m.cycle++;
simulation.gravity();
if (tech.isFireMoveLock && input.fire) {
player.force.x = 0
player.force.y = 0
}
Engine.update(engine, simulation.delta);
m.move();
simulation.checks();
m.walk_cycle += m.flipLegs * m.Vx;
b.fire();
b.bulletDo();
simulation.isTimeSkipping = false;
}
// if (tech.isTimeSkip) {
// m.immuneCycle = 0;
// m.drain += 0.0000025
// m.regenEnergy(); //immunity disables normal regen, so turn off immunity for just this function
// m.immuneCycle = m.cycle + 10;
// simulation.isTimeSkipping = true;
// m.cycle++;
// simulation.gravity();
// if (tech.isFireMoveLock && input.fire) {
// player.force.x = 0
// player.force.y = 0
// }
// Engine.update(engine, simulation.delta);
// m.move();
// simulation.checks();
// m.walk_cycle += m.flipLegs * m.Vx;
// b.fire();
// b.bulletDo();
// simulation.isTimeSkipping = false;
// }
} else { //holding, but field button is released
m.wakeCheck();
}
@@ -2714,23 +2633,96 @@ const m = {
m.wakeCheck();
m.pickUp();
} else {
if (m.drain > 0.0005) m.drain -= 0.000005 //return drain to base level
m.wakeCheck();
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)
}
// console.log(m.drain.toFixed(6))
if (m.energy < m.maxEnergy) m.regenEnergy(); //extra energy regen
m.drawFieldMeter()
}
}
// } else {
// m.fieldFire = true;
// m.isBodiesAsleep = false;
// m.isTimeStopped = false;
// m.drain = 0.005
// let isFieldInputDown = false;
// m.hold = function() {
// if (m.isHolding) {
// m.drawHold(m.holdingTarget);
// m.holding();
// m.throwBlock();
// isFieldInputDown = false
// } else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed
// if (!m.holdingTarget) isFieldInputDown = true;
// m.grabPowerUp();
// m.lookForPickUp();
// // if (m.energy > 0.05) { //deflecting
// // m.drawField();
// // m.pushMobsFacing();
// // }
// } else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released
// m.pickUp();
// } else {
// 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)
// }
// if (isFieldInputDown && !input.field && !m.holdingTarget && !m.isHolding) {
// isFieldInputDown = false;
// m.isTimeStopped = true;
// }
// m.drawFieldMeter()
// if (m.energy < m.maxEnergy) { //extra energy regen
// m.regenEnergy();
// m.regenEnergy();
// }
// if (m.isTimeStopped) {
// if (m.energy > m.drain) {
// // if (player.speed > 0.01 || input.fire)
// m.energy -= m.drain;
// m.immuneCycle = m.cycle + 10; //immune to harm while time is stopped, this also disables regen
// simulation.cycle--; //pause all functions that depend on game cycle increasing
// m.isBodiesAsleep = true;
// ctx.globalCompositeOperation = "saturation" //draw field everywhere
// ctx.fillStyle = "#ccc";
// ctx.fillRect(-100000, -100000, 200000, 200000)
// ctx.globalCompositeOperation = "source-over"
// function sleep(who) {
// for (let i = 0, len = who.length; i < len; ++i) {
// if (!who[i].isSleeping) {
// who[i].storeVelocity = who[i].velocity
// who[i].storeAngularVelocity = who[i].angularVelocity
// }
// Matter.Sleeping.set(who[i], true)
// }
// }
// sleep(mob);
// sleep(body);
// sleep(bullet);
// } else { //restart time
// m.fieldCDcycle = m.cycle + 60;
// m.energy = 0;
// m.isTimeStopped = false
// m.wakeCheck();
// }
// if (simulation.isChoosing) {
// // m.fieldCDcycle = m.cycle + 60;
// m.isTimeStopped = false
// m.wakeCheck();
// }
// }
// }
// }
},
effect() {
// m.fieldMeterColor = "#000"
this.set();
}
},
{
name: "metamaterial cloaking", //"weak photonic coupling" "electromagnetically induced transparency" "optical non-coupling" "slow light field" "electro-optic transparency"
description: "when not firing activate a <strong class='color-cloaked'>cloaking</strong> effect<br><strong>+333%</strong> <strong class='color-d'>damage</strong> if a mob hasn't recently <strong>died</strong><br><strong>collisions</strong> do <strong>50%</strong> less <strong class='color-harm'>harm</strong> when <strong class='color-cloaked'>cloaked</strong>",
//<br><strong>collisions</strong> do <strong>50%</strong> less <strong class='color-harm'>harm</strong> when <strong class='color-cloaked'>cloaked</strong>
description: "when not firing activate <strong class='color-cloaked'>cloaking</strong><br><span style = 'font-size:95%;'><strong>+333%</strong> <strong class='color-d'>damage</strong> if no mob has <strong>died</strong> in <strong>4</strong> seconds</span><br>generate <strong>6</strong> <strong class='color-f'>energy</strong>/second",
effect: () => {
m.fieldFire = true;
m.fieldMeterColor = "#333";
@@ -3028,7 +3020,9 @@ const m = {
// },
{
name: "pilot wave",
description: "use <strong class='color-f'>energy</strong> to push <strong class='color-block'>blocks</strong> with your mouse<br><strong class='color-block'>blocks</strong> can't <strong>collide</strong> with <strong>intangible</strong> mobs<br>field <strong>radius</strong> decreases out of <strong>line of sight</strong>",
//<br><strong class='color-block'>blocks</strong> can't <strong>collide</strong> with <strong>intangible</strong> mobs
//field <strong>radius</strong> decreases out of <strong>line of sight</strong>
description: "use <strong class='color-f'>energy</strong> to guide <strong class='color-block'>blocks</strong><br><strong>unlock</strong> <strong class='color-m'>tech</strong> from other <strong class='color-f'>fields</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong>/second",
effect: () => {
m.fieldPhase = 0;
m.fieldPosition = {
@@ -3223,7 +3217,8 @@ const m = {
},
{
name: "wormhole",
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong class='color-worm'>wormholes</strong> attract <strong class='color-block'>blocks</strong> and power ups<br><strong>5%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
//<strong class='color-worm'>wormholes</strong> attract <strong class='color-block'>blocks</strong> and power ups<br>
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong>5%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong>/second", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
drain: 0,
effect: function() {
m.duplicateChance = 0.05
@@ -3641,10 +3636,6 @@ const m = {
// } else {
// m.hole.isReady = true;
// }
m.drawFieldMeter()
}
},

View File

@@ -280,7 +280,7 @@ const powerUps = {
if (!simulation.paused) {
if (tech.isNoDraftPause) {
powerUps.spawn(m.pos.x, m.pos.y, "ammo");
// powerUps.spawn(m.pos.x, m.pos.y, "ammo");
document.getElementById("choose-grid").style.opacity = "0.7"
} else {
simulation.paused = true;

View File

@@ -3929,7 +3929,7 @@ const spawn = {
me.lockedOn = null;
me.torqueMagnitude = 0.00024 * me.inertia * (Math.random() > 0.5 ? -1 : 1);
me.delay = 120 * simulation.CDScale;
me.delay = 60 + 60 * simulation.CDScale;
me.cd = 0;
me.swordRadius = 0;
me.swordVertex = 1

View File

@@ -221,6 +221,7 @@ const tech = {
},
damageFromTech() {
let dmg = 1 //m.fieldDamage
if (tech.isNoDraftPause) dmg *= 1.5
if (tech.isTechDebt) dmg *= Math.max(41 / (tech.totalCount + 21), 4 - 0.15 * tech.totalCount)
if (tech.isAxion && tech.isHarmMACHO) dmg *= 1 + 0.75 * (1 - m.harmReduction())
if (tech.OccamDamage) dmg *= tech.OccamDamage
@@ -593,25 +594,6 @@ const tech = {
tech.isAmmoFromHealth = false;
}
},
{
name: "eternalism",
description: `choosing a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong> spawns ${powerUps.orb.ammo()}<br><strong>time</strong> doesn't <strong>pause</strong> while choosing`, //${powerUps.orb.heal()} or
// description: "increase <strong class='color-d'>damage</strong> by <strong>50%</strong>, but <strong>time</strong> continues<br>while choosing a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong>",
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return true
},
requires: "",
effect() {
tech.isNoDraftPause = true
},
remove() {
tech.isNoDraftPause = false
}
},
{
name: "exciton",
description: `increase <strong class='color-d'>damage</strong> by <strong>88%</strong>, but<br>${powerUps.orb.ammo()} will no longer <strong>spawn</strong>`,
@@ -3154,9 +3136,9 @@ const tech = {
frequency: 1,
frequencyDefault: 1,
allowed() {
return !tech.isSuperDeterminism
return !tech.isSuperDeterminism && !tech.isNoDraftPause
},
requires: "not superdeterminism",
requires: "not superdeterminism, eternalism",
effect() {
tech.isPauseSwitchField = true;
for (let i = 0, len = tech.tech.length; i < len; i++) {
@@ -3195,8 +3177,10 @@ const tech = {
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() { return true },
requires: "",
allowed() {
return !tech.isSuperDeterminism && !tech.isNoDraftPause
},
requires: "not superdeterminism, eternalism",
effect() {
tech.isPauseEjectTech = true;
},
@@ -3204,6 +3188,25 @@ const tech = {
tech.isPauseEjectTech = false;
}
},
{
name: "eternalism",
// description: `increase <strong class='color-d'>damage</strong> by <strong>60%</strong>, but <strong>time</strong> doesn't <strong>pause</strong><br>while choosing a choosing a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong>`, //${powerUps.orb.heal()} or
description: "increase <strong class='color-d'>damage</strong> by <strong>50%</strong>, but<br><strong>time</strong> can't be <strong>paused</strong> <em>(time dilation still works)</em>",
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return !tech.isPauseSwitchField && !tech.isPauseEjectTech && !tech.isWormHolePause
},
requires: "not unified field theory, paradigm shift, invariant",
effect() {
tech.isNoDraftPause = true
},
remove() {
tech.isNoDraftPause = false
}
},
{
name: "technical debt", // overengineering
// description: `increase <strong class='color-d'>damage</strong> by <strong>300%</strong> minus <strong>10%</strong> for <strong class='color-m'>tech</strong> you have learned(${4 - 0.1 * tech.totalCount})`,
@@ -3505,7 +3508,7 @@ const tech = {
allowed() {
return tech.duplicationChance() > 0.6
},
requires: "duplication chance above 70%",
requires: "NOT EXPERIMENT MODE, duplication chance above 60%",
effect() {
tech.is111Duplicate = true;
tech.maxDuplicationEvent()
@@ -4289,9 +4292,9 @@ const tech = {
frequency: 1,
frequencyDefault: 1,
allowed() {
return (tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIceShot && !tech.isRivets && !tech.isFoamShot && !tech.isSporeWorm && !tech.isNeedles) || tech.haveGunCheck("super balls") || (tech.isRivets && !tech.isNailCrit) || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isDroneTeleport || tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isForeverDrones && !tech.isDroneRadioactive && !tech.isDroneTeleport)
return (tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIceShot && !tech.isRivets && !tech.isFoamShot && !tech.isSporeWorm && !tech.isNeedles) || (tech.haveGunCheck("super balls") && !tech.isFoamBall) || (tech.isRivets && !tech.isNailCrit) || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isDroneTeleport || tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isForeverDrones && !tech.isDroneRadioactive && !tech.isDroneTeleport)
},
requires: "shotgun, super balls, rivets, drones, not irradiated drones or burst drones",
requires: "shotgun, super balls, rivets, drones, not irradiated drones, burst drones, polyurethane",
effect() {
tech.isIncendiary = true
},
@@ -4300,9 +4303,8 @@ const tech = {
}
},
{
name: "supertemporal",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Temporal_paradox' class="link">supertemporal</a>`,
description: "fire <strong>super ball</strong> from the same point in <strong>space</strong><br> but separated by <strong>0.1</strong> seconds in <strong>time</strong>",
name: "autocannon",
description: "fire <strong>+1</strong> extra <strong>super ball</strong><br><strong>balls</strong> are quickly released in same direction",
isGunTech: true,
maxCount: 1,
count: 0,
@@ -4373,6 +4375,26 @@ const tech = {
}
}
},
{
name: "polyurethane foam",
description: "<strong>super balls</strong> colliding with <strong>mobs</strong> catalyzes<br>a reaction that yields <strong>foam</strong> bubbles",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("super balls")
},
requires: "super balls",
effect() {
tech.isFoamBall = true;
},
remove() {
tech.isFoamBall = false;
}
},
//
{
name: "phase velocity",
description: "matter wave <strong>propagates</strong> faster through <strong>solids</strong><br>increase matter wave <strong class='color-d'>damage</strong> by <strong>15%</strong>",
@@ -5218,7 +5240,7 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || tech.haveGunCheck("spores") || tech.haveGunCheck("drones") || tech.haveGunCheck("missiles") || tech.haveGunCheck("foam") || tech.haveGunCheck("matter wave") || tech.isNeutronBomb || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1 || tech.isSporeWorm || tech.foamBotCount > 1
return m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || tech.haveGunCheck("spores") || tech.haveGunCheck("drones") || tech.haveGunCheck("missiles") || tech.haveGunCheck("foam") || tech.haveGunCheck("matter wave") || tech.isNeutronBomb || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1 || tech.isSporeWorm || tech.foamBotCount > 1 || tech.isFoamBall
},
requires: "drones, spores, missiles, foam, matter wave, neutron bomb, ice IX",
effect() {
@@ -5489,7 +5511,7 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
return !tech.isBulletTeleport && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot)
return !tech.isBulletTeleport && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot || tech.isFoamBall)
},
requires: "foam, not uncertainty",
effect() {
@@ -5508,7 +5530,7 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
return (!tech.isFoamAttract && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot)) || (tech.haveGunCheck("matter wave") && !tech.isLongitudinal)
return (!tech.isFoamAttract && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot || tech.isFoamBall)) || (tech.haveGunCheck("matter wave") && !tech.isLongitudinal)
},
requires: "foam, not electrostatic induction, matter wave, not phonon",
effect() {
@@ -5527,7 +5549,7 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot || tech.isSporeWorm
return tech.haveGunCheck("foam") || tech.isFoamBall || tech.foamBotCount > 1 || tech.isFoamShot || tech.isSporeWorm
},
requires: "foam, worms",
effect() {
@@ -5546,7 +5568,7 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot
return tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot || tech.isFoamBall
},
requires: "foam",
effect() {
@@ -6213,9 +6235,9 @@ const tech = {
frequency: 3,
frequencyDefault: 3,
allowed() {
return (m.fieldUpgrades[m.fieldMode].name === "standing wave" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && (build.isExperimentSelection || powerUps.research.count > 1)
return (m.fieldUpgrades[m.fieldMode].name === "standing wave" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "time dilation") && (build.isExperimentSelection || powerUps.research.count > 1)
},
requires: "standing wave or pilot wave",
requires: "standing wave, pilot wave, time dilation",
effect() {
tech.harmonicEnergy = 1
m.setMaxEnergy()
@@ -6747,7 +6769,7 @@ const tech = {
// },
{
name: "degenerate matter",
description: "reduce <strong class='color-harm'>harm</strong> by <strong>66%</strong> while your <strong class='color-f'>field</strong> is active",
description: "reduce <strong class='color-harm'>harm</strong> by <strong>75%</strong> while your <strong class='color-f'>field</strong> is active",
isFieldTech: true,
maxCount: 1,
count: 0,
@@ -6949,25 +6971,25 @@ const tech = {
if (this.count) m.fieldUpgrades[m.fieldMode].set()
}
},
{
name: "timelike",
description: "<strong>time dilation</strong> doubles your relative time <strong>rate</strong><br>and makes you immune to <strong class='color-harm'>harm</strong>",
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "time dilation" && !m.isShipMode && !tech.isRewindField
},
requires: "time dilation, not retrocausality",
effect() {
tech.isTimeSkip = true;
},
remove() {
tech.isTimeSkip = false;
}
},
// {
// name: "timelike",
// description: "<strong>time dilation</strong> doubles your relative time <strong>rate</strong><br>and makes you immune to <strong class='color-harm'>harm</strong>",
// isFieldTech: true,
// maxCount: 1,
// count: 0,
// frequency: 2,
// frequencyDefault: 2,
// allowed() {
// return m.fieldUpgrades[m.fieldMode].name === "time dilation" && !m.isShipMode && !tech.isRewindField
// },
// requires: "time dilation, not retrocausality",
// effect() {
// tech.isTimeSkip = true;
// },
// remove() {
// tech.isTimeSkip = false;
// }
// },
{
name: "Lorentz transformation",
description: `use ${powerUps.orb.research(3)}to increase your time rate<br><strong>move</strong>, <strong>jump</strong>, and <strong>shoot</strong> <strong>50%</strong> faster`,
@@ -6997,7 +7019,7 @@ const tech = {
},
{
name: "time crystals",
description: "<strong>quadruple</strong> your default <strong class='color-f'>energy</strong> regeneration",
description: "<strong>quadruple</strong> your base <strong class='color-f'>energy</strong> regeneration",
isFieldTech: true,
maxCount: 1,
count: 0,
@@ -7241,7 +7263,7 @@ const tech = {
effect: () => {
tech.wimpCount++
spawn.WIMP()
for (let j = 0, len = 1 + 5 * Math.random(); j < len; j++) powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false)
for (let j = 0, len = 5; j < len; j++) powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false)
},
remove() {
tech.wimpCount = 0
@@ -7368,9 +7390,9 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
return m.fieldUpgrades[m.fieldMode].name === "wormhole"
return m.fieldUpgrades[m.fieldMode].name === "wormhole" && !tech.isNoDraftPause
},
requires: "wormhole",
requires: "wormhole, not eternalism",
effect() {
tech.isWormHolePause = true
},
@@ -7822,7 +7844,7 @@ const tech = {
remove() {}
},
{
name: "opacity",
name: "&nbsp;",
description: "",
maxCount: 1,
count: 0,
@@ -9895,4 +9917,6 @@ const tech = {
coyoteTime: null,
missileFireCD: null,
isBotField: null,
isFoamBall: null,
isNoDraftPause: null
}

View File

@@ -1,34 +1,45 @@
******************************************************** NEXT PATCH **************************************************
tech: eternalism - tech,gun,field gives an ammo but, time doesn't pause while choosing
I might change the ammo to something else, not sure, maybe just damage
JUNK tech: panpsychism - awaken blocks, blocks can drop power ups
time dilation field rework
2x energy regen, but pausing time now uses much more energy
you are immune to harm while time is paused
but this stops energy regen
tech timelike is removed
cache gives 14->16x ammo
1st ionization energy gives 8->10% max energy on heal
eternalism gives 50% damage instead of ammo
also disables the pause button, and other pause effects
powerUpBossBaby immunity phase is a bit shorter
tech: polyurethane foam - super balls turn into foam after hitting a mob
supertemporal renamed autocannon
now gives +1 ball, and has a shorter delay between balls
harpoon and grapple no longer lose ammo when you run out of energy
they just trigger a 2 second fire CD
slashBoss doesn't slash as often at higher difficulty levels
field descriptions rewritten
bug fixes
******************************************************** TODO ********************************************************
tech: - don't pause time during draft
tech: eternalism - don't pause time during draft
bugs
requirements change after draft is generated
disable effects that change requirements
when simulation.isChoosing you can't: eject tech,
check for requirements onclick and give random tech if not met?
make lasers on labs flash on and off
make switch a button that stays down
tech expansion: should also make other fields do things
perfect diamagnetism moves forward when you hold down the shield
maybe only with crouch?
time dilation drains 1/2 as much energy when paused
grow plasma torch as you hold it down
negative mass effects much more space
needs more benefit
reduces the cloaking vision effect?
needs more benefit
nonrefundable tech don't display, this is confusing
maybe they can show up but greyed out or something
make your power up list scrollable while in power up selection pause menu
Tech could probably be indexed, something like running
tech.index = new Map();
for (let i = 0; i < tech.tech.length; i++) {
@@ -45,10 +56,6 @@ if (queriedTech) {
guntech fire a bullet that fires nail fragments after 1s in the same direction as the original bullet
like overwatch roadhog
make mol fab field do something cool when it blocks
generate energy?
reset lifespan of: drone,spore,worm, iceIX
bring back:
the old phase decoherence field
make cloak only active on input.field down