elephant's toothpaste

elephant's toothpaste: mines make foam

sentry fires about 40% faster
  but each shot slightly reduces the total duration
  (duration = 17s - 1/10 s per shot)

foam can move through blocks a bit faster
laser reflection damage is increased
  about 15% -> 8% damage loss per reflection
beetleBoss pushes player away and spawns baby flutter mobs
fire rate affects block throwing charge rate
This commit is contained in:
landgreen
2022-08-04 08:55:15 -07:00
parent 05a263e31f
commit b8e7bf7d3d
7 changed files with 237 additions and 140 deletions

View File

@@ -1439,7 +1439,7 @@ const b = {
minDmgSpeed: 4, minDmgSpeed: 4,
lookFrequency: Math.floor(7 + Math.random() * 3), lookFrequency: Math.floor(7 + Math.random() * 3),
density: tech.harpoonDensity, //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed density: tech.harpoonDensity, //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
drain: tech.isRailEnergyGain ? 0.002 : 0.006, drain: tech.isRailEnergy ? 0.002 : 0.006,
beforeDmg(who) { beforeDmg(who) {
if (tech.isShieldPierce && who.isShielded) { //disable shields if (tech.isShieldPierce && who.isShielded) { //disable shields
who.isShielded = false who.isShielded = false
@@ -1695,7 +1695,7 @@ const b = {
friction: 1, friction: 1,
frictionAir: 0.4, frictionAir: 0.4,
thrustMag: 0.1, thrustMag: 0.1,
drain: tech.isRailEnergyGain ? 0.002 : 0.006, drain: tech.isRailEnergy ? 0.002 : 0.006,
turnRate: isReturn ? 0.1 : 0.03, //0.015 turnRate: isReturn ? 0.1 : 0.03, //0.015
drawStringControlMagnitude: 3000 + 5000 * Math.random(), drawStringControlMagnitude: 3000 + 5000 * Math.random(),
drawStringFlip: (Math.round(Math.random()) ? 1 : -1), drawStringFlip: (Math.round(Math.random()) ? 1 : -1),
@@ -2247,7 +2247,7 @@ const b = {
x: where.x + 3000 * Math.cos(m.angle), x: where.x + 3000 * Math.cos(m.angle),
y: where.y + 3000 * Math.sin(m.angle) y: where.y + 3000 * Math.sin(m.angle)
}, dmg = tech.laserDamage, reflections = tech.laserReflections, isThickBeam = false, push = 1) { }, dmg = tech.laserDamage, reflections = tech.laserReflections, isThickBeam = false, push = 1) {
const reflectivity = 1 - 1 / (reflections * 1.5) const reflectivity = 1 - 1 / (reflections * 3)
let damage = m.dmgScale * dmg let damage = m.dmgScale * dmg
let best = { let best = {
x: 1, x: 1,
@@ -2528,10 +2528,56 @@ const b = {
isArmed: false, isArmed: false,
endCycle: Infinity, endCycle: Infinity,
lookFrequency: 0, lookFrequency: 0,
range: 700, range: 700 - 300 * tech.isFoamMine,
beforeDmg() {}, beforeDmg() {},
onEnd() { onEnd() {
if (this.isArmed) b.targetedNail(this.position, tech.isMineSentry ? 7 : 22, 40 + 10 * Math.random(), 1200, true, 2.2) //targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true, damage = 1.4) { if (tech.isFoamMine) {
for (let i = 0; i < 14; i++) {
const radius = 13 + 8 * Math.random()
const velocity = { x: 5.5 * Math.random(), y: 0 }
b.foam(this.position, Vector.rotate(velocity, this.angle + 1.57 + 3 * (Math.random() - 0.5)), radius) //6.28 * Math.random()
}
let count = 0
let cycle = () => {
if (count < 40) {
if (!simulation.paused && !simulation.isChoosing) { //!(simulation.cycle % 1) &&
count++
const targets = [] //target nearby mobs
for (let i = 0, len = mob.length; i < len; i++) {
if (
Vector.magnitude(Vector.sub(this.position, mob[i].position)) < this.range + mob[i].radius + 300 &&
!mob[i].isBadTarget && //|| mob[i].isMobBullet
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
!mob[i].isInvulnerable
) {
// targets.push(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, dist / 50))) //predict where the mob will be in a few cycles
targets.push(mob[i]) //predict where the mob will be in a few cycles
}
}
if (targets.length > 0) { // aim near a random target in array
const index = Math.floor(Math.random() * targets.length) //pick random target from list
const radius = 7 + 10 * Math.random()
const SPEED = 23 + 6 * Math.random() - radius * 0.3 + 0.5 * targets[index].speed
const predict = Vector.mult(targets[index].velocity, Vector.magnitude(Vector.sub(this.position, targets[index].position)) / 60)
const where = Vector.add(targets[index].position, predict)
const velocity = Vector.mult(Vector.normalise(Vector.sub(where, this.position)), SPEED)
b.foam(this.position, Vector.rotate(velocity, 0.2 * (Math.random() - 0.5)), radius)
} else {
const radius = 7 + 10 * Math.random()
const velocity = { x: 10 + 8 * Math.random(), y: 0 }
b.foam(this.position, Vector.rotate(velocity, this.angle + 1.57 + 2.8 * (Math.random() - 0.5)), radius) //6.28 * Math.random()
}
}
requestAnimationFrame(cycle);
}
}
requestAnimationFrame(cycle)
} else if (this.isArmed && !tech.isMineSentry) {
b.targetedNail(this.position, tech.isMineSentry ? 7 : 22, 40 + 10 * Math.random(), 1200, true, 2.2) //targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true, damage = 1.4) {
}
}, },
do() { do() {
this.force.y += this.mass * 0.002; //extra gravity this.force.y += this.mass * 0.002; //extra gravity
@@ -2556,14 +2602,13 @@ const b = {
this.arm(); this.arm();
//sometimes the mine can't attach to map and it just needs to be reset //sometimes the mine can't attach to map and it just needs to be reset
const that = this setTimeout(() => {
setTimeout(function() { if (Matter.Query.collides(this, map).length === 0 || Matter.Query.point(map, this.position).length > 0) {
if (Matter.Query.collides(that, map).length === 0 || Matter.Query.point(map, that.position).length > 0) { this.endCycle = 0 // if not touching map explode
that.endCycle = 0 // if not touching map explode this.isArmed = false
that.isArmed = false b.mine(this.position, this.velocity, this.angle)
b.mine(that.position, that.velocity, that.angle)
} }
}, 100, that); }, 100);
break break
} }
//move until you are touching the wall //move until you are touching the wall
@@ -2599,17 +2644,18 @@ const b = {
for (let i = 0, len = mob.length; i < len; ++i) { for (let i = 0, len = mob.length; i < len; ++i) {
if ( if (
!mob[i].isBadTarget && !mob[i].isBadTarget &&
Vector.magnitude(Vector.sub(this.position, mob[i].position)) < 700 + mob[i].radius + random && Vector.magnitude(Vector.sub(this.position, mob[i].position)) < this.range + mob[i].radius + random &&
Matter.Query.ray(map, this.position, mob[i].position).length === 0 && Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
Matter.Query.ray(body, this.position, mob[i].position).length === 0 Matter.Query.ray(body, this.position, mob[i].position).length === 0
) { ) {
if (tech.isStun) b.AoEStunEffect(this.position, 700 + mob[i].radius + random); //AoEStunEffect(where, range, cycles = 90 + 60 * Math.random()) { if (tech.isStun) b.AoEStunEffect(this.position, this.range + mob[i].radius + random); //AoEStunEffect(where, range, cycles = 90 + 60 * Math.random()) {
if (tech.isMineSentry) { if (tech.isMineSentry) {
this.lookFrequency = 8 + Math.floor(3 * Math.random()) this.lookFrequency = 6
this.endCycle = simulation.cycle + 1020 this.endCycle = simulation.cycle + 1020
this.do = function() { //overwrite the do method for this bullet this.do = function() { //overwrite the do method for this bullet
this.force.y += this.mass * 0.002; //extra gravity this.force.y += this.mass * 0.002; //extra gravity
if (!(simulation.cycle % this.lookFrequency)) { //find mob targets if (!(simulation.cycle % this.lookFrequency)) { //find mob targets
this.endCycle -= 5
b.targetedNail(this.position, 1, 45 + 5 * Math.random(), 1100, false, 2.3) //targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true, damage = 1.4) { b.targetedNail(this.position, 1, 45 + 5 * Math.random(), 1100, false, 2.3) //targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true, damage = 1.4) {
if (!(simulation.cycle % (this.lookFrequency * 6))) { if (!(simulation.cycle % (this.lookFrequency * 6))) {
simulation.drawList.push({ simulation.drawList.push({
@@ -3734,9 +3780,9 @@ const b = {
Matter.Body.setPosition(this, Vector.add(Vector.add(rotate, this.target.velocity), this.target.position)) Matter.Body.setPosition(this, Vector.add(Vector.add(rotate, this.target.velocity), this.target.position))
} }
if (this.target.isBoss) { if (this.target.isBoss) {
if (this.target.speed > 7.5) Matter.Body.setVelocity(this.target, Vector.mult(this.target.velocity, 0.98)) if (this.target.speed > 6.5) Matter.Body.setVelocity(this.target, Vector.mult(this.target.velocity, 0.975))
} else { } else {
if (this.target.speed > 3.5) Matter.Body.setVelocity(this.target, Vector.mult(this.target.velocity, 0.95)) if (this.target.speed > 2.5) Matter.Body.setVelocity(this.target, Vector.mult(this.target.velocity, 0.94))
} }
Matter.Body.setAngularVelocity(this.target, this.target.angularVelocity * 0.9); Matter.Body.setAngularVelocity(this.target, this.target.angularVelocity * 0.9);
@@ -3746,35 +3792,6 @@ const b = {
const SCALE = 1 - 0.004 / tech.isBulletsLastLonger //shrink if mob is shielded const SCALE = 1 - 0.004 / tech.isBulletsLastLonger //shrink if mob is shielded
Matter.Body.scale(this, SCALE, SCALE); Matter.Body.scale(this, SCALE, SCALE);
this.radius *= SCALE; this.radius *= SCALE;
// if (true && !(simulation.cycle % 20)) {
// let electricity = (who) => {
// who.damage(2 * m.dmgScale, true)
// const unit = Vector.normalise(Vector.sub(this.position, who.position))
// //draw electricity
// const step = 80
// ctx.beginPath();
// let x = this.position.x - 20 * unit.x;
// let y = this.position.y - 20 * unit.y;
// ctx.moveTo(x, y);
// for (let i = 0; i < 3; i++) {
// x += step * (-unit.x + 1.5 * (Math.random() - 0.5))
// y += step * (-unit.y + 1.5 * (Math.random() - 0.5))
// ctx.lineTo(x, y);
// }
// ctx.lineWidth = 3;
// ctx.strokeStyle = "#f0f";
// ctx.stroke();
// }
// //find mobs that are close
// for (let i = 0, len = mob.length; i < len; ++i) {
// if (Vector.magnitude(Vector.sub(mob[i].position, this.position)) - mob[i].radius < 5000 && !mob[i].isBadTarget) {
// electricity(mob[0])
// }
// }
// }
} else { } else {
this.target.damage(m.dmgScale * this.damage); this.target.damage(m.dmgScale * this.damage);
} }
@@ -3808,23 +3825,23 @@ const b = {
} }
} }
this.target = null this.target = null
} else if (Matter.Query.point(map, this.position).length > 0) { //slow when touching map or blocks } else if (Matter.Query.point(map, this.position).length > 0) { //slow when touching map
const slow = 0.85 const slow = 0.87
Matter.Body.setVelocity(this, { Matter.Body.setVelocity(this, {
x: this.velocity.x * slow, x: this.velocity.x * slow,
y: this.velocity.y * slow y: this.velocity.y * slow
}); });
const SCALE = 0.96 const SCALE = 0.97
Matter.Body.scale(this, SCALE, SCALE); Matter.Body.scale(this, SCALE, SCALE);
this.radius *= SCALE; this.radius *= SCALE;
// } else if (Matter.Query.collides(this, body).length > 0) { // } else if (Matter.Query.collides(this, body).length > 0) {
} else if (Matter.Query.point(body, this.position).length > 0) { } else if (Matter.Query.point(body, this.position).length > 0) { //slow when touching blocks
const slow = 0.9 const slow = 0.94
Matter.Body.setVelocity(this, { Matter.Body.setVelocity(this, {
x: this.velocity.x * slow, x: this.velocity.x * slow,
y: this.velocity.y * slow y: this.velocity.y * slow
}); });
const SCALE = 0.96 const SCALE = 0.99
Matter.Body.scale(this, SCALE, SCALE); Matter.Body.scale(this, SCALE, SCALE);
this.radius *= SCALE; this.radius *= SCALE;
} else { } else {
@@ -6617,7 +6634,7 @@ const b = {
charge: 0, charge: 0,
railDo() { railDo() {
if (this.charge > 0) { if (this.charge > 0) {
const DRAIN = (tech.isRailEnergyGain ? 0.0005 : 0.002) const DRAIN = (tech.isRailEnergy ? 0.0005 : 0.002)
//exit railgun charging without firing //exit railgun charging without firing
if (m.energy < DRAIN) { if (m.energy < DRAIN) {
// m.energy += 0.025 + this.charge * 22 * this.drain // m.energy += 0.025 + this.charge * 22 * this.drain
@@ -6756,7 +6773,7 @@ const b = {
this.charge = this.charge * smoothRate + 1 - smoothRate this.charge = this.charge * smoothRate + 1 - smoothRate
if (m.energy > DRAIN) m.energy -= DRAIN if (m.energy > DRAIN) m.energy -= DRAIN
// m.energy += (this.charge - previousCharge) * ((tech.isRailEnergyGain ? 0.5 : -0.3)) //energy drain is proportional to charge gained, but doesn't stop normal m.fieldRegen // m.energy += (this.charge - previousCharge) * ((tech.isRailEnergy ? 0.5 : -0.3)) //energy drain is proportional to charge gained, but doesn't stop normal m.fieldRegen
//draw magnetic field //draw magnetic field
const X = m.pos.x const X = m.pos.x

View File

@@ -16,20 +16,20 @@ const level = {
start() { start() {
if (level.levelsCleared === 0) { //this code only runs on the first level if (level.levelsCleared === 0) { //this code only runs on the first level
// simulation.enableConstructMode() //used to build maps in testing mode // simulation.enableConstructMode() //used to build maps in testing mode
// level.difficultyIncrease(2 * 4) //30 is near max on hard //60 is near max on why // level.difficultyIncrease(9 * 4) //30 is near max on hard //60 is near max on why
// simulation.isHorizontalFlipped = true // simulation.isHorizontalFlipped = true
// m.maxHealth = m.health = 100 // m.maxHealth = m.health = 100
// tech.isRerollDamage = true
// powerUps.research.changeRerolls(100000) // powerUps.research.changeRerolls(100000)
// m.immuneCycle = Infinity //you can't take damage // m.immuneCycle = Infinity //you can't take damage
// powerUps.research.changeRerolls(100)
// tech.tech[297].frequency = 100 // tech.tech[297].frequency = 100
// b.guns[0].ammo = 10000 // b.guns[0].ammo = 10000
// m.setField("time dilation") //molecular assembler time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass // m.setField("perfect diamagnetism") //molecular assembler time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass
// b.giveGuns("shotgun") //0 nail gun 1 shotgun 2 super balls 3 matter wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser // b.giveGuns("mine") //0 nail gun 1 shotgun 2 super balls 3 matter wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// tech.giveTech("infrared diode"); // tech.giveTech("sentry");
// tech.giveTech("active cooling"); // tech.giveTech("laser-mines");
// tech.giveTech("pulse") // tech.giveTech("elephant's toothpaste")
// for (let i = 0; i < 1; ++i) tech.giveTech("slow light") // for (let i = 0; i < 1; ++i) tech.giveTech("slow light")
// for (let i = 0; i < 1; ++i) tech.giveTech("free-electron laser") // for (let i = 0; i < 1; ++i) tech.giveTech("free-electron laser")
// m.damage(0.1); // m.damage(0.1);
@@ -37,8 +37,8 @@ const level = {
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "research"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "research");
// spawn.flutter(1900, -500, 10)
// spawn.starter(1900, -500, 200) // spawn.starter(1900, -500, 200)
// spawn.starter(1900, -500, 50)
// spawn.dragonFlyBoss(1900, -400) // spawn.dragonFlyBoss(1900, -400)
// spawn.beetleBoss(1900, -400) // spawn.beetleBoss(1900, -400)
// for (let i = 0; i < 2; ++i) spawn.flutter(1900 + 300 * Math.random(), -500 + 300 * Math.random()) // for (let i = 0; i < 2; ++i) spawn.flutter(1900 + 300 * Math.random(), -500 + 300 * Math.random())
@@ -4586,7 +4586,7 @@ const level = {
spawn.randomMob(3600, 1725, 0.9); spawn.randomMob(3600, 1725, 0.9);
spawn.randomMob(4100, 1225, 0.9); spawn.randomMob(4100, 1225, 0.9);
spawn.randomMob(2825, 400, 0.9); spawn.randomMob(2825, 400, 0.9);
if (simulation.difficulty > 1) spawn.randomLevelBoss(6000, 2300, ["spiderBoss", "launcherBoss", "laserTargetingBoss", "blinkBoss", "streamBoss", "historyBoss", "orbitalBoss", "grenadierBoss", "blockBoss", "revolutionBoss", "slashBoss"]); if (simulation.difficulty > 1) spawn.randomLevelBoss(6000, 2300, ["dragonFlyBoss", "beetleBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "blinkBoss", "streamBoss", "historyBoss", "orbitalBoss", "grenadierBoss", "blockBoss", "revolutionBoss", "slashBoss"]);
powerUps.addResearchToLevel() //needs to run after mobs are spawned powerUps.addResearchToLevel() //needs to run after mobs are spawned
spawn.secondaryBossChance(7725, 2275) spawn.secondaryBossChance(7725, 2275)
@@ -5144,7 +5144,7 @@ const level = {
spawn.randomMob(3975, -3900, 0.5); spawn.randomMob(3975, -3900, 0.5);
spawn.randomMob(1725, 125, 0.5); spawn.randomMob(1725, 125, 0.5);
if (simulation.difficulty > 1) { if (simulation.difficulty > 1) {
if (Math.random() < 0.33) { if (Math.random() < 0.5) {
spawn.randomLevelBoss(4250, -250); spawn.randomLevelBoss(4250, -250);
spawn.debris(-250, 50, 1650, 2); //16 debris per level spawn.debris(-250, 50, 1650, 2); //16 debris per level
spawn.debris(2475, 0, 750, 2); //16 debris per level spawn.debris(2475, 0, 750, 2); //16 debris per level

View File

@@ -589,7 +589,7 @@ const mobs = {
ctx.setLineDash([]); ctx.setLineDash([]);
} }
}, },
wing(a, radius = 250, ellipticity = 0.4, dmg = 0.0004) { wing(a, radius = 250, ellipticity = 0.4, dmg = 0.0006) {
const minorRadius = radius * ellipticity const minorRadius = radius * ellipticity
const perp = { x: Math.cos(a), y: Math.sin(a) } // const perp = { x: Math.cos(a), y: Math.sin(a) } //
const where = Vector.add(this.position, Vector.mult(perp, radius + 0.8 * this.radius)) const where = Vector.add(this.position, Vector.mult(perp, radius + 0.8 * this.radius))

View File

@@ -1124,9 +1124,9 @@ const m = {
if (m.energy > 0.001) { if (m.energy > 0.001) {
if (m.fireCDcycle < m.cycle) m.fireCDcycle = m.cycle if (m.fireCDcycle < m.cycle) m.fireCDcycle = m.cycle
if (tech.isCapacitor && m.throwCharge < 4) m.throwCharge = 4 if (tech.isCapacitor && m.throwCharge < 4) m.throwCharge = 4
m.throwCharge += 0.5 / m.holdingTarget.mass m.throwCharge += 0.5 / m.holdingTarget.mass / b.fireCDscale
if (m.throwCharge < 6) m.energy -= 0.001; // m.throwCharge caps at 5 if (m.throwCharge < 6) m.energy -= 0.001 / b.fireCDscale; // m.throwCharge caps at 5
//trajectory path prediction //trajectory path prediction
if (tech.isTokamak) { if (tech.isTokamak) {
@@ -2073,10 +2073,19 @@ const m = {
} }
} }
} else if (simulation.molecularMode === 1) { } else if (simulation.molecularMode === 1) {
m.energy -= 0.35; m.energy -= 0.33;
b.missile({ x: m.pos.x, y: m.pos.y - 40 }, -Math.PI / 2 + 0.5 * (Math.random() - 0.5), 0, 1) const direction = {
x: Math.cos(m.angle),
y: Math.sin(m.angle)
}
const push = Vector.mult(Vector.perp(direction), 0.08)
b.missile({ x: m.pos.x + 30 * direction.x, y: m.pos.y + 30 * direction.y }, m.angle, -15)
bullet[bullet.length - 1].force.x += push.x * (Math.random() - 0.5)
bullet[bullet.length - 1].force.y += 0.005 + push.y * (Math.random() - 0.5)
// b.missile({ x: m.pos.x, y: m.pos.y - 40 }, -Math.PI / 2 + 0.5 * (Math.random() - 0.5), 0, 1)
} else if (simulation.molecularMode === 2) { } else if (simulation.molecularMode === 2) {
m.energy -= 0.05; m.energy -= 0.045;
b.iceIX(1) b.iceIX(1)
} else if (simulation.molecularMode === 3) { } else if (simulation.molecularMode === 3) {
if (tech.isDroneRadioactive) { if (tech.isDroneRadioactive) {

View File

@@ -1614,7 +1614,7 @@ const spawn = {
// me.isBadTarget = true; // me.isBadTarget = true;
me.isMobBullet = true; me.isMobBullet = true;
me.showHealthBar = false; me.showHealthBar = false;
me.timeLeft = 1500 + Math.floor(600 * Math.random()); me.timeLeft = 1200 + Math.floor(600 * Math.random());
me.isRandomMove = Math.random() < 0.3 //most chase player, some don't me.isRandomMove = Math.random() < 0.3 //most chase player, some don't
me.accelMag = 0.01; //jump height me.accelMag = 0.01; //jump height
@@ -1649,7 +1649,7 @@ const spawn = {
mobs.spawn(x, y, 5, radius, "rgb(0,200,180)"); mobs.spawn(x, y, 5, radius, "rgb(0,200,180)");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
me.damageReduction = 0.05 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) me.damageReduction = 0.06 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.accelMag = 0.05; //jump height me.accelMag = 0.05; //jump height
me.g = 0.003; //required if using this.gravity me.g = 0.003; //required if using this.gravity
me.frictionAir = 0.01; me.frictionAir = 0.01;
@@ -2696,12 +2696,12 @@ const spawn = {
mobs.spawn(x, y, 7, radius, '#16576b'); mobs.spawn(x, y, 7, radius, '#16576b');
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
Matter.Body.setDensity(me, 0.0016); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.002); //extra dense //normal is 0.001 //makes effective life much larger
// me.damageReduction = 0.04 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) // me.damageReduction = 0.04 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front 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); Matter.Body.rotate(me, Math.random() * Math.PI * 2);
me.accelMag = 0.0006 + 0.0006 * Math.sqrt(simulation.accelScale); me.accelMag = 0.0006 + 0.0007 * Math.sqrt(simulation.accelScale);
me.frictionAir = 0.05; me.frictionAir = 0.05;
// me.seePlayerFreq = 40 + Math.floor(13 * Math.random()) // me.seePlayerFreq = 40 + Math.floor(13 * Math.random())
me.memory = 240; me.memory = 240;
@@ -2714,7 +2714,7 @@ const spawn = {
// me.onDeath = function() {}; // me.onDeath = function() {};
me.flapRate = 0.3 + Math.floor(3 * Math.random()) / 10 + 100 * me.accelMag me.flapRate = 0.3 + Math.floor(3 * Math.random()) / 10 + 100 * me.accelMag
me.flapRadius = 75 + 50 * Math.random() + radius * 2 me.flapRadius = 75 + radius * 3
me.do = function() { me.do = function() {
this.seePlayerByHistory() this.seePlayerByHistory()
this.checkStatus(); this.checkStatus();
@@ -2753,7 +2753,7 @@ const spawn = {
} }
}; };
}, },
beetleBoss(x, y, radius = 60) { beetleBoss(x, y, radius = 50) {
mobs.spawn(x, y, 7, radius, '#16576b'); mobs.spawn(x, y, 7, radius, '#16576b');
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
@@ -2764,14 +2764,14 @@ const spawn = {
me.nextHealthThreshold = 0.75 me.nextHealthThreshold = 0.75
me.invulnerableCount = 0 me.invulnerableCount = 0
me.flapRate = 0.25 me.flapRate = 0.2
me.wingSize = 0 me.wingSize = 0
me.wingGoal = 250 me.wingGoal = 250 + simulation.difficulty
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front 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); Matter.Body.rotate(me, Math.random() * Math.PI * 2);
me.accelMag = 0.0005 + 0.0005 * Math.sqrt(simulation.accelScale); me.accelMag = 0.00045 + 0.0005 * Math.sqrt(simulation.accelScale);
me.frictionAir = 0.05; me.frictionAir = 0.05;
me.seePlayerFreq = 30 me.seePlayerFreq = 20
me.memory = 420; me.memory = 420;
me.restitution = 1; me.restitution = 1;
me.frictionStatic = 0; me.frictionStatic = 0;
@@ -2789,58 +2789,94 @@ const spawn = {
// } // }
// } // }
if (Math.random() < 0.3) { // if (Math.random() < 0.3) {
const len = 0.1 * simulation.difficulty //spawn some baby flutters // const len = 0.1 * simulation.difficulty //spawn some baby flutters
// let i = 0
// let spawnFlutters = () => {
// if (i < len) {
// if (!(simulation.cycle % 30) && !simulation.paused && !simulation.isChoosing) {
// const phase = i / len * 2 * Math.PI
// const where = Vector.add(me.position, Vector.mult({ x: Math.cos(phase), y: Math.sin(phase) }, radius * 1.5))
// spawn.flutter(where.x, where.y)
// i++
// }
// requestAnimationFrame(spawnFlutters);
// }
// }
// requestAnimationFrame(spawnFlutters);
// me.isAlreadyHadBabies = true
// }
me.pushAway = function(magX = 0.13, magY = 0.05) {
for (let i = 0, len = body.length; i < len; ++i) { //push blocks away horizontally
if (Vector.magnitudeSquared(Vector.sub(body[i].position, this.position)) < 4000000) { //2000
body[i].force.x += magX * body[i].mass * (body[i].position.x > this.position.x ? 1 : -1)
body[i].force.y -= magY * body[i].mass
}
}
for (let i = 0, len = bullet.length; i < len; ++i) { //push blocks away horizontally
if (Vector.magnitudeSquared(Vector.sub(bullet[i].position, this.position)) < 4000000) { //2000
bullet[i].force.x += magX * bullet[i].mass * (bullet[i].position.x > this.position.x ? 1 : -1)
bullet[i].force.y -= magY * bullet[i].mass
}
}
for (let i = 0, len = powerUp.length; i < len; ++i) { //push blocks away horizontally
if (Vector.magnitudeSquared(Vector.sub(powerUp[i].position, this.position)) < 4000000) { //2000
powerUp[i].force.x += magX * powerUp[i].mass * (powerUp[i].position.x > this.position.x ? 1 : -1)
powerUp[i].force.y -= magY * powerUp[i].mass
}
}
if (Vector.magnitudeSquared(Vector.sub(player.position, this.position)) < 4000000) { //2000
player.force.x += magX * player.mass * (player.position.x > this.position.x ? 1 : -1)
player.force.y -= magY * player.mass
}
}
me.babies = function(len) {
const delay = Math.max(3, Math.floor(15 - len / 2))
let i = 0 let i = 0
let spawnFlutters = () => { let spawnFlutters = () => {
if (i < len) { if (i < len) {
if (!(simulation.cycle % 30) && !simulation.paused && !simulation.isChoosing) { if (!(simulation.cycle % delay) && !simulation.paused && !simulation.isChoosing) {
const phase = i / len * 2 * Math.PI // const phase = i / len * 2 * Math.PI
const where = Vector.add(me.position, Vector.mult({ x: Math.cos(phase), y: Math.sin(phase) }, radius * 1.5)) // const where = Vector.add(this.position, Vector.mult({ x: Math.cos(phase), y: Math.sin(phase) }, radius * 1.5))
spawn.flutter(where.x, where.y) const unit = Vector.normalise(Vector.sub(player.position, this.position))
const velocity = Vector.mult(unit, 10 + 10 * Math.random())
const where = Vector.add(this.position, Vector.mult(unit, radius * 1.2))
spawn.allowShields = false
spawn.flutter(where.x, where.y, Math.floor(7 + 8 * Math.random()))
const who = mob[mob.length - 1]
Matter.Body.setDensity(who, 0.01); //extra dense //normal is 0.001 //makes effective life much larger
Matter.Body.setVelocity(who, velocity);
Matter.Body.setAngle(who, Math.atan2(velocity.y, velocity.x))
this.alertNearByMobs();
spawn.allowShields = true
i++ i++
} }
requestAnimationFrame(spawnFlutters); requestAnimationFrame(spawnFlutters);
} }
} }
requestAnimationFrame(spawnFlutters); requestAnimationFrame(spawnFlutters);
me.isAlreadyHadBabies = true
} }
// me.babies(0.05 * simulation.difficulty + 1)
me.onDeath = function() { me.onDeath = function() {
powerUps.spawnBossPowerUp(this.position.x, this.position.y) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
me.babies(0.05 * simulation.difficulty + 1)
const len = 0.1 * simulation.difficulty //spawn some baby flutters
if (len > 3 && !this.isAlreadyHadBabies) {
let i = 0
let spawnFlutters = () => {
if (i < len) {
if (!(simulation.cycle % 20) && !simulation.paused && !simulation.isChoosing) {
const phase = i / len * 2 * Math.PI
const where = Vector.add(me.position, Vector.mult({ x: Math.cos(phase), y: Math.sin(phase) }, radius * 1.5))
spawn.flutter(where.x, where.y)
i++
}
requestAnimationFrame(spawnFlutters);
}
}
requestAnimationFrame(spawnFlutters);
}
}; };
me.onDamage = function() { me.onDamage = function() {
if (this.health < this.nextHealthThreshold) { if (this.health < this.nextHealthThreshold && this.alive) {
this.health = this.nextHealthThreshold - 0.01 this.health = this.nextHealthThreshold - 0.01
this.nextHealthThreshold = Math.floor(this.health * 4) / 4 this.nextHealthThreshold = Math.floor(this.health * 4) / 4
this.invulnerableCount = 180 + Math.floor(60 * Math.random()) this.invulnerableCount = 90 + Math.floor(30 * Math.random())
this.isInvulnerable = true this.isInvulnerable = true
this.damageReduction = 0 this.damageReduction = 0
this.frictionAir = 0 this.frictionAir = 0
this.wingGoal = 0 this.wingGoal = 0
this.wingSize = 0 this.wingSize = 0
this.flapRate += 0.1 this.flapRate += 0.13
this.accelMag *= 1.25 this.accelMag *= 1.4
} }
}; };
me.do = function() { me.do = function() {
@@ -2853,6 +2889,8 @@ const spawn = {
this.damageReduction = this.startingDamageReduction this.damageReduction = this.startingDamageReduction
this.frictionAir = 0.05 this.frictionAir = 0.05
this.wingGoal = 250 this.wingGoal = 250
this.pushAway(Math.sqrt(this.flapRate) * 0.13, Math.sqrt(this.flapRate) * 0.06) //this.flapRate = 0.2, +0.13x3 -> 0.6
me.babies(0.05 * simulation.difficulty + 1)
} }
// //draw wings as if they are protecting // //draw wings as if they are protecting
// const wingShield = (a, size) => { // const wingShield = (a, size) => {
@@ -2908,10 +2946,10 @@ const spawn = {
this.torque -= turn; this.torque -= turn;
} }
const flapArc = 0.7 //don't go past 1.57 for normal flaps const flapArc = 0.7 //don't go past 1.57 for normal flaps
this.wingSize = 0.98 * this.wingSize + 0.02 * this.wingGoal this.wingSize = 0.97 * this.wingSize + 0.03 * this.wingGoal
ctx.fillStyle = this.fill = `hsla(${160+40*Math.random()}, 100%, ${25 + 25*Math.random()*Math.random()}%, 0.9)`; //"rgba(0,235,255,0.3)"; // ctx.fillStyle = `hsla(44, 79%, 31%,0.4)`; //"rgba(0,235,255,0.3)"; ctx.fillStyle = this.fill = `hsla(${160+40*Math.random()}, 100%, ${25 + 25*Math.random()*Math.random()}%, 0.9)`; //"rgba(0,235,255,0.3)"; // ctx.fillStyle = `hsla(44, 79%, 31%,0.4)`; //"rgba(0,235,255,0.3)";
this.wing(this.angle + Math.PI / 2 + flapArc * Math.sin(simulation.cycle * this.flapRate), this.wingSize, 0.5, 0.0008) this.wing(this.angle + Math.PI / 2 + flapArc * Math.sin(simulation.cycle * this.flapRate), this.wingSize, 0.5, 0.0012)
this.wing(this.angle - Math.PI / 2 - flapArc * Math.sin(simulation.cycle * this.flapRate), this.wingSize, 0.5, 0.0008) this.wing(this.angle - Math.PI / 2 - flapArc * Math.sin(simulation.cycle * this.flapRate), this.wingSize, 0.5, 0.0012)
} else { } else {
this.wingSize = 0.96 * this.wingSize + 0 //shrink while stunned this.wingSize = 0.96 * this.wingSize + 0 //shrink while stunned
} }
@@ -4175,7 +4213,7 @@ const spawn = {
me.isMobBullet = true; me.isMobBullet = true;
me.isUnstable = true; //dies when blocked me.isUnstable = true; //dies when blocked
me.showHealthBar = false; me.showHealthBar = false;
me.explodeRange = 200 + 150 * Math.random() me.explodeRange = 210 + 140 * Math.random()
me.isExploding = false me.isExploding = false
me.countDown = Math.ceil(4 * Math.random()) me.countDown = Math.ceil(4 * Math.random())
me.isInvulnerable = true //not actually invulnerable, just prevents block + ice-9 interaction me.isInvulnerable = true //not actually invulnerable, just prevents block + ice-9 interaction
@@ -4199,7 +4237,7 @@ const spawn = {
this.death(); this.death();
//hit player //hit player
if (Vector.magnitude(Vector.sub(this.position, player.position)) < this.explodeRange && m.immuneCycle < m.cycle) { if (Vector.magnitude(Vector.sub(this.position, player.position)) < this.explodeRange && m.immuneCycle < m.cycle) {
m.damage(0.01 * simulation.dmgScale * (tech.isRadioactiveResistance ? 0.25 : 1)); m.damage(0.015 * simulation.dmgScale * (tech.isRadioactiveResistance ? 0.25 : 1));
m.energy -= 0.15 * (tech.isRadioactiveResistance ? 0.25 : 1) m.energy -= 0.15 * (tech.isRadioactiveResistance ? 0.25 : 1)
if (m.energy < 0) m.energy = 0 if (m.energy < 0) m.energy = 0
} }

View File

@@ -498,7 +498,7 @@ const tech = {
for (let i = 0; i < 7; i++) powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "gun"); for (let i = 0; i < 7; i++) powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "gun");
}, },
remove() { remove() {
tech.isGunCycle = false; if (!this.count) tech.isGunCycle = false; // only set to false if you don't have this tech
// if (tech.isGunCycle) { // if (tech.isGunCycle) {
// for (let i = 0; i < 8; i++) { // for (let i = 0; i < 8; i++) {
// if (b.inventory.length) b.removeGun(b.guns[b.inventory[b.inventory.length - 1]].name) //remove your last gun // if (b.inventory.length) b.removeGun(b.guns[b.inventory[b.inventory.length - 1]].name) //remove your last gun
@@ -3880,7 +3880,7 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.isMineDrop + tech.isNailBotUpgrade + tech.fragments + tech.nailsDeathMob + (tech.haveGunCheck("super balls") + (tech.haveGunCheck("mine") && !tech.isLaserMine) + (tech.haveGunCheck("nail gun")) + tech.isNeedles + tech.isNailShot + tech.isRivets) * 2 > 1 return tech.isMineDrop + tech.isNailBotUpgrade + tech.fragments + tech.nailsDeathMob + (tech.haveGunCheck("super balls") + (tech.haveGunCheck("mine") && !(tech.isLaserMine || tech.isFoamMine)) + (tech.haveGunCheck("nail gun")) + tech.isNeedles + tech.isNailShot + tech.isRivets) * 2 > 1
}, },
requires: "nails, nail gun, rivets, shotgun", requires: "nails, nail gun, rivets, shotgun",
effect() { effect() {
@@ -3900,7 +3900,7 @@ const tech = {
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
// return (tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles) || (tech.haveGunCheck("mines")) // return (tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles) || (tech.haveGunCheck("mines"))
return tech.isMineDrop || tech.isNailBotUpgrade || tech.fragments || tech.nailsDeathMob || (tech.haveGunCheck("mine") && !tech.isLaserMine) || (tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles) || (tech.haveGunCheck("shotgun") && (tech.isNeedles || tech.isNailShot)) return tech.isMineDrop || tech.isNailBotUpgrade || tech.fragments || tech.nailsDeathMob || (tech.haveGunCheck("mine") && !(tech.isLaserMine || tech.isFoamMine)) || (tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles) || (tech.haveGunCheck("shotgun") && (tech.isNeedles || tech.isNailShot))
}, },
// //
requires: "nail gun, not rotary cannon, rivets, or needles", requires: "nail gun, not rotary cannon, rivets, or needles",
@@ -4052,7 +4052,7 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.isMineDrop || tech.isNailBotUpgrade || tech.fragments || tech.nailsDeathMob || (tech.haveGunCheck("mine") && !tech.isLaserMine) || (tech.haveGunCheck("nail gun") && !tech.isShieldPierce) || (tech.haveGunCheck("shotgun") && (tech.isNeedles || tech.isNailShot)) return tech.isMineDrop || tech.isNailBotUpgrade || tech.fragments || tech.nailsDeathMob || (tech.haveGunCheck("mine") && !(tech.isLaserMine || tech.isFoamMine)) || (tech.haveGunCheck("nail gun") && !tech.isShieldPierce) || (tech.haveGunCheck("shotgun") && (tech.isNeedles || tech.isNailShot))
}, },
requires: "nail gun, nails, rivets, mine, not ceramic needles", requires: "nail gun, nails, rivets, mine, not ceramic needles",
effect() { effect() {
@@ -4065,7 +4065,7 @@ const tech = {
{ {
name: "6s half-life", name: "6s half-life",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Half-life' class="link">6s half-life</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Half-life' class="link">6s half-life</a>`,
description: "<strong>nails</strong> are made of <strong class='color-p'>plutonium-238</strong><br><strong>+100%</strong> <strong class='color-d'>damage</strong> over <strong>6</strong> seconds", description: "<span style = 'font-size:90%;'><strong>nails</strong>, <strong>needles</strong>, <strong>rivets</strong> are made of <strong class='color-p'>plutonium-238</strong></span><br><strong class='color-p'>radioactive</strong> <strong class='color-d'>damage</strong> lasts <strong>+3</strong> seconds",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -4085,7 +4085,7 @@ const tech = {
{ {
name: "1s half-life", name: "1s half-life",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Half-life' class="link">1s half-life</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Half-life' class="link">1s half-life</a>`,
description: "<strong>nails</strong> are made of <strong class='color-p'>lithium-8</strong><br><strong class='color-d'>damage</strong> occurs after <strong>1</strong> second", description: "<span style = 'font-size:95%;'><strong>nails</strong>, <strong>needles</strong>, <strong>rivets</strong> are made of <strong class='color-p'>lithium-8</strong><br><strong>+300%</strong> <strong class='color-p'>radioactive</strong> <strong class='color-d'>damage</strong> for <strong>1</strong> second</span>",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -5144,6 +5144,25 @@ const tech = {
} }
} }
}, },
{
name: "elephant's toothpaste",
description: "<strong>mines</strong> catalyze a reaction<br>that yields <strong>foam</strong> bubbles",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("mine") && !tech.isMineSentry
},
requires: "mines, not sentry",
effect() {
tech.isFoamMine = true;
},
remove() {
tech.isFoamMine = false;
}
},
{ {
name: "laser-mines", name: "laser-mines",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Laser' class="link">laser-mines</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Laser' class="link">laser-mines</a>`,
@@ -5173,9 +5192,9 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.haveGunCheck("mine") return tech.haveGunCheck("mine") && !tech.isFoamMine
}, },
requires: "mines", requires: "mines, not elephant's toothpaste",
effect() { effect() {
tech.isMineSentry = true; tech.isMineSentry = true;
}, },
@@ -5285,7 +5304,7 @@ const tech = {
}, },
{ {
name: "siphonaptera", name: "siphonaptera",
description: "<strong>shotgun</strong> and <strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> hatch <strong class='color-p' style='letter-spacing: -0.8px;'>fleas</strong>", //<br><strong class='color-p' style='letter-spacing: 2px;'>spore</strong> <strong class='color-m'>tech</strong> applies to <strong class='color-p' style='letter-spacing: -0.8px;'>fleas</strong> description: "<strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> and <strong>shotgun</strong> hatch <strong class='color-p' style='letter-spacing: -0.8px;'>fleas</strong>", //<br><strong class='color-p' style='letter-spacing: 2px;'>spore</strong> <strong class='color-m'>tech</strong> applies to <strong class='color-p' style='letter-spacing: -0.8px;'>fleas</strong>
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -5621,7 +5640,7 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return !tech.isBulletTeleport && (tech.haveGunCheck("foam") || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isFoamBall) return !tech.isBulletTeleport && (tech.haveGunCheck("foam") || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isFoamBall || tech.isFoamMine)
}, },
requires: "foam, not uncertainty", requires: "foam, not uncertainty",
effect() { effect() {
@@ -5640,7 +5659,7 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return (!tech.isFoamAttract && (tech.haveGunCheck("foam") || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isFoamBall)) || (tech.haveGunCheck("matter wave") && !tech.isLongitudinal) return (!tech.isFoamAttract && (tech.haveGunCheck("foam") || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isFoamBall || tech.isFoamMine)) || (tech.haveGunCheck("matter wave") && !tech.isLongitudinal)
}, },
requires: "foam, matter wave, not electrostatic induction, not phonon", requires: "foam, matter wave, not electrostatic induction, not phonon",
effect() { effect() {
@@ -5659,7 +5678,7 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.haveGunCheck("foam") || tech.isFoamBall || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isSporeWorm || tech.isSporeFlea return tech.haveGunCheck("foam") || tech.isFoamBall || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isSporeWorm || tech.isSporeFlea || tech.isFoamMine
}, },
requires: "foam, worms", requires: "foam, worms",
effect() { effect() {
@@ -5678,7 +5697,7 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.haveGunCheck("foam") || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isFoamBall return tech.haveGunCheck("foam") || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isFoamBall || tech.isFoamMine
}, },
requires: "foam", requires: "foam",
effect() { effect() {
@@ -5699,7 +5718,7 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.haveGunCheck("foam") || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isFoamBall return tech.haveGunCheck("foam") || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isFoamBall || tech.isFoamMine
}, },
requires: "foam", requires: "foam",
effect() { effect() {
@@ -5882,7 +5901,7 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.isGrapple && !tech.isRailEnergyGain return tech.haveGunCheck("harpoon") && tech.isGrapple && !tech.isRailEnergy
}, },
requires: "grappling hook, not alternator", requires: "grappling hook, not alternator",
effect() { effect() {
@@ -5905,10 +5924,10 @@ const tech = {
}, },
requires: "harpoon, not bulk modulus", requires: "harpoon, not bulk modulus",
effect() { effect() {
tech.isRailEnergyGain = true; tech.isRailEnergy = true;
}, },
remove() { remove() {
tech.isRailEnergyGain = false; tech.isRailEnergy = false;
} }
}, },
{ {
@@ -6170,7 +6189,7 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.isLaserLens return tech.haveGunCheck("laser") && tech.isLaserLens
}, },
requires: "lens", requires: "lens",
effect() { effect() {
@@ -6259,7 +6278,7 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.isWideLaser return tech.haveGunCheck("laser") && tech.isWideLaser
}, },
requires: "laser gun, diffuse beam", requires: "laser gun, diffuse beam",
effect() { effect() {
@@ -6648,7 +6667,7 @@ const tech = {
}, },
{ {
name: "dynamic equilibrium", name: "dynamic equilibrium",
descriptionFunction() { return `increase <strong class='color-d'>damage</strong> by your <strong class='color-defense'>defense</strong> times<br><strong>5%</strong> of your last ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"} loss &nbsp; <em style = 'font-size:94%;'>(+${(100*tech.lastHitDamage * m.lastHit * (2 - m.harmReduction())).toFixed(0)}% damage)</em>` }, // = <strong>+${10*m.harmReduction()}%</strong> descriptionFunction() { return `increase <strong class='color-d'>damage</strong> by your <strong class='color-defense'>defense</strong> and<br><strong>5%</strong> of your last ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"} loss &nbsp; <em style = 'font-size:94%;'>(+${(100*tech.lastHitDamage * m.lastHit * (2 - m.harmReduction())).toFixed(0)}% damage)</em>` }, // = <strong>+${10*m.harmReduction()}%</strong>
// descriptionFunction() { return `increase <strong class='color-d'>damage</strong> by your last ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"} loss<br><strong style = 'font-size:90%;'>(${(tech.lastHitDamage).toFixed(0)}%)(${(100*m.lastHit).toFixed(0)} ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"})(${2 - m.harmReduction()} <strong class='color-defense'>defense</strong>) = ${(100*tech.lastHitDamage * m.lastHit * (2 - m.harmReduction())).toFixed(0)}% <strong class='color-d'>damage</strong></strong> ` }, // = <strong>+${10*m.harmReduction()}%</strong> // descriptionFunction() { return `increase <strong class='color-d'>damage</strong> by your last ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"} loss<br><strong style = 'font-size:90%;'>(${(tech.lastHitDamage).toFixed(0)}%)(${(100*m.lastHit).toFixed(0)} ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"})(${2 - m.harmReduction()} <strong class='color-defense'>defense</strong>) = ${(100*tech.lastHitDamage * m.lastHit * (2 - m.harmReduction())).toFixed(0)}% <strong class='color-d'>damage</strong></strong> ` }, // = <strong>+${10*m.harmReduction()}%</strong>
isFieldTech: true, isFieldTech: true,
maxCount: 9, maxCount: 9,
@@ -10335,7 +10354,7 @@ const tech = {
isPulseLaser: null, isPulseLaser: null,
isRadioactive: null, isRadioactive: null,
radioactiveDamage: null, radioactiveDamage: null,
isRailEnergyGain: null, isRailEnergy: null,
isMineSentry: null, isMineSentry: null,
isIncendiary: null, isIncendiary: null,
overfillDrain: null, overfillDrain: null,
@@ -10360,6 +10379,7 @@ const tech = {
isMissileBig: null, isMissileBig: null,
isMissileBiggest: null, isMissileBiggest: null,
isLaserMine: null, isLaserMine: null,
isFoamMine: null,
isAmmoFoamSize: null, isAmmoFoamSize: null,
isIceIX: null, isIceIX: null,
isDupDamage: null, isDupDamage: null,

View File

@@ -1,14 +1,27 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
snakeBoss is now dragonFlyBoss elephant's toothpaste: mines make foam
snakeSpitBoss till exists, don't worry
flutter and beetle mobs changes sentry fires about 40% faster
but each shot slightly reduces the total duration
(duration = 17s - 1/10 s per shot)
Noether violation has 50% less forward recoil for shotgun foam can move through blocks a bit faster
laser reflection damage is increased
about 15% -> 8% damage loss per reflection
beetleBoss pushes player away and spawns baby flutter mobs
fire rate affects block throwing charge rate
*********************************************************** TODO ***************************************************** *********************************************************** TODO *****************************************************
bug blocks and power ups falling through map
always foam gun (4-5 times)
might be about tech pressure vessel
happens rarely, doesn't repeat
normally after level 6
seed isn't working right from shared URL
mob mechanics mob mechanics
bullets hit player and stay attached for 4-5 seconds, slowing player bullets hit player and stay attached for 4-5 seconds, slowing player
hopperBullets? hopperBullets?