diff --git a/img/CIWS.webp b/img/CIWS.webp
new file mode 100644
index 0000000..2033c20
Binary files /dev/null and b/img/CIWS.webp differ
diff --git a/img/autonomous defense.webp b/img/autonomous defense.webp
new file mode 100644
index 0000000..3065ae8
Binary files /dev/null and b/img/autonomous defense.webp differ
diff --git a/img/reel.webp b/img/reel.webp
new file mode 100644
index 0000000..af2baa0
Binary files /dev/null and b/img/reel.webp differ
diff --git a/img/rupture.webp b/img/rupture.webp
new file mode 100644
index 0000000..8c77f01
Binary files /dev/null and b/img/rupture.webp differ
diff --git a/js/bullet.js b/js/bullet.js
index 57d523e..c77361f 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -1498,6 +1498,10 @@ const b = {
classType: "bullet",
endCycle: simulation.cycle + 70,
isSlowPull: false,
+ drawStringControlMagnitude: 1000 + 1000 * Math.random(),
+ drawStringFlip: (Math.round(Math.random()) ? 1 : -1),
+ attached: false,
+ glowColor: tech.isHookExplosion ? "rgba(200,0,0,0.07)" : tech.isHarmReduce ? "rgba(50,100,255,0.1)" : "rgba(0,200,255,0.07)",
collisionFilter: {
category: cat.bullet,
mask: tech.isShieldPierce ? cat.body | cat.mob | cat.mobBullet : cat.body | cat.mob | cat.mobBullet | cat.mobShield,
@@ -1507,13 +1511,31 @@ const b = {
density: 0.004, //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
drain: 0.001,
draw() {
+ // draw rope
const where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
const sub = Vector.sub(where, this.vertices[0])
- const controlPoint = Vector.add(where, Vector.mult(sub, -0.5))
- //draw rope
+ ctx.strokeStyle = "#000" // "#0ce"
+ ctx.lineWidth = 0.5
ctx.beginPath();
ctx.moveTo(where.x, where.y);
- ctx.quadraticCurveTo(controlPoint.x, controlPoint.y, this.vertices[0].x, this.vertices[0].y)
+ if (this.attached) {
+ const controlPoint = Vector.add(where, Vector.mult(sub, -0.5))
+ ctx.quadraticCurveTo(controlPoint.x, controlPoint.y, this.vertices[0].x, this.vertices[0].y)
+ } else {
+ const long = Math.max(Vector.magnitude(sub), 60)
+ const perpendicular = Vector.mult(Vector.normalise(Vector.perp(sub)), this.drawStringFlip * Math.min(0.7 * long, 10 + this.drawStringControlMagnitude / (10 + Vector.magnitude(sub))))
+ const controlPoint = Vector.add(Vector.add(where, Vector.mult(sub, -0.5)), perpendicular)
+ ctx.quadraticCurveTo(controlPoint.x, controlPoint.y, this.vertices[0].x, this.vertices[0].y)
+ }
+ // ctx.lineTo(this.vertices[0].x, this.vertices[0].y);
+ // ctx.stroke();
+ ctx.strokeStyle = this.glowColor // "#0ce"
+ ctx.lineWidth = 10
+ ctx.stroke();
+ ctx.strokeStyle = "#000" // "#0ce"
+ ctx.lineWidth = 0.5
+ ctx.stroke();
+
// ctx.lineTo(this.vertices[0].x, this.vertices[0].y);
// if (tech.isHookWire) {
// //draw wire
@@ -1536,36 +1558,16 @@ const b = {
// ctx.lineWidth = 20
// ctx.stroke();
// }
- ctx.strokeStyle = "rgba(0,255,255,0.2)" // "#0ce"
- ctx.lineWidth = 10
- ctx.stroke();
- ctx.strokeStyle = "#000" // "#0ce"
- ctx.lineWidth = 0.5
- ctx.stroke();
- //draw harpoon spikes
- // ctx.beginPath();
- // ctx.lineTo(this.vertices[3].x, this.vertices[3].y);
- // // const spike1 = Vector.add(this.vertices[1], Vector.mult(Vector.sub(this.vertices[1], this.vertices[2]), 3))
- // // ctx.lineTo(spike1.x, spike1.y);
- // const controlPoint2 = Vector.add(this.vertices[3], Vector.mult(Vector.sub(this.vertices[3], this.vertices[2]), 20))
- // ctx.quadraticCurveTo(controlPoint2.x, controlPoint2.y, this.vertices[2].x, this.vertices[2].y)
- // ctx.fillStyle = '#000'
- // ctx.fill();
-
+ //draw hook
ctx.beginPath();
ctx.lineTo(this.vertices[0].x, this.vertices[0].y);
- const spikeLength = 2
- // const spike1 = Vector.add(this.vertices[1], Vector.mult(Vector.sub(this.vertices[1], this.vertices[2]), spikeLength))
- // ctx.moveTo(this.vertices[2].x, this.vertices[2].y);
- // ctx.lineTo(spike1.x, spike1.y);
- // ctx.lineTo(this.vertices[3].x, this.vertices[3].y);
- const spike2 = Vector.add(this.vertices[3], Vector.mult(Vector.sub(this.vertices[3], this.vertices[2]), spikeLength))
+ const spike = Vector.add(this.vertices[3], Vector.mult(Vector.sub(this.vertices[3], this.vertices[2]), 2))
ctx.moveTo(this.vertices[2].x, this.vertices[2].y);
- ctx.lineTo(spike2.x, spike2.y);
+ ctx.lineTo(spike.x, spike.y);
ctx.lineTo(this.vertices[1].x, this.vertices[1].y);
ctx.fillStyle = '#000'
ctx.fill();
@@ -1577,24 +1579,9 @@ const b = {
who.isShielded = true
});
}
- // if (tech.fragments) {
- // b.targetedNail(this.vertices[2], tech.fragments * Math.floor(2 + Math.random()))
- // }
- // if (tech.isFoamBall) {
- // for (let i = 0, len = 3 * this.mass; i < len; i++) {
- // const radius = 5 + 8 * Math.random()
- // const velocity = {
- // x: Math.max(0.5, 2 - radius * 0.1),
- // y: 0
- // }
- // b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
- // }
- // // this.endCycle = 0;
- // }
if (m.fieldCDcycle < m.cycle + 40) m.fieldCDcycle = m.cycle + 40 //extra long cooldown on hitting mobs
if (tech.isHookExplosion) b.explosion(this.position, 250 + 150 * Math.random()); //makes bullet do explosive damage at end
this.retract()
-
},
caughtPowerUp: null,
dropCaughtPowerUp() {
@@ -1624,6 +1611,7 @@ const b = {
}
},
retract() {
+ this.attached = false
this.do = this.returnToPlayer
this.endCycle = simulation.cycle + 60
Matter.Body.setDensity(this, 0.0005); //reduce density on return
@@ -1644,6 +1632,17 @@ const b = {
player.force.x += momentum.x
player.force.y += momentum.y
if (this.pickUpTarget) {
+ if (tech.isReel && this.blockDist > 150) {
+ // console.log(0.0003 * Math.min(this.blockDist, 1000))
+ m.energy += 0.00044 * Math.min(this.blockDist, 800) //max 0.352 energy
+ simulation.drawList.push({ //add dmg to draw queue
+ x: m.pos.x,
+ y: m.pos.y,
+ radius: 10,
+ color: m.fieldMeterColor,
+ time: simulation.drawTime
+ });
+ }
m.holdingTarget = this.pickUpTarget
// give block to player after it returns
m.isHolding = true;
@@ -1696,22 +1695,46 @@ const b = {
},
pickUpTarget: null,
grabBlocks() {
- if (this.pickUpTarget) {
+ if (this.pickUpTarget) { //if always attached to a block
//position block on hook
Matter.Body.setPosition(this.pickUpTarget, Vector.add(this.vertices[2], this.velocity))
Matter.Body.setVelocity(this.pickUpTarget, { x: 0, y: 0 })
- } else if (!input.down) {
+ } else { // if (!input.down)
const blocks = Matter.Query.collides(this, body)
if (blocks.length) {
// console.log(blocks)
for (let i = 0; i < blocks.length; i++) {
if (blocks[i].bodyA.classType === "body" && !blocks[i].bodyA.isNotHoldable && !blocks[0].bodyA.mass < 60) {
this.retract()
- this.pickUpTarget = blocks[i].bodyA
- if (tech.isHookExplosion) b.explosion(this.position, 250 + 150 * Math.random()); //makes bullet do explosive damage at end
+ if (tech.isHookExplosion) {
+ b.explosion(this.position, 250 + 150 * Math.random()); //makes bullet do explosive damage at end
+ const blockVertices = blocks[i].bodyA.vertices
+ Composite.remove(engine.world, blocks[i].bodyA)
+ body.splice(body.indexOf(blocks[i].bodyA), 1)
+ //animate the block fading away
+ simulation.ephemera.push({
+ name: "blockFadeOut",
+ count: 25, //cycles before it self removes
+ do() {
+ this.count--
+ if (this.count < 0) simulation.removeEphemera(this.name)
+ ctx.beginPath();
+ ctx.moveTo(blockVertices[0].x, blockVertices[0].y);
+ for (let j = 1; j < blockVertices.length; j++) ctx.lineTo(blockVertices[j].x, blockVertices[j].y);
+ ctx.lineTo(blockVertices[0].x, blockVertices[0].y);
+ ctx.lineWidth = 2;
+ ctx.strokeStyle = `rgba(0,0,0,${this.count / 25})`
+ ctx.stroke();
+ },
+ })
+ } else {
+ this.pickUpTarget = blocks[i].bodyA
+ this.blockDist = Vector.magnitude(Vector.sub(this.pickUpTarget.position, m.pos))
+ }
} else if (blocks[i].bodyB.classType === "body" && !blocks[i].bodyB.isNotHoldable && !blocks[0].bodyB.mass < 60) {
this.retract()
this.pickUpTarget = blocks[i].bodyB
+ this.blockDist = Vector.magnitude(Vector.sub(this.pickUpTarget.position, m.pos))
if (tech.isHookExplosion) b.explosion(this.position, 250 + 150 * Math.random()); //makes bullet do explosive damage at end
}
}
@@ -1779,6 +1802,7 @@ const b = {
Matter.Body.setPosition(this, Vector.add(this.position, { x: -20 * Math.cos(this.angle), y: -20 * Math.sin(this.angle) }))
if (Matter.Query.collides(this, map).length) {
if (tech.isHookExplosion) b.explosion(this.position, 150 + 50 * Math.random()); //makes bullet do explosive damage at end
+ this.attached = true
Matter.Body.setVelocity(this, { x: 0, y: 0 });
Matter.Sleeping.set(this, true)
this.endCycle = simulation.cycle + 5
@@ -1802,14 +1826,15 @@ const b = {
if (input.down) { //down
this.isSlowPull = true
dist = 0
- player.force.y += 2.5 * player.mass * simulation.g; //adjust this to control fall rate while hooked and pressing down
+ player.force.y += 3 * player.mass * simulation.g; //adjust this to control fall rate while hooked and pressing down
} else if (input.up) {
this.isSlowPull = false
+ player.force.y -= player.mass * simulation.g; //adjust this to control fall rate while hooked and pressing down
}
if (m.energy < this.drain) this.isSlowPull = true
// pulling friction that allowed a slight swinging, but has high linear pull at short dist
- const drag = 1 - 30 / Math.min(Math.max(100, dist), 700) - 0.1 * (player.speed > 70)
+ const drag = 1 - 30 / Math.min(Math.max(100, dist), 700) - 0.1 * (player.speed > 66)
// console.log(player.speed)
Matter.Body.setVelocity(player, { x: player.velocity.x * drag, y: player.velocity.y * drag });
const pullScale = 0.0004
diff --git a/js/engine.js b/js/engine.js
index 0374fcd..c3813d1 100644
--- a/js/engine.js
+++ b/js/engine.js
@@ -204,24 +204,17 @@ function collisionChecks(event) {
// time: 25
// });
}
- // if (true) { //fire harpoons at mobs after getting hit
- // const countMax = 12
- // let count = countMax
- // const range = 300
- // for (let i = 0; i < mob.length; i++) {
- // if (count > 0 && Vector.magnitude(Vector.sub(m.pos, mob[i].position)) < range) {
- // count--
- // if (m.fieldCDcycle < m.cycle + 30) m.fieldCDcycle = m.cycle + 30
- // const angle = Math.atan2(mob[i].position.y - player.position.y, mob[i].position.x - player.position.x);
- // b.harpoon(m.pos, mob[i], angle, 0.75, true, 20) // harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 35, isReturnAmmo = true, thrust = 0.1) {
- // for (; count > 0; count--) {
- // b.harpoon(m.pos, mob[i], count * Math.PI / countMax, 0.75, true, 9) // harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 35, isReturnAmmo = true, thrust = 0.1) {
- // bullet[bullet.length - 1].drain = 0
- // }
- // break
- // }
- // }
- // }
+ if (tech.isHarpoonDefense) { //fire harpoons at mobs after getting hit
+ const maxCount = 10 + 3 * tech.extraHarpoons //scale the number of hooks fired
+ let count = maxCount - 1
+ const angle = Math.atan2(mob[k].position.y - player.position.y, mob[k].position.x - player.position.x);
+ b.harpoon(m.pos, mob[k], angle, 0.75, true, 7) // harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 35, isReturnAmmo = true, thrust = 0.1) {
+ bullet[bullet.length - 1].drain = 0
+ for (; count > 0; count--) {
+ b.harpoon(m.pos, mob[k], angle + count * 2 * Math.PI / maxCount, 0.75, true, 7)
+ bullet[bullet.length - 1].drain = 0
+ }
+ }
if (tech.isStimulatedEmission) powerUps.ejectTech()
if (mob[k].onHit) mob[k].onHit();
if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage for 30 cycles
diff --git a/js/index.js b/js/index.js
index 54eff25..b6a8552 100644
--- a/js/index.js
+++ b/js/index.js
@@ -1275,7 +1275,7 @@ window.addEventListener("keydown", function (event) {
simulation.molecularMode++
m.fieldUpgrades[4].description = m.fieldUpgrades[4].setDescription()
} else {
- m.setField((m.fieldMode === m.fieldUpgrades.length - 1) ? 0 : m.fieldMode + 1) //cycle to next field
+ m.setField((m.fieldMode === m.fieldUpgrades.length - 1) ? 1 : m.fieldMode + 1) //cycle to next field, skip field emitter
if (m.fieldMode === 4) {
simulation.molecularMode = 0
m.fieldUpgrades[4].description = m.fieldUpgrades[4].setDescription()
diff --git a/js/level.js b/js/level.js
index 3f1401f..ff380f1 100644
--- a/js/level.js
+++ b/js/level.js
@@ -11,7 +11,7 @@ const level = {
// playableLevels: ["pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion"],
//see level.populateLevels: (intro, ... , reservoir or factory, reactor, ... , subway, final) added later
playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion", "lock"],
- communityLevels: ["gauntlet", "stronghold", "basement", "crossfire", "vats", "run", "ngon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp", "biohazard", "stereoMadness", "yingYang", "staircase", "fortress", "commandeer", "clock", "buttonbutton", "downpour", "superNgonBros", "underpass", "cantilever", "tlinat", "ruins", "ace", "crimsonTowers", "LaunchSite"],
+ communityLevels: ["gauntlet", "stronghold", "basement", "crossfire", "vats", "run", "ngon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp", "biohazard", "stereoMadness", "yingYang", "staircase", "fortress", "commandeer", "clock", "buttonbutton", "downpour", "superNgonBros", "underpass", "cantilever", "tlinat", "ruins", "ace", "crimsonTowers", "LaunchSite", "shipwreck"],
trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon", "diamagnetism"],
levels: [],
start() {
@@ -19,7 +19,7 @@ const level = {
// simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode
// simulation.isHorizontalFlipped = true
// tech.giveTech("performance")
- // level.difficultyIncrease(1 * 4) //30 is near max on hard //60 is near max on why
+ // level.difficultyIncrease(5 * 4) //30 is near max on hard //60 is near max on why
// spawn.setSpawnList();
// spawn.setSpawnList();
// m.maxHealth = m.health = 100
@@ -38,25 +38,26 @@ const level = {
// b.giveGuns("harpoon") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.guns[8].ammo = 100000000
// requestAnimationFrame(() => { tech.giveTech("MACHO") });
- // for (let i = 0; i < 1; ++i) tech.giveTech("autonomous defense")
- // for (let i = 0; i < 1; ++i) tech.giveTech("rupture")
- // for (let i = 0; i < 1; ++i) tech.giveTech("nail-bot upgrade")
+ // for (let i = 0; i < 1; ++i) tech.giveTech("degenerate matter")
+ // for (let i = 0; i < 1; ++i) tech.giveTech("reel")
+ // for (let i = 0; i < 1; ++i) tech.giveTech("tokamak")
// requestAnimationFrame(() => { for (let i = 0; i < 30; i++) tech.giveTech("laser-bot") });
// for (let i = 0; i < 1; i++) tech.giveTech("laser-bot upgrade")
- // for (let i = 0; i < 1; ++i) tech.giveTech("uncertainty principle")
- // for (let i = 0; i < 1; ++i) tech.giveTech("mechanical resonance")
+ // for (let i = 0; i < 1; ++i) tech.giveTech("rupture")
+ // for (let i = 0; i < 1; ++i) tech.giveTech("autonomous defense")
// for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "research");
// for (let i = 0; i < 100; i++) powerUps.directSpawn(1750, -500, "coupling");
- // level.testing();
+ // level.shipwreck();
+
// for (let i = 0; i < 4; ++i) spawn.hopMother(1900, -500)
// for (let i = 0; i < 5; ++i) spawn.starter(1900, -500)
- // for (let i = 0; i < 1; ++i) spawn.shooterBoss(1900, -2500)
+ // for (let i = 0; i < 1; ++i) spawn.timeSkipBoss(1900, -2500)
// spawn.beetleBoss(1900, -500, 25)
// spawn.slasher2(2000, -1150)
// spawn.zombie(-3000, -500 + 300 * Math.random(), 30, 5, "white") // zombie(x, y, radius, sides, color)
- // for (let i = 0; i < 20; ++i) spawn.starter(1000 + 1000 * Math.random(), -500 + 300 * Math.random())
+ // for (let i = 0; i < 5; ++i) spawn.starter(1000 + 1000 * Math.random(), -500 + 300 * Math.random())
// tech.addJunkTechToPool(2)
// tech.tech[322].frequency = 100
// spawn.tetherBoss(1900, -500, { x: 1900, y: -500 })
@@ -29768,6 +29769,319 @@ const level = {
// spawn.secondaryBossChance(100, -1500)
powerUps.addResearchToLevel() //needs to run after mobs are spawned
},
+ shipwreck() {
+ simulation.makeTextLog(`shipwreck by 3xionDev`);
+ level.setPosToSpawn(0, -50); //normal spawn
+ level.exit.x = 1500;
+ level.exit.y = -1875;
+ spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); //bump for level entrance
+ spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20); //bump for level exit
+ level.defaultZoom = 1800
+ simulation.zoomTransition(level.defaultZoom)
+ document.body.style.backgroundColor = "#05001C";
+ // color.map = "#444" //custom map color
+ spawn.mapRect(-325, 0, 650, 300);
+ spawn.mapRect(-275, -675, 50, 700);
+ spawn.mapRect(-325, -1025, 650, 300);
+ spawn.mapRect(-275, -750, 50, 75);
+ spawn.mapRect(300, 50, 675, 200);
+ spawn.mapRect(925, 50, 450, 150);
+ spawn.mapRect(275, -750, 50, 275);
+ spawn.mapRect(275, -325, 50, 325);
+ spawn.bodyRect(150, -175, 100, 100);
+ spawn.bodyRect(-200, -450, 100, 400);
+ spawn.bodyRect(-150, -650, 25, 50);
+ spawn.bodyRect(-200, -700, 25, 25);
+ spawn.bodyRect(175, -250, 75, 100);
+ spawn.mapRect(875, -50, 100, 100);
+ spawn.mapRect(350, -175, 25, 25);
+ spawn.mapRect(325, -175, 175, 225);
+ spawn.bodyRect(375, -225, 50, 50);
+ spawn.bodyRect(700, -450, 125, 125);
+ spawn.mapRect(1375, 25, 400, 100);
+ spawn.mapRect(1675, -175, 100, 200);
+ spawn.mapRect(1775, -175, 225, 100);
+ spawn.mapRect(1575, -75, 100, 100);
+ spawn.mapRect(1775, -75, 175, 100);
+ spawn.mapRect(1300, 125, 250, 25);
+ spawn.mapRect(850, 200, 225, 25);
+ spawn.mapRect(1100, 200, 50, 100);
+ spawn.mapRect(1250, 175, 50, 125);
+ spawn.mapRect(1950, -150, 275, 50);
+ spawn.mapRect(2125, -150, 25, 25);
+ spawn.mapRect(2125, -175, 1025, 100);
+ spawn.mapRect(2625, -350, 25, 25);
+ spawn.mapRect(2650, -325, 25, 150);
+ spawn.mapRect(2625, -400, 50, 250);
+ spawn.bodyRect(1900, -200, 325, 25);
+ spawn.bodyRect(2525, -275, 100, 100);
+ spawn.bodyRect(2575, -325, 50, 50);
+ spawn.mapRect(425, -75, 150, 125);
+ spawn.bodyRect(350, -250, 75, 75);
+ spawn.bodyRect(1250, -200, 25, 25);
+ spawn.bodyRect(1150, -350, 100, 175);
+ spawn.bodyRect(1375, -375, 25, 25);
+ spawn.bodyRect(1375, -400, 50, 100);
+ spawn.mapRect(2650, -400, 500, 50);
+ spawn.mapRect(3100, -175, 300, 50);
+ spawn.bodyRect(2700, -250, 75, 25);
+ spawn.bodyRect(2725, -275, 25, 25);
+ spawn.bodyRect(2750, -250, 25, 25);
+ spawn.bodyRect(2825, -275, 75, 100);
+ spawn.randomMob(3650, -250, 0);
+ spawn.bodyRect(2925, -225, 50, 50);
+ spawn.mapRect(325, -950, 25, 25);
+ spawn.mapRect(325, -975, 650, 200);
+ spawn.mapRect(975, -900, 200, 100);
+ spawn.mapRect(1175, -850, 100, 100);
+ spawn.mapRect(1275, -800, 75, 125);
+ spawn.mapRect(1350, -725, 25, 125);
+ spawn.mapRect(1225, -800, 25, 25);
+ spawn.mapRect(950, -925, 100, 25);
+ spawn.mapRect(1150, -875, 100, 25);
+ spawn.mapRect(1250, -825, 75, 50);
+ spawn.mapRect(1125, -825, 75, 50);
+ spawn.mapRect(1250, -775, 50, 50);
+ spawn.mapRect(1400, -225, 100, 200);
+ spawn.mapRect(1550, -150, 125, 75);
+ spawn.mapRect(1500, -100, 75, 75);
+ spawn.mapRect(1175, -225, 225, 100);
+ spawn.mapRect(1475, -200, 100, 100);
+ spawn.mapRect(1300, -175, 125, 100);
+ spawn.mapRect(1250, -150, 50, 200);
+ spawn.mapRect(1600, -275, 50, 150);
+ spawn.mapRect(1300, -275, 75, 75);
+ spawn.mapRect(1475, -375, 50, 225);
+ spawn.mapRect(1575, -225, 25, 100);
+ spawn.mapRect(1500, -325, 50, 125);
+ spawn.bodyRect(1400, -350, 25, 50);
+ spawn.bodyRect(1650, -425, 50, 50);
+ spawn.bodyRect(1750, -475, 25, 125);
+ spawn.bodyRect(1725, -575, 150, 50);
+ spawn.bodyRect(1625, -425, 25, 50);
+ spawn.bodyRect(1175, -425, 75, 75);
+ spawn.mapRect(325, -625, 175, 50);
+ spawn.mapRect(425, -800, 25, 175);
+ spawn.mapRect(375, -800, 25, 200);
+ spawn.mapRect(500, -800, 25, 225);
+ spawn.mapRect(475, -800, 50, 225);
+ spawn.mapRect(675, -875, 50, 575);
+ spawn.mapRect(675, -150, 25, 175);
+ spawn.mapRect(700, -150, 25, 75);
+ spawn.mapRect(675, -125, 25, 200);
+ spawn.bodyRect(675, -300, 50, 150);
+ spawn.mapRect(2125, -1025, 1025, 100);
+ spawn.mapRect(3050, -975, 325, 50);
+ spawn.mapRect(3300, -925, 75, 600);
+ spawn.bodyRect(3300, -325, 75, 125);
+ spawn.bodyRect(3325, -325, 25, 25);
+ spawn.mapRect(3300, -325, 75, 25);
+ spawn.mapRect(3325, -175, 1100, 25);
+ spawn.mapRect(3325, -950, 1100, 25);
+ spawn.mapRect(3350, -725, 225, 25);
+ spawn.mapRect(3500, -925, 75, 200);
+ spawn.mapRect(3350, -850, 175, 25);
+ spawn.bodyRect(4075, -625, 125, 125);
+ spawn.bodyRect(3850, -825, 75, 50);
+ spawn.bodyRect(4050, -800, 25, 50);
+ spawn.bodyRect(4150, -825, 75, 100);
+ spawn.bodyRect(3900, -800, 50, 75);
+ spawn.bodyRect(3575, -375, 100, 75);
+ spawn.bodyRect(3800, -675, 75, 100);
+ spawn.bodyRect(3950, -875, 250, 150);
+ spawn.bodyRect(3975, -700, 50, 100);
+ spawn.bodyRect(4150, -775, 200, 125);
+ spawn.bodyRect(3825, -700, 50, 125);
+ spawn.bodyRect(3575, -550, 125, 50);
+ spawn.bodyRect(3750, -550, 25, 25);
+ spawn.bodyRect(3600, -625, 75, 50);
+ spawn.bodyRect(3550, -500, 75, 50);
+ spawn.bodyRect(4200, -675, 75, 75);
+ spawn.bodyRect(4400, -600, 50, 125);
+ spawn.mapRect(4375, -175, 350, 25);
+ spawn.mapRect(4475, -200, 475, 50);
+ spawn.mapRect(4450, -925, 25, 25);
+ spawn.mapRect(4475, -950, 475, 50);
+ spawn.mapRect(4350, -950, 225, 25);
+ spawn.mapRect(4450, -925, 100, 750);
+ spawn.mapRect(4650, -900, 825, 700);
+ spawn.mapRect(5250, -825, 475, 550);
+ spawn.mapRect(5550, -725, 700, 350);
+ spawn.mapRect(6100, -625, 550, 150);
+ spawn.mapRect(6600, -575, 225, 50);
+ spawn.mapRect(1325, -875, 50, 200);
+ spawn.mapRect(1275, -825, 50, 25);
+ spawn.mapRect(1275, -875, 25, 50);
+ spawn.mapRect(1225, -900, 75, 25);
+ spawn.mapRect(1325, -900, 50, 75);
+ spawn.mapRect(1075, -925, 200, 75);
+ spawn.mapRect(1275, -975, 75, 150);
+ spawn.mapRect(1300, -800, 100, 150);
+ spawn.mapRect(1375, -725, 50, 150);
+ spawn.mapRect(-325, -1525, 650, 300);
+ spawn.mapRect(150, -1275, 50, 375);
+ spawn.mapRect(-100, -1350, 50, 450);
+ spawn.mapRect(-325, -2600, 650, 300);
+ spawn.mapRect(-275, -2400, 25, 50);
+ spawn.mapRect(-275, -2325, 50, 825);
+ spawn.mapRect(300, -1475, 675, 200);
+ spawn.bodyRect(375, -1250, 75, 75);
+ spawn.bodyRect(800, -1275, 25, 300);
+ spawn.mapRect(1950, -1000, 175, 100);
+ spawn.mapRect(1850, -950, 125, 125);
+ spawn.mapRect(1825, -875, 75, 125);
+ spawn.mapRect(1825, -800, 25, 125);
+ spawn.mapRect(1800, -750, 25, 150);
+ spawn.mapRect(1775, -625, 50, 150);
+ spawn.mapRect(2000, -900, 25, 225);
+ spawn.mapRect(2075, -925, 50, 400);
+ spawn.mapRect(1000, -825, 25, 300);
+ spawn.mapRect(1050, -900, 50, 25);
+ spawn.mapRect(1050, -925, 50, 25);
+ spawn.mapRect(2475, -100, 50, 350);
+ spawn.mapRect(2650, -100, 25, 725);
+ spawn.mapRect(2350, -950, 50, 350);
+ spawn.mapRect(775, -825, 25, 375);
+ spawn.mapRect(3750, -950, 25, 175);
+ spawn.mapRect(3625, -925, 25, 275);
+ spawn.mapRect(4225, -925, 50, 200);
+ spawn.mapRect(950, -1425, 200, 100);
+ spawn.mapRect(1150, -1400, 150, 75);
+ spawn.mapRect(1300, -1350, 25, 100);
+ spawn.mapRect(1275, -1350, 25, 50);
+ spawn.bodyRect(1300, -1250, 25, 275);
+ spawn.bodyRect(2600, -1575, 375, 550);
+ spawn.bodyRect(2625, -1300, 75, 150);
+ spawn.bodyRect(2700, -1475, 100, 275);
+ spawn.bodyRect(2525, -1200, 75, 150);
+ spawn.mapRect(1675, -1400, 200, 75);
+ spawn.mapRect(1825, -1425, 225, 100);
+ spawn.mapRect(1650, -1350, 75, 100);
+ spawn.mapRect(1700, -1275, 25, 125);
+ spawn.bodyRect(1225, -1425, 550, 25);
+ spawn.bodyRect(1300, -1650, 100, 150);
+ spawn.bodyRect(1600, -1675, 100, 200);
+ spawn.bodyRect(1575, -1525, 25, 25);
+ spawn.bodyRect(1450, -1575, 25, 125);
+ spawn.bodyRect(1500, -1650, 75, 50);
+ spawn.mapRect(2325, -1225, 50, 200);
+ spawn.mapRect(2375, -1300, 100, 275);
+ spawn.mapRect(2225, -1125, 125, 100);
+ spawn.mapRect(2300, -1150, 50, 50);
+ spawn.bodyRect(2250, -850, 75, 100);
+ spawn.mapRect(150, -2550, 800, 200);
+ spawn.mapRect(875, -2500, 275, 100);
+ spawn.mapRect(325, -2400, 75, 375);
+ spawn.mapRect(325, -1800, 75, 350);
+ spawn.bodyRect(325, -2025, 75, 225);
+ spawn.mapRect(-150, -2375, 25, 375);
+ spawn.mapRect(25, -2400, 50, 500);
+ spawn.mapRect(-100, -2375, 25, 225);
+ spawn.mapRect(200, -2350, 50, 250);
+ spawn.bodyRect(250, -1875, 25, 75);
+ spawn.bodyRect(-50, -2050, 50, 50);
+ spawn.mapRect(1050, -1350, 50, 150);
+ spawn.mapRect(575, -1325, 25, 100);
+ spawn.mapRect(400, -1300, 25, 75);
+ spawn.mapRect(525, -1300, 50, 125);
+ spawn.mapRect(575, -2400, 75, 275);
+ spawn.mapRect(650, -2325, 25, 325);
+ spawn.mapRect(625, -2150, 50, 75);
+ spawn.mapRect(625, -2375, 50, 100);
+ spawn.mapRect(600, -2125, 25, 25);
+ spawn.mapRect(650, -2075, 25, 150);
+ spawn.mapRect(675, -2375, 50, 200);
+ spawn.mapRect(650, -2200, 50, 75);
+ spawn.mapRect(625, -2100, 50, 75);
+ spawn.mapRect(1100, -2475, 950, 50);
+ spawn.mapRect(1325, -1825, 450, 25);
+ spawn.mapRect(1475, -1850, 150, 50);
+ spawn.mapRect(1725, -2425, 50, 600);
+ spawn.mapRect(1325, -2450, 50, 450);
+ spawn.mapRect(1475, -2425, 25, 150);
+ spawn.mapRect(1675, -2425, 25, 600);
+ spawn.bodyRect(1450, -2175, 50, 75);
+ spawn.bodyRect(1650, -2200, 50, 50);
+ spawn.mapRect(950, -1550, 75, 125);
+ spawn.mapRect(900, -1500, 50, 50);
+ spawn.mapRect(2000, -2475, 125, 50);
+ spawn.mapRect(2100, -2475, 1050, 100);
+ spawn.mapRect(3050, -2425, 300, 50);
+ spawn.mapRect(3225, -2400, 1350, 25);
+ spawn.mapRect(4475, -2400, 475, 50);
+ spawn.mapRect(4900, -2375, 1125, 50);
+ spawn.mapRect(3950, -1350, 2075, 50);
+ spawn.mapRect(4075, -1325, 75, 400);
+ spawn.mapRect(4775, -1325, 75, 425);
+ spawn.mapRect(6000, -2350, 1075, 1025);
+ spawn.mapRect(6675, -2250, 950, 825);
+ spawn.mapRect(7375, -2050, 700, 425);
+ spawn.mapRect(7850, -1900, 425, 125);
+ spawn.mapRect(8200, -1850, 275, 25);
+ spawn.mapRect(5000, -2350, 75, 400);
+ spawn.mapRect(5200, -2350, 25, 600);
+ spawn.mapRect(5600, -2325, 25, 475);
+ spawn.mapRect(5750, -2350, 50, 300);
+ spawn.mapRect(5800, -2325, 25, 400);
+ spawn.mapRect(5775, -2075, 25, 50);
+ spawn.bodyRect(5325, -2250, 75, 125);
+ spawn.bodyRect(5925, -1800, 75, 125);
+ spawn.bodyRect(5475, -1800, 75, 225);
+ spawn.bodyRect(5350, -2050, 175, 100);
+ spawn.bodyRect(5475, -2125, 75, 125);
+ spawn.bodyRect(5750, -1750, 100, 100);
+ spawn.bodyRect(5900, -1950, 175, 150);
+ spawn.bodyRect(4600, -1950, 150, 275);
+ spawn.bodyRect(4875, -1875, 150, 100);
+ spawn.mapRect(5675, -1600, 350, 50);
+ spawn.mapRect(4325, -1300, 25, 200);
+ spawn.mapRect(3975, -2375, 75, 350);
+ spawn.mapRect(4250, -2375, 25, 550);
+ spawn.mapRect(2875, -2400, 75, 400);
+ spawn.mapRect(3050, -2425, 25, 700);
+ spawn.mapRect(2450, -2425, 75, 550);
+ spawn.mapRect(3375, -2375, 25, 525);
+ spawn.mapRect(3325, -1125, 75, 225);
+ spawn.mapRect(3125, -1200, 25, 200);
+ spawn.mapRect(2975, -1225, 75, 225);
+ spawn.mapRect(1875, -2425, 50, 550);
+ spawn.mapRect(1900, -1925, 475, 50);
+ spawn.mapRect(2300, -2400, 75, 475);
+ spawn.bodyRect(2025, -2325, 50, 50);
+ spawn.bodyRect(2150, -2300, 100, 100);
+ spawn.bodyRect(2025, -2325, 25, 100);
+ spawn.bodyRect(2125, -2275, 75, 75);
+ spawn.bodyRect(2250, -2250, 25, 50);
+ spawn.bodyRect(2000, -2325, 75, 100);
+ spawn.bodyRect(2150, -2300, 75, 100);
+ spawn.bodyRect(1975, -2300, 75, 75);
+ spawn.bodyRect(2150, -2300, 75, 75);
+ spawn.bodyRect(2025, -2350, 50, 125);
+ spawn.bodyRect(2250, -2325, 50, 75);
+ spawn.randomMob(2625, -750, 0);
+ spawn.randomMob(3200, -725, 0);
+ spawn.randomMob(2900, -575, 0);
+ spawn.randomMob(700, -1100, 0);
+ spawn.randomMob(3275, -1575, 0);
+ spawn.randomMob(3950, -1500, 0);
+ spawn.randomMob(3725, -1300, 0);
+ spawn.randomMob(3625, -1700, 0);
+ spawn.randomMob(2250, -1675, 0);
+ spawn.randomMob(550, -1875, 0);
+ spawn.randomMob(1600, -700, 0);
+ spawn.randomMob(1050, -400, 0);
+ spawn.randomSmallMob(1085, -1591);
+ spawn.randomSmallMob(1516, -532);
+ spawn.randomGroup(1551, -466, 0.4);
+ if (simulation.difficulty > 1) spawn.randomLevelBoss(3928, -655);
+ spawn.secondaryBossChance(4088, -1744)
+
+ level.custom = () => {
+ level.exit.drawAndCheck();
+
+ level.enter.draw();
+ };
+ },
// ********************************************************************************************************
// ********************************************************************************************************
// ***************************************** training levels **********************************************
diff --git a/js/mob.js b/js/mob.js
index 986f725..d86b9fc 100644
--- a/js/mob.js
+++ b/js/mob.js
@@ -1193,6 +1193,11 @@ const mobs = {
this.alive = false; //triggers mob removal in mob[i].replace(i)
if (this.isDropPowerUp) {
+ // if (true) {
+ // //killing a mob heals for the last damage you took
+
+
+ // }
if (this.isSoonZombie) { //spawn zombie on death
this.leaveBody = false;
let count = 5 //delay spawn cycles
diff --git a/js/player.js b/js/player.js
index 459438c..82bc338 100644
--- a/js/player.js
+++ b/js/player.js
@@ -568,8 +568,8 @@ const m = {
if (tech.squirrelFx !== 1) dmg *= 0.78//Math.pow(0.78, (tech.squirrelFx - 1) / 0.4)
if (tech.isAddBlockMass && m.isHolding) dmg *= 0.1
if (tech.isSpeedHarm && player.speed > 0.1) dmg *= 1 - Math.min(player.speed * 0.0165, 0.66)
- if (tech.isHarmReduce && input.field) dmg *= 0.25
- if (tech.isNeutronium && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.1
+ if (tech.isHarmReduce && input.field) dmg *= 0.15
+ if (tech.isNeutronium && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.05
if (tech.isBotArmor) dmg *= 0.94 ** b.totalBots()
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33;
if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.3
@@ -2043,7 +2043,9 @@ const m = {
}
},
setFieldRegen() {
- if (m.fieldMode === 6) {
+ if (m.fieldMode === 0) {
+ m.fieldRegen = 0.00067 //4 energy per second for field emitter
+ } else if (m.fieldMode === 6) {
m.fieldRegen = 0.002 //12 energy per second for time dilation
} else if (m.fieldMode === 2) {
m.fieldRegen = 0.000833 //5 energy per second perfect dia
@@ -2636,7 +2638,7 @@ const m = {
name: "field emitter",
imageNumber: Math.floor(Math.random() * 23),
description: `initial field
use energy to deflect mobs and throw blocks
-
generate 6 energy per second`, //
100 max energy
+
generate 4 energy per second`, //
100 max energy
effect: () => {
m.hold = function () {
if (m.isHolding) {
@@ -4957,7 +4959,7 @@ const m = {
effect: () => {
m.fieldFire = true;
// m.holdingMassScale = 0.01; //can hold heavier blocks with lower cost to jumping
- m.fieldMeterColor = "#333"
+ // m.fieldMeterColor = "#789"//"#456"
m.eyeFillColor = m.fieldMeterColor
m.grabPowerUpRange2 = 300000 //m.grabPowerUpRange2 = 200000;
// m.fieldHarmReduction = 0.45; //55% reduction
diff --git a/js/powerup.js b/js/powerup.js
index 6ffd71b..f481842 100644
--- a/js/powerup.js
+++ b/js/powerup.js
@@ -621,7 +621,7 @@ const powerUps = {
return 17;
},
effect() {
- const couplingExtraAmmo = m.fieldMode === 10 ? 1 + 0.04 * m.coupling : 1
+ const couplingExtraAmmo = (m.fieldMode === 10 || m.fieldMode === 0) ? 1 + 0.04 * m.coupling : 1
if (b.inventory.length > 0) {
powerUps.animatePowerUpGrab('rgba(68, 102, 119,0.25)')
if (tech.isAmmoForGun && b.activeGun !== null) { //give extra ammo to one gun only with tech logistics
diff --git a/js/spawn.js b/js/spawn.js
index fe8834b..cb45c95 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -7236,6 +7236,7 @@ const spawn = {
m.walk_cycle += m.flipLegs * m.Vx //makes the legs look like they are moving fast
+ // if (simulation.fpsCap > 999){}
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
ctx.fillStyle = "#fff";
diff --git a/js/tech.js b/js/tech.js
index 2c835f9..963939c 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -218,7 +218,7 @@ const tech = {
}
},
hasExplosiveDamageCheck() {
- return tech.haveGunCheck("missiles") || (m.fieldMode === 4 && simulation.molecularMode === 1) || tech.missileBotCount > 0 || tech.isBoomBotUpgrade || tech.isIncendiary || tech.isPulseLaser || tech.isTokamak || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb)
+ return tech.haveGunCheck("missiles") || (m.fieldMode === 4 && simulation.molecularMode === 1) || tech.missileBotCount > 0 || tech.isBoomBotUpgrade || tech.isIncendiary || tech.isPulseLaser || tech.isTokamak || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.isHookExplosion
},
damage: 1, //used for tech changes to player damage that don't have complex conditions
damageFromTech() {
@@ -232,7 +232,7 @@ const tech = {
// }
// }
if (tech.isDivisor && b.activeGun && b.guns[b.activeGun].ammo % 3 === 0) dmg *= 1.77
- if (tech.isNoGroundDamage) dmg *= m.onGround ? 0.75 : 2
+ if (tech.isNoGroundDamage) dmg *= m.onGround ? 0.85 : 2
if (tech.isDilate) dmg *= 1.5 + 0.6 * Math.sin(m.cycle * 0.0075)
if (tech.isGunChoice && tech.buffedGun === b.inventoryGun) dmg *= 1 + 0.31 * b.inventory.length
if (powerUps.boost.endCycle > m.cycle) dmg *= 1 + powerUps.boost.damage
@@ -2047,9 +2047,9 @@ const tech = {
frequency: 1,
frequencyDefault: 1,
allowed() {
- return m.fieldMode !== 9 && !tech.isTokamak
+ return m.fieldMode !== 9 && !tech.isTokamak && !tech.isReel
},
- requires: "not wormhole, tokamak",
+ requires: "not wormhole, reel, tokamak",
effect() {
tech.blockDamage = 0.3
},
@@ -5670,7 +5670,7 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
- return !tech.isImmuneExplosion && (build.isExperimentSelection || powerUps.research.count > 1) && (tech.haveGunCheck("missiles") || (m.fieldMode === 4 && simulation.molecularMode === 1) || tech.missileBotCount > 0 || tech.isIncendiary || tech.isPulseLaser || tech.isTokamak || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb))
+ return !tech.isImmuneExplosion && (build.isExperimentSelection || powerUps.research.count > 1) && (tech.haveGunCheck("missiles") || (m.fieldMode === 4 && simulation.molecularMode === 1) || tech.missileBotCount > 0 || tech.isIncendiary || tech.isPulseLaser || tech.isTokamak || tech.isHookExplosion || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb))
},
requires: "an explosive damage source, not rocket propelled grenade",
effect() {
@@ -6780,7 +6780,7 @@ const tech = {
name: "capacitor bank",
// description: "charge effects build up almost instantly
throwing blocks, foam, railgun, pulse, tokamak",
descriptionFunction() {
- return `charge effects build up almost instantly
throwing, ${tech.haveGunCheck("foam", false) ? "foam" : "foam"}, ${tech.isPlasmaBall ? "plasma ball" : "plasma ball"}, ${tech.isRailGun ? "railgun" : "railgun"}, ${tech.isPulseLaser ? "pulse" : "pulse"}, ${tech.isTokamak ? "tokamak" : "tokamak"}`
+ return `charge effects build up almost instantly
blocks, ${tech.haveGunCheck("foam", false) ? "foam" : "foam"}, ${tech.isPlasmaBall ? "plasma ball" : "plasma ball"}, ${tech.isRailGun ? "railgun" : "railgun"}, ${tech.isPulseLaser ? "pulse" : "pulse"}, ${tech.isTokamak ? "tokamak" : "tokamak"}`
},
isGunTech: true,
maxCount: 1,
@@ -6917,6 +6917,25 @@ const tech = {
tech.isRailEnergy = false;
}
},
+ {
+ name: "autonomous defense",
+ description: "if you collide with a mob
fire harpoons at nearby mobs",
+ isGunTech: true,
+ maxCount: 1,
+ count: 0,
+ frequency: 2,
+ frequencyDefault: 2,
+ allowed() {
+ return tech.haveGunCheck("harpoon")
+ },
+ requires: "harpoon",
+ effect() {
+ tech.isHarpoonDefense = true
+ },
+ remove() {
+ tech.isHarpoonDefense = false
+ }
+ },
{
name: "Bessemer process",
descriptionFunction() {
@@ -7718,7 +7737,7 @@ const tech = {
},
{
name: "neutronium",
- description: `move and jump 20% slower
if your field is active +90% defense`,
+ description: `move and jump 20% slower
if your field is active +95% defense`,
isFieldTech: true,
maxCount: 1,
count: 0,
@@ -7746,7 +7765,7 @@ const tech = {
},
{
name: "aerostat",
- description: `+100% damage while off the ground
-25% damage while on the ground`,
+ description: `+100% damage while off the ground
-15% damage while on the ground`,
isFieldTech: true,
maxCount: 1,
count: 0,
@@ -8102,9 +8121,9 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
- return (m.fieldMode === 5 || m.fieldMode === 4) && !tech.isPrinter
+ return (m.fieldMode === 5 || m.fieldMode === 4 || m.fieldMode === 10) && !tech.isPrinter && !tech.isReel
},
- requires: "plasma torch, molecular assembler, not printer",
+ requires: "plasma torch, molecular assembler, grappling hook, not printer, reel",
effect() {
tech.isTokamak = true;
},
@@ -8114,7 +8133,7 @@ const tech = {
},
{
name: "degenerate matter",
- description: "if your field is active
+75% defense",
+ description: "if your field is active
+85% defense",
isFieldTech: true,
maxCount: 1,
count: 0,
@@ -8755,7 +8774,7 @@ const tech = {
}
},
{
- name: "autonomous defense",
+ name: "CIWS",
description: "grappling hook uses 20 energy
to fire harpoons at nearby mobs",
isFieldTech: true,
maxCount: 1,
@@ -8792,8 +8811,29 @@ const tech = {
tech.isHookExplosion = false
}
},
+ {
+ name: "reel",
+ description: "+400% block collision damage
+30 energy when reeling in far away blocks",
+ isFieldTech: true,
+ maxCount: 1,
+ count: 0,
+ frequency: 1,
+ frequencyDefault: 1,
+ allowed() {
+ return m.fieldMode === 10 && !tech.isTokamak && tech.blockDamage === 0.075
+ },
+ requires: "not mass driver",
+ effect() {
+ tech.blockDamage = 0.375
+ tech.isReel = true
+ },
+ remove() {
+ tech.blockDamage = 0.075
+ tech.isReel = false
+ }
+ },
// {
- // name: "autonomous defense",
+ // name: "CIWS",
// description: "if you collide with a mob
fire harpoons at nearby mobs",
// isFieldTech: true,
// maxCount: 1,
@@ -11879,4 +11919,6 @@ const tech = {
// isHookWire: null,
isHookDefense: null,
isHookExplosion: null,
+ isHarpoonDefense: null,
+ isReel: null,
}
\ No newline at end of file
diff --git a/todo.txt b/todo.txt
index bd298b9..024fe8e 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,28 +1,34 @@
******************************************************** NEXT PATCH **************************************************
-grappling hook
- added coupling effect - 4% extra ammo per coupling
- doesn't destroy blocks, instead the player grabs blocks
- doesn't automatically retract after hitting power ups
- improved momentum conservation on yank and catching blocks, power ups
- removed accidental 55% defense for grapple field
- tech (no images yet)
- autonomous defense - fire harpoons at nearby mobs
- rupture - explosion on impact with map, block, mob
+new community level shipwreck by 3xionDev
-negative mass field has horizontal block motion by default
-fixed tech sorting by "allowed tech" in experiment mode
+grappling hook
+ tech: reel - increase block damage 400%, generate 30 energy after hooking blocks
+ added tokamak to grappling hook
+ updated rope graphics
+ added input.up to adjust positioning while hook is attached
+ added images for CIWS, rupture, autonomous defense
+ aerostat: 25->15% reduced damage on ground
+ rupture unlocks explosive tech
+ rupture destroys blocks
+ autonomous defense renamed to CIWS
+
+field emitter 6->4 base energy regen
+tech: autonomous defense - harpoon tech that fires harpoons after taking damage
+degenerate matter: 75->85% defense while field is active
+neutronium: 90->95% defense while field is active
+unified field theory no longer has field emitter as an option
*********************************************************** TODO *****************************************************
-grappling hook is a field
+player got stuck inside block that wasn't pick up able
+
+grappling hook field
check for places that the player could get into but not out of
field tech ideas
- hook and line stuns?
- increase hook damage
- hook damage aura
- hook's line does damage
- generate ___ after destroying blocks
+ Buoyancy - aerostat, but for defense: +70% defense while off the ground
+ too similar to degenerate matter
+ generate ___ after destroying blocks
energy, drones, iceIX, explosion, nails, junk bots?
tech - killing a mob heals for the last damage you took
@@ -30,6 +36,10 @@ tech - killing a mob heals for the last damage you took
heal for 50%?
heal from mob damage or from kills?
+on sucker mob death trigger radiation damage AoE and a graphic (Hawking radiation)
+
+tech prismatic laser - cycles between different laser colors every 1-2 seconds
+
make phonon the default wave gun type and make a tech to switch to the normal wave beam
nerf phonon, buff wave
@@ -1095,6 +1105,7 @@ add sounds
******************************************************** LORE ********************************************************
possible names for tech
+ sidereal - with respect to the stars (an extra rotation for time keeping)
strange loop
holonomy - parallel transport of a vector leads to movement (applies to curved space)
hypergolic - A hypergolic propellant combination used in a rocket engine is one whose components spontaneously ignite when they come into contact with each other.