planned obsolescence
bug fixes strong anthropic principle does 0.03599% more damage spores can stick to rotating blocks now probably fixed the new wormhole field while targeting a block -> crouch lock bug ceramic needles now correctly bypass shields needles fire 3 at a time with a short delay and no spread tech: planned obsolescence - 3x drone ammo, 1/3 drone nano-scale energy cost, but 53% reduced drone life span
This commit is contained in:
122
js/bullet.js
122
js/bullet.js
@@ -35,7 +35,7 @@ const b = {
|
|||||||
if (m.health > 0.05) {
|
if (m.health > 0.05) {
|
||||||
m.damage(0.05 / m.harmReduction()); // /m.harmReduction() undoes damage increase from difficulty
|
m.damage(0.05 / m.harmReduction()); // /m.harmReduction() undoes damage increase from difficulty
|
||||||
if (!(tech.isRewindAvoidDeath && m.energy > 0.66)) { //don't give ammo if CPT triggered
|
if (!(tech.isRewindAvoidDeath && m.energy > 0.66)) { //don't give ammo if CPT triggered
|
||||||
for (let i = 0; i < 3; i++) powerUps.spawn(m.pos.x, m.pos.y, "ammo");
|
for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x, m.pos.y, "ammo");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -66,7 +66,7 @@ const b = {
|
|||||||
if (m.health > 0.05) {
|
if (m.health > 0.05) {
|
||||||
m.damage(0.05 / m.harmReduction()); // /m.harmReduction() undoes damage increase from difficulty
|
m.damage(0.05 / m.harmReduction()); // /m.harmReduction() undoes damage increase from difficulty
|
||||||
if (!(tech.isRewindAvoidDeath && m.energy > 0.66)) { //don't give ammo if CPT triggered
|
if (!(tech.isRewindAvoidDeath && m.energy > 0.66)) { //don't give ammo if CPT triggered
|
||||||
for (let i = 0; i < 3; i++) powerUps.spawn(m.pos.x, m.pos.y, "ammo");
|
for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x, m.pos.y, "ammo");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -98,7 +98,7 @@ const b = {
|
|||||||
if (m.health > 0.05) {
|
if (m.health > 0.05) {
|
||||||
m.damage(0.05 / m.harmReduction()); // /m.harmReduction() undoes damage increase from difficulty
|
m.damage(0.05 / m.harmReduction()); // /m.harmReduction() undoes damage increase from difficulty
|
||||||
if (!(tech.isRewindAvoidDeath && m.energy > 0.66)) { //don't give ammo if CPT triggered
|
if (!(tech.isRewindAvoidDeath && m.energy > 0.66)) { //don't give ammo if CPT triggered
|
||||||
for (let i = 0; i < 3; i++) powerUps.spawn(m.pos.x, m.pos.y, "ammo");
|
for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x, m.pos.y, "ammo");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -2037,7 +2037,7 @@ const b = {
|
|||||||
restitution: 1,
|
restitution: 1,
|
||||||
dmg: 0.24, //damage done in addition to the damage from momentum
|
dmg: 0.24, //damage done in addition to the damage from momentum
|
||||||
lookFrequency: 80 + Math.floor(23 * Math.random()),
|
lookFrequency: 80 + Math.floor(23 * Math.random()),
|
||||||
endCycle: simulation.cycle + Math.floor((1100 + 420 * Math.random()) * tech.isBulletsLastLonger),
|
endCycle: simulation.cycle + Math.floor((1100 + 420 * Math.random()) * tech.isBulletsLastLonger * tech.droneCycleReduction),
|
||||||
classType: "bullet",
|
classType: "bullet",
|
||||||
collisionFilter: {
|
collisionFilter: {
|
||||||
category: cat.bullet,
|
category: cat.bullet,
|
||||||
@@ -2109,7 +2109,7 @@ const b = {
|
|||||||
powerUp.splice(i, 1);
|
powerUp.splice(i, 1);
|
||||||
if (tech.isDroneGrab) {
|
if (tech.isDroneGrab) {
|
||||||
this.isImproved = true;
|
this.isImproved = true;
|
||||||
const SCALE = 3
|
const SCALE = 2.5
|
||||||
Matter.Body.scale(this, SCALE, SCALE);
|
Matter.Body.scale(this, SCALE, SCALE);
|
||||||
this.lookFrequency = 30;
|
this.lookFrequency = 30;
|
||||||
this.endCycle += 2500
|
this.endCycle += 2500
|
||||||
@@ -3214,8 +3214,6 @@ const b = {
|
|||||||
this.baseFire(m.angle + (Math.random() - 0.5) * (Math.random() - 0.5) * (m.crouch ? 1.35 : 3.2) / CD)
|
this.baseFire(m.angle + (Math.random() - 0.5) * (Math.random() - 0.5) * (m.crouch ? 1.35 : 3.2) / CD)
|
||||||
},
|
},
|
||||||
fireNeedles() {
|
fireNeedles() {
|
||||||
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 33 : 16) * b.fireCD); // cool down
|
|
||||||
|
|
||||||
function makeNeedle(angle = m.angle) {
|
function makeNeedle(angle = m.angle) {
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
bullet[me] = Bodies.rectangle(m.pos.x + 40 * Math.cos(m.angle), m.pos.y + 40 * Math.sin(m.angle), 50, 1, b.fireAttributes(angle));
|
bullet[me] = Bodies.rectangle(m.pos.x + 40 * Math.cos(m.angle), m.pos.y + 40 * Math.sin(m.angle), 50, 1, b.fireAttributes(angle));
|
||||||
@@ -3226,34 +3224,36 @@ const b = {
|
|||||||
bullet[me].do = function() {
|
bullet[me].do = function() {
|
||||||
const whom = Matter.Query.collides(this, mob)
|
const whom = Matter.Query.collides(this, mob)
|
||||||
if (whom.length && this.speed > 20) { //if touching a mob
|
if (whom.length && this.speed > 20) { //if touching a mob
|
||||||
who = whom[whom.length - 1].bodyA
|
for (let i = 0, len = whom.length; i < len; i++) {
|
||||||
if (who && who.mob) {
|
who = whom[i].bodyA
|
||||||
let immune = false
|
if (who && who.mob) {
|
||||||
for (let i = 0; i < this.immuneList.length; i++) {
|
let immune = false
|
||||||
if (this.immuneList[i] === who.id) {
|
for (let i = 0; i < this.immuneList.length; i++) { //check if this needle has hit this mob already
|
||||||
immune = true
|
if (this.immuneList[i] === who.id) {
|
||||||
break
|
immune = true
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (!immune) {
|
||||||
if (!immune) {
|
if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.975) {
|
||||||
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 + 30 * Math.random()); //makes bullet do explosive damage at end
|
||||||
b.explosion(this.position, 220 + 30 * Math.random()); //makes bullet do explosive damage at end
|
}
|
||||||
}
|
this.immuneList.push(who.id) //remember that this needle has hit this mob once already
|
||||||
this.immuneList.push(who.id)
|
who.foundPlayer();
|
||||||
who.foundPlayer();
|
if (tech.isNailRadiation) {
|
||||||
if (tech.isNailRadiation) {
|
mobs.statusDoT(who, tech.isFastRadiation ? 9 : 2.25, tech.isSlowRadiation ? 240 : (tech.isFastRadiation ? 30 : 120)) // one tick every 30 cycles
|
||||||
mobs.statusDoT(who, tech.isFastRadiation ? 8 : 2, tech.isSlowRadiation ? 240 : (tech.isFastRadiation ? 30 : 120)) // one tick every 30 cycles
|
} else {
|
||||||
} else {
|
let dmg = b.dmgScale * 3.5
|
||||||
let dmg = b.dmgScale * 3.25
|
if (tech.isCrit && who.isStunned) dmg *= 4
|
||||||
if (tech.isCrit && who.isStunned) dmg *= 4
|
who.damage(dmg, tech.isNeedleShieldPierce);
|
||||||
who.damage(dmg, tech.isNeedleShieldPierce);
|
simulation.drawList.push({ //add dmg to draw queue
|
||||||
simulation.drawList.push({ //add dmg to draw queue
|
x: this.position.x,
|
||||||
x: this.position.x,
|
y: this.position.y,
|
||||||
y: this.position.y,
|
radius: Math.log(2 * dmg + 1.1) * 40,
|
||||||
radius: Math.log(2 * dmg + 1.1) * 40,
|
color: simulation.playerDmgColor,
|
||||||
color: simulation.playerDmgColor,
|
time: simulation.drawTime
|
||||||
time: simulation.drawTime
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3277,10 +3277,26 @@ const b = {
|
|||||||
Matter.Body.setDensity(bullet[me], 0.00001);
|
Matter.Body.setDensity(bullet[me], 0.00001);
|
||||||
World.add(engine.world, bullet[me]); //add bullet to world
|
World.add(engine.world, bullet[me]); //add bullet to world
|
||||||
}
|
}
|
||||||
const spread = (m.crouch ? 0.013 : 0.06)
|
|
||||||
makeNeedle(m.angle + spread)
|
if (m.crouch) {
|
||||||
makeNeedle()
|
m.fireCDcycle = m.cycle + 50 * b.fireCD; // cool down
|
||||||
makeNeedle(m.angle - spread)
|
makeNeedle()
|
||||||
|
for (let i = 1; i < 4; i++) { //4 total needles
|
||||||
|
setTimeout(() => { if (!simulation.paused) makeNeedle() }, 40 * i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m.fireCDcycle = m.cycle + 30 * b.fireCD; // cool down
|
||||||
|
makeNeedle()
|
||||||
|
for (let i = 1; i < 3; i++) { //3 total needles
|
||||||
|
setTimeout(() => { if (!simulation.paused) makeNeedle() }, 40 * i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// const spread = (m.crouch ? 0.013 : 0.06)
|
||||||
|
// makeNeedle(m.angle + spread)
|
||||||
|
// makeNeedle()
|
||||||
|
// makeNeedle(m.angle - spread)
|
||||||
},
|
},
|
||||||
fireRivets() {
|
fireRivets() {
|
||||||
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 30 : 25) * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 30 : 25) * b.fireCD); // cool down
|
||||||
@@ -3553,8 +3569,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "super balls",
|
name: "super balls",
|
||||||
description: "fire <strong>four</strong> balls in a wide arc<br>balls <strong>bounce</strong> with no momentum loss",
|
description: "fire <strong>four</strong> balls in a wide arc<br>balls <strong>bounce</strong> with no momentum loss",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
@@ -3618,8 +3633,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "wave beam",
|
name: "wave beam",
|
||||||
description: "emit a <strong>sine wave</strong> of oscillating particles<br>propagates through <strong>walls</strong>",
|
description: "emit a <strong>sine wave</strong> of oscillating particles<br>propagates through <strong>walls</strong>",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
@@ -3729,8 +3743,7 @@ const b = {
|
|||||||
const transverse = Vector.normalise(Vector.perp(bullet[me].velocity))
|
const transverse = Vector.normalise(Vector.perp(bullet[me].velocity))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "missiles",
|
name: "missiles",
|
||||||
description: "launch <strong>homing</strong> missiles that <strong class='color-e'>explode</strong><br>crouch to <strong>rapidly</strong> launch smaller missiles",
|
description: "launch <strong>homing</strong> missiles that <strong class='color-e'>explode</strong><br>crouch to <strong>rapidly</strong> launch smaller missiles",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
@@ -3846,8 +3859,7 @@ const b = {
|
|||||||
|
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "grenades",
|
name: "grenades",
|
||||||
description: "lob a single <strong>bouncy</strong> projectile<br><strong class='color-e'>explodes</strong> on <strong>contact</strong> or after one second",
|
description: "lob a single <strong>bouncy</strong> projectile<br><strong class='color-e'>explodes</strong> on <strong>contact</strong> or after one second",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
@@ -3857,8 +3869,7 @@ const b = {
|
|||||||
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 40 : 30) * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 40 : 30) * b.fireCD); // cool down
|
||||||
b.grenade()
|
b.grenade()
|
||||||
},
|
},
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "mine",
|
name: "mine",
|
||||||
description: "toss a <strong>proximity</strong> mine that <strong>sticks</strong> to walls<br>fires <strong>nails</strong> at mobs within range",
|
description: "toss a <strong>proximity</strong> mine that <strong>sticks</strong> to walls<br>fires <strong>nails</strong> at mobs within range",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
@@ -3885,8 +3896,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 50 : 25) * b.fireCD); // cool down
|
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 50 : 25) * b.fireCD); // cool down
|
||||||
}
|
}
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "spores",
|
name: "spores",
|
||||||
description: "fire a <strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> that discharges <strong class='color-p' style='letter-spacing: 2px;'>spores</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> seek out nearby mobs",
|
description: "fire a <strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> that discharges <strong class='color-p' style='letter-spacing: 2px;'>spores</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> seek out nearby mobs",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
@@ -3947,7 +3957,7 @@ const b = {
|
|||||||
} else {
|
} else {
|
||||||
const bodyCollisions = Matter.Query.collides(this, body)
|
const bodyCollisions = Matter.Query.collides(this, body)
|
||||||
if (bodyCollisions.length) {
|
if (bodyCollisions.length) {
|
||||||
if (!bodyCollisions[0].bodyA.isNotHoldable) {
|
if (!bodyCollisions[0].bodyA.isComposite) {
|
||||||
onCollide(this)
|
onCollide(this)
|
||||||
this.stuckTo = bodyCollisions[0].bodyA
|
this.stuckTo = bodyCollisions[0].bodyA
|
||||||
//find the relative position for when the mob is at angle zero by undoing the mobs rotation
|
//find the relative position for when the mob is at angle zero by undoing the mobs rotation
|
||||||
@@ -4015,12 +4025,12 @@ const b = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "drones",
|
name: "drones",
|
||||||
description: "deploy drones that <strong>crash</strong> into mobs<br>crashes reduce their <strong>lifespan</strong> by 1 second",
|
description: "deploy drones that <strong>crash</strong> into mobs<br>crashes reduce their <strong>lifespan</strong> by 1 second",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: 14,
|
ammoPack: 14,
|
||||||
|
defaultAmmoPack: 14,
|
||||||
have: false,
|
have: false,
|
||||||
fire() {
|
fire() {
|
||||||
if (m.crouch) {
|
if (m.crouch) {
|
||||||
@@ -4086,8 +4096,7 @@ const b = {
|
|||||||
b.foam(position, Vector.rotate(velocity, 0.5 * (Math.random() - 0.5)), radius)
|
b.foam(position, Vector.rotate(velocity, 0.5 * (Math.random() - 0.5)), radius)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "rail gun",
|
name: "rail gun",
|
||||||
description: "use <strong class='color-f'>energy</strong> to launch a high-speed <strong>dense</strong> rod<br><strong>hold</strong> left mouse to charge, <strong>release</strong> to fire",
|
description: "use <strong class='color-f'>energy</strong> to launch a high-speed <strong>dense</strong> rod<br><strong>hold</strong> left mouse to charge, <strong>release</strong> to fire",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
@@ -4431,8 +4440,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
name: "laser",
|
name: "laser",
|
||||||
description: "emit a <strong>beam</strong> of collimated coherent <strong class='color-laser'>light</strong><br>drains <strong class='color-f'>energy</strong> instead of ammunition",
|
description: "emit a <strong>beam</strong> of collimated coherent <strong class='color-laser'>light</strong><br>drains <strong class='color-f'>energy</strong> instead of ammunition",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
|
|||||||
36
js/level.js
36
js/level.js
@@ -16,11 +16,11 @@ const level = {
|
|||||||
// simulation.zoomScale = 1000;
|
// simulation.zoomScale = 1000;
|
||||||
// simulation.setZoom();
|
// simulation.setZoom();
|
||||||
// m.setField("nano-scale manufacturing")
|
// m.setField("nano-scale manufacturing")
|
||||||
// b.giveGuns("foam")
|
// b.giveGuns("spores")
|
||||||
// tech.isExplodeRadio = true
|
// tech.isExplodeRadio = true
|
||||||
// for (let i = 0; i < 1; i++) tech.giveTech("dynamo-bot")
|
// for (let i = 0; i < 1; i++) tech.giveTech("dynamo-bot")
|
||||||
// tech.giveTech("supercritical fission")
|
// tech.giveTech("needle gun")
|
||||||
// tech.giveTech("micro-extruder")
|
// tech.giveTech("ceramic needles")
|
||||||
// tech.giveTech("causality bombs")
|
// tech.giveTech("causality bombs")
|
||||||
// tech.giveTech("cardinality")
|
// tech.giveTech("cardinality")
|
||||||
// tech.giveTech("Bayesian statistics")
|
// tech.giveTech("Bayesian statistics")
|
||||||
@@ -424,12 +424,14 @@ const level = {
|
|||||||
rotor(x, y, rotate = 0, radius = 800, width = 40, density = 0.0005) {
|
rotor(x, y, rotate = 0, radius = 800, width = 40, density = 0.0005) {
|
||||||
const rotor1 = Matter.Bodies.rectangle(x, y, width, radius, {
|
const rotor1 = Matter.Bodies.rectangle(x, y, width, radius, {
|
||||||
density: density,
|
density: density,
|
||||||
isNotHoldable: true
|
isNotHoldable: true,
|
||||||
|
isComposite: true
|
||||||
});
|
});
|
||||||
const rotor2 = Matter.Bodies.rectangle(x, y, width, radius, {
|
const rotor2 = Matter.Bodies.rectangle(x, y, width, radius, {
|
||||||
angle: Math.PI / 2,
|
angle: Math.PI / 2,
|
||||||
density: density,
|
density: density,
|
||||||
isNotHoldable: true
|
isNotHoldable: true,
|
||||||
|
isComposite: true
|
||||||
});
|
});
|
||||||
rotor = Body.create({ //combine rotor1 and rotor2
|
rotor = Body.create({ //combine rotor1 and rotor2
|
||||||
parts: [rotor1, rotor2],
|
parts: [rotor1, rotor2],
|
||||||
@@ -1100,8 +1102,8 @@ const level = {
|
|||||||
|
|
||||||
// simulation.difficulty = 30
|
// simulation.difficulty = 30
|
||||||
// spawn.starter(1900, -500, 200) //big boy
|
// spawn.starter(1900, -500, 200) //big boy
|
||||||
spawn.pulsar(1900, -500)
|
// spawn.pulsar(1900, -500)
|
||||||
spawn.pulsarBoss(1900, -500)
|
// spawn.pulsarBoss(1900, -500)
|
||||||
// spawn.historyBoss(1900, -500)
|
// spawn.historyBoss(1900, -500)
|
||||||
// spawn.ghoster(2900, -500)
|
// spawn.ghoster(2900, -500)
|
||||||
// spawn.launcherBoss(1200, -500)
|
// spawn.launcherBoss(1200, -500)
|
||||||
@@ -1113,7 +1115,7 @@ const level = {
|
|||||||
// spawn.streamBoss(1600, -500)
|
// spawn.streamBoss(1600, -500)
|
||||||
// spawn.orbitalBoss(1600, -500)
|
// spawn.orbitalBoss(1600, -500)
|
||||||
// spawn.cellBossCulture(1600, -500)
|
// spawn.cellBossCulture(1600, -500)
|
||||||
// spawn.shieldingBoss(1600, -500)
|
spawn.shieldingBoss(1600, -500)
|
||||||
// spawn.beamer(1200, -500)
|
// spawn.beamer(1200, -500)
|
||||||
// spawn.shield(mob[mob.length - 1], 1800, -120, 1);
|
// spawn.shield(mob[mob.length - 1], 1800, -120, 1);
|
||||||
|
|
||||||
@@ -4956,13 +4958,13 @@ const level = {
|
|||||||
document.body.style.backgroundColor = "#dcdcde";
|
document.body.style.backgroundColor = "#dcdcde";
|
||||||
//Level
|
//Level
|
||||||
level.setPosToSpawn(200, 50);
|
level.setPosToSpawn(200, 50);
|
||||||
|
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
||||||
|
|
||||||
level.exit.x = 8950;
|
level.exit.x = 8950;
|
||||||
level.exit.y = 200;
|
level.exit.y = 170;
|
||||||
|
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20);
|
||||||
|
|
||||||
//Map
|
//Map
|
||||||
spawn.mapRect(150, 90, 100, 100);
|
|
||||||
spawn.mapRect(8950, 190, 100, 100);
|
|
||||||
spawn.mapRect(-100, -400, 100, 600);
|
spawn.mapRect(-100, -400, 100, 600);
|
||||||
spawn.mapRect(-100, 100, 700, 100);
|
spawn.mapRect(-100, 100, 700, 100);
|
||||||
spawn.mapRect(500, 100, 100, 1700);
|
spawn.mapRect(500, 100, 100, 1700);
|
||||||
@@ -5006,7 +5008,7 @@ const level = {
|
|||||||
spawn.mapRect(8000, 1500, 300, 100);
|
spawn.mapRect(8000, 1500, 300, 100);
|
||||||
spawn.mapRect(7120, -100, 300, 100);
|
spawn.mapRect(7120, -100, 300, 100);
|
||||||
spawn.mapRect(7000, 1500, 300, 100);
|
spawn.mapRect(7000, 1500, 300, 100);
|
||||||
spawn.mapRect(6500, 1000, 300, 2100);
|
spawn.mapRect(6500, 1000, 300, 1200);
|
||||||
spawn.mapRect(5800, 1100, 300, 100);
|
spawn.mapRect(5800, 1100, 300, 100);
|
||||||
spawn.mapRect(5900, 1700, 300, 100);
|
spawn.mapRect(5900, 1700, 300, 100);
|
||||||
spawn.mapRect(5300, 1400, 300, 100);
|
spawn.mapRect(5300, 1400, 300, 100);
|
||||||
@@ -5063,11 +5065,11 @@ const level = {
|
|||||||
spawn.randomMob(8650, -200, 0.9); //end guards
|
spawn.randomMob(8650, -200, 0.9); //end guards
|
||||||
|
|
||||||
|
|
||||||
//Boss Spawning
|
//Boss Spawning
|
||||||
spawn.randomLevelBoss(6000, 700, ["pulsarBoss", "laserTargetingBoss", "powerUpBoss", "bomberBoss", "historyBoss", "orbitalBoss"]);
|
if (simulation.difficulty > 3) {
|
||||||
spawn.shieldingBoss(7200, 500);
|
spawn.randomLevelBoss(6000, 700, ["pulsarBoss", "laserTargetingBoss", "powerUpBoss", "bomberBoss", "historyBoss", "orbitalBoss"]);
|
||||||
if (simulation.difficulty > 20) {
|
if (simulation.difficulty > 10) spawn.shieldingBoss(7200, 500);
|
||||||
spawn.randomLevelBoss(2000, 300, ["historyBoss", "shooterBoss"]);
|
if (simulation.difficulty > 20) spawn.randomLevelBoss(2000, 300, ["historyBoss", "shooterBoss"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Blocks
|
//Blocks
|
||||||
|
|||||||
501
js/player.js
501
js/player.js
@@ -392,7 +392,7 @@ const m = {
|
|||||||
simulation.makeGunHUD(); //update gun HUD
|
simulation.makeGunHUD(); //update gun HUD
|
||||||
simulation.updateTechHUD();
|
simulation.updateTechHUD();
|
||||||
simulation.isTextLogOpen = true;
|
simulation.isTextLogOpen = true;
|
||||||
if (m.holdingTarget) m.drop();
|
m.drop();
|
||||||
if (simulation.paused) build.pauseGrid() //update the build when paused
|
if (simulation.paused) build.pauseGrid() //update the build when paused
|
||||||
},
|
},
|
||||||
death() {
|
death() {
|
||||||
@@ -498,7 +498,7 @@ const m = {
|
|||||||
harmReduction() {
|
harmReduction() {
|
||||||
let dmg = 1
|
let dmg = 1
|
||||||
dmg *= m.fieldHarmReduction
|
dmg *= m.fieldHarmReduction
|
||||||
if (tech.isImmortal) dmg *= 0.84
|
if (tech.isImmortal) dmg *= 0.79
|
||||||
if (tech.isHarmReduceAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 0.25 : 1.25
|
if (tech.isHarmReduceAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 0.25 : 1.25
|
||||||
if (tech.healthDrain) dmg *= 1 + 2.667 * tech.healthDrain //tech.healthDrain = 0.03 at one stack //cause more damage
|
if (tech.healthDrain) dmg *= 1 + 2.667 * tech.healthDrain //tech.healthDrain = 0.03 at one stack //cause more damage
|
||||||
if (tech.squirrelFx !== 1) dmg *= 1 + (tech.squirrelFx - 1) / 5 //cause more damage
|
if (tech.squirrelFx !== 1) dmg *= 1 + (tech.squirrelFx - 1) / 5 //cause more damage
|
||||||
@@ -631,7 +631,7 @@ const m = {
|
|||||||
}
|
}
|
||||||
m.lastHarmCycle = m.cycle
|
m.lastHarmCycle = m.cycle
|
||||||
if (tech.isDroneOnDamage) { //chance to build a drone on damage from tech
|
if (tech.isDroneOnDamage) { //chance to build a drone on damage from tech
|
||||||
const len = Math.min((dmg - 0.06 * Math.random()) * 40, 40)
|
const len = Math.min((dmg - 0.06 * Math.random()) * 40, 40) / tech.droneEnergyReduction
|
||||||
for (let i = 0; i < len; i++) {
|
for (let i = 0; i < len; i++) {
|
||||||
if (Math.random() < 0.5) b.drone() //spawn drone
|
if (Math.random() < 0.5) b.drone() //spawn drone
|
||||||
}
|
}
|
||||||
@@ -1002,11 +1002,11 @@ const m = {
|
|||||||
m.isHolding = false;
|
m.isHolding = false;
|
||||||
m.throwCharge = 0;
|
m.throwCharge = 0;
|
||||||
m.definePlayerMass()
|
m.definePlayerMass()
|
||||||
if (m.holdingTarget) {
|
}
|
||||||
m.holdingTarget.collisionFilter.category = cat.body;
|
if (m.holdingTarget) {
|
||||||
m.holdingTarget.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet
|
m.holdingTarget.collisionFilter.category = cat.body;
|
||||||
m.holdingTarget = null;
|
m.holdingTarget.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet
|
||||||
}
|
m.holdingTarget = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
definePlayerMass(mass = m.defaultMass) {
|
definePlayerMass(mass = m.defaultMass) {
|
||||||
@@ -1376,7 +1376,7 @@ const m = {
|
|||||||
if (tech.isFreezeMobs) {
|
if (tech.isFreezeMobs) {
|
||||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||||
Matter.Sleeping.set(mob[i], false)
|
Matter.Sleeping.set(mob[i], false)
|
||||||
mobs.statusSlow(mob[i], 90)
|
mobs.statusSlow(mob[i], 60)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
wake(mob);
|
wake(mob);
|
||||||
@@ -1566,7 +1566,7 @@ const m = {
|
|||||||
m.energy -= 0.057;
|
m.energy -= 0.057;
|
||||||
b.iceIX(1)
|
b.iceIX(1)
|
||||||
} else {
|
} else {
|
||||||
m.energy -= 0.45;
|
m.energy -= 0.45 * tech.droneEnergyReduction;
|
||||||
b.drone(1)
|
b.drone(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2297,15 +2297,246 @@ const m = {
|
|||||||
name: "wormhole",
|
name: "wormhole",
|
||||||
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong class='color-worm'>wormholes</strong> attract blocks and power ups<br><strong>7%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
|
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong class='color-worm'>wormholes</strong> attract blocks and power ups<br><strong>7%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
|
||||||
effect: function() {
|
effect: function() {
|
||||||
m.drop();
|
|
||||||
m.duplicateChance = 0.07
|
m.duplicateChance = 0.07
|
||||||
simulation.draw.powerUp = simulation.draw.powerUpBonus //change power up draw
|
simulation.draw.powerUp = simulation.draw.powerUpBonus //change power up draw
|
||||||
|
|
||||||
// if (tech.isRewindGun) {
|
m.hold = function() {
|
||||||
// m.hold = this.rewind
|
// m.hole = { //this is reset with each new field, but I'm leaving it here for reference
|
||||||
// } else {
|
// isOn: false,
|
||||||
m.hold = this.teleport
|
// isReady: true,
|
||||||
// }
|
// pos1: {x: 0,y: 0},
|
||||||
|
// pos2: {x: 0,y: 0},
|
||||||
|
// angle: 0,
|
||||||
|
// unit:{x:0,y:0},
|
||||||
|
// }
|
||||||
|
if (m.hole.isOn) {
|
||||||
|
// draw holes
|
||||||
|
m.fieldRange = 0.97 * m.fieldRange + 0.03 * (50 + 10 * Math.sin(simulation.cycle * 0.025))
|
||||||
|
const semiMajorAxis = m.fieldRange + 30
|
||||||
|
const edge1a = Vector.add(Vector.mult(m.hole.unit, semiMajorAxis), m.hole.pos1)
|
||||||
|
const edge1b = Vector.add(Vector.mult(m.hole.unit, -semiMajorAxis), m.hole.pos1)
|
||||||
|
const edge2a = Vector.add(Vector.mult(m.hole.unit, semiMajorAxis), m.hole.pos2)
|
||||||
|
const edge2b = Vector.add(Vector.mult(m.hole.unit, -semiMajorAxis), m.hole.pos2)
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(edge1a.x, edge1a.y)
|
||||||
|
ctx.bezierCurveTo(m.hole.pos1.x, m.hole.pos1.y, m.hole.pos2.x, m.hole.pos2.y, edge2a.x, edge2a.y);
|
||||||
|
ctx.lineTo(edge2b.x, edge2b.y)
|
||||||
|
ctx.bezierCurveTo(m.hole.pos2.x, m.hole.pos2.y, m.hole.pos1.x, m.hole.pos1.y, edge1b.x, edge1b.y);
|
||||||
|
ctx.fillStyle = `rgba(255,255,255,${200 / m.fieldRange / m.fieldRange})` //"rgba(0,0,0,0.1)"
|
||||||
|
ctx.fill();
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.ellipse(m.hole.pos1.x, m.hole.pos1.y, m.fieldRange, semiMajorAxis, m.hole.angle, 0, 2 * Math.PI)
|
||||||
|
ctx.ellipse(m.hole.pos2.x, m.hole.pos2.y, m.fieldRange, semiMajorAxis, m.hole.angle, 0, 2 * Math.PI)
|
||||||
|
ctx.fillStyle = `rgba(255,255,255,${32 / m.fieldRange})`
|
||||||
|
ctx.fill();
|
||||||
|
|
||||||
|
//suck power ups
|
||||||
|
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||||
|
//which hole is closer
|
||||||
|
const dxP1 = m.hole.pos1.x - powerUp[i].position.x;
|
||||||
|
const dyP1 = m.hole.pos1.y - powerUp[i].position.y;
|
||||||
|
const dxP2 = m.hole.pos2.x - powerUp[i].position.x;
|
||||||
|
const dyP2 = m.hole.pos2.y - powerUp[i].position.y;
|
||||||
|
let dxP, dyP, dist2
|
||||||
|
if (dxP1 * dxP1 + dyP1 * dyP1 < dxP2 * dxP2 + dyP2 * dyP2) {
|
||||||
|
dxP = dxP1
|
||||||
|
dyP = dyP1
|
||||||
|
} else {
|
||||||
|
dxP = dxP2
|
||||||
|
dyP = dyP2
|
||||||
|
}
|
||||||
|
dist2 = dxP * dxP + dyP * dyP;
|
||||||
|
if (dist2 < 600000 && !(m.health === m.maxHealth && powerUp[i].name === "heal")) {
|
||||||
|
powerUp[i].force.x += 4 * (dxP / dist2) * powerUp[i].mass; // float towards hole
|
||||||
|
powerUp[i].force.y += 4 * (dyP / dist2) * powerUp[i].mass - powerUp[i].mass * simulation.g; //negate gravity
|
||||||
|
Matter.Body.setVelocity(powerUp[i], { //extra friction
|
||||||
|
x: powerUp[i].velocity.x * 0.05,
|
||||||
|
y: powerUp[i].velocity.y * 0.05
|
||||||
|
});
|
||||||
|
if (dist2 < 1000 && !simulation.isChoosing) { //use power up if it is close enough
|
||||||
|
m.fieldRange *= 0.8
|
||||||
|
powerUps.onPickUp(powerUp[i]);
|
||||||
|
powerUp[i].effect();
|
||||||
|
Matter.World.remove(engine.world, powerUp[i]);
|
||||||
|
powerUp.splice(i, 1);
|
||||||
|
break; //because the array order is messed up after splice
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//suck and shrink blocks
|
||||||
|
const suckRange = 500
|
||||||
|
const shrinkRange = 100
|
||||||
|
const shrinkScale = 0.97;
|
||||||
|
const slowScale = 0.9
|
||||||
|
for (let i = 0, len = body.length; i < len; i++) {
|
||||||
|
if (!body[i].isNotHoldable) {
|
||||||
|
const dist1 = Vector.magnitude(Vector.sub(m.hole.pos1, body[i].position))
|
||||||
|
const dist2 = Vector.magnitude(Vector.sub(m.hole.pos2, body[i].position))
|
||||||
|
if (dist1 < dist2) {
|
||||||
|
if (dist1 < suckRange) {
|
||||||
|
const pull = Vector.mult(Vector.normalise(Vector.sub(m.hole.pos1, body[i].position)), 1)
|
||||||
|
const slow = Vector.mult(body[i].velocity, slowScale)
|
||||||
|
Matter.Body.setVelocity(body[i], Vector.add(slow, pull));
|
||||||
|
//shrink
|
||||||
|
if (Vector.magnitude(Vector.sub(m.hole.pos1, body[i].position)) < shrinkRange) {
|
||||||
|
Matter.Body.scale(body[i], shrinkScale, shrinkScale);
|
||||||
|
if (body[i].mass < 0.05) {
|
||||||
|
Matter.World.remove(engine.world, body[i]);
|
||||||
|
body.splice(i, 1);
|
||||||
|
m.fieldRange *= 0.8
|
||||||
|
if (tech.isWormholeEnergy) m.energy += 0.63
|
||||||
|
if (tech.isWormSpores) { //pandimensionalspermia
|
||||||
|
for (let i = 0, len = Math.ceil(3 * Math.random()); i < len; i++) {
|
||||||
|
b.spore(Vector.add(m.hole.pos2, Vector.rotate({
|
||||||
|
x: m.fieldRange * 0.4,
|
||||||
|
y: 0
|
||||||
|
}, 2 * Math.PI * Math.random())))
|
||||||
|
Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(m.hole.unit, Math.PI / 2), -15));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (dist2 < suckRange) {
|
||||||
|
const pull = Vector.mult(Vector.normalise(Vector.sub(m.hole.pos2, body[i].position)), 1)
|
||||||
|
const slow = Vector.mult(body[i].velocity, slowScale)
|
||||||
|
Matter.Body.setVelocity(body[i], Vector.add(slow, pull));
|
||||||
|
//shrink
|
||||||
|
if (Vector.magnitude(Vector.sub(m.hole.pos2, body[i].position)) < shrinkRange) {
|
||||||
|
Matter.Body.scale(body[i], shrinkScale, shrinkScale);
|
||||||
|
if (body[i].mass < 0.05) {
|
||||||
|
Matter.World.remove(engine.world, body[i]);
|
||||||
|
body.splice(i, 1);
|
||||||
|
m.fieldRange *= 0.8
|
||||||
|
// if (tech.isWormholeEnergy && m.energy < m.maxEnergy * 2) m.energy = m.maxEnergy * 2
|
||||||
|
if (tech.isWormholeEnergy) m.energy += 0.63
|
||||||
|
if (tech.isWormSpores) { //pandimensionalspermia
|
||||||
|
for (let i = 0, len = Math.ceil(3 * Math.random()); i < len; i++) {
|
||||||
|
b.spore(Vector.add(m.hole.pos1, Vector.rotate({
|
||||||
|
x: m.fieldRange * 0.4,
|
||||||
|
y: 0
|
||||||
|
}, 2 * Math.PI * Math.random())))
|
||||||
|
Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(m.hole.unit, Math.PI / 2), 15));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tech.isWormBullets) {
|
||||||
|
//teleport bullets
|
||||||
|
for (let i = 0, len = bullet.length; i < len; ++i) { //teleport bullets from hole1 to hole2
|
||||||
|
if (!bullet[i].botType && !bullet[i].isInHole) { //don't teleport bots
|
||||||
|
if (Vector.magnitude(Vector.sub(m.hole.pos1, bullet[i].position)) < m.fieldRange) { //find if bullet is touching hole1
|
||||||
|
Matter.Body.setPosition(bullet[i], Vector.add(m.hole.pos2, Vector.sub(m.hole.pos1, bullet[i].position)));
|
||||||
|
m.fieldRange += 5
|
||||||
|
bullet[i].isInHole = true
|
||||||
|
} else if (Vector.magnitude(Vector.sub(m.hole.pos2, bullet[i].position)) < m.fieldRange) { //find if bullet is touching hole1
|
||||||
|
Matter.Body.setPosition(bullet[i], Vector.add(m.hole.pos1, Vector.sub(m.hole.pos2, bullet[i].position)));
|
||||||
|
m.fieldRange += 5
|
||||||
|
bullet[i].isInHole = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// mobs get pushed away
|
||||||
|
for (let i = 0, len = mob.length; i < len; i++) {
|
||||||
|
if (Vector.magnitude(Vector.sub(m.hole.pos1, mob[i].position)) < 200) {
|
||||||
|
const pull = Vector.mult(Vector.normalise(Vector.sub(m.hole.pos1, mob[i].position)), -0.07)
|
||||||
|
Matter.Body.setVelocity(mob[i], Vector.add(mob[i].velocity, pull));
|
||||||
|
}
|
||||||
|
if (Vector.magnitude(Vector.sub(m.hole.pos2, mob[i].position)) < 200) {
|
||||||
|
const pull = Vector.mult(Vector.normalise(Vector.sub(m.hole.pos2, mob[i].position)), -0.07)
|
||||||
|
Matter.Body.setVelocity(mob[i], Vector.add(mob[i].velocity, pull));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed
|
||||||
|
const justPastMouse = Vector.add(Vector.mult(Vector.normalise(Vector.sub(simulation.mouseInGame, m.pos)), 50), simulation.mouseInGame)
|
||||||
|
const scale = 60
|
||||||
|
// console.log(Matter.Query.region(map, bounds))
|
||||||
|
if (m.hole.isReady &&
|
||||||
|
(
|
||||||
|
Matter.Query.region(map, {
|
||||||
|
min: {
|
||||||
|
x: simulation.mouseInGame.x - scale,
|
||||||
|
y: simulation.mouseInGame.y - scale
|
||||||
|
},
|
||||||
|
max: {
|
||||||
|
x: simulation.mouseInGame.x + scale,
|
||||||
|
y: simulation.mouseInGame.y + scale
|
||||||
|
}
|
||||||
|
}).length === 0 &&
|
||||||
|
Matter.Query.ray(map, m.pos, justPastMouse).length === 0
|
||||||
|
// Matter.Query.ray(map, m.pos, simulation.mouseInGame).length === 0 &&
|
||||||
|
// Matter.Query.ray(map, player.position, simulation.mouseInGame).length === 0 &&
|
||||||
|
// Matter.Query.ray(map, player.position, justPastMouse).length === 0
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
const sub = Vector.sub(simulation.mouseInGame, m.pos)
|
||||||
|
const mag = Vector.magnitude(sub)
|
||||||
|
const drain = 0.03 + 0.005 * Math.sqrt(mag)
|
||||||
|
if (m.energy > drain && mag > 300) {
|
||||||
|
m.energy -= drain
|
||||||
|
m.hole.isReady = false;
|
||||||
|
m.fieldRange = 0
|
||||||
|
Matter.Body.setPosition(player, simulation.mouseInGame);
|
||||||
|
m.buttonCD_jump = 0 //this might fix a bug with jumping
|
||||||
|
const velocity = Vector.mult(Vector.normalise(sub), 18)
|
||||||
|
Matter.Body.setVelocity(player, {
|
||||||
|
x: velocity.x,
|
||||||
|
y: velocity.y - 4 //an extra vertical kick so the player hangs in place longer
|
||||||
|
});
|
||||||
|
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage
|
||||||
|
// move bots to player
|
||||||
|
for (let i = 0; i < bullet.length; i++) {
|
||||||
|
if (bullet[i].botType) {
|
||||||
|
Matter.Body.setPosition(bullet[i], Vector.add(player.position, {
|
||||||
|
x: 250 * (Math.random() - 0.5),
|
||||||
|
y: 250 * (Math.random() - 0.5)
|
||||||
|
}));
|
||||||
|
Matter.Body.setVelocity(bullet[i], {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//set holes
|
||||||
|
m.hole.isOn = true;
|
||||||
|
m.hole.pos1.x = m.pos.x
|
||||||
|
m.hole.pos1.y = m.pos.y
|
||||||
|
m.hole.pos2.x = player.position.x
|
||||||
|
m.hole.pos2.y = player.position.y
|
||||||
|
m.hole.angle = Math.atan2(sub.y, sub.x)
|
||||||
|
m.hole.unit = Vector.perp(Vector.normalise(sub))
|
||||||
|
|
||||||
|
if (tech.isWormholeDamage) {
|
||||||
|
who = Matter.Query.ray(mob, m.pos, simulation.mouseInGame, 100)
|
||||||
|
for (let i = 0; i < who.length; i++) {
|
||||||
|
if (who[i].body.alive) {
|
||||||
|
mobs.statusDoT(who[i].body, 1, 420)
|
||||||
|
mobs.statusStun(who[i].body, 360)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m.grabPowerUp();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m.grabPowerUp();
|
||||||
|
}
|
||||||
|
// } else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released
|
||||||
|
// m.pickUp();
|
||||||
|
} else {
|
||||||
|
m.hole.isReady = true;
|
||||||
|
}
|
||||||
|
m.drawFieldMeter()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
rewindCount: 0,
|
rewindCount: 0,
|
||||||
// rewind: function() {
|
// rewind: function() {
|
||||||
@@ -2392,244 +2623,6 @@ const m = {
|
|||||||
// }
|
// }
|
||||||
// m.drawFieldMeter()
|
// m.drawFieldMeter()
|
||||||
// },
|
// },
|
||||||
teleport: function() {
|
|
||||||
// m.hole = { //this is reset with each new field, but I'm leaving it here for reference
|
|
||||||
// isOn: false,
|
|
||||||
// isReady: true,
|
|
||||||
// pos1: {x: 0,y: 0},
|
|
||||||
// pos2: {x: 0,y: 0},
|
|
||||||
// angle: 0,
|
|
||||||
// unit:{x:0,y:0},
|
|
||||||
// }
|
|
||||||
if (m.hole.isOn) {
|
|
||||||
// draw holes
|
|
||||||
m.fieldRange = 0.97 * m.fieldRange + 0.03 * (50 + 10 * Math.sin(simulation.cycle * 0.025))
|
|
||||||
const semiMajorAxis = m.fieldRange + 30
|
|
||||||
const edge1a = Vector.add(Vector.mult(m.hole.unit, semiMajorAxis), m.hole.pos1)
|
|
||||||
const edge1b = Vector.add(Vector.mult(m.hole.unit, -semiMajorAxis), m.hole.pos1)
|
|
||||||
const edge2a = Vector.add(Vector.mult(m.hole.unit, semiMajorAxis), m.hole.pos2)
|
|
||||||
const edge2b = Vector.add(Vector.mult(m.hole.unit, -semiMajorAxis), m.hole.pos2)
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(edge1a.x, edge1a.y)
|
|
||||||
ctx.bezierCurveTo(m.hole.pos1.x, m.hole.pos1.y, m.hole.pos2.x, m.hole.pos2.y, edge2a.x, edge2a.y);
|
|
||||||
ctx.lineTo(edge2b.x, edge2b.y)
|
|
||||||
ctx.bezierCurveTo(m.hole.pos2.x, m.hole.pos2.y, m.hole.pos1.x, m.hole.pos1.y, edge1b.x, edge1b.y);
|
|
||||||
ctx.fillStyle = `rgba(255,255,255,${200 / m.fieldRange / m.fieldRange})` //"rgba(0,0,0,0.1)"
|
|
||||||
ctx.fill();
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.ellipse(m.hole.pos1.x, m.hole.pos1.y, m.fieldRange, semiMajorAxis, m.hole.angle, 0, 2 * Math.PI)
|
|
||||||
ctx.ellipse(m.hole.pos2.x, m.hole.pos2.y, m.fieldRange, semiMajorAxis, m.hole.angle, 0, 2 * Math.PI)
|
|
||||||
ctx.fillStyle = `rgba(255,255,255,${32 / m.fieldRange})`
|
|
||||||
ctx.fill();
|
|
||||||
|
|
||||||
//suck power ups
|
|
||||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
|
||||||
//which hole is closer
|
|
||||||
const dxP1 = m.hole.pos1.x - powerUp[i].position.x;
|
|
||||||
const dyP1 = m.hole.pos1.y - powerUp[i].position.y;
|
|
||||||
const dxP2 = m.hole.pos2.x - powerUp[i].position.x;
|
|
||||||
const dyP2 = m.hole.pos2.y - powerUp[i].position.y;
|
|
||||||
let dxP, dyP, dist2
|
|
||||||
if (dxP1 * dxP1 + dyP1 * dyP1 < dxP2 * dxP2 + dyP2 * dyP2) {
|
|
||||||
dxP = dxP1
|
|
||||||
dyP = dyP1
|
|
||||||
} else {
|
|
||||||
dxP = dxP2
|
|
||||||
dyP = dyP2
|
|
||||||
}
|
|
||||||
dist2 = dxP * dxP + dyP * dyP;
|
|
||||||
if (dist2 < 600000 && !(m.health === m.maxHealth && powerUp[i].name === "heal")) {
|
|
||||||
powerUp[i].force.x += 4 * (dxP / dist2) * powerUp[i].mass; // float towards hole
|
|
||||||
powerUp[i].force.y += 4 * (dyP / dist2) * powerUp[i].mass - powerUp[i].mass * simulation.g; //negate gravity
|
|
||||||
Matter.Body.setVelocity(powerUp[i], { //extra friction
|
|
||||||
x: powerUp[i].velocity.x * 0.05,
|
|
||||||
y: powerUp[i].velocity.y * 0.05
|
|
||||||
});
|
|
||||||
if (dist2 < 1000 && !simulation.isChoosing) { //use power up if it is close enough
|
|
||||||
m.fieldRange *= 0.8
|
|
||||||
powerUps.onPickUp(powerUp[i]);
|
|
||||||
powerUp[i].effect();
|
|
||||||
Matter.World.remove(engine.world, powerUp[i]);
|
|
||||||
powerUp.splice(i, 1);
|
|
||||||
break; //because the array order is messed up after splice
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//suck and shrink blocks
|
|
||||||
const suckRange = 500
|
|
||||||
const shrinkRange = 100
|
|
||||||
const shrinkScale = 0.97;
|
|
||||||
const slowScale = 0.9
|
|
||||||
for (let i = 0, len = body.length; i < len; i++) {
|
|
||||||
if (!body[i].isNotHoldable) {
|
|
||||||
const dist1 = Vector.magnitude(Vector.sub(m.hole.pos1, body[i].position))
|
|
||||||
const dist2 = Vector.magnitude(Vector.sub(m.hole.pos2, body[i].position))
|
|
||||||
if (dist1 < dist2) {
|
|
||||||
if (dist1 < suckRange) {
|
|
||||||
const pull = Vector.mult(Vector.normalise(Vector.sub(m.hole.pos1, body[i].position)), 1)
|
|
||||||
const slow = Vector.mult(body[i].velocity, slowScale)
|
|
||||||
Matter.Body.setVelocity(body[i], Vector.add(slow, pull));
|
|
||||||
//shrink
|
|
||||||
if (Vector.magnitude(Vector.sub(m.hole.pos1, body[i].position)) < shrinkRange) {
|
|
||||||
Matter.Body.scale(body[i], shrinkScale, shrinkScale);
|
|
||||||
if (body[i].mass < 0.05) {
|
|
||||||
Matter.World.remove(engine.world, body[i]);
|
|
||||||
body.splice(i, 1);
|
|
||||||
m.fieldRange *= 0.8
|
|
||||||
if (tech.isWormholeEnergy) m.energy += 0.63
|
|
||||||
if (tech.isWormSpores) { //pandimensionalspermia
|
|
||||||
for (let i = 0, len = Math.ceil(3 * Math.random()); i < len; i++) {
|
|
||||||
b.spore(Vector.add(m.hole.pos2, Vector.rotate({
|
|
||||||
x: m.fieldRange * 0.4,
|
|
||||||
y: 0
|
|
||||||
}, 2 * Math.PI * Math.random())))
|
|
||||||
Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(m.hole.unit, Math.PI / 2), -15));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (dist2 < suckRange) {
|
|
||||||
const pull = Vector.mult(Vector.normalise(Vector.sub(m.hole.pos2, body[i].position)), 1)
|
|
||||||
const slow = Vector.mult(body[i].velocity, slowScale)
|
|
||||||
Matter.Body.setVelocity(body[i], Vector.add(slow, pull));
|
|
||||||
//shrink
|
|
||||||
if (Vector.magnitude(Vector.sub(m.hole.pos2, body[i].position)) < shrinkRange) {
|
|
||||||
Matter.Body.scale(body[i], shrinkScale, shrinkScale);
|
|
||||||
if (body[i].mass < 0.05) {
|
|
||||||
Matter.World.remove(engine.world, body[i]);
|
|
||||||
body.splice(i, 1);
|
|
||||||
m.fieldRange *= 0.8
|
|
||||||
// if (tech.isWormholeEnergy && m.energy < m.maxEnergy * 2) m.energy = m.maxEnergy * 2
|
|
||||||
if (tech.isWormholeEnergy) m.energy += 0.63
|
|
||||||
if (tech.isWormSpores) { //pandimensionalspermia
|
|
||||||
for (let i = 0, len = Math.ceil(3 * Math.random()); i < len; i++) {
|
|
||||||
b.spore(Vector.add(m.hole.pos1, Vector.rotate({
|
|
||||||
x: m.fieldRange * 0.4,
|
|
||||||
y: 0
|
|
||||||
}, 2 * Math.PI * Math.random())))
|
|
||||||
Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(m.hole.unit, Math.PI / 2), 15));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (tech.isWormBullets) {
|
|
||||||
//teleport bullets
|
|
||||||
for (let i = 0, len = bullet.length; i < len; ++i) { //teleport bullets from hole1 to hole2
|
|
||||||
if (!bullet[i].botType && !bullet[i].isInHole) { //don't teleport bots
|
|
||||||
if (Vector.magnitude(Vector.sub(m.hole.pos1, bullet[i].position)) < m.fieldRange) { //find if bullet is touching hole1
|
|
||||||
Matter.Body.setPosition(bullet[i], Vector.add(m.hole.pos2, Vector.sub(m.hole.pos1, bullet[i].position)));
|
|
||||||
m.fieldRange += 5
|
|
||||||
bullet[i].isInHole = true
|
|
||||||
} else if (Vector.magnitude(Vector.sub(m.hole.pos2, bullet[i].position)) < m.fieldRange) { //find if bullet is touching hole1
|
|
||||||
Matter.Body.setPosition(bullet[i], Vector.add(m.hole.pos1, Vector.sub(m.hole.pos2, bullet[i].position)));
|
|
||||||
m.fieldRange += 5
|
|
||||||
bullet[i].isInHole = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// mobs get pushed away
|
|
||||||
for (let i = 0, len = mob.length; i < len; i++) {
|
|
||||||
if (Vector.magnitude(Vector.sub(m.hole.pos1, mob[i].position)) < 200) {
|
|
||||||
const pull = Vector.mult(Vector.normalise(Vector.sub(m.hole.pos1, mob[i].position)), -0.07)
|
|
||||||
Matter.Body.setVelocity(mob[i], Vector.add(mob[i].velocity, pull));
|
|
||||||
}
|
|
||||||
if (Vector.magnitude(Vector.sub(m.hole.pos2, mob[i].position)) < 200) {
|
|
||||||
const pull = Vector.mult(Vector.normalise(Vector.sub(m.hole.pos2, mob[i].position)), -0.07)
|
|
||||||
Matter.Body.setVelocity(mob[i], Vector.add(mob[i].velocity, pull));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed
|
|
||||||
const justPastMouse = Vector.add(Vector.mult(Vector.normalise(Vector.sub(simulation.mouseInGame, m.pos)), 50), simulation.mouseInGame)
|
|
||||||
const scale = 60
|
|
||||||
// console.log(Matter.Query.region(map, bounds))
|
|
||||||
if (m.hole.isReady &&
|
|
||||||
(
|
|
||||||
Matter.Query.region(map, {
|
|
||||||
min: {
|
|
||||||
x: simulation.mouseInGame.x - scale,
|
|
||||||
y: simulation.mouseInGame.y - scale
|
|
||||||
},
|
|
||||||
max: {
|
|
||||||
x: simulation.mouseInGame.x + scale,
|
|
||||||
y: simulation.mouseInGame.y + scale
|
|
||||||
}
|
|
||||||
}).length === 0 &&
|
|
||||||
Matter.Query.ray(map, m.pos, justPastMouse).length === 0
|
|
||||||
// Matter.Query.ray(map, m.pos, simulation.mouseInGame).length === 0 &&
|
|
||||||
// Matter.Query.ray(map, player.position, simulation.mouseInGame).length === 0 &&
|
|
||||||
// Matter.Query.ray(map, player.position, justPastMouse).length === 0
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
const sub = Vector.sub(simulation.mouseInGame, m.pos)
|
|
||||||
const mag = Vector.magnitude(sub)
|
|
||||||
const drain = 0.03 + 0.005 * Math.sqrt(mag)
|
|
||||||
if (m.energy > drain && mag > 300) {
|
|
||||||
m.energy -= drain
|
|
||||||
m.hole.isReady = false;
|
|
||||||
m.fieldRange = 0
|
|
||||||
Matter.Body.setPosition(player, simulation.mouseInGame);
|
|
||||||
m.buttonCD_jump = 0 //this might fix a bug with jumping
|
|
||||||
const velocity = Vector.mult(Vector.normalise(sub), 18)
|
|
||||||
Matter.Body.setVelocity(player, {
|
|
||||||
x: velocity.x,
|
|
||||||
y: velocity.y - 4 //an extra vertical kick so the player hangs in place longer
|
|
||||||
});
|
|
||||||
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage
|
|
||||||
// move bots to player
|
|
||||||
for (let i = 0; i < bullet.length; i++) {
|
|
||||||
if (bullet[i].botType) {
|
|
||||||
Matter.Body.setPosition(bullet[i], Vector.add(player.position, {
|
|
||||||
x: 250 * (Math.random() - 0.5),
|
|
||||||
y: 250 * (Math.random() - 0.5)
|
|
||||||
}));
|
|
||||||
Matter.Body.setVelocity(bullet[i], {
|
|
||||||
x: 0,
|
|
||||||
y: 0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//set holes
|
|
||||||
m.hole.isOn = true;
|
|
||||||
m.hole.pos1.x = m.pos.x
|
|
||||||
m.hole.pos1.y = m.pos.y
|
|
||||||
m.hole.pos2.x = player.position.x
|
|
||||||
m.hole.pos2.y = player.position.y
|
|
||||||
m.hole.angle = Math.atan2(sub.y, sub.x)
|
|
||||||
m.hole.unit = Vector.perp(Vector.normalise(sub))
|
|
||||||
|
|
||||||
if (tech.isWormholeDamage) {
|
|
||||||
who = Matter.Query.ray(mob, m.pos, simulation.mouseInGame, 100)
|
|
||||||
for (let i = 0; i < who.length; i++) {
|
|
||||||
if (who[i].body.alive) {
|
|
||||||
mobs.statusDoT(who[i].body, 1, 420)
|
|
||||||
mobs.statusStun(who[i].body, 360)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m.grabPowerUp();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m.grabPowerUp();
|
|
||||||
}
|
|
||||||
} else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released
|
|
||||||
m.pickUp();
|
|
||||||
} else {
|
|
||||||
m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
|
|
||||||
m.hole.isReady = true;
|
|
||||||
}
|
|
||||||
m.drawFieldMeter()
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
isShipMode: false,
|
isShipMode: false,
|
||||||
|
|||||||
@@ -2566,7 +2566,7 @@ const spawn = {
|
|||||||
this.cycle = 0
|
this.cycle = 0
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
for (let i = 0; i < mob.length; i++) {
|
for (let i = 0; i < mob.length; i++) {
|
||||||
if (!mob[i].isShielded && !mob[i].shield && mob[i].dropPowerUp) {
|
if (!mob[i].isShielded && !mob[i].shield && mob[i].dropPowerUp && mob[i].alive) {
|
||||||
ctx.moveTo(this.position.x, this.position.y)
|
ctx.moveTo(this.position.x, this.position.y)
|
||||||
ctx.lineTo(mob[i].position.x, mob[i].position.y)
|
ctx.lineTo(mob[i].position.x, mob[i].position.y)
|
||||||
|
|
||||||
|
|||||||
355
js/tech.js
355
js/tech.js
@@ -124,7 +124,7 @@
|
|||||||
damageFromTech() {
|
damageFromTech() {
|
||||||
let dmg = m.fieldDamage
|
let dmg = m.fieldDamage
|
||||||
if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.555
|
if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.555
|
||||||
if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.37
|
if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.3703599
|
||||||
if (tech.isDamageAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 1.5 : 0.5
|
if (tech.isDamageAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 1.5 : 0.5
|
||||||
if (tech.isTechDamage) dmg *= 2
|
if (tech.isTechDamage) dmg *= 2
|
||||||
if (tech.isDupDamage) dmg *= 1 + Math.min(1, tech.duplicationChance())
|
if (tech.isDupDamage) dmg *= 1 + Math.min(1, tech.duplicationChance())
|
||||||
@@ -270,8 +270,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "gun technology",
|
name: "gun sciences",
|
||||||
description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-g'>gun</strong> <strong class='color-m'>tech</strong><br>spawn a <strong class='color-g'>gun</strong>",
|
description: "spawn a <strong class='color-g'>gun</strong> and </strong>double</strong> the <strong class='flicker'>frequency</strong><br>of finding <strong class='color-m'>tech</strong> for a specific <strong class='color-g'>gun</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 1,
|
frequency: 1,
|
||||||
@@ -358,14 +358,14 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "catabolism",
|
name: "catabolism",
|
||||||
description: "when you <strong>fire</strong> while <strong>out</strong> of <strong class='color-g'>ammo</strong><br>gain <strong>3</strong> <strong class='color-g'>ammo</strong>, but lose <strong>5</strong> <strong class='color-h'>health</strong>",
|
description: "when you <strong>fire</strong> while <strong>out</strong> of <strong class='color-g'>ammo</strong><br>gain <strong>4</strong> <strong class='color-g'>ammo</strong>, but lose <strong>5</strong> <strong class='color-h'>health</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 1,
|
frequency: 1,
|
||||||
allowed() {
|
allowed() {
|
||||||
return !tech.isEnergyHealth && !tech.isEnergyNoAmmo
|
return m.harmReduction() < 1 && !tech.isEnergyHealth && !tech.isEnergyNoAmmo
|
||||||
},
|
},
|
||||||
requires: "not mass-energy equivalence<br>not exciton-lattice",
|
requires: "some harm reduction, not mass-energy equivalence, exciton-lattice",
|
||||||
effect: () => {
|
effect: () => {
|
||||||
tech.isAmmoFromHealth = true;
|
tech.isAmmoFromHealth = true;
|
||||||
},
|
},
|
||||||
@@ -613,6 +613,58 @@
|
|||||||
b.setFireCD();
|
b.setFireCD();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "microstates",
|
||||||
|
description: "increase <strong class='color-d'>damage</strong> by <strong>4%</strong><br>for every <strong>10</strong> active <strong>bullets</strong>",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 1,
|
||||||
|
allowed() {
|
||||||
|
return tech.isBulletsLastLonger > 1
|
||||||
|
},
|
||||||
|
requires: "anti-shear topology",
|
||||||
|
effect() {
|
||||||
|
tech.isDamageFromBulletCount = true
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isDamageFromBulletCount = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "anti-shear topology",
|
||||||
|
description: "some <strong>bullets</strong> last <strong>30% longer</strong><br><em style = 'font-size: 83%'>drones, spores, missiles, foam, wave, neutron</em>",
|
||||||
|
// isGunTech: true,
|
||||||
|
maxCount: 3,
|
||||||
|
count: 0,
|
||||||
|
frequency: 1,
|
||||||
|
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
|
||||||
|
},
|
||||||
|
requires: "drones, spores, missiles, foam<br>wave beam, neutron bomb",
|
||||||
|
effect() {
|
||||||
|
tech.isBulletsLastLonger += 0.3
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isBulletsLastLonger = 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "radioactive contamination",
|
||||||
|
description: "after a mob or shield <strong>dies</strong>,<br> leftover <strong class='color-p'>radiation</strong> <strong>spreads</strong> to a nearby mob",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 1,
|
||||||
|
allowed() {
|
||||||
|
return tech.isNailRadiation || tech.isWormholeDamage || tech.isNeutronBomb || tech.isExplodeRadio
|
||||||
|
},
|
||||||
|
requires: "radiation damage source",
|
||||||
|
effect() {
|
||||||
|
tech.isRadioactive = true
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isRadioactive = false
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "iridium-192",
|
name: "iridium-192",
|
||||||
description: "<strong class='color-e'>explosions</strong> release <strong class='color-p'>gamma radiation</strong><br><strong>100%</strong> more <strong class='color-d'>damage</strong>, but over 4 seconds",
|
description: "<strong class='color-e'>explosions</strong> release <strong class='color-p'>gamma radiation</strong><br><strong>100%</strong> more <strong class='color-d'>damage</strong>, but over 4 seconds",
|
||||||
@@ -699,6 +751,40 @@
|
|||||||
tech.isImmuneExplosion = false;
|
tech.isImmuneExplosion = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "incendiary ammunition",
|
||||||
|
description: "<strong>shotgun</strong>, <strong>super balls</strong>, and <strong>drones</strong><br>are loaded with <strong class='color-e'>explosives</strong>",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 1,
|
||||||
|
allowed() {
|
||||||
|
return ((m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isMissileField || tech.isIceField)) || tech.haveGunCheck("drones") || tech.haveGunCheck("super balls") || tech.haveGunCheck("shotgun")) && !tech.isNailShot
|
||||||
|
},
|
||||||
|
requires: "drones, super balls, shotgun",
|
||||||
|
effect() {
|
||||||
|
tech.isIncendiary = true
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isIncendiary = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fragmentation",
|
||||||
|
description: "some <strong class='color-e'>detonations</strong> and collisions eject <strong>nails</strong><br><em style = 'font-size: 90%'>blocks, rail gun, grenades, missiles, shotgun slugs</em>",
|
||||||
|
maxCount: 9,
|
||||||
|
count: 0,
|
||||||
|
frequency: 1,
|
||||||
|
allowed() {
|
||||||
|
return (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("missiles") || tech.haveGunCheck("rail gun") || (tech.haveGunCheck("shotgun") && tech.isSlugShot) || tech.throwChargeRate > 1
|
||||||
|
},
|
||||||
|
requires: "grenades, missiles, rail gun, shotgun slugs, or mass driver",
|
||||||
|
effect() {
|
||||||
|
tech.fragments++
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.fragments = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "thermal runaway",
|
name: "thermal runaway",
|
||||||
description: "mobs <strong class='color-e'>explode</strong> when they <strong>die</strong><br><em>be careful</em>",
|
description: "mobs <strong class='color-e'>explode</strong> when they <strong>die</strong><br><em>be careful</em>",
|
||||||
@@ -716,6 +802,23 @@
|
|||||||
tech.isExplodeMob = false;
|
tech.isExplodeMob = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "impact shear",
|
||||||
|
description: "mobs release a <strong>nail</strong> when they <strong>die</strong><br><em>nails target nearby mobs</em>",
|
||||||
|
maxCount: 9,
|
||||||
|
count: 0,
|
||||||
|
frequency: 1,
|
||||||
|
allowed() {
|
||||||
|
return !tech.sporesOnDeath && !tech.isExplodeMob && !tech.isBotSpawner
|
||||||
|
},
|
||||||
|
requires: "no other mob death tech",
|
||||||
|
effect: () => {
|
||||||
|
tech.nailsDeathMob++
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.nailsDeathMob = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "zoospore vector",
|
name: "zoospore vector",
|
||||||
description: "mobs produce <strong class='color-p' style='letter-spacing: 2px;'>spores</strong> when they <strong>die</strong><br><strong>9%</strong> chance",
|
description: "mobs produce <strong class='color-p' style='letter-spacing: 2px;'>spores</strong> when they <strong>die</strong><br><strong>9%</strong> chance",
|
||||||
@@ -736,23 +839,6 @@
|
|||||||
tech.sporesOnDeath = 0;
|
tech.sporesOnDeath = 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "impact shear",
|
|
||||||
description: "mobs release a <strong>nail</strong> when they <strong>die</strong><br><em>nails target nearby mobs</em>",
|
|
||||||
maxCount: 9,
|
|
||||||
count: 0,
|
|
||||||
frequency: 1,
|
|
||||||
allowed() {
|
|
||||||
return !tech.sporesOnDeath && !tech.isExplodeMob && !tech.isBotSpawner
|
|
||||||
},
|
|
||||||
requires: "no other mob death tech",
|
|
||||||
effect: () => {
|
|
||||||
tech.nailsDeathMob++
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
tech.nailsDeathMob = 0;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "reaction inhibitor",
|
name: "reaction inhibitor",
|
||||||
description: "mobs spawn with <strong>11%</strong> less <strong>health</strong>",
|
description: "mobs spawn with <strong>11%</strong> less <strong>health</strong>",
|
||||||
@@ -1492,7 +1578,25 @@
|
|||||||
remove() {
|
remove() {
|
||||||
tech.isFreezeHarmImmune = false;
|
tech.isFreezeHarmImmune = false;
|
||||||
}
|
}
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
|
name: "superfluidity",
|
||||||
|
description: "<strong class='color-s'>freeze</strong> effects are applied to a small area",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 1,
|
||||||
|
allowed() {
|
||||||
|
return tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField
|
||||||
|
},
|
||||||
|
requires: "a localized freeze effect",
|
||||||
|
effect() {
|
||||||
|
tech.isAoESlow = true
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.isAoESlow = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
name: "ablative drones",
|
name: "ablative drones",
|
||||||
description: "rebuild your broken parts as <strong>drones</strong><br>chance to occur after receiving <strong class='color-harm'>harm</strong>",
|
description: "rebuild your broken parts as <strong>drones</strong><br>chance to occur after receiving <strong class='color-harm'>harm</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
@@ -2025,7 +2129,7 @@
|
|||||||
frequency: 1,
|
frequency: 1,
|
||||||
isHealTech: true,
|
isHealTech: true,
|
||||||
allowed() {
|
allowed() {
|
||||||
return (m.health < 0.75 || build.isExperimentSelection) && !tech.isEnergyHealth
|
return ((m.health / m.maxHealth) < 0.7 || build.isExperimentSelection) && !tech.isEnergyHealth
|
||||||
},
|
},
|
||||||
requires: "not mass-energy equivalence",
|
requires: "not mass-energy equivalence",
|
||||||
effect() {
|
effect() {
|
||||||
@@ -2036,14 +2140,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "healing technology",
|
name: "maintenance",
|
||||||
description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-h'>healing</strong> <strong class='color-m'>tech</strong><br>spawn <strong>12</strong> <strong class='color-h'>heals</strong>",
|
description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-h'>healing</strong> <strong class='color-m'>tech</strong><br>spawn <strong>12</strong> <strong class='color-h'>heals</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 1,
|
frequency: 1,
|
||||||
isNonRefundable: true,
|
isNonRefundable: true,
|
||||||
allowed() {
|
allowed() {
|
||||||
return true
|
return ((m.health / m.maxHealth) < 0.7 || build.isExperimentSelection)
|
||||||
},
|
},
|
||||||
requires: "",
|
requires: "",
|
||||||
effect() {
|
effect() {
|
||||||
@@ -2118,14 +2222,14 @@
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
name: "quantum immortality",
|
name: "quantum immortality",
|
||||||
description: "after <strong>dying</strong>, continue in an <strong>alternate reality</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>16%</strong>", //spawn <strong>4</strong> <strong class='color-r'>research</strong>
|
description: "after <strong>dying</strong>, continue in an <strong>alternate reality</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>23%</strong>", //spawn <strong>4</strong> <strong class='color-r'>research</strong>
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 1,
|
frequency: 1,
|
||||||
allowed() {
|
allowed() {
|
||||||
return !tech.isSwitchReality && !tech.isResearchReality
|
return !tech.isSwitchReality && !tech.isResearchReality && tech.isDeathAvoid
|
||||||
},
|
},
|
||||||
requires: "not many-worlds, perturbation theory",
|
requires: "anthropic principle, not many-worlds, perturbation theory",
|
||||||
effect() {
|
effect() {
|
||||||
tech.isImmortal = true;
|
tech.isImmortal = true;
|
||||||
// for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + Math.random() * 10, m.pos.y + Math.random() * 10, "research", false);
|
// for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + Math.random() * 10, m.pos.y + Math.random() * 10, "research", false);
|
||||||
@@ -2156,9 +2260,9 @@
|
|||||||
count: 0,
|
count: 0,
|
||||||
frequency: 1,
|
frequency: 1,
|
||||||
allowed() {
|
allowed() {
|
||||||
return !tech.isImmortal && !tech.isSwitchReality && (powerUps.research.count > 2 || build.isExperimentSelection)
|
return !tech.isImmortal && !tech.isSwitchReality
|
||||||
},
|
},
|
||||||
requires: "at least 2 research, not quantum immortality, many-worlds",
|
requires: "not quantum immortality, many-worlds",
|
||||||
effect() {
|
effect() {
|
||||||
tech.isResearchReality = true;
|
tech.isResearchReality = true;
|
||||||
for (let i = 0; i < 11; i++) powerUps.spawn(m.pos.x + Math.random() * 10, m.pos.y + Math.random() * 10, "research", false);
|
for (let i = 0; i < 11; i++) powerUps.spawn(m.pos.x + Math.random() * 10, m.pos.y + Math.random() * 10, "research", false);
|
||||||
@@ -2166,22 +2270,6 @@
|
|||||||
remove() {
|
remove() {
|
||||||
tech.isResearchReality = false;
|
tech.isResearchReality = false;
|
||||||
}
|
}
|
||||||
}, {
|
|
||||||
name: "renormalization",
|
|
||||||
description: "using a <strong class='color-r'>research</strong> for <strong>any</strong> purpose<br>has a <strong>37%</strong> chance to spawn a <strong class='color-r'>research</strong>",
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
frequency: 1,
|
|
||||||
allowed() {
|
|
||||||
return (powerUps.research.count > 2 || build.isExperimentSelection) && !tech.isSuperDeterminism && !tech.isRerollHaste
|
|
||||||
},
|
|
||||||
requires: "not superdeterminism or Ψ(t) collapse<br>at least 3 research",
|
|
||||||
effect() {
|
|
||||||
tech.renormalization = true;
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
tech.renormalization = false;
|
|
||||||
}
|
|
||||||
}, {
|
}, {
|
||||||
name: "decoherence",
|
name: "decoherence",
|
||||||
description: "<strong class='color-r'>researched</strong> or <strong>canceled</strong> <strong class='color-m'>tech</strong> won't <strong>reoccur</strong> <br>spawn <strong>5</strong> <strong class='color-r'>research</strong>",
|
description: "<strong class='color-r'>researched</strong> or <strong>canceled</strong> <strong class='color-m'>tech</strong> won't <strong>reoccur</strong> <br>spawn <strong>5</strong> <strong class='color-r'>research</strong>",
|
||||||
@@ -2200,6 +2288,22 @@
|
|||||||
tech.isBanish = false
|
tech.isBanish = false
|
||||||
powerUps.tech.banishLog = [] //reset banish log
|
powerUps.tech.banishLog = [] //reset banish log
|
||||||
}
|
}
|
||||||
|
}, {
|
||||||
|
name: "renormalization",
|
||||||
|
description: "using a <strong class='color-r'>research</strong> for <strong>any</strong> purpose<br>has a <strong>37%</strong> chance to spawn a <strong class='color-r'>research</strong>",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 1,
|
||||||
|
allowed() {
|
||||||
|
return (powerUps.research.count > 3 || build.isExperimentSelection) && !tech.isSuperDeterminism && !tech.isRerollHaste
|
||||||
|
},
|
||||||
|
requires: "not superdeterminism or Ψ(t) collapse<br>at least 4 research",
|
||||||
|
effect() {
|
||||||
|
tech.renormalization = true;
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.renormalization = false;
|
||||||
|
}
|
||||||
}, {
|
}, {
|
||||||
name: "perturbation theory",
|
name: "perturbation theory",
|
||||||
description: "<strong>66%</strong> decreased <strong><em>delay</em></strong> after firing<br>when you have no <strong class='color-r'>research</strong> in your inventory",
|
description: "<strong>66%</strong> decreased <strong><em>delay</em></strong> after firing<br>when you have no <strong class='color-r'>research</strong> in your inventory",
|
||||||
@@ -2319,7 +2423,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "meta-analysis",
|
name: "meta-analysis",
|
||||||
description: "if you choose a <strong>junk</strong> <strong class='color-m'>tech</strong> you instead get a <br>random non-junk <strong class='color-m'>tech</strong> and spawn <strong>2</strong> <strong class='color-r'>research</strong>",
|
description: "if you choose a <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> you instead get a <br>random normal <strong class='color-m'>tech</strong> and <strong>2</strong> <strong class='color-r'>research</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 2,
|
frequency: 2,
|
||||||
@@ -2336,7 +2440,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "replication",
|
name: "replication",
|
||||||
description: "<strong>7%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>add <strong>12</strong> junk <strong class='color-m'>tech</strong> to the potential pool",
|
description: "<strong>7%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>add <strong>12</strong> <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> to the potential pool",
|
||||||
maxCount: 9,
|
maxCount: 9,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 1,
|
frequency: 1,
|
||||||
@@ -2378,14 +2482,14 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "futures exchange",
|
name: "futures exchange",
|
||||||
description: "clicking <strong style = 'font-size:150%;'>×</strong> to cancel a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>adds <strong>4.5%</strong> power up <strong class='color-dup'>duplication</strong> chance",
|
description: "clicking <strong style = 'font-size:150%;'>×</strong> to <strong>cancel</strong> a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>adds <strong>4.5%</strong> power up <strong class='color-dup'>duplication</strong> chance",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 1,
|
frequency: 1,
|
||||||
allowed() {
|
allowed() {
|
||||||
return tech.duplicationChance() < 1 && !tech.isDeterminism && (level.levelsCleared < 5 || Math.random() < 0.5)
|
return tech.duplicationChance() < 1 && !tech.isDeterminism && level.levelsCleared < 5
|
||||||
},
|
},
|
||||||
requires: "below 100% duplication chance, not determinism",
|
requires: "below 100% duplication chance, below level 5, not determinism",
|
||||||
effect() {
|
effect() {
|
||||||
tech.isCancelDuplication = true
|
tech.isCancelDuplication = true
|
||||||
tech.cancelCount = 0
|
tech.cancelCount = 0
|
||||||
@@ -2546,7 +2650,7 @@
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
name: "dark patterns",
|
name: "dark patterns",
|
||||||
description: "reduce combat <strong>difficulty</strong> by <strong>1 level</strong><br>add <strong>18</strong> junk <strong class='color-m'>tech</strong> to the potential pool",
|
description: "reduce combat <strong>difficulty</strong> by <strong>1 level</strong><br>add <strong>18</strong> <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> to the potential pool",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 1,
|
frequency: 1,
|
||||||
@@ -2584,7 +2688,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "field technology",
|
name: "vector fields",
|
||||||
description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-f'>field</strong> <strong class='color-m'>tech</strong><br>spawn a <strong class='color-f'>field</strong>",
|
description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-f'>field</strong> <strong class='color-m'>tech</strong><br>spawn a <strong class='color-f'>field</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
@@ -2646,7 +2750,7 @@
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
name: "determinism",
|
name: "determinism",
|
||||||
description: "spawn <strong>5</strong> <strong class='color-m'>tech</strong><br><strong class='color-m'>tech</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong> have only <strong>1 choice</strong>",
|
description: "spawn <strong>5</strong> <strong class='color-m'>tech</strong>, but you have <strong>no cancel</strong><br>and <strong>1 choice</strong> for <strong class='color-m'>tech</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 1,
|
frequency: 1,
|
||||||
@@ -2666,7 +2770,7 @@
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
name: "superdeterminism",
|
name: "superdeterminism",
|
||||||
description: "spawn <strong>7</strong> <strong class='color-m'>tech</strong><br><strong class='color-r'>research</strong>, <strong class='color-g'>guns</strong>, and <strong class='color-f'>fields</strong> no longer <strong>spawn</strong>",
|
description: "spawn <strong>5</strong> <strong class='color-m'>tech</strong><br><strong class='color-r'>research</strong>, <strong class='color-g'>guns</strong>, and <strong class='color-f'>fields</strong> no longer <strong>spawn</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 3,
|
frequency: 3,
|
||||||
@@ -2732,108 +2836,6 @@
|
|||||||
tech.isRewindGun = false
|
tech.isRewindGun = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {
|
|
||||||
name: "incendiary ammunition",
|
|
||||||
description: "<strong>shotgun</strong>, <strong>super balls</strong>, and <strong>drones</strong><br>are loaded with <strong class='color-e'>explosives</strong>",
|
|
||||||
isGunTech: true,
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
frequency: 1,
|
|
||||||
allowed() {
|
|
||||||
return ((m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isMissileField || tech.isIceField)) || tech.haveGunCheck("drones") || tech.haveGunCheck("super balls") || tech.haveGunCheck("shotgun")) && !tech.isNailShot
|
|
||||||
},
|
|
||||||
requires: "drones, super balls, shotgun",
|
|
||||||
effect() {
|
|
||||||
tech.isIncendiary = true
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
tech.isIncendiary = false;
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
name: "fragmentation",
|
|
||||||
description: "some <strong class='color-e'>detonations</strong> and collisions eject <strong>nails</strong><br><em style = 'font-size: 90%'>blocks, rail gun, grenades, missiles, shotgun slugs</em>",
|
|
||||||
isGunTech: true,
|
|
||||||
maxCount: 9,
|
|
||||||
count: 0,
|
|
||||||
frequency: 1,
|
|
||||||
allowed() {
|
|
||||||
return (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("missiles") || tech.haveGunCheck("rail gun") || (tech.haveGunCheck("shotgun") && tech.isSlugShot) || tech.throwChargeRate > 1
|
|
||||||
},
|
|
||||||
requires: "grenades, missiles, rail gun, shotgun slugs, or mass driver",
|
|
||||||
effect() {
|
|
||||||
tech.fragments++
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
tech.fragments = 0
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
name: "superfluidity",
|
|
||||||
description: "<strong class='color-s'>freeze</strong> effects are applied to a small area",
|
|
||||||
isGunTech: true,
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
frequency: 1,
|
|
||||||
allowed() {
|
|
||||||
return tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField
|
|
||||||
},
|
|
||||||
requires: "a freeze effect",
|
|
||||||
effect() {
|
|
||||||
tech.isAoESlow = true
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
tech.isAoESlow = false
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
name: "radioactive contamination",
|
|
||||||
description: "after a mob or shield <strong>dies</strong>,<br> leftover <strong class='color-p'>radiation</strong> <strong>spreads</strong> to a nearby mob",
|
|
||||||
isGunTech: true,
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
frequency: 1,
|
|
||||||
allowed() {
|
|
||||||
return tech.isNailRadiation || tech.isWormholeDamage || tech.isNeutronBomb || tech.isExplodeRadio
|
|
||||||
},
|
|
||||||
requires: "radiation damage source",
|
|
||||||
effect() {
|
|
||||||
tech.isRadioactive = true
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
tech.isRadioactive = false
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
name: "anti-shear topology",
|
|
||||||
description: "some <strong>bullets</strong> last <strong>30% longer</strong><br><em style = 'font-size: 83%'>drones, spores, missiles, foam, wave, neutron</em>",
|
|
||||||
isGunTech: true,
|
|
||||||
maxCount: 3,
|
|
||||||
count: 0,
|
|
||||||
frequency: 1,
|
|
||||||
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
|
|
||||||
},
|
|
||||||
requires: "drones, spores, missiles, foam<br>wave beam, neutron bomb",
|
|
||||||
effect() {
|
|
||||||
tech.isBulletsLastLonger += 0.3
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
tech.isBulletsLastLonger = 1;
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
name: "microstates",
|
|
||||||
description: "increase <strong class='color-d'>damage</strong> by <strong>4%</strong><br>for every <strong>10</strong> active <strong>bullets</strong>",
|
|
||||||
isGunTech: true,
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
frequency: 1,
|
|
||||||
allowed() {
|
|
||||||
return tech.isBulletsLastLonger > 1
|
|
||||||
},
|
|
||||||
requires: "anti-shear topology",
|
|
||||||
effect() {
|
|
||||||
tech.isDamageFromBulletCount = true
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
tech.isDamageFromBulletCount = false
|
|
||||||
}
|
|
||||||
}, {
|
}, {
|
||||||
name: "needle gun",
|
name: "needle gun",
|
||||||
description: "<strong>nail gun</strong> fires <strong>3</strong> mob piercing <strong>needles</strong><br>requires <strong>3</strong> times more <strong class='color-g'>ammo</strong>",
|
description: "<strong>nail gun</strong> fires <strong>3</strong> mob piercing <strong>needles</strong><br>requires <strong>3</strong> times more <strong class='color-g'>ammo</strong>",
|
||||||
@@ -2872,7 +2874,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
name: "ceramic needle",
|
name: "ceramic needles",
|
||||||
description: `your <strong>needles</strong> pierce <strong>shields</strong><br>directly <strong class='color-d'>damaging</strong> shielded mobs`,
|
description: `your <strong>needles</strong> pierce <strong>shields</strong><br>directly <strong class='color-d'>damaging</strong> shielded mobs`,
|
||||||
isGunTech: true,
|
isGunTech: true,
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
@@ -3600,6 +3602,31 @@
|
|||||||
remove() {
|
remove() {
|
||||||
tech.isDroneGrab = false
|
tech.isDroneGrab = false
|
||||||
}
|
}
|
||||||
|
}, {
|
||||||
|
name: "planned obsolescence",
|
||||||
|
description: "reduce all <strong>drone</strong> production costs by <strong>300%</strong><br>reduce the average <strong>drone</strong> lifetime by <strong>53%</strong>",
|
||||||
|
isGunTech: true,
|
||||||
|
maxCount: 3,
|
||||||
|
count: 0,
|
||||||
|
frequency: 1,
|
||||||
|
allowed() {
|
||||||
|
return tech.haveGunCheck("drones") || (m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isMissileField || tech.isIceField))
|
||||||
|
},
|
||||||
|
requires: "drones",
|
||||||
|
effect() {
|
||||||
|
tech.droneCycleReduction = Math.pow(0.47, this.count)
|
||||||
|
tech.droneEnergyReduction = Math.pow(0.33, this.count)
|
||||||
|
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||||
|
if (b.guns[i].name === "drones") b.guns[i].ammoPack = b.guns[i].defaultAmmoPack * Math.pow(3, this.count)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
tech.droneCycleReduction = 1
|
||||||
|
tech.droneEnergyReduction = 1
|
||||||
|
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||||
|
if (b.guns[i].name === "drones") b.guns[i].ammoPack = b.guns[i].defaultAmmoPack
|
||||||
|
}
|
||||||
|
}
|
||||||
}, {
|
}, {
|
||||||
name: "necrophoresis",
|
name: "necrophoresis",
|
||||||
description: "<strong>foam</strong> bubbles grow and split into 3 <strong>copies</strong><br> when the mob they are stuck to <strong>dies</strong>",
|
description: "<strong>foam</strong> bubbles grow and split into 3 <strong>copies</strong><br> when the mob they are stuck to <strong>dies</strong>",
|
||||||
@@ -4845,7 +4872,7 @@
|
|||||||
remove() {}
|
remove() {}
|
||||||
}, {
|
}, {
|
||||||
name: "defragment",
|
name: "defragment",
|
||||||
description: "set the <strong class='flicker'>frequency</strong> of finding junk <strong class='color-m'>tech</strong> to zero",
|
description: "set the <strong class='flicker'>frequency</strong> of finding <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> to zero",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 0,
|
frequency: 0,
|
||||||
@@ -5021,7 +5048,7 @@
|
|||||||
remove() {}
|
remove() {}
|
||||||
}, {
|
}, {
|
||||||
name: "expert system",
|
name: "expert system",
|
||||||
description: "spawn a <strong class='color-m'>tech</strong> power up<br>add <strong>64</strong> junk <strong class='color-m'>tech</strong> to the potential pool",
|
description: "spawn a <strong class='color-m'>tech</strong> power up<br>add <strong>64</strong> <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> to the potential pool",
|
||||||
maxCount: 9,
|
maxCount: 9,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 0,
|
frequency: 0,
|
||||||
@@ -5795,5 +5822,7 @@
|
|||||||
isFlipFlopDamage: null,
|
isFlipFlopDamage: null,
|
||||||
isFlipFlopEnergy: null,
|
isFlipFlopEnergy: null,
|
||||||
isMetaAnalysis: null,
|
isMetaAnalysis: null,
|
||||||
isFoamAttract: null
|
isFoamAttract: null,
|
||||||
|
droneCycleReduction: null,
|
||||||
|
droneEnergyReduction: null
|
||||||
}
|
}
|
||||||
@@ -604,6 +604,13 @@ summary {
|
|||||||
font-weight: 100;
|
font-weight: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.color-j {
|
||||||
|
letter-spacing: 1px;
|
||||||
|
/* font-weight: 100; */
|
||||||
|
font-family: Lucida Console, Courier, monospace;
|
||||||
|
/* transform: rotate(-90deg); */
|
||||||
|
}
|
||||||
|
|
||||||
/* .color-rewind {
|
/* .color-rewind {
|
||||||
background-image: linear-gradient(to left, #fff, #bbb);
|
background-image: linear-gradient(to left, #fff, #bbb);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
|||||||
38
todo.txt
38
todo.txt
@@ -1,16 +1,19 @@
|
|||||||
******************************************************** NEXT PATCH ********************************************************
|
******************************************************** NEXT PATCH ********************************************************
|
||||||
|
|
||||||
tech: electrostatic induction - foam bullets are attracted to nearby mobs
|
bug fixes
|
||||||
|
strong anthropic principle does 0.03599% more damage
|
||||||
|
spores can stick to rotating blocks now
|
||||||
|
probably fixed the new wormhole field while targeting a block -> crouch lock bug
|
||||||
|
ceramic needles now correctly bypass shields
|
||||||
|
|
||||||
portals on perplex map, now remove blocks that fall in
|
needles fire 3 at a time with a short delay and no spread
|
||||||
new community map! coliseum by iNoobBoi
|
|
||||||
|
|
||||||
a few more tech can be refunded properly
|
tech: planned obsolescence - 3x drone ammo, 1/3 drone nano-scale energy cost, but 53% reduced drone life span
|
||||||
nonRefundable tech don't show up in the list of tech you have
|
|
||||||
|
|
||||||
******************************************************** BUGS ********************************************************
|
******************************************************** BUGS ********************************************************
|
||||||
|
|
||||||
fix issue where you have to press z once to get copy to work for simulation.enableConstructMode()
|
you have to press z once to get copy to work for simulation.enableConstructMode() sometimes
|
||||||
|
not sure how to reproduce, but it happens often on the first draw
|
||||||
|
|
||||||
mouse event e.which is deprecated
|
mouse event e.which is deprecated
|
||||||
|
|
||||||
@@ -22,9 +25,6 @@ fix door.isOpen actually meaning isClosed?
|
|||||||
wasn't able to understand bug after extensive testing
|
wasn't able to understand bug after extensive testing
|
||||||
had tech: complex spin statistics
|
had tech: complex spin statistics
|
||||||
|
|
||||||
(a few times) wormhole teleportation can leave the player in a stuck jump state
|
|
||||||
seems to be easily fixed, by porting, firing or something
|
|
||||||
|
|
||||||
(always) make it so that when you are immune to harm you can either jump on mobs or you pass through them
|
(always) make it so that when you are immune to harm you can either jump on mobs or you pass through them
|
||||||
|
|
||||||
(always) is there a way to check if the player is stuck inside the map or block
|
(always) is there a way to check if the player is stuck inside the map or block
|
||||||
@@ -41,6 +41,20 @@ fix door.isOpen actually meaning isClosed?
|
|||||||
|
|
||||||
******************************************************** TODO ********************************************************
|
******************************************************** TODO ********************************************************
|
||||||
|
|
||||||
|
mob vision: look at player history
|
||||||
|
build a new type of attraction for mobs
|
||||||
|
if mobs can't see player, they check to see if they can see where the player was in the history
|
||||||
|
if mobs can't see player, they could check to see if they can find player in the past
|
||||||
|
https://abitawake.com/news/articles/enemy-ai-chasing-a-player-without-navigation2d-or-a-star-pathfinding
|
||||||
|
|
||||||
|
tech: chitin - take 50% less damage, reduce harm reduction by 5% after each collision
|
||||||
|
|
||||||
|
Mob: "Tentacle": Sits on wall. Is a black blob. When you get near it, reaches out and grabs you, similar to wires. Does not deal damage.
|
||||||
|
maybe it could be immune to damage? but it is spawned by an actual mob
|
||||||
|
|
||||||
|
wormhole, or CPT tech: after taking damage teleport in direction of mouse
|
||||||
|
after collision
|
||||||
|
|
||||||
mob sniper: draw aim graphics before fire
|
mob sniper: draw aim graphics before fire
|
||||||
|
|
||||||
tech laser: photon - laser, but it can only move 100 pixels a cycle
|
tech laser: photon - laser, but it can only move 100 pixels a cycle
|
||||||
@@ -153,12 +167,6 @@ tech pilot wave: antigravity - blocks have no gravity for a few seconds after ex
|
|||||||
maybe they bounce too?
|
maybe they bounce too?
|
||||||
maybe they explode?
|
maybe they explode?
|
||||||
|
|
||||||
mob vision: look at player history
|
|
||||||
build a new type of attraction for mobs
|
|
||||||
if mobs can't see player, they check to see if they can see where the player was in the history
|
|
||||||
if mobs can't see player, they could check to see if they can find player in the past
|
|
||||||
https://abitawake.com/news/articles/enemy-ai-chasing-a-player-without-navigation2d-or-a-star-pathfinding
|
|
||||||
|
|
||||||
wormhole - make it clear when the wormhole can and can't teleport to a location before the player clicks
|
wormhole - make it clear when the wormhole can and can't teleport to a location before the player clicks
|
||||||
|
|
||||||
flavor - your bullets destroy blocks
|
flavor - your bullets destroy blocks
|
||||||
|
|||||||
Reference in New Issue
Block a user