free falling

after falling off most open maps you don't take damage
  you fall down into the level again above the entrance

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
This commit is contained in:
landgreen
2023-10-15 19:59:47 -07:00
parent b14f2c1eca
commit ff613dc2cf
8 changed files with 205 additions and 129 deletions

View File

@@ -4612,19 +4612,18 @@ const b = {
this.force.y += this.mass * tech.foamGravity; //gravity this.force.y += this.mass * tech.foamGravity; //gravity
if (tech.isFoamAttract) { if (tech.isFoamAttract) {
for (let i = 0, len = mob.length; i < len; i++) { for (let i = 0, len = mob.length; i < len; i++) {
const range = Vector.magnitude(Vector.sub(mob[i].position, this.position))
if ( if (
!mob[i].isBadTarget && !mob[i].isBadTarget &&
Vector.magnitude(Vector.sub(mob[i].position, this.position)) < 375 &&
mob[i].alive && 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 mag = 0.001 * Math.min(1, 200 / range)
const slow = 0.9 this.force = Vector.mult(Vector.normalise(Vector.sub(mob[i].position, this.position)), this.mass * mag)
Matter.Body.setVelocity(this, { const slow = 0.98
x: this.velocity.x * slow, Matter.Body.setVelocity(this, { x: this.velocity.x * slow, y: this.velocity.y * slow });
y: this.velocity.y * slow
});
break break
} }
} }
@@ -7509,10 +7508,7 @@ const b = {
bullet[me].do = function () { bullet[me].do = function () {
function onCollide(that) { function onCollide(that) {
that.collisionFilter.mask = 0; //non collide with everything that.collisionFilter.mask = 0; //non collide with everything
Matter.Body.setVelocity(that, { Matter.Body.setVelocity(that, { x: 0, y: 0 });
x: 0,
y: 0
});
that.do = that.grow; that.do = that.grow;
} }
const mobCollisions = Matter.Query.collides(this, mob) const mobCollisions = Matter.Query.collides(this, mob)

View File

@@ -4,6 +4,7 @@ let cons = []; //all constraints between a point and a body
let consBB = []; //all constraints between two bodies let consBB = []; //all constraints between two bodies
let composite = [] //rotors and other map elements that don't fit let composite = [] //rotors and other map elements that don't fit
const level = { const level = {
isEndlessFall: false,
defaultZoom: 1400, defaultZoom: 1400,
onLevel: -1, onLevel: -1,
levelsCleared: 0, levelsCleared: 0,
@@ -15,27 +16,27 @@ const level = {
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() //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 // simulation.isHorizontalFlipped = true
// tech.giveTech("performance") // tech.giveTech("performance")
// level.difficultyIncrease(3 * 4) //30 is near max on hard //60 is near max on why // level.difficultyIncrease(3 * 4) //30 is near max on hard //60 is near max on why
// spawn.setSpawnList(); // spawn.setSpawnList();
// spawn.setSpawnList(); // spawn.setSpawnList();
// m.maxHealth = m.health = 100 m.maxHealth = m.health = 100
// tech.isRerollDamage = true // tech.isRerollDamage = true
// powerUps.research.changeRerolls(99999) // powerUps.research.changeRerolls(99999)
// m.immuneCycle = Infinity //you can't take damage // m.immuneCycle = Infinity //you can't take damage
// tech.tech[297].frequency = 100 // tech.tech[297].frequency = 100
// m.couplingChange(10) // 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 // m.energy = 0
// simulation.molecularMode = 2 // simulation.molecularMode = 2
// m.damage(0.1); // 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("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.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[3].ammo = 100000000 // b.guns[8].ammo = 100000000
// requestAnimationFrame(() => { tech.giveTech("MACHO") }); // 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("flatland")
// for (let i = 0; i < 1; ++i) tech.giveTech("foam-bot") // for (let i = 0; i < 1; ++i) tech.giveTech("foam-bot")
// for (let i = 0; i < 1; ++i) tech.giveTech("nail-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, "research");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling"); // 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 < 4; ++i) spawn.hopMother(1900, -500)
// for (let i = 0; i < 0; ++i) spawn.hopper(1900, -500) // for (let i = 0; i < 0; ++i) spawn.hopper(1900, -500)
// for (let i = 0; i < 1; ++i) spawn.shooterBoss(1900, -2500) // 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 }) // spawn.tetherBoss(1900, -500, { x: 1900, y: -500 })
// for (let i = 0; i < 40; ++i) tech.giveTech() // 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.isAutoZoom = false; //look in close
// simulation.zoomScale *= 0.5; // simulation.zoomScale *= 0.5;
@@ -100,7 +101,7 @@ const level = {
} }
} }
if (!simulation.isTraining) level.levelAnnounce(); if (!simulation.isTraining) level.levelAnnounce();
simulation.noCameraScroll(); simulation.setupCamera(player.position);
simulation.setZoom(); simulation.setZoom();
level.addToWorld(); //add bodies to game engine level.addToWorld(); //add bodies to game engine
simulation.draw.setPaths(); simulation.draw.setPaths();
@@ -1345,10 +1346,12 @@ const level = {
//teleport //teleport
if (this.portalPair.angle % (Math.PI / 2)) { //if left, right up or down 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 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 } 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 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 //rotate velocity
let mag let mag
@@ -5347,6 +5350,7 @@ const level = {
powerUps.addResearchToLevel() //needs to run after mobs are spawned powerUps.addResearchToLevel() //needs to run after mobs are spawned
}, },
pavilion() { pavilion() {
level.isEndlessFall = true;
const vanish = [] const vanish = []
level.exit.x = -850; level.exit.x = -850;
level.exit.y = -1485; level.exit.y = -1485;
@@ -5375,6 +5379,7 @@ const level = {
vanish.push(level.vanish(-350, -450, 150, 223)) vanish.push(level.vanish(-350, -450, 150, 223))
spawn.mapRect(2475, -1800, 250, 2300); spawn.mapRect(2475, -1800, 250, 2300);
spawn.mapRect(1200, -750, 100, 450); spawn.mapRect(1200, -750, 100, 450);
spawn.mapRect(1200, -375, 250, 75); spawn.mapRect(1200, -375, 250, 75);
powerUps.spawnStartingPowerUps(550, -100); powerUps.spawnStartingPowerUps(550, -100);
@@ -5403,7 +5408,6 @@ const level = {
} }
// vanish.push(level.vanish(575, -1575, 375, 225)) // vanish.push(level.vanish(575, -1575, 375, 225))
spawn.bodyRect(225, -850, 50, 100, 0.4); spawn.bodyRect(225, -850, 50, 100, 0.4);
spawn.mapRect(600, -1800, 325, 225); spawn.mapRect(600, -1800, 325, 225);
spawn.mapRect(1900, -1500, 325, 25); spawn.mapRect(1900, -1500, 325, 25);
@@ -5421,9 +5425,11 @@ const level = {
vanish.push(level.vanish(-50, -1800, 450, 25)) vanish.push(level.vanish(-50, -1800, 450, 25))
//exit //exit
spawn.mapRect(-1050, -1450, 700, 25); // spawn.mapRect(-1050, -1450, 700, 25);
spawn.mapRect(-1050, -1800, 525, 25); // spawn.mapRect(-1050, -1800, 525, 25);
spawn.mapRect(-550, -1800, 25, 200); 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(-1175, -1975, -0.4);
spawn.randomMob(275, -1500, -0.3); spawn.randomMob(275, -1500, -0.3);
@@ -6193,6 +6199,7 @@ const level = {
}, },
satellite() { satellite() {
level.isEndlessFall = true;
const boost1 = level.boost(5825, 235, 1400) const boost1 = level.boost(5825, 235, 1400)
const elevator = level.elevator(4210, -1265, 380, 50, -3450) //, 0.003, { up: 0.01, down: 0.2 } const elevator = level.elevator(4210, -1265, 380, 50, -3450) //, 0.003, { up: 0.01, down: 0.2 }
level.custom = () => { level.custom = () => {
@@ -6368,6 +6375,8 @@ const level = {
} }
}, },
rooftops() { rooftops() {
level.isEndlessFall = true;
// level.fallPosition = { x: 5000, y:-4000}
const elevator = level.elevator(1450, -990, 235, 45, -2000) const elevator = level.elevator(1450, -990, 235, 45, -2000)
const boost1 = level.boost(4950, 0, 1100) const boost1 = level.boost(4950, 0, 1100)
@@ -6554,6 +6563,7 @@ const level = {
} }
}, },
aerie() { aerie() {
level.isEndlessFall = true;
const boost1 = level.boost(-425, 100, 1400) const boost1 = level.boost(-425, 100, 1400)
const boost2 = level.boost(5350, 275, 2850); const boost2 = level.boost(5350, 275, 2850);
@@ -6782,6 +6792,7 @@ const level = {
} }
}, },
skyscrapers() { skyscrapers() {
level.isEndlessFall = true;
const boost1 = level.boost(475, 0, 1300) const boost1 = level.boost(475, 0, 1300)
const boost2 = level.boost(4450, 0, 1300); const boost2 = level.boost(4450, 0, 1300);
level.custom = () => { level.custom = () => {
@@ -6919,6 +6930,7 @@ const level = {
} }
}, },
highrise() { highrise() {
level.isEndlessFall = true;
const elevator1 = level.elevator(-790, -190, 180, 25, -1150, 0.0025, { const elevator1 = level.elevator(-790, -190, 180, 25, -1150, 0.0025, {
up: 0.01, up: 0.01,
down: 0.2 down: 0.2
@@ -7203,6 +7215,7 @@ const level = {
} }
}, },
warehouse() { warehouse() {
level.isEndlessFall = true;
level.custom = () => { level.custom = () => {
ctx.fillStyle = "#444" //light fixtures ctx.fillStyle = "#444" //light fixtures
ctx.fillRect(-920, -505, 40, 10) ctx.fillRect(-920, -505, 40, 10)
@@ -18205,8 +18218,8 @@ const level = {
spawn.mapRect(1350, -325, 100, 50); spawn.mapRect(1350, -325, 100, 50);
spawn.mapRect(1400, -1500, 325, 1600); spawn.mapRect(1400, -1500, 325, 1600);
spawn.mapRect(1400, -1500, 1550, 50); spawn.mapRect(1400, -1500, 1550, 50);
spawn.mapRect(1400, -1900, 900, 50); spawn.mapRect(1250, -1900, 1050, 50);
spawn.mapRect(1400, -2900, 100, 1050); spawn.mapRect(1250, -2900, 100, 1050);
spawn.mapRect(-600, -2900, 3550, 100); spawn.mapRect(-600, -2900, 3550, 100);
spawn.mapRect(2850, -2900, 100, 700); spawn.mapRect(2850, -2900, 100, 700);
@@ -18243,6 +18256,28 @@ const level = {
const piston7 = horizontalDoor(-2000, -2600, 300, 100, 300, 20); const piston7 = horizontalDoor(-2000, -2600, 300, 100, 300, 20);
const hand1 = clockHand(400, -3700, 75, 600); 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 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(-300, 0, 1300, 6);
spawn.debris(0, -2900, 2500, 8); 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 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 oldMap = [...map];
var oldMob = [...mob]; var oldMob = [...mob];
var spawnGearMobCycle = 0; 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 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 = () => { level.custom = () => {
Matter.Body.setPosition(circleHead, m.pos) if (lightOn) {
if (!(compareArrays(oldMap, map) && compareArrays(oldMob, mob))) { Matter.Body.setPosition(circleHead, m.pos)
losDomain = generateIntersectMap().concat(mob.filter((obj) => { return obj.isNotCloaked == null && (obj.isBoss || obj.label != 'Circle Body') }), [pendulum1, gear1, gear2, piston1, player, circleHead]); 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.fillStyle = "#b0b0b2";
ctx.fillRect(-600, -1700, 2000, 1700); ctx.fillRect(-600, -1700, 2000, 1700);
ctx.fillRect(1350, -1851, 1550, 350); ctx.fillRect(1350, -1851, 1550, 350);
@@ -18330,39 +18365,41 @@ const level = {
ctx.fillStyle = "#000"; ctx.fillStyle = "#000";
ctx.fillRect(350, -2800, 100, 25); ctx.fillRect(350, -2800, 100, 25);
// light // light
var lightPos = { x: 400, y: -2775 }; if (lightOn) {
var lightRadius = 2950; var lightPos = { x: 400, y: -2775 };
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) { var lightRadius = 2950;
ctx.beginPath(); 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.moveTo(vertices[0].x, vertices[0].y); ctx.beginPath();
for (var i = 1; i < vertices.length; i++) { ctx.moveTo(vertices[0].x, vertices[0].y);
var currentDistance = Math.sqrt((vertices[i - 1].x - lightPos.x) ** 2 + (vertices[i - 1].y - lightPos.y) ** 2); for (var i = 1; i < vertices.length; i++) {
var newDistance = Math.sqrt((vertices[i].x - lightPos.x) ** 2 + (vertices[i].y - lightPos.y) ** 2); 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) { 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 currentAngle = Math.atan2(vertices[vertices.length - 1].y - lightPos.y, vertices[vertices.length - 1].x - lightPos.x);
const newAngle = Math.atan2(vertices[i].y - lightPos.y, vertices[i].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); ctx.arc(lightPos.x, lightPos.y, lightRadius, currentAngle, newAngle);
} else { } 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.beginPath();
ctx.moveTo(425, -2775); ctx.moveTo(425, -2775);
ctx.arc(400, -2775, 25, 0, Math.PI); ctx.arc(400, -2775, 25, 0, Math.PI);
ctx.fillStyle = "#c6aa12"; ctx.fillStyle = lightOn ? "#ffe245" : "transparent";
ctx.fill(); ctx.fill();
ctx.strokeStyle = "#000000"; ctx.strokeStyle = "#000000";
ctx.lineWidth = 1; 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) { if (!finishedGearFight && !pistonsLocked && m.pos.x > 2100 && m.pos.x < 2900 && m.pos.y > -1850 && m.pos.y < -1500) {
pistonsLocked = true; pistonsLocked = true;
roofFallCycle = simulation.cycle + 250; roofFallCycle = simulation.cycle + 250;
roofReadyToFall = true; roofReadyToFall = true;
} }
@@ -18627,10 +18663,6 @@ const level = {
distanceToIntersection = (circle3.radius * distance) / (circle3.radius + circle2.radius); distanceToIntersection = (circle3.radius * distance) / (circle3.radius + circle2.radius);
slopeAngle = Math.atan((circle2.y - circle3.y) / (circle2.x - circle3.x)); slopeAngle = Math.atan((circle2.y - circle3.y) / (circle2.x - circle3.x));
angleToTangent = Math.acos(circle3.radius / distanceToIntersection); 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 = { const invertedTangentPoint2 = {
x: Math.cos(-angleToTangent + slopeAngle) * circle3.radius + circle3.x, x: Math.cos(-angleToTangent + slopeAngle) * circle3.radius + circle3.x,
y: Math.sin(-angleToTangent + slopeAngle) * circle3.radius + circle3.y y: Math.sin(-angleToTangent + slopeAngle) * circle3.radius + circle3.y
@@ -18640,10 +18672,6 @@ const level = {
x: Math.cos(angleToTangent + slopeAngle) * -circle2.radius + circle2.x, x: Math.cos(angleToTangent + slopeAngle) * -circle2.radius + circle2.x,
y: Math.sin(angleToTangent + slopeAngle) * -circle2.radius + circle2.y 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); 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)); 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; var lastBlock = Math.sin(simulation.cycle / 50) < 0;
level.customTopLayer = () => { level.customTopLayer = () => {
if (!lightOn) lightButton.query();
if (!lightButton.isUp) lightOn = true;
lightButton.draw();
elevator1.move(); elevator1.move();
ctx.beginPath(); ctx.beginPath();

View File

@@ -196,14 +196,11 @@ const m = {
look() { }, //set to lookDefault() look() { }, //set to lookDefault()
lookDefault() { lookDefault() {
//always on mouse look //always on mouse look
m.angle = Math.atan2( m.angle = Math.atan2(simulation.mouseInGame.y - m.pos.y, simulation.mouseInGame.x - m.pos.x);
simulation.mouseInGame.y - m.pos.y,
simulation.mouseInGame.x - m.pos.x
);
//smoothed mouse look translations //smoothed mouse look translations
const scale = 0.8; const scale = 0.8;
m.transSmoothX = canvas.width2 - m.pos.x - (simulation.mouse.x - canvas.width2) * 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.transSmoothY = canvas.height2 - m.pos.y - (simulation.mouse.y - canvas.height2) * scale
m.transX += (m.transSmoothX - m.transX) * m.lookSmoothing; m.transX += (m.transSmoothX - m.transX) * m.lookSmoothing;
m.transY += (m.transSmoothY - m.transY) * m.lookSmoothing; m.transY += (m.transSmoothY - m.transY) * m.lookSmoothing;
@@ -4609,6 +4606,7 @@ const m = {
m.hole.isReady = false; m.hole.isReady = false;
m.fieldRange = 0 m.fieldRange = 0
Matter.Body.setPosition(player, simulation.mouseInGame); Matter.Body.setPosition(player, simulation.mouseInGame);
// simulation.translatePlayerAndCamera(simulation.mouseInGame) //too jerky
m.buttonCD_jump = 0 //this might fix a bug with jumping m.buttonCD_jump = 0 //this might fix a bug with jumping
const velocity = Vector.mult(Vector.normalise(sub), 20) const velocity = Vector.mult(Vector.normalise(sub), 20)
Matter.Body.setVelocity(player, { Matter.Body.setVelocity(player, {

View File

@@ -245,7 +245,7 @@ const powerUps = {
dupExplode() { dupExplode() {
for (let i = 0, len = powerUp.length; i < len; ++i) { for (let i = 0, len = powerUp.length; i < len; ++i) {
if (powerUp[i].isDuplicated) { 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); b.explosion(powerUp[i].position, 175 + (11 + 3 * Math.random()) * powerUp[i].size);
Matter.Composite.remove(engine.world, powerUp[i]); Matter.Composite.remove(engine.world, powerUp[i]);
powerUp.splice(i, 1); 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 const choose = options[Math.floor(Math.seededRandom(0, options.length))] //pick an element from the array of options
if (tech.isBanish) { if (tech.isBanish) {
tech.tech[choose].isBanished = true tech.tech[choose].isBanished = true
if (i === 0) simulation.makeTextLog(`options.length = ${optionLengthNoDuplicates}`) if (i === 0) simulation.makeTextLog(`options.length = ${optionLengthNoDuplicates} <span class='color-text'>//tech removed from pool by decoherence</span>`)
} }
removeOption(choose) //move from future options pool to avoid repeats on this selection 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 tech.tech[choose].isRecentlyShown = true //this flag prevents this option from being shown the next time you pick up a tech power up

View File

@@ -548,15 +548,31 @@ const simulation = {
} }
} }
}, },
noCameraScroll() { //makes the camera not scroll after changing locations translatePlayerAndCamera(where) {
//only works if velocity is zero //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.x = player.position.x;
m.pos.y = playerBody.position.y - m.yOff; m.pos.y = playerBody.position.y - m.yOff;
const scale = 0.8; const scale = 0.8;
m.transSmoothX = canvas.width2 - m.pos.x - (simulation.mouse.x - canvas.width2) * 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.transSmoothY = canvas.height2 - m.pos.y - (simulation.mouse.y - canvas.height2) * scale;
m.transX += (m.transSmoothX - m.transX) * 1; m.transX += (m.transSmoothX - m.transX);
m.transY += (m.transSmoothY - m.transY) * 1; m.transY += (m.transSmoothY - m.transY);
}, },
edgeZoomOutSmooth: 1, edgeZoomOutSmooth: 1,
camera() { camera() {
@@ -570,6 +586,7 @@ const simulation = {
ctx.translate(canvas.width2, canvas.height2); //center ctx.translate(canvas.width2, canvas.height2); //center
ctx.scale(simulation.zoom / simulation.edgeZoomOutSmooth, simulation.zoom / simulation.edgeZoomOutSmooth); //zoom in once centered 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, -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 //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.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; 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 if (m.pos.y > simulation.fallHeight) { // if 4000px deep
Matter.Body.setVelocity(player, { if (level.isEndlessFall) {
x: 0, //infinite falling. teleport to sky after falling
y: 0
}); simulation.ephemera.push({
Matter.Body.setPosition(player, { name: "slow player",
x: level.enter.x + 50, count: 130, //cycles before it self removes
y: level.enter.y - 20 do() {
}); this.count--
// move bots if (this.count < 0 || m.onGround) simulation.removeEphemera(this.name)
for (let i = 0; i < bullet.length; i++) { // console.log(player.velocity.y)
if (bullet[i].botType) { if (player.velocity.y > 70) Matter.Body.setVelocity(player, { x: player.velocity.x * 0.99, y: player.velocity.y * 0.99 });
Matter.Body.setPosition(bullet[i], Vector.add(player.position, { if (player.velocity.y > 90) Matter.Body.setVelocity(player, { x: player.velocity.x * 0.99, y: player.velocity.y * 0.99 });
x: 250 * (Math.random() - 0.5), },
y: 250 * (Math.random() - 0.5) })
}));
Matter.Body.setVelocity(bullet[i], { const before = { x: player.position.x, y: player.position.y, }
x: 0, Matter.Body.setPosition(player, { x: level.enter.x, y: level.enter.y - 3000 });
y: 0 // 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 (isNaN(player.position.x)) m.death();
if (m.lastKillCycle + 300 > m.cycle) { //effects active for 5 seconds after killing a mob 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 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.isZeno) {
if (tech.isEnergyHealth) { if (tech.isEnergyHealth) {
m.energy *= 0.95 m.energy *= 0.95
@@ -975,10 +1021,7 @@ const simulation = {
while (i--) { while (i--) {
if (who[i].position.y > simulation.fallHeight) { if (who[i].position.y > simulation.fallHeight) {
if (save) { if (save) {
Matter.Body.setVelocity(who[i], { Matter.Body.setVelocity(who[i], { x: 0, y: 0 });
x: 0,
y: 0
});
Matter.Body.setPosition(who[i], { Matter.Body.setPosition(who[i], {
x: level.exit.x + 30 * (Math.random() - 0.5), x: level.exit.x + 30 * (Math.random() - 0.5),
y: level.exit.y + 30 * (Math.random() - 0.5) y: level.exit.y + 30 * (Math.random() - 0.5)
@@ -1016,6 +1059,7 @@ const simulation = {
clearNow: false, clearNow: false,
clearMap() { clearMap() {
level.isProcedural = false; level.isProcedural = false;
level.isEndlessFall = false;
ctx.setTransform(1, 0, 0, 1, 0, 0); ctx.setTransform(1, 0, 0, 1, 0, 0);
if (m.alive) { if (m.alive) {
if (tech.isLongitudinal) b.guns[3].waves = []; //empty array of wave bullets if (tech.isLongitudinal) b.guns[3].waves = []; //empty array of wave bullets

View File

@@ -1510,10 +1510,10 @@ const spawn = {
// } // }
// } // }
me.do = function () { me.do = function () {
this.checkStatus();
this.zombieHealthBar(); this.zombieHealthBar();
this.lookForMobTargets(); this.lookForMobTargets();
this.attack(); this.attack();
this.checkStatus();
}; };
me.mobSearchIndex = 0; me.mobSearchIndex = 0;
me.target = null me.target = null
@@ -1560,7 +1560,7 @@ const spawn = {
} }
me.hitCD = 0 me.hitCD = 0
me.attack = function () { //hit non zombie mobs me.attack = function () { //hit non zombie mobs
if (this.hitCD < simulation.cycle) { if (this.hitCD < simulation.cycle && !this.isStunned && !this.isSlowed) {
if (this.target) { if (this.target) {
this.force = Vector.mult(Vector.normalise(Vector.sub(this.target.position, this.position)), this.accelMag * this.mass) this.force = Vector.mult(Vector.normalise(Vector.sub(this.target.position, this.position)), this.accelMag * this.mass)
} else { //wonder around } else { //wonder around

View File

@@ -3361,7 +3361,7 @@ const tech = {
}, },
{ {
name: "decoherence", name: "decoherence",
description: `<strong class='color-m'>tech</strong> options you don't <strong>choose</strong> won't <strong>reoccur</strong><br>spawn ${powerUps.orb.research(6)}`, description: `<strong class='color-m'>tech</strong> options you don't <strong>choose</strong> won't <strong>reoccur</strong><br>spawn ${powerUps.orb.research(7)}`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -3370,7 +3370,7 @@ const tech = {
return !tech.isSuperDeterminism return !tech.isSuperDeterminism
}, },
requires: "not superdeterminism", requires: "not superdeterminism",
bonusResearch: 6, bonusResearch: 7,
effect() { effect() {
tech.isBanish = true 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); 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", name: "shaped charge",
description: `use ${powerUps.orb.research(3)} to dynamically <strong>reduce</strong><br>all <strong class='color-e'>explosions</strong> to prevent <strong class='color-h'>health</strong> loss`, description: `use ${powerUps.orb.research(2)} to dynamically <strong>reduce</strong><br>all <strong class='color-e'>explosions</strong> to prevent <strong class='color-h'>health</strong> loss`,
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { 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", requires: "an explosive damage source, not rocket propelled grenade",
effect() { effect() {
tech.isSmartRadius = true; 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) if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
} }
}, },
@@ -5731,9 +5731,9 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { 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() { effect() {
tech.isImmuneExplosion = true; tech.isImmuneExplosion = true;
tech.isRPG = true; tech.isRPG = true;
@@ -6615,12 +6615,12 @@ const tech = {
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 1,
frequencyDefault: 2, frequencyDefault: 1,
allowed() { 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() { effect() {
tech.isFoamAttract = true tech.isFoamAttract = true
}, },
@@ -6637,9 +6637,9 @@ const tech = {
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { 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() { effect() {
tech.isBulletTeleport = true tech.isBulletTeleport = true
}, },
@@ -7179,7 +7179,7 @@ const tech = {
}, },
{ {
name: "compound lens", name: "compound lens",
description: "<strong>+50%</strong> <strong class='color-laser'>laser</strong> lens <strong class='color-d'>damage</strong><br><strong>+15°</strong> lens arc", description: "<strong>+40%</strong> <strong class='color-laser'>laser</strong> lens <strong class='color-d'>damage</strong><br><strong>+25°</strong> lens arc",
isGunTech: true, isGunTech: true,
maxCount: 9, maxCount: 9,
count: 0, count: 0,
@@ -7190,8 +7190,8 @@ const tech = {
}, },
requires: "lens", requires: "lens",
effect() { effect() {
b.guns[11].arcRange += 15 * Math.PI / 180 / 2 b.guns[11].arcRange += 25 * Math.PI / 180 / 2
b.guns[11].lensDamageOn += 0.5 b.guns[11].lensDamageOn += 0.4
}, },
remove() { remove() {
b.guns[11].arcRange = 90 * Math.PI / 180 / 2 //0.78 divded by 2 because of how it's drawn b.guns[11].arcRange = 90 * Math.PI / 180 / 2 //0.78 divded by 2 because of how it's drawn

View File

@@ -1,14 +1,21 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
new mob type: hopMother - hoppers that drop eggs that explode on contact and after several seconds they hatch into baby hoppers after falling off most open maps you don't take damage
regular hopper mobs have more life and more 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 ***************************************************** *********************************************************** TODO *****************************************************
a mob/boss? that drops the mines from reactor and final boss
more (all) bosses need to be made of parts more (all) bosses need to be made of parts
good examples: spiderBoss, dragonFlyBoss, beetleBoss good examples: spiderBoss, dragonFlyBoss, beetleBoss
methods: methods:
@@ -1108,7 +1115,7 @@ possible names for tech
magnetorquers - produce spin by pushing on earth's magnetic field magnetorquers - produce spin by pushing on earth's magnetic field
Josephson junction - superconducting junction Josephson junction - superconducting junction
Pyroelectricity - voltage from temp changes - upgrade from piezoelectricity Pyroelectricity - voltage from temp changes - upgrade from piezoelectricity
dark star - upgrade to WIMPs perturbation
******************************************************** CARS IMAGES ******************************************************** ******************************************************** CARS IMAGES ********************************************************