shieldingBoss
shieldingBoss - doesn't attack, but shields all mobs every 2.5s reworked how tetherBoss's constraint work please, let me know if the tether boss is buggy on any of the levels the chance for tether boss was removed from level: detours tech: flip-flop - collisions do 25% more harm, but you become immune to harm for the next collision
This commit is contained in:
12
js/bullet.js
12
js/bullet.js
@@ -2468,7 +2468,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 &&
|
||||
!mob[i].isShielded) {
|
||||
const SPEED = 45
|
||||
const SPEED = 40
|
||||
const unit = Vector.normalise(Vector.sub(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist) / 60)), this.position))
|
||||
b.nail(this.position, Vector.mult(unit, SPEED), 0.4)
|
||||
this.force = Vector.mult(unit, -0.01 * this.mass)
|
||||
@@ -2611,8 +2611,8 @@ const b = {
|
||||
lookFrequency: 40 + Math.floor(7 * Math.random()) - 10 * tech.isLaserBotUpgrade,
|
||||
range: (700 + 400 * tech.isLaserBotUpgrade) * (1 + 0.1 * Math.random()),
|
||||
drainThreshold: tech.isEnergyHealth ? 0.6 : 0.4,
|
||||
drain: 0.7 - 0.52 * tech.isLaserBotUpgrade,
|
||||
laserDamage: 0.38 + 0.29 * tech.isLaserBotUpgrade,
|
||||
drain: 0.56 - 0.42 * tech.isLaserBotUpgrade,
|
||||
laserDamage: 0.5 + 0.35 * tech.isLaserBotUpgrade,
|
||||
endCycle: Infinity,
|
||||
classType: "bullet",
|
||||
collisionFilter: {
|
||||
@@ -3265,11 +3265,11 @@ const b = {
|
||||
if (m.crouch) {
|
||||
spread = 0.75
|
||||
m.fireCDcycle = m.cycle + Math.floor(55 * b.fireCD); // cool down
|
||||
if (tech.isShotgunImmune) m.immuneCycle = m.cycle + Math.floor(58 * b.fireCD); //player is immune to collision damage for 30 cycles
|
||||
if (tech.isShotgunImmune && m.immuneCycle < m.cycle + Math.floor(58 * b.fireCD)) m.immuneCycle = m.cycle + Math.floor(58 * b.fireCD); //player is immune to collision damage for 30 cycles
|
||||
knock = 0.01
|
||||
} else {
|
||||
m.fireCDcycle = m.cycle + Math.floor(45 * b.fireCD); // cool down
|
||||
if (tech.isShotgunImmune) m.immuneCycle = m.cycle + Math.floor(47 * b.fireCD); //player is immune to collision damage for 30 cycles
|
||||
if (tech.isShotgunImmune && m.immuneCycle < m.cycle + Math.floor(47 * b.fireCD)) m.immuneCycle = m.cycle + Math.floor(47 * b.fireCD); //player is immune to collision damage for 30 cycles
|
||||
spread = 1.3
|
||||
knock = 0.1
|
||||
}
|
||||
@@ -4514,7 +4514,7 @@ const b = {
|
||||
m.fireCDcycle = m.cycle + Math.floor(120 * b.fireCD); // cool down
|
||||
} else {
|
||||
m.energy -= DRAIN
|
||||
m.immuneCycle = m.cycle + 30; //player is immune to collision damage for 5 cycles
|
||||
if (m.immuneCycle < m.cycle + 30) m.immuneCycle = m.cycle + 30; //player is immune to collision damage for 5 cycles
|
||||
Matter.Body.setPosition(player, history.position);
|
||||
Matter.Body.setVelocity(player, { x: history.velocity.x, y: history.velocity.y });
|
||||
if (m.health !== history.health) {
|
||||
|
||||
15
js/engine.js
15
js/engine.js
@@ -108,7 +108,20 @@ function collisionChecks(event) {
|
||||
m.damage(dmg);
|
||||
return
|
||||
}
|
||||
m.damage(dmg);
|
||||
|
||||
if (tech.isAnthropicHarm) {
|
||||
if (!tech.isAnthropicHarmImmune) {
|
||||
tech.isAnthropicHarmImmune = true
|
||||
if (document.getElementById("tech-flip-flop")) document.getElementById("tech-flip-flop").innerHTML = ` = on`
|
||||
m.damage(dmg * 1.25); //damage triggers immune to next hit with extra 10% damage
|
||||
} else {
|
||||
tech.isAnthropicHarmImmune = false //immune to damage this hit, lose immunity for next hit
|
||||
if (document.getElementById("tech-flip-flop")) document.getElementById("tech-flip-flop").innerHTML = ` = off`
|
||||
}
|
||||
} else {
|
||||
m.damage(dmg); //normal damage
|
||||
}
|
||||
|
||||
if (tech.isPiezo) m.energy += 20.48;
|
||||
if (tech.isBayesian) powerUps.ejectTech()
|
||||
if (mob[k].onHit) mob[k].onHit(k);
|
||||
|
||||
133
js/level.js
133
js/level.js
@@ -12,7 +12,7 @@ const level = {
|
||||
start() {
|
||||
if (level.levelsCleared === 0) { //this code only runs on the first level
|
||||
// simulation.enableConstructMode() //used to build maps in testing mode
|
||||
// level.difficultyIncrease(40)
|
||||
// level.difficultyIncrease(5)
|
||||
// simulation.zoomScale = 1000;
|
||||
// simulation.setZoom();
|
||||
// m.setField("nano-scale manufacturing")
|
||||
@@ -792,7 +792,7 @@ const level = {
|
||||
} else {
|
||||
if (damage < 0.02) {
|
||||
m.damage(damage)
|
||||
} else if (m.immuneCycle < m.cycle) {
|
||||
} else if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) {
|
||||
m.immuneCycle = m.cycle + tech.collisionImmuneCycles;
|
||||
m.damage(damage)
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
@@ -1090,7 +1090,7 @@ const level = {
|
||||
// spawn.boost(1500, 0, 900);
|
||||
|
||||
// spawn.starter(1900, -500, 200) //big boy
|
||||
// spawn.starter(1900, -500)
|
||||
spawn.starter(1900, -500)
|
||||
// spawn.historyBoss(1900, -500)
|
||||
// spawn.ghoster(2900, -500)
|
||||
// spawn.launcherBoss(1200, -500)
|
||||
@@ -1103,12 +1103,12 @@ const level = {
|
||||
// spawn.cellBossCulture(1600, -500)
|
||||
// spawn.cellBossCulture(1600, -500)
|
||||
// simulation.difficulty = 30
|
||||
spawn.orbitalBoss(1600, -500)
|
||||
spawn.shieldingBoss(1600, -500)
|
||||
// spawn.beamer(1200, -500)
|
||||
// spawn.shield(mob[mob.length - 1], 1800, -120, 1);
|
||||
|
||||
// spawn.nodeGroup(1200, -500, "launcher")
|
||||
// spawn.snakeBoss(1200, -500)
|
||||
spawn.snakeBoss(1200, -500)
|
||||
// spawn.powerUpBoss(2900, -500)
|
||||
// spawn.randomMob(1600, -500)
|
||||
},
|
||||
@@ -1698,16 +1698,16 @@ const level = {
|
||||
spawn.randomMob(-75, -1475, 0);
|
||||
spawn.randomGroup(600, -2600, 0);
|
||||
}
|
||||
if (simulation.difficulty < 25) {
|
||||
if (simulation.difficulty < 20) {
|
||||
spawn.randomMob(700, -1650, 0);
|
||||
spawn.randomMob(600, -3500, 0.2);
|
||||
spawn.randomMob(-75, -1175, 0.2);
|
||||
powerUps.spawnBossPowerUp(-125, -1760);
|
||||
} else {
|
||||
if (Math.random() < 0.5) {
|
||||
spawn.randomLevelBoss(700, -1550, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "streamBoss"]);
|
||||
spawn.randomLevelBoss(700, -1550, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "streamBoss", "shieldingBoss"]);
|
||||
} else {
|
||||
spawn.randomLevelBoss(675, -2775, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "streamBoss"]);
|
||||
spawn.randomLevelBoss(675, -2775, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "streamBoss", "shieldingBoss"]);
|
||||
}
|
||||
}
|
||||
powerUps.addRerollToLevel() //needs to run after mobs are spawned
|
||||
@@ -1854,7 +1854,7 @@ const level = {
|
||||
spawn.randomMob(3600, 1725, 0.9);
|
||||
spawn.randomMob(4100, 1225, 0.9);
|
||||
spawn.randomMob(2825, 400, 0.9);
|
||||
if (simulation.difficulty > 3) spawn.randomLevelBoss(6000, 2300, ["spiderBoss", "launcherBoss", "laserTargetingBoss", "streamBoss", "historyBoss", "orbitalBoss"]);
|
||||
if (simulation.difficulty > 3) spawn.randomLevelBoss(6000, 2300, ["spiderBoss", "launcherBoss", "laserTargetingBoss", "streamBoss", "historyBoss", "orbitalBoss", "shieldingBoss"]);
|
||||
powerUps.addRerollToLevel() //needs to run after mobs are spawned
|
||||
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(7725, 2275);
|
||||
},
|
||||
@@ -2459,17 +2459,7 @@ const level = {
|
||||
if (simulation.difficulty > 3) {
|
||||
if (Math.random() < 0.1) { // tether ball
|
||||
const index = mob.length
|
||||
spawn.tetherBoss(4250, 0)
|
||||
cons[cons.length] = Constraint.create({
|
||||
pointA: {
|
||||
x: 4250,
|
||||
y: -675
|
||||
},
|
||||
bodyB: mob[index],
|
||||
stiffness: 0.00007
|
||||
});
|
||||
World.add(engine.world, cons[cons.length - 1]);
|
||||
|
||||
spawn.tetherBoss(4250, 0, { x: 4250, y: -675 })
|
||||
if (simulation.difficulty > 4) spawn.nodeGroup(4250, 0, "spawns", 8, 20, 105); //chance to spawn a ring of exploding mobs around this boss
|
||||
} else if (Math.random() < 0.2) {
|
||||
spawn.randomLevelBoss(4250, -250);
|
||||
@@ -3214,16 +3204,7 @@ const level = {
|
||||
height: 525,
|
||||
color: "#ccc"
|
||||
});
|
||||
spawn.tetherBoss(2850, -80)
|
||||
cons[cons.length] = Constraint.create({
|
||||
pointA: {
|
||||
x: 2500,
|
||||
y: -500
|
||||
},
|
||||
bodyB: mob[mob.length - 1],
|
||||
stiffness: 0.00012
|
||||
});
|
||||
World.add(engine.world, cons[cons.length - 1]);
|
||||
spawn.tetherBoss(2850, -80, { x: 2500, y: -500 })
|
||||
//chance to spawn a ring of exploding mobs around this boss
|
||||
if (simulation.difficulty > 6) spawn.nodeGroup(2850, -80, "spawns", 8, 20, 105);
|
||||
} else {
|
||||
@@ -3690,16 +3671,7 @@ const level = {
|
||||
if (simulation.difficulty > 2) {
|
||||
if (Math.random() < 0.2) {
|
||||
// tether ball
|
||||
spawn.tetherBoss(7000, -3300)
|
||||
cons[cons.length] = Constraint.create({
|
||||
pointA: {
|
||||
x: 7300,
|
||||
y: -3300
|
||||
},
|
||||
bodyB: mob[mob.length - 1],
|
||||
stiffness: 0.00006
|
||||
});
|
||||
World.add(engine.world, cons[cons.length - 1]);
|
||||
spawn.tetherBoss(7000, -3300, { x: 7300, y: -3300 })
|
||||
if (simulation.difficulty > 4) spawn.nodeGroup(7000, -3300, "spawns", 8, 20, 105);
|
||||
} else if (simulation.difficulty > 3) {
|
||||
spawn.randomLevelBoss(6100, -3600, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss"]);
|
||||
@@ -3709,16 +3681,7 @@ const level = {
|
||||
if (simulation.difficulty > 2) {
|
||||
if (Math.random() < 0.2) {
|
||||
// tether ball
|
||||
spawn.tetherBoss(2300, -1300)
|
||||
cons[cons.length] = Constraint.create({
|
||||
pointA: {
|
||||
x: 2300,
|
||||
y: -1750
|
||||
},
|
||||
bodyB: mob[mob.length - 1],
|
||||
stiffness: 0.00036
|
||||
});
|
||||
World.add(engine.world, cons[cons.length - 1]);
|
||||
spawn.tetherBoss(2300, -1300, { x: 2300, y: -1750 })
|
||||
if (simulation.difficulty > 4) spawn.nodeGroup(2350, -1300, "spawns", 8, 20, 105);
|
||||
} else if (simulation.difficulty > 3) {
|
||||
spawn.randomLevelBoss(2300, -1400, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "snakeBoss"]);
|
||||
@@ -3785,16 +3748,7 @@ const level = {
|
||||
spawn.mapRect(3075, 1075, 375, 150); //Plafond salle trésor
|
||||
spawn.mapRect(3300, 1075, 1500, 1800); //Mur droite salle trésor
|
||||
// tether ball
|
||||
spawn.tetherBoss(2330, 1850)
|
||||
cons[cons.length] = Constraint.create({
|
||||
pointA: {
|
||||
x: 2330,
|
||||
y: 1425
|
||||
},
|
||||
bodyB: mob[mob.length - 1],
|
||||
stiffness: 0.00017
|
||||
});
|
||||
World.add(engine.world, cons[cons.length - 1]);
|
||||
spawn.tetherBoss(2330, 1850, { x: 2330, y: 1425 })
|
||||
//chance to spawn a ring of exploding mobs around this boss
|
||||
if (simulation.difficulty > 4) spawn.nodeGroup(2330, 1850, "spawns", 8, 20, 105);
|
||||
powerUps.chooseRandomPowerUp(3100, 1630);
|
||||
@@ -4062,34 +4016,25 @@ const level = {
|
||||
spawn.randomGroup(8025, -845, 0.2);
|
||||
|
||||
if (simulation.difficulty > 2) {
|
||||
if (Math.random() < 0.2) {
|
||||
// tether ball
|
||||
spawn.tetherBoss(8000, 630)
|
||||
let me = mob[mob.length - 1];
|
||||
me.onDeath = function() {
|
||||
this.removeCons(); //remove constraint
|
||||
spawnCouloirEnHaut()
|
||||
doorSortieSalle.isOpen = false;
|
||||
};
|
||||
cons[cons.length] = Constraint.create({
|
||||
pointA: {
|
||||
x: 8550,
|
||||
y: 680
|
||||
},
|
||||
bodyB: mob[mob.length - 1],
|
||||
stiffness: 0.00015
|
||||
});
|
||||
World.add(engine.world, cons[cons.length - 1]);
|
||||
if (simulation.difficulty > 4) spawn.nodeGroup(8000, 630, "spawns", 8, 20, 105);
|
||||
} else {
|
||||
spawn.randomLevelBoss(8000, 630, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "bomberBoss", "orbitalBoss"]);
|
||||
let me = mob[mob.length - 1];
|
||||
me.onDeath = function() {
|
||||
this.removeCons(); //remove constraint
|
||||
spawnCouloirEnHaut()
|
||||
doorSortieSalle.isOpen = false;
|
||||
};
|
||||
}
|
||||
// if (Math.random() < 0.2) {
|
||||
// // tether ball
|
||||
// spawn.tetherBoss(8000, 630, { x: 8550, y: 680 })
|
||||
// let me = mob[mob.length - 1];
|
||||
// me.onDeath = function() {
|
||||
// this.removeCons(); //remove constraint
|
||||
// spawnCouloirEnHaut()
|
||||
// doorSortieSalle.isOpen = false;
|
||||
// };
|
||||
// if (simulation.difficulty > 4) spawn.nodeGroup(8000, 630, "spawns", 8, 20, 105);
|
||||
// } else {
|
||||
spawn.randomLevelBoss(8000, 630, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "bomberBoss", "orbitalBoss"]);
|
||||
let me = mob[mob.length - 1];
|
||||
me.onDeath = function() {
|
||||
this.removeCons(); //remove constraint
|
||||
spawnCouloirEnHaut()
|
||||
doorSortieSalle.isOpen = false;
|
||||
};
|
||||
// }
|
||||
} else {
|
||||
spawn.randomLevelBoss(8000, 630, ["shooterBoss"]);
|
||||
let me = mob[mob.length - 1];
|
||||
@@ -4658,18 +4603,8 @@ const level = {
|
||||
|
||||
if (simulation.difficulty > 3) {
|
||||
if (Math.random() < 0.16) {
|
||||
spawn.tetherBoss(3380, -1775)
|
||||
cons[cons.length] = Constraint.create({
|
||||
pointA: {
|
||||
x: 3775,
|
||||
y: -1775
|
||||
},
|
||||
bodyB: mob[mob.length - 1],
|
||||
stiffness: 0.00018 + 0.000007 * level.levelsCleared
|
||||
});
|
||||
World.add(engine.world, cons[cons.length - 1]);
|
||||
spawn.tetherBoss(3380, -1775, { x: 3775, y: -1775 })
|
||||
if (simulation.difficulty > 4) spawn.nodeGroup(3380, -1775, "spawns", 8, 20, 105); //chance to spawn a ring of exploding mobs around this boss
|
||||
|
||||
} else {
|
||||
spawn.randomLevelBoss(3100, -1850, ["shooterBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "snakeBoss", "laserBoss"]);
|
||||
}
|
||||
|
||||
40
js/mob.js
40
js/mob.js
@@ -651,25 +651,27 @@ const mobs = {
|
||||
//cause all mobs, and bodies to rotate in a circle
|
||||
applyCurl = function(center, array, isAntiGravity = true) {
|
||||
for (let i = 0; i < array.length; ++i) {
|
||||
const sub = Vector.sub(center, array[i].position)
|
||||
const radius2 = Vector.magnitudeSquared(sub);
|
||||
if (!array[i].isNotHoldable) {
|
||||
const sub = Vector.sub(center, array[i].position)
|
||||
const radius2 = Vector.magnitudeSquared(sub);
|
||||
|
||||
//if too close, like center mob or shield, don't curl // if too far don't curl
|
||||
if (radius2 < range * range && radius2 > 10000) {
|
||||
const curlVector = Vector.mult(Vector.perp(Vector.normalise(sub)), mag)
|
||||
//apply curl force
|
||||
Matter.Body.setVelocity(array[i], {
|
||||
x: array[i].velocity.x * 0.94 + curlVector.x * 0.06,
|
||||
y: array[i].velocity.y * 0.94 + curlVector.y * 0.06
|
||||
})
|
||||
if (isAntiGravity) array[i].force.y -= 0.8 * simulation.g * array[i].mass
|
||||
// //draw curl, for debugging
|
||||
// ctx.beginPath();
|
||||
// ctx.moveTo(array[i].position.x, array[i].position.y);
|
||||
// ctx.lineTo(array[i].position.x + curlVector.x * 10, array[i].position.y + curlVector.y * 10);
|
||||
// ctx.lineWidth = 2;
|
||||
// ctx.strokeStyle = "#000";
|
||||
// ctx.stroke();
|
||||
//if too close, like center mob or shield, don't curl // if too far don't curl
|
||||
if (radius2 < range * range && radius2 > 10000) {
|
||||
const curlVector = Vector.mult(Vector.perp(Vector.normalise(sub)), mag)
|
||||
//apply curl force
|
||||
Matter.Body.setVelocity(array[i], {
|
||||
x: array[i].velocity.x * 0.94 + curlVector.x * 0.06,
|
||||
y: array[i].velocity.y * 0.94 + curlVector.y * 0.06
|
||||
})
|
||||
if (isAntiGravity) array[i].force.y -= 0.8 * simulation.g * array[i].mass
|
||||
// //draw curl, for debugging
|
||||
// ctx.beginPath();
|
||||
// ctx.moveTo(array[i].position.x, array[i].position.y);
|
||||
// ctx.lineTo(array[i].position.x + curlVector.x * 10, array[i].position.y + curlVector.y * 10);
|
||||
// ctx.lineWidth = 2;
|
||||
// ctx.strokeStyle = "#000";
|
||||
// ctx.stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1050,7 +1052,7 @@ const mobs = {
|
||||
bullet[bullet.length - 1].endCycle = simulation.cycle + 1000 + Math.floor(400 * Math.random())
|
||||
this.leaveBody = false; // no body since it turned into the bot
|
||||
}
|
||||
} else if (tech.isShieldAmmo && this.shield) {
|
||||
} else if (tech.isShieldAmmo && this.shield && !this.isBonusShield) {
|
||||
let type = tech.isEnergyNoAmmo ? "heal" : "ammo"
|
||||
if (Math.random() < 0.4) {
|
||||
type = "heal"
|
||||
|
||||
12
js/player.js
12
js/player.js
@@ -570,7 +570,7 @@ const m = {
|
||||
}
|
||||
}
|
||||
m.energy = Math.max(m.energy - steps / 136, 0.01)
|
||||
m.immuneCycle = m.cycle + 30; //player is immune to collision damage for 30 cycles
|
||||
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
|
||||
|
||||
let isDrawPlayer = true
|
||||
const shortPause = function() {
|
||||
@@ -642,7 +642,7 @@ const m = {
|
||||
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span><span class='color-symbol'>--</span><br>${powerUps.research.count}`)
|
||||
for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x, m.pos.y, "heal", false);
|
||||
m.energy = m.maxEnergy
|
||||
m.immuneCycle = m.cycle + 360 //disable this.immuneCycle bonus seconds
|
||||
if (m.immuneCycle < m.cycle + 360) m.immuneCycle = m.cycle + 360 //disable this.immuneCycle bonus seconds
|
||||
simulation.wipe = function() { //set wipe to have trails
|
||||
ctx.fillStyle = "rgba(255,255,255,0.03)";
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
@@ -671,7 +671,7 @@ const m = {
|
||||
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span><span class='color-symbol'>--</span>
|
||||
<br>${powerUps.research.count}`)
|
||||
for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "heal", false);
|
||||
m.immuneCycle = m.cycle + 360 //disable this.immuneCycle bonus seconds
|
||||
if (m.immuneCycle < m.cycle + 360) m.immuneCycle = m.cycle + 360 //disable this.immuneCycle bonus seconds
|
||||
simulation.wipe = function() { //set wipe to have trails
|
||||
ctx.fillStyle = "rgba(255,255,255,0.03)";
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
@@ -1777,7 +1777,7 @@ const m = {
|
||||
|
||||
simulation.cycle--; //pause all functions that depend on game cycle increasing
|
||||
if (tech.isTimeSkip) {
|
||||
m.immuneCycle = m.cycle + 10;
|
||||
if (m.immuneCycle < m.cycle + 10) m.immuneCycle = m.cycle + 10;
|
||||
simulation.isTimeSkipping = true;
|
||||
m.cycle++;
|
||||
simulation.gravity();
|
||||
@@ -2537,7 +2537,7 @@ const m = {
|
||||
x: velocity.x,
|
||||
y: velocity.y - 4 //an extra vertical kick so the player hangs in place longer
|
||||
});
|
||||
m.immuneCycle = m.cycle + 15; //player is immune to collision damage
|
||||
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to collision damage
|
||||
// move bots to player
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType) {
|
||||
@@ -2813,7 +2813,7 @@ const m = {
|
||||
if (tech.isPiezo) m.energy += 20.48;
|
||||
if (tech.isBayesian) powerUps.ejectTech()
|
||||
if (mob[k].onHit) mob[k].onHit(k);
|
||||
m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
|
||||
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
|
||||
//extra kick between player and mob //this section would be better with forces but they don't work...
|
||||
let angle = Math.atan2(player.position.y - mob[k].position.y, player.position.x - mob[k].position.x);
|
||||
Matter.Body.setVelocity(player, {
|
||||
|
||||
@@ -70,7 +70,7 @@ const powerUps = {
|
||||
document.body.style.overflow = "hidden"
|
||||
simulation.paused = false;
|
||||
simulation.isChoosing = false; //stops p from un pausing on key down
|
||||
m.immuneCycle = m.cycle + 60; //player is immune to collision damage for 30 cycles
|
||||
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
|
||||
build.unPauseGrid()
|
||||
requestAnimationFrame(cycle);
|
||||
},
|
||||
|
||||
@@ -1002,7 +1002,7 @@ const simulation = {
|
||||
//ctx.fillText(bodies[i].id,bodies[i].position.x,bodies[i].position.y); //shows the id of every body
|
||||
let vertices = bodies[i].vertices;
|
||||
ctx.moveTo(vertices[0].x, vertices[0].y);
|
||||
for (let j = 1; j < vertices.length; j += 1) {
|
||||
for (let j = 1; j < vertices.length; j++) {
|
||||
ctx.lineTo(vertices[j].x, vertices[j].y);
|
||||
}
|
||||
ctx.lineTo(vertices[0].x, vertices[0].y);
|
||||
|
||||
103
js/spawn.js
103
js/spawn.js
@@ -82,8 +82,8 @@ const spawn = {
|
||||
}
|
||||
}
|
||||
},
|
||||
//, "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss", "snakeBoss", "streamBoss"
|
||||
randomLevelBoss(x, y, options = ["orbitalBoss"]) {
|
||||
//
|
||||
randomLevelBoss(x, y, options = ["shieldingBoss", "orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss", "snakeBoss", "streamBoss"]) {
|
||||
// other bosses: suckerBoss, laserBoss, tetherBoss, //these need a particular level to work so they are not included in the random pool
|
||||
spawn[options[Math.floor(Math.random() * options.length)]](x, y)
|
||||
},
|
||||
@@ -437,7 +437,7 @@ const spawn = {
|
||||
vertexCollision(where, look, body);
|
||||
if (!m.isCloak) vertexCollision(where, look, [player]);
|
||||
if (best.who && best.who === player && m.immuneCycle < m.cycle) {
|
||||
m.immuneCycle = m.cycle + 60 + tech.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
|
||||
if (m.immuneCycle < m.cycle + 60 + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + 60 + tech.collisionImmuneCycles; //player is immune to collision damage extra time
|
||||
m.damage(dmg);
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: best.x,
|
||||
@@ -1623,7 +1623,7 @@ const spawn = {
|
||||
vertexCollision(where, look, body);
|
||||
if (!m.isCloak) vertexCollision(where, look, [player]);
|
||||
if (best.who && best.who === player && m.immuneCycle < m.cycle) {
|
||||
m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
|
||||
m.immuneCycle = m.cycle + tech.collisionImmuneCycles + 60; //player is immune to collision damage for an extra second
|
||||
const dmg = 0.14 * simulation.dmgScale;
|
||||
m.damage(dmg);
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
@@ -1776,9 +1776,8 @@ const spawn = {
|
||||
};
|
||||
},
|
||||
sneaker(x, y, radius = 15 + Math.ceil(Math.random() * 20)) {
|
||||
let me;
|
||||
mobs.spawn(x, y, 5, radius, "transparent");
|
||||
me = mob[mob.length - 1];
|
||||
let me = mob[mob.length - 1];
|
||||
Matter.Body.setDensity(me, 0.002); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
me.accelMag = 0.001 * simulation.accelScale;
|
||||
me.frictionAir = 0.01;
|
||||
@@ -1828,9 +1827,8 @@ const spawn = {
|
||||
};
|
||||
},
|
||||
ghoster(x, y, radius = 40 + Math.ceil(Math.random() * 100)) {
|
||||
let me;
|
||||
mobs.spawn(x, y, 7, radius, "transparent");
|
||||
me = mob[mob.length - 1];
|
||||
let me = mob[mob.length - 1];
|
||||
me.seeAtDistance2 = 300000;
|
||||
me.accelMag = 0.00012 * simulation.accelScale;
|
||||
if (map.length) me.searchTarget = map[Math.floor(Math.random() * (map.length - 1))].position; //required for search
|
||||
@@ -2321,6 +2319,62 @@ const spawn = {
|
||||
}
|
||||
};
|
||||
},
|
||||
shieldingBoss(x, y, radius = 210) {
|
||||
mobs.spawn(x, y, 9, radius, "rgb(150, 150, 255)");
|
||||
let me = mob[mob.length - 1];
|
||||
Matter.Body.rotate(me, Math.random() * 2 * Math.PI)
|
||||
// me.stroke = "rgb(220,220,255)"
|
||||
me.isBoss = true;
|
||||
me.cycle = 0
|
||||
me.maxCycles = 120;
|
||||
me.frictionStatic = 0;
|
||||
me.friction = 0;
|
||||
me.frictionAir = 0.5;
|
||||
spawn.shield(me, x, y, 1);
|
||||
spawn.spawnOrbitals(me, radius + 50 + 200 * Math.random())
|
||||
|
||||
Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
me.onDeath = function() {
|
||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||
// this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //helps collisions functions work better after vertex have been changed
|
||||
};
|
||||
me.onDamage = function() {};
|
||||
me.do = function() {
|
||||
this.checkStatus();
|
||||
|
||||
//draw cycle timer
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.vertices[this.vertices.length - 1].x, this.vertices[this.vertices.length - 1].y)
|
||||
const phase = (this.vertices.length + 1) * this.cycle / this.maxCycles
|
||||
if (phase > 1) ctx.lineTo(this.vertices[0].x, this.vertices[0].y)
|
||||
for (let i = 1; i < phase - 1; i++) {
|
||||
ctx.lineTo(this.vertices[i].x, this.vertices[i].y)
|
||||
}
|
||||
ctx.lineWidth = 5
|
||||
ctx.strokeStyle = "rgb(255,255,255)"
|
||||
ctx.stroke();
|
||||
|
||||
if (!m.isBodiesAsleep) {
|
||||
this.cycle++
|
||||
if (this.cycle > this.maxCycles) {
|
||||
this.cycle = 0
|
||||
ctx.beginPath();
|
||||
for (let i = 0; i < mob.length; i++) {
|
||||
if (!mob[i].isShielded && !mob[i].shield && mob[i].dropPowerUp) {
|
||||
ctx.moveTo(this.position.x, this.position.y)
|
||||
ctx.lineTo(mob[i].position.x, mob[i].position.y)
|
||||
|
||||
spawn.shield(mob[i], mob[i].position.x, mob[i].position.y, 1, true);
|
||||
}
|
||||
}
|
||||
ctx.lineWidth = 20
|
||||
// ctx.lineCap = "round";
|
||||
ctx.strokeStyle = "rgba(200,200,255,0.9)"
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
streamBoss(x, y, radius = 110) {
|
||||
mobs.spawn(x, y, 5, radius, "rgb(245,180,255)");
|
||||
let me = mob[mob.length - 1];
|
||||
@@ -2492,7 +2546,6 @@ const spawn = {
|
||||
me.memory = 250;
|
||||
me.laserRange = 500;
|
||||
Matter.Body.setDensity(me, 0.0015 + 0.0005 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
spawn.shield(me, x, y, 1);
|
||||
me.onDeath = function() {
|
||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||
for (let i = 0; i < mob.length; i++) { //wake up tail mobs
|
||||
@@ -2532,9 +2585,10 @@ const spawn = {
|
||||
stiffness: 0.05
|
||||
});
|
||||
World.add(engine.world, consBB[consBB.length - 1]);
|
||||
spawn.shield(me, x, y, 1);
|
||||
},
|
||||
snakeBody(x, y, radius = 14) {
|
||||
mobs.spawn(x, y, 8, radius, "transparent");
|
||||
mobs.spawn(x, y, 8, radius, "rgba(0,180,180,0.4)");
|
||||
let me = mob[mob.length - 1];
|
||||
// me.onHit = function() {
|
||||
// //run this function on hitting player
|
||||
@@ -2545,7 +2599,7 @@ const spawn = {
|
||||
me.leaveBody = false;
|
||||
me.frictionAir = 0.02;
|
||||
me.isSnakeTail = true;
|
||||
me.stroke = "#099"
|
||||
me.stroke = "transparent"
|
||||
|
||||
me.onDeath = function() {
|
||||
if (this.isSnakeTail) { //wake up tail mobs
|
||||
@@ -2567,7 +2621,7 @@ const spawn = {
|
||||
this.attraction();
|
||||
};
|
||||
},
|
||||
tetherBoss(x, y, radius = 90) {
|
||||
tetherBoss(x, y, constraint, radius = 90) {
|
||||
// constrained mob boss for the towers level
|
||||
// often has a ring of mobs around it
|
||||
mobs.spawn(x, y, 8, radius, "rgb(0,60,80)");
|
||||
@@ -2577,8 +2631,18 @@ const spawn = {
|
||||
me.accelMag = 0.002 * simulation.accelScale;
|
||||
me.memory = 20;
|
||||
Matter.Body.setDensity(me, 0.001 + 0.0005 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
spawn.shield(me, x, y, 1);
|
||||
|
||||
|
||||
cons[cons.length] = Constraint.create({
|
||||
pointA: {
|
||||
x: constraint.x,
|
||||
y: constraint.y
|
||||
},
|
||||
bodyB: me,
|
||||
stiffness: 0.00012
|
||||
});
|
||||
World.add(engine.world, cons[cons.length - 1]);
|
||||
spawn.shield(me, x, y, 1);
|
||||
setTimeout(() => { spawn.spawnOrbitals(me, radius + 50 + 200 * Math.random()) }, 100); //have to wait a sec so the tether constraint doesn't attach to an orbital
|
||||
me.onDeath = function() {
|
||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||
@@ -2591,13 +2655,14 @@ const spawn = {
|
||||
this.attraction();
|
||||
};
|
||||
},
|
||||
shield(target, x, y, chance = Math.min(0.02 + simulation.difficulty * 0.005, 0.2)) {
|
||||
shield(target, x, y, chance = Math.min(0.02 + simulation.difficulty * 0.005, 0.2), isBonusShield = false) {
|
||||
if (this.allowShields && Math.random() < chance) {
|
||||
mobs.spawn(x, y, 9, target.radius + 30, "rgba(220,220,255,0.9)");
|
||||
let me = mob[mob.length - 1];
|
||||
me.stroke = "rgb(220,220,255)";
|
||||
Matter.Body.setDensity(me, 0.00001) //very low density to not mess with the original mob's motion
|
||||
me.shield = true;
|
||||
me.isBonusShield = isBonusShield //this prevents spamming with tech.isShieldAmmo
|
||||
me.collisionFilter.category = cat.mobShield
|
||||
me.collisionFilter.mask = cat.bullet;
|
||||
consBB[consBB.length] = Constraint.create({
|
||||
@@ -2625,12 +2690,16 @@ const spawn = {
|
||||
if (mob[i].id === this.shieldTargetID) mob[i].isShielded = false;
|
||||
}
|
||||
};
|
||||
//swap order of shield and mob, so that mob is behind shield graphically
|
||||
mob[mob.length - 1] = mob[mob.length - 2];
|
||||
mob[mob.length - 2] = me;
|
||||
me.do = function() {
|
||||
this.checkStatus();
|
||||
};
|
||||
|
||||
//move shield to the front of the array, so that mob is behind shield graphically
|
||||
mob.unshift(me);
|
||||
|
||||
//swap order of shield and mob, so that mob is behind shield graphically
|
||||
// mob[mob.length - 1] = mob[mob.length - 2];
|
||||
// mob[mob.length - 2] = me;
|
||||
}
|
||||
},
|
||||
groupShield(targets, x, y, radius, stiffness = 0.4) {
|
||||
|
||||
151
js/tech.js
151
js/tech.js
@@ -95,13 +95,12 @@
|
||||
haveGunCheck(name) {
|
||||
if (
|
||||
!build.isExperimentSelection &&
|
||||
b.inventory.length > 2 &&
|
||||
b.inventory > 2 &&
|
||||
name !== b.guns[b.activeGun].name &&
|
||||
Math.random() > 2 / (b.inventory.length + tech.isGunCycle * 3) //lower chance of tech specific to a gun if you have lots of guns
|
||||
Math.random() > 2 - b.inventory.length * 0.5
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
for (i = 0, len = b.inventory.length; i < len; i++) {
|
||||
if (b.guns[b.inventory[i]].name === name) return true
|
||||
}
|
||||
@@ -1164,10 +1163,10 @@
|
||||
requires: "",
|
||||
effect() {
|
||||
tech.collisionImmuneCycles += 45;
|
||||
m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
|
||||
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
|
||||
},
|
||||
remove() {
|
||||
tech.collisionImmuneCycles = 25;
|
||||
tech.collisionImmuneCycles = 30;
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -1186,6 +1185,84 @@
|
||||
tech.cyclicImmunity = 0;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "flip-flop",
|
||||
description: "after a <strong>collision</strong> take <strong>25%</strong> more <strong class='color-harm'>harm</strong><br>but, on your next <strong>collision</strong> take <strong>0</strong> <strong class='color-harm'>harm</strong>",
|
||||
nameInfo: "<span id = 'tech-flip-flop'></span>",
|
||||
addNameInfo() {
|
||||
setTimeout(function() {
|
||||
if (document.getElementById("tech-flip-flop")) {
|
||||
if (tech.isAnthropicHarmImmune) {
|
||||
document.getElementById("tech-flip-flop").innerHTML = ` = on`
|
||||
} else {
|
||||
document.getElementById("tech-flip-flop").innerHTML = ` = off`
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
return true
|
||||
},
|
||||
requires: "",
|
||||
effect() {
|
||||
tech.isAnthropicHarm = true //do you have this tech
|
||||
tech.isAnthropicHarmImmune = false //are you immune to next collision
|
||||
},
|
||||
remove() {
|
||||
tech.isAnthropicHarm = false
|
||||
tech.isAnthropicHarmImmune = false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "clock gating",
|
||||
description: `<strong>slow</strong> <strong>time</strong> by <strong>50%</strong> after receiving <strong class='color-harm'>harm</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>20%</strong>`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
return simulation.fpsCapDefault > 45 && !tech.isRailTimeSlow
|
||||
},
|
||||
requires: "FPS above 45",
|
||||
effect() {
|
||||
tech.isSlowFPS = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isSlowFPS = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "liquid cooling",
|
||||
description: `<strong class='color-s'>freeze</strong> all mobs for <strong>7</strong> seconds<br>after receiving <strong class='color-harm'>harm</strong>`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
return tech.isSlowFPS
|
||||
},
|
||||
requires: "clock gating",
|
||||
effect() {
|
||||
tech.isHarmFreeze = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isHarmFreeze = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "osmoprotectant",
|
||||
description: `collisions with <strong>stunned</strong> or <strong class='color-s'>frozen</strong> mobs<br>cause you <strong>no</strong> <strong class='color-harm'>harm</strong>`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
return tech.isStunField || tech.isPulseStun || tech.oneSuperBall || tech.isHarmFreeze || tech.isIceField || tech.isIceCrystals || tech.isSporeFreeze || tech.isAoESlow || tech.isFreezeMobs || tech.isCloakStun || tech.orbitBotCount > 1 || tech.isWormholeDamage
|
||||
},
|
||||
requires: "a freezing or stunning effect",
|
||||
effect() {
|
||||
tech.isFreezeHarmImmune = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isFreezeHarmImmune = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "ablative drones",
|
||||
description: "rebuild your broken parts as <strong>drones</strong><br>chance to occur after receiving <strong class='color-harm'>harm</strong>",
|
||||
@@ -1237,54 +1314,6 @@
|
||||
tech.isHarmDamage = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "liquid cooling",
|
||||
description: `<strong class='color-s'>freeze</strong> all mobs for <strong>7</strong> seconds<br>after receiving <strong class='color-harm'>harm</strong>`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
return tech.isSlowFPS
|
||||
},
|
||||
requires: "clock gating",
|
||||
effect() {
|
||||
tech.isHarmFreeze = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isHarmFreeze = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "osmoprotectant",
|
||||
description: `collisions with <strong>stunned</strong> or <strong class='color-s'>frozen</strong> mobs<br>cause you <strong>no</strong> <strong class='color-harm'>harm</strong>`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
return tech.isStunField || tech.isPulseStun || tech.oneSuperBall || tech.isHarmFreeze || tech.isIceField || tech.isIceCrystals || tech.isSporeFreeze || tech.isAoESlow || tech.isFreezeMobs || tech.isCloakStun || tech.orbitBotCount > 1 || tech.isWormholeDamage
|
||||
},
|
||||
requires: "a freezing or stunning effect",
|
||||
effect() {
|
||||
tech.isFreezeHarmImmune = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isFreezeHarmImmune = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "clock gating",
|
||||
description: `<strong>slow</strong> <strong>time</strong> by <strong>50%</strong> after receiving <strong class='color-harm'>harm</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>20%</strong>`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
return simulation.fpsCapDefault > 45 && !tech.isRailTimeSlow
|
||||
},
|
||||
requires: "FPS above 45",
|
||||
effect() {
|
||||
tech.isSlowFPS = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isSlowFPS = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "CPT reversal",
|
||||
description: "<strong>charge</strong>, <strong>parity</strong>, and <strong>time</strong> invert to undo <strong class='color-harm'>harm</strong><br><strong class='color-rewind'>rewind</strong> <strong>(1.5—5)</strong> seconds for <strong>(66—220)</strong> <strong class='color-f'>energy</strong>",
|
||||
@@ -1339,7 +1368,7 @@
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
return !tech.isEnergyHealth && m.harmReduction() < 1
|
||||
return !tech.isEnergyHealth && (m.harmReduction() < 1 || tech.isAnthropicHarm)
|
||||
},
|
||||
requires: "not mass-energy equivalence, some harm reduction",
|
||||
effect() {
|
||||
@@ -1860,7 +1889,7 @@
|
||||
},
|
||||
{
|
||||
name: "decoherence",
|
||||
description: "enter an <strong>alternate reality</strong> after you <strong class='color-r'>research</strong><br>spawn <strong>9</strong> <strong class='color-r'>research</strong>",
|
||||
description: "enter an <strong>alternate reality</strong> after you <strong class='color-r'>research</strong><br>spawn <strong>11</strong> <strong class='color-r'>research</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
@@ -1869,7 +1898,7 @@
|
||||
requires: "not quantum immortality, many-worlds",
|
||||
effect() {
|
||||
tech.isResearchReality = true;
|
||||
for (let i = 0; i < 9; i++) powerUps.spawn(m.pos.x + Math.random() * 10, m.pos.y + Math.random() * 10, "research", false);
|
||||
for (let i = 0; i < 11; i++) powerUps.spawn(m.pos.x + Math.random() * 10, m.pos.y + Math.random() * 10, "research", false);
|
||||
},
|
||||
remove() {
|
||||
tech.isResearchReality = false;
|
||||
@@ -2011,7 +2040,7 @@
|
||||
},
|
||||
{
|
||||
name: "bubble fusion",
|
||||
description: "after destroying a mob's <strong>shield</strong><br>spawn <strong>1-2</strong> <strong class='color-h'>heals</strong>, <strong class='color-g'>ammo</strong>, or <strong class='color-r'>research</strong>",
|
||||
description: "after destroying a mob's natural <strong>shield</strong><br>spawn <strong>1-2</strong> <strong class='color-h'>heals</strong>, <strong class='color-g'>ammo</strong>, or <strong class='color-r'>research</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
@@ -4307,7 +4336,7 @@
|
||||
},
|
||||
{
|
||||
name: "ship",
|
||||
description: "<strong>experimental mode:</strong> fly around with no legs<br>aim by rotating with keyboard",
|
||||
description: "<strong>experiment:</strong> fly around with no legs<br>aim by rotating with keyboard",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
isNonRefundable: true,
|
||||
@@ -4324,7 +4353,7 @@
|
||||
},
|
||||
{
|
||||
name: "quantum leap",
|
||||
description: "<strong>experimental mode:</strong> every 20 seconds<br>become an alternate version of yourself",
|
||||
description: "<strong>experiment:</strong> every 20 seconds<br>become an alternate version of yourself",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
isNonRefundable: true,
|
||||
@@ -5373,5 +5402,7 @@
|
||||
isHarmReduceAfterKill: null,
|
||||
isSwitchReality: null,
|
||||
isResearchReality: null,
|
||||
isAnthropicDamage: null
|
||||
isAnthropicDamage: null,
|
||||
isAnthropicHarm: null,
|
||||
isAnthropicHarmImmune: null
|
||||
}
|
||||
Reference in New Issue
Block a user