spore tech - nematodes - replace spores with 1/2 as many worms that do 200% more damage
  worms are also a bit faster, last longer, have better reaction times
  a cool worm graphic, and a simple searching behavior if they haven't found a mob

mycelial fragmentation - makes 6 extra spores during growth phase (was 4)

historyBoss has less health, slower tracking, and more damage
This commit is contained in:
landgreen
2021-07-16 07:06:05 -07:00
parent 7315d05460
commit d50cd540fa
9 changed files with 234 additions and 73 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -1830,10 +1830,106 @@ const b = {
Matter.Body.setVelocity(bullet[bIndex], velocity); Matter.Body.setVelocity(bullet[bIndex], velocity);
World.add(engine.world, bullet[bIndex]); //add bullet to world World.add(engine.world, bullet[bIndex]); //add bullet to world
}, },
worm(where, isFreeze = tech.isSporeFreeze) { //used with the tech upgrade in mob.death()
const bIndex = bullet.length;
const size = 3
if (bIndex < 500) { //can't make over 500 spores
bullet[bIndex] = Bodies.polygon(where.x, where.y, size, size, {
inertia: Infinity,
isFreeze: isFreeze,
restitution: 0.5,
// angle: Math.random() * 2 * Math.PI,
friction: 0,
frictionAir: 0.025,
thrust: (tech.isFastSpores ? 0.001 : 0.0005) * (1 + 0.5 * (Math.random() - 0.5)),
dmg: (tech.isMutualism ? 16.8 : 7) * 3, //bonus damage from tech.isMutualism //3 is extra damage as worm
lookFrequency: 100 + Math.floor(37 * Math.random()),
classType: "bullet",
collisionFilter: {
category: cat.bullet,
mask: cat.map | cat.mob | cat.mobBullet | cat.mobShield //no collide with body
},
endCycle: simulation.cycle + Math.floor((600 + Math.floor(Math.random() * 420)) * tech.isBulletsLastLonger),
minDmgSpeed: 0,
playerOffPosition: { //used when moving towards player to keep spores separate
x: 100 * (Math.random() - 0.5),
y: 100 * (Math.random() - 0.5)
},
beforeDmg(who) {
this.endCycle = 0; //bullet ends cycle after doing damage
if (this.isFreeze) mobs.statusSlow(who, 90)
},
onEnd() {
if (tech.isMutualism && this.isMutualismActive && !tech.isEnergyHealth) {
m.health += 0.005
if (m.health > m.maxHealth) m.health = m.maxHealth;
m.displayHealth();
}
},
do() {
ctx.beginPath(); //draw nematode
ctx.moveTo(this.position.x, this.position.y);
const dir = Vector.mult(Vector.normalise(this.velocity), -Math.min(80, 7 * this.speed))
const tail = Vector.add(this.position, dir)
ctx.lineTo(tail.x, tail.y);
ctx.lineWidth = 6;
ctx.strokeStyle = "#000";
ctx.stroke();
if (this.lockedOn && this.lockedOn.alive) {
this.force = Vector.mult(Vector.normalise(Vector.sub(this.lockedOn.position, this.position)), this.mass * this.thrust)
} else {
if (!(simulation.cycle % this.lookFrequency)) { //find mob targets
this.closestTarget = null;
this.lockedOn = null;
let closeDist = Infinity;
for (let i = 0, len = mob.length; i < len; ++i) {
if (!mob[i].isBadTarget && Matter.Query.ray(map, this.position, mob[i].position).length === 0) {
const targetVector = Vector.sub(this.position, mob[i].position)
const dist = Vector.magnitude(targetVector) * (Math.random() + 0.5);
if (dist < closeDist) {
this.closestTarget = mob[i].position;
closeDist = dist;
this.lockedOn = mob[i]
if (0.3 > Math.random()) break //doesn't always target the closest mob
}
}
}
}
if (tech.isSporeFollow && this.lockedOn === null) { //move towards player //checking for null means that the spores don't go after the player until it has looked and not found a target
const dx = this.position.x - m.pos.x;
const dy = this.position.y - m.pos.y;
if (dx * dx + dy * dy > 10000) {
this.force = Vector.mult(Vector.normalise(Vector.sub(m.pos, Vector.add(this.playerOffPosition, this.position))), this.mass * this.thrust)
}
} else {
const unit = Vector.normalise(this.velocity)
const force = Vector.mult(Vector.rotate(unit, 0.005 * this.playerOffPosition.x), 0.000003)
this.force.x += force.x
this.force.y += force.y
}
}
},
});
const SPEED = 2 + 1 * Math.random();
const ANGLE = 2 * Math.PI * Math.random()
Matter.Body.setVelocity(bullet[bIndex], {
x: SPEED * Math.cos(ANGLE),
y: SPEED * Math.sin(ANGLE)
});
World.add(engine.world, bullet[bIndex]); //add bullet to world
if (tech.isMutualism && m.health > 0.02) {
m.health -= 0.005
m.displayHealth();
bullet[bIndex].isMutualismActive = true
}
}
},
spore(where, isFreeze = tech.isSporeFreeze) { //used with the tech upgrade in mob.death() spore(where, isFreeze = tech.isSporeFreeze) { //used with the tech upgrade in mob.death()
const bIndex = bullet.length; const bIndex = bullet.length;
const size = 4
if (bIndex < 500) { //can't make over 500 spores if (bIndex < 500) { //can't make over 500 spores
bullet[bIndex] = Bodies.polygon(where.x, where.y, 4, 4, { bullet[bIndex] = Bodies.polygon(where.x, where.y, size, size, {
// density: 0.0015, //frictionAir: 0.01, // density: 0.0015, //frictionAir: 0.01,
inertia: Infinity, inertia: Infinity,
isFreeze: isFreeze, isFreeze: isFreeze,
@@ -2055,7 +2151,7 @@ const b = {
beforeDmg(who) { beforeDmg(who) {
if (tech.isIncendiary && simulation.cycle + this.deathCycles < this.endCycle) { if (tech.isIncendiary && simulation.cycle + this.deathCycles < this.endCycle) {
const max = Math.max(Math.min(this.endCycle - simulation.cycle - this.deathCycles, 1500), 0) const max = Math.max(Math.min(this.endCycle - simulation.cycle - this.deathCycles, 1500), 0)
b.explosion(this.position, max * 0.08 + this.isImproved * 100 + 60 * Math.random()); //makes bullet do explosive damage at end b.explosion(this.position, max * 0.09 + this.isImproved * 100 + 60 * Math.random()); //makes bullet do explosive damage at end
this.endCycle -= max this.endCycle -= max
} else { } else {
//move away from target after hitting //move away from target after hitting
@@ -3749,7 +3845,7 @@ const b = {
if (tech.isIncendiary) { if (tech.isIncendiary) {
bullet[me].endCycle = simulation.cycle + 60 bullet[me].endCycle = simulation.cycle + 60
bullet[me].onEnd = function() { bullet[me].onEnd = function() {
b.explosion(this.position, 300 + (Math.random() - 0.5) * 60); //makes bullet do explosive damage at end b.explosion(this.position, 320 + (Math.random() - 0.5) * 60); //makes bullet do explosive damage at end
} }
bullet[me].beforeDmg = function() { bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
@@ -3804,7 +3900,7 @@ const b = {
y: speed * Math.sin(dirOff) y: speed * Math.sin(dirOff)
}); });
bullet[me].onEnd = function() { bullet[me].onEnd = function() {
b.explosion(this.position, 135 * (tech.isShotgunReversed ? 1.6 : 1) + (Math.random() - 0.5) * 40); //makes bullet do explosive damage at end b.explosion(this.position, 150 * (tech.isShotgunReversed ? 1.6 : 1) + (Math.random() - 0.5) * 40); //makes bullet do explosive damage at end
} }
bullet[me].beforeDmg = function() { bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
@@ -3898,7 +3994,7 @@ const b = {
bullet[me].beforeDmg = function(who) { bullet[me].beforeDmg = function(who) {
mobs.statusStun(who, 180) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds) mobs.statusStun(who, 180) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds)
if (tech.isIncendiary) { if (tech.isIncendiary) {
b.explosion(this.position, this.mass * 285); //makes bullet do explosive damage at end b.explosion(this.position, this.mass * 300); //makes bullet do explosive damage at end
this.endCycle = 0 this.endCycle = 0
} }
}; };
@@ -3926,7 +4022,7 @@ const b = {
}; };
bullet[me].beforeDmg = function() { bullet[me].beforeDmg = function() {
if (tech.isIncendiary) { if (tech.isIncendiary) {
b.explosion(this.position, this.mass * 350 + 60 * Math.random()); //makes bullet do explosive damage at end b.explosion(this.position, this.mass * 355 + 70 * Math.random()); //makes bullet do explosive damage at end
this.endCycle = 0 this.endCycle = 0
} }
}; };
@@ -3958,7 +4054,7 @@ const b = {
}; };
bullet[me].beforeDmg = function() { bullet[me].beforeDmg = function() {
if (tech.isIncendiary) { if (tech.isIncendiary) {
b.explosion(this.position, this.mass * 350 + 60 * Math.random()); //makes bullet do explosive damage at end b.explosion(this.position, this.mass * 355 + 70 * Math.random()); //makes bullet do explosive damage at end
this.endCycle = 0 this.endCycle = 0
} }
}; };
@@ -4466,7 +4562,7 @@ const b = {
bullet[me].maxRadius = 30; bullet[me].maxRadius = 30;
bullet[me].restitution = 0.3; bullet[me].restitution = 0.3;
bullet[me].minDmgSpeed = 0; bullet[me].minDmgSpeed = 0;
bullet[me].totalSpores = 8 + 2 * tech.isFastSpores + 2 * tech.isSporeFreeze bullet[me].totalSpores = 8 + 2 * tech.isFastSpores + 2 * tech.isSporeFreeze * (tech.isSporeWorm ? 0.5 : 1)
bullet[me].stuck = function() {}; bullet[me].stuck = function() {};
bullet[me].beforeDmg = function() {}; bullet[me].beforeDmg = function() {};
bullet[me].do = function() { bullet[me].do = function() {
@@ -4544,11 +4640,15 @@ const b = {
this.stuck(); //runs different code based on what the bullet is stuck to this.stuck(); //runs different code based on what the bullet is stuck to
if (!m.isBodiesAsleep) { if (!m.isBodiesAsleep) {
let scale = 1.01 let scale = 1.01
if (tech.isSporeGrowth && !(simulation.cycle % 60)) { //release a spore if (tech.isSporeGrowth && !(simulation.cycle % 40)) { //release a spore
b.spore(this.position) if (tech.isSporeWorm) {
if (!(simulation.cycle % 80)) b.worm(this.position)
} else {
b.spore(this.position)
}
// this.totalSpores-- // this.totalSpores--
scale = 0.94 scale = 0.96
if (this.stuckTo && this.stuckTo.alive) scale = 0.88 if (this.stuckTo && this.stuckTo.alive) scale = 0.9
Matter.Body.scale(this, scale, scale); Matter.Body.scale(this, scale, scale);
this.radius *= scale this.radius *= scale
} else { } else {
@@ -4570,9 +4670,10 @@ const b = {
//spawn bullets on end //spawn bullets on end
bullet[me].onEnd = function() { bullet[me].onEnd = function() {
const NUM = this.totalSpores if (tech.isSporeWorm) {
for (let i = 0; i < NUM; i++) { for (let i = 0, len = this.totalSpores * 0.5; i < len; i++) b.worm(this.position)
b.spore(this.position) } else {
for (let i = 0; i < this.totalSpores; i++) b.spore(this.position)
} }
} }
} }

View File

@@ -176,7 +176,6 @@ function collisionChecks(event) {
if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) { if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) {
obj.beforeDmg(mob[k]); //some bullets do actions when they hits things, like despawn //forces don't seem to work here 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))) let dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)))
console.log(dmg)
if (tech.isCrit && mob[k].isStunned) dmg *= 4 if (tech.isCrit && mob[k].isStunned) dmg *= 4
mob[k].foundPlayer(); mob[k].foundPlayer();
mob[k].damage(dmg); mob[k].damage(dmg);

View File

@@ -15,13 +15,14 @@ const level = {
// level.difficultyIncrease(30) // level.difficultyIncrease(30)
// simulation.isHorizontalFlipped = true // simulation.isHorizontalFlipped = true
// m.setField("wormhole") // m.setField("wormhole")
// b.giveGuns("drones") // b.giveGuns("spores")
// tech.isSporeWorm = true
// tech.giveTech("tinsellated flagella")
// tech.giveTech("torque bursts") // tech.giveTech("torque bursts")
// b.giveGuns("wave beam") // b.giveGuns("wave beam")
// tech.giveTech("phonon") // tech.giveTech("phonon")
// tech.giveTech("bound state") // tech.giveTech("bound state")
// tech.giveTech("bound state") // tech.giveTech("bound state")
// tech.giveTech("bound state")
// tech.giveTech("isotropic radiator") // tech.giveTech("isotropic radiator")
// for (let i = 0; i < 9; i++) tech.giveTech("spherical harmonics") // for (let i = 0; i < 9; i++) tech.giveTech("spherical harmonics")
// for (let i = 0; i < 3; i++) tech.giveTech("packet length") // for (let i = 0; i < 3; i++) tech.giveTech("packet length")
@@ -2253,7 +2254,7 @@ const level = {
spawn.mapRect(6700, -1800, 800, 2600); //right wall spawn.mapRect(6700, -1800, 800, 2600); //right wall
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
// spawn.starter(1900, -500, 200) //big boy spawn.starter(1900, -500, 200) //big boy
// spawn.pulsarBoss(1900, -500) // spawn.pulsarBoss(1900, -500)
// spawn.shieldingBoss(1900, -500) // spawn.shieldingBoss(1900, -500)
// spawn.grenadierBoss(1900, -500) // spawn.grenadierBoss(1900, -500)
@@ -2269,7 +2270,7 @@ const level = {
// spawn.orbitalBoss(1600, -500) // spawn.orbitalBoss(1600, -500)
// spawn.cellBossCulture(1600, -500) // spawn.cellBossCulture(1600, -500)
// spawn.shieldingBoss(1600, -500) // spawn.shieldingBoss(1600, -500)
spawn.grenadier(1200, -500) // spawn.grenadier(1200, -500)
// spawn.shield(mob[mob.length - 1], 1800, -120, 1); // spawn.shield(mob[mob.length - 1], 1800, -120, 1);
// spawn.nodeGroup(1200, -500, "grenadier") // spawn.nodeGroup(1200, -500, "grenadier")
@@ -6313,15 +6314,21 @@ const level = {
// spawn.randomGroup(7700, -1100, 0.5); // spawn.randomGroup(7700, -1100, 0.5);
spawn.randomGroup(9800, -1100, 0.5); spawn.randomGroup(9800, -1100, 0.5);
if (simulation.difficulty > 10) spawn.randomLevelBoss(8600, -600, ["powerUpBoss", "bomberBoss", "snakeBoss", "spiderBoss", "historyBoss"]) if (simulation.difficulty > 3) spawn.randomLevelBoss(8600, -600, ["powerUpBoss", "bomberBoss", "snakeBoss", "spiderBoss", "historyBoss"])
spawn.secondaryBossChance(7900, -400) spawn.secondaryBossChance(7900, -400)
//Boss Spawning //Boss Spawning
if (simulation.difficulty > 10) { if (simulation.difficulty > 10) {
spawn.pulsarBoss(-400, -200); spawn.pulsarBoss(-400, -200);
powerUps.chooseRandomPowerUp(4006, 400);
powerUps.chooseRandomPowerUp(4407, 400);
powerUps.spawnStartingPowerUps(4400, 400);
if (simulation.difficulty > 30) { if (simulation.difficulty > 30) {
powerUps.chooseRandomPowerUp(4002, 400);
powerUps.chooseRandomPowerUp(4004, 400);
spawn.pulsarBoss(3600, -400); spawn.pulsarBoss(3600, -400);
if (simulation.difficulty > 60) { if (simulation.difficulty > 60) {
powerUps.chooseRandomPowerUp(4409, 400);
spawn.pulsarBoss(4200, 1000); spawn.pulsarBoss(4200, 1000);
if (simulation.difficulty > 80) { if (simulation.difficulty > 80) {
spawn.pulsarBoss(5800, -1200); spawn.pulsarBoss(5800, -1200);
@@ -6338,12 +6345,6 @@ const level = {
//Powerup Spawning //Powerup Spawning
powerUps.spawnStartingPowerUps(4000, 400); powerUps.spawnStartingPowerUps(4000, 400);
powerUps.spawnStartingPowerUps(4400, 400);
powerUps.chooseRandomPowerUp(4002, 400);
powerUps.chooseRandomPowerUp(4004, 400);
powerUps.chooseRandomPowerUp(4006, 400);
powerUps.chooseRandomPowerUp(4407, 400);
powerUps.chooseRandomPowerUp(4409, 400);
powerUps.addResearchToLevel(); //needs to run after mobs are spawned powerUps.addResearchToLevel(); //needs to run after mobs are spawned
//Block Spawning //Block Spawning

View File

@@ -1066,8 +1066,13 @@ const mobs = {
powerUps.spawnRandomPowerUp(this.position.x, this.position.y); powerUps.spawnRandomPowerUp(this.position.x, this.position.y);
m.lastKillCycle = m.cycle; //tracks the last time a kill was made, mostly used in simulation.checks() m.lastKillCycle = m.cycle; //tracks the last time a kill was made, mostly used in simulation.checks()
if (Math.random() < tech.sporesOnDeath) { if (Math.random() < tech.sporesOnDeath) {
const len = Math.min(25, Math.floor(2 + this.mass * (0.5 + 0.5 * Math.random()))) if (tech.isSporeWorm) {
for (let i = 0; i < len; i++) b.spore(this.position) const len = Math.min(25, Math.floor(2 + this.mass * (0.5 + 0.5 * Math.random()))) / 2
for (let i = 0; i < len; i++) b.worm(this.position)
} else {
const len = Math.min(25, Math.floor(2 + this.mass * (0.5 + 0.5 * Math.random())))
for (let i = 0; i < len; i++) b.spore(this.position)
}
} else if (tech.isExplodeMob) { } else if (tech.isExplodeMob) {
b.explosion(this.position, Math.min(600, Math.sqrt(this.mass + 1.5) * (22 + 60 * Math.random()))) b.explosion(this.position, Math.min(600, Math.sqrt(this.mass + 1.5) * (22 + 60 * Math.random())))
} else if (tech.nailsDeathMob) { } else if (tech.nailsDeathMob) {

View File

@@ -1814,15 +1814,29 @@ const m = {
m.hold = function() { m.hold = function() {
if (m.energy > m.maxEnergy - 0.02 && m.fieldCDcycle < m.cycle && !input.field && bullet.length < 150 && (m.cycle % 2)) { if (m.energy > m.maxEnergy - 0.02 && m.fieldCDcycle < m.cycle && !input.field && bullet.length < 150 && (m.cycle % 2)) {
if (tech.isSporeField) { if (tech.isSporeField) {
for (let i = 0, len = Math.random() * 20; i < len; i++) { if (tech.isSporeWorm) {
m.energy -= 0.08 for (let i = 0, len = Math.random() * 20; i < len; i++) {
if (m.energy > 0) { m.energy -= 0.15
b.spore(m.pos) if (m.energy > 0) {
} else { b.worm(m.pos)
m.energy = 0.001 } else {
break; m.energy = 0.001
break;
}
}
} else {
for (let i = 0, len = Math.random() * 20; i < len; i++) {
m.energy -= 0.08
if (m.energy > 0) {
b.spore(m.pos)
} else {
m.energy = 0.001
break;
}
} }
} }
} else if (tech.isMissileField) { } else if (tech.isMissileField) {
m.energy -= 0.3; m.energy -= 0.3;
b.missile({ x: m.pos.x, y: m.pos.y - 40 }, -Math.PI / 2 + 0.5 * (Math.random() - 0.5), 0, 1) b.missile({ x: m.pos.x, y: m.pos.y - 40 }, -Math.PI / 2 + 0.5 * (Math.random() - 0.5), 0, 1)
@@ -2588,7 +2602,7 @@ const m = {
m.fieldRange *= 0.8 m.fieldRange *= 0.8
if (tech.isWormholeEnergy) m.energy += 0.63 if (tech.isWormholeEnergy) m.energy += 0.63
if (tech.isWormSpores) { //pandimensionalspermia if (tech.isWormSpores) { //pandimensionalspermia
for (let i = 0, len = Math.ceil(3 * Math.random()); i < len; i++) { for (let i = 0, len = Math.ceil(3 * (tech.isSporeWorm ? 0.5 : 1) * Math.random()); i < len; i++) {
b.spore(Vector.add(m.hole.pos2, Vector.rotate({ b.spore(Vector.add(m.hole.pos2, Vector.rotate({
x: m.fieldRange * 0.4, x: m.fieldRange * 0.4,
y: 0 y: 0
@@ -2614,7 +2628,7 @@ const m = {
// if (tech.isWormholeEnergy && m.energy < m.maxEnergy * 2) m.energy = m.maxEnergy * 2 // if (tech.isWormholeEnergy && m.energy < m.maxEnergy * 2) m.energy = m.maxEnergy * 2
if (tech.isWormholeEnergy) m.energy += 0.63 if (tech.isWormholeEnergy) m.energy += 0.63
if (tech.isWormSpores) { //pandimensionalspermia if (tech.isWormSpores) { //pandimensionalspermia
for (let i = 0, len = Math.ceil(3 * Math.random()); i < len; i++) { for (let i = 0, len = Math.ceil(3 * (tech.isSporeWorm ? 0.5 : 1) * Math.random()); i < len; i++) {
b.spore(Vector.add(m.hole.pos1, Vector.rotate({ b.spore(Vector.add(m.hole.pos1, Vector.rotate({
x: m.fieldRange * 0.4, x: m.fieldRange * 0.4,
y: 0 y: 0

View File

@@ -1582,7 +1582,7 @@ const spawn = {
} }
mobs.spawn(x, y, 0, radius, "transparent"); mobs.spawn(x, y, 0, radius, "transparent");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
Matter.Body.setDensity(me, 0.25); //extra dense //normal is 0.001 Matter.Body.setDensity(me, 0.20); //extra dense //normal is 0.001
me.laserRange = 300; me.laserRange = 300;
me.seeAtDistance2 = 2000000; me.seeAtDistance2 = 2000000;
me.isBoss = true; me.isBoss = true;
@@ -1621,8 +1621,11 @@ const spawn = {
ctx.setLineDash([125 * Math.random(), 125 * Math.random()]); //the dashed effect is not set back to normal, because it looks neat for how the player is drawn ctx.setLineDash([125 * Math.random(), 125 * Math.random()]); //the dashed effect is not set back to normal, because it looks neat for how the player is drawn
// ctx.lineDashOffset = 6*(simulation.cycle % 215); // ctx.lineDashOffset = 6*(simulation.cycle % 215);
if (this.distanceToPlayer() < this.laserRange) { if (this.distanceToPlayer() < this.laserRange) {
if (m.energy > 0.002) m.energy -= 0.0035 if (m.energy > 0.002) {
if (m.immuneCycle < m.cycle) m.damage(0.00025 * simulation.dmgScale); m.energy -= 0.0035
} else if (m.immuneCycle < m.cycle) {
m.damage(0.0003 * simulation.dmgScale)
}
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(eye.x, eye.y); ctx.moveTo(eye.x, eye.y);
ctx.lineTo(m.pos.x, m.pos.y); ctx.lineTo(m.pos.x, m.pos.y);
@@ -1659,7 +1662,7 @@ const spawn = {
// ctx.fillStyle = "rgba(150,0,255,0.03)"; // ctx.fillStyle = "rgba(150,0,255,0.03)";
// ctx.fill(); // ctx.fill();
if (!m.isBodiesAsleep && !this.isStunned && !this.isSlowed) { if (!m.isBodiesAsleep && !this.isStunned && !this.isSlowed) {
if (this.followDelay > this.delayLimit) this.followDelay -= 0.3; if (this.followDelay > this.delayLimit) this.followDelay -= 0.2;
let history = m.history[(m.cycle - Math.floor(this.followDelay)) % 600] let history = m.history[(m.cycle - Math.floor(this.followDelay)) % 600]
Matter.Body.setPosition(this, { x: history.position.x, y: history.position.y - history.yOff + 24.2859 }) //bullets move with player Matter.Body.setPosition(this, { x: history.position.x, y: history.position.y - history.yOff + 24.2859 }) //bullets move with player
} }

View File

@@ -852,8 +852,8 @@
description: "<strong>shotgun</strong>, <strong>super balls</strong>, and <strong>drones</strong><br>are loaded with <strong class='color-e'>explosives</strong>", description: "<strong>shotgun</strong>, <strong>super balls</strong>, and <strong>drones</strong><br>are loaded with <strong class='color-e'>explosives</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 1,
frequencyDefault: 2, frequencyDefault: 1,
allowed() { allowed() {
return ((m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isDroneRadioactive) || tech.haveGunCheck("super balls") || tech.haveGunCheck("shotgun")) && !tech.isNailShot return ((m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isDroneRadioactive) || tech.haveGunCheck("super balls") || tech.haveGunCheck("shotgun")) && !tech.isNailShot
}, },
@@ -932,8 +932,11 @@
requires: "no other mob death tech", requires: "no other mob death tech",
effect() { effect() {
tech.sporesOnDeath += 0.11; tech.sporesOnDeath += 0.11;
for (let i = 0; i < 8; i++) { if (tech.isSporeWorm) {
b.spore(m.pos) for (let i = 0; i < 4; i++) b.worm(m.pos)
} else {
for (let i = 0; i < 8; i++) b.spore(m.pos)
} }
}, },
remove() { remove() {
@@ -4257,7 +4260,7 @@
}, },
{ {
name: "mycelial fragmentation", name: "mycelial fragmentation",
description: "<strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> release an extra <strong class='color-p' style='letter-spacing: 2px;'>spore</strong><br> once a <strong>second</strong> during their <strong>growth</strong> phase", description: "<strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> release <strong>6</strong> extra <strong class='color-p' style='letter-spacing: 2px;'>spores</strong><br>during their <strong>growth</strong> phase",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -4332,6 +4335,25 @@
tech.isSporeFollow = false tech.isSporeFollow = false
} }
}, },
{
name: "nematodes",
description: "replace <strong class='color-p' style='letter-spacing: 2px;'>spores</strong> with <strong>50%</strong> fewer <strong class='color-p'>worms</strong><br><strong class='color-p'>worms</strong> do <strong>200%</strong> more <strong class='color-d'>damage</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 4,
frequencyDefault: 4,
allowed() {
return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField
},
requires: "spores",
effect() {
tech.isSporeWorm = true
},
remove() {
tech.isSporeWorm = false
}
},
{ {
name: "mutualism", name: "mutualism",
description: "increase <strong class='color-p' style='letter-spacing: 2px;'>spore</strong> <strong class='color-d'>damage</strong> by <strong>150%</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> borrow <strong>0.5</strong> <strong class='color-h'>health</strong> until they <strong>die</strong>", description: "increase <strong class='color-p' style='letter-spacing: 2px;'>spore</strong> <strong class='color-d'>damage</strong> by <strong>150%</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> borrow <strong>0.5</strong> <strong class='color-h'>health</strong> until they <strong>die</strong>",
@@ -5805,20 +5827,24 @@
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 0, frequency: 0,
isNonRefundable: true,
isBadRandomOption: true, isBadRandomOption: true,
isExperimentalMode: true, isExperimentalMode: true,
allowed() { allowed() {
return build.isExperimentSelection return build.isExperimentSelection
}, },
requires: "", requires: "",
interval: undefined,
effect() { effect() {
setInterval(() => { this.interval = setInterval(() => {
m.switchWorlds() if (!build.isExperimentSelection) {
simulation.trails() m.switchWorlds()
simulation.trails()
}
}, 20000); //every 20 seconds }, 20000); //every 20 seconds
}, },
remove() {} remove() {
if (this.count > 0) clearTimeout(this.interval);
}
}, },
{ {
name: "-shields-", name: "-shields-",
@@ -5826,7 +5852,6 @@
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 0, frequency: 0,
isNonRefundable: true,
isBadRandomOption: true, isBadRandomOption: true,
isExperimentalMode: true, isExperimentalMode: true,
allowed() { allowed() {
@@ -5834,13 +5859,18 @@
}, },
requires: "", requires: "",
effect() { effect() {
setInterval(() => { this.interval = setInterval(() => {
for (let i = 0; i < mob.length; i++) { if (!build.isExperimentSelection) {
if (!mob[i].isShielded && !mob[i].shield && mob[i].isDropPowerUp) spawn.shield(mob[i], mob[i].position.x, mob[i].position.y, 1, true); for (let i = 0; i < mob.length; i++) {
if (!mob[i].isShielded && !mob[i].shield && mob[i].isDropPowerUp) spawn.shield(mob[i], mob[i].position.x, mob[i].position.y, 1, true);
}
} }
}, 5000); //every 5 seconds }, 5000); //every 5 seconds
}, },
remove() {} interval: undefined,
remove() {
if (this.count > 0) clearTimeout(this.interval);
}
}, },
{ {
name: "-Fourier analysis-", name: "-Fourier analysis-",
@@ -5848,7 +5878,6 @@
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 0, frequency: 0,
isNonRefundable: true,
isBadRandomOption: true, isBadRandomOption: true,
isExperimentalMode: true, isExperimentalMode: true,
allowed() { allowed() {
@@ -5865,7 +5894,9 @@
m.transY += (m.transSmoothY - m.transY) * 0.07; m.transY += (m.transSmoothY - m.transY) * 0.07;
} }
}, },
remove() {} remove() {
if (this.count > 0) m.look = m.lookDefault()
}
}, },
{ {
name: "-panopticon-", name: "-panopticon-",
@@ -5873,7 +5904,6 @@
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 0, frequency: 0,
isNonRefundable: true,
isBadRandomOption: true, isBadRandomOption: true,
isExperimentalMode: true, isExperimentalMode: true,
allowed() { allowed() {
@@ -5881,16 +5911,21 @@
}, },
requires: "", requires: "",
effect() { effect() {
setInterval(() => { this.interval = setInterval(() => {
for (let i = 0; i < mob.length; i++) { if (!build.isExperimentSelection) {
if (!mob[i].shield && mob[i].isDropPowerUp) { for (let i = 0; i < mob.length; i++) {
mob[i].locatePlayer() if (!mob[i].shield && mob[i].isDropPowerUp) {
mob[i].seePlayer.yes = true; mob[i].locatePlayer()
mob[i].seePlayer.yes = true;
}
} }
} }
}, 1000); //every 1 seconds }, 1000); //every 1 seconds
}, },
remove() {} interval: undefined,
remove() {
if (this.count > 0) clearTimeout(this.interval);
}
}, },
{ {
name: "-decomposers-", name: "-decomposers-",
@@ -7506,5 +7541,6 @@
harmonicEnergy: null, harmonicEnergy: null,
isFieldHarmReduction: null, isFieldHarmReduction: null,
isFastTime: null, isFastTime: null,
isDroneTeleport: null isDroneTeleport: null,
isSporeWorm: null
} }

View File

@@ -1,15 +1,15 @@
******************************************************** NEXT PATCH ******************************************************** ******************************************************** NEXT PATCH ********************************************************
spore tech - nematodes - replace spores with 1/2 as many worms that do 200% more damage
worms are also a bit faster, last longer, have better reaction times
a cool worm graphic, and a simple searching behavior if they haven't found a mob
mycelial fragmentation - makes 6 extra spores during growth phase (was 4)
historyBoss has less health, slower tracking, and more damage
******************************************************** TODO ******************************************************** ******************************************************** TODO ********************************************************
give drones or spores some mobs abilities
striker: teleport towards target
drone tech: snakes
I haven't thought about this much, but I don't know make them look like snakes...
scrolling console history in pause menu? scrolling console history in pause menu?
also make tech, guns scrolling? also make tech, guns scrolling?
in testing mode console log the body you click on in testing mode console log the body you click on
@@ -18,6 +18,8 @@ pause should at least show the last in game console message
make the player get a buff after using wormhole make the player get a buff after using wormhole
while energy lasts: drain energy and give damage buff while energy lasts: drain energy and give damage buff
Tech: "Induced Oscillation": When using phonon, if a block vibrates after it gets hit from a phonon, it has a chance of oscillating and creating an additional phonon coming from the block. The chance is higher the closer the block is to the source of the oscillation.
tech: quantized shields - harmonic standing wave field can only lose 33 energy per hit 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? draw 1,2,3 levels of the field based on energy?
the blocked value only scales up to 2x or 4x (33 energy) blocked the blocked value only scales up to 2x or 4x (33 energy) blocked