stress concentration

nail gun tech: stress concentration - if a mob has below 50% durability after taking damage
  from needles or rivets near the center of it's body it dies

caliber 16->25% nail, needle, rivet size/damage
combined tech: flagella - spores move +50% faster
  spores follow you if they can't find a target
shock wave stun also applies to sporangium
  no longer reduces explosion size

JUNK tech: reincarnation - kill all mobs and spawn new ones
  (also spawn a few extra mobs for fun)

updated pause menu and fields descriptions to new wording style

bug fixes
This commit is contained in:
landgreen
2022-06-19 08:32:45 -07:00
parent e68ed81ba1
commit 698c18482b
9 changed files with 412 additions and 222 deletions

View File

@@ -168,11 +168,9 @@ const b = {
for (let i = 0, len = tech.tech.length; i < len; i++) { for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isGunTech && tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable && !tech.tech[i].isRemoveGun) { if (tech.tech[i].isGunTech && tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable && !tech.tech[i].isRemoveGun) {
const remove = tech.removeTech(i) const remove = tech.removeTech(i)
// console.log(remove, tech.tech[i].count, tech.tech[i].name)
gunTechCount += remove gunTechCount += remove
} }
} }
// console.log(gunTechCount)
//get a random gun tech for your gun //get a random gun tech for your gun
for (let i = 0; i < gunTechCount; i++) { for (let i = 0; i < gunTechCount; i++) {
@@ -353,7 +351,7 @@ const b = {
radius *= tech.explosiveRadius radius *= tech.explosiveRadius
let dist, sub, knock; let dist, sub, knock;
let dmg = radius * 0.019 * (tech.isExplosionStun ? 0.7 : 1); //* 0.013 * (tech.isExplosionStun ? 0.7 : 1); let dmg = radius * 0.019
if (tech.isExplosionHarm) radius *= 1.7 // 1/sqrt(2) radius -> area if (tech.isExplosionHarm) radius *= 1.7 // 1/sqrt(2) radius -> area
if (tech.isSmallExplosion) { if (tech.isSmallExplosion) {
// color = "rgba(255,0,30,0.7)" // color = "rgba(255,0,30,0.7)"
@@ -393,7 +391,7 @@ const b = {
if (mob[i].shield) dmg *= 2.5 //balancing explosion dmg to shields if (mob[i].shield) dmg *= 2.5 //balancing explosion dmg to shields
if (Matter.Query.ray(map, mob[i].position, where).length > 0) dmg *= 0.5 //reduce damage if a wall is in the way if (Matter.Query.ray(map, mob[i].position, where).length > 0) dmg *= 0.5 //reduce damage if a wall is in the way
mobs.statusDoT(mob[i], dmg * damageScale * 0.25, 240) //apply radiation damage status effect on direct hits mobs.statusDoT(mob[i], dmg * damageScale * 0.25, 240) //apply radiation damage status effect on direct hits
if (tech.isExplosionStun) mobs.statusStun(mob[i], 60) if (tech.isStun) mobs.statusStun(mob[i], 30)
mob[i].locatePlayer(); mob[i].locatePlayer();
damageScale *= 0.87 //reduced damage for each additional explosion target damageScale *= 0.87 //reduced damage for each additional explosion target
} }
@@ -429,7 +427,6 @@ const b = {
// const mitigate = Math.min(1, Math.max(1 - m.energy * 0.5, 0)) // const mitigate = Math.min(1, Math.max(1 - m.energy * 0.5, 0))
m.energy -= 0.12 m.energy -= 0.12
// m.damage(0.01 * harm); //remove 99% of the damage 1-0.99 // m.damage(0.01 * harm); //remove 99% of the damage 1-0.99
// console.log(Math.max(0, Math.min(0.15 - 0.01 * player.speed, 0.15)))
knock = Vector.mult(Vector.normalise(sub), -0.6 * player.mass * Math.max(0, Math.min(0.15 - 0.002 * player.speed, 0.15))); knock = Vector.mult(Vector.normalise(sub), -0.6 * player.mass * Math.max(0, Math.min(0.15 - 0.002 * player.speed, 0.15)));
player.force.x = knock.x; // not += so crazy forces can't build up with MIRV player.force.x = knock.x; // not += so crazy forces can't build up with MIRV
player.force.y = knock.y - 0.3; //some extra vertical kick player.force.y = knock.y - 0.3; //some extra vertical kick
@@ -502,8 +499,8 @@ const b = {
mob[i].damage(dmg * damageScale * m.dmgScale); mob[i].damage(dmg * damageScale * m.dmgScale);
mob[i].locatePlayer(); mob[i].locatePlayer();
knock = Vector.mult(Vector.normalise(sub), -Math.sqrt(dmg * damageScale) * mob[i].mass * (mob[i].isBoss ? 0.003 : 0.01)); knock = Vector.mult(Vector.normalise(sub), -Math.sqrt(dmg * damageScale) * mob[i].mass * (mob[i].isBoss ? 0.003 : 0.01));
if (tech.isExplosionStun) { if (tech.isStun) {
mobs.statusStun(mob[i], 120) mobs.statusStun(mob[i], 30)
} else if (!mob[i].isInvulnerable) { } else if (!mob[i].isInvulnerable) {
mob[i].force.x += knock.x; mob[i].force.x += knock.x;
mob[i].force.y += knock.y; mob[i].force.y += knock.y;
@@ -513,8 +510,8 @@ const b = {
} else if (!mob[i].seePlayer.recall && dist < alertRange) { } else if (!mob[i].seePlayer.recall && dist < alertRange) {
mob[i].locatePlayer(); mob[i].locatePlayer();
knock = Vector.mult(Vector.normalise(sub), -Math.sqrt(dmg * damageScale) * mob[i].mass * (mob[i].isBoss ? 0 : 0.006)); knock = Vector.mult(Vector.normalise(sub), -Math.sqrt(dmg * damageScale) * mob[i].mass * (mob[i].isBoss ? 0 : 0.006));
if (tech.isExplosionStun) { if (tech.isStun) {
mobs.statusStun(mob[i], 60) mobs.statusStun(mob[i], 30)
} else if (!mob[i].isInvulnerable) { } else if (!mob[i].isInvulnerable) {
mob[i].force.x += knock.x; mob[i].force.x += knock.x;
mob[i].force.y += knock.y; mob[i].force.y += knock.y;
@@ -2463,7 +2460,7 @@ const b = {
ctx.globalAlpha = 1; ctx.globalAlpha = 1;
} }
}, },
AoEStunEffect(where, range, cycles = 90 + 60 * Math.random()) { AoEStunEffect(where, range, cycles = 120 + 60 * Math.random()) {
for (let i = 0, len = mob.length; i < len; ++i) { for (let i = 0, len = mob.length; i < len; ++i) {
if (mob[i].alive && !mob[i].isShielded && !mob[i].shield && !mob[i].isBadTarget) { if (mob[i].alive && !mob[i].isShielded && !mob[i].shield && !mob[i].isBadTarget) {
if (Vector.magnitude(Vector.sub(where, mob[i].position)) - mob[i].radius < range) mobs.statusStun(mob[i], cycles) if (Vector.magnitude(Vector.sub(where, mob[i].position)) - mob[i].radius < range) mobs.statusStun(mob[i], cycles)
@@ -2509,7 +2506,7 @@ const b = {
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.isExplosionStun) b.AoEStunEffect(this.position, 1300); if (tech.isStun) b.AoEStunEffect(this.position, 1300); //AoEStunEffect(where, range, cycles = 90 + 60 * Math.random()) {
this.do = this.laserSpin this.do = this.laserSpin
if (this.angularSpeed < 0.5) this.torque += this.inertia * this.torqueMagnitude * 200 //spin if (this.angularSpeed < 0.5) this.torque += this.inertia * this.torqueMagnitude * 200 //spin
this.endCycle = simulation.cycle + 360 + 120 this.endCycle = simulation.cycle + 360 + 120
@@ -2644,7 +2641,7 @@ const b = {
Matter.Query.ray(body, this.position, mob[i].position).length === 0 && Matter.Query.ray(body, this.position, mob[i].position).length === 0 &&
!mob[i].isInvulnerable !mob[i].isInvulnerable
) { ) {
if (tech.isExplosionStun) b.AoEStunEffect(this.position, 700 + mob[i].radius + random); if (tech.isStun) b.AoEStunEffect(this.position, 700 + 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 = 8 + Math.floor(3 * Math.random())
this.endCycle = simulation.cycle + 1020 this.endCycle = simulation.cycle + 1020
@@ -2691,7 +2688,7 @@ const b = {
// angle: Math.random() * 2 * Math.PI, // angle: Math.random() * 2 * Math.PI,
friction: 0, friction: 0,
frictionAir: 0.025, frictionAir: 0.025,
thrust: (tech.isFastSpores ? 0.0012 : 0.00055) * (1 + 0.5 * (Math.random() - 0.5)), thrust: (tech.isSporeFollow ? 0.0012 : 0.00055) * (1 + 0.5 * (Math.random() - 0.5)),
wormSize: wormSize, wormSize: wormSize,
wormTail: 1 + Math.max(4, Math.min(wormSize - 2 * tech.wormSize, 30)), wormTail: 1 + Math.max(4, Math.min(wormSize - 2 * tech.wormSize, 30)),
dmg: (tech.isMutualism ? 7 : 2.9) * wormSize, //bonus damage from tech.isMutualism //2.5 is extra damage as worm dmg: (tech.isMutualism ? 7 : 2.9) * wormSize, //bonus damage from tech.isMutualism //2.5 is extra damage as worm
@@ -2809,7 +2806,7 @@ const b = {
angle: Math.random() * 2 * Math.PI, angle: Math.random() * 2 * Math.PI,
friction: 0, friction: 0,
frictionAir: 0.025, frictionAir: 0.025,
thrust: (tech.isFastSpores ? 0.0011 : 0.0005) * (1 + 0.3 * (Math.random() - 0.5)), thrust: (tech.isSporeFollow ? 0.0011 : 0.0005) * (1 + 0.3 * (Math.random() - 0.5)),
dmg: tech.isMutualism ? 16.8 : 7, //bonus damage from tech.isMutualism dmg: tech.isMutualism ? 16.8 : 7, //bonus damage from tech.isMutualism
lookFrequency: 100 + Math.floor(117 * Math.random()), lookFrequency: 100 + Math.floor(117 * Math.random()),
classType: "bullet", classType: "bullet",
@@ -2901,8 +2898,17 @@ const b = {
// this.force.y += this.mass * 0.0001; //gravity // this.force.y += this.mass * 0.0001; //gravity
// } // }
// if (this.nextPortCycle < simulation.cycle) { //teleport around if you have tech.isBulletTeleport
// this.nextPortCycle = simulation.cycle + this.portFrequency
// const range = 50 * Math.random()
// Matter.Body.setPosition(this, Vector.add(this.position, Vector.rotate({ x: range, y: 0 }, 2 * Math.PI * Math.random())))
// }
}, },
}); });
// if (tech.isBulletTeleport) {
// bullet[bIndex].portFrequency = 10 + Math.floor(5 * Math.random())
// bullet[bIndex].nextPortCycle = simulation.cycle + bullet[bIndex].portFrequency
// }
const SPEED = 4 + 8 * Math.random(); const SPEED = 4 + 8 * Math.random();
const ANGLE = 2 * Math.PI * Math.random() const ANGLE = 2 * Math.PI * Math.random()
@@ -2941,12 +2947,12 @@ const b = {
minDmgSpeed: 0, minDmgSpeed: 0,
lockedOn: null, lockedOn: null,
beforeDmg(who) { beforeDmg(who) {
mobs.statusSlow(who, 180)
this.endCycle = simulation.cycle
// if (tech.isHeavyWater) mobs.statusDoT(who, 0.15, 300)
if (tech.iceEnergy && !who.shield && !who.isShielded && who.isDropPowerUp && who.alive && m.immuneCycle < m.cycle) { if (tech.iceEnergy && !who.shield && !who.isShielded && who.isDropPowerUp && who.alive && m.immuneCycle < m.cycle) {
setTimeout(() => { if (!who.alive) m.energy += tech.iceEnergy * 0.8 }, 10); setTimeout(() => { if (!who.alive) m.energy += tech.iceEnergy * 0.8 }, 10);
} }
mobs.statusSlow(who, 180)
this.endCycle = simulation.cycle
// if (tech.isHeavyWater) mobs.statusDoT(who, 0.15, 300)
}, },
onEnd() {}, onEnd() {},
do() { do() {
@@ -3816,6 +3822,38 @@ const b = {
} }
} }
}, },
crit(mob, bullet) {
if (!mob.shield && Vector.dot(Vector.normalise(Vector.sub(mob.position, bullet.position)), Vector.normalise(bullet.velocity)) > 0.99 - 4 / mob.radius) {
let cycle = () => { //makes this run after damage
if (mob.health < 0.5 && mob.damageReduction > 0 && mob.alive) {
const color = 'rgb(255,255,255)'
simulation.drawList.push({
x: mob.position.x,
y: mob.position.y,
radius: mob.radius * 1.2,
color: color, //"rgba(0,0,0,0.6)",
time: 8
});
simulation.drawList.push({
x: mob.position.x,
y: mob.position.y,
radius: mob.radius * 0.75,
color: color, //"rgba(0,0,0,0.85)",
time: 15
});
simulation.drawList.push({
x: mob.position.x,
y: mob.position.y,
radius: mob.radius * 0.4,
color: color, //"rgb(0,0,0)",
time: 20
});
mob.death();
}
}
requestAnimationFrame(cycle);
}
},
nail(pos, velocity, dmg = 1) { nail(pos, velocity, dmg = 1) {
dmg *= tech.bulletSize dmg *= tech.bulletSize
const me = bullet.length; const me = bullet.length;
@@ -3826,11 +3864,10 @@ const b = {
bullet[me].dmg = tech.isNailRadiation ? 0 : dmg bullet[me].dmg = tech.isNailRadiation ? 0 : dmg
bullet[me].beforeDmg = function(who) { //beforeDmg is rewritten with ice crystal tech bullet[me].beforeDmg = function(who) { //beforeDmg is rewritten with ice crystal tech
if (tech.isNailRadiation) mobs.statusDoT(who, dmg * (tech.isFastRadiation ? 1.3 : 0.44), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles if (tech.isNailRadiation) mobs.statusDoT(who, dmg * (tech.isFastRadiation ? 1.3 : 0.44), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles
if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) { if (tech.isNailCrit) {
b.explosion(this.position, 150 + 30 * Math.random()); //makes bullet do explosive damage at end if (!who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.97 - 2 / who.radius) {
} b.explosion(this.position, 150 + 30 * Math.random()); //makes bullet do explosive damage at end
if (true && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) { }
b.targetedNail(this.position, 1, 39 + 6 * Math.random())
} }
}; };
bullet[me].do = function() {}; bullet[me].do = function() {};
@@ -3861,9 +3898,12 @@ const b = {
} }
} }
if (!immune) { if (!immune) {
if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) { if (tech.isNailCrit) {
b.explosion(this.position, 220 * tech.bulletSize + 50 * Math.random()); //makes bullet do explosive damage at end if (!who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.97 - 2 / who.radius) {
} b.explosion(this.position, 220 + 50 * Math.random()); //makes bullet do explosive damage at end
}
} else if (tech.isCritKill) b.crit(who, this)
this.immuneList.push(who.id) //remember that this needle has hit this mob once already this.immuneList.push(who.id) //remember that this needle has hit this mob once already
let dmg = this.dmg * tech.bulletSize * m.dmgScale let dmg = this.dmg * tech.bulletSize * m.dmgScale
if (tech.isNailRadiation) { if (tech.isNailRadiation) {
@@ -3916,9 +3956,12 @@ const b = {
} }
} }
if (!immune) { if (!immune) {
if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) { if (tech.isNailCrit) {
b.explosion(this.position, 220 * tech.bulletSize + 50 * Math.random()); //makes bullet do explosive damage at end if (!who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.97 - 2 / who.radius) {
} b.explosion(this.position, 220 + 50 * Math.random()); //makes bullet do explosive damage at end
}
} else if (tech.isCritKill) b.crit(who, this)
this.immuneList.push(who.id) //remember that this needle has hit this mob once already this.immuneList.push(who.id) //remember that this needle has hit this mob once already
let dmg = this.dmg * tech.bulletSize * m.dmgScale let dmg = this.dmg * tech.bulletSize * m.dmgScale
if (tech.isNailRadiation) { if (tech.isNailRadiation) {
@@ -5060,9 +5103,11 @@ const b = {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
b.explosion(this.position, 100 + (Math.random() - 0.5) * 20); //makes bullet do explosive damage at end b.explosion(this.position, 100 + (Math.random() - 0.5) * 20); //makes bullet do explosive damage at end
} }
if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) { if (tech.isNailCrit) {
b.explosion(this.position, 300 + 30 * Math.random()); //makes bullet do explosive damage at end if (!who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.97 - 2 / who.radius) {
} b.explosion(this.position, 300 + 40 * Math.random()); //makes bullet do explosive damage at end
}
} else if (tech.isCritKill) b.crit(who, this)
if (tech.isNailRadiation) mobs.statusDoT(who, 7 * (tech.isFastRadiation ? 0.7 : 0.24), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles if (tech.isNailRadiation) mobs.statusDoT(who, 7 * (tech.isFastRadiation ? 0.7 : 0.24), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles
if (this.speed > 4 && tech.fragments) { if (this.speed > 4 && tech.fragments) {
b.targetedNail(this.position, 1.25 * tech.fragments * tech.bulletSize) b.targetedNail(this.position, 1.25 * tech.fragments * tech.bulletSize)
@@ -5131,9 +5176,12 @@ const b = {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
b.explosion(this.position, 100 + (Math.random() - 0.5) * 20); //makes bullet do explosive damage at end b.explosion(this.position, 100 + (Math.random() - 0.5) * 20); //makes bullet do explosive damage at end
} }
if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) { if (tech.isNailCrit) {
b.explosion(this.position, 300 + 30 * Math.random()); //makes bullet do explosive damage at end if (!who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.97 - 2 / who.radius) {
} b.explosion(this.position, 300 + 40 * Math.random()); //makes bullet do explosive damage at end
}
} else if (tech.isCritKill) b.crit(who, this)
if (tech.isNailRadiation) mobs.statusDoT(who, 7 * (tech.isFastRadiation ? 0.7 : 0.24), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles if (tech.isNailRadiation) mobs.statusDoT(who, 7 * (tech.isFastRadiation ? 0.7 : 0.24), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles
if (this.speed > 4 && tech.fragments) { if (this.speed > 4 && tech.fragments) {
b.targetedNail(this.position, 1.25 * tech.fragments * tech.bulletSize) b.targetedNail(this.position, 1.25 * tech.fragments * tech.bulletSize)
@@ -5203,14 +5251,16 @@ const b = {
bullet[bullet.length - 1].beforeDmg = function(who) { bullet[bullet.length - 1].beforeDmg = function(who) {
mobs.statusSlow(who, 60) mobs.statusSlow(who, 60)
if (tech.isNailRadiation) mobs.statusDoT(who, 1 * (tech.isFastRadiation ? 1.3 : 0.44), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles if (tech.isNailRadiation) mobs.statusDoT(who, 1 * (tech.isFastRadiation ? 1.3 : 0.44), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles
if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) { if (tech.isNailCrit) {
b.explosion(this.position, 150 + 30 * Math.random()); //makes bullet do explosive damage at end if (!who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.97 - 2 / who.radius) {
b.explosion(this.position, 150 + 30 * Math.random()); //makes bullet do explosive damage at end
}
} }
}; };
if (m.energy < 0.01) { if (m.energy < 0.01) {
m.fireCDcycle = m.cycle + 60; // cool down m.fireCDcycle = m.cycle + 60; // cool down
} else { } else {
m.energy -= m.fieldRegen + 0.008 m.energy -= 0.01
} }
} }
}, },
@@ -5289,12 +5339,13 @@ const b = {
} }
} }
}; };
if (tech.fragments) { bullet[me].beforeDmg = function(who) {
bullet[me].beforeDmg = function() { if (this.speed > 4) {
if (this.speed > 4) { if (tech.fragments) {
b.targetedNail(this.position, 6 * tech.fragments * tech.bulletSize) b.targetedNail(this.position, 6 * tech.fragments * tech.bulletSize)
this.endCycle = 0 //triggers despawn this.endCycle = 0 //triggers despawn
} }
if (tech.isCritKill) b.crit(who, this)
} }
} }
} else if (tech.isIncendiary) { } else if (tech.isIncendiary) {
@@ -6043,7 +6094,7 @@ const b = {
bullet[me].maxRadius = 30; bullet[me].maxRadius = 30;
bullet[me].restitution = 0.3; bullet[me].restitution = 0.3;
bullet[me].minDmgSpeed = 0; bullet[me].minDmgSpeed = 0;
bullet[me].totalSpores = 8 + 2 * tech.isFastSpores + 2 * tech.isSporeFreeze * (tech.isSporeWorm ? 0.5 : 1) bullet[me].totalSpores = 8 + 2 * tech.isSporeFreeze * (tech.isSporeWorm ? 0.5 : 1)
bullet[me].stuck = function() {}; bullet[me].stuck = function() {};
bullet[me].beforeDmg = function() {}; bullet[me].beforeDmg = function() {};
bullet[me].do = function() { bullet[me].do = function() {
@@ -6152,6 +6203,7 @@ const b = {
} else { } else {
for (let i = 0; i < this.totalSpores; i++) b.spore(this.position) for (let i = 0; i < this.totalSpores; i++) b.spore(this.position)
} }
if (tech.isStun) b.AoEStunEffect(this.position, 600, 270 + 120 * Math.random()); //AoEStunEffect(where, range, cycles = 120 + 60 * Math.random()) {
} }
} }
}, { }, {
@@ -6392,7 +6444,6 @@ const b = {
if (mob[i].alive && !mob[i].isBadTarget && !mob[i].shield && Matter.Query.ray(map, m.pos, mob[i].position).length === 0 && !mob[i].isInvulnerable) { if (mob[i].alive && !mob[i].isBadTarget && !mob[i].shield && Matter.Query.ray(map, m.pos, mob[i].position).length === 0 && !mob[i].isInvulnerable) {
const dot = Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, m.pos))) //the dot product of diff and dir will return how much over lap between the vectors const dot = Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, m.pos))) //the dot product of diff and dir will return how much over lap between the vectors
const dist = Vector.magnitude(Vector.sub(where, mob[i].position)) const dist = Vector.magnitude(Vector.sub(where, mob[i].position))
// console.log(dot, 0.95 - Math.min(dist * 0.00015, 0.3))
if (dot > 0.95 - Math.min(dist * 0.00015, 0.3)) { //lower dot product threshold for targeting then if you only have one harpoon //target closest mob that player is looking at and isn't too close to target if (dot > 0.95 - Math.min(dist * 0.00015, 0.3)) { //lower dot product threshold for targeting then if you only have one harpoon //target closest mob that player is looking at and isn't too close to target
// if (this.ammo > -1) { // if (this.ammo > -1) {
// this.ammo-- // this.ammo--

View File

@@ -242,11 +242,13 @@ const build = {
</svg><br>` </svg><br>`
text += ` text += `
<br><strong class='color-d'>damage</strong>: ${((tech.damageFromTech())).toPrecision(3)} &nbsp; &nbsp; difficulty: ${((m.dmgScale)).toPrecision(3)} <br><strong class='color-d'>damage</strong>: ${((tech.damageFromTech())).toPrecision(3)} &nbsp; &nbsp; difficulty: ${((m.dmgScale)).toPrecision(3)}
<br><strong class='color-defense'>defense</strong>: ${(1-m.harmReduction()).toPrecision(3)} &nbsp; &nbsp; difficulty: ${(simulation.dmgScale).toPrecision(3)} <br><strong class='color-defense'>defense</strong>: ${(1-m.harmReduction()).toPrecision(3)} &nbsp; &nbsp; difficulty: ${(1/simulation.dmgScale).toPrecision(3)}
<br><strong><em>fire rate</em></strong>: ${((1-b.fireCDscale)*100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}% <br><strong><em>fire rate</em></strong>: ${((1-b.fireCDscale)*100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}%
<br><strong class='color-dup'>duplication</strong>: ${(tech.duplicationChance()*100).toFixed(0)}% <br><strong class='color-dup'>duplication</strong>: ${(tech.duplicationChance()*100).toFixed(0)}%
${botText} ${botText}
<br><br><strong class='color-h'>health</strong>: (${(m.health*100).toFixed(0)} / ${(m.maxHealth*100).toFixed(0)}) &nbsp; <strong class='color-f'>energy</strong>: (${(m.energy*100).toFixed(0)} / ${(m.maxEnergy*100).toFixed(0)}) <br>
<br><strong class='color-h'>health</strong>: (${(m.health*100).toFixed(0)} / ${(m.maxHealth*100).toFixed(0)})
<br><strong class='color-f'>energy</strong>: (${(m.energy*100).toFixed(0)} / ${(m.maxEnergy*100).toFixed(0)})
<br><strong class='color-g'>gun</strong>: ${b.activeGun === null || b.activeGun === undefined ? "undefined":b.guns[b.activeGun].name} &nbsp; <strong class='color-g'>ammo</strong>: ${b.activeGun === null || b.activeGun === undefined ? "0":b.guns[b.activeGun].ammo} <br><strong class='color-g'>gun</strong>: ${b.activeGun === null || b.activeGun === undefined ? "undefined":b.guns[b.activeGun].name} &nbsp; <strong class='color-g'>ammo</strong>: ${b.activeGun === null || b.activeGun === undefined ? "0":b.guns[b.activeGun].ammo}
<br><strong class='color-m'>tech</strong>: ${tech.totalCount} &nbsp; <strong class='color-r'>research</strong>: ${powerUps.research.count} <br><strong class='color-m'>tech</strong>: ${tech.totalCount} &nbsp; <strong class='color-r'>research</strong>: ${powerUps.research.count}
<br> <br>

View File

@@ -7,9 +7,9 @@ const level = {
defaultZoom: 1400, defaultZoom: 1400,
onLevel: -1, onLevel: -1,
levelsCleared: 0, levelsCleared: 0,
// playableLevels: ["pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion"],
//see level.populateLevels: (intro, ... , reservoir, reactor, ... , gauntlet, final) added later //see level.populateLevels: (intro, ... , reservoir, reactor, ... , gauntlet, final) added later
playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion"], playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion"],
// playableLevels: ["pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion"],
communityLevels: ["stronghold", "basement", "crossfire", "vats", "run", "n-gon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp"], communityLevels: ["stronghold", "basement", "crossfire", "vats", "run", "n-gon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp"],
trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon"], trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon"],
levels: [], levels: [],
@@ -20,12 +20,13 @@ const level = {
// m.setField("time dilation") // m.setField("time dilation")
// b.giveGuns("nail gun") // b.giveGuns("nail gun")
// b.giveGuns("mine") // b.giveGuns("mine")
// tech.giveTech("laser-mines") // tech.giveTech("needle gun")
// tech.giveTech("free-electron laser") // tech.giveTech("stress concentration")
// tech.giveTech("energy conservation") // for (let i = 0; i < 100; ++i) tech.giveTech("nail-bot")
// tech.giveTech("6s half-life") // tech.giveTech("rivet gun")
// for (let i = 0; i < 10; i++) tech.giveTech("replication") // tech.giveTech("needle ice")
// tech.giveTech("eternalism") // tech.giveTech("flash freeze")
// tech.giveTech("superfluidity")
// m.maxHealth = 100 // m.maxHealth = 100
// m.health = m.maxHealth // m.health = m.maxHealth
// for (let i = 0; i < 10; i++) tech.giveTech("tungsten carbide") // for (let i = 0; i < 10; i++) tech.giveTech("tungsten carbide")
@@ -36,12 +37,14 @@ const level = {
// powerUps.research.changeRerolls(100000) // powerUps.research.changeRerolls(100000)
// tech.tech[297].frequency = 100 // tech.tech[297].frequency = 100
// m.immuneCycle = Infinity //you can't take damage // m.immuneCycle = Infinity //you can't take damage
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why // level.difficultyIncrease(40) //30 is near max on hard //60 is near max on why
// simulation.enableConstructMode() //used to build maps in testing mode // simulation.enableConstructMode() //used to build maps in testing mode
// level.perplex(); // level.perplex();
// spawn.cellBossCulture(1900, -500) // spawn.cellBossCulture(1900, -500)
// level.testing(); //not in rotation, used for testing // level.testing(); //not in rotation, used for testing
// spawn.starter(1900, -500) // spawn.starter(1900, -500, 300)
// for (let i = 0; i < 50; ++i) spawn.starter(1900, -500)
// spawn.powerUpBoss(1900, -500)
if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************ if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************
// powerUps.research.changeRerolls(3000) // powerUps.research.changeRerolls(3000)
@@ -1327,10 +1330,10 @@ const level = {
if (this.height > 0 && Matter.Query.region([player], this).length) { if (this.height > 0 && Matter.Query.region([player], this).length) {
if (m.immuneCycle < m.cycle) { if (m.immuneCycle < m.cycle) {
const DRAIN = 0.002 * (tech.isRadioactiveResistance ? 0.25 : 1) + m.fieldRegen const DRAIN = 0.0022 * (tech.isRadioactiveResistance ? 0.25 : 1) + m.fieldRegen
if (m.energy > DRAIN) { if (m.energy > DRAIN) {
m.energy -= DRAIN m.energy -= DRAIN
m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1) * 0.03) //still take 2% damage while you have energy // m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1) * 0.03) //still take 2% damage while you have energy
} else { } else {
m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1)) m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1))
} }
@@ -8849,7 +8852,7 @@ const level = {
} else { } else {
tech.addJunkTechToPool(0.49) tech.addJunkTechToPool(0.49)
} }
// spawn.randomLevelBoss(x, y, ["historyBoss"]); spawn.randomLevelBoss(x, y, ["historyBoss"]);
} }
} }

View File

@@ -59,9 +59,32 @@ const mobs = {
} }
function applySlow(whom) { function applySlow(whom) {
if (!whom.shield && !whom.isShielded && who.alive) { if (!whom.shield && !whom.isShielded && whom.alive) {
if (tech.isIceMaxHealthLoss && who.health > 0.66 && who.damageReduction > 0) who.health = 0.66 if (tech.isIceMaxHealthLoss && whom.health > 0.65 && whom.damageReduction > 0) whom.health = 0.66
if (tech.isIceKill && who.health < 0.33 && who.damageReduction > 0) who.death(); if (tech.isIceKill && whom.health < 0.34 && whom.damageReduction > 0 && whom.alive) {
simulation.drawList.push({
x: whom.position.x,
y: whom.position.y,
radius: whom.radius * 1.2,
color: "rgb(0,100,255)",
time: 8
});
simulation.drawList.push({
x: whom.position.x,
y: whom.position.y,
radius: whom.radius * 0.7,
color: "rgb(0,100,255)",
time: 12
});
simulation.drawList.push({
x: whom.position.x,
y: whom.position.y,
radius: whom.radius * 0.4,
color: "rgb(0,100,255)",
time: 16
});
whom.death();
}
if (whom.isBoss) cycles = Math.floor(cycles * 0.25) if (whom.isBoss) cycles = Math.floor(cycles * 0.25)
let i = whom.status.length let i = whom.status.length
while (i--) { while (i--) {

View File

@@ -858,7 +858,7 @@ const m = {
ctx.fillStyle = m.fillColor; ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx; m.walk_cycle += m.flipLegs * m.Vx;
ctx.save(); ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20)
ctx.translate(m.pos.x, m.pos.y); ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -3); m.calcLeg(Math.PI, -3);
m.drawLeg("#4a4a4a"); m.drawLeg("#4a4a4a");
@@ -2622,7 +2622,7 @@ const m = {
} else { } else {
m.fieldFire = true; m.fieldFire = true;
m.isBodiesAsleep = false; m.isBodiesAsleep = false;
m.drain = 0.0025 m.drain = 0.002
m.hold = function() { m.hold = function() {
if (m.isHolding) { if (m.isHolding) {
m.wakeCheck(); m.wakeCheck();

View File

@@ -105,6 +105,7 @@ const simulation = {
simulation.isTimeSkipping = true; simulation.isTimeSkipping = true;
for (let i = 0; i < cycles; i++) { for (let i = 0; i < cycles; i++) {
simulation.cycle++; simulation.cycle++;
// m.walk_cycle += (m.flipLegs * m.Vx) * 0.5; //makes the legs look like they are moving fast (it's times 0.5 because when they move too fast it's a blur)
simulation.gravity(); simulation.gravity();
Engine.update(engine, simulation.delta); Engine.update(engine, simulation.delta);
// level.custom(); // level.custom();

View File

@@ -47,13 +47,13 @@ const spawn = {
}, },
randomMob(x, y, chance = 1) { randomMob(x, y, chance = 1) {
if (spawn.spawnChance(chance) || chance === Infinity) { if (spawn.spawnChance(chance) || chance === Infinity) {
const pick = this.pickList[Math.floor(Math.random() * this.pickList.length)]; const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
this[pick](x, y); spawn[pick](x, y);
} }
if (tech.isMoreMobs || (tech.isDuplicateBoss && Math.random() < tech.duplicationChance())) { if (tech.isMoreMobs || (tech.isDuplicateBoss && Math.random() < tech.duplicationChance())) {
const pick = this.pickList[Math.floor(Math.random() * this.pickList.length)]; const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
this[pick](x, y); spawn[pick](x, y);
} }
}, },
randomSmallMob(x, y, randomSmallMob(x, y,
@@ -62,14 +62,14 @@ const spawn = {
chance = 1) { chance = 1) {
if (spawn.spawnChance(chance)) { if (spawn.spawnChance(chance)) {
for (let i = 0; i < num; ++i) { for (let i = 0; i < num; ++i) {
const pick = this.pickList[Math.floor(Math.random() * this.pickList.length)]; const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
this[pick](x + Math.round((Math.random() - 0.5) * 20) + i * size * 2.5, y + Math.round((Math.random() - 0.5) * 20), size); spawn[pick](x + Math.round((Math.random() - 0.5) * 20) + i * size * 2.5, y + Math.round((Math.random() - 0.5) * 20), size);
} }
} }
if (tech.isMoreMobs || (tech.isDuplicateBoss && Math.random() < tech.duplicationChance())) { if (tech.isMoreMobs || (tech.isDuplicateBoss && Math.random() < tech.duplicationChance())) {
for (let i = 0; i < num; ++i) { for (let i = 0; i < num; ++i) {
const pick = this.pickList[Math.floor(Math.random() * this.pickList.length)]; const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
this[pick](x + Math.round((Math.random() - 0.5) * 20) + i * size * 2.5, y + Math.round((Math.random() - 0.5) * 20), size); spawn[pick](x + Math.round((Math.random() - 0.5) * 20) + i * size * 2.5, y + Math.round((Math.random() - 0.5) * 20), size);
} }
} }
}, },
@@ -3576,7 +3576,7 @@ const spawn = {
ctx.setLineDash([]); ctx.setLineDash([]);
} }
}, },
sprayBoss(x, y, radius = 30, isSpawnBossPowerUp = true) { sprayBoss(x, y, radius = 35, isSpawnBossPowerUp = true) {
mobs.spawn(x, y, 16, radius, "rgb(255,255,255)"); mobs.spawn(x, y, 16, radius, "rgb(255,255,255)");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
@@ -3587,7 +3587,7 @@ const spawn = {
me.friction = 0; me.friction = 0;
me.frictionAir = 0; me.frictionAir = 0;
me.restitution = 1 me.restitution = 1
spawn.spawnOrbitals(me, radius + 50 + 150 * Math.random(), 1) spawn.spawnOrbitals(me, radius + 50 + 125 * Math.random(), 1)
Matter.Body.setDensity(me, 0.0022 + 0.0001 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.0022 + 0.0001 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.09 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) me.damageReduction = 0.09 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.startingDamageReduction = me.damageReduction me.startingDamageReduction = me.damageReduction
@@ -3630,8 +3630,8 @@ const spawn = {
if (this.speed < 0.01) { if (this.speed < 0.01) {
Matter.Body.setVelocity(this, Vector.mult(Vector.normalise(Vector.sub(player.position, this.position)), 0.1)); Matter.Body.setVelocity(this, Vector.mult(Vector.normalise(Vector.sub(player.position, this.position)), 0.1));
} else { } else {
if (Math.abs(this.velocity.y) < 12) Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.07 }); if (Math.abs(this.velocity.y) < 11) Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.07 });
if (Math.abs(this.velocity.x) < 9) Matter.Body.setVelocity(this, { x: this.velocity.x * 1.07, y: this.velocity.y }); if (Math.abs(this.velocity.x) < 8) Matter.Body.setVelocity(this, { x: this.velocity.x * 1.07, y: this.velocity.y });
} }
} }
me.burstFire = function() { me.burstFire = function() {
@@ -5188,12 +5188,12 @@ const spawn = {
me.eventHorizon = 0; //set in mob loop me.eventHorizon = 0; //set in mob loop
me.frictionStatic = 0; me.frictionStatic = 0;
me.friction = 0; me.friction = 0;
me.frictionAir = 0.004; me.frictionAir = 0.005;
me.accelMag = 0.00008 + 0.00002 * simulation.accelScale me.accelMag = 0.00008 + 0.00002 * simulation.accelScale
spawn.shield(me, x, y, 1); spawn.shield(me, x, y, 1);
spawn.spawnOrbitals(me, radius + 50 + 100 * Math.random()) spawn.spawnOrbitals(me, radius + 50 + 100 * Math.random())
Matter.Body.setDensity(me, 0.003); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.0025); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.07 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) me.damageReduction = 0.07 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.startingDamageReduction = me.damageReduction me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false me.isInvulnerable = false
@@ -5217,9 +5217,13 @@ const spawn = {
this.attraction(); this.attraction();
this.damageReduction = this.startingDamageReduction this.damageReduction = this.startingDamageReduction
this.isInvulnerable = false this.isInvulnerable = false
if (!(simulation.cycle % 15)) requestAnimationFrame(() => { // if (!(simulation.cycle % 15)) requestAnimationFrame(() => {
simulation.timePlayerSkip(5) // simulation.timePlayerSkip(5)
simulation.loop(); //ending with a wipe and normal loop fixes some very minor graphical issues where things are draw in the wrong locations // // simulation.loop(); //ending with a wipe and normal loop fixes some very minor graphical issues where things are draw in the wrong locations
// }); //wrapping in animation frame prevents errors, probably
requestAnimationFrame(() => {
simulation.timePlayerSkip(1)
m.walk_cycle += m.flipLegs * m.Vx //makes the legs look like they are moving fast
}); //wrapping in animation frame prevents errors, probably }); //wrapping in animation frame prevents errors, probably
ctx.beginPath(); ctx.beginPath();

View File

@@ -868,7 +868,7 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.isStunField || tech.oneSuperBall || tech.isCloakStun || tech.isOrbitBotUpgrade || tech.isExplosionStun return tech.isStunField || tech.oneSuperBall || tech.isCloakStun || tech.isOrbitBotUpgrade || tech.isStun
}, },
requires: "a stun effect", requires: "a stun effect",
effect() { effect() {
@@ -1666,7 +1666,7 @@ const tech = {
}, },
{ {
name: "Pauli exclusion", name: "Pauli exclusion",
description: `after mob collisions<br>become <strong>invulnerable</strong> for <strong>+2.5</strong> seconds`, description: `after mob collisions<br>become <strong>invulnerable</strong> for <strong>+3</strong> seconds`,
maxCount: 9, maxCount: 9,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -1674,7 +1674,7 @@ const tech = {
allowed() { return true }, allowed() { return true },
requires: "", requires: "",
effect() { effect() {
tech.collisionImmuneCycles += 150; tech.collisionImmuneCycles += 180;
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage
}, },
remove() { remove() {
@@ -1683,7 +1683,7 @@ const tech = {
}, },
{ {
name: "spinstatistics theorem", name: "spinstatistics theorem",
description: `every <strong>7</strong> seconds<br>become <strong>invulnerable</strong> for <strong>1.75</strong> seconds`, description: `every <strong>7</strong> seconds<br>become <strong>invulnerable</strong> for <strong>+1.75</strong> seconds`,
maxCount: 3, maxCount: 3,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -1888,96 +1888,6 @@ const tech = {
tech.relayIce = 0 tech.relayIce = 0
} }
}, },
{
name: "freezer burn",
description: "mobs <strong class='color-s'>frozen</strong> while below <strong>33%</strong> durability <strong>die</strong>",
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1
},
requires: "a freeze effect",
effect() {
tech.isIceKill = true
},
remove() {
tech.isIceKill = false
}
},
{
name: "flash freeze",
description: "mobs <strong class='color-s'>frozen</strong> while above <strong>66%</strong> durability<br>have their durability reduced to <strong>66%</strong>",
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1
},
requires: "a freeze effect",
effect() {
tech.isIceMaxHealthLoss = true
},
remove() {
tech.isIceMaxHealthLoss = false
}
},
{
name: "crystallizer",
description: "after <strong class='color-s'>frozen</strong> mobs <strong>die</strong> they<br>shatter into <strong class='color-s'>ice IX</strong> crystals",
maxCount: 9,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return (tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1) && !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.nailsDeathMob
},
requires: "a localized freeze effect, no other mob death tech",
effect() {
tech.iceIXOnDeath++
},
remove() {
tech.iceIXOnDeath = 0
}
},
{
name: "thermoelectric effect",
description: "<strong>killing</strong> mobs with <strong class='color-s'>ice IX</strong><br>generates <strong>100</strong> <strong class='color-f'>energy</strong>",
maxCount: 9,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isIceField || tech.relayIce || tech.isNeedleIce || tech.blockingIce || tech.iceIXOnDeath || tech.isIceShot
},
requires: "ice IX",
effect() {
tech.iceEnergy++
},
remove() {
tech.iceEnergy = 0;
}
},
{
name: "superfluidity",
description: "<strong class='color-s'>freeze</strong> effects are applied<br>to a small area around the target",
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1 || tech.iceIXOnDeath || tech.isIceShot
},
requires: "a localized freeze effect",
effect() {
tech.isAoESlow = true
},
remove() {
tech.isAoESlow = false
}
},
{ {
name: "liquid cooling", name: "liquid cooling",
description: `after losing <strong class='color-h'>health</strong><br><strong class='color-s'>freeze</strong> all mobs for <strong>7</strong> seconds`, description: `after losing <strong class='color-h'>health</strong><br><strong class='color-s'>freeze</strong> all mobs for <strong>7</strong> seconds`,
@@ -2429,7 +2339,7 @@ const tech = {
}, },
{ {
name: "inductive coupling", name: "inductive coupling",
description: "if <strong>crouched</strong> <strong>+700%</strong> passive <strong class='color-f'>energy</strong> generation<br>if not <strong>crouched</strong> <strong class='color-f'>energy</strong> generation is disabled", description: "if <strong>crouched</strong> <strong>+600%</strong> passive <strong class='color-f'>energy</strong> generation<br>if not <strong>crouched</strong> <strong class='color-f'>energy</strong> generation is disabled",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -3245,7 +3155,7 @@ const tech = {
}, },
requires: "at least 4 research, not parthenogenesis", requires: "at least 4 research, not parthenogenesis",
effect() { effect() {
tech.isResearchBoss = true; //abiogenesis tech.isResearchBoss = true;
}, },
remove() { remove() {
tech.isResearchBoss = false; tech.isResearchBoss = false;
@@ -3891,7 +3801,7 @@ const tech = {
}, },
{ {
name: "caliber", name: "caliber",
description: `<strong>rivets</strong>, <strong>needles</strong>, <strong>super balls</strong>, and <strong>nails</strong><br>have <strong>+16%</strong> mass and physical <strong class='color-d'>damage</strong>`, description: `<strong>rivets</strong>, <strong>needles</strong>, <strong>super balls</strong>, and <strong>nails</strong><br>have <strong>+25%</strong> mass and physical <strong class='color-d'>damage</strong>`,
isGunTech: true, isGunTech: true,
maxCount: 9, maxCount: 9,
count: 0, count: 0,
@@ -3902,7 +3812,7 @@ const tech = {
}, },
requires: "nails, nail gun, rivets, shotgun", requires: "nails, nail gun, rivets, shotgun",
effect() { effect() {
tech.bulletSize += 0.16 tech.bulletSize += 0.25
}, },
remove() { remove() {
tech.bulletSize = 1; tech.bulletSize = 1;
@@ -3938,7 +3848,7 @@ const tech = {
{ {
name: "ice crystal nucleation", name: "ice crystal nucleation",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Nucleation' class="link">ice crystal nucleation</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Nucleation' class="link">ice crystal nucleation</a>`,
description: "the <strong>nail gun</strong> uses <strong class='color-f'>energy</strong> to condense<br>unlimited <strong class='color-s'>freezing</strong> <strong>ice shards</strong>", description: "<strong>nail gun</strong> uses <strong class='color-f'>energy</strong> to condense<br>unlimited <strong class='color-s'>freezing</strong> <strong>ice shards</strong>",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -4002,17 +3912,36 @@ const tech = {
} }
}, },
{ {
name: "supercritical fission", name: "stress concentration",
description: "<strong>nails</strong>, <strong>needles</strong>, and <strong>rivets</strong> can <strong class='color-e'>explode</strong><br>if they strike mobs near their <strong>center</strong>", description: "mobs below <strong>50%</strong> durability <strong>die</strong> after you shoot<br>them near their <strong>center</strong> with <strong>needles</strong> or <strong>rivets</strong>",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return (tech.isNailShot || tech.isNeedles || tech.isNailBotUpgrade || tech.haveGunCheck("nail gun") || tech.isRivets) && !tech.isIncendiary return (tech.isNeedles || tech.isRivets) && !tech.isNailCrit && !tech.isIncendiary
}, },
requires: "nail gun, needles, nails, rivets, not incendiary", requires: "needles, rivets, not incendiary, supercritical fission",
effect() {
tech.isCritKill = true
},
remove() {
tech.isCritKill = false
}
},
{
name: "supercritical fission",
description: "if bullets strike mobs near their <strong>center</strong><br>they can <strong class='color-e'>explode</strong> <em style = 'font-size:95%;'>(nails, needles, rivets)</em>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return (tech.isNailShot || tech.isNeedles || tech.isNailBotUpgrade || tech.haveGunCheck("nail gun") || tech.isRivets) && !tech.isIncendiary && !tech.isCritKill
},
requires: "nail gun, needles, nails, rivets, not incendiary, fire-control system",
effect() { effect() {
tech.isNailCrit = true tech.isNailCrit = true
}, },
@@ -4219,6 +4148,101 @@ const tech = {
tech.isIceShot = false; tech.isIceShot = false;
} }
}, },
{
name: "freezer burn",
description: "mobs <strong class='color-s'>frozen</strong> while below <strong>33%</strong> durability <strong>die</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1
},
requires: "a freeze effect",
effect() {
tech.isIceKill = true
},
remove() {
tech.isIceKill = false
}
},
{
name: "flash freeze",
description: "mobs <strong class='color-s'>frozen</strong> while above <strong>66%</strong> durability<br>have their durability reduced to <strong>66%</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1
},
requires: "a freeze effect",
effect() {
tech.isIceMaxHealthLoss = true
},
remove() {
tech.isIceMaxHealthLoss = false
}
},
{
name: "crystallizer",
description: "after <strong class='color-s'>frozen</strong> mobs <strong>die</strong> they<br>shatter into <strong class='color-s'>ice IX</strong> crystals",
isGunTech: true,
maxCount: 9,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return (tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1) && !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.nailsDeathMob
},
requires: "a localized freeze effect, no other mob death tech",
effect() {
tech.iceIXOnDeath++
},
remove() {
tech.iceIXOnDeath = 0
}
},
{
name: "thermoelectric effect",
description: "<strong>killing</strong> mobs with <strong class='color-s'>ice IX</strong><br>generates <strong>100</strong> <strong class='color-f'>energy</strong>",
isGunTech: true,
maxCount: 9,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isIceField || tech.relayIce || tech.isNeedleIce || tech.blockingIce || tech.iceIXOnDeath || tech.isIceShot
},
requires: "ice IX",
effect() {
tech.iceEnergy++
},
remove() {
tech.iceEnergy = 0;
}
},
{
name: "superfluidity",
description: "<strong class='color-s'>freeze</strong> effects are applied<br>to a small area around the target",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1 || tech.iceIXOnDeath || tech.isIceShot
},
requires: "a localized freeze effect",
effect() {
tech.isAoESlow = true
},
remove() {
tech.isAoESlow = false
}
},
{ {
name: "incendiary ammunition", name: "incendiary ammunition",
description: "<strong>shotgun</strong>, <strong>rivets</strong>, <strong>super balls</strong>, and <strong>drones</strong><br>are loaded with <strong class='color-e'>explosives</strong>", description: "<strong>shotgun</strong>, <strong>rivets</strong>, <strong>super balls</strong>, and <strong>drones</strong><br>are loaded with <strong class='color-e'>explosives</strong>",
@@ -4687,26 +4711,26 @@ const tech = {
}, },
{ {
name: "shock wave", name: "shock wave",
description: "<strong>mines</strong> and <strong class='color-e'>explosions</strong> <strong>stun</strong> for <strong>1-2</strong> seconds<br><strong>30%</strong> <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong>", description: "<strong>mines</strong> and <strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> <strong>stun</strong> for <strong>3-5</strong> seconds<br><strong class='color-e'>explosions</strong> <strong>stun</strong> for <strong>0.5</strong> seconds",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return tech.haveGunCheck("mine") || (!tech.isExplodeRadio && tech.hasExplosiveDamageCheck()) return tech.haveGunCheck("spores") || tech.haveGunCheck("mine") || (!tech.isExplodeRadio && tech.hasExplosiveDamageCheck())
}, },
requires: "an explosive damage source, not iridium-192", requires: "mine, spores, an explosive damage source, not iridium-192",
effect() { effect() {
tech.isExplosionStun = true; tech.isStun = true;
}, },
remove() { remove() {
tech.isExplosionStun = false; tech.isStun = false;
} }
}, },
{ {
name: "controlled explosion", name: "controlled explosion",
description: `use ${powerUps.orb.research(4)} to dynamically <strong>reduce</strong><br>all <strong class='color-e'>explosive</strong> radius to prevent <strong class='color-h'>health</strong> loss`, description: `use ${powerUps.orb.research(4)} to dynamically <strong>reduce</strong><br>all <strong class='color-e'>explosions</strong> to prevent <strong class='color-h'>health</strong> loss`,
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -5067,24 +5091,43 @@ const tech = {
tech.isSporeGrowth = false tech.isSporeGrowth = false
} }
}, },
// {
// name: "tinsellated flagella",
// link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Zoospore#Flagella_types' class="link">tinsellated flagella</a>`,
// description: "<strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> release <strong>+2</strong> <strong class='color-p' style='letter-spacing: 2px;'>spores</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> accelerate <strong>50% faster</strong>",
// isGunTech: true,
// maxCount: 1,
// count: 0,
// frequency: 2,
// frequencyDefault: 2,
// allowed() {
// return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField
// },
// requires: "spores",
// effect() {
// tech.isFastSpores = true
// },
// remove() {
// tech.isFastSpores = false
// }
// },
{ {
name: "tinsellated flagella", name: "flagella",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Zoospore#Flagella_types' class="link">tinsellated flagella</a>`, description: "<strong>+50%</strong> <strong class='color-p' style='letter-spacing: 2px;'>spores</strong> acceleration<br>if they can't find a target <strong class='color-p' style='letter-spacing: 2px;'>spores</strong> follow you",
description: "<strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> release <strong>+2</strong> <strong class='color-p' style='letter-spacing: 2px;'>spores</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> accelerate <strong>50% faster</strong>",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isSporeWorm
}, },
requires: "spores", requires: "spores",
effect() { effect() {
tech.isFastSpores = true tech.isSporeFollow = true //isSporeFollow
}, },
remove() { remove() {
tech.isFastSpores = false tech.isSporeFollow = false //isFastSpores
} }
}, },
{ {
@@ -5107,25 +5150,25 @@ const tech = {
tech.isSporeFreeze = false tech.isSporeFreeze = false
} }
}, },
{ // {
name: "diplochory", // name: "diplochory",
description: "if <strong class='color-p' style='letter-spacing: 2px;'>spores</strong> can't <strong>locate</strong> a viable host<br>they use you for <strong>dispersal</strong>", // description: "if <strong class='color-p' style='letter-spacing: 2px;'>spores</strong> can't <strong>locate</strong> a viable host<br>they use you for <strong>dispersal</strong>",
isGunTech: true, // isGunTech: true,
maxCount: 1, // maxCount: 1,
count: 0, // count: 0,
frequency: 2, // frequency: 2,
frequencyDefault: 2, // frequencyDefault: 2,
allowed() { // allowed() {
return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isSporeWorm // return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isSporeWorm
}, // },
requires: "spores", // requires: "spores",
effect() { // effect() {
tech.isSporeFollow = true // tech.isSporeFollow = true
}, // },
remove() { // remove() {
tech.isSporeFollow = false // tech.isSporeFollow = false
} // }
}, // },
{ {
name: "mutualism", name: "mutualism",
description: "<strong>+150%</strong> <strong class='color-p' style='letter-spacing: 2px;'>spore</strong> <strong class='color-d'>damage</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> borrow <strong>0.5</strong> <strong class='color-h'>health</strong> until they <strong>die</strong>", description: "<strong>+150%</strong> <strong class='color-p' style='letter-spacing: 2px;'>spore</strong> <strong class='color-d'>damage</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> borrow <strong>0.5</strong> <strong class='color-h'>health</strong> until they <strong>die</strong>",
@@ -7023,7 +7066,7 @@ const tech = {
}, },
{ {
name: "time crystals", name: "time crystals",
description: "<strong>+400%</strong> passive <strong class='color-f'>energy</strong> generation", description: "<strong>+300%</strong> passive <strong class='color-f'>energy</strong> generation",
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -8958,6 +9001,30 @@ const tech = {
}, },
remove() {} remove() {}
}, },
{
name: "reincarnation",
description: "kill all mobs and spawn new ones<br>(also spawn a few extra mobs for fun)",
maxCount: 3,
count: 0,
frequency: 0,
isNonRefundable: true,
isJunk: true,
allowed() { return true },
requires: "",
effect() {
spawn.setSpawnList();
spawn.setSpawnList();
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].alive && !mob[i].shield && !mob[i].isBadTarget) {
const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
spawn[pick](mob[i].position.x, mob[i].position.y);
if (Math.random() < 0.5) spawn[pick](mob[i].position.x, mob[i].position.y);
mob[i].death();
}
}
},
remove() {}
},
{ {
name: "expert system", name: "expert system",
description: "spawn a <strong class='color-m'>tech</strong> power up<br><strong>+64%</strong> <strong class='color-j'>JUNK</strong> to <strong class='color-m'>tech</strong> pool", description: "spawn a <strong class='color-m'>tech</strong> power up<br><strong>+64%</strong> <strong class='color-j'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
@@ -9902,7 +9969,6 @@ const tech = {
isBlockRadiation: null, isBlockRadiation: null,
isPiezo: null, isPiezo: null,
isFastDrones: null, isFastDrones: null,
isFastSpores: null,
oneSuperBall: null, oneSuperBall: null,
laserReflections: null, laserReflections: null,
laserDamage: null, laserDamage: null,
@@ -9934,7 +10000,7 @@ const tech = {
isSporeFollow: null, isSporeFollow: null,
isNailRadiation: null, isNailRadiation: null,
isEnergyHealth: null, isEnergyHealth: null,
isExplosionStun: null, isStun: null,
restDamage: null, restDamage: null,
isRPG: null, isRPG: null,
missileCount: null, missileCount: null,
@@ -10179,5 +10245,6 @@ const tech = {
isPetalsExplode: null, isPetalsExplode: null,
isDeathSkipTime: null, isDeathSkipTime: null,
isIceMaxHealthLoss: null, isIceMaxHealthLoss: null,
isIceKill: null isIceKill: null,
isCritKill: null
} }

View File

@@ -1,24 +1,63 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
nail gun tech: stress concentration - if a mob has below 50% durability after taking damage
from needles or rivets near the center of it's body it dies
caliber 16->25% nail, needle, rivet size/damage
combined tech: flagella - spores move +50% faster
spores follow you if they can't find a target
shock wave stun also applies to sporangium
no longer reduces explosion size
JUNK tech: reincarnation - kill all mobs and spawn new ones
(also spawn a few extra mobs for fun)
updated pause menu and fields descriptions to new wording style updated pause menu and fields descriptions to new wording style
bug fixes
*********************************************************** TODO ***************************************************** *********************************************************** TODO *****************************************************
Tech: florescence
Hitting a mob makes it emit lasers from its vertices
all laser but pulse?
should trigger a global cd so it can't occur more then once per cycle
tech spawn bots that last until you get hit
bots can check you health every cycle and see if it lower
it it's high update the health check value
JUNK?
after killing a mob go invulnerable for 1 second
critical hit with laser, harpoon, nails, needle, rivet
spawn 2 bots after exiting 1 level
or spawn 3 after 2 levels?
(randomize 2-5 bots)
replace all bot tech with this?
cloaking field
for 6 seconds after de-cloaking tell all active mobs that the player is in the wrong position?
how to code?
just delay setting the m.isCloak for a couple seconds
and also set all active bots to remember player in the de-cloaked stop
give laser gun _____ if you fire in an angle range
draw angle range as a slowly rotation circle arc around player
effect:
bonus damage
extra beams
extra reflections
scrap bots can't move? scrap bots can't move?
only works for nail, foam, laser only works for nail, foam, laser
might be tricky code? might be tricky code?
make a new bot type called scrap bot? make a new bot type called scrap bot?
nail gun needs a small damage buff
JUNK tech: Pacifism JUNK tech: Pacifism
You cannot attack mobs, mobs cannot attack you You cannot attack mobs, mobs cannot attack you
over write the mob.damage and player.damage methods over write the mob.damage and player.damage methods
JUNK tech: incubation: spawn something after 5 minutes
4 bots?
mob mechanic: beacon mob mechanic: beacon
periodically add locations to an array periodically add locations to an array
teleport back to a location in the array teleport back to a location in the array