diff --git a/.DS_Store b/.DS_Store
index c8937b9..3ea3311 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/js/bullet.js b/js/bullet.js
index 094e361..c068892 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -5391,49 +5391,6 @@ const b = {
angle += SPREAD
}
},
- }, {
- name: "mine",
- description: "toss a proximity mine that sticks to walls
refund undetonated mines on exiting a level", //fires nails at mobs within range
- ammo: 0,
- ammoPack: 1.25,
- have: false,
- do() {
- if (!input.field && input.down && !tech.isLaserMine) {
- const cycles = 60 //30
- const speed = 40
- const v = { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) } //m.Vy / 2 + removed to make the path less jerky
- ctx.strokeStyle = "rgba(68, 68, 68, 0.2)" //color.map
- ctx.lineWidth = 2
- ctx.beginPath()
- for (let i = 1.5, len = 19; i < len + 1; i++) {
- const time = cycles * i / len
- ctx.lineTo(m.pos.x + time * v.x, m.pos.y + time * v.y + 0.34 * time * time)
- }
- ctx.stroke()
- }
- },
- fire() {
- if (input.down) {
- if (tech.isLaserMine) {
- const speed = 30
- const velocity = { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }
- b.laserMine(m.pos, velocity)
- m.fireCDcycle = m.cycle + Math.floor(65 * b.fireCDscale); // cool down
- } else {
- const pos = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
- let speed = 36
- if (Matter.Query.point(map, pos).length > 0) speed = -2 //don't launch if mine will spawn inside map
- b.mine(pos, { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }, 0)
- m.fireCDcycle = m.cycle + Math.floor(55 * b.fireCDscale); // cool down
- }
- } else {
- const pos = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
- let speed = 23
- if (Matter.Query.point(map, pos).length > 0) speed = -2 //don't launch if mine will spawn inside map
- b.mine(pos, { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }, 0)
- m.fireCDcycle = m.cycle + Math.floor(35 * b.fireCDscale); // cool down
- }
- }
}, {
name: "spores",
description: "fire a sporangium that discharges spores
spores seek out nearby mobs",
@@ -5981,6 +5938,49 @@ const b = {
player.force.y -= recoil.y
tech.harpoonDensity = 0.008
}
+ }, {
+ name: "mine",
+ description: "toss a proximity mine that sticks to walls
refund undetonated mines on exiting a level", //fires nails at mobs within range
+ ammo: 0,
+ ammoPack: 1.25,
+ have: false,
+ do() {
+ if (!input.field && input.down && !tech.isLaserMine) {
+ const cycles = 60 //30
+ const speed = 40
+ const v = { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) } //m.Vy / 2 + removed to make the path less jerky
+ ctx.strokeStyle = "rgba(68, 68, 68, 0.2)" //color.map
+ ctx.lineWidth = 2
+ ctx.beginPath()
+ for (let i = 1.5, len = 19; i < len + 1; i++) {
+ const time = cycles * i / len
+ ctx.lineTo(m.pos.x + time * v.x, m.pos.y + time * v.y + 0.34 * time * time)
+ }
+ ctx.stroke()
+ }
+ },
+ fire() {
+ if (input.down) {
+ if (tech.isLaserMine) {
+ const speed = 30
+ const velocity = { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }
+ b.laserMine(m.pos, velocity)
+ m.fireCDcycle = m.cycle + Math.floor(65 * b.fireCDscale); // cool down
+ } else {
+ const pos = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
+ let speed = 36
+ if (Matter.Query.point(map, pos).length > 0) speed = -2 //don't launch if mine will spawn inside map
+ b.mine(pos, { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }, 0)
+ m.fireCDcycle = m.cycle + Math.floor(55 * b.fireCDscale); // cool down
+ }
+ } else {
+ const pos = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
+ let speed = 23
+ if (Matter.Query.point(map, pos).length > 0) speed = -2 //don't launch if mine will spawn inside map
+ b.mine(pos, { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }, 0)
+ m.fireCDcycle = m.cycle + Math.floor(35 * b.fireCDscale); // cool down
+ }
+ }
},
// {
// name: "railgun",
diff --git a/js/level.js b/js/level.js
index 5725304..1a68dbd 100644
--- a/js/level.js
+++ b/js/level.js
@@ -7,8 +7,9 @@ const level = {
defaultZoom: 1400,
onLevel: -1,
levelsCleared: 0,
- playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber"],
- trainingLevels: ["trainingWalk", "trainingCrouch", "trainingJump", "trainingHold", "trainingThrow", "trainingHit", "trainingHeal", "trainingFire", "trainingDeflect"],
+ playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber"], //intro, gauntlet, final are added in at the start and end of level order
+ trainingLevels: ["trainingWalk", "trainingCrouch", "trainingJump", "trainingHold", "trainingThrow", "trainingThrowAt", "trainingDeflect", "trainingHeal", "trainingFire", "trainingNailGun", "trainingShotGun", "trainingSuperBall", "trainingMatterWave", "trainingMissile"],
+ communityLevels: ["stronghold", "basement", "crossfire", "vats", "run", "n-gon", "house", "perplex", "coliseum", "tunnel"],
levels: [],
start() {
if (level.levelsCleared === 0) { //this code only runs on the first level
@@ -27,12 +28,9 @@ const level = {
// for (let i = 0; i < 1; i++) tech.giveTech("reticulum")
// for (let i = 0; i < 2; i++) tech.giveTech("laser-bot")
// tech.tech[297].frequency = 100
- // level.trainingDeflect();
- if (simulation.isTraining) {
- level.trainingWalk();
- } else {
- level.intro(); //starting level
- }
+ // level.run();
+
+ if (simulation.isTraining) { level.trainingWalk(); } else { level.intro(); }
// level.testing(); //not in rotation, used for testing
// level.template(); //not in rotation, blank start new map development
// level.final() //final boss level
@@ -192,10 +190,6 @@ const level = {
},
trainingCrouch() { //learn to crouch
m.addHealth(Infinity)
- //hide your health bar
- document.getElementById("health").style.display = "none"
- document.getElementById("health-bg").style.display = "none"
-
level.setPosToSpawn(60, -50); //normal spawn
spawn.mapRect(10, -10, 100, 20); //small platform for player
level.exit.x = 1775;
@@ -251,9 +245,6 @@ const level = {
},
trainingJump() { //learn to jump
m.addHealth(Infinity)
- document.getElementById("health").style.display = "none" //hide your health bar
- document.getElementById("health-bg").style.display = "none"
-
level.setPosToSpawn(60, -50); //normal spawn
spawn.mapRect(10, -10, 100, 20); //small platform for player
level.exit.x = 1775;
@@ -282,9 +273,8 @@ const level = {
};
level.customTopLayer = () => {
//dark
- ctx.fillStyle = "rgba(0,0,0,0.05)"
+ ctx.fillStyle = "rgba(0,0,0,0.2)"
ctx.fillRect(1000, 0, 450, 1800)
- ctx.fillRect(1000, -2800, 450, 2200)
//exit room glow
ctx.fillStyle = "rgba(0,255,255,0.05)"
ctx.fillRect(1600, -400, 400, 400)
@@ -301,13 +291,25 @@ const level = {
spawn.mapRect(1600, -1200, 500, 850); //exit roof
spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
+
+ //roof steps
+ spawn.mapRect(1000, -650, 25, 25);
+ spawn.mapRect(1000, -675, 50, 25);
+ spawn.mapRect(1000, -700, 75, 25);
+ spawn.mapRect(1000, -725, 100, 25);
+ spawn.mapRect(1425, -650, 25, 25);
+ spawn.mapRect(1400, -675, 50, 25);
+ spawn.mapRect(1375, -700, 75, 25);
+ spawn.mapRect(1350, -725, 100, 25);
+ spawn.mapRect(1325, -750, 150, 25);
+ spawn.mapRect(1300, -775, 150, 25);
+ spawn.mapRect(1000, -750, 125, 25);
+ spawn.mapRect(1275, -2800, 200, 2025);
+ spawn.mapRect(975, -2800, 200, 2025);
+ spawn.mapRect(1000, -775, 150, 25);
},
trainingHold() { //put block on button to open door
m.addHealth(Infinity)
- //hide your health bar
- document.getElementById("health").style.display = "none"
- document.getElementById("health-bg").style.display = "none"
-
level.setPosToSpawn(60, -50); //normal spawn
spawn.mapRect(10, -10, 100, 20); //small platform for player
level.exit.x = 1775;
@@ -376,10 +378,6 @@ const level = {
},
trainingThrow() { //throw a block on button to open door
m.addHealth(Infinity)
- //hide your health bar
- document.getElementById("health").style.display = "none"
- document.getElementById("health-bg").style.display = "none"
-
level.setPosToSpawn(60, -50); //normal spawn
spawn.mapRect(10, -10, 100, 20); //small platform for player
level.exit.x = 1775;
@@ -455,12 +453,8 @@ const level = {
spawn.mapRect(1625, -400, 400, 50);
spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
},
- trainingHit() { //throw a block at mob to open door
+ trainingThrowAt() { //throw a block at mob to open door
m.addHealth(Infinity)
- //hide your health bar
- document.getElementById("health").style.display = "none"
- document.getElementById("health-bg").style.display = "none"
-
level.setPosToSpawn(60, -50); //normal spawn
spawn.mapRect(10, -10, 100, 20); //small platform for player
level.exit.x = 1775;
@@ -524,6 +518,165 @@ const level = {
spawn.starter(425, -350, 35)
spawn.starter(800, -350, 44)
},
+ trainingFire() { //throw a block at mob to open door
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = 15;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+
+ const door = level.door(1612.5, -125, 25, 190, 185, 3)
+ const buttonDoor = level.button(400, 0)
+
+ let instruction = 0
+ level.trainingText(`use your field to pick up the gun power up`)
+
+ level.custom = () => {
+ if (instruction === 0 && simulation.isChoosing) {
+ instruction++
+ level.trainingText(`use your field to pick up the gun power up
+
choose a gun`)
+ } else if (instruction === 1 && !simulation.isChoosing) {
+ instruction++
+ level.trainingText(`use your field to pick up the gun power up
+
choose a gun
+
use the left mouse button to shoot the mobs`)
+ } else if (instruction === 2 && mob.length === 0) {
+ instruction++
+ level.trainingText(`use your field to pick up the gun power up
+
choose a gun
+
use the left mouse button to shoot the mobs
+
drop a block on the red button to open the door`)
+ } else if (instruction === 3 && !door.isClosing) {
+ instruction++
+ level.trainingText(`use your field to pick up the gun power up
+
choose a gun
+
use the left mouse button to shoot the mobs
+
put a block on the red button to open the door`)
+ }
+ //spawn ammo if you run out
+ if (!powerUp.length && b.inventory.length && b.guns[b.activeGun].ammo === 0) powerUps.directSpawn(1300, -2000, "ammo", false);
+
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -350, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ buttonDoor.query();
+ buttonDoor.draw();
+ if (buttonDoor.isUp) {
+ door.isClosing = true
+ } else {
+ door.isClosing = false
+ }
+ door.openClose();
+ door.draw();
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -350, 400, 400)
+ //ammo tunnel shadow
+ ctx.fillStyle = "rgba(0,0,0,0.4)"
+ ctx.fillRect(1250, -2800, 100, 2200)
+ };
+
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(-250, 50, 3500, 1750); //floor
+ spawn.mapRect(-200, 0, 950, 100);
+ spawn.mapRect(-150, -2800, 1400, 2200); //roof with tunnel for ammo
+ spawn.mapRect(1350, -2800, 675, 2200);
+
+ //ceiling steps
+ spawn.mapRect(725, -588, 50, 25);
+ spawn.mapRect(725, -600, 75, 25);
+ spawn.mapRect(750, -612, 75, 25);
+ spawn.mapRect(-275, -650, 1025, 87);
+
+ spawn.mapRect(725, 12, 50, 25);
+ spawn.mapRect(725, 25, 75, 25);
+ spawn.mapRect(750, 38, 75, 25);
+
+ spawn.mapRect(1600, -600, 425, 300);
+ spawn.mapRect(1600, -400, 50, 275);
+
+ powerUps.directSpawn(1300, -1500, "gun", false);
+ spawn.starter(900, -300, 35)
+ spawn.starter(1400, -400, 44)
+ },
+ trainingDeflect() { //learn to jump
+ m.addHealth(Infinity)
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = -35;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+
+ let instruction = 0
+ // activate your field with ${input.key.field.replace('Key', '').replace('Digit', '')} or right mouse
+ level.trainingText(`use your field to deflect the mobs`)
+
+ level.custom = () => {
+ if (instruction === 0 && m.pos.x > 1350) {
+ instruction++
+ level.trainingText(`use your field to deflect the mobs`)
+ }
+ //teleport to start if hit
+ if (m.immuneCycle > m.cycle) {
+ m.energy = m.maxEnergy
+ Matter.Body.setPosition(player, { x: 60, y: -50 })
+ }
+ //spawn bullets
+ if (!(simulation.cycle % 5)) {
+ spawn.sniperBullet(660 + 580 * Math.random(), -2000, 10, 4);
+ const who = mob[mob.length - 1]
+ Matter.Body.setVelocity(who, { x: 0, y: 8 });
+ who.timeLeft = 300
+ }
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -400, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ //dark
+ ctx.fillStyle = "rgba(0,0,0,0.05)"
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -400, 400, 400)
+ };
+
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+
+ spawn.mapRect(-250, 0, 3000, 1800); //floor
+ spawn.mapRect(-250, -2800, 900, 2200); //roof
+ spawn.mapRect(1250, -2800, 1275, 2200); //roof
+ spawn.mapVertex(950, 0, "400 0 -400 0 -300 -50 300 -50"); //base
+
+ spawn.mapRect(1600, -1200, 500, 850); //exit roof
+ spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
+
+ //spawn bullets on load to avoid rush
+ for (let i = 0; i < 32; i++) {
+ spawn.sniperBullet(660 + 580 * Math.random(), -2000 + 40 * i, 10, 4);
+ const who = mob[mob.length - 1]
+ Matter.Body.setVelocity(who, { x: 0, y: 8 });
+ who.timeLeft = 300
+ }
+ },
trainingHeal() { //learn to heal
m.addHealth(Infinity)
m.health = 0;
@@ -541,15 +694,14 @@ const level = {
simulation.zoomTransition(level.defaultZoom, 1)
document.body.style.backgroundColor = level.trainingBackgroundColor
-
let instruction = 0
level.trainingText(`your health is displayed in the top left corner
-
use your field to pick up ${powerUps.orb.heal(3)} until your health is full`)
+
use your field to pick up
until your health is full`)
level.custom = () => {
if (instruction === 0 && m.health === 1) {
instruction++
- level.trainingText(`use your field to pick up ${powerUps.orb.heal(3)} until your health is full`)
+ level.trainingText(`use your field to pick up until your health is full`)
}
//exit room
ctx.fillStyle = "#f2f2f2"
@@ -583,63 +735,397 @@ const level = {
spawn.mapRect(1375, -16, 50, 50);
spawn.mapRect(1400, -8, 50, 25);
spawn.mapRect(750, -24, 650, 100);
- powerUps.directSpawn(875, -500, "heal", false, null, 15);
- powerUps.directSpawn(1075, -500, "heal", false, null, 25);
- powerUps.directSpawn(1275, -500, "heal", false, null, 35);
+ powerUps.directSpawn(875, -40, "heal", false, null, 15);
+ powerUps.directSpawn(1075, -50, "heal", false, null, 25);
+ powerUps.directSpawn(1275, -65, "heal", false, null, 35);
const door = level.door(1612.5, -175, 25, 190, 185, 3)
-
spawn.mapRect(1600, -1200, 500, 850); //exit roof
spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
},
- trainingFire() { //throw a block at mob to open door
+ trainingNailGun() { //throw a block on button to open door
+ level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
level.setPosToSpawn(60, -50); //normal spawn
spawn.mapRect(10, -10, 100, 20); //small platform for player
level.exit.x = 1775;
- level.exit.y = 15;
+ level.exit.y = -35;
spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
simulation.zoomScale = 1400 //1400 is normal
level.defaultZoom = 1400
simulation.zoomTransition(level.defaultZoom, 1)
document.body.style.backgroundColor = level.trainingBackgroundColor
+ b.removeAllGuns();
+ b.giveGuns("nail gun")
+ b.guns[b.activeGun].ammo = 0
+ simulation.updateGunHUD();
- const door = level.door(1612.5, -125, 25, 190, 185, 3)
- const buttonDoor = level.button(400, 0)
-
-
+ const door = level.door(1612.5, -175, 25, 190, 185, 3)
let instruction = 0
- level.trainingText(`use your field to pick up the gun power up`)
+ level.trainingText(`use your field to pick up for your nail gun`)
level.custom = () => {
- if (instruction === 0 && simulation.isChoosing) {
+ if (instruction === 0 && b.inventory.length && b.guns[b.activeGun].ammo > 0) {
instruction++
- level.trainingText(`use your field to pick up the gun power up
-
choose a gun`)
- } else if (instruction === 1 && !simulation.isChoosing) {
- instruction++
- level.trainingText(`use your field to pick up the gun power up
-
choose a gun
+ level.trainingText(`use your field to pick up for your nail gun
use the left mouse button to shoot the mobs`)
- } else if (instruction === 2 && mob.length === 0) {
+ } else if (instruction === 1 && mob.length === 0) {
instruction++
- level.trainingText(`use your field to pick up the gun power up
-
choose a gun
-
use the left mouse button to shoot the mobs
-
drop a block on the red button to open the door`)
- } else if (instruction === 3 && !door.isClosing) {
- instruction++
- level.trainingText(`use your field to pick up the gun power up
-
choose a gun
-
use the left mouse button to shoot the mobs
-
put a block on the red button to open the door`)
+ level.trainingText(`use your field to pick up for your nail gun
+
use the left mouse button to shoot the mobs`)
}
//spawn ammo if you run out
- if (!powerUp.length && b.activeGun && b.guns[b.activeGun].ammo === 0 && door.isClosing) {
- powerUps.directSpawn(1275, -500, "ammo");
+ let isAmmo = false
+ for (let i = 0; i < powerUp.length; i++) {
+ if (powerUp[i].name === 'ammo') isAmmo = true
}
+ if (!isAmmo && b.inventory.length && b.guns[b.activeGun].ammo === 0) {
+ powerUps.directSpawn(1300, -2000, "ammo", false);
+ powerUps.directSpawn(1301, -2200, "ammo", false);
+ }
+
//exit room
ctx.fillStyle = "#f2f2f2"
- ctx.fillRect(1600, -350, 400, 400)
+ ctx.fillRect(1600, -400, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ if (mob.length > 0) {
+ door.isClosing = true
+ } else {
+ door.isClosing = false
+ }
+ door.openClose();
+ door.draw();
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -400, 400, 400)
+ //ammo tunnel shadow
+ ctx.fillStyle = "rgba(0,0,0,0.4)"
+ ctx.fillRect(1250, -2800, 100, 2200)
+ };
+
+ if (m.health < 1) {
+ powerUps.directSpawn(1298, -3500, "heal", false, 23);
+ powerUps.directSpawn(1305, -3000, "heal", false, 35);
+ }
+ for (let i = 0; i < 2; i++) {
+ spawn.spinner(1300 + i, -3000 - 200 * i, 25 + 5 * i)
+ Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 62 });
+ }
+
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(-250, 50, 3500, 1750); //floor
+ spawn.mapRect(-200, 0, 950, 100);
+ spawn.mapRect(1575, 0, 500, 100);
+ spawn.mapRect(-150, -2800, 1400, 2200); //roof with tunnel for ammo
+ spawn.mapRect(1350, -2800, 675, 2200);
+
+ spawn.mapRect(725, 12, 50, 25);
+ spawn.mapRect(725, 25, 75, 25);
+ spawn.mapRect(750, 38, 75, 25);
+ spawn.mapRect(1525, 25, 75, 50);
+ spawn.mapRect(1500, 38, 50, 25);
+ spawn.mapRect(1550, 12, 50, 25);
+ // spawn.mapRect(1600, -1200, 500, 850); //exit roof
+ // spawn.mapRect(1790, -600, 250, 225); //button left wall
+ // spawn.mapRect(1625, -400, 400, 50);
+ spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
+ spawn.mapRect(1600, -600, 425, 250);
+ },
+ trainingShotGun() { //throw a block on button to open door
+ level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = -35;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+ b.removeAllGuns();
+ b.giveGuns("shotgun")
+ // b.guns[b.activeGun].ammo = 0
+ // simulation.updateGunHUD();
+ const door = level.door(1612.5, -175, 25, 190, 185, 3)
+ let instruction = 0
+ level.trainingText(`use your shotgun to clear the room of mobs`)
+
+ level.custom = () => {
+ if (instruction === 0 && mob.length === 0) {
+ instruction++
+ level.trainingText(`use your shotgun to clear the room of mobs`)
+ }
+ //spawn ammo if you run out
+ let isAmmo = false
+ for (let i = 0; i < powerUp.length; i++) {
+ if (powerUp[i].name === 'ammo') isAmmo = true
+ }
+ if (!isAmmo && b.inventory.length && b.guns[b.activeGun].ammo === 0) {
+ powerUps.directSpawn(1300, -2000, "ammo", false);
+ powerUps.directSpawn(1301, -2200, "ammo", false);
+ }
+
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -400, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ if (mob.length > 0) {
+ door.isClosing = true
+ } else {
+ door.isClosing = false
+ }
+ door.openClose();
+ door.draw();
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -400, 400, 400)
+ //ammo tunnel shadow
+ ctx.fillStyle = "rgba(0,0,0,0.4)"
+ ctx.fillRect(1250, -2800, 100, 2200)
+ };
+
+ if (m.health < 1) {
+ powerUps.directSpawn(1298, -3500, "heal", false, 23);
+ powerUps.directSpawn(1305, -3000, "heal", false, 35);
+ }
+ for (let i = 0; i < 3; i++) {
+ spawn.hopper(1300 + i, -3000 - 2000 * i, 25 + 5 * i)
+ // Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 0 });
+ }
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(-250, 50, 3500, 1750); //floor
+ spawn.mapRect(-200, 0, 950, 100);
+ spawn.mapRect(1575, 0, 500, 100);
+ spawn.mapRect(-150, -2800, 1400, 2200); //roof with tunnel for ammo
+ spawn.mapRect(1350, -2800, 675, 2200);
+
+ spawn.mapRect(725, 12, 50, 25);
+ spawn.mapRect(725, 25, 75, 25);
+ spawn.mapRect(750, 38, 75, 25);
+ spawn.mapRect(1525, 25, 75, 50);
+ spawn.mapRect(1500, 38, 50, 25);
+ spawn.mapRect(1550, 12, 50, 25);
+ spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
+ spawn.mapRect(1600, -600, 425, 250);
+ },
+ trainingSuperBall() { //throw a block on button to open door
+ level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = -35;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+ b.removeAllGuns();
+ b.giveGuns("super balls")
+ // b.guns[b.activeGun].ammo = 0
+ // simulation.updateGunHUD();
+ const door = level.door(1612.5, -175, 25, 190, 185, 3)
+ let instruction = 0
+ level.trainingText(`use super balls to clear the room of mobs`)
+
+ level.custom = () => {
+ if (instruction === 0 && mob.length === 0) {
+ instruction++
+ level.trainingText(`use super balls to clear the room of mobs`)
+ }
+ //spawn ammo if you run out
+ let isAmmo = false
+ for (let i = 0; i < powerUp.length; i++) {
+ if (powerUp[i].name === 'ammo') isAmmo = true
+ }
+ if (!isAmmo && b.inventory.length && b.guns[b.activeGun].ammo === 0) {
+ powerUps.directSpawn(1300, -2000, "ammo", false);
+ powerUps.directSpawn(1301, -2200, "ammo", false);
+ }
+
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -400, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ if (mob.length > 0) {
+ door.isClosing = true
+ } else {
+ door.isClosing = false
+ }
+ door.openClose();
+ door.draw();
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -400, 400, 400)
+ //ammo tunnel shadow
+ ctx.fillStyle = "rgba(0,0,0,0.2)"
+ // ctx.fillRect(1225, -2800, 125, 2450)
+ ctx.fillRect(-150, -2800, 1500, 2450);
+ };
+
+ if (m.health < 1) {
+ powerUps.directSpawn(1298, -3500, "heal", false, 23);
+ powerUps.directSpawn(1305, -3000, "heal", false, 35);
+ }
+ for (let i = 0; i < 6; i++) {
+ spawn.spawner(i * 230, -800)
+ // Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 0 });
+ }
+ spawn.mapVertex(510, -430, "725 0 725 80 -650 80 -650 -80 650 -80"); //upper room with mobs
+ spawn.mapRect(-225, -2800, 1450, 2000);
+ spawn.mapRect(1350, -2800, 675, 2450);
+
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(-250, 50, 3500, 1750); //floor
+ spawn.mapRect(-200, 0, 950, 100);
+ spawn.mapRect(1575, 0, 500, 100);
+
+ spawn.mapRect(725, 12, 50, 25);
+ spawn.mapRect(725, 25, 75, 25);
+ spawn.mapRect(750, 38, 75, 25);
+ spawn.mapRect(1525, 25, 75, 50);
+ spawn.mapRect(1500, 38, 50, 25);
+ spawn.mapRect(1550, 12, 50, 25);
+ spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
+ },
+ trainingMatterWave() { //throw a block on button to open door
+ level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = -35;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+ b.removeAllGuns();
+ b.giveGuns("matter wave")
+ // b.guns[b.activeGun].ammo = 0
+ // simulation.updateGunHUD();
+ const door = level.door(1612.5, -175, 25, 190, 185, 3)
+ let instruction = 0
+ level.trainingText(`use matter wave to clear the room of mobs`)
+
+ level.custom = () => {
+ if (instruction === 0 && mob.length === 0) {
+ instruction++
+ level.trainingText(`use matter wave to clear the room of mobs`)
+ }
+ //spawn ammo if you run out
+ let isAmmo = false
+ for (let i = 0; i < powerUp.length; i++) {
+ if (powerUp[i].name === 'ammo') isAmmo = true
+ }
+ if (!isAmmo && b.inventory.length && b.guns[b.activeGun].ammo === 0) {
+ powerUps.directSpawn(1300, -2000, "ammo", false);
+ powerUps.directSpawn(1301, -2200, "ammo", false);
+ }
+
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -400, 400, 400)
+ level.exit.draw();
+ level.enter.draw();
+ level.playerExitCheck();
+ };
+ level.customTopLayer = () => {
+ if (mob.length > 0) {
+ door.isClosing = true
+ } else {
+ door.isClosing = false
+ }
+ door.openClose();
+ door.draw();
+ //exit room glow
+ ctx.fillStyle = "rgba(0,255,255,0.05)"
+ ctx.fillRect(1600, -400, 400, 400)
+ //ammo tunnel shadow
+ ctx.fillStyle = "rgba(0,0,0,0.2)"
+ // ctx.fillRect(1225, -2800, 125, 2450)
+ ctx.fillRect(-150, -2800, 1500, 2450);
+ };
+
+ if (m.health < 1) {
+ powerUps.directSpawn(1298, -3500, "heal", false, 23);
+ powerUps.directSpawn(1305, -3000, "heal", false, 35);
+ }
+ for (let i = 0; i < 6; i++) {
+ spawn.springer(i * 200, -800)
+ // Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 0 });
+ }
+ spawn.springer(1825, -330, 20);
+
+ spawn.mapRect(1125, -850, 100, 500); //upper room with mobs
+ spawn.mapRect(-225, -450, 1450, 100);
+ spawn.mapRect(-225, -2800, 1450, 2000);
+ spawn.mapRect(1350, -2800, 675, 2450);
+
+ spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
+ spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(-250, 50, 3500, 1750); //floor
+ spawn.mapRect(-200, 0, 950, 100);
+ spawn.mapRect(1575, 0, 500, 100);
+
+ spawn.mapRect(725, 12, 50, 25);
+ spawn.mapRect(725, 25, 75, 25);
+ spawn.mapRect(750, 38, 75, 25);
+ spawn.mapRect(1525, 25, 75, 50);
+ spawn.mapRect(1500, 38, 50, 25);
+ spawn.mapRect(1550, 12, 50, 25);
+ spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
+ },
+ trainingMissile() { //throw a block on button to open door
+ level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
+ level.setPosToSpawn(60, -50); //normal spawn
+ spawn.mapRect(10, -10, 100, 20); //small platform for player
+ level.exit.x = 1775;
+ level.exit.y = -35;
+ spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 30); //exit bump
+ simulation.zoomScale = 1400 //1400 is normal
+ level.defaultZoom = 1400
+ simulation.zoomTransition(level.defaultZoom, 1)
+ document.body.style.backgroundColor = level.trainingBackgroundColor
+ b.removeAllGuns();
+ b.giveGuns("missiles")
+ // b.guns[b.activeGun].ammo = 0
+ // simulation.updateGunHUD();
+ const buttonDoor = level.button(2500, 50)
+ const door = level.door(1612.5, -175, 25, 190, 185, 3)
+ let instruction = 0
+ level.trainingText(`use missiles to drop a block on the button`)
+
+ level.custom = () => {
+ if (instruction === 0 && mob.length === 0) {
+ instruction++
+ level.trainingText(`use missiles to drop a block on the button`)
+ }
+ //spawn ammo if you run out
+ let isAmmo = false
+ for (let i = 0; i < powerUp.length; i++) {
+ if (powerUp[i].name === 'ammo') isAmmo = true
+ }
+ if (!isAmmo && b.inventory.length && b.guns[b.activeGun].ammo === 0) {
+ powerUps.directSpawn(1300, -2000, "ammo", false);
+ powerUps.directSpawn(1301, -2200, "ammo", false);
+ }
+
+ //exit room
+ ctx.fillStyle = "#f2f2f2"
+ ctx.fillRect(1600, -400, 400, 400)
level.exit.draw();
level.enter.draw();
level.playerExitCheck();
@@ -654,109 +1140,43 @@ const level = {
}
door.openClose();
door.draw();
+
//exit room glow
ctx.fillStyle = "rgba(0,255,255,0.05)"
- ctx.fillRect(1600, -350, 400, 400)
+ ctx.fillRect(1600, -400, 400, 400)
+ //tunnel shadow
+ ctx.fillStyle = "rgba(0,0,0,0.4)"
+ ctx.fillRect(1250, -2800, 100, 2200)
+ ctx.fillRect(1550, 25, 475, 25);
};
+ if (m.health < 1) {
+ powerUps.directSpawn(1298, -3500, "heal", false, 23);
+ powerUps.directSpawn(1305, -3000, "heal", false, 35);
+ }
+ for (let i = 0; i < 10; i++) {
+ spawn.springer(2100 + i * 100, -250)
+ // Matter.Body.setVelocity(mob[mob.length - 1], { x: 0, y: 0 });
+ }
spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
- spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ // spawn.mapRect(2000, -2800, 2600, 4600); //right wall
+ spawn.mapRect(3050, -2800, 1550, 4600);
spawn.mapRect(-250, 50, 3500, 1750); //floor
spawn.mapRect(-200, 0, 950, 100);
- spawn.mapRect(-250, -2800, 3500, 2200); //roof
-
- //ceiling steps
- spawn.mapRect(725, -588, 50, 25);
- spawn.mapRect(725, -600, 75, 25);
- spawn.mapRect(750, -612, 75, 25);
- spawn.mapRect(-275, -650, 1025, 87);
+ spawn.mapRect(-150, -2800, 1400, 2200); //roof with tunnel for ammo
+ spawn.mapRect(1350, -2800, 675, 2200);
spawn.mapRect(725, 12, 50, 25);
spawn.mapRect(725, 25, 75, 25);
spawn.mapRect(750, 38, 75, 25);
-
- spawn.mapRect(1600, -600, 425, 300);
- spawn.mapRect(1600, -400, 50, 275);
-
- powerUps.directSpawn(1275, -500, "gun", false);
- spawn.starter(900, -300, 35)
- spawn.starter(1400, -400, 44)
- },
- trainingDeflect() { //learn to jump
- m.addHealth(Infinity)
- m.health = 1;
- document.getElementById("health").style.display = "inline" //show your health bar
- document.getElementById("health-bg").style.display = "inline"
-
- level.setPosToSpawn(60, -50); //normal spawn
- spawn.mapRect(10, -10, 100, 20); //small platform for player
- level.exit.x = 1775;
- level.exit.y = -35;
- spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
- simulation.zoomScale = 1400 //1400 is normal
- level.defaultZoom = 1400
- simulation.zoomTransition(level.defaultZoom, 1)
- document.body.style.backgroundColor = level.trainingBackgroundColor
-
-
- let instruction = 0
- // activate your field with ${input.key.field.replace('Key', '').replace('Digit', '')} or right mouse
- level.trainingText(`use your field to deflect the mobs`)
-
- level.custom = () => {
- if (instruction === 0 && m.pos.x > 1350) {
- instruction++
- level.trainingText(`use your field to deflect the mobs`)
- }
- //teleport to start if hit
- if (m.immuneCycle > m.cycle) {
- m.energy = m.maxEnergy
- Matter.Body.setPosition(player, { x: 60, y: -50 })
- }
- //spawn bullets
- if (!(simulation.cycle % 5)) {
- spawn.sniperBullet(660 + 580 * Math.random(), -2000, 10, 4);
- const who = mob[mob.length - 1]
- Matter.Body.setVelocity(who, { x: 0, y: 8 });
- who.timeLeft = 300
- }
-
-
- //exit room
- ctx.fillStyle = "#f2f2f2"
- ctx.fillRect(1600, -400, 400, 400)
- level.exit.draw();
- level.enter.draw();
- level.playerExitCheck();
- };
- level.customTopLayer = () => {
- //dark
- ctx.fillStyle = "rgba(0,0,0,0.05)"
- // ctx.fillRect(450, -2800, 1025, 2200)
- //exit room glow
- ctx.fillStyle = "rgba(0,255,255,0.05)"
- ctx.fillRect(1600, -400, 400, 400)
- };
-
- spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
- spawn.mapRect(2000, -2800, 2600, 4600); //right wall
-
- spawn.mapRect(-250, 0, 3000, 1800); //floor
- spawn.mapRect(-250, -2800, 900, 2200); //roof
- spawn.mapRect(1250, -2800, 1275, 2200); //roof
- spawn.mapVertex(950, 0, "400 0 -400 0 -300 -50 300 -50"); //base
-
- spawn.mapRect(1600, -1200, 500, 850); //exit roof
+ // spawn.mapRect(1350, 0, 675, 30);
+ spawn.mapRect(1550, 0, 475, 35);
spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
+ spawn.mapRect(1600, -600, 425, 250);
+
+ spawn.mapRect(1975, -600, 50, 625);
+ spawn.mapRect(2025, -2800, 1075, 2450);
- //spawn bullets on load to avoid sprint
- //spawn bullets
- for (let i = 0; i < 32; i++) {
- spawn.sniperBullet(660 + 580 * Math.random(), -2000 + 40 * i, 10, 4);
- const who = mob[mob.length - 1]
- Matter.Body.setVelocity(who, { x: 0, y: 8 });
- who.timeLeft = 300
- }
},
trainingTemplate() { //learn to crouch
@@ -920,15 +1340,8 @@ const level = {
simulation.isHorizontalFlipped = (Math.random() < 0.5) ? true : false //if true, some maps are flipped horizontally
level.levels = level.playableLevels.slice(0) //copy array, not by just by assignment
if (simulation.isCommunityMaps) {
- level.levels.push("stronghold");
- level.levels.push("basement");
- level.levels.push("crossfire");
- level.levels.push("vats")
- level.levels.push("n-gon")
- level.levels.push("house");
- level.levels.push("perplex");
- level.levels.push("coliseum");
- level.levels.push("tunnel");
+ // level.levels.push(level.communityLevels)
+ level.levels = level.levels.concat(level.communityLevels)
level.levels = shuffle(level.levels); //shuffles order of maps
level.levels.splice(0, 9); //remove some random levels to make up for adding the community levels
} else {
@@ -1432,9 +1845,10 @@ const level = {
y = y + height / 2
const doorBlock = body[body.length] = Bodies.rectangle(x, y, width, height, {
collisionFilter: {
- category: cat.body,
+ category: cat.map,
mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet //cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
},
+ isNoSetCollision: true,
inertia: Infinity, //prevents rotation
isNotHoldable: true,
friction: 1,
@@ -8526,5 +8940,355 @@ const level = {
ctx.shadowColor = "#0000";
}
}
- }
+ },
+ run() {
+ addPartToMap = (len) => { //adds new map elements to the level while the level is already running //don't forget to run simulation.draw.setPaths() after you all the the elements so they show up visually
+ map[len].collisionFilter.category = cat.map;
+ map[len].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet;
+ Matter.Body.setStatic(map[len], true); //make static
+ Composite.add(engine.world, map[len]);
+ }
+
+ anotherBoss = (x, y) => {
+ if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) {
+ tech.isScaleMobsWithDuplication = true
+ spawn.randomLevelBoss(x, y, ["historyBoss"]);
+ tech.isScaleMobsWithDuplication = false
+ } else if (tech.isResearchBoss) {
+ if (powerUps.research.count > 3) {
+ powerUps.research.changeRerolls(-4)
+ simulation.makeTextLog(`m.research -= 4
${powerUps.research.count}`)
+ } else {
+ tech.addJunkTechToPool(0.49)
+ }
+ spawn.randomLevelBoss(x, y, ["historyBoss"]);
+ }
+ }
+
+ const climbPad = level.boost(8200, -200, 500);
+ var climbTime = false;
+ var climbGroup = 0;
+ var initialSpawn = false;
+ var endTime = false;
+
+ let runMobList = [
+ "hopper",
+ "slasher",
+ "striker",
+ "stabber",
+ "springer",
+ "pulsar",
+ "sneaker",
+ "spinner",
+ "grower",
+ "focuser",
+ "spawner",
+ ];
+
+ let removeList = [];
+
+ level.custom = () => {
+ level.playerExitCheck();
+ level.exit.draw();
+ level.enter.draw();
+
+ climbPad.query();
+
+ if (m.pos.x > 8000 && climbTime === false) {
+ spawn.mapRect(7800, -900, 200, 900);
+ addPartToMap(map.length - 1);
+ simulation.draw.setPaths();
+
+ simulation.makeTextLog(`UNKNOWN: "Well done. Now climb."`, 600);
+ simulation.makeTextLog(`UNKNOWN: "I left a gift at the top."`, 600);
+
+ climbTime = true;
+ } //toggles on a mapRect when player passes a certain area
+
+ if (m.pos.x > 9000 && endTime === false) {
+ simulation.makeTextLog("UNKNOWN: \"Good luck. I hope you get out of here.\"", 600);
+ endTime = true;
+ }
+
+ for (i in mob) {
+ mob[i].damageReduction = 0;
+ Matter.Body.setVelocity(mob[i], {
+ x: mob[i].velocity.x * 0.97,
+ y: mob[i].velocity.y * 0.97
+ });
+ } //makes everything slow and immune
+ };
+
+ level.customTopLayer = () => {
+ ctx.fillStyle = "#888";
+
+ if (climbGroup === 0) {
+ //toggle on fillRect: 1
+ ctx.fillRect(8000, -900, 300, 100);
+ ctx.fillRect(8500, -1800, 300, 100);
+ ctx.fillRect(8300, -2700, 300, 100);
+ ctx.fillRect(8000, -3600, 300, 100);
+ ctx.fillRect(8200, -4500, 300, 100);
+ } else if (climbGroup === 1) {
+ //toggle on fillRect: 2
+ ctx.fillRect(8300, -1200, 300, 100);
+ ctx.fillRect(8500, -2100, 300, 100);
+ ctx.fillRect(8100, -3000, 300, 100);
+ ctx.fillRect(8000, -3900, 300, 100);
+ ctx.fillRect(8200, -4800, 300, 100);
+ } else if (climbGroup === 2) {
+ //toggle on fillRect: 0
+ ctx.fillRect(8500, -600, 300, 100);
+ ctx.fillRect(8100, -1500, 300, 100);
+ ctx.fillRect(8000, -2400, 300, 100);
+ ctx.fillRect(8500, -3300, 300, 100);
+ ctx.fillRect(8500, -4200, 300, 100);
+ }
+
+ if ((simulation.cycle % 120) === 0) {
+ for (var i = 0; i < map.length; i++) {
+ if (map[i].isRemove) {
+ Matter.Composite.remove(engine.world, map[i]);
+ map.splice(i, 1);
+ }
+ }
+
+ if (climbGroup === 0) {
+ //toggle on platforms: 0
+ spawn.mapRect(8000, -900, 300, 100);
+ addPartToMap(map.length - 1);
+ map[map.length - 1].isRemove = true;
+ spawn.mapRect(8500, -1800, 300, 100);
+ addPartToMap(map.length - 1);
+ map[map.length - 1].isRemove = true;
+ spawn.mapRect(8300, -2700, 300, 100);
+ addPartToMap(map.length - 1);
+ map[map.length - 1].isRemove = true;
+ spawn.mapRect(8000, -3600, 300, 100);
+ addPartToMap(map.length - 1);
+ map[map.length - 1].isRemove = true;
+ spawn.mapRect(8200, -4500, 300, 100);
+ addPartToMap(map.length - 1);
+ map[map.length - 1].isRemove = true;
+
+ climbGroup = 1;
+ } else if (climbGroup === 1) {
+ //toggle on platforms: 1
+ spawn.mapRect(8300, -1200, 300, 100);
+ addPartToMap(map.length - 1);
+ map[map.length - 1].isRemove = true;
+ spawn.mapRect(8500, -2100, 300, 100);
+ addPartToMap(map.length - 1);
+ map[map.length - 1].isRemove = true;
+ spawn.mapRect(8100, -3000, 300, 100);
+ addPartToMap(map.length - 1);
+ map[map.length - 1].isRemove = true;
+ spawn.mapRect(8000, -3900, 300, 100);
+ addPartToMap(map.length - 1);
+ map[map.length - 1].isRemove = true;
+ spawn.mapRect(8200, -4800, 300, 100);
+ addPartToMap(map.length - 1);
+ map[map.length - 1].isRemove = true;
+
+ climbGroup = 2;
+ } else if (climbGroup === 2) {
+ //toggle on platforms: 2
+ spawn.mapRect(8500, -600, 300, 100);
+ addPartToMap(map.length - 1);
+ map[map.length - 1].isRemove = true;
+ spawn.mapRect(8100, -1500, 300, 100);
+ addPartToMap(map.length - 1);
+ map[map.length - 1].isRemove = true;
+ spawn.mapRect(8000, -2400, 300, 100);
+ addPartToMap(map.length - 1);
+ map[map.length - 1].isRemove = true;
+ spawn.mapRect(8500, -3300, 300, 100);
+ addPartToMap(map.length - 1);
+ map[map.length - 1].isRemove = true;
+ spawn.mapRect(8500, -4200, 300, 100);
+ addPartToMap(map.length - 1);
+ map[map.length - 1].isRemove = true;
+
+ climbGroup = 0;
+ }
+
+ simulation.draw.setPaths(); //update map graphics
+ } //every 120 cycles, first deletes previous group, then cycles through one of 3 toggle groups
+ };
+
+ if (!initialSpawn) {
+ level.defaultZoom = 1000 //was 800 I changed this
+ simulation.zoomTransition(level.defaultZoom)
+ document.body.style.backgroundColor = "#dcdcde";
+ //Level
+ level.setPosToSpawn(-100, -1450);
+ spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
+
+ level.exit.x = 9300;
+ level.exit.y = -5130;
+ spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20);
+
+ //Map
+ spawn.mapRect(-1400, -2200, 1700, 200);
+ spawn.mapRect(100, -2200, 200, 1000);
+ spawn.mapRect(-600, -1400, 8600, 200);
+ spawn.mapRect(-1400, -2200, 200, 1000);
+ spawn.mapRect(-2800, -1400, 1600, 200);
+ spawn.mapRect(-2800, -1400, 200, 1400);
+ spawn.mapRect(-2800, -200, 11800, 200);
+ spawn.mapRect(-900, -600, 600, 600);
+ spawn.mapRect(200, -800, 500, 100);
+ spawn.mapRect(1300, -1400, 200, 900);
+ spawn.mapRect(1300, -600, 500, 100);
+ spawn.mapRect(2300, -800, 200, 200);
+ spawn.mapRect(2900, -400, 100, 400);
+ spawn.mapRect(3200, -600, 100, 600);
+ spawn.mapRect(3500, -800, 100, 800);
+ spawn.mapRect(4400, -900, 500, 100);
+ spawn.mapRect(4400, -600, 500, 100);
+ spawn.mapRect(4800, -900, 100, 400);
+ spawn.mapRect(5300, -550, 600, 550);
+ spawn.mapRect(5600, -900, 300, 800);
+ spawn.mapRect(6300, -300, 1100, 300);
+ spawn.mapRect(6600, -400, 500, 200);
+ spawn.mapRect(6600, -800, 500, 100);
+ spawn.mapRect(7000, -1400, 100, 700);
+ spawn.mapRect(7800, -5900, 200, 5100);
+ spawn.mapRect(7800, -5900, 1900, 200);
+ spawn.mapRect(9500, -5900, 200, 1000);
+ spawn.mapRect(8800, -5100, 900, 200);
+ spawn.mapRect(8800, -5100, 200, 5100);
+
+ //Text
+ spawn.mapRect(400, -1600, 100, 10);
+ spawn.mapRect(400, -1600, 10, 100);
+ spawn.mapRect(490, -1600, 10, 40);
+ spawn.mapRect(400, -1570, 100, 10);
+ spawn.mapRect(400, -1540, 100, 10);
+ spawn.mapRect(490, -1540, 10, 40);
+
+ spawn.mapRect(600, -1600, 10, 100);
+ spawn.mapRect(600, -1510, 100, 10);
+ spawn.mapRect(690, -1600, 10, 100);
+
+ spawn.mapRect(800, -1600, 100, 10);
+ spawn.mapRect(800, -1600, 10, 100);
+ spawn.mapRect(890, -1600, 10, 100);
+
+ spawn.mapRect(0, 0, 1, 1); //dont ask why i have these
+ spawn.mapRect(1, 0, 1, 1); //dont ask why i have these
+ spawn.mapRect(0, 1, 1, 1); //dont ask why i have these
+ spawn.mapRect(1, 1, 1, 1); //dont ask why i have these
+ spawn.mapRect(-1, 0, 1, 1); //dont ask why i have these
+ spawn.mapRect(0, -1, 1, 1); //dont ask why i have these
+ spawn.mapRect(-1, -1, 1, 1); //dont ask why i have these
+ spawn.mapRect(1, -1, 1, 1); //dont ask why i have these
+ spawn.mapRect(-1, 1, 1, 1); //dont ask why i have these
+
+ //Mob Spawning
+ setTimeout(() => {
+ simulation.makeTextLog("UNKNOWN: \"You cannot kill them.\"", 600);
+ }, 2000);
+
+ setTimeout(() => {
+ simulation.makeTextLog("UNKNOWN: \"But I have slowed them down for you.\"", 600);
+ }, 6000);
+
+
+ spawn[runMobList[Math.floor(Math.random() * runMobList.length)]](200, -400);
+ spawn[runMobList[Math.floor(Math.random() * runMobList.length)]](1800, -1000);
+ spawn[runMobList[Math.floor(Math.random() * runMobList.length)]](3200, -1000);
+ spawn[runMobList[Math.floor(Math.random() * runMobList.length)]](6200, -400);
+
+ if (simulation.difficulty > 10) {
+ spawn[runMobList[Math.floor(Math.random() * runMobList.length)]](1000, -400);
+ spawn[runMobList[Math.floor(Math.random() * runMobList.length)]](2400, -400);
+ spawn[runMobList[Math.floor(Math.random() * runMobList.length)]](4000, -400);
+ spawn[runMobList[Math.floor(Math.random() * runMobList.length)]](6600, -1000);
+
+ setTimeout(() => {
+ simulation.makeTextLog("UNKNOWN: \"Run.\"", 600);
+ }, 10000);
+ } //some of the mobs
+ if (simulation.difficulty > 20) {
+ spawn[runMobList[Math.floor(Math.random() * runMobList.length)]](1000, -1000);
+ spawn[runMobList[Math.floor(Math.random() * runMobList.length)]](3100, -300);
+ spawn[runMobList[Math.floor(Math.random() * runMobList.length)]](4200, -1000);
+ spawn[runMobList[Math.floor(Math.random() * runMobList.length)]](7400, -800);
+
+ setTimeout(() => {
+ simulation.makeTextLog("UNKNOWN: \"RUN!\"", 600);
+ }, 11000);
+ } //most of the mobs
+ if (simulation.difficulty > 30) {
+ spawn[runMobList[Math.floor(Math.random() * runMobList.length)]](200, -1000);
+ spawn[runMobList[Math.floor(Math.random() * runMobList.length)]](3400, -300);
+ spawn[runMobList[Math.floor(Math.random() * runMobList.length)]](5200, -800);
+ spawn[runMobList[Math.floor(Math.random() * runMobList.length)]](7500, -300);
+
+ setTimeout(() => {
+ simulation.makeTextLog("UNKNOWN: \"GET OUT OF HERE.\"", 600);
+ }, 12000);
+ } //all the mobs
+
+ //Boss Spawning
+ if (simulation.difficulty > 5) {
+ spawn.randomLevelBoss(-2200, -700, ["historyBoss", "powerUpBossBaby", "blockBoss", "revolutionBoss"]);
+
+ setTimeout(() => {
+ simulation.makeTextLog("UNKNOWN: \"They are coming for you.\"", 600);
+ }, 14000);
+ }
+ anotherBoss(-1800, -700); //custom second boss spawn
+
+ //Blocks
+ spawn.bodyRect(1300, -500, 200, 100);
+ spawn.bodyRect(1400, -500, 200, 100);
+ spawn.bodyRect(1500, -500, 200, 100);
+
+ spawn.bodyRect(5700, -1200, 100, 100);
+ spawn.bodyRect(5700, -1100, 100, 100);
+ spawn.bodyRect(5700, -1000, 100, 100);
+
+ spawn.bodyRect(6800, -700, 100, 100);
+ spawn.bodyRect(6800, -600, 100, 100);
+ spawn.bodyRect(6800, -500, 100, 100);
+
+ spawn.debris(4400, -300, 500, 16);
+ spawn.debris(3300, -600, 200, 6);
+ spawn.debris(3000, -500, 20, 6);
+ spawn.debris(2300, -300, 200, 6);
+ spawn.debris(200, -300, 500, 16);
+
+ //Powerups
+ if (simulation.difficulty > 10) {
+ powerUps.spawn(1600, -700, "tech");
+ }
+ powerUps.spawnRandomPowerUp(1700, -700);
+
+ if (simulation.difficulty > 20) {
+ powerUps.spawn(4600, -700, "tech");
+ }
+ powerUps.spawnRandomPowerUp(4700, -700);
+
+ if (simulation.difficulty > 30) {
+ powerUps.spawn(6800, -1000, "tech");
+ }
+ powerUps.spawnRandomPowerUp(6900, -1000);
+
+ powerUps.spawn(9200, -5400, "tech");
+
+ if (simulation.difficulty > 10) {
+ powerUps.spawn(9200, -5500, "tech");
+ }
+ if (simulation.difficulty > 20) {
+ powerUps.spawn(9200, -5600, "tech");
+ }
+ if (simulation.difficulty > 30) {
+ powerUps.spawn(9200, -5700, "tech");
+ }
+ powerUps.addResearchToLevel() //needs to run after mobs are spawned
+ initialSpawn == true;
+ }
+ },
};
\ No newline at end of file
diff --git a/js/mob.js b/js/mob.js
index d72aa8f..9f0583c 100644
--- a/js/mob.js
+++ b/js/mob.js
@@ -667,6 +667,7 @@ const mobs = {
y: this.position.y + seeRange * Math.sin(this.angle)
};
vertexCollision(this.position, look, map);
+ vertexCollision(this.position, look, body);
if (best.dist2 != Infinity) {
this.springTarget.x = best.x;
this.springTarget.y = best.y;
diff --git a/js/powerup.js b/js/powerup.js
index 81fe330..b7c7f44 100644
--- a/js/powerup.js
+++ b/js/powerup.js
@@ -1103,7 +1103,7 @@ const powerUps = {
if (
(!tech.isSuperDeterminism || (target !== 'research')) &&
!(tech.isEnergyNoAmmo && target === 'ammo') &&
- (!simulation.isNoPowerUps || (target === 'research' || target === 'heal' || target === 'ammo'))
+ (!simulation.isNoPowerUps)
) {
powerUps.directSpawn(x, y, target, moving, mode, size)
if (Math.random() < tech.duplicationChance()) {
diff --git a/js/spawn.js b/js/spawn.js
index d87316f..c125a21 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -1443,6 +1443,7 @@ const spawn = {
me.delay = 120 * simulation.CDScale;
me.randomHopFrequency = 200 + Math.floor(Math.random() * 150);
me.randomHopCD = simulation.cycle + me.randomHopFrequency;
+ Matter.Body.rotate(me, Math.random() * Math.PI);
spawn.shield(me, x, y);
me.do = function() {
this.gravity();
diff --git a/js/tech.js b/js/tech.js
index 1fe8add..49e6d15 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -16,7 +16,7 @@ const tech = {
//remove lore if it's your first time playing since it's confusing
//also remove lore if cheating
lore.techCount = 0;
- if (simulation.isCheating || localSettings.runCount > 1) { //simulation.isCommunityMaps ||
+ if (simulation.isCheating || localSettings.runCount < 1) { //simulation.isCommunityMaps ||
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isLore) {
tech.tech[i].frequency = 0;
@@ -228,7 +228,7 @@ const tech = {
if (tech.isEnergyLoss) dmg *= 1.55;
if (tech.isAcidDmg && m.health > 1) dmg *= 1.35;
if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage
- if (tech.isEnergyDamage) dmg *= 1 + m.energy * 0.1;
+ if (tech.isEnergyDamage) dmg *= 1 + m.energy * 0.11;
if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.007
if (tech.isRerollDamage) dmg *= 1 + 0.037 * powerUps.research.count
if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.25
@@ -2225,7 +2225,7 @@ const tech = {
},
{
name: "electronegativity",
- description: "increase damage by 1%
for every 10 stored energy",
+ description: "increase damage by 1%
for every 9 stored energy",
maxCount: 1,
count: 0,
frequency: 1,
@@ -2617,6 +2617,10 @@ const tech = {
effect() {
tech.largerHeals++;
this.refundAmount += tech.addJunkTechToPool(0.05)
+ //update current heals
+ for (let i = 0; i < powerUp.length; i++) {
+ if (powerUp[i].name === "heal") powerUp[i].size = powerUps.heal.size()
+ }
},
refundAmount: 0,
remove() {
diff --git a/style.css b/style.css
index 54e9dc5..ec3bdec 100644
--- a/style.css
+++ b/style.css
@@ -131,12 +131,13 @@ summary {
#training-button {
position: absolute;
- bottom: 4px;
- right: 0px;
+ /* bottom: 4px; */
+ /* right: 0px;
left: 0px;
- margin: auto;
+ margin: auto; */
/* bottom: 58px; */
- /* right: 4px; */
+ top: 4px;
+ right: 4px;
z-index: 12;
transition: opacity 5s ease-in;
diff --git a/todo.txt b/todo.txt
index 6a53623..a816489 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,42 +1,81 @@
******************************************************** NEXT PATCH **************************************************
-more training levels: "trainingWalk", "trainingCrouch", "trainingJump", "trainingHold", "trainingThrow", "trainingHit", "trainingHeal", "trainingFire", "trainingDeflect"
+new community level "run" (by iSuggestedThatAlready / iNoobBoi)!!!!!!
+ try it out by enabling community levels in the settings
-tech: Bose Einstein condensate is removed until I can balance it
+more training levels: "trainingNailGun", "trainingShotGun", "trainingSuperBall", "trainingMatterWave", "trainingMissile"
-bug fixes
+no power ups check box in experiment mode now disables all types of power ups, not just tech
+ simulation.isNoPowerUps
+powerUps can no longer move through doors
+ this might lead to problems that I haven't thought about, but let's see
+adiabatic healing now updates active heal power ups as well as future ones
+
+fixed bug with undefined tech not showing up
******************************************************** TODO ********************************************************
-balance time dilation with bose einstein (you can freeze everything and take no damage)
- code is still there, need to balance
- balance with energy drain?
+decoherence rewrite with flags instead of a banish array, to fix bugs
training
- make the button more obvious if the account has only played 1-2 times
+ save training level progress as local variable
+ reset progress to zero if you clear all training levels
+ maybe only save progress if you made if past the trainingHeal level
+ make the training button more obvious if the account has only played 1-2 times
uses the lore voice/text code?
- add vertical tunnels for power ups spawns like in intro?
+ replace all mob clear triggers with button triggers?
tutorial rooms:
done walk forwards and backwards
done crouch through tunnel
done jump over wall and gap
+ look around with your mouse
done pick up a block an drop onto a button to open door
done fire block at button to open door
done fire block at mob to open door
+ done use field to deflect bullets
done pick up heal power ups with field to open door
done use a gun to kill a mob and use it's block body to activate a button to open a door
- done use field to deflect bullets
- use field to pick up a field and research
- research once to open door
- puzzle rooms
- save training level progress as local variable if puzzles are added
+ gun rooms: (different mobs type in each room)
+ different mobs in each room
+ how to introduce shields?
+ "hopper" "slasher" "shooter "grenadier" "striker" "laser" "stabber" "springer" "pulsar" "launcher" "launcherOne" "exploder" "sneaker" "sucker" "sniper" "spinner" "grower" "beamer" "focuser" "spawner" "ghoster"
+ done nailgun - start with no ammo collect ammo and shoot at mobs
+ done shotgun - some simple close range combat
+ done superball - use 1 ammo to take out several mobs
+ done matter wave - kill a mob inside a map element
+ done missiles - take out mobs that are around corner and have them drop on a button
+ grenades - use 1 ammo to take out several mobs at once
+ spores - use 1 ammo to take out several mobs at once
+ drones - use mouse to bring drones around a corner
+ foam - slow boss mob, and run away
+ harpoon - kill one close mob, pick up ammo that is out of reach, first at several far away mobs with crouch
+ mine - built kill zone, get mobs to follow into mine kill zone
+ laser - reflect off walls to hit mob
+ field rooms:
+ standing wave - bullets come from every direction
+ perfect diamagnetism - drop field to rapid stream of bullets and fire gun at them
+ negative mass - fly over a bunch of ground based mobs , hoppers
+ molecular assembler - guide drones around the corner
+ plasma torch - nothing fancy, just kill mobs
+ time dilation - get past some mobs
+ cloaking - sneak past mobs to collect some heals
+ pilot wave - toss blocks at mobs
+ worm hole - teleport past lasers
+ puzzle rooms:
+ close a door to trigger a button
combat rooms:
+ kill so many mobs that the mob bodies pile up and you can get over a wall by jumping on them
boss gauntlet, spawn with nothing but a few power ups and fight 10 bosses
+ use no gun, just bots to kil stuff
JUNK tech disable level exit for 5 minutes
level.disableExit = true
setTimeout( () => {level.disableExit = false;}, 5*60000);
+balance time dilation with bose einstein (you can freeze everything and take no damage)
+ code is still there, need to balance
+ balance with energy drain?
+
tech: basic research - heal power ups spawn as research power ups instead, and using research heals you (needs to be pretty low, like 3% health)
tech: maintenance - heals no longer spawn, but using research heals you 100%
@@ -44,6 +83,9 @@ tech reversed regression - mobs take less damage after each time you hit them,
maybe a gun tech only?
what gun?
+foam tech - make it move slower, last much longer, and push away other foam bullets
+ not sure about bouncing off walls, but that might be fun too
+
tech extend fracture analysis to give bonus damage to frozen also, but reduce the 400%->300%?
pulsar mobs retarget too easily