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:
119
js/bullet.js
119
js/bullet.js
@@ -168,11 +168,9 @@ const b = {
|
||||
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) {
|
||||
const remove = tech.removeTech(i)
|
||||
// console.log(remove, tech.tech[i].count, tech.tech[i].name)
|
||||
gunTechCount += remove
|
||||
}
|
||||
}
|
||||
// console.log(gunTechCount)
|
||||
|
||||
//get a random gun tech for your gun
|
||||
for (let i = 0; i < gunTechCount; i++) {
|
||||
@@ -353,7 +351,7 @@ const b = {
|
||||
radius *= tech.explosiveRadius
|
||||
|
||||
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.isSmallExplosion) {
|
||||
// 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 (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
|
||||
if (tech.isExplosionStun) mobs.statusStun(mob[i], 60)
|
||||
if (tech.isStun) mobs.statusStun(mob[i], 30)
|
||||
mob[i].locatePlayer();
|
||||
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))
|
||||
m.energy -= 0.12
|
||||
// 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)));
|
||||
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
|
||||
@@ -502,8 +499,8 @@ const b = {
|
||||
mob[i].damage(dmg * damageScale * m.dmgScale);
|
||||
mob[i].locatePlayer();
|
||||
knock = Vector.mult(Vector.normalise(sub), -Math.sqrt(dmg * damageScale) * mob[i].mass * (mob[i].isBoss ? 0.003 : 0.01));
|
||||
if (tech.isExplosionStun) {
|
||||
mobs.statusStun(mob[i], 120)
|
||||
if (tech.isStun) {
|
||||
mobs.statusStun(mob[i], 30)
|
||||
} else if (!mob[i].isInvulnerable) {
|
||||
mob[i].force.x += knock.x;
|
||||
mob[i].force.y += knock.y;
|
||||
@@ -513,8 +510,8 @@ const b = {
|
||||
} else if (!mob[i].seePlayer.recall && dist < alertRange) {
|
||||
mob[i].locatePlayer();
|
||||
knock = Vector.mult(Vector.normalise(sub), -Math.sqrt(dmg * damageScale) * mob[i].mass * (mob[i].isBoss ? 0 : 0.006));
|
||||
if (tech.isExplosionStun) {
|
||||
mobs.statusStun(mob[i], 60)
|
||||
if (tech.isStun) {
|
||||
mobs.statusStun(mob[i], 30)
|
||||
} else if (!mob[i].isInvulnerable) {
|
||||
mob[i].force.x += knock.x;
|
||||
mob[i].force.y += knock.y;
|
||||
@@ -2463,7 +2460,7 @@ const b = {
|
||||
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) {
|
||||
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)
|
||||
@@ -2509,7 +2506,7 @@ const b = {
|
||||
Matter.Query.ray(map, 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
|
||||
if (this.angularSpeed < 0.5) this.torque += this.inertia * this.torqueMagnitude * 200 //spin
|
||||
this.endCycle = simulation.cycle + 360 + 120
|
||||
@@ -2644,7 +2641,7 @@ const b = {
|
||||
Matter.Query.ray(body, this.position, mob[i].position).length === 0 &&
|
||||
!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) {
|
||||
this.lookFrequency = 8 + Math.floor(3 * Math.random())
|
||||
this.endCycle = simulation.cycle + 1020
|
||||
@@ -2691,7 +2688,7 @@ const b = {
|
||||
// angle: Math.random() * 2 * Math.PI,
|
||||
friction: 0,
|
||||
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,
|
||||
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
|
||||
@@ -2809,7 +2806,7 @@ const b = {
|
||||
angle: Math.random() * 2 * Math.PI,
|
||||
friction: 0,
|
||||
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
|
||||
lookFrequency: 100 + Math.floor(117 * Math.random()),
|
||||
classType: "bullet",
|
||||
@@ -2901,8 +2898,17 @@ const b = {
|
||||
// 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 ANGLE = 2 * Math.PI * Math.random()
|
||||
@@ -2941,12 +2947,12 @@ const b = {
|
||||
minDmgSpeed: 0,
|
||||
lockedOn: null,
|
||||
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) {
|
||||
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() {},
|
||||
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) {
|
||||
dmg *= tech.bulletSize
|
||||
const me = bullet.length;
|
||||
@@ -3826,11 +3864,10 @@ const b = {
|
||||
bullet[me].dmg = tech.isNailRadiation ? 0 : dmg
|
||||
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.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) {
|
||||
if (tech.isNailCrit) {
|
||||
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() {};
|
||||
@@ -3861,9 +3898,12 @@ const b = {
|
||||
}
|
||||
}
|
||||
if (!immune) {
|
||||
if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) {
|
||||
b.explosion(this.position, 220 * tech.bulletSize + 50 * Math.random()); //makes bullet do explosive damage at end
|
||||
if (tech.isNailCrit) {
|
||||
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
|
||||
let dmg = this.dmg * tech.bulletSize * m.dmgScale
|
||||
if (tech.isNailRadiation) {
|
||||
@@ -3916,9 +3956,12 @@ const b = {
|
||||
}
|
||||
}
|
||||
if (!immune) {
|
||||
if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) {
|
||||
b.explosion(this.position, 220 * tech.bulletSize + 50 * Math.random()); //makes bullet do explosive damage at end
|
||||
if (tech.isNailCrit) {
|
||||
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
|
||||
let dmg = this.dmg * tech.bulletSize * m.dmgScale
|
||||
if (tech.isNailRadiation) {
|
||||
@@ -5060,9 +5103,11 @@ const b = {
|
||||
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
|
||||
}
|
||||
if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) {
|
||||
b.explosion(this.position, 300 + 30 * Math.random()); //makes bullet do explosive damage at end
|
||||
if (tech.isNailCrit) {
|
||||
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 (this.speed > 4 && tech.fragments) {
|
||||
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
|
||||
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) {
|
||||
b.explosion(this.position, 300 + 30 * Math.random()); //makes bullet do explosive damage at end
|
||||
if (tech.isNailCrit) {
|
||||
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 (this.speed > 4 && tech.fragments) {
|
||||
b.targetedNail(this.position, 1.25 * tech.fragments * tech.bulletSize)
|
||||
@@ -5203,14 +5251,16 @@ const b = {
|
||||
bullet[bullet.length - 1].beforeDmg = function(who) {
|
||||
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.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) {
|
||||
if (tech.isNailCrit) {
|
||||
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) {
|
||||
m.fireCDcycle = m.cycle + 60; // cool down
|
||||
} else {
|
||||
m.energy -= m.fieldRegen + 0.008
|
||||
m.energy -= 0.01
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -5289,12 +5339,13 @@ const b = {
|
||||
}
|
||||
}
|
||||
};
|
||||
if (tech.fragments) {
|
||||
bullet[me].beforeDmg = function() {
|
||||
bullet[me].beforeDmg = function(who) {
|
||||
if (this.speed > 4) {
|
||||
if (tech.fragments) {
|
||||
b.targetedNail(this.position, 6 * tech.fragments * tech.bulletSize)
|
||||
this.endCycle = 0 //triggers despawn
|
||||
}
|
||||
if (tech.isCritKill) b.crit(who, this)
|
||||
}
|
||||
}
|
||||
} else if (tech.isIncendiary) {
|
||||
@@ -6043,7 +6094,7 @@ const b = {
|
||||
bullet[me].maxRadius = 30;
|
||||
bullet[me].restitution = 0.3;
|
||||
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].beforeDmg = function() {};
|
||||
bullet[me].do = function() {
|
||||
@@ -6152,6 +6203,7 @@ const b = {
|
||||
} else {
|
||||
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) {
|
||||
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))
|
||||
// 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 (this.ammo > -1) {
|
||||
// this.ammo--
|
||||
|
||||
@@ -242,11 +242,13 @@ const build = {
|
||||
</svg><br>`
|
||||
text += `
|
||||
<br><strong class='color-d'>damage</strong>: ${((tech.damageFromTech())).toPrecision(3)} difficulty: ${((m.dmgScale)).toPrecision(3)}
|
||||
<br><strong class='color-defense'>defense</strong>: ${(1-m.harmReduction()).toPrecision(3)} difficulty: ${(simulation.dmgScale).toPrecision(3)}
|
||||
<br><strong class='color-defense'>defense</strong>: ${(1-m.harmReduction()).toPrecision(3)} 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 class='color-dup'>duplication</strong>: ${(tech.duplicationChance()*100).toFixed(0)}%
|
||||
${botText}
|
||||
<br><br><strong class='color-h'>health</strong>: (${(m.health*100).toFixed(0)} / ${(m.maxHealth*100).toFixed(0)}) <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} <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} <strong class='color-r'>research</strong>: ${powerUps.research.count}
|
||||
<br>
|
||||
|
||||
27
js/level.js
27
js/level.js
@@ -7,9 +7,9 @@ const level = {
|
||||
defaultZoom: 1400,
|
||||
onLevel: -1,
|
||||
levelsCleared: 0,
|
||||
// playableLevels: ["pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion"],
|
||||
//see level.populateLevels: (intro, ... , reservoir, reactor, ... , gauntlet, final) added later
|
||||
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"],
|
||||
trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon"],
|
||||
levels: [],
|
||||
@@ -20,12 +20,13 @@ const level = {
|
||||
// m.setField("time dilation")
|
||||
// b.giveGuns("nail gun")
|
||||
// b.giveGuns("mine")
|
||||
// tech.giveTech("laser-mines")
|
||||
// tech.giveTech("free-electron laser")
|
||||
// tech.giveTech("energy conservation")
|
||||
// tech.giveTech("6s half-life")
|
||||
// for (let i = 0; i < 10; i++) tech.giveTech("replication")
|
||||
// tech.giveTech("eternalism")
|
||||
// tech.giveTech("needle gun")
|
||||
// tech.giveTech("stress concentration")
|
||||
// for (let i = 0; i < 100; ++i) tech.giveTech("nail-bot")
|
||||
// tech.giveTech("rivet gun")
|
||||
// tech.giveTech("needle ice")
|
||||
// tech.giveTech("flash freeze")
|
||||
// tech.giveTech("superfluidity")
|
||||
// m.maxHealth = 100
|
||||
// m.health = m.maxHealth
|
||||
// for (let i = 0; i < 10; i++) tech.giveTech("tungsten carbide")
|
||||
@@ -36,12 +37,14 @@ const level = {
|
||||
// powerUps.research.changeRerolls(100000)
|
||||
// tech.tech[297].frequency = 100
|
||||
// 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
|
||||
// level.perplex();
|
||||
// spawn.cellBossCulture(1900, -500)
|
||||
// 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 ************************************************
|
||||
// powerUps.research.changeRerolls(3000)
|
||||
@@ -1327,10 +1330,10 @@ const level = {
|
||||
|
||||
if (this.height > 0 && Matter.Query.region([player], this).length) {
|
||||
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) {
|
||||
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 {
|
||||
m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1))
|
||||
}
|
||||
@@ -8849,7 +8852,7 @@ const level = {
|
||||
} else {
|
||||
tech.addJunkTechToPool(0.49)
|
||||
}
|
||||
// spawn.randomLevelBoss(x, y, ["historyBoss"]);
|
||||
spawn.randomLevelBoss(x, y, ["historyBoss"]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
29
js/mob.js
29
js/mob.js
@@ -59,9 +59,32 @@ const mobs = {
|
||||
}
|
||||
|
||||
function applySlow(whom) {
|
||||
if (!whom.shield && !whom.isShielded && who.alive) {
|
||||
if (tech.isIceMaxHealthLoss && who.health > 0.66 && who.damageReduction > 0) who.health = 0.66
|
||||
if (tech.isIceKill && who.health < 0.33 && who.damageReduction > 0) who.death();
|
||||
if (!whom.shield && !whom.isShielded && whom.alive) {
|
||||
if (tech.isIceMaxHealthLoss && whom.health > 0.65 && whom.damageReduction > 0) whom.health = 0.66
|
||||
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)
|
||||
let i = whom.status.length
|
||||
while (i--) {
|
||||
|
||||
@@ -858,7 +858,7 @@ const m = {
|
||||
ctx.fillStyle = m.fillColor;
|
||||
m.walk_cycle += m.flipLegs * m.Vx;
|
||||
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);
|
||||
m.calcLeg(Math.PI, -3);
|
||||
m.drawLeg("#4a4a4a");
|
||||
@@ -2622,7 +2622,7 @@ const m = {
|
||||
} else {
|
||||
m.fieldFire = true;
|
||||
m.isBodiesAsleep = false;
|
||||
m.drain = 0.0025
|
||||
m.drain = 0.002
|
||||
m.hold = function() {
|
||||
if (m.isHolding) {
|
||||
m.wakeCheck();
|
||||
|
||||
@@ -105,6 +105,7 @@ const simulation = {
|
||||
simulation.isTimeSkipping = true;
|
||||
for (let i = 0; i < cycles; i++) {
|
||||
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();
|
||||
Engine.update(engine, simulation.delta);
|
||||
// level.custom();
|
||||
|
||||
38
js/spawn.js
38
js/spawn.js
@@ -47,13 +47,13 @@ const spawn = {
|
||||
},
|
||||
randomMob(x, y, chance = 1) {
|
||||
if (spawn.spawnChance(chance) || chance === Infinity) {
|
||||
const pick = this.pickList[Math.floor(Math.random() * this.pickList.length)];
|
||||
this[pick](x, y);
|
||||
const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
||||
spawn[pick](x, y);
|
||||
}
|
||||
|
||||
if (tech.isMoreMobs || (tech.isDuplicateBoss && Math.random() < tech.duplicationChance())) {
|
||||
const pick = this.pickList[Math.floor(Math.random() * this.pickList.length)];
|
||||
this[pick](x, y);
|
||||
const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
||||
spawn[pick](x, y);
|
||||
}
|
||||
},
|
||||
randomSmallMob(x, y,
|
||||
@@ -62,14 +62,14 @@ const spawn = {
|
||||
chance = 1) {
|
||||
if (spawn.spawnChance(chance)) {
|
||||
for (let i = 0; i < num; ++i) {
|
||||
const pick = this.pickList[Math.floor(Math.random() * this.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);
|
||||
const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
||||
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())) {
|
||||
for (let i = 0; i < num; ++i) {
|
||||
const pick = this.pickList[Math.floor(Math.random() * this.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);
|
||||
const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
||||
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([]);
|
||||
}
|
||||
},
|
||||
sprayBoss(x, y, radius = 30, isSpawnBossPowerUp = true) {
|
||||
sprayBoss(x, y, radius = 35, isSpawnBossPowerUp = true) {
|
||||
mobs.spawn(x, y, 16, radius, "rgb(255,255,255)");
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
@@ -3587,7 +3587,7 @@ const spawn = {
|
||||
me.friction = 0;
|
||||
me.frictionAir = 0;
|
||||
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
|
||||
me.damageReduction = 0.09 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
me.startingDamageReduction = me.damageReduction
|
||||
@@ -3630,8 +3630,8 @@ const spawn = {
|
||||
if (this.speed < 0.01) {
|
||||
Matter.Body.setVelocity(this, Vector.mult(Vector.normalise(Vector.sub(player.position, this.position)), 0.1));
|
||||
} 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.x) < 9) Matter.Body.setVelocity(this, { x: this.velocity.x * 1.07, y: this.velocity.y });
|
||||
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) < 8) Matter.Body.setVelocity(this, { x: this.velocity.x * 1.07, y: this.velocity.y });
|
||||
}
|
||||
}
|
||||
me.burstFire = function() {
|
||||
@@ -5188,12 +5188,12 @@ const spawn = {
|
||||
me.eventHorizon = 0; //set in mob loop
|
||||
me.frictionStatic = 0;
|
||||
me.friction = 0;
|
||||
me.frictionAir = 0.004;
|
||||
me.frictionAir = 0.005;
|
||||
me.accelMag = 0.00008 + 0.00002 * simulation.accelScale
|
||||
spawn.shield(me, x, y, 1);
|
||||
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.startingDamageReduction = me.damageReduction
|
||||
me.isInvulnerable = false
|
||||
@@ -5217,9 +5217,13 @@ const spawn = {
|
||||
this.attraction();
|
||||
this.damageReduction = this.startingDamageReduction
|
||||
this.isInvulnerable = false
|
||||
if (!(simulation.cycle % 15)) requestAnimationFrame(() => {
|
||||
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
|
||||
// if (!(simulation.cycle % 15)) requestAnimationFrame(() => {
|
||||
// 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
|
||||
// }); //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
|
||||
|
||||
ctx.beginPath();
|
||||
|
||||
343
js/tech.js
343
js/tech.js
@@ -868,7 +868,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
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",
|
||||
effect() {
|
||||
@@ -1666,7 +1666,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
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,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -1674,7 +1674,7 @@ const tech = {
|
||||
allowed() { return true },
|
||||
requires: "",
|
||||
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
|
||||
},
|
||||
remove() {
|
||||
@@ -1683,7 +1683,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "spin–statistics 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,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -1888,96 +1888,6 @@ const tech = {
|
||||
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",
|
||||
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",
|
||||
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,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -3245,7 +3155,7 @@ const tech = {
|
||||
},
|
||||
requires: "at least 4 research, not parthenogenesis",
|
||||
effect() {
|
||||
tech.isResearchBoss = true; //abiogenesis
|
||||
tech.isResearchBoss = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isResearchBoss = false;
|
||||
@@ -3891,7 +3801,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
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,
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
@@ -3902,7 +3812,7 @@ const tech = {
|
||||
},
|
||||
requires: "nails, nail gun, rivets, shotgun",
|
||||
effect() {
|
||||
tech.bulletSize += 0.16
|
||||
tech.bulletSize += 0.25
|
||||
},
|
||||
remove() {
|
||||
tech.bulletSize = 1;
|
||||
@@ -3938,7 +3848,7 @@ const tech = {
|
||||
{
|
||||
name: "ice crystal nucleation",
|
||||
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,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -4002,17 +3912,36 @@ const tech = {
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "supercritical fission",
|
||||
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>",
|
||||
name: "stress concentration",
|
||||
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,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
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() {
|
||||
tech.isNailCrit = true
|
||||
},
|
||||
@@ -4219,6 +4148,101 @@ const tech = {
|
||||
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",
|
||||
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",
|
||||
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,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
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() {
|
||||
tech.isExplosionStun = true;
|
||||
tech.isStun = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isExplosionStun = false;
|
||||
tech.isStun = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
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,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -5067,24 +5091,43 @@ const tech = {
|
||||
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",
|
||||
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>",
|
||||
name: "flagella",
|
||||
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",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField
|
||||
return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isSporeWorm
|
||||
},
|
||||
requires: "spores",
|
||||
effect() {
|
||||
tech.isFastSpores = true
|
||||
tech.isSporeFollow = true //isSporeFollow
|
||||
},
|
||||
remove() {
|
||||
tech.isFastSpores = false
|
||||
tech.isSporeFollow = false //isFastSpores
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -5107,25 +5150,25 @@ const tech = {
|
||||
tech.isSporeFreeze = false
|
||||
}
|
||||
},
|
||||
{
|
||||
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>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isSporeWorm
|
||||
},
|
||||
requires: "spores",
|
||||
effect() {
|
||||
tech.isSporeFollow = true
|
||||
},
|
||||
remove() {
|
||||
tech.isSporeFollow = false
|
||||
}
|
||||
},
|
||||
// {
|
||||
// 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>",
|
||||
// isGunTech: true,
|
||||
// maxCount: 1,
|
||||
// count: 0,
|
||||
// frequency: 2,
|
||||
// frequencyDefault: 2,
|
||||
// allowed() {
|
||||
// return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isSporeWorm
|
||||
// },
|
||||
// requires: "spores",
|
||||
// effect() {
|
||||
// tech.isSporeFollow = true
|
||||
// },
|
||||
// remove() {
|
||||
// tech.isSporeFollow = false
|
||||
// }
|
||||
// },
|
||||
{
|
||||
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>",
|
||||
@@ -7023,7 +7066,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
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,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -8958,6 +9001,30 @@ const tech = {
|
||||
},
|
||||
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",
|
||||
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,
|
||||
isPiezo: null,
|
||||
isFastDrones: null,
|
||||
isFastSpores: null,
|
||||
oneSuperBall: null,
|
||||
laserReflections: null,
|
||||
laserDamage: null,
|
||||
@@ -9934,7 +10000,7 @@ const tech = {
|
||||
isSporeFollow: null,
|
||||
isNailRadiation: null,
|
||||
isEnergyHealth: null,
|
||||
isExplosionStun: null,
|
||||
isStun: null,
|
||||
restDamage: null,
|
||||
isRPG: null,
|
||||
missileCount: null,
|
||||
@@ -10179,5 +10245,6 @@ const tech = {
|
||||
isPetalsExplode: null,
|
||||
isDeathSkipTime: null,
|
||||
isIceMaxHealthLoss: null,
|
||||
isIceKill: null
|
||||
isIceKill: null,
|
||||
isCritKill: null
|
||||
}
|
||||
49
todo.txt
49
todo.txt
@@ -1,24 +1,63 @@
|
||||
******************************************************** 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
|
||||
|
||||
bug fixes
|
||||
|
||||
*********************************************************** 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?
|
||||
only works for nail, foam, laser
|
||||
might be tricky code?
|
||||
make a new bot type called scrap bot?
|
||||
|
||||
nail gun needs a small damage buff
|
||||
|
||||
JUNK tech: Pacifism
|
||||
You cannot attack mobs, mobs cannot attack you
|
||||
over write the mob.damage and player.damage methods
|
||||
|
||||
JUNK tech: incubation: spawn something after 5 minutes
|
||||
4 bots?
|
||||
|
||||
mob mechanic: beacon
|
||||
periodically add locations to an array
|
||||
teleport back to a location in the array
|
||||
|
||||
Reference in New Issue
Block a user