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:
landgreen
2021-08-03 06:46:19 -07:00
parent f9dc66797b
commit d8e891a681
11 changed files with 160 additions and 117 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -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,

View File

@@ -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)

View File

@@ -494,10 +494,12 @@ const build = {
count = 0;
for (let i = 0; i < tech.tech.length; i++) {
for (let j = 0; j < tech.tech[i].count; j++) {
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())}`
url += `&difficulty=${simulation.difficultyMode}`
if (isCustom) {

View File

@@ -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

View File

@@ -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() {

View File

@@ -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)

View File

@@ -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,

View File

@@ -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();

View File

@@ -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,

View File

@@ -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