reservoir

new map reservoir - still in development, but putting it out for feedback

tech: optical amplifier - get 3 random laser tech, but you can't turn off your laser until you run out of energy

slow light - lasers are slightly closer together at higher stacks of this tech
research power ups no longer log to the "in game console" to prevent spam
dynamo-bots give 6->7 more energy (upgraded 20->23)
some Boss invulnerability times are very slightly shorter
music tech now links to actual n-gon music
  https://www.youtube.com/watch?v=lEbHeSdmS-k&list=PL9Z5wjoBiPKEDhwCW2RN-VZoCpmhIojdn
This commit is contained in:
landgreen
2022-01-10 20:59:44 -08:00
parent fb13826adb
commit 514b72c76d
7 changed files with 383 additions and 87 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -3617,7 +3617,7 @@ const b = {
if (Vector.magnitude(Vector.sub(this.position, player.position)) < 250 && m.immuneCycle < m.cycle) { //give energy if (Vector.magnitude(Vector.sub(this.position, player.position)) < 250 && m.immuneCycle < m.cycle) { //give energy
Matter.Body.setAngularVelocity(this, this.spin) Matter.Body.setAngularVelocity(this, this.spin)
if (this.isUpgraded) { if (this.isUpgraded) {
m.energy += 0.1 m.energy += 0.115
simulation.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
x: this.position.x, x: this.position.x,
y: this.position.y, y: this.position.y,
@@ -3626,7 +3626,7 @@ const b = {
time: simulation.drawTime time: simulation.drawTime
}); });
} else { } else {
m.energy += 0.03 m.energy += 0.035
simulation.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
x: this.position.x, x: this.position.x,
y: this.position.y, y: this.position.y,
@@ -6374,10 +6374,20 @@ const b = {
ammoPack: Infinity, ammoPack: Infinity,
have: false, have: false,
charge: 0, charge: 0,
isStuckOn: false,
do() {}, do() {},
fire() {}, fire() {},
chooseFireMethod() { chooseFireMethod() {
this.do = () => {}; this.do = () => {
if (tech.isStuckOn) {
if (this.isStuckOn) {
if (!input.fire) this.fire();
if (m.energy < tech.laserFieldDrain * tech.isLaserDiode) this.isStuckOn = false
} else if (input.fire) {
this.isStuckOn = true
}
}
};
if (tech.isPulseLaser) { if (tech.isPulseLaser) {
this.fire = () => { this.fire = () => {
const drain = 0.01 * tech.isLaserDiode * (tech.isCapacitor ? 10 : 1) const drain = 0.01 * tech.isLaserDiode * (tech.isCapacitor ? 10 : 1)
@@ -6455,7 +6465,6 @@ const b = {
} else { } else {
this.fire = this.fireLaser this.fire = this.fireLaser
} }
// this.fire = this.firePhoton // this.fire = this.firePhoton
}, },
// firePhoton() { // firePhoton() {
@@ -6569,7 +6578,7 @@ const b = {
m.fireCDcycle = m.cycle m.fireCDcycle = m.cycle
m.energy -= m.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode m.energy -= m.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode
const dmg = 0.4 * tech.laserDamage // 3.5 * 0.55 = 200% more damage const dmg = 0.4 * tech.laserDamage // 3.5 * 0.55 = 200% more damage
const spacing = Math.ceil(5.2 - 0.2 * tech.historyLaser) const spacing = Math.ceil(5.2 - 0.4 * tech.historyLaser)
ctx.beginPath(); ctx.beginPath();
b.laser({ b.laser({
x: m.pos.x + 20 * Math.cos(m.angle), x: m.pos.x + 20 * Math.cos(m.angle),

View File

@@ -7,35 +7,30 @@ const level = {
defaultZoom: 1400, defaultZoom: 1400,
onLevel: -1, onLevel: -1,
levelsCleared: 0, levelsCleared: 0,
playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "ruins"], //intro, gauntlet, final are added in at the start and end of level order playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "ruins"], //see level.populateLevels: (intro, ... , reservoir, ... , gauntlet, final) added later
// playableLevels: ["ruins", "ruins", "ruins", "ruins", "ruins", "ruins", "ruins", "ruins", "ruins", "ruins", "ruins"], //intro, gauntlet, final are added in at the start and end of level order
communityLevels: ["stronghold", "basement", "crossfire", "vats", "run", "n-gon", "house", "perplex", "coliseum", "tunnel"], communityLevels: ["stronghold", "basement", "crossfire", "vats", "run", "n-gon", "house", "perplex", "coliseum", "tunnel"],
trainingLevels: [ trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon"],
"walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect",
"heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile",
"stack", "mine", "grenades", "harpoon"
],
levels: [], levels: [],
start() { start() {
if (level.levelsCleared === 0) { //this code only runs on the first level if (level.levelsCleared === 0) { //this code only runs on the first level
// simulation.enableConstructMode() //used to build maps in testing mode
// m.immuneCycle = Infinity //you can't take damage // m.immuneCycle = Infinity //you can't take damage
// localSettings.levelsClearedLastGame = 10 // localSettings.levelsClearedLastGame = 10
// level.difficultyIncrease(1) //30 is near max on hard //60 is near max on why // level.difficultyIncrease(1) //30 is near max on hard //60 is near max on why
// simulation.isHorizontalFlipped = true // simulation.isHorizontalFlipped = true
// m.setField("plasma torch") // m.setField("plasma torch")
// b.giveGuns("harpoon") // b.giveGuns("laser")
// tech.giveTech("extruder") // for (let i = 0; i < 9; i++) tech.giveTech("slow light")
// tech.giveTech("thermocouple") // tech.giveTech("thermocouple")
// for (let i = 0; i < 2; i++) powerUps.directSpawn(0, 0, "tech"); // for (let i = 0; i < 2; i++) powerUps.directSpawn(0, 0, "tech");
// for (let i = 0; i < 9; i++) tech.giveTech("annelids") // tech.giveTech("annelids")
// tech.giveTech("tinsellated flagella") // tech.giveTech("tinsellated flagella")
// for (let i = 0; i < 2; i++) tech.giveTech("refractory metal") // for (let i = 0; i < 2; i++) tech.giveTech("refractory metal")
// tech.giveTech("antiscience") // tech.giveTech("antiscience")
// for (let i = 0; i < 1; i++) tech.giveTech("reticulum") // for (let i = 0; i < 1; i++) tech.giveTech("reticulum")
// for (let i = 0; i < 2; i++) tech.giveTech("laser-bot") // for (let i = 0; i < 2; i++) tech.giveTech("laser-bot")
// tech.tech[297].frequency = 100 // tech.tech[297].frequency = 100
// level.ruins(); // level.reservoir();
// simulation.enableConstructMode() //used to build maps in testing mode
if (simulation.isTraining) { level.walk(); } else { level.intro(); } if (simulation.isTraining) { level.walk(); } else { level.intro(); }
// level.testing(); //not in rotation, used for testing // level.testing(); //not in rotation, used for testing
@@ -261,6 +256,7 @@ const level = {
} else { } else {
level.levels = shuffle(level.levels); //shuffles order of maps level.levels = shuffle(level.levels); //shuffles order of maps
} }
level.levels.splice(Math.floor(level.levels.length * (0.4 + 0.6 * Math.random())), 0, "reservoir"); //add level to the back half of the randomized levels list
if (!build.isExperimentSelection || (build.hasExperimentalMode && !simulation.isCheating)) { //experimental mode is endless, unless you only have an experiment Tech if (!build.isExperimentSelection || (build.hasExperimentalMode && !simulation.isCheating)) { //experimental mode is endless, unless you only have an experiment Tech
level.levels.unshift("intro"); //add level to the start of the randomized levels list level.levels.unshift("intro"); //add level to the start of the randomized levels list
level.levels.push("gauntlet"); //add level to the end of the randomized levels list level.levels.push("gauntlet"); //add level to the end of the randomized levels list
@@ -451,13 +447,13 @@ const level = {
}); });
return who return who
}, },
elevator(x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) { elevator(x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }, isAtTop = false) {
x += width / 2 x += width / 2
y += height / 2 y += height / 2
maxHeight += height / 2 maxHeight += height / 2
const yTravel = maxHeight - y const yTravel = maxHeight - y
force += simulation.g force += simulation.g
const who = body[body.length] = Bodies.rectangle(x, y, width, height, { const who = body[body.length] = Bodies.rectangle(x, isAtTop ? maxHeight : y, width, height, {
collisionFilter: { collisionFilter: {
category: cat.body, category: cat.body,
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 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
@@ -543,10 +539,8 @@ const level = {
Matter.Body.setDensity(who, 0.01) //10x density for added stability Matter.Body.setDensity(who, 0.01) //10x density for added stability
return who return who
}, },
platform(x, y, width, height, speed = 0, density = 0.001) { spring(x, y, v = "-100 0 100 0 70 40 0 50 -70 40", force = 0.01, distance = 300, angle = 0) {
x = x + width / 2 const who = body[body.length] = Matter.Bodies.fromVertices(x, y, Vertices.fromPath(v), {
y = y + height / 2
const who = body[body.length] = Bodies.rectangle(x, y, width, height, {
collisionFilter: { collisionFilter: {
category: cat.body, category: cat.body,
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 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
@@ -556,26 +550,52 @@ const level = {
friction: 1, friction: 1,
frictionStatic: 1, frictionStatic: 1,
restitution: 0, restitution: 0,
}); frictionAir: 1,
density: 0.1,
isReady: true,
isResetting: false,
query() {
if (this.isReady) {
if (Matter.Query.collides(this, [player]).length) {
this.isReady = false
this.constraint.stiffness = 0
this.constraint.damping = 0 //0.3
this.frictionAir = 0
Matter.Body.setVelocity(this, { x: 0, y: 0 });
//show graphically being ready?
Matter.Body.setDensity(who, density) }
const constraint = Constraint.create({ //fix rotor in place, but allow rotation } else {
if (this.isResetting) {
this.constraint.stiffness += 0.0005
if (this.constraint.stiffness > 0.1) {
this.isResetting = false
this.isReady = true
}
} else {
if (Vector.magnitudeSquared(Vector.sub(this.position, { x: x, y: y })) < distance * distance) {
this.force.y -= force * this.mass
} else {
this.constraint.damping = 1
this.frictionAir = 1
this.isResetting = true
Matter.Body.setVelocity(this, { x: 0, y: 0 });
}
}
}
}
});
who.constraint = Constraint.create({
pointA: { pointA: {
x: x, x: who.position.x,
y: y y: who.position.y
}, },
bodyB: who, bodyB: who,
stiffness: 0.1, stiffness: 1,
damping: 0.3 damping: 1
}); });
Composite.add(engine.world, constraint); Composite.add(engine.world, who.constraint);
constraint.plat = { return who
position: who.position,
speed: speed,
}
constraint.pauseUntilCycle = 0 //to to pause platform at top and bottom
return constraint
}, },
rotor(x, y, rotate = 0, radius = 800, width = 40, density = 0.0005) { rotor(x, y, rotate = 0, radius = 800, width = 40, density = 0.0005) {
const rotor1 = Matter.Bodies.rectangle(x, y, width, radius, { const rotor1 = Matter.Bodies.rectangle(x, y, width, radius, {
@@ -1174,10 +1194,10 @@ const level = {
for (let i = 0, len = powerUpCollide.length; i < len; i++) { for (let i = 0, len = powerUpCollide.length; i < len; i++) {
const diameter = 2 * powerUpCollide[i].size const diameter = 2 * powerUpCollide[i].size
const buoyancy = 1 - 0.2 * Math.max(0, Math.min(diameter, this.min.y - powerUpCollide[i].position.y + powerUpCollide[i].size)) / diameter const buoyancy = 1 - 0.2 * Math.max(0, Math.min(diameter, this.min.y - powerUpCollide[i].position.y + powerUpCollide[i].size)) / diameter
powerUpCollide[i].force.y -= buoyancy * 1.1 * powerUpCollide[i].mass * simulation.g; powerUpCollide[i].force.y -= buoyancy * 1.14 * powerUpCollide[i].mass * simulation.g;
Matter.Body.setVelocity(powerUpCollide[i], { Matter.Body.setVelocity(powerUpCollide[i], {
x: powerUpCollide[i].velocity.x, x: powerUpCollide[i].velocity.x,
y: 0.95 * powerUpCollide[i].velocity.y y: 0.96 * powerUpCollide[i].velocity.y
}); });
} }
} }
@@ -1188,9 +1208,22 @@ const level = {
// ctx.fillRect(this.min.x, this.min.y, this.width, this.height) // ctx.fillRect(this.min.x, this.min.y, this.width, this.height)
// } // }
// }, // },
level(isFill) { levelRise(growRate = 1) {
if (this.height < this.maxHeight && !m.isBodiesAsleep) {
this.height += growRate
this.min.y -= growRate
this.max.y = this.min.y + this.height
}
},
levelFall(fallRate = 1) {
if (this.height > 0 && !m.isBodiesAsleep) {
this.height -= fallRate
this.min.y += fallRate
this.max.y = this.min.y + this.height
}
},
level(isFill, growSpeed = 1) {
if (!m.isBodiesAsleep) { if (!m.isBodiesAsleep) {
const growSpeed = 1
if (isFill) { if (isFill) {
if (this.height < this.maxHeight) { if (this.height < this.maxHeight) {
this.height += growSpeed this.height += growSpeed
@@ -2149,7 +2182,7 @@ const level = {
) )
}, },
// (x = offset.x, y = offset.y) => { // (x = offset.x, y = offset.y) => {
// const elevator1 = level.elevator(x + 1100, y - 200, 250, 30, -2100, 0.0015) // elevator(x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }, isTeleport = false) { // const elevator1 = level.elevator(x + 1100, y - 200, 250, 30, -2100, 0.0015) // x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }, isTeleport = false) {
// // const elevator1 = level.elevator(x + 175, y - 200, 250, 30, -1400, 0.001) // // const elevator1 = level.elevator(x + 175, y - 200, 250, 30, -1400, 0.001)
// // const elevator2 = level.elevator(x + 2175, y - 200, 250, 30, -1400, 0.001) // // const elevator2 = level.elevator(x + 2175, y - 200, 250, 30, -1400, 0.001)
@@ -2928,6 +2961,204 @@ const level = {
spawn.bodyRect(2400, -100, 100, 60); spawn.bodyRect(2400, -100, 100, 60);
spawn.bodyRect(2500, -150, 100, 150); //exit step spawn.bodyRect(2500, -150, 100, 150); //exit step
}, },
reservoir() {
level.exit.x = 1700;
level.exit.y = -4510;
spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 25);
level.setPosToSpawn(-500, 850); //normal spawn
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
level.defaultZoom = 2300
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#d8dadf";
powerUps.spawnStartingPowerUps(-1175, -3875);
//no debris?
// spawn.debris(750, -2200, 3700, 16); //16 debris per level
//walls
spawn.mapRect(-3500, -5000, 1500, 6500);
spawn.mapRect(2000, -5000, 1500, 6500);
spawn.mapRect(-2500, 1100, 5000, 400); //slime floor
spawn.mapRect(-3500, -5475, 7000, 600); //top
spawn.mapRect(-1925, -4900, 175, 375); //pipe
spawn.mapRect(-1950, -4550, 225, 25); //pipe
//top floor exit
spawn.mapRect(1025, -4475, 1100, 50);
spawn.mapRect(1475, -4900, 50, 250);
// ground
spawn.mapVertex(-687, 1060, "700 0 -700 0 -450 -300 450 -300"); //left base
spawn.mapVertex(863, 1060, "700 0 -700 0 -450 -300 450 -300"); //right base
//entrance
spawn.mapRect(-730, 525, 475, 50);
spawn.mapRect(-730, 550, 50, 150);
spawn.mapRect(-305, 550, 50, 500);
spawn.bodyRect(-717, 700, 25, 100); //door
spawn.bodyRect(-717, 800, 25, 100); //door
//1st floor
//left
spawn.mapVertex(-1125 + 435, -50, "325 0 250 80 -250 80 -325 0 -250 -80 250 -80");
spawn.mapRect(-1125, -100, 870, 100);
if (Math.random() < 0.33) {
spawn.mapVertex(-687, -1000, "-100 -300 0 -350 100 -300 100 300 0 350 -100 300");
} else if (Math.random() < 0.5) {
spawn.mapVertex(-687, -1000, "-150 -450 0 -525 150 -450 150 450 0 525 -150 450");
} else {
spawn.mapVertex(-687, -700, "-150 0 150 0 150 450 0 525 -150 450");
}
const spinnerArray = []
spinnerArray.push(level.spinner(72, -300, 40, 500, 0.003, Math.PI / 2))
//right
spawn.mapVertex(425 + 435, -50, "325 0 250 80 -250 80 -325 0 -250 -80 250 -80");
spawn.mapRect(425, -100, 870, 100);
spawn.mapRect(300, 675, 250, 25);
spawn.mapRect(675, 450, 375, 25);
spawn.mapRect(1175, 225, 240, 25);
if (Math.random() < 0.33) {
spawn.mapVertex(855, -1000, "-100 -300 0 -350 100 -300 100 300 0 350 -100 300");
} else if (Math.random() < 0.5) {
spawn.mapVertex(855, -1000, "-150 -450 0 -525 150 -450 150 450 0 525 -150 450");
} else {
spawn.mapVertex(855, -700, "-150 0 150 0 150 450 0 525 -150 450");
}
//2nd floor
spawn.mapVertex(855, -1936, "-612 50 0 100 612 50 612 -50 -612 -50");
spawn.mapVertex(-687, -1936, "-612 50 0 100 612 50 612 -50 -612 -50");
//2nd floor right building
const boost1 = level.boost(800, -2000, 700)
spawn.mapRect(550, -3050, 600, 175);
spawn.mapRect(550, -2700, 150, 600);
spawn.mapRect(1000, -2700, 150, 600);
spawn.mapRect(450, -2700, 250, 25);
spawn.mapRect(1000, -2700, 250, 25);
const boost2 = level.boost(800, -3050, 1500)
spinnerArray.push(level.spinner(50, -3325, 45, 600, 0.003, Math.PI / 2))
//2nd floor left building
spawn.mapRect(-875, -2350, 600, 200);
spawn.mapRect(-825, -2825, 425, 275);
spawn.mapRect(-450, -3125, 50, 350);
spawn.mapRect(-750, -3150, 350, 50);
spawn.mapRect(-650, -3400, 250, 300);
spawn.mapRect(-650, -3675, 200, 50);
spawn.bodyRect(-375, -2150, 100, 150, 0.2);
//2nd floor left pillar
spawn.mapRect(-1300, -2625, 225, 25);
spawn.mapRect(-1300, -3225, 225, 25);
spawn.mapRect(-1300, -3825, 225, 25);
const slime = level.hazard(-2000, -5000, 4000, 6060); // hazard(x, y, width, height, damage = 0.003)
slime.height -= slime.maxHeight - 60 //start slime at zero
slime.min.y += slime.maxHeight
slime.max.y = slime.min.y + slime.height
const elevator1 = level.elevator(-1625, -90, 310, 35, -2000, 0.0025, { up: 0.1, down: 0.2 }) //x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) {
elevator1.isOn = true
level.custom = () => {
elevator1.drawTrack();
ctx.fillStyle = "#c0c3c9"
ctx.fillRect(-1200, -3825, 25, 1850); //small pillar background
ctx.fillStyle = "#d0d4d6"
ctx.fillRect(-1100, -1925, 825, 2925) //large pillar background
ctx.fillRect(450, -1925, 825, 2925) //large pillar background
ctx.fillStyle = "#cff" //exit
ctx.fillRect(1475, -4900, 525, 425)
level.playerExitCheck();
level.exit.draw();
level.enter.draw();
};
let waterFallWidth = 0
let waterFallX = 0
let waterFallSmoothX = 0
let isWaterfallFilling = false
const riseRate = 0.25 + Math.min(1, simulation.difficulty * 0.01)
level.customTopLayer = () => {
boost1.query();
boost2.query();
if (elevator1.isOn) {
elevator1.move();
} else if (Matter.Query.collides(elevator1, [player]).length) {
elevator1.isOn = true
elevator1.isUp = false
elevator1.removeConstraint();
elevator1.frictionAir = 0.2
}
ctx.fillStyle = "#233"
ctx.beginPath(); //central dot on spinners
ctx.arc(spinnerArray[0].pointA.x, spinnerArray[0].pointA.y, 9, 0, 2 * Math.PI);
for (let i = 0, len = spinnerArray.length; i < len; i++) {
ctx.moveTo(spinnerArray[i].pointA.x, spinnerArray[i].pointA.y)
ctx.arc(spinnerArray[i].pointA.x, spinnerArray[i].pointA.y, 9, 0, 2 * Math.PI);
}
ctx.fill();
//shadow
ctx.fillStyle = "rgba(0,10,30,0.1)"
ctx.fillRect(550, -2900, 600, 925);
ctx.fillRect(-750, -3100, 300, 275);
ctx.fillRect(-650, -3625, 200, 225);
ctx.fillRect(-825, -2575, 425, 325);
ctx.fillRect(-875, -2150, 600, 150);
slime.query();
if (isWaterfallFilling) {
if (slime.height < 5500) {
//draw slime fill
waterFallWidth = 0.98 * waterFallWidth + 4.7 * Math.random()
waterFallSmoothX = 0.98 * waterFallSmoothX + 3.5 * Math.random()
waterFallX = waterFallSmoothX - 1985
ctx.fillStyle = `hsla(160, 100%, 43%,${0.3+0.07*Math.random()})`
ctx.fillRect(waterFallX, -5050, waterFallWidth, 6175 - slime.height)
ctx.fillRect(waterFallX + waterFallWidth * Math.random(), -5050, 4, 6175 - slime.height)
//push player down if they go under waterfall
if (player.position.x > waterFallX && player.position.x < waterFallX + waterFallWidth && player.position.y < slime.height) {
Matter.Body.setVelocity(player, {
x: player.velocity.x,
y: player.velocity.y + 2
});
}
slime.levelRise(riseRate)
}
} else if (Vector.magnitudeSquared(Vector.sub(player.position, level.enter)) > 100000) {
isWaterfallFilling = true
}
};
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
// m.immuneCycle = Infinity //you can't take damage
// spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
// spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
spawn.randomMob(1000, -275, 0.3);
spawn.randomMob(950, -1725, 0.2);
spawn.randomMob(-725, -1775, 0.2);
spawn.randomMob(1775, 1000, 0.1);
spawn.randomMob(-200, -2075, 0.1);
spawn.randomMob(375, -2125, 0.1);
spawn.randomMob(1025, -3200, 0);
spawn.randomMob(-525, -3750, 0);
spawn.randomMob(-550, -3500, 0);
spawn.randomMob(-700, -2450, -0.1);
spawn.randomMob(-1175, -2775, -0.1);
spawn.randomMob(1350, -2075, -0.2);
spawn.randomSmallMob(-575, -2925);
spawn.randomGroup(-400, -4400, 0);
if (simulation.difficulty > 1) {
spawn.randomLevelBoss(825, -3500);
spawn.secondaryBossChance(75, -1350)
}
powerUps.addResearchToLevel() //needs to run after mobs are spawned
},
ruins() { ruins() {
const vanish = [] const vanish = []
level.exit.x = -850; level.exit.x = -850;
@@ -3005,11 +3236,6 @@ const level = {
spawn.mapRect(-1050, -1800, 525, 25); spawn.mapRect(-1050, -1800, 525, 25);
spawn.mapRect(-550, -1800, 25, 200); spawn.mapRect(-550, -1800, 25, 200);
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
// m.immuneCycle = Infinity //you can't take damage
// spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
// spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
spawn.randomMob(-1175, -1975, -0.4); spawn.randomMob(-1175, -1975, -0.4);
spawn.randomMob(275, -1500, -0.3); spawn.randomMob(275, -1500, -0.3);
spawn.randomMob(700, -1875, -0.2); spawn.randomMob(700, -1875, -0.2);
@@ -4255,12 +4481,12 @@ const level = {
} }
}, },
highrise() { highrise() {
const elevator1 = level.elevator(-790, -190, 180, 25, -1150) //, 0.007 const elevator1 = level.elevator(-790, -190, 180, 25, -1150, 0.0025, { up: 0.01, down: 0.2 }, true) //x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) {
elevator1.addConstraint(); elevator1.addConstraint();
// const button1 = level.button(-500, -200) // const button1 = level.button(-500, -200)
const toggle1 = level.toggle(-500, -200) //(x,y,isOn,isLockOn = true/false) const toggle1 = level.toggle(-500, -200) //(x,y,isOn,isLockOn = true/false)
const elevator2 = level.elevator(-3630, -1000, 180, 25, -1740) //, 0.007 const elevator2 = level.elevator(-3630, -1000, 180, 25, -1740) //x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) {
elevator2.addConstraint(); elevator2.addConstraint();
// const button2 = level.button(-3100, -1330) // const button2 = level.button(-3100, -1330)
const toggle2 = level.toggle(-3100, -1330) //(x,y,isOn, isLockOn = true/false) const toggle2 = level.toggle(-3100, -1330) //(x,y,isOn, isLockOn = true/false)
@@ -4295,11 +4521,10 @@ const level = {
if (elevator1.isOn) { if (elevator1.isOn) {
elevator1.move(); elevator1.move();
ctx.fillStyle = "#444" ctx.fillStyle = "#444"
ctx.fillRect(-700, -1140, 1, 975)
} else { } else {
ctx.fillStyle = "#aaa" ctx.fillStyle = "#aaa"
ctx.fillRect(-700, -1140, 1, 975)
} }
ctx.fillRect(-700, -1140, 1, 975)
toggle2.query(); toggle2.query();
// button2.draw(); // button2.draw();
@@ -4319,11 +4544,10 @@ const level = {
if (elevator2.isOn) { if (elevator2.isOn) {
elevator2.move(); elevator2.move();
ctx.fillStyle = "#444" ctx.fillStyle = "#444"
ctx.fillRect(-3540, -1720, 1, 740)
} else { } else {
ctx.fillStyle = "#aaa" ctx.fillStyle = "#aaa"
ctx.fillRect(-3540, -1720, 1, 740)
} }
ctx.fillRect(-3540, -1720, 1, 740)
ctx.fillStyle = "rgba(64,64,64,0.97)" //hidden section ctx.fillStyle = "rgba(64,64,64,0.97)" //hidden section
ctx.fillRect(-4450, -750, 800, 200) ctx.fillRect(-4450, -750, 800, 200)
@@ -4638,7 +4862,7 @@ const level = {
let elevator1, elevator2, elevator3 let elevator1, elevator2, elevator3
if (Math.random() < 0.5) { if (Math.random() < 0.5) {
isElevators = true isElevators = true
elevator1 = level.elevator(-1780, 500, 260, 40, 7, 0.0003) // elevator(x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) { elevator1 = level.elevator(-1780, 500, 260, 40, 7, 0.0003) // x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) {
elevator2 = level.elevator(820, 1300, 260, 40, 607, 0.0003) elevator2 = level.elevator(820, 1300, 260, 40, 607, 0.0003)
elevator3 = level.elevator(-2850, 1250, 160, 40, 600, 0.007) elevator3 = level.elevator(-2850, 1250, 160, 40, 600, 0.007)
if (simulation.isHorizontalFlipped) { if (simulation.isHorizontalFlipped) {
@@ -8132,7 +8356,7 @@ const level = {
} else { } else {
tech.addJunkTechToPool(0.49) tech.addJunkTechToPool(0.49)
} }
spawn.randomLevelBoss(x, y, ["historyBoss"]); // spawn.randomLevelBoss(x, y, ["historyBoss"]);
} }
} }
@@ -9664,11 +9888,11 @@ const level = {
b.removeAllGuns(); b.removeAllGuns();
b.giveGuns("grenades") b.giveGuns("grenades")
const elevator1 = level.elevator(550, -100, 180, 25, -840, 0.003, { up: 0.05, down: 0.2 }) // elevator(x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) { const elevator1 = level.elevator(550, -100, 180, 25, -840, 0.003, { up: 0.05, down: 0.2 }) // x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) {
elevator1.addConstraint(); elevator1.addConstraint();
const toggle1 = level.toggle(275, 0) //(x,y,isOn,isLockOn = true/false) const toggle1 = level.toggle(275, 0) //(x,y,isOn,isLockOn = true/false)
const elevator2 = level.elevator(1400, -950, 180, 25, -2400, 0.0025) // elevator(x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) { const elevator2 = level.elevator(1400, -950, 180, 25, -2400, 0.0025) // x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) {
elevator2.addConstraint(); elevator2.addConstraint();
const button2 = level.button(1000, -850) const button2 = level.button(1000, -850)

View File

@@ -344,9 +344,10 @@ const powerUps = {
powerUps.research.count += amount powerUps.research.count += amount
if (powerUps.research.count < 0) { if (powerUps.research.count < 0) {
powerUps.research.count = 0 powerUps.research.count = 0
} else {
simulation.makeTextLog(`powerUps.research.count <span class='color-symbol'>+=</span> ${amount}`) // <br>${powerUps.research.count}
} }
// else {
// simulation.makeTextLog(`powerUps.research.count <span class='color-symbol'>+=</span> ${amount}`) // <br>${powerUps.research.count}
// }
} }
if (tech.isRerollBots) { if (tech.isRerollBots) {
let delay = 0 let delay = 0

View File

@@ -1127,7 +1127,7 @@ const spawn = {
this.isInvulnerable = true this.isInvulnerable = true
if (this.damageReduction) this.startingDamageReduction = this.damageReduction if (this.damageReduction) this.startingDamageReduction = this.damageReduction
this.damageReduction = 0 this.damageReduction = 0
this.invulnerabilityCountDown = simulation.difficulty * 2 this.invulnerabilityCountDown = simulation.difficulty
} }
me.onDeath = function() { me.onDeath = function() {
this.isBuffBoss = false; this.isBuffBoss = false;
@@ -2020,7 +2020,7 @@ const spawn = {
this.cons2.length = -200; this.cons2.length = -200;
this.isInvulnerable = false this.isInvulnerable = false
this.invulnerabilityCountDown = 45 + Math.max(0, 70 - simulation.difficulty) this.invulnerabilityCountDown = 60 + Math.max(0, 70 - simulation.difficulty)
this.damageReduction = this.startingDamageReduction this.damageReduction = this.startingDamageReduction
for (let i = 0; i < this.babyList.length; i++) { for (let i = 0; i < this.babyList.length; i++) {
if (this.babyList[i].alive) this.babyList[i].damageReduction = this.startingDamageReduction if (this.babyList[i].alive) this.babyList[i].damageReduction = this.startingDamageReduction

View File

@@ -354,22 +354,15 @@ const tech = {
requires: "NOT EXPERIMENT MODE, at least 2 guns", requires: "NOT EXPERIMENT MODE, at least 2 guns",
effect() { effect() {
for (let i = b.inventory.length - 1; i > -1; i--) { for (let i = b.inventory.length - 1; i > -1; i--) {
//spawn a research for each gun const gunTechPool = [] //find gun tech for this gun
// powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
//find a gun tech for this gun
const gunTechPool = []
for (let j = 0, len = tech.tech.length; j < len; j++) { for (let j = 0, len = tech.tech.length; j < len; j++) {
// console.log(j, tech.tech[j].isGunTech, tech.tech[j].allowed(), !tech.tech[j].isJunk, !tech.tech[j].isBadRandomOption, tech.tech[j].count < tech.tech[j].maxCount) // console.log(j, tech.tech[j].isGunTech, tech.tech[j].allowed(), !tech.tech[j].isJunk, !tech.tech[j].isBadRandomOption, tech.tech[j].count < tech.tech[j].maxCount)
//set current gun to active so allowed works const originalActiveGunIndex = b.activeGun //set current gun to active so allowed works
const originalActiveGunIndex = b.activeGun
b.activeGun = b.inventory[i] //to make the .allowed work for guns that aren't active b.activeGun = b.inventory[i] //to make the .allowed work for guns that aren't active
if (tech.tech[j].isGunTech && tech.tech[j].allowed() && !tech.tech[j].isJunk && !tech.tech[j].isBadRandomOption && tech.tech[j].count < tech.tech[j].maxCount) { if (tech.tech[j].isGunTech && tech.tech[j].allowed() && !tech.tech[j].isJunk && !tech.tech[j].isBadRandomOption && tech.tech[j].count < tech.tech[j].maxCount) {
const regex = tech.tech[j].requires.search(b.guns[b.inventory[i]].name) //get string index of gun name const regex = tech.tech[j].requires.search(b.guns[b.inventory[i]].name) //get string index of gun name
const not = tech.tech[j].requires.search(' not ') //get string index of ' not ' const not = tech.tech[j].requires.search(' not ') //get string index of ' not '
//look for the gun name in the requirements, but the gun name needs to show up before the word ' not ' if (regex !== -1 && (not === -1 || not > regex)) gunTechPool.push(j) //look for the gun name in the requirements, but the gun name needs to show up before the word ' not '
if (regex !== -1 && (not === -1 || not > regex)) {
gunTechPool.push(j)
}
} }
b.activeGun = originalActiveGunIndex b.activeGun = originalActiveGunIndex
} }
@@ -1290,7 +1283,7 @@ const tech = {
{ {
name: "dynamo-bot", name: "dynamo-bot",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Robot' class="link">dynamo-bot</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Robot' class="link">dynamo-bot</a>`,
description: "a <strong class='color-bot'>bot</strong> <strong class='color-d'>damages</strong> mobs while it <strong>traces</strong> your path<br>regen <strong>6</strong> <strong class='color-f'>energy</strong> per second when it's near", description: "a <strong class='color-bot'>bot</strong> <strong class='color-d'>damages</strong> mobs while it <strong>traces</strong> your path<br>regen <strong>7</strong> <strong class='color-f'>energy</strong> per second when it's near",
maxCount: 9, maxCount: 9,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -1314,7 +1307,7 @@ const tech = {
{ {
name: "dynamo-bot upgrade", name: "dynamo-bot upgrade",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Robot' class="link">dynamo-bot upgrade</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Robot' class="link">dynamo-bot upgrade</a>`,
description: "<strong>convert</strong> your current bots to <strong>dynamo-bots</strong><br>increase regen to <strong>20</strong> <strong class='color-f'>energy</strong> per second", description: "<strong>convert</strong> your current bots to <strong>dynamo-bots</strong><br>increase regen to <strong>23</strong> <strong class='color-f'>energy</strong> per second",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 3, frequency: 3,
@@ -5634,6 +5627,53 @@ const tech = {
// tech.isRodAreaDamage = false; // tech.isRodAreaDamage = false;
// } // }
// }, // },
{
name: "optical amplifier",
description: "gain <strong>3</strong> random <strong class='color-laser'>laser</strong> <strong class='color-g'>gun</strong><strong class='color-m'>tech</strong><br><strong class='color-laser'>laser</strong> only turns <strong>off</strong> if you have no <strong class='color-f'>energy</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
isNonRefundable: true,
allowed() {
return tech.haveGunCheck("laser") && !tech.isPulseLaser
},
requires: "laser gun, not pulse",
effect() {
tech.isStuckOn = true
for (let j = 0; j < 3; j++) {
const names = ["laser diode", "free-electron laser", "relativistic momentum", "specular reflection", "diffraction grating", "diffuse beam", "output coupler", "slow light"]
//convert names into indexes
const options = []
for (let i = 0; i < names.length; i++) {
for (let k = 0; k < tech.tech.length; k++) {
if (tech.tech[k].name === names[i]) {
options.push(k)
break
}
}
}
//remove options that don't meet requirements
for (let i = options.length - 1; i > -1; i--) {
const index = options[i]
if (!(tech.tech[index].count < tech.tech[index].maxCount) || !tech.tech[index].allowed()) {
options.splice(i, 1);
}
}
//pick one option
if (options.length) {
const index = options[Math.floor(Math.random() * options.length)]
simulation.makeTextLog(`<span class='color-var'>tech</span>.giveTech("<span class='color-text'>${tech.tech[index].name}</span>") <em>//optical amplifier</em>`);
tech.giveTech(index)
}
}
},
remove() {
tech.isStuckOn = false
}
},
{ {
name: "laser diode", name: "laser diode",
description: "all <strong class='color-laser'>lasers</strong> drain <strong>30%</strong> less <strong class='color-f'>energy</strong><br><em>affects laser-gun, laser-bot, laser-mines, pulse</em>", description: "all <strong class='color-laser'>lasers</strong> drain <strong>30%</strong> less <strong class='color-f'>energy</strong><br><em>affects laser-gun, laser-bot, laser-mines, pulse</em>",
@@ -5844,9 +5884,9 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.isWideLaser && tech.laserDamage === 0.17 return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.isWideLaser && tech.laserDamage === 0.17 && !tech.isStuckOn
}, },
requires: "laser gun, not specular reflection, diffuse, free-electron laser", requires: "laser gun, not specular reflection, diffuse, free-electron laser, optical amplifier",
effect() { effect() {
tech.isPulseLaser = true; tech.isPulseLaser = true;
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
@@ -8147,7 +8187,7 @@ const tech = {
allowed() { return true }, allowed() { return true },
requires: "", requires: "",
effect() { effect() {
window.open('https://www.youtube.com/results?search_query=music', '_blank') window.open('https://www.youtube.com/watch?v=lEbHeSdmS-k&list=PL9Z5wjoBiPKEDhwCW2RN-VZoCpmhIojdn', '_blank')
}, },
remove() {} remove() {}
}, },

View File

@@ -1,26 +1,45 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
new map reservoir - still in development, but putting it out for feedback
tech: optical amplifier - get 3 random laser tech, but you can't turn off your laser until you run out of energy
slow light - lasers are slightly closer together at higher stacks of this tech
research power ups no longer log to the "in game console" to prevent spam
dynamo-bots give 6->7 more energy (upgraded 20->23)
some Boss invulnerability times are very slightly shorter
music tech now links to actual n-gon music
https://www.youtube.com/watch?v=lEbHeSdmS-k&list=PL9Z5wjoBiPKEDhwCW2RN-VZoCpmhIojdn
******************************************************** TODO ******************************************************** ******************************************************** TODO ********************************************************
set damage reduction equal to how much mana you have below 95 reversed version of reservoir level, start at top and press buttons to lower slime
override all other harm reduction effects?
make shields not able to get radioactive tech immune to harm after mob kill
require no other mob kill tech?
cloaking field tech?
final boss invulnerability
until mobs are cleared?
in between phases
for all of one phase
JUNK tech - do something to the mob display health method
new platform element, spring
toggle to on when player touches platform
platform extends in any direction
start toggled elevators in the high or middle state, not low
wormhole tech - pause while placing the wormhole wormhole tech - pause while placing the wormhole
tech requires cache - ammo automatically regenerates every second, ammo is capped even lower
new level climb tech - set damage reduction equal to how much mana you have below 95
3 vertical climb sections override all other harm reduction effects?
use vanish elements
ruins: mobs can see you too easily at the start
vanish element: vanish element:
grow as it returns? grow as it returns?
option to shrink in vertical
pull bullets back to player with crouch/field pull bullets back to player with crouch/field
bullets type?: drones, spores, missiles, bullets type?: drones, spores, missiles,
@@ -37,6 +56,9 @@ training
reset progress to zero if you clear all training levels reset progress to zero if you clear all training levels
maybe only save progress if you made if past the trainingHeal level 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 make the training button more obvious if the account has only played 1-2 times
larger?
position?
animated text?
uses the lore voice/text code? uses the lore voice/text code?
replace all mob clear triggers with button triggers? replace all mob clear triggers with button triggers?
tutorial rooms: tutorial rooms: