worm-shot, ice-shot, needle-shot, foam-shot
shotgun techs: (I haven't done enough testing so let me know if these different shotgun modes aren't balanced) worm shot ice-IX shot foam shot needle shot foam lasts much longer on shielded mobs overall foam damage is reduced about 8% attacks that drain energy don't work when the player is immune to harm slime, radiation fields, black holes energy regen that consumes something (ammo, blocks, power ups) now works when immune to harm but passive energy regen is still stopped while you are immune to harm pilot wave field can no longer hit intangible mobs with blocks it was too annoying that you can't use blocks to move around so I reverted it back
This commit is contained in:
256
js/bullet.js
256
js/bullet.js
@@ -329,7 +329,7 @@ const b = {
|
||||
if (Vector.magnitude(Vector.sub(where, player.position)) < radius) {
|
||||
const DRAIN = (tech.isExplosionHarm ? 0.5 : 0.25) * (tech.isRadioactiveResistance ? 0.25 : 1)
|
||||
// * (tech.isImmuneExplosion ? Math.min(1, Math.max(1 - m.energy * 0.7, 0)) : 1)
|
||||
m.energy -= DRAIN
|
||||
if (m.immuneCycle < m.cycle) m.energy -= DRAIN
|
||||
if (m.energy < 0) {
|
||||
m.energy = 0
|
||||
m.damage(0.03 * (tech.isRadioactiveResistance ? 0.25 : 1));
|
||||
@@ -1036,7 +1036,7 @@ const b = {
|
||||
if (Vector.magnitude(Vector.sub(player.position, this.position)) < this.damageRadius) {
|
||||
const DRAIN = tech.isRadioactiveResistance ? 0.0025 * 0.25 : 0.0025
|
||||
if (m.energy > DRAIN) {
|
||||
m.energy -= DRAIN
|
||||
if (m.immuneCycle < m.cycle) m.energy -= DRAIN
|
||||
} else {
|
||||
m.energy = 0;
|
||||
m.damage(tech.isRadioactiveResistance ? 0.00016 * 0.25 : 0.00016) //0.00015
|
||||
@@ -1861,7 +1861,7 @@ const b = {
|
||||
},
|
||||
onEnd() {
|
||||
if (tech.isMutualism && this.isMutualismActive && !tech.isEnergyHealth) {
|
||||
m.health += 0.005
|
||||
m.health += 0.005 + 0.005 * tech.isSporeWorm
|
||||
if (m.health > m.maxHealth) m.health = m.maxHealth;
|
||||
m.displayHealth();
|
||||
}
|
||||
@@ -1919,7 +1919,7 @@ const b = {
|
||||
});
|
||||
World.add(engine.world, bullet[bIndex]); //add bullet to world
|
||||
if (tech.isMutualism && m.health > 0.02) {
|
||||
m.health -= 0.005
|
||||
m.health -= 0.005 - 0.005 * tech.isSporeWorm
|
||||
m.displayHealth();
|
||||
bullet[bIndex].isMutualismActive = true
|
||||
}
|
||||
@@ -1957,7 +1957,7 @@ const b = {
|
||||
},
|
||||
onEnd() {
|
||||
if (tech.isMutualism && this.isMutualismActive && !tech.isEnergyHealth) {
|
||||
m.health += 0.005
|
||||
m.health += 0.005 + 0.005 * tech.isSporeWorm
|
||||
if (m.health > m.maxHealth) m.health = m.maxHealth;
|
||||
m.displayHealth();
|
||||
}
|
||||
@@ -2040,7 +2040,7 @@ const b = {
|
||||
World.add(engine.world, bullet[bIndex]); //add bullet to world
|
||||
|
||||
if (tech.isMutualism && m.health > 0.02) {
|
||||
m.health -= 0.005
|
||||
m.health -= 0.005 - 0.005 * tech.isSporeWorm
|
||||
m.displayHealth();
|
||||
bullet[bIndex].isMutualismActive = true
|
||||
}
|
||||
@@ -2048,17 +2048,18 @@ const b = {
|
||||
},
|
||||
iceIX(speed = 0, dir = m.angle + Math.PI * 2 * Math.random(), where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }) {
|
||||
const me = bullet.length;
|
||||
const THRUST = 0.004
|
||||
const THRUST = 0.0006
|
||||
const RADIUS = 18
|
||||
const SCALE = 1 - 0.08 / tech.isBulletsLastLonger
|
||||
bullet[me] = Bodies.polygon(where.x, where.y, 3, RADIUS, {
|
||||
angle: dir - Math.PI,
|
||||
inertia: Infinity,
|
||||
friction: 0,
|
||||
frictionAir: 0.10,
|
||||
restitution: 0.3,
|
||||
dmg: 0.42, //damage done in addition to the damage from momentum
|
||||
frictionAir: 0.023,
|
||||
restitution: 0.9,
|
||||
dmg: 0.5, //damage done in addition to the damage from momentum
|
||||
lookFrequency: 14 + Math.floor(8 * Math.random()),
|
||||
endCycle: simulation.cycle + 140 * tech.isBulletsLastLonger,
|
||||
endCycle: simulation.cycle + 150 * tech.isBulletsLastLonger + Math.floor(25 * Math.random()),
|
||||
classType: "bullet",
|
||||
collisionFilter: {
|
||||
category: cat.bullet,
|
||||
@@ -2071,13 +2072,8 @@ const b = {
|
||||
mobs.statusSlow(who, 180)
|
||||
this.endCycle = simulation.cycle
|
||||
// if (tech.isHeavyWater) mobs.statusDoT(who, 0.15, 300)
|
||||
if (m.immuneCycle < m.cycle && tech.iceEnergy && !who.shield && !who.isShielded && who.isDropPowerUp && who.alive && m.immuneCycle < m.cycle) {
|
||||
setTimeout(function() {
|
||||
if (!who.alive) {
|
||||
m.energy += tech.iceEnergy * 0.8
|
||||
// m.addHealth(tech.iceEnergy * 0.04)
|
||||
}
|
||||
}, 10);
|
||||
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);
|
||||
}
|
||||
},
|
||||
onEnd() {},
|
||||
@@ -2085,8 +2081,7 @@ const b = {
|
||||
// this.force.y += this.mass * 0.0002;
|
||||
//find mob targets
|
||||
if (!(simulation.cycle % this.lookFrequency)) {
|
||||
const scale = 1 - 0.08 / tech.isBulletsLastLonger //0.9 * tech.isBulletsLastLonger;
|
||||
Matter.Body.scale(this, scale, scale);
|
||||
Matter.Body.scale(this, SCALE, SCALE);
|
||||
this.lockedOn = null;
|
||||
let closeDist = Infinity;
|
||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||
@@ -2380,7 +2375,7 @@ const b = {
|
||||
if (Vector.magnitude(Vector.sub(player.position, this.position)) < this.radioRadius) {
|
||||
const DRAIN = tech.isRadioactiveResistance ? 0.0023 * 0.25 : 0.0023
|
||||
if (m.energy > DRAIN) {
|
||||
m.energy -= DRAIN
|
||||
if (m.immuneCycle < m.cycle) m.energy -= DRAIN
|
||||
} else {
|
||||
m.energy = 0;
|
||||
m.damage(tech.isRadioactiveResistance ? 0.00015 * 0.25 : 0.00015) //0.00015
|
||||
@@ -2543,14 +2538,11 @@ const b = {
|
||||
// radius *= Math.sqrt(tech.bulletSize)
|
||||
const me = bullet.length;
|
||||
bullet[me] = Bodies.polygon(position.x, position.y, 20, radius, {
|
||||
// angle: 0,
|
||||
density: 0.000001, // 0.001 is normal density
|
||||
inertia: Infinity,
|
||||
frictionAir: 0.003,
|
||||
// friction: 0.2,
|
||||
// restitution: 0.2,
|
||||
dmg: 0, //damage on impact
|
||||
damage: (tech.isFastFoam ? 0.048 : 0.012) * (tech.isFoamTeleport ? 1.66 : 1), //damage done over time
|
||||
damage: (tech.isFastFoam ? 0.044 : 0.011) * (tech.isFoamTeleport ? 1.66 : 1), //damage done over time
|
||||
scale: 1 - 0.006 / tech.isBulletsLastLonger * (tech.isFastFoam ? 1.6 : 1),
|
||||
classType: "bullet",
|
||||
collisionFilter: {
|
||||
@@ -2610,9 +2602,6 @@ const b = {
|
||||
this.radius *= this.scale;
|
||||
if (this.radius < 8) this.endCycle = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (this.target && this.target.alive) { //if stuck to a target
|
||||
const rotate = Vector.rotate(this.targetRelativePosition, this.target.angle) //add in the mob's new angle to the relative position vector
|
||||
if (this.target.isVerticesChange) {
|
||||
@@ -2622,12 +2611,10 @@ const b = {
|
||||
}
|
||||
Matter.Body.setVelocity(this.target, Vector.mult(this.target.velocity, 0.9))
|
||||
Matter.Body.setAngularVelocity(this.target, this.target.angularVelocity * 0.9);
|
||||
|
||||
// Matter.Body.setAngularVelocity(this.target, this.target.angularVelocity * 0.9)
|
||||
if (this.target.isShielded) {
|
||||
this.target.damage(b.dmgScale * this.damage, true); //shield damage bypass
|
||||
//shrink if mob is shielded
|
||||
const SCALE = 1 - 0.01 / tech.isBulletsLastLonger
|
||||
const SCALE = 1 - 0.004 / tech.isBulletsLastLonger //shrink if mob is shielded
|
||||
Matter.Body.scale(this, SCALE, SCALE);
|
||||
this.radius *= SCALE;
|
||||
} else {
|
||||
@@ -2641,9 +2628,7 @@ const b = {
|
||||
let targets = []
|
||||
for (let i = 0, len = mob.length; i < len; i++) {
|
||||
const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position));
|
||||
if (dist < 1000000) {
|
||||
targets.push(mob[i])
|
||||
}
|
||||
if (dist < 1000000) targets.push(mob[i])
|
||||
}
|
||||
const radius = Math.min(this.radius * 0.5, 10)
|
||||
const len = bullet.length < 100 ? 2 : 1
|
||||
@@ -2682,7 +2667,6 @@ const b = {
|
||||
this.radius *= SCALE;
|
||||
} else {
|
||||
this.force.y += this.mass * tech.foamGravity; //gravity
|
||||
|
||||
if (tech.isFoamAttract) {
|
||||
for (let i = 0, len = mob.length; i < len; i++) {
|
||||
if (!mob[i].isBadTarget && Vector.magnitude(Vector.sub(mob[i].position, this.position)) < 375 && mob[i].alive && Matter.Query.ray(map, this.position, mob[i].position).length === 0) {
|
||||
@@ -2768,6 +2752,71 @@ const b = {
|
||||
};
|
||||
bullet[me].do = function() {};
|
||||
},
|
||||
needle(angle = m.angle) {
|
||||
const me = bullet.length;
|
||||
bullet[me] = Bodies.rectangle(m.pos.x + 40 * Math.cos(m.angle), m.pos.y + 40 * Math.sin(m.angle), 75, 0.75, b.fireAttributes(angle));
|
||||
bullet[me].collisionFilter.mask = tech.isNeedleShieldPierce ? cat.body : cat.body | cat.mobShield
|
||||
Matter.Body.setDensity(bullet[me], 0.00001); //0.001 is normal
|
||||
bullet[me].endCycle = simulation.cycle + 180;
|
||||
bullet[me].immuneList = []
|
||||
bullet[me].do = function() {
|
||||
const whom = Matter.Query.collides(this, mob)
|
||||
if (whom.length && this.speed > 20) { //if touching a mob
|
||||
for (let i = 0, len = whom.length; i < len; i++) {
|
||||
who = whom[i].bodyA
|
||||
if (who && who.mob) {
|
||||
let immune = false
|
||||
for (let i = 0; i < this.immuneList.length; i++) { //check if this needle has hit this mob already
|
||||
if (this.immuneList[i] === who.id) {
|
||||
immune = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!immune) {
|
||||
if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.975) {
|
||||
b.explosion(this.position, 220 + 50 * Math.random()); //makes bullet do explosive damage at end
|
||||
}
|
||||
this.immuneList.push(who.id) //remember that this needle has hit this mob once already
|
||||
who.foundPlayer();
|
||||
if (tech.isNailRadiation) {
|
||||
mobs.statusDoT(who, tech.isFastRadiation ? 12 : 3, tech.isSlowRadiation ? 240 : (tech.isFastRadiation ? 30 : 120)) // one tick every 30 cycles
|
||||
} else {
|
||||
let dmg = b.dmgScale * 5.5
|
||||
if (tech.isCrit && who.isStunned) dmg *= 4
|
||||
who.damage(dmg, tech.isNeedleShieldPierce);
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: this.position.x,
|
||||
y: this.position.y,
|
||||
radius: Math.log(2 * dmg + 1.1) * 40,
|
||||
color: simulation.playerDmgColor,
|
||||
time: simulation.drawTime
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (Matter.Query.collides(this, map).length) { //stick in walls
|
||||
this.collisionFilter.mask = 0;
|
||||
Matter.Body.setAngularVelocity(this, 0)
|
||||
Matter.Body.setVelocity(this, {
|
||||
x: 0,
|
||||
y: 0
|
||||
});
|
||||
this.do = function() {
|
||||
if (!Matter.Query.collides(this, map).length) this.force.y += this.mass * 0.001;
|
||||
}
|
||||
} else if (this.speed < 30) {
|
||||
this.force.y += this.mass * 0.001; //no gravity until it slows down to improve aiming
|
||||
}
|
||||
};
|
||||
const SPEED = 90
|
||||
Matter.Body.setVelocity(bullet[me], {
|
||||
x: m.Vx / 2 + SPEED * Math.cos(angle),
|
||||
y: m.Vy / 2 + SPEED * Math.sin(angle)
|
||||
});
|
||||
// Matter.Body.setDensity(bullet[me], 0.00001);
|
||||
World.add(engine.world, bullet[me]); //add bullet to world
|
||||
},
|
||||
// **************************************************************************************************
|
||||
// **************************************************************************************************
|
||||
// ******************************** Bots *********************************************
|
||||
@@ -3629,91 +3678,19 @@ const b = {
|
||||
this.baseFire(m.angle + (Math.random() - 0.5) * (Math.random() - 0.5) * (m.crouch ? 1.35 : 3.2) / CD)
|
||||
},
|
||||
fireNeedles() {
|
||||
function makeNeedle(angle = m.angle) {
|
||||
const me = bullet.length;
|
||||
bullet[me] = Bodies.rectangle(m.pos.x + 40 * Math.cos(m.angle), m.pos.y + 40 * Math.sin(m.angle), 75, 0.75, b.fireAttributes(angle));
|
||||
bullet[me].collisionFilter.mask = tech.isNeedleShieldPierce ? cat.body : cat.body | cat.mobShield
|
||||
Matter.Body.setDensity(bullet[me], 0.00001); //0.001 is normal
|
||||
bullet[me].endCycle = simulation.cycle + 180;
|
||||
bullet[me].immuneList = []
|
||||
bullet[me].do = function() {
|
||||
const whom = Matter.Query.collides(this, mob)
|
||||
if (whom.length && this.speed > 20) { //if touching a mob
|
||||
for (let i = 0, len = whom.length; i < len; i++) {
|
||||
who = whom[i].bodyA
|
||||
if (who && who.mob) {
|
||||
let immune = false
|
||||
for (let i = 0; i < this.immuneList.length; i++) { //check if this needle has hit this mob already
|
||||
if (this.immuneList[i] === who.id) {
|
||||
immune = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!immune) {
|
||||
if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.975) {
|
||||
b.explosion(this.position, 220 + 50 * Math.random()); //makes bullet do explosive damage at end
|
||||
}
|
||||
this.immuneList.push(who.id) //remember that this needle has hit this mob once already
|
||||
who.foundPlayer();
|
||||
if (tech.isNailRadiation) {
|
||||
mobs.statusDoT(who, tech.isFastRadiation ? 12 : 3, tech.isSlowRadiation ? 240 : (tech.isFastRadiation ? 30 : 120)) // one tick every 30 cycles
|
||||
} else {
|
||||
let dmg = b.dmgScale * 5.5
|
||||
if (tech.isCrit && who.isStunned) dmg *= 4
|
||||
who.damage(dmg, tech.isNeedleShieldPierce);
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: this.position.x,
|
||||
y: this.position.y,
|
||||
radius: Math.log(2 * dmg + 1.1) * 40,
|
||||
color: simulation.playerDmgColor,
|
||||
time: simulation.drawTime
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (Matter.Query.collides(this, map).length) { //stick in walls
|
||||
this.collisionFilter.mask = 0;
|
||||
Matter.Body.setAngularVelocity(this, 0)
|
||||
Matter.Body.setVelocity(this, {
|
||||
x: 0,
|
||||
y: 0
|
||||
});
|
||||
this.do = function() {
|
||||
if (!Matter.Query.collides(this, map).length) this.force.y += this.mass * 0.001;
|
||||
}
|
||||
} else if (this.speed < 30) {
|
||||
this.force.y += this.mass * 0.001; //no gravity until it slows down to improve aiming
|
||||
}
|
||||
};
|
||||
const SPEED = 90
|
||||
Matter.Body.setVelocity(bullet[me], {
|
||||
x: m.Vx / 2 + SPEED * Math.cos(angle),
|
||||
y: m.Vy / 2 + SPEED * Math.sin(angle)
|
||||
});
|
||||
// Matter.Body.setDensity(bullet[me], 0.00001);
|
||||
World.add(engine.world, bullet[me]); //add bullet to world
|
||||
}
|
||||
|
||||
if (m.crouch) {
|
||||
m.fireCDcycle = m.cycle + 45 * b.fireCDscale; // cool down
|
||||
makeNeedle()
|
||||
b.needle()
|
||||
for (let i = 1; i < 4; i++) { //4 total needles
|
||||
setTimeout(() => { if (!simulation.paused) makeNeedle() }, 60 * i);
|
||||
setTimeout(() => { if (!simulation.paused) b.needle() }, 60 * i);
|
||||
}
|
||||
} else {
|
||||
m.fireCDcycle = m.cycle + 25 * b.fireCDscale; // cool down
|
||||
makeNeedle()
|
||||
b.needle()
|
||||
for (let i = 1; i < 3; i++) { //3 total needles
|
||||
setTimeout(() => { if (!simulation.paused) makeNeedle() }, 60 * i);
|
||||
setTimeout(() => { if (!simulation.paused) b.needle() }, 60 * i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// const spread = (m.crouch ? 0.013 : 0.06)
|
||||
// makeNeedle(m.angle + spread)
|
||||
// makeNeedle()
|
||||
// makeNeedle(m.angle - spread)
|
||||
},
|
||||
fireRivets() {
|
||||
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 25 : 17) * b.fireCDscale); // cool down
|
||||
@@ -3806,11 +3783,11 @@ const b = {
|
||||
let knock, spread
|
||||
if (m.crouch) {
|
||||
spread = 0.65
|
||||
m.fireCDcycle = m.cycle + Math.floor(55 * b.fireCDscale); // cool down
|
||||
m.fireCDcycle = m.cycle + Math.floor(55 * b.fireCDscale) // cool down
|
||||
if (tech.isShotgunImmune && m.immuneCycle < m.cycle + Math.floor(58 * b.fireCDscale)) m.immuneCycle = m.cycle + Math.floor(58 * b.fireCDscale); //player is immune to damage for 30 cycles
|
||||
knock = 0.01
|
||||
} else {
|
||||
m.fireCDcycle = m.cycle + Math.floor(45 * b.fireCDscale); // cool down
|
||||
m.fireCDcycle = m.cycle + Math.floor(45 * b.fireCDscale) // cool down
|
||||
if (tech.isShotgunImmune && m.immuneCycle < m.cycle + Math.floor(47 * b.fireCDscale)) m.immuneCycle = m.cycle + Math.floor(47 * b.fireCDscale); //player is immune to damage for 30 cycles
|
||||
spread = 1.3
|
||||
knock = 0.1
|
||||
@@ -3900,7 +3877,7 @@ const b = {
|
||||
y: speed * Math.sin(dirOff)
|
||||
});
|
||||
bullet[me].onEnd = function() {
|
||||
b.explosion(this.position, 150 * (tech.isShotgunReversed ? 1.6 : 1) + (Math.random() - 0.5) * 40); //makes bullet do explosive damage at end
|
||||
b.explosion(this.position, 160 * (tech.isShotgunReversed ? 1.6 : 1) + (Math.random() - 0.5) * 40); //makes bullet do explosive damage at end
|
||||
}
|
||||
bullet[me].beforeDmg = function() {
|
||||
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
|
||||
@@ -3910,7 +3887,7 @@ const b = {
|
||||
}
|
||||
} else if (tech.isNailShot) {
|
||||
spread *= 0.65
|
||||
const dmg = 1.4 * (tech.isShotgunReversed ? 1.6 : 1)
|
||||
const dmg = 2 * (tech.isShotgunReversed ? 1.6 : 1)
|
||||
if (m.crouch) {
|
||||
for (let i = 0; i < 17; i++) {
|
||||
speed = 38 + 15 * Math.random()
|
||||
@@ -3938,6 +3915,49 @@ const b = {
|
||||
}, dmg)
|
||||
}
|
||||
}
|
||||
} else if (tech.isWormShot) {
|
||||
const unit = {
|
||||
x: Math.cos(m.angle),
|
||||
y: Math.sin(m.angle)
|
||||
}
|
||||
const where = {
|
||||
x: m.pos.x + 35 * unit.x,
|
||||
y: m.pos.y + 35 * unit.y
|
||||
}
|
||||
for (let i = 0, len = 3 * (tech.isShotgunReversed ? 1.6 : 1) + Math.random(); i < len; i++) {
|
||||
b.worm(where)
|
||||
const SPEED = 14 + 6 * Math.random() + 20 * m.crouch;
|
||||
Matter.Body.setVelocity(bullet[bullet.length - 1], {
|
||||
x: SPEED * unit.x,
|
||||
y: SPEED * unit.y
|
||||
});
|
||||
}
|
||||
} else if (tech.isIceShot) {
|
||||
const spread = (m.crouch ? 0.6 : 1.6)
|
||||
for (let i = 0, len = 16 * (tech.isShotgunReversed ? 1.6 : 1); i < len; i++) {
|
||||
// iceIX(speed = 0, dir = m.angle + Math.PI * 2 * Math.random(), where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }) {
|
||||
b.iceIX(14 + 30 * Math.random(), m.angle + spread * (Math.random() - 0.5))
|
||||
}
|
||||
} else if (tech.isFoamShot) {
|
||||
const spread = (m.crouch ? 0.35 : 0.7)
|
||||
const where = {
|
||||
x: m.pos.x + 25 * Math.cos(m.angle),
|
||||
y: m.pos.y + 25 * Math.sin(m.angle)
|
||||
}
|
||||
const number = 14 * (tech.isShotgunReversed ? 1.6 : 1)
|
||||
for (let i = 0; i < number; i++) {
|
||||
const SPEED = 25 + 12 * Math.random();
|
||||
const angle = m.angle + spread * (Math.random() - 0.5)
|
||||
b.foam(where, { x: SPEED * Math.cos(angle), y: SPEED * Math.sin(angle) }, 5 + 8 * Math.random())
|
||||
}
|
||||
} else if (tech.isNeedleShot) {
|
||||
const number = 12 * (tech.isShotgunReversed ? 1.6 : 1)
|
||||
const spread = (m.crouch ? 0.04 : 0.08)
|
||||
let angle = m.angle - (number - 1) * spread * 0.5
|
||||
for (let i = 0; i < number; i++) {
|
||||
b.needle(angle)
|
||||
angle += spread
|
||||
}
|
||||
} else {
|
||||
const side = 22
|
||||
for (let i = 0; i < 17; i++) {
|
||||
@@ -4843,7 +4863,7 @@ const b = {
|
||||
|
||||
if (tech.isCapacitor) {
|
||||
if ((m.energy > 0.16 || tech.isRailEnergyGain)) { //&& m.immuneCycle < m.cycle
|
||||
if (m.immuneCycle < m.cycle) m.energy += 0.16 * (tech.isRailEnergyGain ? 6 : -1)
|
||||
m.energy += 0.16 * (tech.isRailEnergyGain ? 4.5 : -1)
|
||||
m.fireCDcycle = m.cycle + Math.floor(30 * b.fireCDscale);
|
||||
const me = bullet.length;
|
||||
bullet[me] = Bodies.rectangle(m.pos.x + 50 * Math.cos(m.angle), m.pos.y + 50 * Math.sin(m.angle), 60, 14, {
|
||||
@@ -4970,7 +4990,7 @@ const b = {
|
||||
bullet[me].charge = 0;
|
||||
bullet[me].do = function() {
|
||||
if (m.energy < 0.005 && !tech.isRailEnergyGain) {
|
||||
if (m.immuneCycle < m.cycle) m.energy += 0.05 + this.charge * 0.3
|
||||
m.energy += 0.05 + this.charge * 0.2
|
||||
m.fireCDcycle = m.cycle + 120; // cool down if out of energy
|
||||
this.endCycle = 0;
|
||||
return
|
||||
@@ -5019,7 +5039,7 @@ const b = {
|
||||
let smoothRate = 0.98 * (m.crouch ? 0.99 : 1) * (0.98 + 0.02 * b.fireCDscale) //small b.fireCDscale = faster shots, b.fireCDscale=1 = normal shot, big b.fireCDscale = slower chot
|
||||
this.charge = this.charge * smoothRate + 1 * (1 - smoothRate)
|
||||
if (tech.isRailEnergyGain) {
|
||||
if (m.immuneCycle < m.cycle) m.energy += (this.charge - previousCharge) * 2 //energy drain is proportional to charge gained, but doesn't stop normal m.fieldRegen
|
||||
m.energy += (this.charge - previousCharge) * 1.5 //energy drain is proportional to charge gained, but doesn't stop normal m.fieldRegen
|
||||
} else {
|
||||
m.energy -= (this.charge - previousCharge) * 0.33 //energy drain is proportional to charge gained, but doesn't stop normal m.fieldRegen
|
||||
}
|
||||
|
||||
35
js/level.js
35
js/level.js
@@ -12,10 +12,15 @@ const level = {
|
||||
start() {
|
||||
if (level.levelsCleared === 0) { //this code only runs on the first level
|
||||
// simulation.enableConstructMode() //used to build maps in testing mode
|
||||
// level.difficultyIncrease(60) //30 is near max on hard //60 is near max on why
|
||||
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
|
||||
// simulation.isHorizontalFlipped = true
|
||||
// m.setField("wormhole")
|
||||
// b.giveGuns("spores")
|
||||
// b.giveGuns("shotgun")
|
||||
// b.giveGuns("foam")
|
||||
// tech.isNeedleShot = true
|
||||
// tech.isIceShot = true
|
||||
// tech.isFoamShot = true
|
||||
// tech.isWormShot = true
|
||||
// tech.giveTech("CPT reversal")
|
||||
// tech.giveTech("causality bombs")
|
||||
// b.giveGuns("wave beam")
|
||||
@@ -966,12 +971,14 @@ const level = {
|
||||
ctx.fillRect(this.min.x, this.min.y + offset, this.width, this.height - offset)
|
||||
|
||||
if (this.height > 0 && Matter.Query.region([player], this).length) {
|
||||
const DRAIN = 0.002 * (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
|
||||
} else {
|
||||
m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1))
|
||||
if (m.immuneCycle < m.cycle) {
|
||||
const DRAIN = 0.002 * (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
|
||||
} else {
|
||||
m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1))
|
||||
}
|
||||
}
|
||||
//float
|
||||
if (player.velocity.y > 5) player.force.y -= 0.95 * player.mass * simulation.g
|
||||
@@ -1621,8 +1628,10 @@ const level = {
|
||||
ctx.lineWidth = 2;
|
||||
if (Vector.magnitudeSquared(Vector.sub(m.pos, powerUp1.position)) < 90000) { //zone radius is 300
|
||||
//damage player and drain energy
|
||||
if (m.immuneCycle < m.cycle) m.damage(0.01);
|
||||
if (m.energy > 0.1) m.energy -= 0.02
|
||||
if (m.immuneCycle < m.cycle) {
|
||||
m.damage(0.01);
|
||||
if (m.energy > 0.1) m.energy -= 0.02
|
||||
}
|
||||
//draw electricity going towards player
|
||||
const unit = Vector.normalise(Vector.sub(m.pos, powerUp1.position))
|
||||
let xElec = powerUp1.position.x + 40 * unit.x;
|
||||
@@ -2256,10 +2265,10 @@ const level = {
|
||||
spawn.mapRect(6700, -1800, 800, 2600); //right wall
|
||||
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
|
||||
|
||||
// spawn.starter(1900, -500, 200) //big boy
|
||||
spawn.growBossCulture(1900, -500)
|
||||
spawn.starter(1900, -500, 200) //big boy
|
||||
// spawn.growBossCulture(1900, -500)
|
||||
|
||||
// spawn.pulsarBoss(1900, -500)
|
||||
// spawn.snakeBoss(1900, -500)
|
||||
// spawn.shieldingBoss(1900, -500)
|
||||
// spawn.grenadierBoss(1900, -500)
|
||||
|
||||
|
||||
@@ -417,8 +417,10 @@ const mobs = {
|
||||
ctx.setLineDash([125 * Math.random(), 125 * Math.random()]);
|
||||
// ctx.lineDashOffset = 6*(simulation.cycle % 215);
|
||||
if (this.distanceToPlayer() < this.laserRange) {
|
||||
if (m.immuneCycle < m.cycle) m.damage(0.0003 * simulation.dmgScale);
|
||||
if (m.energy > 0.1) m.energy -= 0.003
|
||||
if (m.immuneCycle < m.cycle) {
|
||||
m.damage(0.0003 * simulation.dmgScale);
|
||||
if (m.energy > 0.1) m.energy -= 0.003
|
||||
}
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.position.x, this.position.y);
|
||||
ctx.lineTo(m.pos.x, m.pos.y);
|
||||
|
||||
@@ -635,7 +635,7 @@ const m = {
|
||||
}
|
||||
|
||||
if (tech.isEnergyHealth) {
|
||||
m.energy -= dmg * 1.15;
|
||||
m.energy -= dmg * 1.1;
|
||||
if (m.energy < 0 || isNaN(m.energy)) { //taking deadly damage
|
||||
if (tech.isDeathAvoid && powerUps.research.count && !tech.isDeathAvoidedThisLevel) {
|
||||
tech.isDeathAvoidedThisLevel = true
|
||||
@@ -2443,7 +2443,9 @@ const m = {
|
||||
const unit = Vector.mult(Vector.normalise(sub), body[i].mass * tech.pilotForce * Vector.magnitude(sub))
|
||||
body[i].force.x += unit.x
|
||||
body[i].force.y += unit.y - body[i].mass * simulation.g //remove gravity effects
|
||||
if (body[i].collisionFilter.category !== cat.bullet) body[i].collisionFilter.category = cat.bullet;
|
||||
// if (body[i].collisionFilter.category !== cat.bullet) {
|
||||
// body[i].collisionFilter.category = cat.bullet;
|
||||
// }
|
||||
} else {
|
||||
m.fieldCDcycle = m.cycle + 120;
|
||||
m.fieldOn = false
|
||||
@@ -2602,7 +2604,7 @@ const m = {
|
||||
Matter.World.remove(engine.world, body[i]);
|
||||
body.splice(i, 1);
|
||||
m.fieldRange *= 0.8
|
||||
if (tech.isWormholeEnergy && m.immuneCycle < m.cycle) m.energy += 0.63
|
||||
if (tech.isWormholeEnergy) m.energy += 0.63
|
||||
if (tech.isWormSpores) { //pandimensionalspermia
|
||||
for (let i = 0, len = Math.ceil(3 * (tech.isSporeWorm ? 0.5 : 1) * Math.random()); i < len; i++) {
|
||||
if (tech.isSporeWorm) {
|
||||
|
||||
@@ -676,7 +676,7 @@ const powerUps = {
|
||||
onPickUp(who) {
|
||||
powerUps.research.currentRerollCount = 0
|
||||
if (tech.isTechDamage && who.name === "tech") m.damage(0.11)
|
||||
if (tech.isMassEnergy && m.immuneCycle < m.cycle) m.energy += 2;
|
||||
if (tech.isMassEnergy) m.energy += 2;
|
||||
if (tech.isMineDrop) {
|
||||
if (tech.isLaserMine) {
|
||||
b.laserMine(who.position)
|
||||
|
||||
@@ -696,7 +696,7 @@ const simulation = {
|
||||
if (tech.isMutualism && !tech.isEnergyHealth) {
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].isMutualismActive) {
|
||||
m.health += 0.005
|
||||
m.health += 0.005 + 0.005 * tech.isSporeWorm
|
||||
if (m.health > m.maxHealth) m.health = m.maxHealth;
|
||||
m.displayHealth();
|
||||
}
|
||||
|
||||
47
js/spawn.js
47
js/spawn.js
@@ -188,7 +188,7 @@ const spawn = {
|
||||
if (m.immuneCycle < m.cycle && Vector.magnitude(Vector.sub(player.position, this.position)) < this.radius) {
|
||||
const DRAIN = tech.isRadioactiveResistance ? 0.07 * 0.25 : 0.07
|
||||
if (m.energy > DRAIN) {
|
||||
m.energy -= DRAIN
|
||||
if (m.immuneCycle < m.cycle) m.energy -= DRAIN
|
||||
} else {
|
||||
m.energy = 0;
|
||||
m.damage((tech.isRadioactiveResistance ? 0.007 * 0.25 : 0.007) * simulation.dmgScale)
|
||||
@@ -504,9 +504,9 @@ const spawn = {
|
||||
ctx.fill();
|
||||
//when player is inside event horizon
|
||||
if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) {
|
||||
if (m.energy > 0) m.energy -= 0.01
|
||||
if (m.energy < 0.15 && m.immuneCycle < m.cycle) {
|
||||
m.damage(0.0004 * simulation.dmgScale);
|
||||
if (m.immuneCycle < m.cycle) {
|
||||
if (m.energy > 0) m.energy -= 0.01
|
||||
if (m.energy < 0.15 && m.immuneCycle < m.cycle) m.damage(0.0004 * simulation.dmgScale);
|
||||
}
|
||||
const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x);
|
||||
player.force.x -= 0.0017 * Math.cos(angle) * player.mass * (m.onGround ? 1.7 : 1);
|
||||
@@ -704,7 +704,7 @@ const spawn = {
|
||||
let me = mob[mob.length - 1];
|
||||
// console.log(`mass=${me.mass}, radius = ${radius}`)
|
||||
me.accelMag = 0.0002
|
||||
me.repulsionRange = 100000; //squared
|
||||
me.repulsionRange = 100000 + radius * radius; //squared
|
||||
// me.memory = 120;
|
||||
me.seeAtDistance2 = 2000000 //1400 vision range
|
||||
Matter.Body.setDensity(me, 0.0005) // normal density is 0.001 // this reduces life by half and decreases knockback
|
||||
@@ -1338,9 +1338,9 @@ const spawn = {
|
||||
|
||||
//when player is inside event horizon
|
||||
if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) {
|
||||
if (m.energy > 0) m.energy -= 0.004
|
||||
if (m.energy < 0.1 && m.immuneCycle < m.cycle) {
|
||||
m.damage(0.00015 * simulation.dmgScale);
|
||||
if (m.immuneCycle < m.cycle) {
|
||||
if (m.energy > 0) m.energy -= 0.004
|
||||
if (m.energy < 0.1) m.damage(0.00015 * simulation.dmgScale);
|
||||
}
|
||||
const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x);
|
||||
player.force.x -= 0.00125 * player.mass * Math.cos(angle) * (m.onGround ? 1.8 : 1);
|
||||
@@ -1447,9 +1447,9 @@ const spawn = {
|
||||
ctx.fill();
|
||||
//when player is inside event horizon
|
||||
if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) {
|
||||
if (m.energy > 0) m.energy -= 0.006
|
||||
if (m.energy < 0.1 && m.immuneCycle < m.cycle) {
|
||||
m.damage(0.0002 * simulation.dmgScale);
|
||||
if (m.immuneCycle < m.cycle) {
|
||||
if (m.energy > 0) m.energy -= 0.006
|
||||
if (m.energy < 0.1) m.damage(0.0002 * simulation.dmgScale);
|
||||
}
|
||||
const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x);
|
||||
player.force.x -= 0.0013 * Math.cos(angle) * player.mass * (m.onGround ? 1.7 : 1);
|
||||
@@ -1703,10 +1703,12 @@ const spawn = {
|
||||
ctx.setLineDash([125 * Math.random(), 125 * Math.random()]); //the dashed effect is not set back to normal, because it looks neat for how the player is drawn
|
||||
// ctx.lineDashOffset = 6*(simulation.cycle % 215);
|
||||
if (this.distanceToPlayer() < this.laserRange) {
|
||||
if (m.energy > 0.002) {
|
||||
m.energy -= 0.0035
|
||||
} else if (m.immuneCycle < m.cycle) {
|
||||
m.damage(0.0003 * simulation.dmgScale)
|
||||
if (m.immuneCycle < m.cycle) {
|
||||
if (m.energy > 0.002) {
|
||||
m.energy -= 0.0035
|
||||
} else {
|
||||
m.damage(0.0003 * simulation.dmgScale)
|
||||
}
|
||||
}
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(eye.x, eye.y);
|
||||
@@ -3551,7 +3553,8 @@ const spawn = {
|
||||
};
|
||||
},
|
||||
snakeBoss(x, y, radius = 75) { //snake boss with a laser head
|
||||
mobs.spawn(x, y, 8, radius, "rgb(55,170,170)");
|
||||
const color1 = "#f27"
|
||||
mobs.spawn(x, y, 8, radius, color1); //"rgb(55,170,170)"
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.damageReduction = 0.25;
|
||||
@@ -3579,6 +3582,14 @@ const spawn = {
|
||||
//snake tail
|
||||
const nodes = Math.min(8 + Math.ceil(0.5 * simulation.difficulty), 40)
|
||||
spawn.lineGroup(x + 105, y, "snakeBody", nodes);
|
||||
|
||||
for (let i = mob.length - 1, len = i - nodes; i > len; i--) { //set alternating colors
|
||||
if (i % 2) {
|
||||
mob[i].fill = "#333"
|
||||
} else {
|
||||
mob[i].fill = color1
|
||||
}
|
||||
}
|
||||
//constraint with first 3 mobs in line
|
||||
consBB[consBB.length] = Constraint.create({
|
||||
bodyA: mob[mob.length - nodes],
|
||||
@@ -3598,7 +3609,7 @@ const spawn = {
|
||||
stiffness: 0.05
|
||||
});
|
||||
World.add(engine.world, consBB[consBB.length - 1]);
|
||||
spawn.shield(me, x, y, 1);
|
||||
// spawn.shield(me, x, y, 1);
|
||||
},
|
||||
snakeBody(x, y, radius = 10) {
|
||||
mobs.spawn(x, y, 8, radius, "rgba(0,180,180,0.4)");
|
||||
@@ -3610,6 +3621,8 @@ const spawn = {
|
||||
me.collisionFilter.mask = cat.bullet | cat.player | cat.mob //| cat.body
|
||||
me.accelMag = 0.0004 * simulation.accelScale;
|
||||
me.leaveBody = false;
|
||||
me.showHealthBar = false;
|
||||
// Matter.Body.setDensity(me, 0.00004); //normal is 0.001
|
||||
me.frictionAir = 0.02;
|
||||
me.isSnakeTail = true;
|
||||
me.stroke = "transparent"
|
||||
|
||||
266
js/tech.js
266
js/tech.js
@@ -682,7 +682,7 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" || tech.haveGunCheck("spores") || tech.haveGunCheck("drones") || tech.haveGunCheck("missiles") || tech.haveGunCheck("foam") || tech.haveGunCheck("wave beam") || tech.isNeutronBomb || tech.isIceField || tech.relayIce || tech.blockingIce > 1
|
||||
return m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" || tech.haveGunCheck("spores") || tech.haveGunCheck("drones") || tech.haveGunCheck("missiles") || tech.haveGunCheck("foam") || tech.haveGunCheck("wave beam") || tech.isNeutronBomb || tech.isIceField || tech.isIceShot || tech.relayIce || tech.blockingIce > 1
|
||||
},
|
||||
requires: "drones, spores, missiles, foam, wave beam, neutron bomb, ice IX",
|
||||
effect() {
|
||||
@@ -865,9 +865,9 @@
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return ((m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isDroneRadioactive) || tech.haveGunCheck("super balls") || tech.haveGunCheck("shotgun")) && !tech.isNailShot
|
||||
return ((m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isDroneRadioactive) || tech.haveGunCheck("super balls") || tech.haveGunCheck("shotgun")) && !tech.isNailShot && !tech.isIceShot && !tech.isFoamShot && !tech.isWormShot
|
||||
},
|
||||
requires: "super balls, shotgun, drones, not irradiated drones",
|
||||
requires: "super balls, basic or slug shotgun, drones, not irradiated drones",
|
||||
effect() {
|
||||
tech.isIncendiary = true
|
||||
},
|
||||
@@ -1812,7 +1812,7 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return (tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.relayIce || tech.blockingIce > 1) && !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.nailsDeathMob
|
||||
return (tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.isIceShot || tech.relayIce || tech.blockingIce > 1) && !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.nailsDeathMob
|
||||
},
|
||||
requires: "a localized freeze effect, no other mob death tech",
|
||||
effect() {
|
||||
@@ -1830,7 +1830,7 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.isIceField || tech.relayIce || tech.blockingIce || tech.iceIXOnDeath
|
||||
return tech.isIceField || tech.relayIce || tech.blockingIce || tech.iceIXOnDeath || tech.isIceShot
|
||||
},
|
||||
requires: "ice IX",
|
||||
effect() {
|
||||
@@ -1848,7 +1848,7 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.relayIce || tech.blockingIce > 1 || tech.iceIXOnDeath
|
||||
return tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.relayIce || tech.blockingIce > 1 || tech.iceIXOnDeath || tech.isIceShot
|
||||
},
|
||||
requires: "a localized freeze effect",
|
||||
effect() {
|
||||
@@ -1866,7 +1866,7 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.isStunField || tech.isExplosionStun || tech.oneSuperBall || tech.isHarmFreeze || tech.isIceField || tech.relayIce || tech.isIceCrystals || tech.isSporeFreeze || tech.isAoESlow || tech.isFreezeMobs || tech.isCloakStun || tech.orbitBotCount > 1 || tech.isWormholeDamage || tech.blockingIce > 1 || tech.iceIXOnDeath
|
||||
return tech.isStunField || tech.isExplosionStun || tech.oneSuperBall || tech.isHarmFreeze || tech.isIceField || tech.relayIce || tech.isIceCrystals || tech.isSporeFreeze || tech.isAoESlow || tech.isFreezeMobs || tech.isCloakStun || tech.orbitBotCount > 1 || tech.isWormholeDamage || tech.blockingIce > 1 || tech.iceIXOnDeath || tech.isIceShot
|
||||
},
|
||||
requires: "a freezing or stunning effect",
|
||||
effect() {
|
||||
@@ -3461,9 +3461,9 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.isNeedles && !tech.isNailRadiation
|
||||
return (tech.isNeedles || tech.isNeedleShot) && !tech.isNailRadiation
|
||||
},
|
||||
requires: "needle gun, not irradiated nails",
|
||||
requires: "needle gun, needle-shot, not irradiated nails",
|
||||
effect() {
|
||||
tech.isNeedleShieldPierce = true
|
||||
},
|
||||
@@ -3729,44 +3729,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "nailshot",
|
||||
description: "the <strong>shotgun</strong> fires a burst of <strong>nails</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("shotgun") && !tech.isIncendiary && !tech.isSlugShot
|
||||
},
|
||||
requires: "shotgun, not slug, incendiary",
|
||||
effect() {
|
||||
tech.isNailShot = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isNailShot = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "shotgun slug",
|
||||
description: "the <strong>shotgun</strong> fires 1 large <strong>bullet</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("shotgun") && !tech.isNailShot
|
||||
},
|
||||
requires: "shotgun, not nailshot",
|
||||
effect() {
|
||||
tech.isSlugShot = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isSlugShot = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Newton's 3rd law",
|
||||
description: "<strong>shotgun</strong> <strong>recoil</strong> is increased<br>decrease <strong>shotgun</strong> <strong><em>delay</em></strong> after firing by <strong>66%</strong>",
|
||||
@@ -3805,6 +3767,120 @@
|
||||
tech.isShotgunReversed = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "shotgun slug",
|
||||
description: "the <strong>shotgun</strong> fires a huge dense <strong>bullet</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isIceShot && !tech.isFoamShot && !tech.isWormShot && !tech.isNeedleShot
|
||||
},
|
||||
requires: "shotgun, not nail-shot, foam-shot, worm-shot, ice-shot",
|
||||
effect() {
|
||||
tech.isSlugShot = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isSlugShot = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "nail-shot",
|
||||
description: "the <strong>shotgun</strong> fires a burst of <strong>nails</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("shotgun") && !tech.isIncendiary && !tech.isSlugShot && !tech.isIceShot && !tech.isFoamShot && !tech.isWormShot && !tech.isNeedleShot
|
||||
},
|
||||
requires: "shotgun, not incendiary, slug, foam-shot, worm-shot, ice-shot",
|
||||
effect() {
|
||||
tech.isNailShot = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isNailShot = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "worm-shot",
|
||||
description: "the <strong>shotgun</strong> fires <strong>3-4</strong> <strong class='color-p' style='letter-spacing: -0.8px;'>worms</strong>", //<br><strong class='color-p' style='letter-spacing: -0.8px;'>worms</strong> seek out nearby mobs
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isSlugShot && !tech.isIceShot && !tech.isFoamShot && !tech.isNeedleShot
|
||||
},
|
||||
requires: "shotgun, not incendiary, nail-shot, slug, foam-shot, ice-shot",
|
||||
effect() {
|
||||
tech.isWormShot = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isWormShot = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "foam-shot",
|
||||
description: "the <strong>shotgun</strong> fires <strong>14</strong> <strong>foam</strong> bubbles",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isSlugShot && !tech.isIceShot && !tech.isWormShot && !tech.isNeedleShot
|
||||
},
|
||||
requires: "shotgun, not incendiary, nail-shot, slug, worm-shot, ice-shot",
|
||||
effect() {
|
||||
tech.isFoamShot = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isFoamShot = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "ice-shot",
|
||||
description: "the <strong>shotgun</strong> fires <strong>16</strong> <strong class='color-s'>ice IX</strong> crystals",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isSlugShot && !tech.isFoamShot && !tech.isWormShot && !tech.isNeedleShot
|
||||
},
|
||||
requires: "shotgun, not incendiary, nail-shot, slug, foam-shot, worm-shot",
|
||||
effect() {
|
||||
tech.isIceShot = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isIceShot = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "needle-shot",
|
||||
description: "the <strong>shotgun</strong> fires <strong>12</strong> mob piercing <strong>needles</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isSlugShot && !tech.isFoamShot && !tech.isWormShot && !tech.isIceShot
|
||||
},
|
||||
requires: "shotgun, not incendiary, nail-shot, slug, foam-shot, worm-shot, ice-shot",
|
||||
effect() {
|
||||
tech.isNeedleShot = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isNeedleShot = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "super duper",
|
||||
description: "fire <strong>1</strong> additional <strong>super ball</strong>",
|
||||
@@ -4318,9 +4394,9 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField
|
||||
return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isWormShot
|
||||
},
|
||||
requires: "spores",
|
||||
requires: "spores or worms",
|
||||
effect() {
|
||||
tech.isSporeFreeze = true
|
||||
},
|
||||
@@ -4337,9 +4413,9 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField
|
||||
return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isWormShot
|
||||
},
|
||||
requires: "spores",
|
||||
requires: "spores or worms",
|
||||
effect() {
|
||||
tech.isSporeFollow = true
|
||||
},
|
||||
@@ -4347,6 +4423,25 @@
|
||||
tech.isSporeFollow = false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "mutualism",
|
||||
description: "increase <strong class='color-p' style='letter-spacing: 2px;'>spore</strong> <strong class='color-d'>damage</strong> by <strong>150%</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>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return (tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField) && !tech.isEnergyHealth || tech.isWormShot
|
||||
},
|
||||
requires: "spores, worms, not mass-energy",
|
||||
effect() {
|
||||
tech.isMutualism = true
|
||||
},
|
||||
remove() {
|
||||
tech.isMutualism = false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "nematodes",
|
||||
description: "<strong class='color-p' style='letter-spacing: 2px;'>spores</strong> develop into <strong>1/2</strong> as many <strong class='color-p' style='letter-spacing: -0.8px;'>worms</strong><br><strong class='color-p' style='letter-spacing: -0.8px;'>worms</strong> do <strong>200%</strong> more <strong class='color-d'>damage</strong>",
|
||||
@@ -4366,25 +4461,6 @@
|
||||
tech.isSporeWorm = false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "mutualism",
|
||||
description: "increase <strong class='color-p' style='letter-spacing: 2px;'>spore</strong> <strong class='color-d'>damage</strong> by <strong>150%</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>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return (tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField) && !tech.isEnergyHealth
|
||||
},
|
||||
requires: "spores, not mass-energy",
|
||||
effect() {
|
||||
tech.isMutualism = true
|
||||
},
|
||||
remove() {
|
||||
tech.isMutualism = false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "reduced tolerances",
|
||||
description: "increase <strong>drone</strong> <strong class='color-g'>ammo</strong>/<strong class='color-f'>efficiency</strong> by <strong>66%</strong><br>reduce the average <strong>drone</strong> lifetime by <strong>40%</strong>",
|
||||
@@ -4543,6 +4619,25 @@
|
||||
tech.droneRadioDamage = 1
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "electrostatic induction",
|
||||
description: "<strong>foam</strong> bubbles are electrically charged<br>causing <strong>attraction</strong> to nearby <strong>mobs</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return !tech.isFoamTeleport && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot)
|
||||
},
|
||||
requires: "foam, not uncertainty",
|
||||
effect() {
|
||||
tech.isFoamAttract = true
|
||||
},
|
||||
remove() {
|
||||
tech.isFoamAttract = false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "uncertainty principle",
|
||||
description: "<strong>foam</strong> bubbles randomly change <strong>position</strong><br>increase <strong>foam</strong> <strong class='color-d'>damage</strong> per second by <strong>66%</strong>",
|
||||
@@ -4552,7 +4647,7 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return !tech.isFoamAttract && (tech.haveGunCheck("foam") || tech.foamBotCount > 1)
|
||||
return !tech.isFoamAttract && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot)
|
||||
},
|
||||
requires: "foam, not electrostatic induction",
|
||||
effect() {
|
||||
@@ -4571,7 +4666,7 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("foam") || tech.foamBotCount > 1
|
||||
return tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot
|
||||
},
|
||||
requires: "foam",
|
||||
effect() {
|
||||
@@ -4590,7 +4685,7 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("foam") || tech.foamBotCount > 1
|
||||
return tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot
|
||||
},
|
||||
requires: "foam",
|
||||
effect() {
|
||||
@@ -4640,25 +4735,6 @@
|
||||
tech.isAmmoFoamSize = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "electrostatic induction",
|
||||
description: "<strong>foam</strong> bubbles are electrically charged<br>causing <strong>attraction</strong> to nearby <strong>mobs</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return !tech.isFoamTeleport && (tech.haveGunCheck("foam") || tech.foamBotCount > 1)
|
||||
},
|
||||
requires: "foam, not uncertainty",
|
||||
effect() {
|
||||
tech.isFoamAttract = true
|
||||
},
|
||||
remove() {
|
||||
tech.isFoamAttract = false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "half-wave rectifier",
|
||||
description: "charging the <strong>rail gun</strong> gives you <strong class='color-f'>energy</strong><br><em>instead of draining it</em>",
|
||||
@@ -7553,6 +7629,10 @@
|
||||
isFieldHarmReduction: null,
|
||||
isFastTime: null,
|
||||
isDroneTeleport: null,
|
||||
isAnthropicTech: null,
|
||||
isSporeWorm: null,
|
||||
isAnthropicTech: null
|
||||
isWormShot: null,
|
||||
isFoamShot: null,
|
||||
isIceShot: null,
|
||||
isNeedleShot: null
|
||||
}
|
||||
Reference in New Issue
Block a user