super determinism...

damage immunity after a collisions is reduced from 1/2s to 1/4s
freezing status effects only last 1/4 as long on boss mobs
mod - shotgun 66% increased fire rate and recoil
mod - slowly heal when below 25% health
mod - superdeterminism spawn 4 mods, but rerolls, fields, and guns no longer spawn
This commit is contained in:
landgreen
2020-06-21 19:14:01 -07:00
parent 6f503ff3c0
commit d1cb3aff15
11 changed files with 359 additions and 185 deletions

View File

@@ -467,17 +467,18 @@ const b = {
Matter.Body.setVelocity(bullet[bIndex], velocity);
World.add(engine.world, bullet[bIndex]); //add bullet to world
},
spore(who) { //used with the mod upgrade in mob.death()
spore(where, isFreeze = mod.isSporeFreeze) { //used with the mod upgrade in mob.death()
const bIndex = bullet.length;
const side = 4;
bullet[bIndex] = Bodies.polygon(who.position.x, who.position.y, 5, side, {
bullet[bIndex] = Bodies.polygon(where.x, where.y, 5, side, {
// density: 0.0015, //frictionAir: 0.01,
inertia: Infinity,
isFreeze: isFreeze,
restitution: 0.5,
angle: Math.random() * 2 * Math.PI,
friction: 0,
frictionAir: 0.025,
thrust: mod.isFastSpores ? 0.001 : 0.0004,
thrust: (mod.isFastSpores ? 0.001 : 0.0004) * (1 + 0.3 * (Math.random() - 0.5)),
dmg: mod.isMutualism ? 5.6 : 2.8, //2x bonus damage from mod.isMutualism
lookFrequency: 97 + Math.floor(117 * Math.random()),
classType: "bullet",
@@ -491,8 +492,9 @@ const b = {
x: 100 * (Math.random() - 0.5),
y: 100 * (Math.random() - 0.5)
},
onDmg() {
onDmg(who) {
this.endCycle = 0; //bullet ends cycle after doing damage
if (this.isFreeze) mobs.statusSlow(who, 60)
},
onEnd() {
if (mod.isMutualism && this.isMutualismActive && !mod.isEnergyHealth) {
@@ -503,39 +505,70 @@ const b = {
}
},
do() {
if (!(game.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].dropPowerUp && Matter.Query.ray(map, this.position, mob[i].position).length === 0) {
// Matter.Query.ray(body, this.position, mob[i].position).length === 0
const targetVector = Vector.sub(this.position, mob[i].position)
const dist = Vector.magnitude(targetVector);
if (dist < closeDist) {
this.closestTarget = mob[i].position;
closeDist = dist;
this.lockedOn = mob[i] //Vector.normalise(targetVector);
if (0.3 > Math.random()) break //doesn't always target the closest mob
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 (!(game.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].dropPowerUp && 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 (this.lockedOn && this.lockedOn.alive) { //accelerate towards mobs
this.force = Vector.mult(Vector.normalise(Vector.sub(this.lockedOn.position, this.position)), this.mass * this.thrust)
} else if (mod.isSporeFollow && this.lockedOn !== undefined) { //move towards player
//checking for undefined means that the spores don't go after the player until it has looked and not found a target
const dx = this.position.x - mech.pos.x;
const dy = this.position.y - mech.pos.y;
if (dx * dx + dy * dy > 10000) {
this.force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, Vector.add(this.playerOffPosition, this.position))), this.mass * this.thrust)
if (mod.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 - mech.pos.x;
const dy = this.position.y - mech.pos.y;
if (dx * dx + dy * dy > 10000) {
this.force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, Vector.add(this.playerOffPosition, this.position))), this.mass * this.thrust)
}
} else {
this.force.y += this.mass * 0.0001; //gravity
}
// this.force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, this.position)), this.mass * this.thrust)
} else {
this.force.y += this.mass * 0.0001; //gravity
}
// if (!this.lockedOn && !(game.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].dropPowerUp && Matter.Query.ray(map, this.position, mob[i].position).length === 0) {
// // Matter.Query.ray(body, this.position, mob[i].position).length === 0
// const targetVector = Vector.sub(this.position, mob[i].position)
// const dist = Vector.magnitude(targetVector);
// if (dist < closeDist) {
// this.closestTarget = mob[i].position;
// closeDist = dist;
// this.lockedOn = mob[i] //Vector.normalise(targetVector);
// if (0.3 > Math.random()) break //doesn't always target the closest mob
// }
// }
// }
// }
// if (this.lockedOn && this.lockedOn.alive) { //accelerate towards mobs
// this.force = Vector.mult(Vector.normalise(Vector.sub(this.lockedOn.position, this.position)), this.mass * this.thrust)
// } else if (mod.isSporeFollow && this.lockedOn !== undefined) { //move towards player
// //checking for undefined means that the spores don't go after the player until it has looked and not found a target
// const dx = this.position.x - mech.pos.x;
// const dy = this.position.y - mech.pos.y;
// if (dx * dx + dy * dy > 10000) {
// this.force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, Vector.add(this.playerOffPosition, this.position))), this.mass * this.thrust)
// }
// // this.force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, this.position)), this.mass * this.thrust)
// } else {
// this.force.y += this.mass * 0.0001; //gravity
// }
},
});
const SPEED = 4 + 8 * Math.random();
@@ -578,7 +611,7 @@ const b = {
onDmg(who) {
mobs.statusSlow(who, 60)
this.endCycle = game.cycle
if (mod.isAlphaRadiation) mobs.statusDoT(who, 0.1, 180)
if (mod.isHeavyWater) mobs.statusDoT(who, 0.1, 180)
},
onEnd() {},
do() {
@@ -1226,18 +1259,27 @@ const b = {
fire() {
let knock, spread
if (mech.crouch) {
spread = 0.75
mech.fireCDcycle = mech.cycle + Math.floor(55 * b.fireCD); // cool down
if (mod.isShotgunImmune) mech.immuneCycle = mech.cycle + Math.floor(58 * b.fireCD); //player is immune to collision damage for 30 cycles
spread = 0.75
knock = 0.01 * mod.bulletSize * mod.bulletSize
knock = 0.01
} else {
mech.fireCDcycle = mech.cycle + Math.floor(45 * b.fireCD); // cool down
if (mod.isShotgunImmune) mech.immuneCycle = mech.cycle + Math.floor(47 * b.fireCD); //player is immune to collision damage for 30 cycles
spread = 1.3
knock = 0.08 * mod.bulletSize * mod.bulletSize
knock = 0.08
}
player.force.x -= knock * Math.cos(mech.angle)
player.force.y -= knock * Math.sin(mech.angle) * 0.3 //reduce knock back in vertical direction to stop super jumps
if (mod.isShotgunRecoil) {
mech.fireCDcycle -= 15
player.force.x -= 2 * knock * Math.cos(mech.angle)
player.force.y -= 2 * knock * Math.sin(mech.angle) //reduce knock back in vertical direction to stop super jumps
} else {
player.force.x -= knock * Math.cos(mech.angle)
player.force.y -= knock * Math.sin(mech.angle) * 0.3 //reduce knock back in vertical direction to stop super jumps
}
b.muzzleFlash(35);
if (mod.isNailShot) {
@@ -2142,7 +2184,7 @@ const b = {
bullet[me].onEnd = function () {
const NUM = 10
for (let i = 0; i < NUM; i++) {
b.spore(this)
b.spore(this.position)
}
}
}
@@ -2669,10 +2711,20 @@ const b = {
}
//use energy to explode
const energy = 0.3 * Math.min(mech.energy, 1.75)
mech.energy -= energy * mod.isLaserDiode
if (best.who) b.explosion(path[1], 1000 * energy, true)
mech.fireCDcycle = mech.cycle + Math.floor(50 * b.fireCD); // cool down
let energy;
if (mod.isRapidPulse) {
energy = 0.02 + 0.06 * Math.min(mech.energy, 1.75)
if (mech.energy < energy) return
mech.energy -= energy * mod.isLaserDiode
if (best.who) b.explosion(path[1], 2000 * energy, true)
mech.fireCDcycle = mech.cycle + Math.floor(15 * b.fireCD); // cool down
} else {
energy = 0.3 * Math.min(mech.energy, 1.75)
mech.energy -= energy * mod.isLaserDiode
if (best.who) b.explosion(path[1], 1000 * energy, true)
mech.fireCDcycle = mech.cycle + Math.floor(50 * b.fireCD); // cool down
}
if (mod.isPulseStun) {
const range = 100 + 2000 * energy

View File

@@ -205,13 +205,9 @@ function collisionChecks(event) {
if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) {
// const dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)));
let dmg = b.dmgScale * (obj.dmg + mod.acidDmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)))
// console.log(obj.dmg, 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)))
// console.log(obj.dmg / (0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity))))
if (mod.isCrit && !mob[k].seePlayer.recall && !mob[k].shield) dmg *= 5
mob[k].foundPlayer();
console.log(dmg)
mob[k].damage(dmg);
// console.log(dmg)
obj.onDmg(mob[k]); //some bullets do actions when they hits things, like despawn
game.drawList.push({ //add dmg to draw queue
x: pairs[i].activeContacts[0].vertex.x,

View File

@@ -771,6 +771,12 @@ const game = {
if (mod.isHealthRecovery) mech.addHealth(0.01)
}
if (mod.isHealLowHealth) {
if (mech.health < mech.maxHealth * 0.25) {
mech.addHealth(0.01 * mech.maxHealth)
}
}
if (!(game.cycle % 420)) { //once every 7 seconds
fallCheck = function (who, save = false) {
let i = who.length;

View File

@@ -81,7 +81,7 @@ const build = {
<br>${mob.length} mobs, &nbsp; ${body.length} blocks, &nbsp; ${bullet.length} bullets, &nbsp; ${powerUp.length} power ups
<br>mouse: (${game.mouseInGame.x.toFixed(1)}, ${game.mouseInGame.y.toFixed(1)}) &nbsp; ${mech.cycle} cycles
<br>
<br>health: ${(mech.health*100).toFixed(0)}% &nbsp; energy: ${(mech.energy*100).toFixed(0)}% &nbsp;
<br>health: (${(mech.health*100).toFixed(0)} / ${(mech.maxHealth*100).toFixed(0)}) &nbsp; energy: (${(mech.energy*100).toFixed(0)} / ${(mech.maxEnergy*100).toFixed(0)})
<br>mass: ${player.mass.toFixed(1)} &nbsp; rerolls: ${powerUps.reroll.rerolls}
<br>position: (${player.position.x.toFixed(1)}, ${player.position.y.toFixed(1)}) &nbsp; velocity: (${player.velocity.x.toFixed(1)}, ${player.velocity.y.toFixed(1)})
<br>

View File

@@ -16,17 +16,13 @@ const level = {
if (level.levelsCleared === 0) { //this code only runs on the first level
// game.enableConstructMode() //used to build maps in testing mode
// level.difficultyIncrease(9)
// mech.setField("time dilation field")
// mod.giveMod("logistics");
// mod.giveMod("negative temperature");
// b.giveGuns("flechettes")
mod.giveMod("automatic shotgun");
// b.giveGuns("spores")
// mech.setField("negative mass field")
// mech.setField("phase decoherence field")
// mech.setField("plasma torch")
level.intro(); //starting level
// level.testing();
// level.testing();
// level.stronghold()
// level.bosses();
// level.satellite();
@@ -58,8 +54,8 @@ const level = {
}
if (mod.isArmorFromPowerUps) {
// for (let i = 0; i < powerUps.totalPowerUps; i++) {}
mech.maxHealth += 0.03 * powerUps.totalPowerUps
game.makeTextLog("<span style='font-size:115%;'> max health increased by " + (0.05 * powerUps.totalPowerUps * 100).toFixed(0) + "%</span>", 300)
mech.maxHealth += 0.04 * powerUps.totalPowerUps
if (powerUps.totalPowerUps) game.makeTextLog("<span style='font-size:115%;'> max health increased by " + (0.04 * powerUps.totalPowerUps * 100).toFixed(0) + "%</span>", 300)
}
},
isBuildRun: false,
@@ -135,7 +131,7 @@ const level = {
//******************************************************************************************************************
testing() {
level.difficultyIncrease(14); //hard mode level 7
// level.difficultyIncrease(14); //hard mode level 7
spawn.setSpawnList();
spawn.setSpawnList();
level.defaultZoom = 1500
@@ -193,9 +189,10 @@ const level = {
// spawn.launcherBoss(1200, -500)
// spawn.laserTargetingBoss(1600, -400)
// spawn.spawner(1600, -500)
spawn.sniper(1700, -120, 50)
// spawn.sniper(1600, -120)
// spawn.sniper(1800, -120)
// spawn.sniper(1700, -120, 50)
spawn.sniper(1400, -120)
spawn.sniper(1800, -120)
spawn.sniper(2200, -120)
// spawn.cellBossCulture(1600, -500)
// spawn.shooter(1600, -500)
// spawn.striker(1600, -500)

View File

@@ -45,6 +45,9 @@ const mobs = {
},
statusSlow(who, cycles = 60) {
if (!who.shield && !who.isShielded && !mech.isBodiesAsleep) {
if (who.isBoss) {
cycles = Math.floor(cycles * 0.25)
}
//remove other "slow" effects on this mob
let i = who.status.length
while (i--) {
@@ -993,7 +996,7 @@ const mobs = {
if (Math.random() < mod.sporesOnDeath) {
const len = Math.min(30, Math.floor(4 + this.mass * Math.random()))
for (let i = 0; i < len; i++) {
b.spore(this) //spawn drone
b.spore(this.position)
}
}
if (Math.random() < mod.isBotSpawner) {

View File

@@ -245,14 +245,14 @@ const mod = {
},
{
name: "electrostatic shots",
description: "<strong>33%</strong> increased <strong class='color-d'>damage</strong><br><strong>33%</strong> increased <strong>delay</strong> after firing",
description: "<strong>25%</strong> increased <strong class='color-d'>damage</strong><br><strong>25%</strong> increased <strong>delay</strong> after firing",
maxCount: 1,
count: 0,
allowed() {
return true
},
effect() {
mod.slowFire = 1.33
mod.slowFire = 1.25
b.setFireCD();
},
remove() {
@@ -431,7 +431,7 @@ const mod = {
effect() {
mod.sporesOnDeath += 0.11;
for (let i = 0; i < 10; i++) {
b.spore(player)
b.spore(mech.pos)
}
},
remove() {
@@ -552,7 +552,7 @@ const mod = {
mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
},
remove() {
mod.collisionImmuneCycles = 30;
mod.collisionImmuneCycles = 15;
}
},
{
@@ -720,6 +720,38 @@ const mod = {
mech.displayHealth();
}
},
{
name: "negentropy",
description: "when below <strong>25%</strong> of <strong>maximum health</strong><br> <strong class='color-h'>heal</strong> <strong>1%</strong> of <strong>maximum health</strong> per second",
maxCount: 9,
count: 0,
allowed() {
return mech.maxHealth > 1
},
requires: "increased max health",
effect() {
mod.isHealLowHealth = true;
},
remove() {
mod.isHealLowHealth = false;
}
},
{
name: "crystallized armor",
description: "increase <strong>maximum</strong> <strong class='color-h'>health</strong> by <strong>4%</strong> for each<br>unused <strong>power up</strong> at the end of a <strong>level</strong>",
maxCount: 1,
count: 0,
allowed() {
return !mod.isEnergyHealth
},
requires: "not mass-energy equivalence",
effect() {
mod.isArmorFromPowerUps = true;
},
remove() {
mod.isArmorFromPowerUps = false;
}
},
{
name: "recursive healing",
description: "<strong class='color-h'>healing</strong> <strong>power ups</strong> trigger <strong>+1</strong> more time",
@@ -736,22 +768,6 @@ const mod = {
mod.recursiveHealing = 1;
}
},
{
name: "crystallized armor",
description: "increase <strong>maximum</strong> <strong class='color-h'>health</strong> by <strong>3%</strong> for each<br>unused <strong>power up</strong> at the end of a <strong>level</strong>",
maxCount: 1,
count: 0,
allowed() {
return !mod.isEnergyHealth
},
requires: "not mass-energy equivalence",
effect() {
mod.isArmorFromPowerUps = true;
},
remove() {
mod.isArmorFromPowerUps = false;
}
},
{
name: "pair production",
description: "<strong>power ups</strong> overfill your <strong class='color-f'>energy</strong><br>temporarily gain <strong>twice</strong> your max <strong class='color-f'>energy</strong>",
@@ -787,13 +803,13 @@ const mod = {
},
{
name: "logistics",
description: "<strong>ammo</strong> power ups <strong>add</strong> to your current <strong>gun</strong><br>spawn <strong>4 ammo</strong>",
description: "<strong>ammo</strong> power ups add to your <strong>current gun</strong><br>spawn <strong>4 ammo</strong>",
maxCount: 1,
count: 0,
allowed() {
return true
return b.inventory.length > 1
},
requires: "",
requires: "at least 2 guns",
effect() {
mod.isAmmoForGun = true;
for (let i = 0; i < 4; i++) {
@@ -858,6 +874,7 @@ const mod = {
description: "spawn <strong>5</strong> <strong class='color-m'>mods</strong><br><strong>power ups</strong> are limited to <strong>one choice</strong>",
maxCount: 1,
count: 0,
isNonRefundable: true,
allowed() {
return !mod.isExtraChoice
},
@@ -873,15 +890,36 @@ const mod = {
mod.isDeterminism = false;
}
},
{
name: "superdeterminism",
description: "spawn <strong>4</strong> <strong class='color-m'>mods</strong><br><strong class='color-r'>rerolls</strong>, <strong>guns</strong>, and <strong>fields</strong> will no longer <strong>spawn</strong>",
maxCount: 1,
count: 0,
isNonRefundable: true,
allowed() {
return mod.isDeterminism && !mod.manyWorlds
},
requires: "determinism",
effect: () => {
mod.isSuperDeterminism = true;
for (let i = 0; i < 4; i++) { //if you change the six also change it in Born rule
powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
if (Math.random() < mod.bayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
}
},
remove() {
mod.isSuperDeterminism = false;
}
},
{
name: "many-worlds",
description: "after choosing a <strong>gun</strong>, <strong>field</strong>, or <strong class='color-m'>mod</strong><br>spawn a <strong class='color-r'>reroll</strong>, if you have none",
maxCount: 1,
count: 0,
allowed() {
return true
return !mod.isSuperDeterminism
},
requires: "",
requires: "not superdeterminism",
effect: () => {
mod.manyWorlds = true;
},
@@ -947,7 +985,9 @@ const mod = {
for (let i = 0, len = mod.mods.length; i < len; i++) { // spawn new mods power ups
if (!mod.mods[i].isNonRefundable) count += mod.mods[i].count
}
if (mod.isDeterminism) count -= 5 //remove the 5 bonus mods when getting rid of determinism
if (mod.isDeterminism) count -= 3 //remove the bonus mods
if (mod.isSuperDeterminism) count -= 2 //remove the bonus mods
mod.setupAllMods(); // remove all mods
for (let i = 0; i < count; i++) { // spawn new mods power ups
powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
@@ -963,7 +1003,7 @@ const mod = {
count: 0,
isNonRefundable: true,
allowed() {
return (mod.totalCount > 0) && !build.isCustomSelection
return (mod.totalCount > 0) && !build.isCustomSelection && !mod.isSuperDeterminism
},
requires: "at least 1 mod",
effect: () => {
@@ -1121,6 +1161,22 @@ const mod = {
mod.isNailShot = false;
}
},
{
name: "automatic shotgun",
description: "the <strong>shotgun</strong> fires <strong>66%</strong> faster<br><strong>recoil</strong> is greatly increased",
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("shotgun")
},
requires: "shotgun",
effect() {
mod.isShotgunRecoil = true;
},
remove() {
mod.isShotgunRecoil = false;
}
},
{
name: "super duper",
description: "fire <strong>+2</strong> additional <strong>super balls</strong>",
@@ -1187,7 +1243,7 @@ const mod = {
},
{
name: "6s half-life",
description: "<strong>needles</strong> are exposed to <strong class='color-p'>plutonium-238</strong><br><strong>2x</strong> <strong class='color-d'>damage</strong> spread over <strong>6</strong> seconds",
description: "<strong>flechette</strong> needles made of <strong class='color-p'>plutonium-238</strong><br><strong>2x</strong> <strong class='color-d'>damage</strong> spread over <strong>6</strong> seconds",
maxCount: 1,
count: 0,
allowed() {
@@ -1203,7 +1259,7 @@ const mod = {
},
{
name: "1/2s half-life",
description: "<strong>needles</strong> are exposed to <strong class='color-p'>lithium-8</strong><br>flechette <strong class='color-d'>damage</strong> occurs after <strong>1/2</strong> a second",
description: "<strong>flechette</strong> needles made of <strong class='color-p'>lithium-8</strong><br>flechette <strong class='color-d'>damage</strong> occurs after <strong>1/2</strong> a second",
maxCount: 1,
count: 0,
allowed() {
@@ -1259,7 +1315,7 @@ const mod = {
},
requires: "wave beam",
effect() {
mod.waveSpeedMap = 3 //needs to be 3 for pocket universe require check
mod.waveSpeedMap = 3 //needs to be 3 to stop bound state require check
mod.waveSpeedBody = 1.9
},
remove() {
@@ -1268,8 +1324,8 @@ const mod = {
}
},
{
name: "pocket universe",
description: "<strong>wave beam</strong> bullets last <strong>5x</strong> longer<br>bullets are <strong>confined</strong> to a <strong>region</strong> around player",
name: "bound state",
description: "<strong>wave beam</strong> bullets last <strong>5x</strong> longer<br>bullets are <strong>bound</strong> to a <strong>region</strong> around player",
maxCount: 1,
count: 0,
allowed() {
@@ -1385,7 +1441,7 @@ const mod = {
},
{
name: "rocket-propelled grenade",
description: "<strong>grenades</strong> are rapidly <strong>accelerated</strong> forward<br>map <strong>collisions</strong> trigger an <strong class='color-e'>explosion</strong>",
description: "<strong>grenades</strong> rapidly <strong>accelerate</strong> forward<br>map <strong>collisions</strong> trigger an <strong class='color-e'>explosion</strong>",
maxCount: 1,
count: 0,
allowed() {
@@ -1527,6 +1583,23 @@ const mod = {
mod.isMutualism = false
}
},
{
name: "cryodesiccation",
description: "<strong class='color-p' style='letter-spacing: 2px;'>spores</strong> <strong class='color-s'>freeze</strong> mobs for <strong>1</strong> second",
// <br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> do <strong>1/3</strong> <strong class='color-d'>damage</strong>
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("spores") || mod.sporesOnDeath > 0 || mod.isSporeField
},
requires: "spores",
effect() {
mod.isSporeFreeze = true
},
remove() {
mod.isSporeFreeze = false
}
},
{
name: "brushless motor",
description: "<strong>drones</strong> accelerate <strong>50%</strong> faster",
@@ -1545,7 +1618,7 @@ const mod = {
},
{
name: "heavy water",
description: "<strong>ice IX</strong> is synthesized with unstable isotopes<br>does <strong class='color-p'>radioactive</strong> <strong class='color-d'>damage</strong> over 3 seconds",
description: "<strong>ice IX</strong> is synthesized with an extra neutron<br>does <strong class='color-p'>radioactive</strong> <strong class='color-d'>damage</strong> over 3 seconds",
maxCount: 1,
count: 0,
allowed() {
@@ -1553,15 +1626,15 @@ const mod = {
},
requires: "ice IX",
effect() {
mod.isAlphaRadiation = true
mod.isHeavyWater = true
},
remove() {
mod.isAlphaRadiation = false;
mod.isHeavyWater = false;
}
},
{
name: "necrophoresis",
description: "<strong>foam</strong> splits into 3 <strong>copies</strong><br>when the mob it is stuck to <strong>dies</strong>",
description: "<strong>foam</strong> splits into 3 <strong>copies</strong><br>when the mob it's stuck to <strong>dies</strong>",
maxCount: 1,
count: 0,
allowed() {
@@ -1644,6 +1717,38 @@ const mod = {
mod.isPulseStun = false;
}
},
// {
// name: "aim",
// description: "<strong>pulse</strong> <strong class='color-e'>explosions</strong> aim",
// maxCount: 1,
// count: 0,
// allowed() {
// return mod.haveGunCheck("pulse")
// },
// requires: "pulse",
// effect() {
// mod.isPulseAim = true;
// },
// remove() {
// mod.isPulseAim = false;
// }
// },
// {
// name: "fast ignition",
// description: "<strong>pulse</strong> <strong class='color-e'>explosions</strong> more <strong>efficient</strong><br><strong>delay</strong> after firing is <strong>shorter</strong>",
// maxCount: 1,
// count: 0,
// allowed() {
// return mod.haveGunCheck("pulse")
// },
// requires: "pulse",
// effect() {
// mod.isRapidPulse = true;
// },
// remove() {
// mod.isRapidPulse = false;
// }
// },
//**************************************************
//************************************************** field
//************************************************** mods
@@ -1772,7 +1877,7 @@ const mod = {
},
{
name: "bremsstrahlung radiation",
description: "<strong>blocking</strong> with your field does <strong class='color-d'>damage</strong>",
description: "<strong>blocking</strong> with <strong>standing wave harmonics</strong><br> does <strong class='color-d'>damage</strong> to mobs",
maxCount: 9,
count: 0,
allowed() {
@@ -1945,9 +2050,9 @@ const mod = {
count: 0,
isNonRefundable: true,
allowed() {
return true
return !mod.isSuperDeterminism
},
requires: "",
requires: "not superdeterminism",
effect() {
for (let i = 0; i < 6; i++) {
powerUps.spawn(mech.pos.x, mech.pos.y, "reroll");
@@ -1963,9 +2068,9 @@ const mod = {
count: 0,
isNonRefundable: true,
allowed() {
return true
return !mod.isSuperDeterminism
},
requires: "",
requires: "not superdeterminism",
effect() {
powerUps.spawn(mech.pos.x, mech.pos.y, "gun");
if (Math.random() < mod.bayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "gun");
@@ -1979,9 +2084,9 @@ const mod = {
count: 0,
isNonRefundable: true,
allowed() {
return true
return !mod.isSuperDeterminism
},
requires: "",
requires: "not superdeterminism",
effect() {
powerUps.spawn(mech.pos.x, mech.pos.y, "field");
if (Math.random() < mod.bayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "field");
@@ -2050,7 +2155,7 @@ const mod = {
isBlockStun: null,
isStunField: null,
isHarmDamage: null,
isAlphaRadiation: null,
isHeavyWater: null,
energyRegen: null,
isVacuumShield: null,
renormalization: null,
@@ -2067,6 +2172,7 @@ const mod = {
isRPG: null,
is3Missiles: null,
isDeterminism: null,
isSuperDeterminism: null,
isHarmReduce: null,
nailsDeathMob: null,
isSlowFPS: null,
@@ -2081,5 +2187,10 @@ const mod = {
fastTimeJump: null,
isFastDot: null,
isArmorFromPowerUps: null,
isAmmoForGun: null
isAmmoForGun: null,
isRapidPulse: null,
// isPulseAim: null,
isSporeFreeze: null,
isShotgunRecoil: null,
isHealLowHealth: null
}

View File

@@ -219,17 +219,6 @@ const mech = {
mech.doCrouch();
mech.yOff = mech.yOffWhen.jump;
mech.hardLandCD = mech.cycle + Math.min(momentum / 6.5 - 6, 40)
// if (mod.isStomp) {
// const len = Math.min(25, (momentum - 120) * 0.1)
// for (let i = 0; i < len; i++) {
// b.spore(player) //spawn drone
// }
// } else if (player.velocity.y > 27 && momentum > 180 * mod.squirrelFx) { //falling damage
// let dmg = Math.sqrt(momentum - 180) * 0.01
// dmg = Math.min(Math.max(dmg, 0.02), 0.20);
// mech.damage(dmg);
// }
} else {
mech.yOffGoal = mech.yOffWhen.stand;
}
@@ -316,8 +305,11 @@ const mech = {
//count mods
let totalMods = 0;
for (let i = 0; i < mod.mods.length; i++) {
totalMods += mod.mods[i].count
if (!mod.mods[i].isNonRefundable) totalMods += mod.mods[i].count
}
if (mod.isDeterminism) totalMods -= 3 //remove the bonus mods
if (mod.isSuperDeterminism) totalMods -= 2 //remove the bonus mods
const totalGuns = b.inventory.length //count guns
function randomizeMods() {
@@ -328,7 +320,6 @@ const mech = {
if (mod.mods[i].count < mod.mods[i].maxCount &&
!mod.mods[i].isNonRefundable &&
mod.mods[i].name !== "quantum immortality" &&
mod.mods[i].name !== "determinism" &&
mod.mods[i].allowed()
) options.push(i);
}
@@ -1335,7 +1326,7 @@ const mech = {
const len = Math.floor(6 + 4 * Math.random())
mech.energy -= len * 0.074;
for (let i = 0; i < len; i++) {
b.spore(player)
b.spore(mech.pos)
}
} else if (mod.isMissileField) {
// mech.fieldCDcycle = mech.cycle + 10; // set cool down to prevent +energy from making huge numbers of drones
@@ -1506,9 +1497,8 @@ const mech = {
name: "plasma torch",
description: "use <strong class='color-f'>energy</strong> to emit short range plasma<br>plasma <strong class='color-d'>damages</strong> and <strong>pushes</strong> mobs",
isEasyToAim: false,
effect: () => {
effect() {
mech.fieldMeterColor = "#f0f"
mech.hold = function () {
if (mech.isHolding) {
mech.drawHold(mech.holdingTarget);
@@ -1607,13 +1597,6 @@ const mech = {
x: best.who.velocity.x * 0.7,
y: best.who.velocity.y * 0.7
});
// const angle = Math.atan2(player.position.y - best.who.position.y, player.position.x - best.who.position.x);
// const mass = Math.min(Math.sqrt(best.who.mass), 6);
// Matter.Body.setVelocity(best.who, {
// x: best.who.velocity.x * 0.85 - 3 * Math.cos(angle) / mass,
// y: best.who.velocity.y * 0.85 - 3 * Math.sin(angle) / mass
// });
//draw mob damage circle
game.drawList.push({
x: path[1].x,
@@ -1648,7 +1631,6 @@ const mech = {
ctx.beginPath();
ctx.moveTo(x, y);
const step = Vector.magnitude(Vector.sub(path[0], path[1])) / 10
for (let i = 0; i < 8; i++) {
x += step * (Dx + 1.5 * (Math.random() - 0.5))
y += step * (Dy + 1.5 * (Math.random() - 0.5))
@@ -1656,12 +1638,6 @@ const mech = {
}
ctx.lineWidth = 2 * Math.random();
ctx.stroke();
//draw shield around player
// ctx.beginPath();
// ctx.arc(mech.pos.x, mech.pos.y, mech.fieldRange * 0.75, 0, 2 * Math.PI);
// ctx.fillStyle = "rgba(255,0,255,0.05)"
// ctx.fill();
// mech.pushBody360(100); //disabled because doesn't work at short range
}
} else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding, but field button is released
mech.pickUp();
@@ -1669,6 +1645,7 @@ const mech = {
mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
}
mech.drawFieldMeter("rgba(0, 0, 0, 0.2)")
}
}
},

View File

@@ -475,35 +475,35 @@ const powerUps = {
}
},
spawn(x, y, target, moving = true, mode = null) {
// if (!level.isBuildRun || target === "heal" || target === "ammo") {
let index = powerUp.length;
target = powerUps[target];
size = target.size();
powerUp[index] = Matter.Bodies.polygon(x, y, 0, size, {
density: 0.001,
frictionAir: 0.01,
restitution: 0.8,
inertia: Infinity, //prevents rotation
collisionFilter: {
group: 0,
category: cat.powerUp,
mask: cat.map | cat.powerUp
},
color: target.color,
effect: target.effect,
name: target.name,
size: size
});
if (mode) {
powerUp[index].mode = mode
}
if (moving) {
Matter.Body.setVelocity(powerUp[index], {
x: (Math.random() - 0.5) * 15,
y: Math.random() * -9 - 3
if (!(mod.isSuperDeterminism && (target === 'gun' || target === 'field' || target === 'reroll'))) {
let index = powerUp.length;
target = powerUps[target];
size = target.size();
powerUp[index] = Matter.Bodies.polygon(x, y, 0, size, {
density: 0.001,
frictionAir: 0.01,
restitution: 0.8,
inertia: Infinity, //prevents rotation
collisionFilter: {
group: 0,
category: cat.powerUp,
mask: cat.map | cat.powerUp
},
color: target.color,
effect: target.effect,
name: target.name,
size: size
});
if (mode) {
powerUp[index].mode = mode
}
if (moving) {
Matter.Body.setVelocity(powerUp[index], {
x: (Math.random() - 0.5) * 15,
y: Math.random() * -9 - 3
});
}
World.add(engine.world, powerUp[index]); //add to world
}
World.add(engine.world, powerUp[index]); //add to world
// }
},
};

View File

@@ -159,6 +159,7 @@ const spawn = {
cellBoss(x, y, radius = 20) {
mobs.spawn(x + Math.random(), y + Math.random(), 20, radius * (1 + 1.2 * Math.random()), "rgba(0,150,155,0.7)");
let me = mob[mob.length - 1];
me.isBoss = true;
me.isCell = true;
me.accelMag = 0.00015 * game.accelScale;
me.memory = 40;
@@ -214,11 +215,12 @@ const spawn = {
}
};
me.onDeath = function () {
this.isCell = false;
let count = 0 //count other cells
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].isCell) count++
}
if (count === 1) { //only drop a power up if this is the last cell
if (count < 1) { //only drop a power up if this is the last cell
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
} else {
this.leaveBody = false;
@@ -553,6 +555,7 @@ const spawn = {
suckerBoss(x, y, radius = 25) {
mobs.spawn(x, y, 12, radius, "#000");
let me = mob[mob.length - 1];
me.isBoss = true;
me.stroke = "transparent"; //used for drawSneaker
me.eventHorizon = 1100; //required for black hole
me.seeAtDistance2 = (me.eventHorizon + 1000) * (me.eventHorizon + 1000); //vision limit is event horizon
@@ -653,6 +656,7 @@ const spawn = {
let targets = [] //track who is in the node boss, for shields
mobs.spawn(x, y, 6, radius, "#b386e8");
let me = mob[mob.length - 1];
me.isBoss = true;
targets.push(me.id) //add to shield protection
me.friction = 0;
me.frictionAir = 0.0065;
@@ -732,6 +736,7 @@ const spawn = {
timeSkipBoss(x, y, radius = 55) {
mobs.spawn(x, y, 6, radius, '#000');
let me = mob[mob.length - 1];
me.isBoss = true;
// me.stroke = "transparent"; //used for drawSneaker
me.timeSkipLastCycle = 0
me.eventHorizon = 1800; //required for black hole
@@ -896,6 +901,7 @@ const spawn = {
const color = "#05f"
mobs.spawn(x, y, 3, radius, color);
let me = mob[mob.length - 1];
me.isBoss = true;
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
Matter.Body.rotate(me, Math.random() * Math.PI * 2);
me.accelMag = 0.0005 * game.accelScale;
@@ -1054,6 +1060,7 @@ const spawn = {
laserBoss(x, y, radius = 30) {
mobs.spawn(x, y, 3, radius, "#f00");
let me = mob[mob.length - 1];
me.isBoss = true;
me.startingPosition = {
x: x,
y: y
@@ -1463,6 +1470,7 @@ const spawn = {
//boss that drops bombs from above and holds a set distance from player
mobs.spawn(x, y, 3, radius, "transparent");
let me = mob[mob.length - 1];
me.isBoss = true;
Matter.Body.setDensity(me, 0.0015 + 0.0004 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.stroke = "rgba(255,0,200)"; //used for drawGhost
@@ -1527,6 +1535,7 @@ const spawn = {
shooterBoss(x, y, radius = 130) {
mobs.spawn(x, y, 3, radius, "rgb(255,70,180)");
let me = mob[mob.length - 1];
me.isBoss = true;
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
me.isVerticesChange = true
me.memory = 240;
@@ -1739,7 +1748,7 @@ const spawn = {
this.seePlayerCheck();
this.checkStatus();
this.attraction();
if (this.seePlayer.recall && !(game.cycle % this.fireFreq)) {
if (this.seePlayer.recall && !(game.cycle % this.fireFreq) && !mech.isBodiesAsleep) {
Matter.Body.setAngularVelocity(this, 0.14)
//fire a bullet from each vertex
for (let i = 0, len = this.vertices.length; i < len; i++) {
@@ -1757,6 +1766,7 @@ const spawn = {
launcherBoss(x, y, radius = 90) {
mobs.spawn(x, y, 6, radius, "rgb(150,150,255)");
let me = mob[mob.length - 1];
me.isBoss = true;
me.accelMag = 0.00008 * game.accelScale;
me.fireFreq = Math.floor(330 * game.CDScale)
me.frictionStatic = 0;
@@ -1776,7 +1786,7 @@ const spawn = {
this.checkStatus();
this.attraction();
this.repulsion();
if (this.seePlayer.recall && !(game.cycle % this.fireFreq)) {
if (this.seePlayer.recall && !(game.cycle % this.fireFreq) && !mech.isBodiesAsleep) {
Matter.Body.setAngularVelocity(this, 0.11)
//fire a bullet from each vertex
for (let i = 0, len = this.vertices.length; i < len; i++) {
@@ -1881,6 +1891,7 @@ const spawn = {
//snake boss with a laser head
mobs.spawn(x, y, 8, radius, "rgb(255,50,130)");
let me = mob[mob.length - 1];
me.isBoss = true;
me.accelMag = 0.0012 * game.accelScale;
me.memory = 200;
me.laserRange = 500;
@@ -1922,6 +1933,7 @@ const spawn = {
// often has a ring of mobs around it
mobs.spawn(x, y, 8, radius, "rgb(0,60,80)");
let me = mob[mob.length - 1];
me.isBoss = true;
me.g = 0.0001; //required if using 'gravity'
me.accelMag = 0.002 * game.accelScale;
me.memory = 20;