tech supertemporal - fire your super balls at the same place in space, but delayed in time

super ball starts with 3 not 4 balls, but they are is 25% larger, 10% faster, and 25% lower divergence
  (this makes adding more balls much stronger)
gun - super balls has 15% less ammo

standing wave harmonics - still has no block cooldown, but now it has a cooldown for how often it can drain energy
  this should make rapidly blocking drain upto 10x less energy
  base blocking cost have increased by 25%

wormhole gets 10% duplication (was 7%)
ice-IX does 15% more damage

new level element - toggle(x, y, isLockOn = false)
  similar to a button but doesn't require a block
  used on the level highrise
  can toggle "off and on" or "lock on"
This commit is contained in:
landgreen
2021-06-15 05:58:28 -07:00
parent a285375e2b
commit fe05a57a13
7 changed files with 311 additions and 143 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -1944,7 +1944,7 @@ const b = {
friction: 0, friction: 0,
frictionAir: 0.10, frictionAir: 0.10,
restitution: 0.3, restitution: 0.3,
dmg: 0.33, //damage done in addition to the damage from momentum dmg: 0.38, //damage done in addition to the damage from momentum
lookFrequency: 14 + Math.floor(8 * Math.random()), lookFrequency: 14 + Math.floor(8 * Math.random()),
endCycle: simulation.cycle + 140 * tech.isBulletsLastLonger, endCycle: simulation.cycle + 140 * tech.isBulletsLastLonger,
classType: "bullet", classType: "bullet",
@@ -3366,15 +3366,15 @@ const b = {
// makeNeedle(m.angle - spread) // makeNeedle(m.angle - spread)
}, },
fireRivets() { fireRivets() {
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 23 : 17) * b.fireCD); // cool down m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 23 : 15) * b.fireCD); // cool down
const me = bullet.length; const me = bullet.length;
const size = tech.rivetSize * 7 const size = tech.rivetSize * 7.5
bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 5 * size, size, b.fireAttributes(m.angle)); bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 5 * size, size, b.fireAttributes(m.angle));
bullet[me].dmg = tech.isNailRadiation ? 0 : 2.75 bullet[me].dmg = tech.isNailRadiation ? 0 : 2.75
Matter.Body.setDensity(bullet[me], 0.002); Matter.Body.setDensity(bullet[me], 0.002);
World.add(engine.world, bullet[me]); //add bullet to world World.add(engine.world, bullet[me]); //add bullet to world
const SPEED = m.crouch ? 55 : 46 const SPEED = m.crouch ? 55 : 44
Matter.Body.setVelocity(bullet[me], { Matter.Body.setVelocity(bullet[me], {
x: SPEED * Math.cos(m.angle), x: SPEED * Math.cos(m.angle),
y: SPEED * Math.sin(m.angle) y: SPEED * Math.sin(m.angle)
@@ -3613,14 +3613,13 @@ const b = {
name: "super balls", name: "super balls",
description: "fire <strong>four</strong> balls in a wide arc<br>balls <strong>bounce</strong> with no momentum loss", description: "fire <strong>four</strong> balls in a wide arc<br>balls <strong>bounce</strong> with no momentum loss",
ammo: 0, ammo: 0,
ammoPack: 13, ammoPack: 11,
have: false, have: false,
// num: 5, // num: 5,
do() {}, do() {},
fire() { fireOne() {
const SPEED = m.crouch ? 43 : 32 const SPEED = m.crouch ? 43 : 36
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 23 : 15) * b.fireCD); // cool down m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 23 : 15) * b.fireCD); // cool down
if (tech.oneSuperBall) {
let dir = m.angle let dir = m.angle
const me = bullet.length; const me = bullet.length;
bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, 21 * tech.bulletSize, b.fireAttributes(dir, false)); bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, 21 * tech.bulletSize, b.fireAttributes(dir, false));
@@ -3640,17 +3639,19 @@ const b = {
bullet[me].beforeDmg = function(who) { bullet[me].beforeDmg = function(who) {
mobs.statusStun(who, 180) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds) mobs.statusStun(who, 180) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds)
if (tech.isIncendiary) { if (tech.isIncendiary) {
b.explosion(this.position, this.mass * 265); //makes bullet do explosive damage at end b.explosion(this.position, this.mass * 285); //makes bullet do explosive damage at end
this.endCycle = 0 this.endCycle = 0
} }
}; };
} else { },
b.muzzleFlash(20); fireMulti() {
const SPREAD = m.crouch ? 0.08 : 0.15 const SPEED = m.crouch ? 43 : 36
m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 23 : 15) * b.fireCD); // cool down
const SPREAD = m.crouch ? 0.08 : 0.13
let dir = m.angle - SPREAD * (tech.superBallNumber - 1) / 2; let dir = m.angle - SPREAD * (tech.superBallNumber - 1) / 2;
for (let i = 0; i < tech.superBallNumber; i++) { for (let i = 0; i < tech.superBallNumber; i++) {
const me = bullet.length; const me = bullet.length;
bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, 9 * tech.bulletSize, b.fireAttributes(dir, false)); bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, 11 * tech.bulletSize, b.fireAttributes(dir, false));
World.add(engine.world, bullet[me]); //add bullet to world World.add(engine.world, bullet[me]); //add bullet to world
Matter.Body.setVelocity(bullet[me], { Matter.Body.setVelocity(bullet[me], {
x: SPEED * Math.cos(dir), x: SPEED * Math.cos(dir),
@@ -3666,14 +3667,59 @@ const b = {
}; };
bullet[me].beforeDmg = function() { bullet[me].beforeDmg = function() {
if (tech.isIncendiary) { if (tech.isIncendiary) {
b.explosion(this.position, this.mass * 330 + 60 * Math.random()); //makes bullet do explosive damage at end b.explosion(this.position, this.mass * 350 + 60 * Math.random()); //makes bullet do explosive damage at end
this.endCycle = 0 this.endCycle = 0
} }
}; };
dir += SPREAD; dir += SPREAD;
} }
},
fireQueue() {
const SPEED = m.crouch ? 43 : 36
const dir = m.angle
const x = m.pos.x + 30 * Math.cos(m.angle)
const y = m.pos.y + 30 * Math.sin(m.angle)
const delay = Math.floor((m.crouch ? 18 : 12) * b.fireCD)
m.fireCDcycle = m.cycle + delay; // cool down
for (let i = 0; i < tech.superBallNumber; i++) {
setTimeout(() => {
if (!simulation.paused) {
const me = bullet.length;
bullet[me] = Bodies.polygon(x, y, 12, 11 * tech.bulletSize, b.fireAttributes(dir, false));
World.add(engine.world, bullet[me]); //add bullet to world
Matter.Body.setVelocity(bullet[me], {
x: SPEED * Math.cos(dir),
y: SPEED * Math.sin(dir)
});
bullet[me].endCycle = simulation.cycle + Math.floor(330 * tech.isBulletsLastLonger);
bullet[me].minDmgSpeed = 0;
bullet[me].restitution = 0.99;
bullet[me].friction = 0;
bullet[me].do = function() {
this.force.y += this.mass * 0.001;
};
bullet[me].beforeDmg = function() {
if (tech.isIncendiary) {
b.explosion(this.position, this.mass * 350 + 60 * Math.random()); //makes bullet do explosive damage at end
this.endCycle = 0
} }
};
m.fireCDcycle = m.cycle + delay; // cool down
} }
}, 50 * i + 100);
}
},
chooseFireMethod() { //set in simulation.startGame
if (tech.oneSuperBall) {
this.fire = this.fireOne
} else if (tech.superBallDelay) {
this.fire = this.fireQueue
} else {
this.fire = this.fireMulti
}
},
fire() {}
}, { }, {
name: "wave beam", name: "wave beam",
description: "emit a <strong>wave packet</strong> of oscillating particles<br>that propagates through <strong>solids</strong>", description: "emit a <strong>wave packet</strong> of oscillating particles<br>that propagates through <strong>solids</strong>",

View File

@@ -15,21 +15,20 @@ const level = {
// simulation.zoomScale = 1000; // simulation.zoomScale = 1000;
// simulation.setZoom(); // simulation.setZoom();
// simulation.enableConstructMode() //used to build maps in testing mode // simulation.enableConstructMode() //used to build maps in testing mode
// m.setField("negative mass field") // simulation.isHorizontalFlipped = true
// level.difficultyIncrease(30)
// m.setField("standing wave harmonics")
// tech.giveTech("spherical harmonics")
// for (let i = 0; i < 9; i++) tech.giveTech("spherical harmonics") // for (let i = 0; i < 9; i++) tech.giveTech("spherical harmonics")
// b.giveGuns("laser") // b.giveGuns("super balls")
// tech.isExplodeRadio = true // tech.isExplodeRadio = true
// tech.giveTech("Z-pinch") // tech.giveTech("Z-pinch")
// tech.giveTech("MACHO") // tech.giveTech("MACHO")
// tech.giveTech("potential well") // tech.giveTech("supertemporal")
// for (let i = 0; i < 3; i++) tech.giveTech("packet length") // for (let i = 0; i < 3; i++) tech.giveTech("packet length")
// for (let i = 0; i < 3; i++) tech.giveTech("propagation") // for (let i = 0; i < 3; i++) tech.giveTech("propagation")
// for (let i = 0; i < 3; i++) tech.giveTech("bound state") // for (let i = 0; i < 3; i++) tech.giveTech("bound state")
// for (let i = 0; i < 9; i++) tech.giveTech("WIMPs") // for (let i = 0; i < 9; i++) tech.giveTech("WIMPs")
// tech.giveTech("attract")
// level.difficultyIncrease(30)
// simulation.isHorizontalFlipped = true
// tech.isFlyFaster = true
level.intro(); //starting level level.intro(); //starting level
// level.testing(); //not in rotation, used for testing // level.testing(); //not in rotation, used for testing
@@ -260,7 +259,7 @@ const level = {
}, },
addToWorld() { //needs to be run to put bodies into the world addToWorld() { //needs to be run to put bodies into the world
for (let i = 0; i < body.length; i++) { for (let i = 0; i < body.length; i++) {
if (body[i] !== m.holdingTarget) { if (body[i] !== m.holdingTarget && !body[i].isNoSetCollision) {
body[i].collisionFilter.category = cat.body; body[i].collisionFilter.category = cat.body;
body[i].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet body[i].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet
} }
@@ -548,6 +547,71 @@ const level = {
composite[composite.length] = rotor composite[composite.length] = rotor
return rotor return rotor
}, },
toggle(x, y, isLockOn = false) {
spawn.mapVertex(x + 65, y + 2, "70 10 -70 10 -40 -10 40 -10");
map[map.length - 1].restitution = 0;
map[map.length - 1].friction = 1;
map[map.length - 1].frictionStatic = 1;
spawn.bodyRect(x, y, 125, 15) //Portal platform
let flip = body[body.length - 1];
flip.isNoSetCollision = true //prevents collision form being rewritten in level.addToWorld
flip.collisionFilter.category = cat.body
flip.collisionFilter.mask = cat.player | cat.body
flip.isNotHoldable = true
flip.frictionAir = 0.01
flip.restitution = 0
Matter.Body.setDensity(flip, 0.003)
Matter.Body.setAngle(flip, (-0.25 - 0.5) * Math.PI)
setTimeout(function() {}, 100);
cons[cons.length] = Constraint.create({
pointA: {
x: x + 65,
y: y
},
bodyB: flip,
stiffness: 1,
length: 0
});
World.add(engine.world, [cons[cons.length - 1]]);
return {
flip: flip,
isOn: false,
query() {
const limit = {
right: (-0.25 - 0.5) * Math.PI,
left: (0.25 - 0.5) * Math.PI
}
if (flip.angle < limit.right) {
Matter.Body.setAngle(flip, limit.right)
Matter.Body.setAngularVelocity(flip, 0);
if (!isLockOn) this.isOn = false
} else if (flip.angle > limit.left) {
Matter.Body.setAngle(flip, limit.left)
Matter.Body.setAngularVelocity(flip, 0);
this.isOn = true
}
if (this.isOn) {
ctx.beginPath();
ctx.moveTo(flip.vertices[0].x, flip.vertices[0].y);
for (let j = 1; j < flip.vertices.length; j++) {
ctx.lineTo(flip.vertices[j].x, flip.vertices[j].y);
}
ctx.lineTo(flip.vertices[0].x, flip.vertices[0].y);
ctx.fillStyle = "#3df"
ctx.fill();
ctx.lineWidth = 1;
ctx.strokeStyle = simulation.draw.bodyStroke;
ctx.stroke();
}
},
}
},
button(x, y, width = 126) { button(x, y, width = 126) {
spawn.mapVertex(x + 65, y + 2, "100 10 -100 10 -70 -10 70 -10"); spawn.mapVertex(x + 65, y + 2, "100 10 -100 10 -70 -10 70 -10");
map[map.length - 1].restitution = 0; map[map.length - 1].restitution = 0;
@@ -1109,17 +1173,19 @@ const level = {
spawn.mapRect(475, -25, 25, 50); //edge shelf spawn.mapRect(475, -25, 25, 50); //edge shelf
}, },
testing() { testing() {
const button = level.button(200, -700) // const button = level.button(200, -700)
const toggle = level.toggle(200, -700)
level.custom = () => { level.custom = () => {
button.query(); // button.draw();
button.draw();
ctx.fillStyle = "rgba(0,255,255,0.1)"; ctx.fillStyle = "rgba(0,255,255,0.1)";
ctx.fillRect(6400, -550, 300, 350); ctx.fillRect(6400, -550, 300, 350);
level.playerExitCheck(); level.playerExitCheck();
level.exit.draw(); level.exit.draw();
level.enter.draw(); level.enter.draw();
}; };
level.customTopLayer = () => {}; level.customTopLayer = () => {
toggle.query();
};
level.setPosToSpawn(0, -750); //normal spawn level.setPosToSpawn(0, -750); //normal spawn
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
@@ -1171,7 +1237,7 @@ const level = {
// spawn.grower(1900, -500) // spawn.grower(1900, -500)
// spawn.pulsarBoss(1900, -500) // spawn.pulsarBoss(1900, -500)
// spawn.shooterBoss(1900, -500) // spawn.shooterBoss(1900, -500)
spawn.historyBoss(1200, -500) // spawn.historyBoss(1200, -500)
// spawn.laserTargetingBoss(1600, -400) // spawn.laserTargetingBoss(1600, -400)
// spawn.striker(1600, -500) // spawn.striker(1600, -500)
// spawn.laserTargetingBoss(1700, -120) // spawn.laserTargetingBoss(1700, -120)
@@ -2018,7 +2084,7 @@ const level = {
level.enter.draw(); level.enter.draw();
}; };
level.customTopLayer = () => { level.customTopLayer = () => {
ctx.fillStyle = "rgba(0,20,40,0.2)" ctx.fillStyle = "rgba(0,20,40,0.25)"
ctx.fillRect(-250, -400, 1800, 775) ctx.fillRect(-250, -400, 1800, 775)
ctx.fillRect(1800, -275, 850, 775) ctx.fillRect(1800, -275, 850, 775)
ctx.fillRect(5200, 125, 450, 200) ctx.fillRect(5200, 125, 450, 200)
@@ -2073,18 +2139,18 @@ const level = {
//tall platform //tall platform
spawn.mapVertex(1125, -450, "325 0 250 80 -250 80 -325 0 -250 -80 250 -80"); //base spawn.mapVertex(1125, -450, "325 0 250 80 -250 80 -325 0 -250 -80 250 -80"); //base
spawn.mapRect(150, -500, 1400, 100); //far left starting ceiling spawn.mapRect(150, -500, 1410, 100); //far left starting ceiling
spawn.mapRect(625, -2450, 1000, 50); //super high shade spawn.mapRect(625, -2450, 1000, 50); //super high shade
spawn.bodyRect(1300, -3600, 150, 150); //shield from laser spawn.bodyRect(1300, -3600, 150, 150); //shield from laser
//tall platform //tall platform
spawn.mapVertex(2225, -250, "325 0 250 80 -250 80 -325 0 -250 -80 250 -80"); //base spawn.mapVertex(2225, -250, "325 0 250 80 -250 80 -325 0 -250 -80 250 -80"); //base
spawn.mapRect(1725, -2800, 1000, 50); //super high shade spawn.mapRect(1725, -2800, 1000, 50); //super high shade
spawn.mapRect(1800, -300, 850, 100); //far left starting ceiling spawn.mapRect(1790, -300, 870, 100); //far left starting ceiling
spawn.bodyRect(2400, -2950, 150, 150); //shield from laser spawn.bodyRect(2400, -2950, 150, 150); //shield from laser
//tall platform //tall platform
spawn.mapVertex(3350, 200, "400 0 -400 0 -275 -275 275 -275"); //base spawn.mapVertex(3350, 175, "425 0 -425 0 -275 -300 275 -300"); //base
spawn.bodyRect(3400, -150, 150, 150); spawn.bodyRect(3350, -150, 200, 120);
spawn.mapRect(2850, -3150, 1000, 50); //super high shade spawn.mapRect(2850, -3150, 1000, 50); //super high shade
spawn.bodyRect(3675, -3470, 525, 20); //plank spawn.bodyRect(3675, -3470, 525, 20); //plank
spawn.bodyRect(3600, -3450, 200, 300); //plank support block spawn.bodyRect(3600, -3450, 200, 300); //plank support block
@@ -2165,7 +2231,7 @@ const level = {
}; };
level.customTopLayer = () => { level.customTopLayer = () => {
elevator.move() elevator.move()
ctx.fillStyle = "rgba(0,20,40,0.2)" ctx.fillStyle = "rgba(0,20,40,0.25)"
ctx.fillRect(250 - 1800, -400, 1800, 775) ctx.fillRect(250 - 1800, -400, 1800, 775)
ctx.fillRect(-1800 - 850, -275, 850, 775) ctx.fillRect(-1800 - 850, -275, 850, 775)
ctx.fillRect(-5200 - 450, 125, 450, 200) ctx.fillRect(-5200 - 450, 125, 450, 200)
@@ -2738,10 +2804,14 @@ 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.007
elevator1.addConstraint(); elevator1.addConstraint();
const button1 = level.button(-500, -200) // const button1 = level.button(-500, -200)
const toggle1 = level.toggle(-500, -200) //(x,y,isLockOn = true/false)
const elevator2 = level.elevator(-3630, -1000, 180, 25, -1740) //, 0.007 const elevator2 = level.elevator(-3630, -1000, 180, 25, -1740) //, 0.007
elevator2.addConstraint(); elevator2.addConstraint();
const button2 = level.button(-3100, -1330) // const button2 = level.button(-3100, -1330)
const toggle2 = level.toggle(-3100, -1330) //(x,y,isLockOn = true/false)
level.custom = () => { level.custom = () => {
// ctx.fillStyle = "#d0d0d2" // ctx.fillStyle = "#d0d0d2"
@@ -2755,9 +2825,9 @@ const level = {
level.enter.draw(); level.enter.draw();
}; };
level.customTopLayer = () => { level.customTopLayer = () => {
button1.query(); // button1.draw();
button1.draw(); toggle1.query();
if (button1.isUp) { if (!toggle1.isOn) {
if (elevator1.isOn) { if (elevator1.isOn) {
elevator1.isOn = false elevator1.isOn = false
elevator1.frictionAir = 0.2 elevator1.frictionAir = 0.2
@@ -2778,9 +2848,9 @@ const level = {
ctx.fillRect(-700, -1140, 1, 975) ctx.fillRect(-700, -1140, 1, 975)
} }
button2.query(); toggle2.query();
button2.draw(); // button2.draw();
if (button2.isUp) { if (!toggle2.isOn) {
if (elevator2.isOn) { if (elevator2.isOn) {
elevator2.isOn = false elevator2.isOn = false
elevator2.frictionAir = 0.2 elevator2.frictionAir = 0.2
@@ -2874,7 +2944,7 @@ const level = {
spawn.mapRect(-4450, -600, 2300, 750); spawn.mapRect(-4450, -600, 2300, 750);
spawn.mapRect(-2225, -450, 175, 550); spawn.mapRect(-2225, -450, 175, 550);
// spawn.mapRect(-2600, -975, 450, 50); // spawn.mapRect(-2600, -975, 450, 50);
spawn.mapRect(-3425, -1325, 525, 50); spawn.mapRect(-3425, -1325, 525, 75);
spawn.mapRect(-3425, -2200, 525, 50); spawn.mapRect(-3425, -2200, 525, 50);
spawn.mapRect(-2600, -1700, 450, 50); spawn.mapRect(-2600, -1700, 450, 50);
// spawn.mapRect(-2600, -2450, 450, 50); // spawn.mapRect(-2600, -2450, 450, 50);
@@ -2944,17 +3014,12 @@ const level = {
// boost1.boostBounds.max.x = -boost1.boostBounds.max.x + 100 // boost1.boostBounds.max.x = -boost1.boostBounds.max.x + 100
level.setPosToSpawn(300, -700); //-x level.setPosToSpawn(300, -700); //-x
elevator1.holdX = -elevator1.holdX // flip the elevator horizontally elevator1.holdX = -elevator1.holdX // flip the elevator horizontally
elevator2.removeConstraint(); elevator1.removeConstraint();
elevator2.addConstraint(); elevator1.addConstraint();
elevator2.holdX = -elevator2.holdX // flip the elevator horizontally elevator2.holdX = -elevator2.holdX // flip the elevator horizontally
elevator2.removeConstraint(); elevator2.removeConstraint();
elevator2.addConstraint(); elevator2.addConstraint();
button1.min.x = -button1.min.x - 126 // flip the button horizontally
button1.max.x = -button1.max.x + 126 // flip the button horizontally
button2.min.x = -button2.min.x - 126 // flip the button horizontally
button2.max.x = -button2.max.x + 126 // flip the button horizontally
level.custom = () => { level.custom = () => {
ctx.fillStyle = "#cff" //exit ctx.fillStyle = "#cff" //exit
ctx.fillRect(4425 - 425, -3050, 425, 275) ctx.fillRect(4425 - 425, -3050, 425, 275)
@@ -2963,9 +3028,8 @@ const level = {
level.enter.draw(); level.enter.draw();
}; };
level.customTopLayer = () => { level.customTopLayer = () => {
button1.query(); toggle1.query();
button1.draw(); if (!toggle1.isOn) {
if (button1.isUp) {
if (elevator1.isOn) { if (elevator1.isOn) {
elevator1.isOn = false elevator1.isOn = false
elevator1.frictionAir = 0.2 elevator1.frictionAir = 0.2
@@ -2986,9 +3050,8 @@ const level = {
ctx.fillRect(700 - 1, -1140, 1, 975) ctx.fillRect(700 - 1, -1140, 1, 975)
} }
button2.query(); toggle2.query();
button2.draw(); if (!toggle2.isOn) {
if (button2.isUp) {
if (elevator2.isOn) { if (elevator2.isOn) {
elevator2.isOn = false elevator2.isOn = false
elevator2.frictionAir = 0.2 elevator2.frictionAir = 0.2
@@ -3038,7 +3101,7 @@ const level = {
}; };
level.customTopLayer = () => { level.customTopLayer = () => {
ctx.fillStyle = "rgba(0,0,0,0.1)"; //shadows and lights ctx.fillStyle = "rgba(0,0,0,0.15)"; //shadows and lights
ctx.beginPath() ctx.beginPath()
ctx.moveTo(-1800, -500) ctx.moveTo(-1800, -500)
ctx.lineTo(-910, -500) //3rd floor light ctx.lineTo(-910, -500) //3rd floor light
@@ -3125,7 +3188,7 @@ const level = {
isElevators = true isElevators = true
elevator1 = level.elevator(-1780, 500, 260, 40, 7, 0.0003) elevator1 = level.elevator(-1780, 500, 260, 40, 7, 0.0003)
elevator2 = level.elevator(820, 1300, 260, 40, 607, 0.0003) elevator2 = level.elevator(820, 1300, 260, 40, 607, 0.0003)
elevator3 = level.elevator(-2755, 1260, 160, 40, 1000, 0.006) elevator3 = level.elevator(-2755, 1260, 160, 40, 850, 0.003)
spawn.bodyRect(-2375, 1300, 100, 100); spawn.bodyRect(-2375, 1300, 100, 100);
spawn.bodyRect(-2325, 1250, 50, 50); spawn.bodyRect(-2325, 1250, 50, 50);
spawn.bodyRect(-2275, 1350, 125, 50); spawn.bodyRect(-2275, 1350, 125, 50);
@@ -3291,7 +3354,7 @@ const level = {
}; };
} }
level.customTopLayer = () => { level.customTopLayer = () => {
ctx.fillStyle = "rgba(0,0,0,0.1)"; //shadows and lights ctx.fillStyle = "rgba(0,0,0,0.15)"; //shadows and lights
ctx.beginPath() ctx.beginPath()
ctx.moveTo(1800, -500) ctx.moveTo(1800, -500)
ctx.lineTo(910, -500) //3rd floor light ctx.lineTo(910, -500) //3rd floor light

View File

@@ -1276,11 +1276,7 @@ const m = {
} }
} }
}, },
pushMass(who) { pushMass(who, fieldBlockCost = (0.025 + Math.sqrt(who.mass) * Vector.magnitude(Vector.sub(who.velocity, player.velocity)) * 0.002) * m.fieldShieldingScale) {
const speed = Vector.magnitude(Vector.sub(who.velocity, player.velocity))
const fieldBlockCost = (0.025 + Math.sqrt(who.mass) * speed * 0.002) * m.fieldShieldingScale;
const unit = Vector.normalise(Vector.sub(player.position, who.position))
if (m.energy > fieldBlockCost * 0.2) { //shield needs at least some of the cost to block if (m.energy > fieldBlockCost * 0.2) { //shield needs at least some of the cost to block
m.energy -= fieldBlockCost m.energy -= fieldBlockCost
if (m.energy < 0) m.energy = 0; if (m.energy < 0) m.energy = 0;
@@ -1292,6 +1288,7 @@ const m = {
for (let i = 0; i < tech.blockingIce; i++) b.iceIX(10, m.angle + Math.random() - 0.5, m.pos) for (let i = 0; i < tech.blockingIce; i++) b.iceIX(10, m.angle + Math.random() - 0.5, m.pos)
} }
} }
const unit = Vector.normalise(Vector.sub(player.position, who.position))
if (tech.blockDmg) { if (tech.blockDmg) {
who.damage(tech.blockDmg * b.dmgScale) who.damage(tech.blockDmg * b.dmgScale)
//draw electricity //draw electricity
@@ -1364,15 +1361,6 @@ const m = {
} }
} }
}, },
pushMobs360(range) { // find mobs in range in any direction
for (let i = 0, len = mob.length; i < len; ++i) {
if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < range && !mob[i].isShielded) {
// && Matter.Query.ray(map, mob[i].position, m.pos).length === 0
mob[i].locatePlayer();
m.pushMass(mob[i]);
}
}
},
lookForPickUp() { //find body to pickup lookForPickUp() { //find body to pickup
if (m.energy > m.fieldRegen) m.energy -= m.fieldRegen; if (m.energy > m.fieldRegen) m.energy -= m.fieldRegen;
const grabbing = { const grabbing = {
@@ -1505,15 +1493,14 @@ const m = {
}, },
{ {
name: "standing wave harmonics", name: "standing wave harmonics",
description: "<strong>3</strong> oscillating <strong>shields</strong> are permanently active<br><strong>deflecting</strong> drains <strong class='color-f'>energy</strong> with no <strong>cool down</strong><br><strong>deflecting</strong> has <strong>50%</strong> less <strong>recoil</strong>", //<strong class='color-harm'>harm</strong> and description: "<strong>3</strong> oscillating <strong>shields</strong> are permanently active<br><strong>deflecting</strong> protects you in every <strong>direction</strong><br><strong>deflecting</strong> has <strong>50%</strong> less <strong>recoil</strong>", //drains <strong class='color-f'>energy</strong>
drainCD: 0,
effect: () => { effect: () => {
// m.fieldHarmReduction = 0.80;
m.fieldBlockCD = 0; m.fieldBlockCD = 0;
// m.fieldHarmReduction = 0.75;
m.blockingRecoil = 2 //4 is normal m.blockingRecoil = 2 //4 is normal
m.fieldRange = 175 m.fieldRange = 175
m.fieldShieldingScale = Math.pow(0.5, (tech.harmonics - 3)) m.fieldShieldingScale = 1.3 * Math.pow(0.6, (tech.harmonics - 2))
m.harmonicRadius = 1 //for smoothing function when player holds mouse (for harmonicAtomic)
m.harmonic3Phase = () => { //normal standard 3 different 2-d circles m.harmonic3Phase = () => { //normal standard 3 different 2-d circles
const fieldRange1 = (0.7 + 0.3 * Math.sin(m.cycle / 23)) * m.fieldRange * m.harmonicRadius const fieldRange1 = (0.7 + 0.3 * Math.sin(m.cycle / 23)) * m.fieldRange * m.harmonicRadius
const fieldRange2 = (0.63 + 0.37 * Math.sin(m.cycle / 37)) * m.fieldRange * m.harmonicRadius const fieldRange2 = (0.63 + 0.37 * Math.sin(m.cycle / 37)) * m.fieldRange * m.harmonicRadius
@@ -1529,12 +1516,24 @@ const m = {
ctx.beginPath(); ctx.beginPath();
ctx.arc(m.pos.x, m.pos.y, fieldRange3, 0, 2 * Math.PI); ctx.arc(m.pos.x, m.pos.y, fieldRange3, 0, 2 * Math.PI);
ctx.fill(); ctx.fill();
m.pushMobs360(netfieldRange); //360 block
for (let i = 0, len = mob.length; i < len; ++i) {
if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < netfieldRange && !mob[i].isShielded) { // && Matter.Query.ray(map, mob[i].position, m.pos).length === 0
mob[i].locatePlayer();
if (this.drainCD > m.cycle) {
m.pushMass(mob[i], 0);
} else {
m.pushMass(mob[i]);
this.drainCD = m.cycle + 10
} }
}
}
}
m.harmonicRadius = 1 //for smoothing function when player holds mouse (for harmonicAtomic)
m.harmonicAtomic = () => { //several ellipses spinning about different axises m.harmonicAtomic = () => { //several ellipses spinning about different axises
const rotation = simulation.cycle * 0.002 const rotation = simulation.cycle * 0.002
const phase = simulation.cycle * 0.03 const phase = simulation.cycle * 0.03
const radius = m.fieldRange * m.harmonicRadius //+ 20 * Math.sin(m.cycle * 0.05) const radius = m.fieldRange * m.harmonicRadius
ctx.lineWidth = 1; ctx.lineWidth = 1;
ctx.strokeStyle = "rgba(110,170,200,0.9)" ctx.strokeStyle = "rgba(110,170,200,0.9)"
ctx.fillStyle = "rgba(110,170,200," + Math.min(0.7, m.energy * (0.13 + 0.15 * Math.random()) * (3 / tech.harmonics)) + ")"; ctx.fillStyle = "rgba(110,170,200," + Math.min(0.7, m.energy * (0.13 + 0.15 * Math.random()) * (3 / tech.harmonics)) + ")";
@@ -1545,7 +1544,18 @@ const m = {
ctx.fill(); ctx.fill();
ctx.stroke(); ctx.stroke();
} }
m.pushMobs360(radius); //360 block
for (let i = 0, len = mob.length; i < len; ++i) {
if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < radius && !mob[i].isShielded) { // && Matter.Query.ray(map, mob[i].position, m.pos).length === 0
mob[i].locatePlayer();
if (this.drainCD > m.cycle) {
m.pushMass(mob[i], 0);
} else {
m.pushMass(mob[i]);
this.drainCD = m.cycle + 10
}
}
}
} }
if (tech.harmonics === 2) { if (tech.harmonics === 2) {
m.harmonicShield = m.harmonic3Phase m.harmonicShield = m.harmonic3Phase
@@ -1577,8 +1587,6 @@ const m = {
} }
m.harmonicShield() m.harmonicShield()
} }
m.drawFieldMeter() m.drawFieldMeter()
} }
} }
@@ -2479,9 +2487,9 @@ const m = {
}, },
{ {
name: "wormhole", name: "wormhole",
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong class='color-worm'>wormholes</strong> attract <strong class='color-block'>blocks</strong> and power ups<br><strong>7%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong> description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong class='color-worm'>wormholes</strong> attract <strong class='color-block'>blocks</strong> and power ups<br><strong>10%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
effect: function() { effect: function() {
m.duplicateChance = 0.07 m.duplicateChance = 0.1
powerUps.setDo(); //needed after adjusting duplication chance powerUps.setDo(); //needed after adjusting duplication chance
m.hold = function() { m.hold = function() {

View File

@@ -540,6 +540,7 @@ const simulation = {
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
if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod() if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod()
if (b.guns[i].name === "nail gun") b.guns[i].chooseFireMethod() if (b.guns[i].name === "nail gun") b.guns[i].chooseFireMethod()
if (b.guns[i].name === "super balls") b.guns[i].chooseFireMethod()
} }
tech.dynamoBotCount = 0; tech.dynamoBotCount = 0;
tech.nailBotCount = 0; tech.nailBotCount = 0;

View File

@@ -3643,7 +3643,33 @@
tech.superBallNumber++ tech.superBallNumber++
}, },
remove() { remove() {
tech.superBallNumber = 4; tech.superBallNumber = 3;
}
},
{
name: "supertemporal",
description: "fire <strong>super ball</strong> from the same point in <strong>space</strong><br> but separated by <strong>0.1</strong> seconds in <strong>time</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
allowed() {
return tech.haveGunCheck("super balls") && !tech.oneSuperBall
},
requires: "super balls, but not the tech super ball or super duper",
effect() {
tech.superBallDelay = true
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "super balls") b.guns[i].chooseFireMethod()
}
},
remove() {
if (tech.superBallDelay) {
tech.superBallDelay = false;
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "super balls") b.guns[i].chooseFireMethod()
}
}
} }
}, },
{ {
@@ -3654,14 +3680,22 @@
count: 0, count: 0,
frequency: 2, frequency: 2,
allowed() { allowed() {
return tech.haveGunCheck("super balls") && tech.superBallNumber === 4 return tech.haveGunCheck("super balls") && tech.superBallNumber === 3 && !tech.superBallDelay
}, },
requires: "super balls, but not super duper", requires: "super balls, but not super duper or super queue",
effect() { effect() {
tech.oneSuperBall = true; tech.oneSuperBall = true;
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "super balls") b.guns[i].chooseFireMethod()
}
}, },
remove() { remove() {
if (tech.oneSuperBall) {
tech.oneSuperBall = false; tech.oneSuperBall = false;
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "super balls") b.guns[i].chooseFireMethod()
}
}
} }
}, },
{ {
@@ -4559,12 +4593,12 @@
requires: "standing wave harmonics", requires: "standing wave harmonics",
effect() { effect() {
tech.harmonics++ tech.harmonics++
m.fieldShieldingScale = Math.pow(0.6, (tech.harmonics - 2)) m.fieldShieldingScale = 1.3 * Math.pow(0.6, (tech.harmonics - 2))
m.harmonicShield = m.harmonicAtomic m.harmonicShield = m.harmonicAtomic
}, },
remove() { remove() {
tech.harmonics = 2 tech.harmonics = 2
m.fieldShieldingScale = Math.pow(0.6, (tech.harmonics - 2)) m.fieldShieldingScale = 1.3 * Math.pow(0.6, (tech.harmonics - 2))
m.harmonicShield = m.harmonic3Phase m.harmonicShield = m.harmonic3Phase
} }
}, },
@@ -6893,5 +6927,6 @@
isFallingDamage: null, isFallingDamage: null,
harmonics: null, harmonics: null,
isStandingWaveExpand: null, isStandingWaveExpand: null,
isBlockExplosion: null isBlockExplosion: null,
superBallDelay: null
} }

View File

@@ -1,24 +1,28 @@
******************************************************** NEXT PATCH ******************************************************** ******************************************************** NEXT PATCH ********************************************************
tech supertemporal - fire your super balls at the same place in space, but delayed in time
tech: WIMPs now requires wormhole super ball starts with 3 not 4 balls, but they are is 25% larger, 10% faster, and 25% lower divergence
gives 3-9 research now (was 2-3) (this makes adding more balls much stronger)
gun - super balls has 15% less ammo
tech: eddy current brake - is 15% larger and caps mob speeds at 20% slower standing wave harmonics - still has no block cooldown, but now it has a cooldown for how often it can drain energy
this should make rapidly blocking drain upto 10x less energy
base blocking cost have increased by 25%
wormhole gets 10% duplication (was 7%)
ice-IX does 15% more damage
new level element - toggle(x, y, isLockOn = false)
similar to a button but doesn't require a block
used on the level highrise
can toggle "off and on" or "lock on"
bug fixes
******************************************************** BUGS ******************************************************** ******************************************************** BUGS ********************************************************
sharing 1 stack of spherical harmonics doesn't activate visually
https://landgreen.github.io/sidescroller/index.html?&tech0=crystallizer&tech1=thermoelectric%20effect&tech2=thermoelectric%20effect&tech3=spherical%20harmonics&tech4=expansion&tech5=triple%20point&tech6=triple%20point&tech7=flux%20pinning&field=standing%20wave%20harmonics&difficulty=4&level=0&noPower=0
a couple times people have reported the final boss dropping extra bodies on death a couple times people have reported the final boss dropping extra bodies on death
figure out how to undo ship mode
if you die in ship mode it spawns with m.look set to non ship methods
look is set in many tech and in startGame
Why does micro-extruder lag so much Why does micro-extruder lag so much
blue triangle boss can move backwards and aim away from you if set up properly blue triangle boss can move backwards and aim away from you if set up properly
@@ -45,28 +49,39 @@ labs - procedural generation
1500px, 3000px per room 1500px, 3000px per room
room types room types
entrance - no mobs, starting power ups` entrance - no mobs, starting power ups`
exit - plenty of mobs exit - possible duplication boss spawn location
up, down - 2 paired rooms - boost, elevator, portal up, down - 2 paired rooms - boost, elevator, portal
boss - standard random boss spawns boss - standard random boss spawns
empty - just a dead end - possible duplication boss spawn location empty - a dead end
button - opens door to exit room button - like empty, but also has a switch that opens door to exit room
room ideas - room ideas -
gravity room low gravity room, controlled with a button?
portal room portal room
endlessly falling blocks down a slide, that the player has to climb up endlessly falling blocks down a slide, that the player has to climb up
portal + rotor + falling blocks = perpetual motion portal + rotor + falling blocks = perpetual motion
laser room laser room
slime radiation room slime radiation room
spinner room
make a switch level element
basically button, but go off and on when it hits player (or block?)
use a constrained body like a spinner
use offset constraint? like in vats
can this work?
check location of center of mass for on/off state
only collide with player, but run code that stops it from rotating too far
part of it is inside switch map element
player moving left go on, right go off as if they are pushing the switch in that direction ?
indicate on/off
angle of stick "light-switch"
with colors?
******************************************************** TODO ******************************************************** ******************************************************** TODO ********************************************************
standing wave harmonics - can block too often on the same mob if you push it into a corner standing wave harmonics - can block too often on the same mob if you push it into a corner
add a small cooldown add a cool down that only stops energy drain and iceIX, but still lets you block
return to normal knock back // 4
let standing wave harmonics get tech decorrelation let standing wave harmonics get tech decorrelation
* inductive coupling - sucks without catabolism, too much delayed gratification. should probably be bundled with transceiver chip
tech: cloaking field - decrease/increase cooldown on sneak attack? tech: cloaking field - decrease/increase cooldown on sneak attack?
decrease/increase damage bonus? decrease/increase damage bonus?
decrease/increase visual radius? decrease/increase visual radius?