stress concentration

nail gun tech: stress concentration - if a mob has below 50% durability after taking damage
  from needles or rivets near the center of it's body it dies

caliber 16->25% nail, needle, rivet size/damage
combined tech: flagella - spores move +50% faster
  spores follow you if they can't find a target
shock wave stun also applies to sporangium
  no longer reduces explosion size

JUNK tech: reincarnation - kill all mobs and spawn new ones
  (also spawn a few extra mobs for fun)

updated pause menu and fields descriptions to new wording style

bug fixes
This commit is contained in:
landgreen
2022-06-19 08:32:45 -07:00
parent e68ed81ba1
commit 698c18482b
9 changed files with 412 additions and 222 deletions

View File

@@ -168,11 +168,9 @@ const b = {
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isGunTech && tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable && !tech.tech[i].isRemoveGun) {
const remove = tech.removeTech(i)
// console.log(remove, tech.tech[i].count, tech.tech[i].name)
gunTechCount += remove
}
}
// console.log(gunTechCount)
//get a random gun tech for your gun
for (let i = 0; i < gunTechCount; i++) {
@@ -353,7 +351,7 @@ const b = {
radius *= tech.explosiveRadius
let dist, sub, knock;
let dmg = radius * 0.019 * (tech.isExplosionStun ? 0.7 : 1); //* 0.013 * (tech.isExplosionStun ? 0.7 : 1);
let dmg = radius * 0.019
if (tech.isExplosionHarm) radius *= 1.7 // 1/sqrt(2) radius -> area
if (tech.isSmallExplosion) {
// color = "rgba(255,0,30,0.7)"
@@ -393,7 +391,7 @@ const b = {
if (mob[i].shield) dmg *= 2.5 //balancing explosion dmg to shields
if (Matter.Query.ray(map, mob[i].position, where).length > 0) dmg *= 0.5 //reduce damage if a wall is in the way
mobs.statusDoT(mob[i], dmg * damageScale * 0.25, 240) //apply radiation damage status effect on direct hits
if (tech.isExplosionStun) mobs.statusStun(mob[i], 60)
if (tech.isStun) mobs.statusStun(mob[i], 30)
mob[i].locatePlayer();
damageScale *= 0.87 //reduced damage for each additional explosion target
}
@@ -429,7 +427,6 @@ const b = {
// const mitigate = Math.min(1, Math.max(1 - m.energy * 0.5, 0))
m.energy -= 0.12
// m.damage(0.01 * harm); //remove 99% of the damage 1-0.99
// console.log(Math.max(0, Math.min(0.15 - 0.01 * player.speed, 0.15)))
knock = Vector.mult(Vector.normalise(sub), -0.6 * player.mass * Math.max(0, Math.min(0.15 - 0.002 * player.speed, 0.15)));
player.force.x = knock.x; // not += so crazy forces can't build up with MIRV
player.force.y = knock.y - 0.3; //some extra vertical kick
@@ -502,8 +499,8 @@ const b = {
mob[i].damage(dmg * damageScale * m.dmgScale);
mob[i].locatePlayer();
knock = Vector.mult(Vector.normalise(sub), -Math.sqrt(dmg * damageScale) * mob[i].mass * (mob[i].isBoss ? 0.003 : 0.01));
if (tech.isExplosionStun) {
mobs.statusStun(mob[i], 120)
if (tech.isStun) {
mobs.statusStun(mob[i], 30)
} else if (!mob[i].isInvulnerable) {
mob[i].force.x += knock.x;
mob[i].force.y += knock.y;
@@ -513,8 +510,8 @@ const b = {
} else if (!mob[i].seePlayer.recall && dist < alertRange) {
mob[i].locatePlayer();
knock = Vector.mult(Vector.normalise(sub), -Math.sqrt(dmg * damageScale) * mob[i].mass * (mob[i].isBoss ? 0 : 0.006));
if (tech.isExplosionStun) {
mobs.statusStun(mob[i], 60)
if (tech.isStun) {
mobs.statusStun(mob[i], 30)
} else if (!mob[i].isInvulnerable) {
mob[i].force.x += knock.x;
mob[i].force.y += knock.y;
@@ -2463,7 +2460,7 @@ const b = {
ctx.globalAlpha = 1;
}
},
AoEStunEffect(where, range, cycles = 90 + 60 * Math.random()) {
AoEStunEffect(where, range, cycles = 120 + 60 * Math.random()) {
for (let i = 0, len = mob.length; i < len; ++i) {
if (mob[i].alive && !mob[i].isShielded && !mob[i].shield && !mob[i].isBadTarget) {
if (Vector.magnitude(Vector.sub(where, mob[i].position)) - mob[i].radius < range) mobs.statusStun(mob[i], cycles)
@@ -2509,7 +2506,7 @@ const b = {
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
Matter.Query.ray(body, this.position, mob[i].position).length === 0
) {
if (tech.isExplosionStun) b.AoEStunEffect(this.position, 1300);
if (tech.isStun) b.AoEStunEffect(this.position, 1300); //AoEStunEffect(where, range, cycles = 90 + 60 * Math.random()) {
this.do = this.laserSpin
if (this.angularSpeed < 0.5) this.torque += this.inertia * this.torqueMagnitude * 200 //spin
this.endCycle = simulation.cycle + 360 + 120
@@ -2644,7 +2641,7 @@ const b = {
Matter.Query.ray(body, this.position, mob[i].position).length === 0 &&
!mob[i].isInvulnerable
) {
if (tech.isExplosionStun) b.AoEStunEffect(this.position, 700 + mob[i].radius + random);
if (tech.isStun) b.AoEStunEffect(this.position, 700 + mob[i].radius + random); //AoEStunEffect(where, range, cycles = 90 + 60 * Math.random()) {
if (tech.isMineSentry) {
this.lookFrequency = 8 + Math.floor(3 * Math.random())
this.endCycle = simulation.cycle + 1020
@@ -2691,7 +2688,7 @@ const b = {
// angle: Math.random() * 2 * Math.PI,
friction: 0,
frictionAir: 0.025,
thrust: (tech.isFastSpores ? 0.0012 : 0.00055) * (1 + 0.5 * (Math.random() - 0.5)),
thrust: (tech.isSporeFollow ? 0.0012 : 0.00055) * (1 + 0.5 * (Math.random() - 0.5)),
wormSize: wormSize,
wormTail: 1 + Math.max(4, Math.min(wormSize - 2 * tech.wormSize, 30)),
dmg: (tech.isMutualism ? 7 : 2.9) * wormSize, //bonus damage from tech.isMutualism //2.5 is extra damage as worm
@@ -2809,7 +2806,7 @@ const b = {
angle: Math.random() * 2 * Math.PI,
friction: 0,
frictionAir: 0.025,
thrust: (tech.isFastSpores ? 0.0011 : 0.0005) * (1 + 0.3 * (Math.random() - 0.5)),
thrust: (tech.isSporeFollow ? 0.0011 : 0.0005) * (1 + 0.3 * (Math.random() - 0.5)),
dmg: tech.isMutualism ? 16.8 : 7, //bonus damage from tech.isMutualism
lookFrequency: 100 + Math.floor(117 * Math.random()),
classType: "bullet",
@@ -2901,8 +2898,17 @@ const b = {
// this.force.y += this.mass * 0.0001; //gravity
// }
// if (this.nextPortCycle < simulation.cycle) { //teleport around if you have tech.isBulletTeleport
// this.nextPortCycle = simulation.cycle + this.portFrequency
// const range = 50 * Math.random()
// Matter.Body.setPosition(this, Vector.add(this.position, Vector.rotate({ x: range, y: 0 }, 2 * Math.PI * Math.random())))
// }
},
});
// if (tech.isBulletTeleport) {
// bullet[bIndex].portFrequency = 10 + Math.floor(5 * Math.random())
// bullet[bIndex].nextPortCycle = simulation.cycle + bullet[bIndex].portFrequency
// }
const SPEED = 4 + 8 * Math.random();
const ANGLE = 2 * Math.PI * Math.random()
@@ -2941,12 +2947,12 @@ const b = {
minDmgSpeed: 0,
lockedOn: null,
beforeDmg(who) {
mobs.statusSlow(who, 180)
this.endCycle = simulation.cycle
// if (tech.isHeavyWater) mobs.statusDoT(who, 0.15, 300)
if (tech.iceEnergy && !who.shield && !who.isShielded && who.isDropPowerUp && who.alive && m.immuneCycle < m.cycle) {
setTimeout(() => { if (!who.alive) m.energy += tech.iceEnergy * 0.8 }, 10);
}
mobs.statusSlow(who, 180)
this.endCycle = simulation.cycle
// if (tech.isHeavyWater) mobs.statusDoT(who, 0.15, 300)
},
onEnd() {},
do() {
@@ -3816,6 +3822,38 @@ const b = {
}
}
},
crit(mob, bullet) {
if (!mob.shield && Vector.dot(Vector.normalise(Vector.sub(mob.position, bullet.position)), Vector.normalise(bullet.velocity)) > 0.99 - 4 / mob.radius) {
let cycle = () => { //makes this run after damage
if (mob.health < 0.5 && mob.damageReduction > 0 && mob.alive) {
const color = 'rgb(255,255,255)'
simulation.drawList.push({
x: mob.position.x,
y: mob.position.y,
radius: mob.radius * 1.2,
color: color, //"rgba(0,0,0,0.6)",
time: 8
});
simulation.drawList.push({
x: mob.position.x,
y: mob.position.y,
radius: mob.radius * 0.75,
color: color, //"rgba(0,0,0,0.85)",
time: 15
});
simulation.drawList.push({
x: mob.position.x,
y: mob.position.y,
radius: mob.radius * 0.4,
color: color, //"rgb(0,0,0)",
time: 20
});
mob.death();
}
}
requestAnimationFrame(cycle);
}
},
nail(pos, velocity, dmg = 1) {
dmg *= tech.bulletSize
const me = bullet.length;
@@ -3826,11 +3864,10 @@ const b = {
bullet[me].dmg = tech.isNailRadiation ? 0 : dmg
bullet[me].beforeDmg = function(who) { //beforeDmg is rewritten with ice crystal tech
if (tech.isNailRadiation) mobs.statusDoT(who, dmg * (tech.isFastRadiation ? 1.3 : 0.44), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles
if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) {
b.explosion(this.position, 150 + 30 * Math.random()); //makes bullet do explosive damage at end
}
if (true && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) {
b.targetedNail(this.position, 1, 39 + 6 * Math.random())
if (tech.isNailCrit) {
if (!who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.97 - 2 / who.radius) {
b.explosion(this.position, 150 + 30 * Math.random()); //makes bullet do explosive damage at end
}
}
};
bullet[me].do = function() {};
@@ -3861,9 +3898,12 @@ const b = {
}
}
if (!immune) {
if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) {
b.explosion(this.position, 220 * tech.bulletSize + 50 * Math.random()); //makes bullet do explosive damage at end
}
if (tech.isNailCrit) {
if (!who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.97 - 2 / who.radius) {
b.explosion(this.position, 220 + 50 * Math.random()); //makes bullet do explosive damage at end
}
} else if (tech.isCritKill) b.crit(who, this)
this.immuneList.push(who.id) //remember that this needle has hit this mob once already
let dmg = this.dmg * tech.bulletSize * m.dmgScale
if (tech.isNailRadiation) {
@@ -3916,9 +3956,12 @@ const b = {
}
}
if (!immune) {
if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) {
b.explosion(this.position, 220 * tech.bulletSize + 50 * Math.random()); //makes bullet do explosive damage at end
}
if (tech.isNailCrit) {
if (!who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.97 - 2 / who.radius) {
b.explosion(this.position, 220 + 50 * Math.random()); //makes bullet do explosive damage at end
}
} else if (tech.isCritKill) b.crit(who, this)
this.immuneList.push(who.id) //remember that this needle has hit this mob once already
let dmg = this.dmg * tech.bulletSize * m.dmgScale
if (tech.isNailRadiation) {
@@ -5060,9 +5103,11 @@ const b = {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
b.explosion(this.position, 100 + (Math.random() - 0.5) * 20); //makes bullet do explosive damage at end
}
if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) {
b.explosion(this.position, 300 + 30 * Math.random()); //makes bullet do explosive damage at end
}
if (tech.isNailCrit) {
if (!who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.97 - 2 / who.radius) {
b.explosion(this.position, 300 + 40 * Math.random()); //makes bullet do explosive damage at end
}
} else if (tech.isCritKill) b.crit(who, this)
if (tech.isNailRadiation) mobs.statusDoT(who, 7 * (tech.isFastRadiation ? 0.7 : 0.24), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles
if (this.speed > 4 && tech.fragments) {
b.targetedNail(this.position, 1.25 * tech.fragments * tech.bulletSize)
@@ -5131,9 +5176,12 @@ const b = {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
b.explosion(this.position, 100 + (Math.random() - 0.5) * 20); //makes bullet do explosive damage at end
}
if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) {
b.explosion(this.position, 300 + 30 * Math.random()); //makes bullet do explosive damage at end
}
if (tech.isNailCrit) {
if (!who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.97 - 2 / who.radius) {
b.explosion(this.position, 300 + 40 * Math.random()); //makes bullet do explosive damage at end
}
} else if (tech.isCritKill) b.crit(who, this)
if (tech.isNailRadiation) mobs.statusDoT(who, 7 * (tech.isFastRadiation ? 0.7 : 0.24), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles
if (this.speed > 4 && tech.fragments) {
b.targetedNail(this.position, 1.25 * tech.fragments * tech.bulletSize)
@@ -5203,14 +5251,16 @@ const b = {
bullet[bullet.length - 1].beforeDmg = function(who) {
mobs.statusSlow(who, 60)
if (tech.isNailRadiation) mobs.statusDoT(who, 1 * (tech.isFastRadiation ? 1.3 : 0.44), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles
if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) {
b.explosion(this.position, 150 + 30 * Math.random()); //makes bullet do explosive damage at end
if (tech.isNailCrit) {
if (!who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.97 - 2 / who.radius) {
b.explosion(this.position, 150 + 30 * Math.random()); //makes bullet do explosive damage at end
}
}
};
if (m.energy < 0.01) {
m.fireCDcycle = m.cycle + 60; // cool down
} else {
m.energy -= m.fieldRegen + 0.008
m.energy -= 0.01
}
}
},
@@ -5289,12 +5339,13 @@ const b = {
}
}
};
if (tech.fragments) {
bullet[me].beforeDmg = function() {
if (this.speed > 4) {
bullet[me].beforeDmg = function(who) {
if (this.speed > 4) {
if (tech.fragments) {
b.targetedNail(this.position, 6 * tech.fragments * tech.bulletSize)
this.endCycle = 0 //triggers despawn
}
if (tech.isCritKill) b.crit(who, this)
}
}
} else if (tech.isIncendiary) {
@@ -6043,7 +6094,7 @@ const b = {
bullet[me].maxRadius = 30;
bullet[me].restitution = 0.3;
bullet[me].minDmgSpeed = 0;
bullet[me].totalSpores = 8 + 2 * tech.isFastSpores + 2 * tech.isSporeFreeze * (tech.isSporeWorm ? 0.5 : 1)
bullet[me].totalSpores = 8 + 2 * tech.isSporeFreeze * (tech.isSporeWorm ? 0.5 : 1)
bullet[me].stuck = function() {};
bullet[me].beforeDmg = function() {};
bullet[me].do = function() {
@@ -6152,6 +6203,7 @@ const b = {
} else {
for (let i = 0; i < this.totalSpores; i++) b.spore(this.position)
}
if (tech.isStun) b.AoEStunEffect(this.position, 600, 270 + 120 * Math.random()); //AoEStunEffect(where, range, cycles = 120 + 60 * Math.random()) {
}
}
}, {
@@ -6392,7 +6444,6 @@ const b = {
if (mob[i].alive && !mob[i].isBadTarget && !mob[i].shield && Matter.Query.ray(map, m.pos, mob[i].position).length === 0 && !mob[i].isInvulnerable) {
const dot = Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, m.pos))) //the dot product of diff and dir will return how much over lap between the vectors
const dist = Vector.magnitude(Vector.sub(where, mob[i].position))
// console.log(dot, 0.95 - Math.min(dist * 0.00015, 0.3))
if (dot > 0.95 - Math.min(dist * 0.00015, 0.3)) { //lower dot product threshold for targeting then if you only have one harpoon //target closest mob that player is looking at and isn't too close to target
// if (this.ammo > -1) {
// this.ammo--

View File

@@ -242,11 +242,13 @@ const build = {
</svg><br>`
text += `
<br><strong class='color-d'>damage</strong>: ${((tech.damageFromTech())).toPrecision(3)} &nbsp; &nbsp; difficulty: ${((m.dmgScale)).toPrecision(3)}
<br><strong class='color-defense'>defense</strong>: ${(1-m.harmReduction()).toPrecision(3)} &nbsp; &nbsp; difficulty: ${(simulation.dmgScale).toPrecision(3)}
<br><strong class='color-defense'>defense</strong>: ${(1-m.harmReduction()).toPrecision(3)} &nbsp; &nbsp; difficulty: ${(1/simulation.dmgScale).toPrecision(3)}
<br><strong><em>fire rate</em></strong>: ${((1-b.fireCDscale)*100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}%
<br><strong class='color-dup'>duplication</strong>: ${(tech.duplicationChance()*100).toFixed(0)}%
${botText}
<br><br><strong class='color-h'>health</strong>: (${(m.health*100).toFixed(0)} / ${(m.maxHealth*100).toFixed(0)}) &nbsp; <strong class='color-f'>energy</strong>: (${(m.energy*100).toFixed(0)} / ${(m.maxEnergy*100).toFixed(0)})
<br>
<br><strong class='color-h'>health</strong>: (${(m.health*100).toFixed(0)} / ${(m.maxHealth*100).toFixed(0)})
<br><strong class='color-f'>energy</strong>: (${(m.energy*100).toFixed(0)} / ${(m.maxEnergy*100).toFixed(0)})
<br><strong class='color-g'>gun</strong>: ${b.activeGun === null || b.activeGun === undefined ? "undefined":b.guns[b.activeGun].name} &nbsp; <strong class='color-g'>ammo</strong>: ${b.activeGun === null || b.activeGun === undefined ? "0":b.guns[b.activeGun].ammo}
<br><strong class='color-m'>tech</strong>: ${tech.totalCount} &nbsp; <strong class='color-r'>research</strong>: ${powerUps.research.count}
<br>

View File

@@ -7,9 +7,9 @@ const level = {
defaultZoom: 1400,
onLevel: -1,
levelsCleared: 0,
// playableLevels: ["pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion"],
//see level.populateLevels: (intro, ... , reservoir, reactor, ... , gauntlet, final) added later
playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion"],
// playableLevels: ["pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion"],
communityLevels: ["stronghold", "basement", "crossfire", "vats", "run", "n-gon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp"],
trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon"],
levels: [],
@@ -20,12 +20,13 @@ const level = {
// m.setField("time dilation")
// b.giveGuns("nail gun")
// b.giveGuns("mine")
// tech.giveTech("laser-mines")
// tech.giveTech("free-electron laser")
// tech.giveTech("energy conservation")
// tech.giveTech("6s half-life")
// for (let i = 0; i < 10; i++) tech.giveTech("replication")
// tech.giveTech("eternalism")
// tech.giveTech("needle gun")
// tech.giveTech("stress concentration")
// for (let i = 0; i < 100; ++i) tech.giveTech("nail-bot")
// tech.giveTech("rivet gun")
// tech.giveTech("needle ice")
// tech.giveTech("flash freeze")
// tech.giveTech("superfluidity")
// m.maxHealth = 100
// m.health = m.maxHealth
// for (let i = 0; i < 10; i++) tech.giveTech("tungsten carbide")
@@ -36,12 +37,14 @@ const level = {
// powerUps.research.changeRerolls(100000)
// tech.tech[297].frequency = 100
// m.immuneCycle = Infinity //you can't take damage
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
// level.difficultyIncrease(40) //30 is near max on hard //60 is near max on why
// simulation.enableConstructMode() //used to build maps in testing mode
// level.perplex();
// spawn.cellBossCulture(1900, -500)
// level.testing(); //not in rotation, used for testing
// spawn.starter(1900, -500)
// spawn.starter(1900, -500, 300)
// for (let i = 0; i < 50; ++i) spawn.starter(1900, -500)
// spawn.powerUpBoss(1900, -500)
if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************
// powerUps.research.changeRerolls(3000)
@@ -1327,10 +1330,10 @@ const level = {
if (this.height > 0 && Matter.Query.region([player], this).length) {
if (m.immuneCycle < m.cycle) {
const DRAIN = 0.002 * (tech.isRadioactiveResistance ? 0.25 : 1) + m.fieldRegen
const DRAIN = 0.0022 * (tech.isRadioactiveResistance ? 0.25 : 1) + m.fieldRegen
if (m.energy > DRAIN) {
m.energy -= DRAIN
m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1) * 0.03) //still take 2% damage while you have energy
// m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1) * 0.03) //still take 2% damage while you have energy
} else {
m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1))
}
@@ -8849,7 +8852,7 @@ const level = {
} else {
tech.addJunkTechToPool(0.49)
}
// spawn.randomLevelBoss(x, y, ["historyBoss"]);
spawn.randomLevelBoss(x, y, ["historyBoss"]);
}
}

View File

@@ -59,9 +59,32 @@ const mobs = {
}
function applySlow(whom) {
if (!whom.shield && !whom.isShielded && who.alive) {
if (tech.isIceMaxHealthLoss && who.health > 0.66 && who.damageReduction > 0) who.health = 0.66
if (tech.isIceKill && who.health < 0.33 && who.damageReduction > 0) who.death();
if (!whom.shield && !whom.isShielded && whom.alive) {
if (tech.isIceMaxHealthLoss && whom.health > 0.65 && whom.damageReduction > 0) whom.health = 0.66
if (tech.isIceKill && whom.health < 0.34 && whom.damageReduction > 0 && whom.alive) {
simulation.drawList.push({
x: whom.position.x,
y: whom.position.y,
radius: whom.radius * 1.2,
color: "rgb(0,100,255)",
time: 8
});
simulation.drawList.push({
x: whom.position.x,
y: whom.position.y,
radius: whom.radius * 0.7,
color: "rgb(0,100,255)",
time: 12
});
simulation.drawList.push({
x: whom.position.x,
y: whom.position.y,
radius: whom.radius * 0.4,
color: "rgb(0,100,255)",
time: 16
});
whom.death();
}
if (whom.isBoss) cycles = Math.floor(cycles * 0.25)
let i = whom.status.length
while (i--) {

View File

@@ -858,7 +858,7 @@ const m = {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20)
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -3);
m.drawLeg("#4a4a4a");
@@ -2622,7 +2622,7 @@ const m = {
} else {
m.fieldFire = true;
m.isBodiesAsleep = false;
m.drain = 0.0025
m.drain = 0.002
m.hold = function() {
if (m.isHolding) {
m.wakeCheck();

View File

@@ -105,6 +105,7 @@ const simulation = {
simulation.isTimeSkipping = true;
for (let i = 0; i < cycles; i++) {
simulation.cycle++;
// m.walk_cycle += (m.flipLegs * m.Vx) * 0.5; //makes the legs look like they are moving fast (it's times 0.5 because when they move too fast it's a blur)
simulation.gravity();
Engine.update(engine, simulation.delta);
// level.custom();

View File

@@ -47,13 +47,13 @@ const spawn = {
},
randomMob(x, y, chance = 1) {
if (spawn.spawnChance(chance) || chance === Infinity) {
const pick = this.pickList[Math.floor(Math.random() * this.pickList.length)];
this[pick](x, y);
const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
spawn[pick](x, y);
}
if (tech.isMoreMobs || (tech.isDuplicateBoss && Math.random() < tech.duplicationChance())) {
const pick = this.pickList[Math.floor(Math.random() * this.pickList.length)];
this[pick](x, y);
const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
spawn[pick](x, y);
}
},
randomSmallMob(x, y,
@@ -62,14 +62,14 @@ const spawn = {
chance = 1) {
if (spawn.spawnChance(chance)) {
for (let i = 0; i < num; ++i) {
const pick = this.pickList[Math.floor(Math.random() * this.pickList.length)];
this[pick](x + Math.round((Math.random() - 0.5) * 20) + i * size * 2.5, y + Math.round((Math.random() - 0.5) * 20), size);
const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
spawn[pick](x + Math.round((Math.random() - 0.5) * 20) + i * size * 2.5, y + Math.round((Math.random() - 0.5) * 20), size);
}
}
if (tech.isMoreMobs || (tech.isDuplicateBoss && Math.random() < tech.duplicationChance())) {
for (let i = 0; i < num; ++i) {
const pick = this.pickList[Math.floor(Math.random() * this.pickList.length)];
this[pick](x + Math.round((Math.random() - 0.5) * 20) + i * size * 2.5, y + Math.round((Math.random() - 0.5) * 20), size);
const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
spawn[pick](x + Math.round((Math.random() - 0.5) * 20) + i * size * 2.5, y + Math.round((Math.random() - 0.5) * 20), size);
}
}
},
@@ -3576,7 +3576,7 @@ const spawn = {
ctx.setLineDash([]);
}
},
sprayBoss(x, y, radius = 30, isSpawnBossPowerUp = true) {
sprayBoss(x, y, radius = 35, isSpawnBossPowerUp = true) {
mobs.spawn(x, y, 16, radius, "rgb(255,255,255)");
let me = mob[mob.length - 1];
me.isBoss = true;
@@ -3587,7 +3587,7 @@ const spawn = {
me.friction = 0;
me.frictionAir = 0;
me.restitution = 1
spawn.spawnOrbitals(me, radius + 50 + 150 * Math.random(), 1)
spawn.spawnOrbitals(me, radius + 50 + 125 * Math.random(), 1)
Matter.Body.setDensity(me, 0.0022 + 0.0001 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.09 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.startingDamageReduction = me.damageReduction
@@ -3630,8 +3630,8 @@ const spawn = {
if (this.speed < 0.01) {
Matter.Body.setVelocity(this, Vector.mult(Vector.normalise(Vector.sub(player.position, this.position)), 0.1));
} else {
if (Math.abs(this.velocity.y) < 12) Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.07 });
if (Math.abs(this.velocity.x) < 9) Matter.Body.setVelocity(this, { x: this.velocity.x * 1.07, y: this.velocity.y });
if (Math.abs(this.velocity.y) < 11) Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.07 });
if (Math.abs(this.velocity.x) < 8) Matter.Body.setVelocity(this, { x: this.velocity.x * 1.07, y: this.velocity.y });
}
}
me.burstFire = function() {
@@ -5188,12 +5188,12 @@ const spawn = {
me.eventHorizon = 0; //set in mob loop
me.frictionStatic = 0;
me.friction = 0;
me.frictionAir = 0.004;
me.frictionAir = 0.005;
me.accelMag = 0.00008 + 0.00002 * simulation.accelScale
spawn.shield(me, x, y, 1);
spawn.spawnOrbitals(me, radius + 50 + 100 * Math.random())
Matter.Body.setDensity(me, 0.003); //extra dense //normal is 0.001 //makes effective life much larger
Matter.Body.setDensity(me, 0.0025); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.07 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
@@ -5217,10 +5217,14 @@ const spawn = {
this.attraction();
this.damageReduction = this.startingDamageReduction
this.isInvulnerable = false
if (!(simulation.cycle % 15)) requestAnimationFrame(() => {
simulation.timePlayerSkip(5)
simulation.loop(); //ending with a wipe and normal loop fixes some very minor graphical issues where things are draw in the wrong locations
}); //wrapping in animation frame prevents errors, probably
// if (!(simulation.cycle % 15)) requestAnimationFrame(() => {
// simulation.timePlayerSkip(5)
// // simulation.loop(); //ending with a wipe and normal loop fixes some very minor graphical issues where things are draw in the wrong locations
// }); //wrapping in animation frame prevents errors, probably
requestAnimationFrame(() => {
simulation.timePlayerSkip(1)
m.walk_cycle += m.flipLegs * m.Vx //makes the legs look like they are moving fast
}); //wrapping in animation frame prevents errors, probably
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);

View File

@@ -868,7 +868,7 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isStunField || tech.oneSuperBall || tech.isCloakStun || tech.isOrbitBotUpgrade || tech.isExplosionStun
return tech.isStunField || tech.oneSuperBall || tech.isCloakStun || tech.isOrbitBotUpgrade || tech.isStun
},
requires: "a stun effect",
effect() {
@@ -1666,7 +1666,7 @@ const tech = {
},
{
name: "Pauli exclusion",
description: `after mob collisions<br>become <strong>invulnerable</strong> for <strong>+2.5</strong> seconds`,
description: `after mob collisions<br>become <strong>invulnerable</strong> for <strong>+3</strong> seconds`,
maxCount: 9,
count: 0,
frequency: 1,
@@ -1674,7 +1674,7 @@ const tech = {
allowed() { return true },
requires: "",
effect() {
tech.collisionImmuneCycles += 150;
tech.collisionImmuneCycles += 180;
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage
},
remove() {
@@ -1683,7 +1683,7 @@ const tech = {
},
{
name: "spinstatistics theorem",
description: `every <strong>7</strong> seconds<br>become <strong>invulnerable</strong> for <strong>1.75</strong> seconds`,
description: `every <strong>7</strong> seconds<br>become <strong>invulnerable</strong> for <strong>+1.75</strong> seconds`,
maxCount: 3,
count: 0,
frequency: 1,
@@ -1888,96 +1888,6 @@ const tech = {
tech.relayIce = 0
}
},
{
name: "freezer burn",
description: "mobs <strong class='color-s'>frozen</strong> while below <strong>33%</strong> durability <strong>die</strong>",
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1
},
requires: "a freeze effect",
effect() {
tech.isIceKill = true
},
remove() {
tech.isIceKill = false
}
},
{
name: "flash freeze",
description: "mobs <strong class='color-s'>frozen</strong> while above <strong>66%</strong> durability<br>have their durability reduced to <strong>66%</strong>",
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1
},
requires: "a freeze effect",
effect() {
tech.isIceMaxHealthLoss = true
},
remove() {
tech.isIceMaxHealthLoss = false
}
},
{
name: "crystallizer",
description: "after <strong class='color-s'>frozen</strong> mobs <strong>die</strong> they<br>shatter into <strong class='color-s'>ice IX</strong> crystals",
maxCount: 9,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return (tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1) && !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.nailsDeathMob
},
requires: "a localized freeze effect, no other mob death tech",
effect() {
tech.iceIXOnDeath++
},
remove() {
tech.iceIXOnDeath = 0
}
},
{
name: "thermoelectric effect",
description: "<strong>killing</strong> mobs with <strong class='color-s'>ice IX</strong><br>generates <strong>100</strong> <strong class='color-f'>energy</strong>",
maxCount: 9,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isIceField || tech.relayIce || tech.isNeedleIce || tech.blockingIce || tech.iceIXOnDeath || tech.isIceShot
},
requires: "ice IX",
effect() {
tech.iceEnergy++
},
remove() {
tech.iceEnergy = 0;
}
},
{
name: "superfluidity",
description: "<strong class='color-s'>freeze</strong> effects are applied<br>to a small area around the target",
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1 || tech.iceIXOnDeath || tech.isIceShot
},
requires: "a localized freeze effect",
effect() {
tech.isAoESlow = true
},
remove() {
tech.isAoESlow = false
}
},
{
name: "liquid cooling",
description: `after losing <strong class='color-h'>health</strong><br><strong class='color-s'>freeze</strong> all mobs for <strong>7</strong> seconds`,
@@ -2429,7 +2339,7 @@ const tech = {
},
{
name: "inductive coupling",
description: "if <strong>crouched</strong> <strong>+700%</strong> passive <strong class='color-f'>energy</strong> generation<br>if not <strong>crouched</strong> <strong class='color-f'>energy</strong> generation is disabled",
description: "if <strong>crouched</strong> <strong>+600%</strong> passive <strong class='color-f'>energy</strong> generation<br>if not <strong>crouched</strong> <strong class='color-f'>energy</strong> generation is disabled",
maxCount: 1,
count: 0,
frequency: 1,
@@ -3245,7 +3155,7 @@ const tech = {
},
requires: "at least 4 research, not parthenogenesis",
effect() {
tech.isResearchBoss = true; //abiogenesis
tech.isResearchBoss = true;
},
remove() {
tech.isResearchBoss = false;
@@ -3891,7 +3801,7 @@ const tech = {
},
{
name: "caliber",
description: `<strong>rivets</strong>, <strong>needles</strong>, <strong>super balls</strong>, and <strong>nails</strong><br>have <strong>+16%</strong> mass and physical <strong class='color-d'>damage</strong>`,
description: `<strong>rivets</strong>, <strong>needles</strong>, <strong>super balls</strong>, and <strong>nails</strong><br>have <strong>+25%</strong> mass and physical <strong class='color-d'>damage</strong>`,
isGunTech: true,
maxCount: 9,
count: 0,
@@ -3902,7 +3812,7 @@ const tech = {
},
requires: "nails, nail gun, rivets, shotgun",
effect() {
tech.bulletSize += 0.16
tech.bulletSize += 0.25
},
remove() {
tech.bulletSize = 1;
@@ -3938,7 +3848,7 @@ const tech = {
{
name: "ice crystal nucleation",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Nucleation' class="link">ice crystal nucleation</a>`,
description: "the <strong>nail gun</strong> uses <strong class='color-f'>energy</strong> to condense<br>unlimited <strong class='color-s'>freezing</strong> <strong>ice shards</strong>",
description: "<strong>nail gun</strong> uses <strong class='color-f'>energy</strong> to condense<br>unlimited <strong class='color-s'>freezing</strong> <strong>ice shards</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
@@ -4002,17 +3912,36 @@ const tech = {
}
},
{
name: "supercritical fission",
description: "<strong>nails</strong>, <strong>needles</strong>, and <strong>rivets</strong> can <strong class='color-e'>explode</strong><br>if they strike mobs near their <strong>center</strong>",
name: "stress concentration",
description: "mobs below <strong>50%</strong> durability <strong>die</strong> after you shoot<br>them near their <strong>center</strong> with <strong>needles</strong> or <strong>rivets</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return (tech.isNailShot || tech.isNeedles || tech.isNailBotUpgrade || tech.haveGunCheck("nail gun") || tech.isRivets) && !tech.isIncendiary
return (tech.isNeedles || tech.isRivets) && !tech.isNailCrit && !tech.isIncendiary
},
requires: "nail gun, needles, nails, rivets, not incendiary",
requires: "needles, rivets, not incendiary, supercritical fission",
effect() {
tech.isCritKill = true
},
remove() {
tech.isCritKill = false
}
},
{
name: "supercritical fission",
description: "if bullets strike mobs near their <strong>center</strong><br>they can <strong class='color-e'>explode</strong> <em style = 'font-size:95%;'>(nails, needles, rivets)</em>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return (tech.isNailShot || tech.isNeedles || tech.isNailBotUpgrade || tech.haveGunCheck("nail gun") || tech.isRivets) && !tech.isIncendiary && !tech.isCritKill
},
requires: "nail gun, needles, nails, rivets, not incendiary, fire-control system",
effect() {
tech.isNailCrit = true
},
@@ -4219,6 +4148,101 @@ const tech = {
tech.isIceShot = false;
}
},
{
name: "freezer burn",
description: "mobs <strong class='color-s'>frozen</strong> while below <strong>33%</strong> durability <strong>die</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1
},
requires: "a freeze effect",
effect() {
tech.isIceKill = true
},
remove() {
tech.isIceKill = false
}
},
{
name: "flash freeze",
description: "mobs <strong class='color-s'>frozen</strong> while above <strong>66%</strong> durability<br>have their durability reduced to <strong>66%</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1
},
requires: "a freeze effect",
effect() {
tech.isIceMaxHealthLoss = true
},
remove() {
tech.isIceMaxHealthLoss = false
}
},
{
name: "crystallizer",
description: "after <strong class='color-s'>frozen</strong> mobs <strong>die</strong> they<br>shatter into <strong class='color-s'>ice IX</strong> crystals",
isGunTech: true,
maxCount: 9,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return (tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1) && !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.nailsDeathMob
},
requires: "a localized freeze effect, no other mob death tech",
effect() {
tech.iceIXOnDeath++
},
remove() {
tech.iceIXOnDeath = 0
}
},
{
name: "thermoelectric effect",
description: "<strong>killing</strong> mobs with <strong class='color-s'>ice IX</strong><br>generates <strong>100</strong> <strong class='color-f'>energy</strong>",
isGunTech: true,
maxCount: 9,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isIceField || tech.relayIce || tech.isNeedleIce || tech.blockingIce || tech.iceIXOnDeath || tech.isIceShot
},
requires: "ice IX",
effect() {
tech.iceEnergy++
},
remove() {
tech.iceEnergy = 0;
}
},
{
name: "superfluidity",
description: "<strong class='color-s'>freeze</strong> effects are applied<br>to a small area around the target",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1 || tech.iceIXOnDeath || tech.isIceShot
},
requires: "a localized freeze effect",
effect() {
tech.isAoESlow = true
},
remove() {
tech.isAoESlow = false
}
},
{
name: "incendiary ammunition",
description: "<strong>shotgun</strong>, <strong>rivets</strong>, <strong>super balls</strong>, and <strong>drones</strong><br>are loaded with <strong class='color-e'>explosives</strong>",
@@ -4687,26 +4711,26 @@ const tech = {
},
{
name: "shock wave",
description: "<strong>mines</strong> and <strong class='color-e'>explosions</strong> <strong>stun</strong> for <strong>1-2</strong> seconds<br><strong>30%</strong> <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong>",
description: "<strong>mines</strong> and <strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> <strong>stun</strong> for <strong>3-5</strong> seconds<br><strong class='color-e'>explosions</strong> <strong>stun</strong> for <strong>0.5</strong> seconds",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return tech.haveGunCheck("mine") || (!tech.isExplodeRadio && tech.hasExplosiveDamageCheck())
return tech.haveGunCheck("spores") || tech.haveGunCheck("mine") || (!tech.isExplodeRadio && tech.hasExplosiveDamageCheck())
},
requires: "an explosive damage source, not iridium-192",
requires: "mine, spores, an explosive damage source, not iridium-192",
effect() {
tech.isExplosionStun = true;
tech.isStun = true;
},
remove() {
tech.isExplosionStun = false;
tech.isStun = false;
}
},
{
name: "controlled explosion",
description: `use ${powerUps.orb.research(4)} to dynamically <strong>reduce</strong><br>all <strong class='color-e'>explosive</strong> radius to prevent <strong class='color-h'>health</strong> loss`,
description: `use ${powerUps.orb.research(4)} to dynamically <strong>reduce</strong><br>all <strong class='color-e'>explosions</strong> to prevent <strong class='color-h'>health</strong> loss`,
isGunTech: true,
maxCount: 1,
count: 0,
@@ -5067,24 +5091,43 @@ const tech = {
tech.isSporeGrowth = false
}
},
// {
// name: "tinsellated flagella",
// link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Zoospore#Flagella_types' class="link">tinsellated flagella</a>`,
// description: "<strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> release <strong>+2</strong> <strong class='color-p' style='letter-spacing: 2px;'>spores</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> accelerate <strong>50% faster</strong>",
// isGunTech: true,
// maxCount: 1,
// count: 0,
// frequency: 2,
// frequencyDefault: 2,
// allowed() {
// return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField
// },
// requires: "spores",
// effect() {
// tech.isFastSpores = true
// },
// remove() {
// tech.isFastSpores = false
// }
// },
{
name: "tinsellated flagella",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Zoospore#Flagella_types' class="link">tinsellated flagella</a>`,
description: "<strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> release <strong>+2</strong> <strong class='color-p' style='letter-spacing: 2px;'>spores</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> accelerate <strong>50% faster</strong>",
name: "flagella",
description: "<strong>+50%</strong> <strong class='color-p' style='letter-spacing: 2px;'>spores</strong> acceleration<br>if they can't find a target <strong class='color-p' style='letter-spacing: 2px;'>spores</strong> follow you",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField
return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isSporeWorm
},
requires: "spores",
effect() {
tech.isFastSpores = true
tech.isSporeFollow = true //isSporeFollow
},
remove() {
tech.isFastSpores = false
tech.isSporeFollow = false //isFastSpores
}
},
{
@@ -5107,25 +5150,25 @@ const tech = {
tech.isSporeFreeze = false
}
},
{
name: "diplochory",
description: "if <strong class='color-p' style='letter-spacing: 2px;'>spores</strong> can't <strong>locate</strong> a viable host<br>they use you for <strong>dispersal</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isSporeWorm
},
requires: "spores",
effect() {
tech.isSporeFollow = true
},
remove() {
tech.isSporeFollow = false
}
},
// {
// name: "diplochory",
// description: "if <strong class='color-p' style='letter-spacing: 2px;'>spores</strong> can't <strong>locate</strong> a viable host<br>they use you for <strong>dispersal</strong>",
// isGunTech: true,
// maxCount: 1,
// count: 0,
// frequency: 2,
// frequencyDefault: 2,
// allowed() {
// return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isSporeWorm
// },
// requires: "spores",
// effect() {
// tech.isSporeFollow = true
// },
// remove() {
// tech.isSporeFollow = false
// }
// },
{
name: "mutualism",
description: "<strong>+150%</strong> <strong class='color-p' style='letter-spacing: 2px;'>spore</strong> <strong class='color-d'>damage</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> borrow <strong>0.5</strong> <strong class='color-h'>health</strong> until they <strong>die</strong>",
@@ -7023,7 +7066,7 @@ const tech = {
},
{
name: "time crystals",
description: "<strong>+400%</strong> passive <strong class='color-f'>energy</strong> generation",
description: "<strong>+300%</strong> passive <strong class='color-f'>energy</strong> generation",
isFieldTech: true,
maxCount: 1,
count: 0,
@@ -8958,6 +9001,30 @@ const tech = {
},
remove() {}
},
{
name: "reincarnation",
description: "kill all mobs and spawn new ones<br>(also spawn a few extra mobs for fun)",
maxCount: 3,
count: 0,
frequency: 0,
isNonRefundable: true,
isJunk: true,
allowed() { return true },
requires: "",
effect() {
spawn.setSpawnList();
spawn.setSpawnList();
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].alive && !mob[i].shield && !mob[i].isBadTarget) {
const pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
spawn[pick](mob[i].position.x, mob[i].position.y);
if (Math.random() < 0.5) spawn[pick](mob[i].position.x, mob[i].position.y);
mob[i].death();
}
}
},
remove() {}
},
{
name: "expert system",
description: "spawn a <strong class='color-m'>tech</strong> power up<br><strong>+64%</strong> <strong class='color-j'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
@@ -9902,7 +9969,6 @@ const tech = {
isBlockRadiation: null,
isPiezo: null,
isFastDrones: null,
isFastSpores: null,
oneSuperBall: null,
laserReflections: null,
laserDamage: null,
@@ -9934,7 +10000,7 @@ const tech = {
isSporeFollow: null,
isNailRadiation: null,
isEnergyHealth: null,
isExplosionStun: null,
isStun: null,
restDamage: null,
isRPG: null,
missileCount: null,
@@ -10179,5 +10245,6 @@ const tech = {
isPetalsExplode: null,
isDeathSkipTime: null,
isIceMaxHealthLoss: null,
isIceKill: null
isIceKill: null,
isCritKill: null
}

View File

@@ -1,24 +1,63 @@
******************************************************** NEXT PATCH **************************************************
nail gun tech: stress concentration - if a mob has below 50% durability after taking damage
from needles or rivets near the center of it's body it dies
caliber 16->25% nail, needle, rivet size/damage
combined tech: flagella - spores move +50% faster
spores follow you if they can't find a target
shock wave stun also applies to sporangium
no longer reduces explosion size
JUNK tech: reincarnation - kill all mobs and spawn new ones
(also spawn a few extra mobs for fun)
updated pause menu and fields descriptions to new wording style
bug fixes
*********************************************************** TODO *****************************************************
Tech: florescence
Hitting a mob makes it emit lasers from its vertices
all laser but pulse?
should trigger a global cd so it can't occur more then once per cycle
tech spawn bots that last until you get hit
bots can check you health every cycle and see if it lower
it it's high update the health check value
JUNK?
after killing a mob go invulnerable for 1 second
critical hit with laser, harpoon, nails, needle, rivet
spawn 2 bots after exiting 1 level
or spawn 3 after 2 levels?
(randomize 2-5 bots)
replace all bot tech with this?
cloaking field
for 6 seconds after de-cloaking tell all active mobs that the player is in the wrong position?
how to code?
just delay setting the m.isCloak for a couple seconds
and also set all active bots to remember player in the de-cloaked stop
give laser gun _____ if you fire in an angle range
draw angle range as a slowly rotation circle arc around player
effect:
bonus damage
extra beams
extra reflections
scrap bots can't move?
only works for nail, foam, laser
might be tricky code?
make a new bot type called scrap bot?
nail gun needs a small damage buff
JUNK tech: Pacifism
You cannot attack mobs, mobs cannot attack you
over write the mob.damage and player.damage methods
JUNK tech: incubation: spawn something after 5 minutes
4 bots?
mob mechanic: beacon
periodically add locations to an array
teleport back to a location in the array