osmoprotectant

after you die, you can find the build you used in the custom menu

shooterBoss - smaller, but more massive,
  aims better at short range, and fires faster
bomberBoss fires faster, bombs are more likely to split

mod: osmoprotectant - stunned or frozen mobs cause no harm
This commit is contained in:
landgreen
2020-09-06 18:07:43 -07:00
parent 6c51916f04
commit e3d8dda23f
11 changed files with 130 additions and 130 deletions

View File

@@ -2418,7 +2418,7 @@ const b = {
}, },
{ {
name: "spores", name: "spores",
description: "fire a <strong>sporangium</strong> that discharges <strong class='color-p' style='letter-spacing: 2px;'>spores</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> seek out nearby mobs", description: "fire a <strong class='color-p' style='letter-spacing: 2px;'>sporangium</strong> that discharges <strong class='color-p' style='letter-spacing: 2px;'>spores</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> seek out nearby mobs",
ammo: 0, ammo: 0,
ammoPack: 3, ammoPack: 3,
have: false, have: false,

View File

@@ -135,25 +135,11 @@ function collisionChecks(event) {
function collideMob(obj) { function collideMob(obj) {
//player + mob collision //player + mob collision
if (mech.immuneCycle < mech.cycle && (obj === playerBody || obj === playerHead)) { if (
// const a = Object.values(event.pairs[0].contacts) mech.immuneCycle < mech.cycle &&
// contains = Matter.Bounds.contains({ (obj === playerBody || obj === playerHead) &&
// max: { !(mod.isFreezeHarmImmune && (mob[k].isSlowed || mob[k].isStunned))
// x: player.position.x + 60, ) {
// y: player.position.y + 120
// },
// min: {
// x: player.position.x - 60,
// y: player.position.y + 40
// }
// }, {
// x: a[0].vertex.x,
// y: a[0].vertex.y
// })
// // Matter.Query.point([jumpSensor], point)
// console.log(contains)
// if (!contains) {
mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
mob[k].foundPlayer(); mob[k].foundPlayer();
let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * game.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0 let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * game.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0
@@ -168,10 +154,7 @@ function collisionChecks(event) {
if (mod.mods[i].count > 0) have.push(i) if (mod.mods[i].count > 0) have.push(i)
} }
const choose = have[Math.floor(Math.random() * have.length)] const choose = have[Math.floor(Math.random() * have.length)]
//message about what mod was lost game.makeTextLog(`<div class='circle mod'></div> &nbsp; <strong>${mod.mods[choose].name}</strong> ejected by exciton-lattice`, 300) //message about what mod was lost
game.makeTextLog(`<div class='circle mod'></div> &nbsp; <strong>${mod.mods[choose].name}</strong> ejected by exciton-lattice`, 300)
for (let i = 0; i < mod.mods[choose].count; i++) powerUps.spawn(mech.pos.x, mech.pos.y, "mod"); for (let i = 0; i < mod.mods[choose].count; i++) powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
mod.mods[choose].count = 0; mod.mods[choose].count = 0;
mod.mods[choose].remove(); // remove a random mod form the list of mods you have mod.mods[choose].remove(); // remove a random mod form the list of mods you have

View File

@@ -621,7 +621,6 @@ const game = {
game.CDScale = 1; game.CDScale = 1;
game.difficulty = 0; game.difficulty = 0;
game.difficultyMode = Number(document.getElementById("difficulty-select").value) game.difficultyMode = Number(document.getElementById("difficulty-select").value)
level.isBuildRun = false;
build.isCustomSelection = false; build.isCustomSelection = false;
if (game.difficultyMode === 0) { if (game.difficultyMode === 0) {
game.isEasyMode = true; game.isEasyMode = true;
@@ -652,7 +651,6 @@ const game = {
splashReturn() { splashReturn() {
game.onTitlePage = true; game.onTitlePage = true;
// document.getElementById('splash').onclick = 'run(this)'; // document.getElementById('splash').onclick = 'run(this)';
// build.isURLBuild = false;
document.getElementById("splash").onclick = function () { document.getElementById("splash").onclick = function () {
game.startGame(); game.startGame();
}; };
@@ -669,8 +667,8 @@ const game = {
}, },
fpsInterval: 0, //set in startGame fpsInterval: 0, //set in startGame
then: null, then: null,
startGame() { startGame(isBuildRun = false) {
if (!level.isBuildRun) { //if a build run logic flow returns to "build-button").addEventListener if (!isBuildRun) { //if a build run logic flow returns to "build-button").addEventListener
document.body.style.cursor = "none"; document.body.style.cursor = "none";
document.body.style.overflow = "hidden" document.body.style.overflow = "hidden"
} }
@@ -686,7 +684,6 @@ const game = {
if (game.firstRun) { if (game.firstRun) {
mech.spawn(); //spawns the player mech.spawn(); //spawns the player
mod.setupAllMods(); //doesn't run on reset so that gun mods carry over to new runs
if (game.isCommunityMaps) { if (game.isCommunityMaps) {
level.levels.push("stronghold"); level.levels.push("stronghold");
level.levels.push("basement"); level.levels.push("basement");

View File

@@ -50,7 +50,6 @@ function getUrlVars() {
window.addEventListener('load', (event) => { window.addEventListener('load', (event) => {
const set = getUrlVars() const set = getUrlVars()
if (Object.keys(set).length !== 0) { if (Object.keys(set).length !== 0) {
build.isURLBuild = true;
// game.startGame() // game.startGame()
openCustomBuildMenu(); openCustomBuildMenu();
//add custom selections based on url //add custom selections based on url
@@ -118,7 +117,6 @@ window.addEventListener('load', (event) => {
//build build grid display //build build grid display
const build = { const build = {
isURLBuild: false,
onLoadPowerUps() { onLoadPowerUps() {
const set = getUrlVars() const set = getUrlVars()
if (Object.keys(set).length !== 0) { if (Object.keys(set).length !== 0) {
@@ -309,6 +307,7 @@ const build = {
for (let i = 0, len = mech.fieldUpgrades.length; i < len; i++) { for (let i = 0, len = mech.fieldUpgrades.length; i < len; i++) {
text += `<div id ="field-${i}" class="build-grid-module" onclick="build.choosePowerUp(this,${i},'field')"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${mech.fieldUpgrades[i].name}</div> ${mech.fieldUpgrades[i].description}</div>` text += `<div id ="field-${i}" class="build-grid-module" onclick="build.choosePowerUp(this,${i},'field')"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${mech.fieldUpgrades[i].name}</div> ${mech.fieldUpgrades[i].description}</div>`
} }
for (let i = 0, len = b.guns.length; i < len; i++) { for (let i = 0, len = b.guns.length; i < len; i++) {
text += `<div id = "gun-${i}" class="build-grid-module" onclick="build.choosePowerUp(this,${i},'gun')"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[i].name}</div> ${b.guns[i].description}</div>` text += `<div id = "gun-${i}" class="build-grid-module" onclick="build.choosePowerUp(this,${i},'gun')"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[i].name}</div> ${b.guns[i].description}</div>`
} }
@@ -400,7 +399,6 @@ const build = {
} }
function openCustomBuildMenu() { function openCustomBuildMenu() {
build.isURLBuild = false;
game.isCheating = true; game.isCheating = true;
document.getElementById("build-button").style.display = "none"; document.getElementById("build-button").style.display = "none";
const el = document.getElementById("build-grid") const el = document.getElementById("build-grid")
@@ -409,15 +407,38 @@ function openCustomBuildMenu() {
document.body.style.overflowX = "hidden"; document.body.style.overflowX = "hidden";
document.getElementById("info").style.display = 'none' document.getElementById("info").style.display = 'none'
level.isBuildRun = true; game.startGame(true); //starts game, but pauses it
game.startGame(); //starts game, but pauses it
build.isCustomSelection = true; build.isCustomSelection = true;
game.paused = true; game.paused = true;
build.reset(); build.reset();
} }
document.getElementById("build-button").addEventListener("click", () => { //setup build run document.getElementById("build-button").addEventListener("click", () => { //setup build run
//record settings so they can be reproduced in the custom menu
let field = 0;
let inventory = [];
let modList = [];
if (!game.firstRun) {
field = mech.fieldMode
inventory = [...b.inventory]
for (let i = 0; i < mod.mods.length; i++) {
modList.push(mod.mods[i].count)
}
}
openCustomBuildMenu(); openCustomBuildMenu();
if (!game.firstRun) { //if player has already died once load that previous build
// console.log(modList)
build.choosePowerUp(document.getElementById(`field-${field}`), field, 'field')
for (let i = 0; i < inventory.length; i++) {
build.choosePowerUp(document.getElementById(`gun-${inventory[i]}`), inventory[i], 'gun')
}
for (let i = 0; i < modList.length; i++) {
for (let j = 0; j < modList[i]; j++) {
build.choosePowerUp(document.getElementById(`mod-${i}`), i, 'mod')
}
}
}
}); });

View File

@@ -9,15 +9,14 @@ const level = {
levelsCleared: 0, levelsCleared: 0,
levels: ["skyscrapers", "rooftops", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber"], levels: ["skyscrapers", "rooftops", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber"],
start() { start() {
// if (build.isURLBuild && level.levelsCleared === 0) build.onLoadPowerUps();
if (level.levelsCleared === 0) { //this code only runs on the first level if (level.levelsCleared === 0) { //this code only runs on the first level
// level.difficultyIncrease(12) // level.difficultyIncrease(8)
// game.enableConstructMode() //used to build maps in testing mode // game.enableConstructMode() //used to build maps in testing mode
// game.zoomScale = 1000; // game.zoomScale = 1000;
// game.setZoom(); // game.setZoom();
// mech.isStealth = true; // mech.isStealth = true;
// mech.setField("time dilation field") // mech.setField("time dilation field")
// b.giveGuns("rail gun") // b.giveGuns("ice IX")
// mod.giveMod("quantum immortality"); // mod.giveMod("quantum immortality");
level.intro(); //starting level level.intro(); //starting level
@@ -136,8 +135,8 @@ const level = {
// spawn.launcherBoss(1200, -500) // spawn.launcherBoss(1200, -500)
// spawn.laserTargetingBoss(1600, -400) // spawn.laserTargetingBoss(1600, -400)
// spawn.spawner(1600, -500) // spawn.spawner(1600, -500)
// spawn.sniper(1700, -120, 50) spawn.sniper(1700, -120, 50)
spawn.starter(1400, -120, 100) // spawn.bomberBoss(1400, -500)
// spawn.sniper(1800, -120) // spawn.sniper(1800, -120)
// spawn.sniper(2200, -120) // spawn.sniper(2200, -120)
// spawn.cellBossCulture(1600, -500) // spawn.cellBossCulture(1600, -500)
@@ -3164,9 +3163,7 @@ const level = {
//****************************************************************************************************************** //******************************************************************************************************************
//****************************************************************************************************************** //******************************************************************************************************************
//****************************************************************************************************************** //******************************************************************************************************************
isBuildRun: false,
difficultyIncrease(num = 1) { difficultyIncrease(num = 1) {
// if (level.isBuildRun) num++
for (let i = 0; i < num; i++) { for (let i = 0; i < num; i++) {
game.difficulty++ game.difficulty++
game.dmgScale += 0.3; //damage done by mobs increases each level game.dmgScale += 0.3; //damage done by mobs increases each level

View File

@@ -60,7 +60,6 @@ const mobs = {
}); });
} }
function applySlow(target) { function applySlow(target) {
if (!target.shield && !target.isShielded && !mech.isBodiesAsleep) { if (!target.shield && !target.isShielded && !mech.isBodiesAsleep) {
if (target.isBoss) cycles = Math.floor(cycles * 0.25) if (target.isBoss) cycles = Math.floor(cycles * 0.25)
@@ -69,6 +68,7 @@ const mobs = {
while (i--) { while (i--) {
if (target.status[i].type === "slow") target.status.splice(i, 1); //remove other "slow" effects on this mob if (target.status[i].type === "slow") target.status.splice(i, 1); //remove other "slow" effects on this mob
} }
target.isSlowed = true;
target.status.push({ target.status.push({
effect() { effect() {
Matter.Body.setVelocity(target, { Matter.Body.setVelocity(target, {
@@ -88,6 +88,10 @@ const mobs = {
ctx.fillStyle = target.fill ctx.fillStyle = target.fill
ctx.fill(); ctx.fill();
}, },
endEffect() {
//check to see if there are not other freeze effects?
target.isSlowed = false;
},
type: "slow", type: "slow",
endCycle: game.cycle + cycles, endCycle: game.cycle + cycles,
}) })
@@ -138,6 +142,7 @@ const mobs = {
}, },
endEffect() {},
type: "stun", type: "stun",
endCycle: game.cycle + cycles, endCycle: game.cycle + cycles,
}) })
@@ -163,6 +168,7 @@ const mobs = {
} }
}, },
endEffect() {},
// type: "DoT", // type: "DoT",
endCycle: game.cycle + cycles, endCycle: game.cycle + cycles,
startCycle: game.cycle startCycle: game.cycle
@@ -242,9 +248,14 @@ const mobs = {
let j = this.status.length; let j = this.status.length;
while (j--) { while (j--) {
this.status[j].effect(); this.status[j].effect();
if (this.status[j].endCycle < game.cycle) this.status.splice(j, 1); if (this.status[j].endCycle < game.cycle) {
this.status[j].endEffect();
this.status.splice(j, 1);
}
} }
}, },
isSlowed: false,
isStunned: false,
seeAtDistance2: Infinity, //sqrt(4000000) = 2000 = max seeing range seeAtDistance2: Infinity, //sqrt(4000000) = 2000 = max seeing range
distanceToPlayer() { distanceToPlayer() {
const dx = this.position.x - player.position.x; const dx = this.position.x - player.position.x;
@@ -882,7 +893,7 @@ const mobs = {
//set direction to turn to fire //set direction to turn to fire
if (!(game.cycle % this.seePlayerFreq)) { if (!(game.cycle % this.seePlayerFreq)) {
this.fireDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position)); this.fireDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position));
this.fireDir.y -= Math.abs(this.seePlayer.position.x - this.position.x) / 1600; //gives the bullet an arc this.fireDir.y -= Math.abs(this.seePlayer.position.x - this.position.x) / 2500; //gives the bullet an arc //was / 1600
} }
//rotate towards fireAngle //rotate towards fireAngle
const angle = this.angle + Math.PI / 2; const angle = this.angle + Math.PI / 2;
@@ -897,8 +908,8 @@ const mobs = {
spawn.bullet(this.vertices[1].x, this.vertices[1].y, 5 + Math.ceil(this.radius / 15), 5); spawn.bullet(this.vertices[1].x, this.vertices[1].y, 5 + Math.ceil(this.radius / 15), 5);
const v = 15; const v = 15;
Matter.Body.setVelocity(mob[mob.length - 1], { Matter.Body.setVelocity(mob[mob.length - 1], {
x: this.velocity.x + this.fireDir.x * v + Math.random(), x: this.velocity.x + this.fireDir.x * v + 3 * Math.random(),
y: this.velocity.y + this.fireDir.y * v + Math.random() y: this.velocity.y + this.fireDir.y * v + 3 * Math.random()
}); });
this.noseLength = 0; this.noseLength = 0;
// recoil // recoil
@@ -1029,7 +1040,7 @@ const mobs = {
} }
if (Math.random() < mod.isBotSpawner) b.randomBot(this.position, false) if (Math.random() < mod.isBotSpawner) b.randomBot(this.position, false)
if (mod.isExplodeMob) b.explosion(this.position, Math.min(450, Math.sqrt(this.mass + 3) * 80)) if (mod.isExplodeMob) b.explosion(this.position, Math.min(450, Math.sqrt(this.mass + 3) * 80))
if (mod.nailsDeathMob) b.targetedNail(this.position, mod.nailsDeathMob) if (mod.nailsDeathMob) b.targetedNail(this.position, mod.nailsDeathMob, 40 + 7 * Math.random())
} else if (mod.isShieldAmmo && this.shield) { } else if (mod.isShieldAmmo && this.shield) {
let type = "ammo" let type = "ammo"
if (Math.random() < 0.4) { if (Math.random() < 0.4) {

View File

@@ -368,7 +368,7 @@ const mod = {
}, },
{ {
name: "impact shear", name: "impact shear",
description: "mobs release <strong>2</strong> <strong>nails</strong> when they <strong>die</strong><br>nails target nearby mobs", description: "mobs release <strong>1-2</strong> <strong>nails</strong> when they <strong>die</strong><br>nails target nearby mobs",
maxCount: 9, maxCount: 9,
count: 0, count: 0,
allowed() { allowed() {
@@ -761,6 +761,23 @@ const mod = {
mod.isHarmFreeze = false; mod.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 mod.superposition + !!mod.isStunField + mod.isPulseStun + !!mod.isNeutronStun + mod.oneSuperBall + mod.isHarmFreeze + mod.isIceField + mod.isIceCrystals + mod.isSporeFreeze + mod.isAoESlow + mod.isFreezeMobs + mod.isPilotFreeze + mod.haveGunCheck("ice IX") > 1
},
requires: "at least 2 freezing or stunning effects",
effect() {
mod.isFreezeHarmImmune = true;
},
remove() {
mod.isFreezeHarmImmune = false;
}
},
{ {
name: "piezoelectricity", name: "piezoelectricity",
description: "<strong>colliding</strong> with mobs fills your <strong class='color-f'>energy</strong><br><strong>15%</strong> less <strong class='color-harm'>harm</strong> from mob collisions", description: "<strong>colliding</strong> with mobs fills your <strong class='color-f'>energy</strong><br><strong>15%</strong> less <strong class='color-harm'>harm</strong> from mob collisions",
@@ -952,22 +969,6 @@ const mod = {
mod.isHealLowHealth = false; mod.isHealLowHealth = false;
} }
}, },
// {
// name: "prismatic cleavage",
// description: "harm that would be fatal no longer kills you<br>instead it is removed from your maximum health",
// maxCount: 1,
// count: 0,
// allowed() {
// return mech.maxHealth > 1 || mod.isArmorFromPowerUps
// },
// requires: "increased max health",
// effect() {
// mod.isMaxHealthRemove = true;
// },
// remove() {
// mod.isMaxHealthRemove = false;
// }
// },
{ {
name: "adiabatic healing", name: "adiabatic healing",
description: "<strong class='color-h'>heal</strong> <strong>power ups</strong> are <strong>100%</strong> more effective", description: "<strong class='color-h'>heal</strong> <strong>power ups</strong> are <strong>100%</strong> more effective",
@@ -2020,7 +2021,7 @@ const mod = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
return mod.haveGunCheck("ice IX") || mod.isIceCrystals || mod.isSporeFreeze || (mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" && mod.isIceField) return mod.haveGunCheck("ice IX") || mod.isIceCrystals || mod.isSporeFreeze || mod.isIceField
}, },
requires: "a freeze effect", requires: "a freeze effect",
effect() { effect() {
@@ -2171,13 +2172,13 @@ const mod = {
requires: "laser", requires: "laser",
effect() { effect() {
mod.laserReflections++; mod.laserReflections++;
mod.laserDamage += 0.065; //base is 0.11 mod.laserDamage += 0.06; //base is 0.12
mod.laserFieldDrain += 0.0009 //base is 0.002 mod.laserFieldDrain += 0.0008 //base is 0.002
}, },
remove() { remove() {
mod.laserReflections = 2; mod.laserReflections = 2;
mod.laserDamage = 0.13; mod.laserDamage = 0.12;
mod.laserFieldDrain = 0.0018; mod.laserFieldDrain = 0.0016;
} }
}, },
{ {
@@ -2213,22 +2214,6 @@ const mod = {
mod.isPulseAim = false; 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 //************************************************** field
//************************************************** mods //************************************************** mods
@@ -2734,5 +2719,6 @@ const mod = {
nailGun: null, nailGun: null,
nailInstantFireRate: null, nailInstantFireRate: null,
isCapacitor: null, isCapacitor: null,
isEjectMod: null isEjectMod: null,
isFreezeHarmImmune: null
} }

View File

@@ -1286,7 +1286,7 @@ const mech = {
description: "<strong>blocking</strong> does not drain <strong class='color-f'>energy</strong><br><strong>blocking</strong> has no <strong>cool down</strong> and less <strong>recoil</strong><br><strong>attract</strong> power ups from <strong>far away</strong>", description: "<strong>blocking</strong> does not drain <strong class='color-f'>energy</strong><br><strong>blocking</strong> has no <strong>cool down</strong> and less <strong>recoil</strong><br><strong>attract</strong> power ups from <strong>far away</strong>",
effect: () => { effect: () => {
mech.fieldShieldingScale = 0; mech.fieldShieldingScale = 0;
mech.grabPowerUpRange2 = 4000000 mech.grabPowerUpRange2 = 10000000
// mech.holdingMassScale = 0.03; //can hold heavier blocks with lower cost to jumping // mech.holdingMassScale = 0.03; //can hold heavier blocks with lower cost to jumping
// mech.fieldMeterColor = "#0af" // mech.fieldMeterColor = "#0af"
// mech.fieldArc = 0.3; //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob) // mech.fieldArc = 0.3; //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)

View File

@@ -180,7 +180,6 @@ const powerUps = {
// if (!game.lastLogTime) game.makeTextLog("<span style='font-size:115%;'><span class='color-f'>+energy</span></span>", 300); // if (!game.lastLogTime) game.makeTextLog("<span style='font-size:115%;'><span class='color-f'>+energy</span></span>", 300);
// } else { // } else {
// let ammo = Math.ceil((target.ammoPack * (0.8 + 0.25 * Math.random()))); // let ammo = Math.ceil((target.ammoPack * (0.8 + 0.25 * Math.random())));
// // if (level.isBuildRun) ammo = Math.floor(ammo * 1.1) //extra ammo on build run because no ammo from getting a new gun
// target.ammo += ammo; // target.ammo += ammo;
// game.updateGunHUD(); // game.updateGunHUD();
// game.makeTextLog("<div class='circle gun'></div> &nbsp; <span style='font-size:110%;'>+" + ammo + " ammo for " + target.name + "</span>", 300); // game.makeTextLog("<div class='circle gun'></div> &nbsp; <span style='font-size:110%;'>+" + ammo + " ammo for " + target.name + "</span>", 300);

View File

@@ -81,9 +81,9 @@ const spawn = {
} }
} }
}, },
//"shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss",
randomLevelBoss(x, y, options = ["shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss"]) { randomLevelBoss(x, y, options = ["snakeBoss"]) {
// other bosses: suckerBoss, laserBoss, tetherBoss, snakeBoss //all need a particular level to work so they are not included // other bosses: suckerBoss, laserBoss, tetherBoss, //all need a particular level to work so they are not included
spawn[options[Math.floor(Math.random() * options.length)]](x, y) spawn[options[Math.floor(Math.random() * options.length)]](x, y)
}, },
//mob templates ********************************************************************************************* //mob templates *********************************************************************************************
@@ -955,21 +955,21 @@ const spawn = {
me.isBoss = true; me.isBoss = true;
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front 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); Matter.Body.rotate(me, Math.random() * Math.PI * 2);
me.accelMag = 0.00065 * game.accelScale; me.accelMag = 0.0002 * Math.sqrt(game.accelScale);
me.seePlayerFreq = Math.floor(25 * game.lookFreqScale); me.seePlayerFreq = Math.floor(30 * game.lookFreqScale);
me.memory = 420; me.memory = 420;
me.restitution = 1; me.restitution = 1;
me.frictionAir = 0.035; me.frictionAir = 0.01;
me.frictionStatic = 0; me.frictionStatic = 0;
me.friction = 0; me.friction = 0;
me.lookTorque = 0.000005 * (Math.random() > 0.5 ? -1 : 1); me.lookTorque = 0.000001 * (Math.random() > 0.5 ? -1 : 1);
me.fireDir = { me.fireDir = {
x: 0, x: 0,
y: 0 y: 0
} }
Matter.Body.setDensity(me, 0.025); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.023); //extra dense //normal is 0.001 //makes effective life much larger
spawn.shield(me, x, y, 1); spawn.shield(me, x, y, 1);
me.onHit = function () { me.onHit = function () {
//run this function on hitting player //run this function on hitting player
@@ -994,7 +994,7 @@ const spawn = {
//rotate towards fireAngle //rotate towards fireAngle
const angle = this.angle + Math.PI / 2; const angle = this.angle + Math.PI / 2;
c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y; c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y;
const threshold = 0.04; const threshold = 0.4;
if (c > threshold) { if (c > threshold) {
this.torque += 0.000004 * this.inertia; this.torque += 0.000004 * this.inertia;
} else if (c < -threshold) { } else if (c < -threshold) {
@@ -1087,7 +1087,6 @@ const spawn = {
ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]); ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
ctx.stroke(); ctx.stroke();
ctx.setLineDash([0, 0]); ctx.setLineDash([0, 0]);
} }
}; };
}, },
@@ -1515,7 +1514,7 @@ const spawn = {
// } // }
// }; // };
// }, // },
bomberBoss(x, y, radius = 80 + Math.floor(Math.random() * 15)) { bomberBoss(x, y, radius = 88) {
//boss that drops bombs from above and holds a set distance from player //boss that drops bombs from above and holds a set distance from player
mobs.spawn(x, y, 3, radius, "transparent"); mobs.spawn(x, y, 3, radius, "transparent");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
@@ -1524,7 +1523,7 @@ const spawn = {
me.stroke = "rgba(255,0,200)"; //used for drawGhost me.stroke = "rgba(255,0,200)"; //used for drawGhost
me.seeAtDistance2 = 1500000; me.seeAtDistance2 = 1500000;
me.fireFreq = Math.ceil(60 + 3000 / radius); me.fireFreq = Math.floor(120 * game.CDScale);
me.searchTarget = map[Math.floor(Math.random() * (map.length - 1))].position; //required for search me.searchTarget = map[Math.floor(Math.random() * (map.length - 1))].position; //required for search
me.hoverElevation = 460 + (Math.random() - 0.5) * 200; //squared me.hoverElevation = 460 + (Math.random() - 0.5) * 200; //squared
me.hoverXOff = (Math.random() - 0.5) * 100; me.hoverXOff = (Math.random() - 0.5) * 100;
@@ -1581,7 +1580,7 @@ const spawn = {
this.fire(); this.fire();
}; };
}, },
shooterBoss(x, y, radius = 130) { shooterBoss(x, y, radius = 110) {
mobs.spawn(x, y, 3, radius, "rgb(255,70,180)"); mobs.spawn(x, y, 3, radius, "rgb(255,70,180)");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
@@ -1592,7 +1591,7 @@ const spawn = {
x: x, x: x,
y: y y: y
}; };
me.fireFreq = 0.02; me.fireFreq = 0.025;
me.noseLength = 0; me.noseLength = 0;
me.fireAngle = 0; me.fireAngle = 0;
me.accelMag = 0.005 * game.accelScale; me.accelMag = 0.005 * game.accelScale;
@@ -1602,7 +1601,7 @@ const spawn = {
x: 0, x: 0,
y: 0 y: 0
}; };
Matter.Body.setDensity(me, 0.02 + 0.0008 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.03 + 0.0008 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.onDeath = function () { me.onDeath = function () {
powerUps.spawnBossPowerUp(this.position.x, this.position.y) 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 // this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //helps collisions functions work better after vertex have been changed
@@ -1649,7 +1648,7 @@ const spawn = {
this.explode(this.mass * 10); this.explode(this.mass * 10);
}; };
me.onDeath = function () { me.onDeath = function () {
if (game.difficulty > 10) { if (game.difficulty > 7) {
spawn.bullet(this.position.x, this.position.y, this.radius / 3, 5); spawn.bullet(this.position.x, this.position.y, this.radius / 3, 5);
spawn.bullet(this.position.x, this.position.y, this.radius / 3, 5); spawn.bullet(this.position.x, this.position.y, this.radius / 3, 5);
spawn.bullet(this.position.x, this.position.y, this.radius / 3, 5); spawn.bullet(this.position.x, this.position.y, this.radius / 3, 5);
@@ -1679,7 +1678,7 @@ const spawn = {
} }
} }
Matter.Body.setDensity(me, 0.0001); //normal is 0.001 Matter.Body.setDensity(me, 0.0001); //normal is 0.001
me.timeLeft = 95 + Math.floor(Math.random() * 15); me.timeLeft = 140 + Math.floor(Math.random() * 30);
me.g = 0.001; //required if using 'gravity' me.g = 0.001; //required if using 'gravity'
me.frictionAir = 0; me.frictionAir = 0;
me.restitution = 1; me.restitution = 1;
@@ -1693,7 +1692,6 @@ const spawn = {
this.timeLimit(); this.timeLimit();
}; };
}, },
sniper(x, y, radius = 35 + Math.ceil(Math.random() * 30)) { sniper(x, y, radius = 35 + Math.ceil(Math.random() * 30)) {
mobs.spawn(x, y, 3, radius, "transparent"); //"rgb(25,0,50)") mobs.spawn(x, y, 3, radius, "transparent"); //"rgb(25,0,50)")
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
@@ -1761,8 +1759,6 @@ const spawn = {
// recoil // recoil
this.force.x -= 0.005 * this.fireDir.x * this.mass; this.force.x -= 0.005 * this.fireDir.x * this.mass;
this.force.y -= 0.005 * this.fireDir.y * this.mass; this.force.y -= 0.005 * this.fireDir.y * this.mass;
} else {
this.torque += 0.000001 * this.inertia; //
} }
if (this.noseLength < 1.5) this.noseLength += this.fireFreq; if (this.noseLength < 1.5) this.noseLength += this.fireFreq;
setNoseShape(); setNoseShape();
@@ -1804,12 +1800,11 @@ const spawn = {
this.canTouchPlayer = false; this.canTouchPlayer = false;
this.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player this.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
} }
}; };
}, },
sniperBullet(x, y, radius = 6, sides = 4) { sniperBullet(x, y, radius = 6, sides = 4) {
//bullets //bullets
mobs.spawn(x, y, sides, radius, "rgb(190,0,255)"); mobs.spawn(x, y, sides, radius, "rgb(255,0,155)");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.stroke = "transparent"; me.stroke = "transparent";
me.onHit = function () { me.onHit = function () {
@@ -1826,9 +1821,7 @@ const spawn = {
me.collisionFilter.category = cat.mobBullet; me.collisionFilter.category = cat.mobBullet;
me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet; me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet;
me.do = function () { me.do = function () {
// this.gravity();
this.timeLimit(); this.timeLimit();
if (Matter.Query.collides(this, map).length > 0 || Matter.Query.collides(this, body).length > 0 && this.speed < 3) { if (Matter.Query.collides(this, map).length > 0 || Matter.Query.collides(this, body).length > 0 && this.speed < 3) {
this.dropPowerUp = false; this.dropPowerUp = false;
this.death(); //death with no power up this.death(); //death with no power up
@@ -1864,12 +1857,12 @@ const spawn = {
} }
}; };
}, },
launcherBoss(x, y, radius = 90) { launcherBoss(x, y, radius = 85) {
mobs.spawn(x, y, 6, radius, "rgb(150,150,255)"); mobs.spawn(x, y, 6, radius, "rgb(150,150,255)");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
me.accelMag = 0.00008 * game.accelScale; me.accelMag = 0.00008 * game.accelScale;
me.fireFreq = Math.floor(330 * game.CDScale) me.fireFreq = Math.floor(360 * game.CDScale)
me.frictionStatic = 0; me.frictionStatic = 0;
me.friction = 0; me.friction = 0;
me.frictionAir = 0.02; me.frictionAir = 0.02;

View File

@@ -1,19 +1,37 @@
field: perfect diamagnetism is a bit larger after you die, you can find the build you used in the custom menu
can now grab power ups from far away
mod: exciton-lattice - reduce harm by 80%, but after taking collision damage eject a random mod shooterBoss - smaller, but more massive,
eject extra mods if you have recursive stacks aims better at short range, and fires faster
bomberBoss fires faster, bombs are more likely to split
power ups have a bit more air friction mod: osmoprotectant - stunned or frozen mobs cause no harm
power ups must be in line of sight to be pulled by the player
why mode now gets 100% chance for a second boss power up (up from 50%)
this should let why mode reach more interesting build depth
laser and pulse got a damage and energy use buff
immune to harm for a second after exiting the power up selection menu
************** TODO - n-gon ************** ************** TODO - n-gon **************
new gun fire 3+ balls in arc after you die custom should be populated with your last build
also you should be able to share while paused
standing wave harmonics mod - push things away
push scales with mass up to about 4
has a 25% effect on shielded mobs?
push when using field key
or push away at the peak of an oscillation
or always push
give drones bremstranlung radiation?
name: micro-harmonics?
reduce drone life span by 50%
drone drain energy on hits?
add tailed level boss to random pool?
hit scan bullets -> nails
mod: frozen mobs can't do collision damage
also stunned mobs can't do collision damage
or they do reduced damage
new gun or field - fire 3+ balls in arc
name: something about energy name: something about energy
does damage in area, like neutron bomb does damage in area, like neutron bomb
ends on contact with wall, doesn't stick or bounce ends on contact with wall, doesn't stick or bounce
@@ -23,8 +41,6 @@ new gun fire 3+ balls in arc
fix: even with a scroll bar the top of the selection window is off screen for very short windows fix: even with a scroll bar the top of the selection window is off screen for very short windows
rework perfect diamagnetism rework perfect diamagnetism
keep the zero energy cost
add a very short blocking CD
let the shield also do bremsstrahlung radiation let the shield also do bremsstrahlung radiation
mod: grab and launch mobs? mod: grab and launch mobs?
@@ -45,9 +61,6 @@ fix door.isOpen actually meaning isClosed
mod - laser fires 3 beams mod - laser fires 3 beams
after you die custom should be populated with your last build
also you should be able to share while paused
give missiles a suck and delay explosion, like vacuum bomb give missiles a suck and delay explosion, like vacuum bomb
bot that does AOE damage while it rotates around player bot that does AOE damage while it rotates around player