diff --git a/js/bullet.js b/js/bullet.js
index 294f84a..fae5e81 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -4612,19 +4612,18 @@ const b = {
this.force.y += this.mass * tech.foamGravity; //gravity
if (tech.isFoamAttract) {
for (let i = 0, len = mob.length; i < len; i++) {
+ const range = Vector.magnitude(Vector.sub(mob[i].position, this.position))
if (
!mob[i].isBadTarget &&
- Vector.magnitude(Vector.sub(mob[i].position, this.position)) < 375 &&
mob[i].alive &&
- Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
- !mob[i].isInvulnerable
+ !mob[i].isInvulnerable &&
+ range < 500 &&
+ Matter.Query.ray(map, this.position, mob[i].position).length === 0
) {
- this.force = Vector.mult(Vector.normalise(Vector.sub(mob[i].position, this.position)), this.mass * 0.004)
- const slow = 0.9
- Matter.Body.setVelocity(this, {
- x: this.velocity.x * slow,
- y: this.velocity.y * slow
- });
+ const mag = 0.001 * Math.min(1, 200 / range)
+ this.force = Vector.mult(Vector.normalise(Vector.sub(mob[i].position, this.position)), this.mass * mag)
+ const slow = 0.98
+ Matter.Body.setVelocity(this, { x: this.velocity.x * slow, y: this.velocity.y * slow });
break
}
}
@@ -7509,10 +7508,7 @@ const b = {
bullet[me].do = function () {
function onCollide(that) {
that.collisionFilter.mask = 0; //non collide with everything
- Matter.Body.setVelocity(that, {
- x: 0,
- y: 0
- });
+ Matter.Body.setVelocity(that, { x: 0, y: 0 });
that.do = that.grow;
}
const mobCollisions = Matter.Query.collides(this, mob)
diff --git a/js/level.js b/js/level.js
index 1f9928b..208cc30 100644
--- a/js/level.js
+++ b/js/level.js
@@ -4,6 +4,7 @@ let cons = []; //all constraints between a point and a body
let consBB = []; //all constraints between two bodies
let composite = [] //rotors and other map elements that don't fit
const level = {
+ isEndlessFall: false,
defaultZoom: 1400,
onLevel: -1,
levelsCleared: 0,
@@ -15,27 +16,27 @@ const level = {
levels: [],
start() {
if (level.levelsCleared === 0) { //this code only runs on the first level
- // simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode
+ simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode
// simulation.isHorizontalFlipped = true
// tech.giveTech("performance")
// level.difficultyIncrease(3 * 4) //30 is near max on hard //60 is near max on why
// spawn.setSpawnList();
// spawn.setSpawnList();
- // m.maxHealth = m.health = 100
+ m.maxHealth = m.health = 100
// tech.isRerollDamage = true
// powerUps.research.changeRerolls(99999)
// m.immuneCycle = Infinity //you can't take damage
// tech.tech[297].frequency = 100
// m.couplingChange(10)
- // m.setField("standing wave") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole
+ // m.setField("wormhole") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole
// m.energy = 0
// simulation.molecularMode = 2
// m.damage(0.1);
// b.giveGuns("super balls") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
- // b.giveGuns("drones") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
- // b.guns[3].ammo = 100000000
+ // b.giveGuns("foam") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
+ // b.guns[8].ammo = 100000000
// requestAnimationFrame(() => { tech.giveTech("MACHO") });
- // for (let i = 0; i < 1; ++i) tech.giveTech("additive manufacturing")
+ // for (let i = 0; i < 1; ++i) tech.giveTech("electrostatic induction")
// for (let i = 0; i < 1; ++i) tech.giveTech("flatland")
// for (let i = 0; i < 1; ++i) tech.giveTech("foam-bot")
// for (let i = 0; i < 1; ++i) tech.giveTech("nail-bot")
@@ -49,7 +50,7 @@ const level = {
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "research");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling");
- // level.testing();
+ level.skyscrapers();
// for (let i = 0; i < 4; ++i) spawn.hopMother(1900, -500)
// for (let i = 0; i < 0; ++i) spawn.hopper(1900, -500)
// for (let i = 0; i < 1; ++i) spawn.shooterBoss(1900, -2500)
@@ -62,7 +63,7 @@ const level = {
// spawn.tetherBoss(1900, -500, { x: 1900, y: -500 })
// for (let i = 0; i < 40; ++i) tech.giveTech()
- level[simulation.isTraining ? "walk" : "intro"]() //normal starting level **************************************************
+ // level[simulation.isTraining ? "walk" : "intro"]() //normal starting level **************************************************
// simulation.isAutoZoom = false; //look in close
// simulation.zoomScale *= 0.5;
@@ -100,7 +101,7 @@ const level = {
}
}
if (!simulation.isTraining) level.levelAnnounce();
- simulation.noCameraScroll();
+ simulation.setupCamera(player.position);
simulation.setZoom();
level.addToWorld(); //add bodies to game engine
simulation.draw.setPaths();
@@ -1345,10 +1346,12 @@ const level = {
//teleport
if (this.portalPair.angle % (Math.PI / 2)) { //if left, right up or down
if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage for 30 cycles
- Matter.Body.setPosition(player, this.portalPair.portal.position);
+ // Matter.Body.setPosition(player, this.portalPair.portal.position);
+ simulation.translatePlayerAndCamera(this.portalPair.portal.position)
} else { //if at some odd angle
if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage for 30 cycles
- Matter.Body.setPosition(player, this.portalPair.position);
+ // Matter.Body.setPosition(player, this.portalPair.position);
+ simulation.translatePlayerAndCamera(this.portalPair.position)
}
//rotate velocity
let mag
@@ -5347,6 +5350,7 @@ const level = {
powerUps.addResearchToLevel() //needs to run after mobs are spawned
},
pavilion() {
+ level.isEndlessFall = true;
const vanish = []
level.exit.x = -850;
level.exit.y = -1485;
@@ -5375,6 +5379,7 @@ const level = {
vanish.push(level.vanish(-350, -450, 150, 223))
spawn.mapRect(2475, -1800, 250, 2300);
+
spawn.mapRect(1200, -750, 100, 450);
spawn.mapRect(1200, -375, 250, 75);
powerUps.spawnStartingPowerUps(550, -100);
@@ -5403,7 +5408,6 @@ const level = {
}
// vanish.push(level.vanish(575, -1575, 375, 225))
-
spawn.bodyRect(225, -850, 50, 100, 0.4);
spawn.mapRect(600, -1800, 325, 225);
spawn.mapRect(1900, -1500, 325, 25);
@@ -5421,9 +5425,11 @@ const level = {
vanish.push(level.vanish(-50, -1800, 450, 25))
//exit
- spawn.mapRect(-1050, -1450, 700, 25);
- spawn.mapRect(-1050, -1800, 525, 25);
- spawn.mapRect(-550, -1800, 25, 200);
+ // spawn.mapRect(-1050, -1450, 700, 25);
+ // spawn.mapRect(-1050, -1800, 525, 25);
+ spawn.mapRect(-575, -1800, 50, 200);
+ spawn.mapRect(-1050, -1800, 525, 75);
+ spawn.mapRect(-1050, -1450, 700, 75);
spawn.randomMob(-1175, -1975, -0.4);
spawn.randomMob(275, -1500, -0.3);
@@ -6193,6 +6199,7 @@ const level = {
},
satellite() {
+ level.isEndlessFall = true;
const boost1 = level.boost(5825, 235, 1400)
const elevator = level.elevator(4210, -1265, 380, 50, -3450) //, 0.003, { up: 0.01, down: 0.2 }
level.custom = () => {
@@ -6368,6 +6375,8 @@ const level = {
}
},
rooftops() {
+ level.isEndlessFall = true;
+ // level.fallPosition = { x: 5000, y:-4000}
const elevator = level.elevator(1450, -990, 235, 45, -2000)
const boost1 = level.boost(4950, 0, 1100)
@@ -6554,6 +6563,7 @@ const level = {
}
},
aerie() {
+ level.isEndlessFall = true;
const boost1 = level.boost(-425, 100, 1400)
const boost2 = level.boost(5350, 275, 2850);
@@ -6782,6 +6792,7 @@ const level = {
}
},
skyscrapers() {
+ level.isEndlessFall = true;
const boost1 = level.boost(475, 0, 1300)
const boost2 = level.boost(4450, 0, 1300);
level.custom = () => {
@@ -6919,6 +6930,7 @@ const level = {
}
},
highrise() {
+ level.isEndlessFall = true;
const elevator1 = level.elevator(-790, -190, 180, 25, -1150, 0.0025, {
up: 0.01,
down: 0.2
@@ -7203,6 +7215,7 @@ const level = {
}
},
warehouse() {
+ level.isEndlessFall = true;
level.custom = () => {
ctx.fillStyle = "#444" //light fixtures
ctx.fillRect(-920, -505, 40, 10)
@@ -18205,8 +18218,8 @@ const level = {
spawn.mapRect(1350, -325, 100, 50);
spawn.mapRect(1400, -1500, 325, 1600);
spawn.mapRect(1400, -1500, 1550, 50);
- spawn.mapRect(1400, -1900, 900, 50);
- spawn.mapRect(1400, -2900, 100, 1050);
+ spawn.mapRect(1250, -1900, 1050, 50);
+ spawn.mapRect(1250, -2900, 100, 1050);
spawn.mapRect(-600, -2900, 3550, 100);
spawn.mapRect(2850, -2900, 100, 700);
@@ -18243,6 +18256,28 @@ const level = {
const piston7 = horizontalDoor(-2000, -2600, 300, 100, 300, 20);
const hand1 = clockHand(400, -3700, 75, 600);
const elevator1 = level.elevator(3200, 0, 150, 50, -1750, 0.0025, { up: 0.05, down: 0.2 });
+ const lightButton = level.button(1400, -1900);
+ lightButton.isUp = true;
+ var lightOn = false;
+ simulation.ephemera.push({
+ name: "lightWire",
+ do() {
+ if (level.levels[level.onLevel] == "clock") {
+ // light wire
+ ctx.beginPath();
+ ctx.moveTo(1460, -1887);
+ ctx.lineTo(1300, -1887);
+ ctx.lineTo(1300, -2860);
+ ctx.lineTo(400, -2860);
+ ctx.lineTo(400, -2800);
+ ctx.lineWidth = 6;
+ ctx.strokeStyle = lightOn ? "#ffd700" : "000";
+ ctx.stroke();
+ } else {
+ simulation.removeEphemera(this.name);
+ }
+ },
+ })
spawn.debris(-300, 0, 1300, 6);
spawn.debris(0, -2900, 2500, 8);
@@ -18299,7 +18334,7 @@ const level = {
}
var circleHead = Matter.Bodies.polygon(m.pos.x, m.pos.y, 0, 31);
- var losDomain = generateIntersectMap().concat(mob.filter((obj) => { return obj.isNotCloaked == null && (obj.isBoss || obj.label != 'Circle Body') }), [pendulum1, gear1, gear2, piston1, player, circleHead]);
+ var losDomain = generateIntersectMap().concat(mob.filter((obj) => { return obj.isNotCloaked == null && (obj.isBoss || obj.label != 'Circle Body') }), [pendulum1, gear1, gear2, player, circleHead]);
var oldMap = [...map];
var oldMob = [...mob];
var spawnGearMobCycle = 0;
@@ -18313,12 +18348,12 @@ const level = {
var startCycle = simulation.cycle; // used to offset simulation.cycle to avoid the swing starting halfway through at the start of the level and messing up syncronization
level.custom = () => {
- Matter.Body.setPosition(circleHead, m.pos)
- if (!(compareArrays(oldMap, map) && compareArrays(oldMob, mob))) {
- losDomain = generateIntersectMap().concat(mob.filter((obj) => { return obj.isNotCloaked == null && (obj.isBoss || obj.label != 'Circle Body') }), [pendulum1, gear1, gear2, piston1, player, circleHead]);
+ if (lightOn) {
+ Matter.Body.setPosition(circleHead, m.pos)
+ if (!(compareArrays(oldMap, map) && compareArrays(oldMob, mob))) losDomain = generateIntersectMap().concat(mob.filter((obj) => { return obj.isNotCloaked == null && (obj.isBoss || obj.label != 'Circle Body') }), [pendulum1, gear1, gear2, player, circleHead]);
+ oldMap = [...map];
+ oldMob = [...mob];
}
- oldMap = [...map];
- oldMob = [...mob];
ctx.fillStyle = "#b0b0b2";
ctx.fillRect(-600, -1700, 2000, 1700);
ctx.fillRect(1350, -1851, 1550, 350);
@@ -18330,39 +18365,41 @@ const level = {
ctx.fillStyle = "#000";
ctx.fillRect(350, -2800, 100, 25);
// light
- var lightPos = { x: 400, y: -2775 };
- var lightRadius = 2950;
- const vertices = circleLoS(lightPos, lightRadius, map.concat(mob.filter((obj) => { return obj.isNotCloaked == null && (obj.isBoss || obj.label != 'Circle Body') }), [pendulum1, gear1, gear2, piston1, player, circleHead])); if (vertices.length > 0 && vertices[0].x) {
- ctx.beginPath();
- ctx.moveTo(vertices[0].x, vertices[0].y);
- for (var i = 1; i < vertices.length; i++) {
- var currentDistance = Math.sqrt((vertices[i - 1].x - lightPos.x) ** 2 + (vertices[i - 1].y - lightPos.y) ** 2);
- var newDistance = Math.sqrt((vertices[i].x - lightPos.x) ** 2 + (vertices[i].y - lightPos.y) ** 2);
+ if (lightOn) {
+ var lightPos = { x: 400, y: -2775 };
+ var lightRadius = 2950;
+ const vertices = circleLoS(lightPos, lightRadius, map.concat(mob.filter((obj) => { return obj.isNotCloaked == null && (obj.isBoss || obj.label != 'Circle Body') }), [pendulum1, gear1, gear2, player, circleHead])); if (vertices.length > 0 && vertices[0].x) {
+ ctx.beginPath();
+ ctx.moveTo(vertices[0].x, vertices[0].y);
+ for (var i = 1; i < vertices.length; i++) {
+ var currentDistance = Math.sqrt((vertices[i - 1].x - lightPos.x) ** 2 + (vertices[i - 1].y - lightPos.y) ** 2);
+ var newDistance = Math.sqrt((vertices[i].x - lightPos.x) ** 2 + (vertices[i].y - lightPos.y) ** 2);
+ if (Math.abs(currentDistance - lightRadius) < 1 && Math.abs(newDistance - lightRadius) < 1) {
+ const currentAngle = Math.atan2(vertices[i - 1].y - lightPos.y, vertices[i - 1].x - lightPos.x);
+ const newAngle = Math.atan2(vertices[i].y - lightPos.y, vertices[i].x - lightPos.x);
+ ctx.arc(lightPos.x, lightPos.y, lightRadius, currentAngle, newAngle);
+ } else {
+ ctx.lineTo(vertices[i].x, vertices[i].y)
+ }
+ }
+ newDistance = Math.sqrt((vertices[0].x - lightPos.x) ** 2 + (vertices[0].y - lightPos.y) ** 2);
+ currentDistance = Math.sqrt((vertices[vertices.length - 1].x - lightPos.x) ** 2 + (vertices[vertices.length - 1].y - lightPos.y) ** 2);
if (Math.abs(currentDistance - lightRadius) < 1 && Math.abs(newDistance - lightRadius) < 1) {
- const currentAngle = Math.atan2(vertices[i - 1].y - lightPos.y, vertices[i - 1].x - lightPos.x);
- const newAngle = Math.atan2(vertices[i].y - lightPos.y, vertices[i].x - lightPos.x);
+ const currentAngle = Math.atan2(vertices[vertices.length - 1].y - lightPos.y, vertices[vertices.length - 1].x - lightPos.x);
+ const newAngle = Math.atan2(vertices[0].y - lightPos.y, vertices[0].x - lightPos.x);
ctx.arc(lightPos.x, lightPos.y, lightRadius, currentAngle, newAngle);
} else {
- ctx.lineTo(vertices[i].x, vertices[i].y)
+ ctx.lineTo(vertices[0].x, vertices[0].y)
}
+ ctx.fillStyle = "rgba(216, 218, 223, 0.5)";
+ ctx.fill();
}
- newDistance = Math.sqrt((vertices[0].x - lightPos.x) ** 2 + (vertices[0].y - lightPos.y) ** 2);
- currentDistance = Math.sqrt((vertices[vertices.length - 1].x - lightPos.x) ** 2 + (vertices[vertices.length - 1].y - lightPos.y) ** 2);
- if (Math.abs(currentDistance - lightRadius) < 1 && Math.abs(newDistance - lightRadius) < 1) {
- const currentAngle = Math.atan2(vertices[vertices.length - 1].y - lightPos.y, vertices[vertices.length - 1].x - lightPos.x);
- const newAngle = Math.atan2(vertices[0].y - lightPos.y, vertices[0].x - lightPos.x);
- ctx.arc(lightPos.x, lightPos.y, lightRadius, currentAngle, newAngle);
- } else {
- ctx.lineTo(vertices[0].x, vertices[0].y)
- }
- ctx.fillStyle = "rgba(216, 218, 223, 0.5)";
- ctx.fill();
}
ctx.beginPath();
ctx.moveTo(425, -2775);
ctx.arc(400, -2775, 25, 0, Math.PI);
- ctx.fillStyle = "#c6aa12";
+ ctx.fillStyle = lightOn ? "#ffe245" : "transparent";
ctx.fill();
ctx.strokeStyle = "#000000";
ctx.lineWidth = 1;
@@ -18473,7 +18510,6 @@ const level = {
if (!finishedGearFight && !pistonsLocked && m.pos.x > 2100 && m.pos.x < 2900 && m.pos.y > -1850 && m.pos.y < -1500) {
pistonsLocked = true;
-
roofFallCycle = simulation.cycle + 250;
roofReadyToFall = true;
}
@@ -18627,10 +18663,6 @@ const level = {
distanceToIntersection = (circle3.radius * distance) / (circle3.radius + circle2.radius);
slopeAngle = Math.atan((circle2.y - circle3.y) / (circle2.x - circle3.x));
angleToTangent = Math.acos(circle3.radius / distanceToIntersection);
- const tangentPoint2 = {
- x: Math.cos(angleToTangent + slopeAngle) * circle3.radius + circle3.x,
- y: Math.sin(angleToTangent + slopeAngle) * circle3.radius + circle3.y
- }
const invertedTangentPoint2 = {
x: Math.cos(-angleToTangent + slopeAngle) * circle3.radius + circle3.x,
y: Math.sin(-angleToTangent + slopeAngle) * circle3.radius + circle3.y
@@ -18640,10 +18672,6 @@ const level = {
x: Math.cos(angleToTangent + slopeAngle) * -circle2.radius + circle2.x,
y: Math.sin(angleToTangent + slopeAngle) * -circle2.radius + circle2.y
}
- const invertedTangentPoint3 = {
- x: Math.cos(-angleToTangent + slopeAngle) * -circle2.radius + circle2.x,
- y: Math.sin(-angleToTangent + slopeAngle) * -circle2.radius + circle2.y
- }
distance = Math.sqrt((piston2.position.y - 175 - circle3.y) ** 2 + (piston2.position.x - 50 - circle3.x) ** 2);
slopeAngle = Math.atan((piston2.position.y - 175 - circle3.y) / (piston2.position.x - 50 - circle3.x));
@@ -18894,6 +18922,9 @@ const level = {
var lastBlock = Math.sin(simulation.cycle / 50) < 0;
level.customTopLayer = () => {
+ if (!lightOn) lightButton.query();
+ if (!lightButton.isUp) lightOn = true;
+ lightButton.draw();
elevator1.move();
ctx.beginPath();
diff --git a/js/player.js b/js/player.js
index f295e38..1643ce2 100644
--- a/js/player.js
+++ b/js/player.js
@@ -196,14 +196,11 @@ const m = {
look() { }, //set to lookDefault()
lookDefault() {
//always on mouse look
- m.angle = Math.atan2(
- simulation.mouseInGame.y - m.pos.y,
- simulation.mouseInGame.x - m.pos.x
- );
+ m.angle = Math.atan2(simulation.mouseInGame.y - m.pos.y, simulation.mouseInGame.x - m.pos.x);
//smoothed mouse look translations
const scale = 0.8;
- m.transSmoothX = canvas.width2 - m.pos.x - (simulation.mouse.x - canvas.width2) * scale;
- m.transSmoothY = canvas.height2 - m.pos.y - (simulation.mouse.y - canvas.height2) * scale;
+ m.transSmoothX = canvas.width2 - m.pos.x - (simulation.mouse.x - canvas.width2) * scale
+ m.transSmoothY = canvas.height2 - m.pos.y - (simulation.mouse.y - canvas.height2) * scale
m.transX += (m.transSmoothX - m.transX) * m.lookSmoothing;
m.transY += (m.transSmoothY - m.transY) * m.lookSmoothing;
@@ -4609,6 +4606,7 @@ const m = {
m.hole.isReady = false;
m.fieldRange = 0
Matter.Body.setPosition(player, simulation.mouseInGame);
+ // simulation.translatePlayerAndCamera(simulation.mouseInGame) //too jerky
m.buttonCD_jump = 0 //this might fix a bug with jumping
const velocity = Vector.mult(Vector.normalise(sub), 20)
Matter.Body.setVelocity(player, {
diff --git a/js/powerup.js b/js/powerup.js
index 8fef7cb..9f1e6dd 100644
--- a/js/powerup.js
+++ b/js/powerup.js
@@ -245,7 +245,7 @@ const powerUps = {
dupExplode() {
for (let i = 0, len = powerUp.length; i < len; ++i) {
if (powerUp[i].isDuplicated) {
- if (Math.random() < 0.003) { // (1-0.003)^240 = chance to be removed after 4 seconds, 240 = 4 seconds * 60 cycles per second
+ if (Math.random() < 0.003 && !m.isBodiesAsleep) { // (1-0.003)^240 = chance to be removed after 4 seconds, 240 = 4 seconds * 60 cycles per second
b.explosion(powerUp[i].position, 175 + (11 + 3 * Math.random()) * powerUp[i].size);
Matter.Composite.remove(engine.world, powerUp[i]);
powerUp.splice(i, 1);
@@ -1070,7 +1070,7 @@ const powerUps = {
const choose = options[Math.floor(Math.seededRandom(0, options.length))] //pick an element from the array of options
if (tech.isBanish) {
tech.tech[choose].isBanished = true
- if (i === 0) simulation.makeTextLog(`options.length = ${optionLengthNoDuplicates}`)
+ if (i === 0) simulation.makeTextLog(`options.length = ${optionLengthNoDuplicates} //tech removed from pool by decoherence`)
}
removeOption(choose) //move from future options pool to avoid repeats on this selection
tech.tech[choose].isRecentlyShown = true //this flag prevents this option from being shown the next time you pick up a tech power up
diff --git a/js/simulation.js b/js/simulation.js
index a89422e..0a254ab 100644
--- a/js/simulation.js
+++ b/js/simulation.js
@@ -548,15 +548,31 @@ const simulation = {
}
}
},
- noCameraScroll() { //makes the camera not scroll after changing locations
- //only works if velocity is zero
+ translatePlayerAndCamera(where) {
+ //infinite falling. teleport to sky after falling
+ const before = { x: player.position.x, y: player.position.y, }
+ Matter.Body.setPosition(player, { x: where.x, y: where.y });
+ const change = { x: before.x - player.position.x, y: before.y - player.position.y }
+ // translate camera to preserve illusion to endless fall
+ m.transX += change.x
+ m.transY += change.y
+ simulation.mouseInGame.x = (simulation.mouse.x - canvas.width2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.width2 - m.transX;
+ simulation.mouseInGame.y = (simulation.mouse.y - canvas.height2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.height2 - m.transY;
+ m.angle = Math.atan2(simulation.mouseInGame.y - m.pos.y, simulation.mouseInGame.x - m.pos.x);
+
+ //is there a reason to update m.pos here?
+ // m.pos.x = player.position.x;
+ // m.pos.y = playerBody.position.y - m.yOff;
+ },
+ setupCamera() { //makes the camera not scroll after changing locations
+ // //only works if velocity is zero
m.pos.x = player.position.x;
m.pos.y = playerBody.position.y - m.yOff;
const scale = 0.8;
m.transSmoothX = canvas.width2 - m.pos.x - (simulation.mouse.x - canvas.width2) * scale;
m.transSmoothY = canvas.height2 - m.pos.y - (simulation.mouse.y - canvas.height2) * scale;
- m.transX += (m.transSmoothX - m.transX) * 1;
- m.transY += (m.transSmoothY - m.transY) * 1;
+ m.transX += (m.transSmoothX - m.transX);
+ m.transY += (m.transSmoothY - m.transY);
},
edgeZoomOutSmooth: 1,
camera() {
@@ -570,6 +586,7 @@ const simulation = {
ctx.translate(canvas.width2, canvas.height2); //center
ctx.scale(simulation.zoom / simulation.edgeZoomOutSmooth, simulation.zoom / simulation.edgeZoomOutSmooth); //zoom in once centered
ctx.translate(-canvas.width2 + m.transX, -canvas.height2 + m.transY); //translate
+ // ctx.translate(-canvas.width2 + m.transX - player.velocity.x, -canvas.height2 + m.transY + player.velocity.y); //translate
//calculate in game mouse position by undoing the zoom and translations
simulation.mouseInGame.x = (simulation.mouse.x - canvas.width2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.width2 - m.transX;
simulation.mouseInGame.y = (simulation.mouse.y - canvas.height2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.height2 - m.transY;
@@ -909,29 +926,51 @@ const simulation = {
}
if (m.pos.y > simulation.fallHeight) { // if 4000px deep
- Matter.Body.setVelocity(player, {
- x: 0,
- y: 0
- });
- Matter.Body.setPosition(player, {
- x: level.enter.x + 50,
- y: level.enter.y - 20
- });
- // move bots
- for (let i = 0; i < bullet.length; i++) {
- if (bullet[i].botType) {
- Matter.Body.setPosition(bullet[i], Vector.add(player.position, {
- x: 250 * (Math.random() - 0.5),
- y: 250 * (Math.random() - 0.5)
- }));
- Matter.Body.setVelocity(bullet[i], {
- x: 0,
- y: 0
- });
+ if (level.isEndlessFall) {
+ //infinite falling. teleport to sky after falling
+
+ simulation.ephemera.push({
+ name: "slow player",
+ count: 130, //cycles before it self removes
+ do() {
+ this.count--
+ if (this.count < 0 || m.onGround) simulation.removeEphemera(this.name)
+ // console.log(player.velocity.y)
+ if (player.velocity.y > 70) Matter.Body.setVelocity(player, { x: player.velocity.x * 0.99, y: player.velocity.y * 0.99 });
+ if (player.velocity.y > 90) Matter.Body.setVelocity(player, { x: player.velocity.x * 0.99, y: player.velocity.y * 0.99 });
+ },
+ })
+
+ const before = { x: player.position.x, y: player.position.y, }
+ Matter.Body.setPosition(player, { x: level.enter.x, y: level.enter.y - 3000 });
+ // Matter.Body.setPosition(player, level.fallPosition);
+
+ const change = { x: before.x - player.position.x, y: before.y - player.position.y }
+ // translate camera smoothly to preserve illusion to endless fall
+ m.transX += change.x
+ m.transY += change.y
+ simulation.mouseInGame.x = (simulation.mouse.x - canvas.width2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.width2 - m.transX;
+ simulation.mouseInGame.y = (simulation.mouse.y - canvas.height2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.height2 - m.transY;
+ m.angle = Math.atan2(simulation.mouseInGame.y - m.pos.y, simulation.mouseInGame.x - m.pos.x);
+
+ } else {
+ Matter.Body.setVelocity(player, { x: 0, y: 0 });
+ Matter.Body.setPosition(player, { x: level.enter.x + 50, y: level.enter.y - 20 });
+ m.damage(0.05 * simulation.difficultyMode);
+ m.energy -= 0.05 * simulation.difficultyMode
+ // move bots
+ for (let i = 0; i < bullet.length; i++) {
+ if (bullet[i].botType) {
+ Matter.Body.setPosition(bullet[i], Vector.add(player.position, { x: 250 * (Math.random() - 0.5), y: 250 * (Math.random() - 0.5) }));
+ Matter.Body.setVelocity(bullet[i], { x: 0, y: 0 });
+ }
}
}
- m.damage(0.1 * simulation.difficultyMode);
- m.energy -= 0.1 * simulation.difficultyMode
+
+
+
+
+
}
if (isNaN(player.position.x)) m.death();
if (m.lastKillCycle + 300 > m.cycle) { //effects active for 5 seconds after killing a mob
@@ -959,6 +998,13 @@ const simulation = {
}
if (!(m.cycle % 420)) { //once every 7 seconds
+ //check if player is inside the map
+ if (Matter.Query.point(map, m.pos).length > 0 || Matter.Query.point(map, player.position).length > 0) {
+ // console.log('halp', Matter.Query.point(map, m.pos))
+ Matter.Body.setVelocity(player, { x: 0, y: 0 });
+ Matter.Body.setPosition(player, { x: level.enter.x + 50, y: level.enter.y - 20 });
+ }
+
if (tech.isZeno) {
if (tech.isEnergyHealth) {
m.energy *= 0.95
@@ -975,10 +1021,7 @@ const simulation = {
while (i--) {
if (who[i].position.y > simulation.fallHeight) {
if (save) {
- Matter.Body.setVelocity(who[i], {
- x: 0,
- y: 0
- });
+ Matter.Body.setVelocity(who[i], { x: 0, y: 0 });
Matter.Body.setPosition(who[i], {
x: level.exit.x + 30 * (Math.random() - 0.5),
y: level.exit.y + 30 * (Math.random() - 0.5)
@@ -1016,6 +1059,7 @@ const simulation = {
clearNow: false,
clearMap() {
level.isProcedural = false;
+ level.isEndlessFall = false;
ctx.setTransform(1, 0, 0, 1, 0, 0);
if (m.alive) {
if (tech.isLongitudinal) b.guns[3].waves = []; //empty array of wave bullets
diff --git a/js/spawn.js b/js/spawn.js
index 01ef73c..fe8834b 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -1510,10 +1510,10 @@ const spawn = {
// }
// }
me.do = function () {
+ this.checkStatus();
this.zombieHealthBar();
this.lookForMobTargets();
this.attack();
- this.checkStatus();
};
me.mobSearchIndex = 0;
me.target = null
@@ -1560,7 +1560,7 @@ const spawn = {
}
me.hitCD = 0
me.attack = function () { //hit non zombie mobs
- if (this.hitCD < simulation.cycle) {
+ if (this.hitCD < simulation.cycle && !this.isStunned && !this.isSlowed) {
if (this.target) {
this.force = Vector.mult(Vector.normalise(Vector.sub(this.target.position, this.position)), this.accelMag * this.mass)
} else { //wonder around
diff --git a/js/tech.js b/js/tech.js
index 2a32bcf..7e7cc17 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -3361,7 +3361,7 @@ const tech = {
},
{
name: "decoherence",
- description: `tech options you don't choose won't reoccur
spawn ${powerUps.orb.research(6)}`,
+ description: `tech options you don't choose won't reoccur
spawn ${powerUps.orb.research(7)}`,
maxCount: 1,
count: 0,
frequency: 1,
@@ -3370,7 +3370,7 @@ const tech = {
return !tech.isSuperDeterminism
},
requires: "not superdeterminism",
- bonusResearch: 6,
+ bonusResearch: 7,
effect() {
tech.isBanish = true
for (let i = 0; i < this.bonusResearch; i++) powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
@@ -5662,19 +5662,19 @@ const tech = {
},
{
name: "shaped charge",
- description: `use ${powerUps.orb.research(3)} to dynamically reduce
all explosions to prevent health loss`,
+ description: `use ${powerUps.orb.research(2)} to dynamically reduce
all explosions to prevent health loss`,
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
- return !tech.isImmuneExplosion && (build.isExperimentSelection || powerUps.research.count > 2) && (tech.haveGunCheck("missiles") || (m.fieldMode === 4 && simulation.molecularMode === 1) || tech.missileBotCount > 0 || tech.isIncendiary || tech.isPulseLaser || tech.isTokamak || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb))
+ return !tech.isImmuneExplosion && (build.isExperimentSelection || powerUps.research.count > 1) && (tech.haveGunCheck("missiles") || (m.fieldMode === 4 && simulation.molecularMode === 1) || tech.missileBotCount > 0 || tech.isIncendiary || tech.isPulseLaser || tech.isTokamak || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb))
},
requires: "an explosive damage source, not rocket propelled grenade",
effect() {
tech.isSmartRadius = true;
- for (let i = 0; i < 3; i++) {
+ for (let i = 0; i < 2; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
},
@@ -5731,9 +5731,9 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
- return tech.haveGunCheck("grenades") && !tech.isVacuumBomb
+ return tech.haveGunCheck("grenades") && !tech.isVacuumBomb && !tech.isSmartRadius
},
- requires: "grenades, not vacuum bomb",
+ requires: "grenades, not vacuum bomb, shaped charges",
effect() {
tech.isImmuneExplosion = true;
tech.isRPG = true;
@@ -6615,12 +6615,12 @@ const tech = {
isGunTech: true,
maxCount: 1,
count: 0,
- frequency: 2,
- frequencyDefault: 2,
+ frequency: 1,
+ frequencyDefault: 1,
allowed() {
- return !tech.isBulletTeleport && (tech.haveGunCheck("foam") || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isFoamBall || tech.isFoamMine)
+ return tech.haveGunCheck("foam") || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isFoamBall || tech.isFoamMine
},
- requires: "foam, not uncertainty",
+ requires: "foam",
effect() {
tech.isFoamAttract = true
},
@@ -6637,9 +6637,9 @@ const tech = {
frequency: 1,
frequencyDefault: 1,
allowed() {
- return (!tech.isFoamAttract && (tech.haveGunCheck("foam") || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isFoamBall || tech.isFoamMine)) || (tech.haveGunCheck("wave") && !tech.is360Longitudinal) || (tech.haveGunCheck("super balls") && !tech.isSuperHarm) || tech.isSoundBotUpgrade
+ return (tech.haveGunCheck("foam") || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isFoamBall || tech.isFoamMine) || (tech.haveGunCheck("wave") && !tech.is360Longitudinal) || (tech.haveGunCheck("super balls") && !tech.isSuperHarm) || tech.isSoundBotUpgrade
},
- requires: "foam, wave, super balls, not isotropic, electrostatic induction, Zectron",
+ requires: "foam, wave, super balls, not isotropic, Zectron",
effect() {
tech.isBulletTeleport = true
},
@@ -7179,7 +7179,7 @@ const tech = {
},
{
name: "compound lens",
- description: "+50% laser lens damage
+15° lens arc",
+ description: "+40% laser lens damage
+25° lens arc",
isGunTech: true,
maxCount: 9,
count: 0,
@@ -7190,8 +7190,8 @@ const tech = {
},
requires: "lens",
effect() {
- b.guns[11].arcRange += 15 * Math.PI / 180 / 2
- b.guns[11].lensDamageOn += 0.5
+ b.guns[11].arcRange += 25 * Math.PI / 180 / 2
+ b.guns[11].lensDamageOn += 0.4
},
remove() {
b.guns[11].arcRange = 90 * Math.PI / 180 / 2 //0.78 divded by 2 because of how it's drawn
diff --git a/todo.txt b/todo.txt
index 010889f..246090e 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,14 +1,21 @@
******************************************************** NEXT PATCH **************************************************
-new mob type: hopMother - hoppers that drop eggs that explode on contact and after several seconds they hatch into baby hoppers
- regular hopper mobs have more life and more damage
+after falling off most open maps you don't take damage
+ you fall down into the level again above the entrance
-a few bug fixes
+disabled smooth camera tracking for
+ portals
+ falling off map
+
+added a once every 7 seconds check to see if the player is suck inside the map
+ if stuck you teleport to the level entrance
+ catches about 90% of the ways to get stuck from falling too fast
+ this might causing problems after more testing, not sure
+
+bug fixes
*********************************************************** TODO *****************************************************
-a mob/boss? that drops the mines from reactor and final boss
-
more (all) bosses need to be made of parts
good examples: spiderBoss, dragonFlyBoss, beetleBoss
methods:
@@ -1108,7 +1115,7 @@ possible names for tech
magnetorquers - produce spin by pushing on earth's magnetic field
Josephson junction - superconducting junction
Pyroelectricity - voltage from temp changes - upgrade from piezoelectricity
- dark star - upgrade to WIMPs
+ perturbation
******************************************************** CARS IMAGES ********************************************************