not a full patch, just syncing between my 2 computers

This commit is contained in:
landgreen
2022-12-28 12:35:03 -08:00
parent 3cbc2c7941
commit feb8824bc7
12 changed files with 473 additions and 313 deletions

View File

@@ -1857,17 +1857,12 @@ const b = {
}
}
}
if (tech.isFoamBall) {
for (let i = 0, len = 4 * this.mass; i < len; i++) {
for (let i = 0, len = Math.min(50, 3 + 4 * Math.sqrt(this.mass)); i < len; i++) {
const radius = 5 + 8 * Math.random()
const velocity = {
x: Math.max(0.5, 2 - radius * 0.1),
y: 0
}
const velocity = {x: Math.max(0.5, 2 - radius * 0.1),y: 0}
b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
}
// this.endCycle = 0;
}
},
caughtPowerUp: null,
@@ -3768,6 +3763,72 @@ const b = {
y: speed * Math.sin(dir)
});
},
superBall(where, velocity, radius){
let dir = m.angle
const me = bullet.length;
bullet[me] = Bodies.polygon(where.x,where.y, 12, radius, b.fireAttributes(dir, false));
Composite.add(engine.world, bullet[me]); //add bullet to world
Matter.Body.setVelocity(bullet[me], velocity);
Matter.Body.setDensity(bullet[me], 0.0001 + 0.001 * tech.isSuperHarm);
bullet[me].endCycle = simulation.cycle + Math.floor(300 + 90 * Math.random());
bullet[me].minDmgSpeed = 0;
bullet[me].restitution = 1;
bullet[me].friction = 0;
if (tech.isIncendiary) {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
if (Matter.Query.collides(this, map).length) {
b.explosion(this.position, this.mass * 280); //makes bullet do explosive damage at end
this.endCycle = 0
}
};
} else if (tech.isSuperHarm){
bullet[me].collidePlayerDo = function(){
if (Matter.Query.collides(this, [player]).length) {
this.endCycle = 0
let dmg = 0.03
m.damage(dmg);
simulation.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,
radius: Math.sqrt(dmg) * 200,
color: simulation.mobDmgColor,
time: simulation.drawTime*2
});
}
}
bullet[me].cycle= 0
bullet[me].do = function() {
this.cycle++
if (this.cycle > 60) this.do = this.collidePlayerDo
this.force.y += this.mass * 0.0012;
};
} else {
bullet[me].do = function() {
this.cycle++
this.force.y += this.mass * 0.0012;
};
}
bullet[me].beforeDmg = function(who) {
if (tech.oneSuperBall) mobs.statusStun(who, 120) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds)
// if (tech.isIncendiary) {
// b.explosion(this.position, this.mass * (240+70 * Math.random()) ); //makes bullet do explosive damage at end
// this.endCycle = 0
// }
if (tech.isFoamBall) {
for (let i = 0, len = 6 * this.mass; i < len; i++) {
const radius = 5 + 8 * Math.random()
// const velocity = { x: Math.max(2, 10 - radius * 0.25), y: 0 }
const velocity = {
x: Math.max(0.5, 2 - radius * 0.1),
y: 0
}
b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
}
this.endCycle = 0
}
};
},
// plasmaBall(position, velocity, radius) {
// // radius *= Math.sqrt(tech.bulletSize)
// const me = bullet.length;
@@ -6110,181 +6171,59 @@ const b = {
do() {},
foamBall() {
},
fireOne() {
const SPEED = input.down ? 40 : 33
m.fireCDcycle = m.cycle + Math.floor((input.down ? 27 : 19) * b.fireCDscale); // cool down
let dir = m.angle
const me = bullet.length;
bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, 21 * tech.bulletSize, b.fireAttributes(dir, false));
Composite.add(engine.world, bullet[me]); //add bullet to world
Matter.Body.setVelocity(bullet[me], {
x: SPEED * Math.cos(dir),
y: SPEED * Math.sin(dir)
});
// Matter.Body.setDensity(bullet[me], 0.0001);
bullet[me].endCycle = simulation.cycle + Math.floor(300 + 90 * Math.random());
bullet[me].minDmgSpeed = 0;
bullet[me].restitution = 1;
bullet[me].friction = 0;
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
};
if (tech.isIncendiary) {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
if (Matter.Query.collides(this, map).length) {
b.explosion(this.position, this.mass * 280); //makes bullet do explosive damage at end
this.endCycle = 0
}
};
} else {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
};
}
bullet[me].beforeDmg = function(who) {
mobs.statusStun(who, 120) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds)
if (tech.isIncendiary) {
b.explosion(this.position, this.mass * 280); //makes bullet do explosive damage at end
this.endCycle = 0
}
if (tech.isFoamBall) {
for (let i = 0, len = 6 * this.mass; i < len; i++) {
const radius = 5 + 8 * Math.random()
// const velocity = { x: Math.max(2, 10 - radius * 0.25), y: 0 }
const velocity = {
x: Math.max(0.5, 2 - radius * 0.1),
y: 0
}
b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
}
this.endCycle = 0
}
};
const speed = input.down ? 43 : 36
b.superBall({
x:m.pos.x + 30 * Math.cos(m.angle),
y:m.pos.y + 30 * Math.sin(m.angle)
},{
x: speed * Math.cos(m.angle),
y: speed * Math.sin(m.angle)
}, 21 * tech.bulletSize)
},
fireMulti() {
const SPEED = input.down ? 43 : 36
m.fireCDcycle = m.cycle + Math.floor((input.down ? 23 : 15) * b.fireCDscale); // cool down
const SPREAD = input.down ? 0.08 : 0.13
const num = 3 + Math.floor(tech.extraSuperBalls * Math.random())
const radius = 11 * tech.bulletSize
const speed = input.down ? 43 : 36
let dir = m.angle - SPREAD * (num - 1) / 2;
for (let i = 0; i < num; i++) {
const me = bullet.length;
bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, radius, b.fireAttributes(dir, false));
Composite.add(engine.world, bullet[me]); //add bullet to world
Matter.Body.setVelocity(bullet[me], {
x: SPEED * Math.cos(dir),
y: SPEED * Math.sin(dir)
});
// Matter.Body.setDensity(bullet[me], 0.0001);
bullet[me].endCycle = simulation.cycle + Math.floor((300 + 90 * Math.random()) * tech.isBulletsLastLonger);
bullet[me].minDmgSpeed = 0;
bullet[me].restitution = 0.99;
bullet[me].friction = 0;
if (tech.isIncendiary) {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
if (Matter.Query.collides(this, map).length) {
b.explosion(this.position, this.mass * 280); //makes bullet do explosive damage at end
this.endCycle = 0
}
};
} else {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
};
}
bullet[me].beforeDmg = function() {
if (tech.isIncendiary) {
b.explosion(this.position, this.mass * 320 + 70 * Math.random()); //makes bullet do explosive damage at end
this.endCycle = 0
}
if (tech.isFoamBall) {
for (let i = 0, len = 6 * this.mass; i < len; i++) {
const radius = 5 + 8 * Math.random()
const velocity = {
x: Math.max(0.5, 2 - radius * 0.1),
y: 0
}
b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
}
this.endCycle = 0
// this.mass = 0 //prevent damage
}
};
b.superBall({
x:m.pos.x + 30 * Math.cos(dir),
y:m.pos.y + 30 * Math.sin(dir)
},{
x: speed * Math.cos(dir),
y: speed * Math.sin(dir)
}, 11 * tech.bulletSize)
dir += SPREAD;
}
},
fireQueue() {
// const dir = m.angle
// const x = m.pos.x
// const y = m.pos.y
const SPEED = input.down ? 43 : 36
m.fireCDcycle = m.cycle + Math.floor((input.down ? 23 : 15) * b.fireCDscale); // cool down
const num = 1 + 3 + Math.floor(tech.extraSuperBalls * Math.random()) //1 extra
const speed = input.down ? 43 : 36
const delay = Math.floor((input.down ? 18 : 12) * b.fireCDscale)
m.fireCDcycle = m.cycle + delay; // cool down
const fireBall = () => {
const me = bullet.length;
bullet[me] = Bodies.polygon(m.pos.x, m.pos.y, 12, 11 * tech.bulletSize, b.fireAttributes(m.angle, false));
Composite.add(engine.world, bullet[me]); //add bullet to world
Matter.Body.setVelocity(bullet[me], {
x: SPEED * Math.cos(m.angle),
y: SPEED * Math.sin(m.angle)
});
bullet[me].endCycle = simulation.cycle + Math.floor(330 * tech.isBulletsLastLonger);
bullet[me].minDmgSpeed = 0;
bullet[me].restitution = 0.99;
bullet[me].friction = 0;
if (tech.isIncendiary) {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
if (Matter.Query.collides(this, map).length) {
b.explosion(this.position, this.mass * 280); //makes bullet do explosive damage at end
this.endCycle = 0
}
};
} else {
bullet[me].do = function() {
this.force.y += this.mass * 0.0012;
};
}
bullet[me].beforeDmg = function() {
if (tech.isIncendiary) {
b.explosion(this.position, this.mass * 320 + 70 * Math.random()); //makes bullet do explosive damage at end
this.endCycle = 0
}
if (tech.isFoamBall) {
for (let i = 0, len = 6 * this.mass; i < len; i++) {
const radius = 5 + 8 * Math.random()
const velocity = {
x: Math.max(0.5, 2 - radius * 0.1),
y: 0
}
b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
}
this.endCycle = 0
// this.mass = 0 //prevent damage
}
};
m.fireCDcycle = m.cycle + delay; // cool down
}
function cycle() {
// if (simulation.paused || m.isBodiesAsleep) {
// requestAnimationFrame(cycle)
// } else {
count++
// if (count % 2)
fireBall()
b.superBall({
x:m.pos.x + 30 * Math.cos(m.angle),
y:m.pos.y + 30 * Math.sin(m.angle)
},{
x: speed * Math.cos(m.angle),
y: speed * Math.sin(m.angle)
}, 11 * tech.bulletSize)
if (count < num && m.alive) requestAnimationFrame(cycle);
// }
m.fireCDcycle = m.cycle + delay; // cool down
}
let count = 0
requestAnimationFrame(cycle);
// fireBall();
},
chooseFireMethod() { //set in simulation.startGame
if (tech.oneSuperBall) {
@@ -6871,17 +6810,13 @@ const b = {
});
that.do = that.grow;
}
const mobCollisions = Matter.Query.collides(this, mob)
if (mobCollisions.length) {
onCollide(this)
this.stuckTo = mobCollisions[0].bodyA
if (tech.isZombieMobs) this.stuckTo.isSoonZombie = true
if (this.stuckTo.isVerticesChange) {
this.stuckToRelativePosition = {
x: 0,
y: 0
}
this.stuckToRelativePosition = {x: 0, y: 0}
} else {
//find the relative position for when the mob is at angle zero by undoing the mobs rotation
this.stuckToRelativePosition = Vector.rotate(Vector.sub(this.position, this.stuckTo.position), -this.stuckTo.angle)
@@ -6968,7 +6903,6 @@ const b = {
};
//spawn bullets on end
bullet[me].onEnd = function() {
let count = 0 //used in for loop below
const things = [
() => { //spore
@@ -7000,6 +6934,14 @@ const b = {
() => { //nail
b.targetedNail(this.position, 1, 39 + 6 * Math.random())
},
() => { //super ball
const speed = 36
const angle = 2*Math.PI*Math.random()
b.superBall(this.position,{
x: speed * Math.cos(angle),
y: speed * Math.sin(angle)
}, 11 * tech.bulletSize)
},
]
for (len = this.totalSpores; count < len; count++) {

View File

@@ -588,7 +588,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
},
populateGrid() { //background-color:var(--build-bg-color);
let text = `
<div class="experiment-grid-module" style="position: sticky; top:0; z-index: 10; align-self: start; width: 160px; font-size: 1.00em; line-height: 170%; background-color: #fafcfd;display: flex; flex-direction: column; justify-content: center; align-items: center;border: 1.5px #333 solid;border-radius:10px;">
<div class="experiment-grid-module" style="position: sticky; top:0; z-index: 10; align-self: start; width: 165px; font-size: 1.00em; line-height: 170%; background-color: #fafcfd;display: flex; flex-direction: column; justify-content: center; align-items: center;border: 1.5px #333 solid;border-radius:10px;">
<div>
<svg class="SVG-button" onclick="build.startExperiment()" width="150" height="68" >
<g stroke='none' fill='#333' stroke-width="2" font-size="60px" font-family="Ariel, sans-serif">

View File

@@ -31,19 +31,21 @@ const level = {
// b.giveGuns("nail gun") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.giveGuns("spores") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.guns[0].ammo = 10000
// tech.giveTech("alternator")
// tech.giveTech("posture")
// for (let i = 0; i < 1; ++i) tech.giveTech("Sleipnir")
// tech.giveTech("Zectron")
// tech.giveTech("cordyceps")
// for (let i = 0; i < 1; ++i) tech.giveTech("super ball")
// tech.isFoamBall = true
// for (let i = 0; i < 9; ++i) tech.giveTech("emergence")
// for (let i = 0; i < 1; ++i) tech.giveTech("incendiary ammunition")
// for (let i = 0; i < 2; i++) tech.giveTech("unified field theory")
// for (let i = 0; i < 9; i++) tech.giveTech("replication")
// for (let i = 0; i < 1; i++) tech.giveTech("colony")
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "boost");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling");
// level.testing();
// spawn.shooter(1900, -500, 200)
// spawn.starter(1900, -500)
// spawn.sneakBoss(1900, -500)
// spawn.starter(1900, -500, 25)
// spawn.sneaker(1900, -500, 25)
// spawn.hopper(2538, -950)
// for (let i = 0; i < 2; ++i) spawn.starter(1000 + 1000 * Math.random(), -500 + 300 * Math.random())
// tech.addJunkTechToPool(2)

View File

@@ -1192,23 +1192,21 @@ const mobs = {
this.alive = false; //triggers mob removal in mob[i].replace(i)
if (this.isDropPowerUp) {
// if (true) { //spawn zombie on death
// // console.log(this)
// this.leaveBody = false;
// let count = 45 //delay spawn cycles
// let cycle = () => {
// if (count > 0) {
// if (m.alive) requestAnimationFrame(cycle);
// if (!simulation.paused && !simulation.isChoosing) {
// count--
// }
// } else {
// spawn.zombie(this.position.x, this.position.y, this.radius, this.vertices.length, this.fill) // zombie(x, y, radius, sides, color)
// }
// }
// requestAnimationFrame(cycle);
// }
if (this.isSoonZombie) { //spawn zombie on death
this.leaveBody = false;
let count = 45 //delay spawn cycles
let cycle = () => {
if (count > 0) {
if (m.alive) requestAnimationFrame(cycle);
if (!simulation.paused && !simulation.isChoosing) {
count--
}
} else {
spawn.zombie(this.position.x, this.position.y, this.radius, this.vertices.length, this.fill) // zombie(x, y, radius, sides, color)
}
}
requestAnimationFrame(cycle);
}
@@ -1248,19 +1246,19 @@ const mobs = {
mobs.mobDeaths++
if (Math.random() < tech.sporesOnDeath) {
const amount = Math.min(25, Math.floor(2 + this.mass * (0.5 + 0.5 * Math.random())))
if (tech.isSporeFlea) {
const len = Math.min(25, Math.floor(2 + this.mass * (0.5 + 0.5 * Math.random()))) / 2
const len = amount / 2
for (let i = 0; i < len; i++) {
const speed = 10 + 5 * Math.random()
const angle = 2 * Math.PI * Math.random()
b.flea(this.position, { x: speed * Math.cos(angle), y: speed * Math.sin(angle) })
}
} else if (tech.isSporeWorm) {
const len = Math.min(25, Math.floor(2 + this.mass * (0.5 + 0.5 * Math.random()))) / 2
const len = amount / 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)
for (let i = 0; i < amount; i++) b.spore(this.position)
}
} else if (tech.isExplodeMob) {
b.explosion(this.position, Math.min(700, Math.sqrt(this.mass + 6) * (30 + 60 * Math.random())))

View File

@@ -549,7 +549,7 @@ const m = {
if (tech.isZeno) dmg *= 0.15
if (tech.isFieldHarmReduction) dmg *= 0.5
if (tech.isHarmMACHO) dmg *= 0.4
if (tech.isImmortal) dmg *= 0.66
if (tech.isImmortal) dmg *= 0.67
if (tech.isSlowFPS) dmg *= 0.8
if (tech.energyRegen === 0) dmg *= 0.34
if (tech.healthDrain) dmg *= 1 + 3.33 * tech.healthDrain //tech.healthDrain = 0.03 at one stack //cause more damage

View File

@@ -636,7 +636,7 @@ const powerUps = {
} else if (powerUps.research.count > 0) {
text += `<div onclick="powerUps.research.use('${type}')" class='choose-grid-module research-card' >` // style = "margin-left: 192px; margin-right: -192px;"
text += `<div><div><span style="position:relative;">`
for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += `<div class="circle-grid research" style="position:absolute; top:0; left:${(18 - len*0.21)*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += `<div class="circle-grid research" style="font-size:0.82em; position:absolute; top:0; left:${(18 - len*0.21)*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
text += `</span>&nbsp; <span class='research-select'>${tech.isResearchReality?"<span class='alt'>alternate reality</span>": "research"}</span></div></div></div>`
} else {
text += `<div></div>`
@@ -1300,7 +1300,6 @@ const powerUps = {
if (have.length) {
choose = have[Math.floor(Math.random() * have.length)]
// simulation.makeTextLog(`<div class='circle tech'></div> &nbsp; <strong>${tech.tech[choose].name}</strong> was ejected`, 600) //message about what tech was lost
simulation.makeTextLog(`<span class='color-var'>tech</span>.remove("<span class='color-text'>${tech.tech[choose].name}</span>")`)
for (let i = 0; i < tech.tech[choose].count; i++) {
@@ -1318,7 +1317,6 @@ const powerUps = {
return false
}
} else if (tech.tech[choose].count && !tech.tech[choose].isNonRefundable) {
// simulation.makeTextLog(`<div class='circle tech'></div> &nbsp; <strong>${tech.tech[choose].name}</strong> was ejected`, 600) //message about what tech was lost
simulation.makeTextLog(`<span class='color-var'>tech</span>.remove("<span class='color-text'>${tech.tech[choose].name}</span>")`)
for (let i = 0; i < tech.tech[choose].count; i++) {

View File

@@ -895,7 +895,7 @@ const simulation = {
if (tech.isMutualism && !tech.isEnergyHealth) {
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].isMutualismActive) {
m.health += 0.01 + 0.01 * (bullet[i].isSpore || bullet[i].isFlea)
m.health += 0.01 + 0.01 * ((bullet[i].isSpore || bullet[i].isFlea) ? 0: 1)
if (m.health > m.maxHealth) m.health = m.maxHealth;
m.displayHealth();
}

View File

@@ -6,7 +6,7 @@ const spawn = {
"orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss",
"powerUpBoss", "powerUpBossBaby", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss",
"snakeSpitBoss", "laserBombingBoss", "blockBoss", "revolutionBoss", "slashBoss", "shieldingBoss",
"timeSkipBoss", "dragonFlyBoss", "beetleBoss"
"timeSkipBoss", "dragonFlyBoss", "beetleBoss", "sneakBoss"
],
bossTypeSpawnOrder: [], //preset list of boss names calculated at the start of a run by the randomSeed
bossTypeSpawnIndex: 0, //increases as the boss type cycles
@@ -31,7 +31,8 @@ const spawn = {
"striker", "striker",
"laser", "laser",
"pulsar", "pulsar",
"launcher", "launcherOne", "exploder", "sneaker", "sucker", "sniper", "spinner", "grower", "beamer", "spawner", "ghoster",
"sneaker", "sneaker",
"launcher", "launcherOne", "exploder", "sucker", "sniper", "spinner", "grower", "beamer", "spawner", "ghoster",
//, "focuser"
],
mobTypeSpawnOrder: [], //preset list of mob names calculated at the start of a run by the randomSeed
@@ -1541,8 +1542,7 @@ const spawn = {
zombie(x, y, radius, sides, color) { //mob that attacks other mobs
mobs.spawn(x, y, sides, radius, color);
let me = mob[mob.length - 1];
me.damageReduction = 0.5 //take less damage
// Matter.Body.setDensity(me, 0.0005) // normal density is 0.001 // this reduces life by half and decreases knockback
me.damageReduction = 0 //take NO damage until targeting player, but also slowly lose health
me.isZombie = true
me.isBadTarget = true;
me.isDropPowerUp = false;
@@ -1550,9 +1550,24 @@ const spawn = {
me.stroke = "#83a"
me.accelMag = 0.0015
me.frictionAir = 0.01
// me.collisionFilter.mask = cat.player | cat.map | cat.body
// me.memory = 120;
me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.mob
me.seeAtDistance2 = 1000000 //1000 vision range
// me.onDeath = function() {
// const amount = Math.min(10, Math.ceil(this.mass * 0.5))
// if (tech.isSporeFlea) {
// const len = amount / 2
// for (let i = 0; i < len; i++) {
// const speed = 10 + 5 * Math.random()
// const angle = 2 * Math.PI * Math.random()
// b.flea(this.position, { x: speed * Math.cos(angle), y: speed * Math.sin(angle) })
// }
// } else if (tech.isSporeWorm) {
// const len = amount / 2
// for (let i = 0; i < len; i++) b.worm(this.position)
// } else {
// for (let i = 0; i < amount; i++) b.spore(this.position)
// }
// }
me.do = function() {
this.zombieHealthBar();
this.lookForMobTargets();
@@ -1572,9 +1587,11 @@ const spawn = {
(Vector.magnitudeSquared(Vector.sub(this.position, mob[this.mobSearchIndex].position)) < this.seeAtDistance2 && Matter.Query.ray(map, this.position, mob[this.mobSearchIndex].position).length === 0)
) {
this.target = mob[this.mobSearchIndex]
} else if (Math.random() < 0.05 && (Vector.magnitudeSquared(Vector.sub(this.position, player.position)) < this.seeAtDistance2 || Matter.Query.ray(map, this.position, player.position).length === 0)) {
} else if (Math.random() < 0.005 * player.speed && (Vector.magnitudeSquared(Vector.sub(this.position, player.position)) < this.seeAtDistance2 || Matter.Query.ray(map, this.position, player.position).length === 0)) {
this.target = player
this.isBadTarget = false;
this.damageReduction = 0.5
me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob
}
}
}
@@ -1585,13 +1602,13 @@ const spawn = {
Vector.magnitudeSquared(Vector.sub(this.position, this.target.position)) > this.seeAtDistance2 ||
Matter.Query.ray(map, this.position, this.target.position).length !== 0
) {
if (this.target === player) this.isBadTarget = true
this.target = null
}
}
}
me.zombieHealthBar = function() {
this.damage(0.001); //decay
this.health -= 0.0005 //decay
if ((this.health < 0.01 || isNaN(this.health)) && this.alive) this.death();
const h = this.radius * 0.3;
const w = this.radius * 2;
@@ -1624,7 +1641,7 @@ const spawn = {
this.force.y -= force.y;
this.target = null //look for a new target
const dmg = 0.3 * m.dmgScale
const dmg = 0.2 * m.dmgScale
who.damage(dmg);
who.locatePlayer();
simulation.drawList.push({
@@ -1647,7 +1664,6 @@ const spawn = {
}
// me.onDamage = function(dmg) {
// }
},
starter(x, y, radius = Math.floor(15 + 20 * Math.random())) { //easy mob for on level 1
mobs.spawn(x, y, 8, radius, "#9ccdc6");
@@ -5703,21 +5719,132 @@ const spawn = {
ctx.setLineDash([]);
}
},
sneaker(x, y, radius = 15 + Math.ceil(Math.random() * 10)) {
sneakBoss(x, y, radius = 70) {
mobs.spawn(x, y, 5, radius, "transparent");
let me = mob[mob.length - 1];
Matter.Body.setDensity(me, 0.002); //extra dense //normal is 0.001 //makes effective life much larger
me.isBoss = true;
me.damageReduction = 0.4 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.accelMag = 0.0017 * Math.sqrt(simulation.accelScale);
me.frictionAir = 0.01;
me.g = 0.0001; //required if using this.gravity
me.stroke = "transparent"; //used for drawSneaker
me.alpha = 1; //used in drawSneaker
me.isCloaked = true; //used in drawSneaker
me.isBadTarget = true;
me.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
me.showHealthBar = false;
me.memory = 30;
me.vanishesLeft = 2+simulation.difficultyMode
me.onDamage = function() {
if (this.vanishesLeft>0 && this.health < 0.1){ //if health is below 10% teleport to a random spot on player history, heal, and cloak
this.vanishesLeft--
// const scale = 0.95;
// Matter.Body.scale(this, scale, scale);
// this.radius *= scale;
//flash screen to hide vanish
for(let i=0; i<8; i++){
simulation.drawList.push({
x: this.position.x,
y: this.position.y,
radius: 3000,
color: `rgba(0, 0, 0,${1-0.1*i})`,
time: (i+1)*3
});
}
//teleport to near the end of player history
const index = Math.floor( (m.history.length-1)*(0.66+0.2*Math.random() ))
let history = m.history[(m.cycle - index) % 600]
Matter.Body.setPosition(this, history.position)
Matter.Body.setVelocity(this, {x: 0,y: 0});
this.seePlayer.recall = 0
this.cloak();
this.health = 1;
}
};
me.cloak = function() {
if (!this.isCloaked) { //stealth
this.alpha = 0;
this.isCloaked = true;
this.isBadTarget = true;
this.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
this.damageReduction = 0.04 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
}
}
me.deCloak = function() {
if (this.isCloaked) {
this.damageReduction = 0.4 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
this.isCloaked = false;
this.isBadTarget = false;
this.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob; //can touch player
}
}
me.do = function() {
this.gravity();
this.seePlayerByHistory(55);
this.checkStatus();
this.attraction();
//draw
if (this.seePlayer.recall) {
if (this.alpha < 1) this.alpha += 0.005 + 0.003 / simulation.CDScale;
} else {
if (this.alpha > 0) this.alpha -= 0.04;
}
if (this.alpha > 0) {
if (this.alpha > 0.7) {
this.healthBar();
this.deCloak()
}
//draw body
ctx.beginPath();
const vertices = this.vertices;
ctx.moveTo(vertices[0].x, vertices[0].y);
for (let j = 1, len = vertices.length; j < len; ++j) ctx.lineTo(vertices[j].x, vertices[j].y);
ctx.lineTo(vertices[0].x, vertices[0].y);
ctx.fillStyle = `rgba(0,0,0,${this.alpha * this.alpha})`;
ctx.fill();
} else {
this.cloak()
}
};
},
sneaker(x, y, radius = 15 + Math.ceil(Math.random() * 10)) {
mobs.spawn(x, y, 5, radius, "transparent");
let me = mob[mob.length - 1];
// Matter.Body.setDensity(me, 0.001); //extra dense //normal is 0.001 //makes effective life much larger
me.accelMag = 0.001 * Math.sqrt(simulation.accelScale);
me.frictionAir = 0.01;
me.g = 0.0002; //required if using this.gravity
me.stroke = "transparent"; //used for drawSneaker
me.alpha = 1; //used in drawSneaker
// me.leaveBody = false;
me.canTouchPlayer = false; //used in drawSneaker
me.isNotCloaked = false; //used in drawSneaker
me.isBadTarget = true;
me.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
me.showHealthBar = false;
me.memory = 240;
me.isVanished = false;
me.onDamage = function() {
if (!this.isVanished && this.health < 0.1){ //if health is below 10% teleport to a random spot on player history, heal, and cloak
this.health = 1;
this.isVanished = true
this.cloak();
//teleport to near the end of player history
Matter.Body.setPosition(this, m.history[Math.floor((m.history.length-1)*(0.66+0.33*Math.random()))].position)
Matter.Body.setVelocity(this, {x: 0,y: 0});
}
};
me.cloak = function() {
if (this.isNotCloaked) { //stealth
this.alpha = 0;
this.isNotCloaked = false;
this.isBadTarget = true;
this.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
}
}
me.do = function() {
this.gravity();
this.seePlayerByHistory(15);
@@ -5732,8 +5859,8 @@ const spawn = {
if (this.alpha > 0) {
if (this.alpha > 0.7) {
this.healthBar();
if (!this.canTouchPlayer) {
this.canTouchPlayer = true;
if (!this.isNotCloaked) {
this.isNotCloaked = true;
this.isBadTarget = false;
this.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob; //can touch player
}
@@ -5748,10 +5875,8 @@ const spawn = {
ctx.lineTo(vertices[0].x, vertices[0].y);
ctx.fillStyle = `rgba(0,0,0,${this.alpha * this.alpha})`;
ctx.fill();
} else if (this.canTouchPlayer) { //stealth
this.canTouchPlayer = false;
this.isBadTarget = true;
this.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
} else {
this.cloak()
}
};
},
@@ -5764,7 +5889,7 @@ const spawn = {
Matter.Body.setDensity(me, 0.0015); //normal is 0.001 //makes effective life much lower
me.stroke = "transparent"; //used for drawGhost
me.alpha = 1; //used in drawGhost
me.canTouchPlayer = false; //used in drawGhost
me.isNotCloaked = false; //used in drawGhost
me.isBadTarget = true;
// me.leaveBody = false;
me.collisionFilter.mask = cat.bullet //| cat.body
@@ -5791,8 +5916,8 @@ const spawn = {
if (this.alpha > 0) {
if (this.alpha > 0.8 && this.seePlayer.recall) {
this.healthBar();
if (!this.canTouchPlayer) {
this.canTouchPlayer = true;
if (!this.isNotCloaked) {
this.isNotCloaked = true;
this.isBadTarget = false;
this.collisionFilter.mask = cat.player | cat.bullet
}
@@ -5808,8 +5933,8 @@ const spawn = {
ctx.lineWidth = 1;
ctx.fillStyle = `rgba(255,255,255,${this.alpha * this.alpha})`;
ctx.fill();
} else if (this.canTouchPlayer) {
this.canTouchPlayer = false;
} else if (this.isNotCloaked) {
this.isNotCloaked = false;
this.isBadTarget = true;
this.collisionFilter.mask = cat.bullet; //can't touch player or walls
}
@@ -6110,7 +6235,7 @@ const spawn = {
me.showHealthBar = false;
me.frictionStatic = 0;
me.friction = 0;
me.canTouchPlayer = false; //used in drawSneaker
me.isNotCloaked = false; //used in drawSneaker
me.isBadTarget = true;
me.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
@@ -6192,8 +6317,8 @@ const spawn = {
if (this.alpha > 0) {
if (this.alpha > 0.95) {
this.healthBar();
if (!this.canTouchPlayer) {
this.canTouchPlayer = true;
if (!this.isNotCloaked) {
this.isNotCloaked = true;
this.isBadTarget = false;
this.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob; //can touch player
}
@@ -6208,8 +6333,8 @@ const spawn = {
ctx.lineTo(vertices[0].x, vertices[0].y);
ctx.fillStyle = `rgba(25,0,50,${this.alpha * this.alpha})`;
ctx.fill();
} else if (this.canTouchPlayer) {
this.canTouchPlayer = false;
} else if (this.isNotCloaked) {
this.isNotCloaked = false;
this.isBadTarget = true
this.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
}
@@ -6373,7 +6498,7 @@ const spawn = {
// // Matter.Body.setDensity(me, 0.001); //normal is 0.001 //makes effective life much lower
// me.stroke = "transparent"; //used for drawGhost
// me.alpha = 1; //used in drawGhost
// me.canTouchPlayer = false; //used in drawGhost
// me.isNotCloaked = false; //used in drawGhost
// me.isBadTarget = true;
// // me.leaveBody = false;
// me.collisionFilter.mask = cat.bullet //| cat.body
@@ -6414,8 +6539,8 @@ const spawn = {
// if (this.alpha > 0) {
// if (this.alpha > 0.8 && this.seePlayer.recall) {
// this.healthBar();
// if (!this.canTouchPlayer) {
// this.canTouchPlayer = true;
// if (!this.isNotCloaked) {
// this.isNotCloaked = true;
// this.isBadTarget = false;
// this.collisionFilter.mask = cat.player | cat.bullet
// }
@@ -6452,8 +6577,8 @@ const spawn = {
// }
// } else if (this.canTouchPlayer) {
// this.canTouchPlayer = false;
// } else if (this.isNotCloaked) {
// this.isNotCloaked = false;
// this.isBadTarget = true;
// this.collisionFilter.mask = cat.bullet; //can't touch player or walls
// }

View File

@@ -4669,9 +4669,9 @@ const tech = {
frequency: 1,
frequencyDefault: 1,
allowed() {
return (tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIceShot && !tech.isRivets && !tech.isFoamShot && !tech.isSporeWorm && !tech.isSporeFlea && !tech.isNeedles) || (tech.haveGunCheck("super balls") && !tech.isFoamBall) || (tech.isRivets && !tech.isNailCrit) || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && simulation.molecularMode === 3) || (tech.haveGunCheck("drones") && !tech.isForeverDrones && !tech.isDroneRadioactive && !tech.isDroneTeleport)
return (tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIceShot && !tech.isRivets && !tech.isFoamShot && !tech.isSporeWorm && !tech.isSporeFlea && !tech.isNeedles) || (tech.haveGunCheck("super balls") && !tech.isFoamBall && !tech.isSuperHarm) || (tech.isRivets && !tech.isNailCrit) || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && simulation.molecularMode === 3) || (tech.haveGunCheck("drones") && !tech.isForeverDrones && !tech.isDroneRadioactive && !tech.isDroneTeleport)
},
requires: "shotgun, super balls, rivets, drones, not irradiated drones, burst drones, polyurethane",
requires: "shotgun, super balls, rivets, drones, not irradiated drones, burst drones, polyurethane, Zectron",
effect() {
tech.isIncendiary = true
},
@@ -4706,6 +4706,25 @@ const tech = {
}
}
},
{
name: "Zectron",
description: `<strong>+100%</strong> <strong>super ball</strong> density and <strong class='color-d'>damage</strong><br>after colliding with <strong>super balls</strong> <strong>lose</strong> <strong class='color-h'>health</strong>`,
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("super balls") && !tech.isIncendiary
},
requires: "super balls not incendiary ammunition",
effect() {
tech.isSuperHarm = true
},
remove() {
tech.isSuperHarm = false
}
},
{
name: "super duper",
description: `randomly fire <strong>+0</strong>, <strong>+1</strong>, or <strong>+2</strong> extra <strong>super balls</strong><br>&nbsp;`,
@@ -5016,7 +5035,7 @@ const tech = {
},
{
name: "launch system",
description: `<strong>+500%</strong> <strong>missile</strong> <strong><em>fire rate</em></strong><br><strong>+20%</strong> missile <strong class='color-ammo'>ammo</strong> per ${powerUps.orb.ammo(1)}`,
description: `<strong>+500%</strong> <strong>missile</strong> <strong class='color-g'>gun</strong> <strong><em>fire rate</em></strong><br><strong>+20%</strong> missile <strong class='color-ammo'>ammo</strong> per ${powerUps.orb.ammo(1)}`,
isGunTech: true,
maxCount: 1,
count: 0,
@@ -5607,6 +5626,25 @@ const tech = {
tech.isSporeGrowth = false
}
},
{
name: "cordyceps",
description: "mobs infected by <strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong><br><strong>resurrect</strong> and attack other mobs",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("spores")
},
requires: "spores",
effect() {
tech.isZombieMobs = true
},
remove() {
tech.isZombieMobs = false
}
},
{
name: "colony",
description: "<strong>+50%</strong> <strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> discharge<br><strong>40%</strong> chance to discharge something different",
@@ -6314,28 +6352,18 @@ const tech = {
ammoBonus: 9,
effect() {
tech.isRailGun = true;
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "harpoon") {
b.guns[i].chooseFireMethod()
b.guns[i].ammoPack = 5;
b.guns[i].ammo = b.guns[i].ammo * 6;
simulation.updateGunHUD();
break
}
}
b.guns[9].chooseFireMethod()
b.guns[9].ammoPack = 5;
b.guns[9].ammo = b.guns[9].ammo * 6;
simulation.updateGunHUD();
},
remove() {
if (tech.isRailGun) {
tech.isRailGun = false;
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "harpoon") {
b.guns[i].chooseFireMethod()
b.guns[i].ammoPack = 1.7;
b.guns[i].ammo = Math.ceil(b.guns[i].ammo / 6);
simulation.updateGunHUD();
break
}
}
b.guns[9].chooseFireMethod()
b.guns[9].ammoPack = 1.7;
b.guns[9].ammo = Math.ceil(b.guns[9].ammo / 6);
simulation.updateGunHUD();
}
}
},
@@ -9288,6 +9316,28 @@ const tech = {
if (this.count) m.look = m.lookDefault
}
},
{
name: "p-zombie",
description: "set your <strong class='color-h'>health</strong> to <strong>1</strong><br>all mobs die and <strong>resurrect</strong> as zombies",
maxCount: 1,
count: 0,
frequency: 0,
isNonRefundable: true,
isJunk: true,
allowed() {return true},
requires: "",
effect() {
m.health = 0.01 //set health to 1
m.displayHealth();
for (let i = mob.length - 1; i > -1; i--) { //replace mobs with zombies
if (mob[i].isDropPowerUp && !mob[i].isBoss && mob[i].alive) {
mob[i].isSoonZombie = true
mob[i].death()
}
}
},
remove() {}
},
{
name: "decomposers",
description: "after they die <strong>mobs</strong> leave behind <strong>spawns</strong><br>&nbsp;",
@@ -11256,4 +11306,6 @@ const tech = {
buffedGun: 0,
isGunChoice: null,
railChargeRate: null,
isSuperHarm: null,
isZombieMobs: null
}