chain reaction
tech: chain reaction now requires vacuum bomb, but it increases grenade radius and damage 33% (and makes blocks explode) needle gun fires with more regular timing needles despawn 1.5s faster, for performance reasons intro level power ups are relocated tech: decomposers renamed necrophage if mobs are one shotted before they see you, they no longer alert nearby mobs clicking on a mob in testing will log that mob in console
This commit is contained in:
48
js/bullet.js
48
js/bullet.js
@@ -774,7 +774,7 @@ const b = {
|
||||
const me = bullet.length;
|
||||
bullet[me] = Bodies.circle(where.x, where.y, 15, b.fireAttributes(angle, false));
|
||||
Matter.Body.setDensity(bullet[me], 0.0005);
|
||||
bullet[me].explodeRad = 350 + Math.floor(Math.random() * 50);;
|
||||
bullet[me].explodeRad = 333 + Math.floor(Math.random() * 50) + tech.isBlockExplode * 100
|
||||
bullet[me].onEnd = function() {
|
||||
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
|
||||
if (tech.fragments) b.targetedNail(this.position, tech.fragments * 4)
|
||||
@@ -850,7 +850,7 @@ const b = {
|
||||
const me = bullet.length;
|
||||
bullet[me] = Bodies.circle(where.x, where.y, 20, b.fireAttributes(angle, false));
|
||||
Matter.Body.setDensity(bullet[me], 0.0003);
|
||||
bullet[me].explodeRad = 325 + Math.floor(Math.random() * 50);;
|
||||
bullet[me].explodeRad = 333 + Math.floor(Math.random() * 50) + tech.isBlockExplode * 100
|
||||
bullet[me].onEnd = function() {
|
||||
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
|
||||
if (tech.fragments) b.targetedNail(this.position, tech.fragments * 6)
|
||||
@@ -1260,7 +1260,7 @@ const b = {
|
||||
Matter.Body.setPosition(this, Vector.add(this.position, q[i].velocity)) //move with the medium
|
||||
let dmg = this.dmg / Math.min(10, q[i].mass)
|
||||
q[i].damage(dmg);
|
||||
q[i].foundPlayer();
|
||||
if (q[i].alive) q[i].foundPlayer();
|
||||
//removed to improve performance
|
||||
// simulation.drawList.push({ //add dmg to draw queue
|
||||
// x: this.position.x,
|
||||
@@ -2764,7 +2764,7 @@ const b = {
|
||||
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].endCycle = simulation.cycle + 100;
|
||||
bullet[me].immuneList = []
|
||||
bullet[me].do = function() {
|
||||
const whom = Matter.Query.collides(this, mob)
|
||||
@@ -2784,7 +2784,6 @@ const b = {
|
||||
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();
|
||||
let dmg = b.dmgScale * 6
|
||||
if (tech.isNailRadiation) {
|
||||
mobs.statusDoT(who, tech.isFastRadiation ? 12 : 3, tech.isSlowRadiation ? 240 : (tech.isFastRadiation ? 30 : 120)) // one tick every 30 cycles
|
||||
@@ -2792,6 +2791,7 @@ const b = {
|
||||
}
|
||||
if (tech.isCrit && who.isStunned) dmg *= 4
|
||||
who.damage(dmg, tech.isNeedleShieldPierce);
|
||||
if (who.alive) who.foundPlayer();
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: this.position.x,
|
||||
y: this.position.y,
|
||||
@@ -3008,7 +3008,7 @@ const b = {
|
||||
// const dmg = 0.5 * b.dmgScale * (this.isUpgraded ? 2.5 : 1)
|
||||
const dmg = 0.5 * b.dmgScale
|
||||
q[i].damage(dmg);
|
||||
q[i].foundPlayer();
|
||||
if (q[i].alive) q[i].foundPlayer();
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: this.position.x,
|
||||
y: this.position.y,
|
||||
@@ -3606,7 +3606,7 @@ const b = {
|
||||
mobs.statusStun(q[i], 180)
|
||||
const dmg = 0.5 * b.dmgScale * (this.isUpgraded ? 3.5 : 1) * (tech.isCrit ? 4 : 1)
|
||||
q[i].damage(dmg);
|
||||
q[i].foundPlayer();
|
||||
if (q[i].alive) q[i].foundPlayer();
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: this.position.x,
|
||||
y: this.position.y,
|
||||
@@ -3686,24 +3686,38 @@ const b = {
|
||||
},
|
||||
fireNeedles() {
|
||||
if (m.crouch) {
|
||||
m.fireCDcycle = m.cycle + 45 * b.fireCDscale; // cool down
|
||||
m.fireCDcycle = m.cycle + 38 * b.fireCDscale; // cool down
|
||||
b.needle()
|
||||
for (let i = 1; i < 4; i++) { //4 total needles
|
||||
setTimeout(() => { if (!simulation.paused) b.needle() }, 60 * i);
|
||||
|
||||
function cycle() {
|
||||
if (simulation.paused || m.isBodiesAsleep) { requestAnimationFrame(cycle) } else {
|
||||
count++
|
||||
if (count % 2) b.needle()
|
||||
if (count < 5 && m.alive) requestAnimationFrame(cycle);
|
||||
}
|
||||
}
|
||||
let count = -1
|
||||
requestAnimationFrame(cycle);
|
||||
} else {
|
||||
m.fireCDcycle = m.cycle + 25 * b.fireCDscale; // cool down
|
||||
m.fireCDcycle = m.cycle + 28 * b.fireCDscale; // cool down
|
||||
b.needle()
|
||||
for (let i = 1; i < 3; i++) { //3 total needles
|
||||
setTimeout(() => { if (!simulation.paused) b.needle() }, 60 * i);
|
||||
|
||||
function cycle() {
|
||||
if (simulation.paused || m.isBodiesAsleep) { requestAnimationFrame(cycle) } else {
|
||||
count++
|
||||
if (count % 2) b.needle()
|
||||
if (count < 3 && m.alive) requestAnimationFrame(cycle);
|
||||
}
|
||||
}
|
||||
let count = -1
|
||||
requestAnimationFrame(cycle);
|
||||
}
|
||||
},
|
||||
fireRivets() {
|
||||
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 25 : 17) * b.fireCDscale); // cool down
|
||||
|
||||
const me = bullet.length;
|
||||
const size = tech.rivetSize * 7.5
|
||||
const size = tech.rivetSize * 8
|
||||
bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 5 * size, size, b.fireAttributes(m.angle));
|
||||
bullet[me].dmg = tech.isNailRadiation ? 0 : 2.75
|
||||
Matter.Body.setDensity(bullet[me], 0.002);
|
||||
@@ -3958,7 +3972,7 @@ const b = {
|
||||
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 number = 11 * (tech.isShotgunReversed ? 1.6 : 1)
|
||||
const spread = (m.crouch ? 0.03 : 0.05)
|
||||
let angle = m.angle - (number - 1) * spread * 0.5
|
||||
for (let i = 0; i < number; i++) {
|
||||
@@ -4351,7 +4365,7 @@ const b = {
|
||||
for (let i = 0; i < q.length; i++) {
|
||||
let dmg = this.dmg // / Math.min(10, q[i].mass)
|
||||
q[i].damage(dmg);
|
||||
q[i].foundPlayer();
|
||||
if (q[i].alive) q[i].foundPlayer();
|
||||
Matter.Body.setVelocity(q[i], Vector.mult(q[i].velocity, 0.9))
|
||||
|
||||
this.endCycle = 0; //bullet ends cycle after doing damage
|
||||
@@ -4417,7 +4431,7 @@ const b = {
|
||||
name: "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,
|
||||
ammoPack: 3.5,
|
||||
ammoPack: 4,
|
||||
have: false,
|
||||
fireCycle: 0,
|
||||
ammoLoaded: 0,
|
||||
|
||||
@@ -177,8 +177,8 @@ function collisionChecks(event) {
|
||||
obj.beforeDmg(mob[k]); //some bullets do actions when they hits things, like despawn //forces don't seem to work here
|
||||
let dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)))
|
||||
if (tech.isCrit && mob[k].isStunned) dmg *= 4
|
||||
mob[k].foundPlayer();
|
||||
mob[k].damage(dmg);
|
||||
if (mob[k].alive) mob[k].foundPlayer();
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: pairs[i].activeContacts[0].vertex.x,
|
||||
y: pairs[i].activeContacts[0].vertex.y,
|
||||
@@ -207,7 +207,7 @@ function collisionChecks(event) {
|
||||
|
||||
const stunTime = dmg / Math.sqrt(obj.mass)
|
||||
if (stunTime > 0.5) mobs.statusStun(mob[k], 60 + 60 * Math.sqrt(stunTime))
|
||||
if (mob[k].distanceToPlayer2() < 1000000 && !m.isCloak) mob[k].foundPlayer();
|
||||
if (mob[k].alive && mob[k].distanceToPlayer2() < 1000000 && !m.isCloak) mob[k].foundPlayer();
|
||||
if (tech.fragments && obj.speed > 10 && !obj.hasFragmented) {
|
||||
obj.hasFragmented = true;
|
||||
b.targetedNail(obj.position, tech.fragments * 4)
|
||||
|
||||
@@ -494,8 +494,10 @@ const build = {
|
||||
count = 0;
|
||||
for (let i = 0; i < tech.tech.length; i++) {
|
||||
for (let j = 0; j < tech.tech[i].count; j++) {
|
||||
url += `&tech${count}=${encodeURIComponent(tech.tech[i].name.trim())}`
|
||||
count++
|
||||
if (!tech.tech[i].isLore && !tech.tech[i].isJunk && !tech.tech[i].isNonRefundable && !tech.tech[i].isExperimentHide) {
|
||||
url += `&tech${count}=${encodeURIComponent(tech.tech[i].name.trim())}`
|
||||
count++
|
||||
}
|
||||
}
|
||||
}
|
||||
url += `&field=${encodeURIComponent(m.fieldUpgrades[m.fieldMode].name.trim())}`
|
||||
|
||||
85
js/level.js
85
js/level.js
@@ -11,13 +11,14 @@ const level = {
|
||||
levels: [],
|
||||
start() {
|
||||
if (level.levelsCleared === 0) { //this code only runs on the first level
|
||||
// localSettings.levelsClearedLastGame = 10
|
||||
// simulation.enableConstructMode() //used to build maps in testing mode
|
||||
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
|
||||
// simulation.isHorizontalFlipped = true
|
||||
// tech.isFieldFree = true
|
||||
// m.setField("perfect diamagnetism")
|
||||
// b.giveGuns("shotgun")
|
||||
// tech.giveTech("Noether violation")
|
||||
// m.setField("time dilation")
|
||||
// b.giveGuns("nail gun")
|
||||
// tech.giveTech("needle gun")
|
||||
// b.giveGuns("wave beam")
|
||||
// tech.giveTech("Lenz's law")
|
||||
// for (let i = 0; i < 3; i++) tech.giveTech("packet length")
|
||||
@@ -2105,6 +2106,7 @@ const level = {
|
||||
}
|
||||
|
||||
// const hazardSlime = level.hazard(-1800, 150, 3600, 650, 0.004, "hsla(160, 100%, 35%,0.75)")
|
||||
level.isHazardRise = false //this is set to true to make the slime rise up
|
||||
const hazardSlime = level.hazard(-1800, -800, 3600, 1600, 0.004, "hsla(160, 100%, 35%,0.75)")
|
||||
hazardSlime.height -= 950
|
||||
hazardSlime.min.y += 950
|
||||
@@ -2454,6 +2456,39 @@ const level = {
|
||||
}
|
||||
},
|
||||
intro() {
|
||||
if (level.levelsCleared === 0) { //if this is the 1st level of the game
|
||||
// powerUps.spawn(2500, -50, "research", false);
|
||||
powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070, "research", false);
|
||||
powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070 - 25, "heal", false);
|
||||
powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070 - 75, "heal", false);
|
||||
powerUps.spawnStartingPowerUps(2095 + 15 * (Math.random() - 0.5), -2070 - 125);
|
||||
if (localSettings.levelsClearedLastGame < 3) {
|
||||
if (!simulation.isCheating && !m.isShipMode) {
|
||||
spawn.wireFoot();
|
||||
spawn.wireFootLeft();
|
||||
spawn.wireKnee();
|
||||
spawn.wireKneeLeft();
|
||||
spawn.wireHead();
|
||||
// for (let i = 0; i < 3; i++) powerUps.spawn(2095, -1220 - 50 * i, "tech", false); //unavailable tech spawns
|
||||
// spawn.mapRect(2000, -1025, 200, 25);
|
||||
}
|
||||
} else {
|
||||
simulation.trails()
|
||||
//bonus power ups for clearing runs in the last game
|
||||
if (!simulation.isCheating && localSettings.levelsClearedLastGame > 1) {
|
||||
for (let i = 0; i < localSettings.levelsClearedLastGame / 3; i++) powerUps.spawn(2095 + 2 * Math.random(), -1270 - 50 * i, "tech", false); //spawn a tech for levels cleared in last game
|
||||
simulation.makeTextLog(`for (let i <span class='color-symbol'>=</span> 0; i <span class='color-symbol'><</span> localSettings.levelsClearedLastGame <span class='color-symbol'>/</span> 3; i<span class='color-symbol'>++</span>)`);
|
||||
simulation.makeTextLog(`{ powerUps.spawn(m.pos.x, m.pos.y, "tech") <em>//simulation superposition</em>}`);
|
||||
localSettings.levelsClearedLastGame = 0 //after getting bonus power ups reset run history
|
||||
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < 60; i++) {
|
||||
setTimeout(() => { spawn.sneaker(2100, -1500 - 50 * i); }, 2000 + 500 * i);
|
||||
}
|
||||
}
|
||||
|
||||
level.custom = () => {
|
||||
//draw binary number
|
||||
const binary = (localSettings.runCount >>> 0).toString(2)
|
||||
@@ -2611,6 +2646,11 @@ const level = {
|
||||
//exit room glow
|
||||
ctx.fillStyle = "rgba(0,255,255,0.05)"
|
||||
ctx.fillRect(2600, -600, 400, 300)
|
||||
//draw shade for ceiling tech
|
||||
ctx.fillStyle = "rgba(68, 68, 68,0.95)"
|
||||
ctx.fillRect(2030, -2800, 150, 1800);
|
||||
ctx.fillStyle = "rgba(68, 68, 68,0.95)"
|
||||
ctx.fillRect(2030, 0, 150, 1800);
|
||||
};
|
||||
|
||||
level.setPosToSpawn(460, -100); //normal spawn
|
||||
@@ -2623,10 +2663,26 @@ const level = {
|
||||
simulation.zoomTransition(level.defaultZoom, 1)
|
||||
document.body.style.backgroundColor = "#e1e1e1";
|
||||
|
||||
spawn.mapRect(-250, 0, 3600, 1800); //ground
|
||||
spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
|
||||
spawn.mapRect(3000, -2800, 2600, 4600); //right wall
|
||||
spawn.mapRect(-250, -2800, 3600, 1800); //roof
|
||||
|
||||
// spawn.mapRect(-250, 0, 3600, 1800); //ground
|
||||
spawn.mapRect(-250, 0, 2300, 1800); //split roof
|
||||
spawn.mapRect(2150, 0, 1200, 1800); //split roof
|
||||
spawn.mapRect(2025, -3, 25, 15); //lip on power up chamber
|
||||
spawn.mapRect(2150, -3, 25, 15); //lip on power up chamber
|
||||
spawn.mapRect(2025, 0, 150, 50);
|
||||
|
||||
// spawn.mapRect(-250, -2800, 3600, 1800); //roof
|
||||
spawn.mapRect(-250, -2800, 2300, 1800); //split roof
|
||||
map[map.length - 1].friction = 0
|
||||
map[map.length - 1].frictionStatic = 0
|
||||
spawn.mapRect(2150, -2800, 1200, 1800); //split roof
|
||||
map[map.length - 1].friction = 0
|
||||
map[map.length - 1].frictionStatic = 0
|
||||
spawn.mapRect(2025, -1010, 25, 13); //lip on power up chamber
|
||||
spawn.mapRect(2150, -1010, 25, 13); //lip on power up chamber
|
||||
|
||||
spawn.mapRect(2600, -300, 500, 500); //exit shelf
|
||||
spawn.mapRect(2600, -1200, 500, 600); //exit roof
|
||||
spawn.mapRect(-95, -1100, 80, 110); //wire source
|
||||
@@ -2635,25 +2691,6 @@ const level = {
|
||||
spawn.bodyRect(2425, -120, 70, 50);
|
||||
spawn.bodyRect(2400, -100, 100, 60);
|
||||
spawn.bodyRect(2500, -150, 100, 150); //exit step
|
||||
|
||||
// localSettings.levelsClearedLastGame = 20
|
||||
if (level.levelsCleared === 0) {
|
||||
// powerUps.spawn(2500, -50, "research", false);
|
||||
powerUps.spawn(1900, -50, "heal", false);
|
||||
powerUps.spawn(2050, -50, "heal", false);
|
||||
if (localSettings.levelsClearedLastGame < 6) {
|
||||
if (!simulation.isCheating && !m.isShipMode) {
|
||||
spawn.wireFoot();
|
||||
spawn.wireFootLeft();
|
||||
spawn.wireKnee();
|
||||
spawn.wireKneeLeft();
|
||||
spawn.wireHead();
|
||||
}
|
||||
} else {
|
||||
simulation.trails()
|
||||
}
|
||||
}
|
||||
powerUps.spawnStartingPowerUps(2300, -50);
|
||||
},
|
||||
testChamber() {
|
||||
level.setPosToSpawn(0, -50); //lower start
|
||||
|
||||
@@ -1054,7 +1054,9 @@ const mobs = {
|
||||
this.health -= dmg
|
||||
//this.fill = this.color + this.health + ')';
|
||||
this.onDamage(dmg); //custom damage effects
|
||||
if (this.health < 0.05 && this.alive) this.death();
|
||||
if (this.health < 0.05 && this.alive) {
|
||||
this.death();
|
||||
}
|
||||
}
|
||||
},
|
||||
onDamage() {
|
||||
|
||||
@@ -3208,8 +3208,8 @@ const m = {
|
||||
obj.beforeDmg(mob[k]); //some bullets do actions when they hits things, like despawn //forces don't seem to work here
|
||||
let dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)))
|
||||
if (tech.isCrit && mob[k].isStunned) dmg *= 4
|
||||
mob[k].foundPlayer();
|
||||
mob[k].damage(dmg);
|
||||
if (mob[k].alive) mob[k].foundPlayer();
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: pairs[i].activeContacts[0].vertex.x,
|
||||
y: pairs[i].activeContacts[0].vertex.y,
|
||||
@@ -3239,7 +3239,7 @@ const m = {
|
||||
|
||||
const stunTime = dmg / Math.sqrt(obj.mass)
|
||||
if (stunTime > 0.5) mobs.statusStun(mob[k], 30 + 60 * Math.sqrt(stunTime))
|
||||
if (mob[k].distanceToPlayer2() < 1000000 && !m.isCloak) mob[k].foundPlayer();
|
||||
if (mob[k].alive && mob[k].distanceToPlayer2() < 1000000 && !m.isCloak) mob[k].foundPlayer();
|
||||
if (tech.fragments && obj.speed > 10 && !obj.hasFragmented) {
|
||||
obj.hasFragmented = true;
|
||||
b.targetedNail(obj.position, tech.fragments * 4)
|
||||
|
||||
@@ -175,7 +175,7 @@ const powerUps = {
|
||||
tech.maxDuplicationEvent()
|
||||
}
|
||||
if (tech.isCancelRerolls) {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
for (let i = 0; i < 9; i++) {
|
||||
let spawnType = (m.health < 0.25 || tech.isEnergyNoAmmo) ? "heal" : "ammo"
|
||||
if (Math.random() < 0.33) {
|
||||
spawnType = "heal"
|
||||
@@ -780,15 +780,6 @@ const powerUps = {
|
||||
spawnStartingPowerUps(x, y) { //used for map specific power ups, mostly to give player a starting gun
|
||||
if (level.levelsCleared < 4) { //runs 4 times on all difficulty levels
|
||||
if (level.levelsCleared > 1) powerUps.spawn(x, y, "tech")
|
||||
|
||||
//bonus power ups for clearing runs in the last game
|
||||
if (level.levelsCleared === 0 && !simulation.isCheating && localSettings.levelsClearedLastGame > 1) {
|
||||
for (let i = 0; i < localSettings.levelsClearedLastGame / 3; i++) powerUps.spawn(m.pos.x, m.pos.y, "tech", false); //spawn a tech for levels cleared in last game
|
||||
simulation.makeTextLog(`for (let i <span class='color-symbol'>=</span> 0; i <span class='color-symbol'><</span> localSettings.levelsClearedLastGame <span class='color-symbol'>/</span> 3; i<span class='color-symbol'>++</span>)`);
|
||||
simulation.makeTextLog(`{ powerUps.spawn(m.pos.x, m.pos.y, "tech") <em>//simulation superposition</em>}`);
|
||||
localSettings.levelsClearedLastGame = 0 //after getting bonus power ups reset run history
|
||||
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
||||
}
|
||||
if (b.inventory.length === 0) {
|
||||
powerUps.spawn(x, y, "gun", false); //first gun
|
||||
} else if (tech.totalCount === 0) { //first tech
|
||||
@@ -886,9 +877,7 @@ const powerUps = {
|
||||
name: target.name,
|
||||
size: size
|
||||
});
|
||||
if (mode) {
|
||||
powerUp[index].mode = mode
|
||||
}
|
||||
if (mode) powerUp[index].mode = mode
|
||||
if (moving) {
|
||||
Matter.Body.setVelocity(powerUp[index], {
|
||||
x: (Math.random() - 0.5) * 15,
|
||||
|
||||
@@ -57,6 +57,14 @@ const simulation = {
|
||||
m.hold();
|
||||
level.customTopLayer();
|
||||
simulation.draw.wireFrame();
|
||||
if (input.fire && m.fireCDcycle < m.cycle) {
|
||||
m.fireCDcycle = m.cycle + 15; //fire cooldown
|
||||
for (let i = 0, len = mob.length; i < len; i++) {
|
||||
if (Vector.magnitudeSquared(Vector.sub(mob[i].position, simulation.mouseInGame)) < mob[i].radius * mob[i].radius) {
|
||||
console.log(mob[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
simulation.draw.cons();
|
||||
simulation.draw.testing();
|
||||
simulation.drawCircle();
|
||||
|
||||
74
js/tech.js
74
js/tech.js
@@ -180,7 +180,7 @@
|
||||
if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage
|
||||
if (tech.isEnergyDamage) dmg *= 1 + m.energy / 9;
|
||||
if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.005
|
||||
if (tech.isRerollDamage) dmg *= 1 + 0.042 * powerUps.research.count
|
||||
if (tech.isRerollDamage) dmg *= 1 + 0.04 * powerUps.research.count
|
||||
if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.23
|
||||
if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2
|
||||
if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.66, player.speed * 0.0165)
|
||||
@@ -188,12 +188,12 @@
|
||||
return dmg * tech.slowFire * tech.aimDamage
|
||||
},
|
||||
duplicationChance() {
|
||||
return (tech.isPowerUpsVanish ? 0.2 : 0) + (tech.isStimulatedEmission ? 0.22 : 0) + tech.cancelCount * 0.05 + tech.duplicateChance + m.duplicateChance + tech.wormDuplicate + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0)
|
||||
return (tech.isPowerUpsVanish ? 0.2 : 0) + (tech.isStimulatedEmission ? 0.22 : 0) + tech.cancelCount * 0.048 + tech.duplicateChance + m.duplicateChance + tech.wormDuplicate + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0)
|
||||
},
|
||||
maxDuplicationEvent() {
|
||||
if (tech.is100Duplicate && tech.duplicationChance() > 0.99) {
|
||||
tech.is100Duplicate = false
|
||||
const range = 600
|
||||
const range = 450
|
||||
spawn.randomLevelBoss(m.pos.x + range, m.pos.y, spawn.nonCollideBossList);
|
||||
spawn.randomLevelBoss(m.pos.x, m.pos.y + range, spawn.nonCollideBossList);
|
||||
spawn.randomLevelBoss(m.pos.x - range, m.pos.y, spawn.nonCollideBossList);
|
||||
@@ -767,7 +767,7 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.explosiveRadius === 1 && !tech.isSmallExplosion && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion)
|
||||
return !tech.isBlockExplode && tech.explosiveRadius === 1 && !tech.isSmallExplosion && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion)
|
||||
},
|
||||
requires: "an explosive damage source, not ammonium nitrate or nitroglycerin",
|
||||
effect: () => {
|
||||
@@ -785,7 +785,7 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion)
|
||||
return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion)
|
||||
},
|
||||
requires: "an explosive damage source, not iridium-192",
|
||||
effect: () => {
|
||||
@@ -803,7 +803,7 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion)
|
||||
return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion)
|
||||
},
|
||||
requires: "an explosive damage source, not iridium-192",
|
||||
effect: () => {
|
||||
@@ -821,7 +821,7 @@
|
||||
frequency: 2,
|
||||
isBadRandomOption: true,
|
||||
allowed() {
|
||||
return !tech.isRewindGrenade && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.isBlockExplosion)
|
||||
return !tech.isRewindGrenade && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.isPulseLaser || tech.isMissileField || tech.isBlockExplosion)
|
||||
},
|
||||
requires: "an explosive damage source, not causality bombs",
|
||||
effect: () => {
|
||||
@@ -831,25 +831,6 @@
|
||||
tech.isExplosionHarm = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "chain reaction",
|
||||
description: "<strong class='color-block'>blocks</strong> caught in <strong class='color-e'>explosions</strong> also <strong class='color-e'>explode</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion)
|
||||
},
|
||||
requires: "an explosive damage source, not iridium-192",
|
||||
effect() {
|
||||
tech.isBlockExplode = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isBlockExplode = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "shock wave",
|
||||
description: "<strong class='color-e'>explosions</strong> <strong>stun</strong> mobs for <strong>1-2</strong> seconds<br>decrease <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong> by <strong>30%</strong>",
|
||||
@@ -859,7 +840,7 @@
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion)
|
||||
return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion)
|
||||
},
|
||||
requires: "an explosive damage source, not iridium-192",
|
||||
effect() {
|
||||
@@ -878,7 +859,7 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isMissileField || tech.isExplodeMob || tech.isPulseLaser || tech.isBlockExplosion)
|
||||
return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.isMissileField || tech.isExplodeMob || tech.isPulseLaser || tech.isBlockExplosion)
|
||||
},
|
||||
requires: "an explosive damage source, not iridium-192",
|
||||
effect: () => {
|
||||
@@ -2915,7 +2896,7 @@
|
||||
},
|
||||
{
|
||||
name: "Bayesian statistics",
|
||||
description: "increase <strong class='color-d'>damage</strong> by <strong>4.2%</strong><br>for each <strong class='color-r'>research</strong> in your inventory",
|
||||
description: "increase <strong class='color-d'>damage</strong> by <strong>4%</strong><br>for each <strong class='color-r'>research</strong> in your inventory",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
@@ -3038,7 +3019,7 @@
|
||||
},
|
||||
{
|
||||
name: "replication",
|
||||
description: "<strong>10%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br><strong>+18</strong> <strong class='color-j'>JUNK</strong> to the potential <strong class='color-m'>tech</strong> pool",
|
||||
description: "<strong>10%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br><strong>+30</strong> <strong class='color-j'>JUNK</strong> to the potential <strong class='color-m'>tech</strong> pool",
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -3055,7 +3036,7 @@
|
||||
remove() {
|
||||
tech.duplicateChance = 0
|
||||
powerUps.setDo(); //needed after adjusting duplication chance
|
||||
if (this.count > 1) tech.removeJunkTechFromPool(18)
|
||||
if (this.count > 1) tech.removeJunkTechFromPool(30)
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -3100,7 +3081,7 @@
|
||||
},
|
||||
{
|
||||
name: "futures exchange",
|
||||
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>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.8%</strong> power up <strong class='color-dup'>duplication</strong> chance",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -3122,7 +3103,7 @@
|
||||
},
|
||||
{
|
||||
name: "commodities 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>spawns <strong>10</strong> <strong class='color-h'>heals</strong>, <strong class='color-g'>ammo</strong>, and <strong class='color-r'>research</strong>",
|
||||
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>spawns <strong>9</strong> <strong class='color-h'>heals</strong>, <strong class='color-g'>ammo</strong>, and <strong class='color-r'>research</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -3651,7 +3632,7 @@
|
||||
allowed() {
|
||||
return tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles // && !tech.isNailRadiation && !tech.isNailCrit
|
||||
},
|
||||
requires: "nail gun, not powder-actuated, rivets, needles, irradiated, or fission",
|
||||
requires: "nail gun, not rivets, needles",
|
||||
effect() {
|
||||
tech.isIceCrystals = true;
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
@@ -3762,7 +3743,7 @@
|
||||
allowed() {
|
||||
return tech.isMineDrop + tech.nailBotCount + tech.fragments + tech.nailsDeathMob / 2 + ((tech.haveGunCheck("mine") && !tech.isLaserMine) + (tech.haveGunCheck("nail gun") && !tech.isNeedleShieldPierce) + tech.isNeedleShot + tech.isNailShot) * 2 > 1
|
||||
},
|
||||
requires: "nails, rivets, not ceramic needles, not ice crystals",
|
||||
requires: "nails, rivets, not ceramic needles",
|
||||
effect() {
|
||||
tech.isNailRadiation = true;
|
||||
},
|
||||
@@ -3924,7 +3905,7 @@
|
||||
},
|
||||
{
|
||||
name: "needle-shot",
|
||||
description: "<strong>shotgun</strong> propels <strong>12</strong> mob piercing <strong>needles</strong>",
|
||||
description: "<strong>shotgun</strong> propels <strong>11</strong> mob piercing <strong>needles</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -4345,6 +4326,25 @@
|
||||
b.setGrenadeMode()
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "chain reaction",
|
||||
description: "increase <strong>grenade</strong> radius and <strong class='color-d'>damage</strong> <strong>33%</strong><br><strong class='color-block'>blocks</strong> caught in <strong class='color-e'>explosions</strong> also <strong class='color-e'>explode</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return tech.isVacuumBomb && !tech.isExplodeRadio
|
||||
},
|
||||
requires: "vacuum bomb && not iridium-192",
|
||||
effect() {
|
||||
tech.isBlockExplode = true; //chain reaction
|
||||
},
|
||||
remove() {
|
||||
tech.isBlockExplode = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "neutron bomb",
|
||||
description: "<strong>grenades</strong> are <strong class='color-p'>irradiated</strong> with <strong class='color-p'>Cf-252</strong><br>does <strong class='color-d'>damage</strong>, <strong class='color-harm'>harm</strong>, and drains <strong class='color-f'>energy</strong>",
|
||||
@@ -4579,7 +4579,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "decomposer",
|
||||
name: "necrophage",
|
||||
description: "if <strong class='color-p' style='letter-spacing: -0.8px;'>worms</strong> <strong>kill</strong> their target<br>they reset their <strong>lifespan</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
|
||||
29
todo.txt
29
todo.txt
@@ -1,28 +1,22 @@
|
||||
******************************************************** NEXT PATCH ********************************************************
|
||||
|
||||
decomposers - worms reset their lifespan if they kill their target
|
||||
tech: chain reaction now requires vacuum bomb, but it increases grenade radius and damage 33%
|
||||
(and makes blocks explode)
|
||||
|
||||
nail tech tree reworked a bit
|
||||
removed powder actuated, nail gun ramps up to full fire rate with just pneumatic actuator
|
||||
needles and ice crystal nucleation can get supercritical fission and irradiated nails now
|
||||
supercritical fission crits easier
|
||||
|
||||
labs exit platforming is a much easier since it's in the general rotation now
|
||||
|
||||
bug fixes
|
||||
needle gun fires with more regular timing
|
||||
needles despawn 1.5s faster, for performance reasons
|
||||
intro level power ups are relocated
|
||||
tech: decomposers renamed necrophage
|
||||
if mobs are one shotted before they see you, they no longer alert nearby mobs
|
||||
clicking on a mob in testing will log that mob in console
|
||||
|
||||
******************************************************** TODO ********************************************************
|
||||
|
||||
make
|
||||
|
||||
buff nail gun
|
||||
|
||||
buff missiles?
|
||||
maybe they can release grenades after they explode, like CPT grenades?
|
||||
|
||||
move the bonus tech on intro to the right so players don't have to backtrack as much
|
||||
maybe draw something in the background to explain where the tech is coming from
|
||||
|
||||
make the player get a buff after using wormhole
|
||||
while energy lasts: drain energy and give damage buff
|
||||
using wormhole makes you immune to harm and drains energy until you run out
|
||||
disable incoming energy, by saving current energy and just setting energy in the next cycle to be lower then the saved value
|
||||
|
||||
@@ -37,9 +31,6 @@ pause should at least show the last in game console message
|
||||
|
||||
in testing mode console log the body you click on
|
||||
|
||||
make the player get a buff after using wormhole
|
||||
while energy lasts: drain energy and give damage buff
|
||||
|
||||
tech: quantized shields - harmonic standing wave field can only lose 33 energy per hit
|
||||
draw 1,2,3 levels of the field based on energy?
|
||||
the blocked value only scales up to 2x or 4x (33 energy) blocked
|
||||
|
||||
Reference in New Issue
Block a user