diff --git a/.DS_Store b/.DS_Store
index 3a8ed2b..904cd0a 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/js/bullet.js b/js/bullet.js
index 48f4efc..fefa9e2 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -957,23 +957,16 @@ const b = {
bullet[me].beforeDmg = function() {};
bullet[me].stuck = function() {};
bullet[me].do = function() {
- function onCollide(that) {
- that.collisionFilter.mask = 0; //non collide with everything
- Matter.Body.setVelocity(that, {
- x: 0,
- y: 0
- });
- if (tech.isRPG) that.thrust = {
- x: 0,
- y: 0
- }
- that.do = that.radiationMode;
- // if (collides(that, map).length || Matter.Query.collides(that, body).length || Matter.Query.collides(that, mob).length) {
+ const onCollide = () => {
+ this.collisionFilter.mask = 0; //non collide with everything
+ Matter.Body.setVelocity(this, { x: 0, y: 0 });
+ if (tech.isRPG) this.thrust = { x: 0, y: 0 }
+ this.do = this.radiationMode;
}
const mobCollisions = Matter.Query.collides(this, mob)
if (mobCollisions.length) {
- onCollide(this)
+ onCollide()
this.stuckTo = mobCollisions[0].bodyA
mobs.statusDoT(this.stuckTo, 0.5, 360) //apply radiation damage status effect on direct hits
@@ -1002,7 +995,7 @@ const b = {
const bodyCollisions = Matter.Query.collides(this, body)
if (bodyCollisions.length) {
if (!bodyCollisions[0].bodyA.isNotHoldable) {
- onCollide(this)
+ onCollide()
this.stuckTo = bodyCollisions[0].bodyA
//find the relative position for when the mob is at angle zero by undoing the mobs rotation
this.stuckToRelativePosition = Vector.rotate(Vector.sub(this.position, this.stuckTo.position), -this.stuckTo.angle)
@@ -1020,7 +1013,7 @@ const b = {
}
} else {
if (Matter.Query.collides(this, map).length) {
- onCollide(this)
+ onCollide()
} else if (tech.isRPG) { //if colliding with nothing
this.force.x += this.thrust.x;
this.force.y += this.thrust.y;
@@ -1142,7 +1135,7 @@ const b = {
// const futurePos = this.lockedOn ? :Vector.add(this.position, Vector.mult(this.velocity, 50))
for (let i = 0, len = mob.length; i < len; ++i) {
if (
- mob[i].alive && !mob[i].isBadTarget && !mob[i].isBadTarget &&
+ mob[i].alive && !mob[i].isBadTarget &&
Matter.Query.ray(map, this.position, mob[i].position).length === 0
// && Matter.Query.ray(body, this.position, mob[i].position).length === 0
) {
@@ -1525,7 +1518,8 @@ const b = {
});
if (tech.isLaserPush) { //push mobs away
const index = path.length - 1
- const force = Vector.mult(Vector.normalise(Vector.sub(path[index], path[Math.max(0, index - 1)])), 0.0035 * push * Math.min(6, best.who.mass))
+ Matter.Body.setVelocity(best.who, { x: best.who.velocity.x * 0.94, y: best.who.velocity.y * 0.94 });
+ const force = Vector.mult(Vector.normalise(Vector.sub(path[index], path[Math.max(0, index - 1)])), 0.006 * push * Math.min(6, best.who.mass))
Matter.Body.applyForce(best.who, path[index], force)
}
}
@@ -3123,7 +3117,11 @@ const b = {
if (this.cd < simulation.cycle && !(simulation.cycle % this.lookFrequency) && !m.isCloak) {
for (let i = 0, len = mob.length; i < len; i++) {
const dist2 = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position));
- if (Matter.Query.ray(map, this.position, mob[i].position).length === 0 && dist2 > 250000) {
+ if (
+ mob[i].alive && !mob[i].isBadTarget &&
+ dist2 > 250000 &&
+ Matter.Query.ray(map, this.position, mob[i].position).length === 0
+ ) {
this.cd = simulation.cycle + this.delay;
const angle = Vector.angle(this.position, mob[i].position)
Matter.Body.setAngle(this, angle)
@@ -4750,48 +4748,30 @@ const b = {
name: "drones",
description: "deploy drones that crash into mobs
crashes reduce their lifespan by 1 second",
ammo: 0,
- ammoPack: 14,
- defaultAmmoPack: 14,
+ ammoPack: 14.5,
+ defaultAmmoPack: 14.5,
have: false,
do() {},
fire() {
if (tech.isDroneRadioactive) {
if (m.crouch) {
b.droneRadioactive({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 45)
- m.fireCDcycle = m.cycle + Math.floor(5 * 13 * b.fireCDscale); // cool down
+ m.fireCDcycle = m.cycle + Math.floor(50 * b.fireCDscale); // cool down
} else {
b.droneRadioactive({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 10)
- m.fireCDcycle = m.cycle + Math.floor(5 * 6 * b.fireCDscale); // cool down
+ m.fireCDcycle = m.cycle + Math.floor(25 * b.fireCDscale); // cool down
}
} else {
if (m.crouch) {
- b.drone({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 45)
- m.fireCDcycle = m.cycle + Math.floor(13 * b.fireCDscale); // cool down
+ b.drone({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 55)
+ m.fireCDcycle = m.cycle + Math.floor(10 * b.fireCDscale); // cool down
} else {
- b.drone()
- m.fireCDcycle = m.cycle + Math.floor(6 * b.fireCDscale); // cool down
+ b.drone({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 20)
+ m.fireCDcycle = m.cycle + Math.floor(5 * b.fireCDscale); // cool down
}
}
}
},
- // {
- // name: "ice IX",
- // description: "synthesize short-lived ice crystals
crystals seek out and freeze mobs",
- // ammo: 0,
- // ammoPack: 64,
- // have: false,
- // do() {},
- // fire() {
- // if (m.crouch) {
- // b.iceIX(10, 0.3)
- // m.fireCDcycle = m.cycle + Math.floor(8 * b.fireCDscale); // cool down
- // } else {
- // b.iceIX(2)
- // m.fireCDcycle = m.cycle + Math.floor(3 * b.fireCDscale); // cool down
- // }
-
- // }
- // },
{
name: "foam",
description: "spray bubbly foam that sticks to mobs
slows mobs and does damage over time",
@@ -4812,7 +4792,36 @@ const b = {
if (this.isDischarge) {
this.charge--
- this.fireFoam()
+ const spread = (m.crouch ? 0.05 : 0.6) * (Math.random() - 0.5)
+ const radius = 5 + 8 * Math.random() + (tech.isAmmoFoamSize && this.ammo < 300) * 12
+ const SPEED = 18 - radius * 0.4;
+ const dir = m.angle + 0.15 * (Math.random() - 0.5)
+ const velocity = {
+ x: SPEED * Math.cos(dir),
+ y: SPEED * Math.sin(dir)
+ }
+ const position = {
+ x: m.pos.x + 30 * Math.cos(m.angle),
+ y: m.pos.y + 30 * Math.sin(m.angle)
+ }
+ if (tech.foamFutureFire) {
+ simulation.drawList.push({ //add dmg to draw queue
+ x: position.x,
+ y: position.y,
+ radius: 5,
+ color: "rgba(0,50,50,0.3)",
+ time: 15 * tech.foamFutureFire
+ });
+ setTimeout(() => {
+ if (!simulation.paused) {
+ b.foam(position, Vector.rotate(velocity, spread), radius)
+ // (tech.isFastFoam ? 0.044 : 0.011) * (tech.isFoamTeleport ? 1.60 : 1)
+ bullet[bullet.length - 1].damage *= (1 + 0.75 * tech.foamFutureFire)
+ }
+ }, 250 * tech.foamFutureFire);
+ } else {
+ b.foam(position, Vector.rotate(velocity, spread), radius)
+ }
m.fireCDcycle = m.cycle + 1; //disable firing and adding more charge
} else if (!input.fire) {
this.isDischarge = true;
@@ -4825,38 +4834,6 @@ const b = {
this.charge++
m.fireCDcycle = m.cycle + Math.floor((1 + 0.35 * this.charge) * b.fireCDscale);
},
- fireFoam() {
- const spread = (m.crouch ? 0.05 : 0.6) * (Math.random() - 0.5)
- const radius = 5 + 8 * Math.random() + (tech.isAmmoFoamSize && this.ammo < 300) * 12
- const SPEED = 18 - radius * 0.4;
- const dir = m.angle + 0.15 * (Math.random() - 0.5)
- const velocity = {
- x: SPEED * Math.cos(dir),
- y: SPEED * Math.sin(dir)
- }
- const position = {
- x: m.pos.x + 30 * Math.cos(m.angle),
- y: m.pos.y + 30 * Math.sin(m.angle)
- }
- if (tech.foamFutureFire) {
- simulation.drawList.push({ //add dmg to draw queue
- x: position.x,
- y: position.y,
- radius: 5,
- color: "rgba(0,50,50,0.3)",
- time: 15 * tech.foamFutureFire
- });
- setTimeout(() => {
- if (!simulation.paused) {
- b.foam(position, Vector.rotate(velocity, spread), radius)
- // (tech.isFastFoam ? 0.044 : 0.011) * (tech.isFoamTeleport ? 1.60 : 1)
- bullet[bullet.length - 1].damage *= (1 + 0.75 * tech.foamFutureFire)
- }
- }, 250 * tech.foamFutureFire);
- } else {
- b.foam(position, Vector.rotate(velocity, spread), radius)
- }
- }
}, {
name: "rail gun",
description: "use energy to launch a high-speed dense rod
hold left mouse to charge, release to fire",
diff --git a/js/level.js b/js/level.js
index d862f56..628f13e 100644
--- a/js/level.js
+++ b/js/level.js
@@ -12,7 +12,7 @@ const level = {
start() {
if (level.levelsCleared === 0) { //this code only runs on the first level
// localSettings.levelsClearedLastGame = 10
- // level.difficultyIncrease(10) //30 is near max on hard //60 is near max on why
+ // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
// simulation.isHorizontalFlipped = true
// tech.isFieldFree = true
// m.setField("perfect diamagnetism")
@@ -2267,12 +2267,16 @@ const level = {
spawn.mapRect(5050, -100, 50, 150);
spawn.mapRect(4850, -275, 50, 175);
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
- // spawn.starter(1900, -500, 200) //big boy
+ spawn.starter(1900, -500, 200) //big boy
+ // spawn.spiderBoss(1900, -500)
+ // spawn.laserBombingBoss(1900, -500)
+ // for (let i = 0; i < 5; i++) spawn.focuser(1900, -500)
+
// spawn.growBossCulture(1900, -500)
- spawn.laserBombingBoss(1900, -500)
- // spawn.snakeSpitBoss(1900, -500)
- // spawn.growBossCulture(1900, -500)
- // spawn.sneaker(1900, -500)
+ spawn.sneaker(1900, -500)
+ spawn.sneaker(1900, -500)
+ spawn.shield(mob[mob.length - 1], 1900, -500, 1);
+ // mob[mob.length - 1].isShielded = true
// spawn.historyBoss(1200, -500)
// spawn.laserTargetingBoss(1600, -400)
// spawn.focuser(1600, -500)
@@ -2284,7 +2288,6 @@ const level = {
// spawn.cellBossCulture(1600, -500)
// spawn.laserTargetingBoss(1600, -500)
// spawn.grenadierBoss(1200, -500)
- // spawn.shield(mob[mob.length - 1], 1800, -120, 1);
// spawn.nodeGroup(1200, -500, "grenadier")
// spawn.snakeBoss(1200, -500)
diff --git a/js/lore.js b/js/lore.js
index d02b2c6..388f0e8 100644
--- a/js/lore.js
+++ b/js/lore.js
@@ -305,7 +305,7 @@ const lore = {
lore.talkingColor = "#dff"
level.isHazardRise = true
//remove all bullets, so they can't get endless energy
- for (let i = 0; i < bullet.length; ++i) Matter.Composite.remove(engine.world, bullet[i]);
+ for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
bullet = [];
setTimeout(() => { lore.anand.text("I'm actually surprised you haven't been attacked by the adversarial network this time.") }, 500);
},
diff --git a/js/player.js b/js/player.js
index 95797e1..7584699 100644
--- a/js/player.js
+++ b/js/player.js
@@ -1332,12 +1332,13 @@ const m = {
for (let i = 0, len = mob.length; i < len; ++i) {
if (
Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < m.fieldRange &&
- !mob[i].isShielded &&
m.lookingAt(mob[i]) &&
+ !mob[i].isUnblockable &&
Matter.Query.ray(map, mob[i].position, m.pos).length === 0
) {
mob[i].locatePlayer();
m.pushMass(mob[i]);
+ if (mob[i].isShielded) m.fieldCDcycle = m.cycle + 60
}
}
},
@@ -1499,7 +1500,7 @@ const m = {
ctx.fill();
//360 block
for (let i = 0, len = mob.length; i < len; ++i) {
- if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < netfieldRange && !mob[i].isShielded) { // && Matter.Query.ray(map, mob[i].position, m.pos).length === 0
+ if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < netfieldRange && !mob[i].isUnblockable) { // && Matter.Query.ray(map, mob[i].position, m.pos).length === 0
mob[i].locatePlayer();
if (this.drainCD > m.cycle) {
m.pushMass(mob[i], 0);
@@ -1507,6 +1508,7 @@ const m = {
m.pushMass(mob[i]);
this.drainCD = m.cycle + 10
}
+ if (mob[i].isShielded) m.fieldCDcycle = m.cycle + 45
}
}
}
@@ -1527,7 +1529,7 @@ const m = {
}
//360 block
for (let i = 0, len = mob.length; i < len; ++i) {
- if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < radius && !mob[i].isShielded) { // && Matter.Query.ray(map, mob[i].position, m.pos).length === 0
+ if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < radius && !mob[i].isUnblockable) { // && Matter.Query.ray(map, mob[i].position, m.pos).length === 0
mob[i].locatePlayer();
if (this.drainCD > m.cycle) {
m.pushMass(mob[i], 0);
@@ -1535,6 +1537,7 @@ const m = {
m.pushMass(mob[i]);
this.drainCD = m.cycle + 10
}
+ if (mob[i].isShielded) m.fieldCDcycle = m.cycle + 45
}
}
}
@@ -1584,27 +1587,25 @@ const m = {
m.fieldPosition = { x: m.pos.x, y: m.pos.y }
m.fieldAngle = m.angle
m.perfectPush = (isFree = false) => {
- for (let i = 0, len = mob.length; i < len; ++i) {
- if (
- Vector.magnitude(Vector.sub(mob[i].position, m.fieldPosition)) - mob[i].radius < m.fieldRange &&
- !mob[i].isShielded &&
- Vector.dot({ x: Math.cos(m.fieldAngle), y: Math.sin(m.fieldAngle) }, Vector.normalise(Vector.sub(mob[i].position, m.fieldPosition))) > m.fieldThreshold &&
- Matter.Query.ray(map, mob[i].position, m.fieldPosition).length === 0
- ) {
- mob[i].locatePlayer();
-
- const unit = Vector.normalise(Vector.sub(m.fieldPosition, mob[i].position))
- if (m.fieldCDcycle < m.cycle) {
- m.fieldCDcycle = m.cycle + m.fieldBlockCD;
+ if (m.fieldCDcycle < m.cycle) {
+ for (let i = 0, len = mob.length; i < len; ++i) {
+ if (
+ Vector.magnitude(Vector.sub(mob[i].position, m.fieldPosition)) - mob[i].radius < m.fieldRange &&
+ !mob[i].isUnblockable &&
+ Vector.dot({ x: Math.cos(m.fieldAngle), y: Math.sin(m.fieldAngle) }, Vector.normalise(Vector.sub(mob[i].position, m.fieldPosition))) > m.fieldThreshold &&
+ Matter.Query.ray(map, mob[i].position, m.fieldPosition).length === 0
+ ) {
+ mob[i].locatePlayer();
+ const unit = Vector.normalise(Vector.sub(m.fieldPosition, mob[i].position))
+ m.fieldCDcycle = m.cycle + m.fieldBlockCD + (mob[i].isShielded ? 15 : 0);
if (tech.blockingIce) {
for (let i = 0; i < tech.blockingIce; i++) {
const angle = m.fieldAngle + 1.55 * (Math.random() - 0.5)
b.iceIX(10, angle, Vector.add(m.fieldPosition, { x: m.fieldRange * Math.cos(angle), y: m.fieldRange * Math.sin(angle) }))
}
}
- if (tech.blockDmg) {
+ if (tech.blockDmg) { //electricity
mob[i].damage(tech.blockDmg * b.dmgScale)
- //draw electricity
const step = 40
ctx.beginPath();
for (let i = 0, len = 1.5 * tech.blockDmg; i < len; i++) {
@@ -1622,32 +1623,9 @@ const m = {
ctx.stroke();
} else if (isFree) {
//when blocking draw this graphic
- // const len = mob[i].vertices.length - 1;
ctx.fillStyle = "rgba(110,170,200," + (0.2 + 0.4 * Math.random()) + ")";
ctx.lineWidth = 2;
ctx.strokeStyle = "#000";
- // const angleOff = m.fieldAngle + 2 * m.fieldArc * (Math.random() - 0.5)
- // const off = {
- // x: m.fieldRange * Math.cos(angleOff),
- // y: m.fieldRange * Math.sin(angleOff),
- // }
- // const where = Vector.add(m.fieldPosition, off)
- // ctx.beginPath();
- // ctx.moveTo(where.x, where.y);
- // ctx.lineTo(mob[i].vertices[len].x, mob[i].vertices[len].y);
- // ctx.lineTo(mob[i].vertices[0].x, mob[i].vertices[0].y);
- // ctx.fill();
- // ctx.stroke();
- // for (let j = 0; j < len; j++) {
- // ctx.beginPath();
- // ctx.moveTo(where.x, where.y);
- // ctx.lineTo(mob[i].vertices[j].x, mob[i].vertices[j].y);
- // ctx.lineTo(mob[i].vertices[j + 1].x, mob[i].vertices[j + 1].y);
- // ctx.fill();
- // ctx.stroke();
- // }
-
-
const len = mob[i].vertices.length - 1;
const mag = mob[i].radius
ctx.beginPath();
@@ -1681,31 +1659,26 @@ const m = {
}
}
if (tech.isStunField) mobs.statusStun(mob[i], tech.isStunField)
- //knock backs
- const massRoot = Math.sqrt(Math.max(0.15, mob[i].mass));
+ //mob knock backs
+ const massRoot = Math.sqrt(Math.max(1, mob[i].mass));
Matter.Body.setVelocity(mob[i], {
- x: player.velocity.x - (20 * unit.x) / massRoot,
- y: player.velocity.y - (20 * unit.y) / massRoot
+ x: player.velocity.x - (30 * unit.x) / massRoot,
+ y: player.velocity.y - (30 * unit.y) / massRoot
});
if (mob[i].isOrbital) Matter.Body.setVelocity(mob[i], { x: 0, y: 0 });
- }
-
- if (isFree) {
-
- } else {
- if (mob[i].isDropPowerUp && player.speed < 12) {
- const massRootCap = Math.sqrt(Math.min(10, Math.max(0.2, mob[i].mass)));
- Matter.Body.setVelocity(player, {
- x: 0.9 * player.velocity.x + 0.6 * unit.x * massRootCap,
- y: 0.9 * player.velocity.y + 0.6 * unit.y * massRootCap
- });
+ if (!isFree) { //player knock backs
+ if (mob[i].isDropPowerUp && player.speed < 12) {
+ const massRootCap = Math.sqrt(Math.min(10, Math.max(0.2, mob[i].mass)));
+ Matter.Body.setVelocity(player, {
+ x: 0.9 * player.velocity.x + 0.6 * unit.x * massRootCap,
+ y: 0.9 * player.velocity.y + 0.6 * unit.y * massRootCap
+ });
+ }
}
}
-
}
}
}
-
m.hold = function() {
const wave = Math.sin(m.cycle * 0.022);
m.fieldRange = 190 + 12 * wave
@@ -1744,13 +1717,12 @@ const m = {
cp1y = m.pos.y + curve * m.fieldRange * Math.sin(a)
ctx.quadraticCurveTo(cp1x, cp1y, m.pos.x + 1 * m.fieldRange * Math.cos(m.angle - Math.PI * m.fieldArc), m.pos.y + 1 * m.fieldRange * Math.sin(m.angle - Math.PI * m.fieldArc))
ctx.fill();
- // m.pushMobsFacing();
m.perfectPush();
} 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 (tech.isFieldFree && !input.field) {
+ if (!input.field) { //tech.isFieldFre
//draw field free of player
ctx.fillStyle = "rgba(110,170,200," + (0.27 + 0.2 * Math.random() - 0.1 * wave) + ")";
ctx.strokeStyle = "rgba(110, 200, 235, " + (0.4 + 0.5 * Math.random()) + ")"
@@ -1769,7 +1741,7 @@ const m = {
}
m.drawFieldMeter()
if (tech.isPerfectBrake) { //cap mob speed around player
- const range = 160 + 140 * wave + 200 * m.energy
+ const range = 200 + 140 * wave + 150 * m.energy
for (let i = 0; i < mob.length; i++) {
const distance = Vector.magnitude(Vector.sub(m.pos, mob[i].position))
if (distance < range) {
@@ -2705,6 +2677,26 @@ const m = {
y: powerUp[i].velocity.y * 0.05
});
if (dist2 < 1000 && !simulation.isChoosing) { //use power up if it is close enough
+
+ // if (true) { //AoE radiation effect
+ // const range = 800
+
+ // for (let i = 0, len = mob.length; i < len; ++i) {
+ // if (mob[i].alive && !mob[i].isShielded) {
+ // dist = Vector.magnitude(Vector.sub(powerUp[i].position, mob[i].position)) - mob[i].radius;
+ // if (dist < range) mobs.statusDoT(mob[i], 0.5) //apply radiation damage status effect on direct hits
+ // }
+ // }
+
+ // simulation.drawList.push({
+ // x: powerUp[i].position.x,
+ // y: powerUp[i].position.y,
+ // radius: range,
+ // color: "rgba(0,150,200,0.3)",
+ // time: 4
+ // });
+ // }
+
m.fieldRange *= 0.8
powerUps.onPickUp(powerUp[i]);
powerUp[i].effect();
@@ -2846,19 +2838,19 @@ const m = {
) {
const sub = Vector.sub(simulation.mouseInGame, m.pos)
const mag = Vector.magnitude(sub)
- const drain = 0.03 + 0.005 * Math.sqrt(mag)
+ const drain = 0.06 + 0.006 * Math.sqrt(mag)
if (m.energy > drain && mag > 300) {
m.energy -= drain
m.hole.isReady = false;
m.fieldRange = 0
Matter.Body.setPosition(player, simulation.mouseInGame);
m.buttonCD_jump = 0 //this might fix a bug with jumping
- const velocity = Vector.mult(Vector.normalise(sub), 18)
+ const velocity = Vector.mult(Vector.normalise(sub), 20)
Matter.Body.setVelocity(player, {
x: velocity.x,
y: velocity.y - 4 //an extra vertical kick so the player hangs in place longer
});
- if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage
+ if (m.immuneCycle < m.cycle + 15) m.immuneCycle = m.cycle + 15; //player is immune to damage for 1/4 seconds
// move bots to player
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType) {
diff --git a/js/simulation.js b/js/simulation.js
index e1c572e..25cbf5c 100644
--- a/js/simulation.js
+++ b/js/simulation.js
@@ -812,13 +812,13 @@ const simulation = {
if (tech.isFlipFlopOn) {
if (m.immuneCycle < m.cycle) m.energy += 0.22;
} else {
- m.energy -= 0.041;
+ m.energy -= 0.022;
if (m.energy < 0) m.energy = 0
}
}
if (tech.relayIce && tech.isFlipFlopOn) {
for (let j = 0; j < tech.relayIce; j++) {
- for (let i = 0, len = Math.ceil(8 * Math.random()); i < len; i++) b.iceIX(2)
+ for (let i = 0, len = Math.ceil(9 * Math.random()); i < len; i++) b.iceIX(2)
}
}
diff --git a/js/spawn.js b/js/spawn.js
index e4fadf7..af38da7 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -110,6 +110,7 @@ const spawn = {
me.isShielded = true; //makes it immune to damage
me.leaveBody = false;
me.isBadTarget = true;
+ me.isUnblockable = true;
me.isDropPowerUp = false;
me.showHealthBar = false;
me.collisionFilter.category = 0;
@@ -166,6 +167,7 @@ const spawn = {
me.isShielded = true; //makes it immune to damage
me.leaveBody = false;
me.isBadTarget = true;
+ me.isUnblockable = true;
me.isDropPowerUp = false;
me.showHealthBar = false;
me.collisionFilter.category = 0;
@@ -1998,19 +2000,19 @@ const spawn = {
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
Matter.Body.rotate(me, Math.random() * Math.PI * 2);
- me.accelMag = 0.0005 * Math.sqrt(simulation.accelScale);
+ me.accelMag = 0.00055 * Math.sqrt(simulation.accelScale);
me.seePlayerFreq = Math.floor(30 * simulation.lookFreqScale);
me.memory = 420;
me.restitution = 1;
me.frictionAir = 0.05;
me.frictionStatic = 0;
me.friction = 0;
- me.lookTorque = 0.000005 * (Math.random() > 0.5 ? -1 : 1);
+ me.lookTorque = 0.0000055 * (Math.random() > 0.5 ? -1 : 1) * (1 + 0.1 * Math.sqrt(simulation.difficulty))
me.fireDir = {
x: 0,
y: 0
}
- Matter.Body.setDensity(me, 0.008); //extra dense //normal is 0.001 //makes effective life much larger
+ Matter.Body.setDensity(me, 0.01); //extra dense //normal is 0.001 //makes effective life much larger
spawn.shield(me, x, y, 1);
spawn.spawnOrbitals(me, radius + 200 + 300 * Math.random())
me.onHit = function() {};
@@ -2019,7 +2021,7 @@ const spawn = {
};
me.damageReduction = 0.25
me.targetingCount = 0;
- me.targetingTime = 60 - Math.min(55, 2 * simulation.difficulty)
+ me.targetingTime = 60 - Math.min(58, 3 * simulation.difficulty)
me.do = function() {
// this.armor();
this.seePlayerByLookingAt();
@@ -2103,7 +2105,7 @@ const spawn = {
this.targetingCount -= 10;
const sub = Vector.sub(player.position, this.position)
const dist = Vector.magnitude(sub)
- const speed = 30
+ const speed = Math.min(55, 5 + 20 * simulation.accelScale)
const velocity = Vector.mult(Vector.normalise(sub), speed)
spawn.grenade(this.vertices[1].x, this.vertices[1].y, dist / speed, Math.min(550, 250 + simulation.difficulty * 3), 6); // grenade(x, y, lifeSpan = 90 + Math.ceil(60 / simulation.accelScale), pulseRadius = Math.min(550, 250 + simulation.difficulty * 3), size = 4) {
Matter.Body.setVelocity(mob[mob.length - 1], velocity);
@@ -2125,15 +2127,15 @@ const spawn = {
ctx.moveTo(this.vertices[1].x, this.vertices[1].y);
ctx.lineTo(best.x, best.y);
ctx.strokeStyle = "rgba(0,235,255,1)";
- ctx.lineWidth = 2
+ ctx.lineWidth = 3
ctx.stroke();
if (this.targetingCount / this.targetingTime > 0.33) {
- ctx.strokeStyle = "rgba(0,235,255,0.4)";
- ctx.lineWidth = 8
+ ctx.strokeStyle = "rgba(0,235,255,0.45)";
+ ctx.lineWidth = 10
ctx.stroke();
if (this.targetingCount / this.targetingTime > 0.66) {
- ctx.strokeStyle = "rgba(0,235,255,0.2)";
- ctx.lineWidth = 25
+ ctx.strokeStyle = "rgba(0,235,255,0.25)";
+ ctx.lineWidth = 30
ctx.stroke();
}
}
@@ -2144,20 +2146,20 @@ const spawn = {
};
},
blinkBoss(x, y) {
- mobs.spawn(x, y, 5, 50, "rgb(215,80,190)"); //"rgb(221,102,119)"
+ mobs.spawn(x, y, 5, 50, "rgb(0,235,255)"); //"rgb(221,102,119)"
let me = mob[mob.length - 1];
Matter.Body.rotate(me, Math.PI * 0.1);
- Matter.Body.setDensity(me, 0.02); //extra dense //normal is 0.001 //makes effective life much larger
+ Matter.Body.setDensity(me, 0.018); //extra dense //normal is 0.001 //makes effective life much larger
me.isBoss = true;
me.frictionStatic = 0;
me.friction = 0;
me.memory = 240
me.seePlayerFreq = 60
- me.delay = 20 + 30 * simulation.CDScale;
+ me.delay = 25 + 30 * simulation.CDScale;
me.nextBlinkCycle = me.delay;
me.blinkRange = 235
- me.grenadeDelay = 30 + 60 * simulation.CDScale
+ me.grenadeDelay = 35 + 60 * simulation.CDScale
me.pulseRadius = 2 * Math.min(550, 220 + simulation.difficulty * 4)
spawn.shield(me, x, y, 1);
me.onDamage = function() {
@@ -3185,7 +3187,7 @@ const spawn = {
} else if (this.noseLength > 1.5 && dot > -0.2 && dot < 0.2) {
//fire
spawn.sniperBullet(this.vertices[1].x, this.vertices[1].y, 7 + Math.ceil(this.radius / 15), 4);
- const v = 20 * simulation.accelScale;
+ const v = 10 + 15 * simulation.accelScale;
Matter.Body.setVelocity(mob[mob.length - 1], {
x: this.velocity.x + this.fireDir.x * v + Math.random(),
y: this.velocity.y + this.fireDir.y * v + Math.random()
@@ -3246,8 +3248,8 @@ const spawn = {
this.explode(this.mass * 20);
};
Matter.Body.setDensity(me, 0.00005); //normal is 0.001
- me.timeLeft = 240;
- me.g = 0.0005; //required if using 'gravity'
+ me.timeLeft = 120;
+ // me.g = 0.0005; //required if using 'gravity'
me.frictionAir = 0;
me.restitution = 0;
me.leaveBody = false;
@@ -3258,7 +3260,7 @@ const spawn = {
me.collisionFilter.category = cat.mobBullet;
me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet;
me.do = function() {
- this.gravity();
+ // this.gravity();
this.timeLimit();
if (Matter.Query.collides(this, map).length > 0 || Matter.Query.collides(this, body).length > 0 && this.speed < 3) {
this.isDropPowerUp = false;
@@ -3339,7 +3341,7 @@ const spawn = {
};
},
grenadierBoss(x, y, radius = 95) {
- mobs.spawn(x, y, 6, radius, "rgb(215,80,190)");
+ mobs.spawn(x, y, 6, radius, "rgb(0,235,255)");
let me = mob[mob.length - 1];
me.isBoss = true;
@@ -3391,7 +3393,7 @@ const spawn = {
};
},
grenadier(x, y, radius = 35 + Math.ceil(Math.random() * 20)) {
- mobs.spawn(x, y, 3, radius, "rgb(215,80,190)"); //rgb(255,100,200)
+ mobs.spawn(x, y, 3, radius, "rgb(0,235,255)"); //rgb(255,100,200)
let me = mob[mob.length - 1];
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
me.isVerticesChange = true
@@ -4063,6 +4065,7 @@ const spawn = {
Matter.Body.setDensity(me, 0.00001) //very low density to not mess with the original mob's motion
me.shield = true;
me.damageReduction = 0.075
+ me.isUnblockable = true
me.isExtraShield = isExtraShield //this prevents spamming with tech.isShieldAmmo
me.collisionFilter.category = cat.mobShield
me.collisionFilter.mask = cat.bullet;
@@ -4162,6 +4165,7 @@ const spawn = {
me.leaveBody = false;
me.isDropPowerUp = false;
me.isBadTarget = true;
+ me.isUnblockable = true;
me.showHealthBar = false;
me.isOrbital = true;
// me.isShielded = true
@@ -4393,6 +4397,7 @@ const spawn = {
me.isDropPowerUp = false;
me.showHealthBar = false;
me.isBadTarget = true;
+ me.isUnblockable = true;
me.do = function() {
let wireX = -50;
@@ -4461,6 +4466,7 @@ const spawn = {
me.isDropPowerUp = false;
me.showHealthBar = false;
me.isBadTarget = true;
+ me.isUnblockable = true;
me.do = function() {
let wireX = -50 - 20;
@@ -4512,6 +4518,7 @@ const spawn = {
me.isDropPowerUp = false;
me.showHealthBar = false;
me.isBadTarget = true;
+ me.isUnblockable = true;
me.do = function() {
let wireX = -50 - 35;
@@ -4562,6 +4569,7 @@ const spawn = {
me.isDropPowerUp = false;
me.showHealthBar = false;
me.isBadTarget = true;
+ me.isUnblockable = true;
me.do = function() {
let wireX = -50 + 16;
@@ -4612,6 +4620,7 @@ const spawn = {
me.isDropPowerUp = false;
me.showHealthBar = false;
me.isBadTarget = true;
+ me.isUnblockable = true;
me.do = function() {
let wireX = -50 + 26;
diff --git a/js/tech.js b/js/tech.js
index 8d80184..f380abb 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -168,7 +168,7 @@
damageFromTech() {
let dmg = 1 //m.fieldDamage
if (tech.isCloakingDamage) dmg *= 1.35
- if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.45
+ if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.5
if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.3703599
if (tech.isDamageAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 2 : 0.66
if (m.isSneakAttack && m.cycle > m.lastKillCycle + 240) dmg *= tech.sneakAttackDmg
@@ -1805,7 +1805,7 @@
},
{
name: "thermocouple",
- description: "if relay switch is in the ON state
condense 1-7 ice IX crystals every second",
+ description: "if relay switch is in the ON state
condense 1-9 ice IX crystals every second",
maxCount: 9,
count: 0,
frequency: 4,
@@ -1823,7 +1823,7 @@
},
{
name: "NAND gate",
- description: "if in the ON state
do 45% more damage",
+ description: "if in the ON state
do 50% more damage",
maxCount: 1,
count: 0,
frequency: 4,
@@ -1841,7 +1841,7 @@
},
{
name: "transistor",
- description: "if ON regen 22 energy per second
if OFF drain 4.1 energy per second",
+ description: "if ON regen 22 energy per second
if OFF drain 2.2 energy per second",
maxCount: 1,
count: 0,
frequency: 4,
@@ -7536,7 +7536,8 @@
description: `this`,
maxCount: 1,
count: 0,
- frequency: 2,
+ frequency: 3,
+ frequencyDefault: 3,
isLore: true,
// isNonRefundable: true,
isExperimentHide: true,
diff --git a/todo.txt b/todo.txt
index eafe9ad..2f63a7f 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,28 +1,16 @@
******************************************************** NEXT PATCH ********************************************************
-new laserBombingBoss
- I didn't do any difficulty testing, so maybe let me know if it's too easy
+relativistic momentum: laser pushes harder and slows mobs a bit to give a more predictable effect
+laserBombingBoss targets faster at higher levels
+you can now block shielded mobs, but your shield gets disabled for a bit
-laser and plasma bots will target mobs bullets
-non updating health bar bug fix
+fixed bug that made perfect diamagnetism have trouble blocking too many things at once
+and more small bug fixes, of course
******************************************************** TODO ********************************************************
mob: spawning seekers on death
-"Lazer pulser Boss"
-Basically the blue lazer boss, but it has another color
-Instead of shooting one current stream of lasers, the laser is completely harmless
-If the boss focused the Lazer on the player for a certain amount of time, it'll glow brightly and send a fast, explosive pulse down the Lazer beam
-The harmless lazer beam serves like a sniper's lazer scope
-
-laser damage seems low based on 2 runs
- history is low damage
-
-buff laser push tech
- push like plasma?
- push harder
-
drones can combine with other drones to get bigger?
drones that grab powers ups can grab more then one and get even bigger each time