diff --git a/js/bullet.js b/js/bullet.js
index 7dea5e7..8d1d258 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -1207,18 +1207,18 @@ const b = {
m.energy = 0;
}
b.isExtruderOn = true
- const SPEED = 8
+ const SPEED = 14
const me = bullet.length;
const where = Vector.add(m.pos, player.velocity)
bullet[me] = Bodies.polygon(where.x + 20 * Math.cos(m.angle), where.y + 20 * Math.sin(m.angle), 4, 0.01, {
cycle: -0.5,
isWave: true,
- endCycle: simulation.cycle + 35 + 45 * tech.isPlasmaRange,
+ endCycle: simulation.cycle + 53, // + 30 * tech.isPlasmaRange,
inertia: Infinity,
frictionAir: 0,
isInHole: true, //this keeps the bullet from entering wormholes
minDmgSpeed: 0,
- dmg: b.dmgScale * 1.2, //damage also changes when you divide by mob.mass on in .do()
+ dmg: b.dmgScale * 1.5, //damage also changes when you divide by mob.mass on in .do()
classType: "bullet",
isBranch: false,
restitution: 0,
@@ -1270,7 +1270,7 @@ const b = {
y: SPEED * Math.sin(m.angle)
});
const transverse = Vector.normalise(Vector.perp(bullet[me].velocity))
- if (180 - Math.abs(Math.abs(b.lastAngle - m.angle) - 180) > 0.3) bullet[me].isBranch = true; //don't draw stroke for this bullet
+ if (180 - Math.abs(Math.abs(b.lastAngle - m.angle) - 180) > 0.13) bullet[me].isBranch = true; //don't draw stroke for this bullet
b.lastAngle = m.angle //track last angle for the above angle difference calculation
if (!b.wasExtruderOn) bullet[me].isBranch = true;
} else {
@@ -1825,119 +1825,122 @@ const b = {
},
spore(where, isFreeze = tech.isSporeFreeze) { //used with the tech upgrade in mob.death()
const bIndex = bullet.length;
- const side = 4;
- bullet[bIndex] = Bodies.polygon(where.x, where.y, 4, side, {
- // density: 0.0015, //frictionAir: 0.01,
- inertia: Infinity,
- isFreeze: isFreeze,
- restitution: 0.5,
- angle: Math.random() * 2 * Math.PI,
- friction: 0,
- frictionAir: 0.025,
- thrust: (tech.isFastSpores ? 0.001 : 0.0004) * (1 + 0.3 * (Math.random() - 0.5)),
- dmg: tech.isMutualism ? 12 : 5, //bonus damage from tech.isMutualism
- lookFrequency: 100 + Math.floor(117 * Math.random()),
- classType: "bullet",
- collisionFilter: {
- category: cat.bullet,
- mask: cat.map | cat.mob | cat.mobBullet | cat.mobShield //no collide with body
- },
- endCycle: simulation.cycle + Math.floor((600 + Math.floor(Math.random() * 420)) * tech.isBulletsLastLonger),
- minDmgSpeed: 0,
- playerOffPosition: { //used when moving towards player to keep spores separate
- x: 100 * (Math.random() - 0.5),
- y: 100 * (Math.random() - 0.5)
- },
- beforeDmg(who) {
- this.endCycle = 0; //bullet ends cycle after doing damage
- if (this.isFreeze) mobs.statusSlow(who, 90)
- },
- onEnd() {
- if (tech.isMutualism && this.isMutualismActive && !tech.isEnergyHealth) {
- m.health += 0.005
- if (m.health > m.maxHealth) m.health = m.maxHealth;
- m.displayHealth();
- }
- },
- do() {
- if (this.lockedOn && this.lockedOn.alive) {
- this.force = Vector.mult(Vector.normalise(Vector.sub(this.lockedOn.position, this.position)), this.mass * this.thrust)
- } else {
- if (!(simulation.cycle % this.lookFrequency)) { //find mob targets
- this.closestTarget = null;
- this.lockedOn = null;
- let closeDist = Infinity;
- for (let i = 0, len = mob.length; i < len; ++i) {
- if (mob[i].dropPowerUp && Matter.Query.ray(map, this.position, mob[i].position).length === 0) {
- const targetVector = Vector.sub(this.position, mob[i].position)
- const dist = Vector.magnitude(targetVector) * (Math.random() + 0.5);
- if (dist < closeDist) {
- this.closestTarget = mob[i].position;
- closeDist = dist;
- this.lockedOn = mob[i]
- if (0.3 > Math.random()) break //doesn't always target the closest mob
+ if (bIndex < 500) { //can't make over 500 spores
+ bullet[bIndex] = Bodies.polygon(where.x, where.y, 4, 4, {
+ // density: 0.0015, //frictionAir: 0.01,
+ inertia: Infinity,
+ isFreeze: isFreeze,
+ restitution: 0.5,
+ angle: Math.random() * 2 * Math.PI,
+ friction: 0,
+ frictionAir: 0.025,
+ thrust: (tech.isFastSpores ? 0.001 : 0.0004) * (1 + 0.3 * (Math.random() - 0.5)),
+ dmg: tech.isMutualism ? 12 : 5, //bonus damage from tech.isMutualism
+ lookFrequency: 100 + Math.floor(117 * Math.random()),
+ classType: "bullet",
+ collisionFilter: {
+ category: cat.bullet,
+ mask: cat.map | cat.mob | cat.mobBullet | cat.mobShield //no collide with body
+ },
+ endCycle: simulation.cycle + Math.floor((600 + Math.floor(Math.random() * 420)) * tech.isBulletsLastLonger),
+ minDmgSpeed: 0,
+ playerOffPosition: { //used when moving towards player to keep spores separate
+ x: 100 * (Math.random() - 0.5),
+ y: 100 * (Math.random() - 0.5)
+ },
+ beforeDmg(who) {
+ this.endCycle = 0; //bullet ends cycle after doing damage
+ if (this.isFreeze) mobs.statusSlow(who, 90)
+ },
+ onEnd() {
+ if (tech.isMutualism && this.isMutualismActive && !tech.isEnergyHealth) {
+ m.health += 0.005
+ if (m.health > m.maxHealth) m.health = m.maxHealth;
+ m.displayHealth();
+ }
+ },
+ do() {
+ if (this.lockedOn && this.lockedOn.alive) {
+ this.force = Vector.mult(Vector.normalise(Vector.sub(this.lockedOn.position, this.position)), this.mass * this.thrust)
+ } else {
+ if (!(simulation.cycle % this.lookFrequency)) { //find mob targets
+ this.closestTarget = null;
+ this.lockedOn = null;
+ let closeDist = Infinity;
+ for (let i = 0, len = mob.length; i < len; ++i) {
+ if (mob[i].dropPowerUp && Matter.Query.ray(map, this.position, mob[i].position).length === 0) {
+ const targetVector = Vector.sub(this.position, mob[i].position)
+ const dist = Vector.magnitude(targetVector) * (Math.random() + 0.5);
+ if (dist < closeDist) {
+ this.closestTarget = mob[i].position;
+ closeDist = dist;
+ this.lockedOn = mob[i]
+ if (0.3 > Math.random()) break //doesn't always target the closest mob
+ }
}
}
}
- }
- if (tech.isSporeFollow && this.lockedOn === null) { //move towards player
- //checking for null means that the spores don't go after the player until it has looked and not found a target
- const dx = this.position.x - m.pos.x;
- const dy = this.position.y - m.pos.y;
- if (dx * dx + dy * dy > 10000) {
- this.force = Vector.mult(Vector.normalise(Vector.sub(m.pos, Vector.add(this.playerOffPosition, this.position))), this.mass * this.thrust)
+ if (tech.isSporeFollow && this.lockedOn === null) { //move towards player
+ //checking for null means that the spores don't go after the player until it has looked and not found a target
+ const dx = this.position.x - m.pos.x;
+ const dy = this.position.y - m.pos.y;
+ if (dx * dx + dy * dy > 10000) {
+ this.force = Vector.mult(Vector.normalise(Vector.sub(m.pos, Vector.add(this.playerOffPosition, this.position))), this.mass * this.thrust)
+ }
+ } else {
+ this.force.y += this.mass * 0.0001; //gravity
}
- } else {
- this.force.y += this.mass * 0.0001; //gravity
+
}
- }
+ // if (!this.lockedOn && !(simulation.cycle % this.lookFrequency)) { //find mob targets
+ // this.closestTarget = null;
+ // this.lockedOn = null;
+ // let closeDist = Infinity;
+ // for (let i = 0, len = mob.length; i < len; ++i) {
+ // if (mob[i].dropPowerUp && Matter.Query.ray(map, this.position, mob[i].position).length === 0) {
+ // // Matter.Query.ray(body, this.position, mob[i].position).length === 0
+ // const targetVector = Vector.sub(this.position, mob[i].position)
+ // const dist = Vector.magnitude(targetVector);
+ // if (dist < closeDist) {
+ // this.closestTarget = mob[i].position;
+ // closeDist = dist;
+ // this.lockedOn = mob[i] //Vector.normalise(targetVector);
+ // if (0.3 > Math.random()) break //doesn't always target the closest mob
+ // }
+ // }
+ // }
+ // }
+ // if (this.lockedOn && this.lockedOn.alive) { //accelerate towards mobs
+ // this.force = Vector.mult(Vector.normalise(Vector.sub(this.lockedOn.position, this.position)), this.mass * this.thrust)
+ // } else if (tech.isSporeFollow && this.lockedOn !== undefined) { //move towards player
+ // //checking for undefined means that the spores don't go after the player until it has looked and not found a target
+ // const dx = this.position.x - m.pos.x;
+ // const dy = this.position.y - m.pos.y;
+ // if (dx * dx + dy * dy > 10000) {
+ // this.force = Vector.mult(Vector.normalise(Vector.sub(m.pos, Vector.add(this.playerOffPosition, this.position))), this.mass * this.thrust)
+ // }
+ // // this.force = Vector.mult(Vector.normalise(Vector.sub(m.pos, this.position)), this.mass * this.thrust)
+ // } else {
+ // this.force.y += this.mass * 0.0001; //gravity
+ // }
- // if (!this.lockedOn && !(simulation.cycle % this.lookFrequency)) { //find mob targets
- // this.closestTarget = null;
- // this.lockedOn = null;
- // let closeDist = Infinity;
- // for (let i = 0, len = mob.length; i < len; ++i) {
- // if (mob[i].dropPowerUp && Matter.Query.ray(map, this.position, mob[i].position).length === 0) {
- // // Matter.Query.ray(body, this.position, mob[i].position).length === 0
- // const targetVector = Vector.sub(this.position, mob[i].position)
- // const dist = Vector.magnitude(targetVector);
- // if (dist < closeDist) {
- // this.closestTarget = mob[i].position;
- // closeDist = dist;
- // this.lockedOn = mob[i] //Vector.normalise(targetVector);
- // if (0.3 > Math.random()) break //doesn't always target the closest mob
- // }
- // }
- // }
- // }
- // if (this.lockedOn && this.lockedOn.alive) { //accelerate towards mobs
- // this.force = Vector.mult(Vector.normalise(Vector.sub(this.lockedOn.position, this.position)), this.mass * this.thrust)
- // } else if (tech.isSporeFollow && this.lockedOn !== undefined) { //move towards player
- // //checking for undefined means that the spores don't go after the player until it has looked and not found a target
- // const dx = this.position.x - m.pos.x;
- // const dy = this.position.y - m.pos.y;
- // if (dx * dx + dy * dy > 10000) {
- // this.force = Vector.mult(Vector.normalise(Vector.sub(m.pos, Vector.add(this.playerOffPosition, this.position))), this.mass * this.thrust)
- // }
- // // this.force = Vector.mult(Vector.normalise(Vector.sub(m.pos, this.position)), this.mass * this.thrust)
- // } else {
- // this.force.y += this.mass * 0.0001; //gravity
- // }
- },
- });
- const SPEED = 4 + 8 * Math.random();
- const ANGLE = 2 * Math.PI * Math.random()
- Matter.Body.setVelocity(bullet[bIndex], {
- x: SPEED * Math.cos(ANGLE),
- y: SPEED * Math.sin(ANGLE)
- });
- World.add(engine.world, bullet[bIndex]); //add bullet to world
+ },
+ });
- if (tech.isMutualism && m.health > 0.02) {
- m.health -= 0.005
- m.displayHealth();
- bullet[bIndex].isMutualismActive = true
+ const SPEED = 4 + 8 * Math.random();
+ const ANGLE = 2 * Math.PI * Math.random()
+ Matter.Body.setVelocity(bullet[bIndex], {
+ x: SPEED * Math.cos(ANGLE),
+ y: SPEED * Math.sin(ANGLE)
+ });
+ World.add(engine.world, bullet[bIndex]); //add bullet to world
+
+ if (tech.isMutualism && m.health > 0.02) {
+ m.health -= 0.005
+ m.displayHealth();
+ bullet[bIndex].isMutualismActive = true
+ }
}
},
iceIX(speed = 0, spread = 2 * Math.PI) {
@@ -3405,6 +3408,7 @@ const b = {
const me = bullet.length;
const dir = m.angle + 0.02 * (Math.random() - 0.5)
bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 45, 20, b.fireAttributes(dir));
+
Matter.Body.setDensity(bullet[me], 0.004);
World.add(engine.world, bullet[me]); //add bullet to world
const SPEED = (m.crouch ? 52 : 43) + Math.random() * 7
diff --git a/js/level.js b/js/level.js
index 205a2d9..bfdce9c 100644
--- a/js/level.js
+++ b/js/level.js
@@ -16,7 +16,7 @@ const level = {
// simulation.zoomScale = 1000;
// simulation.setZoom();
// m.setField("nano-scale manufacturing")
- // b.giveGuns("laser")
+ // b.giveGuns("shotgun")
// tech.isExplodeRadio = true
// for (let i = 0; i < 1; i++) tech.giveTech("dynamo-bot")
// tech.giveTech("supercritical fission")
@@ -55,6 +55,8 @@ const level = {
// level.detours() //fan level
// level.basement(); //fan level
// level.stronghold() //fan level
+ // level.testChamber2() //fan level
+
// powerUps.directSpawn(simulation.mouseInGame.x, simulation.mouseInGame.y, "tech");
// tech.giveTech("undefined")
@@ -768,7 +770,7 @@ const level = {
mapB.portalPair = mapA
return [portalA, portalB, mapA, mapB]
},
- hazard(x, y, width, height, damage = 0.003, color = "hsla(160, 100%, 35%,0.75)", isOptical = false) {
+ hazard(x, y, width, height, damage = 0.003, color = "hsla(160, 100%, 35%,0.75)") {
return {
min: {
x: x,
@@ -782,15 +784,30 @@ const level = {
height: height,
maxHeight: height,
isOn: true,
+ opticalQuery() {
+ if (this.isOn && this.height > 0 && Matter.Query.region([player], this).length && !(m.isCloak)) {
+ if (m.immuneCycle < m.cycle) {
+ m.immuneCycle = m.cycle + tech.collisionImmuneCycles;
+ m.damage(damage)
+ simulation.drawList.push({ //add dmg to draw queue
+ x: player.position.x,
+ y: player.position.y,
+ radius: damage * 1500,
+ color: simulation.mobDmgColor,
+ time: 20
+ });
+ }
+ }
+ },
query() {
- if (this.isOn && this.height > 0 && Matter.Query.region([player], this).length && !(m.isCloak && isOptical)) {
+ if (this.isOn && this.height > 0 && Matter.Query.region([player], this).length) {
const drain = 0.003 + m.fieldRegen
if (m.energy > drain) {
m.energy -= drain
} else {
if (damage < 0.02) {
m.damage(damage)
- } else if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) {
+ } else if (m.immuneCycle < m.cycle) {
m.immuneCycle = m.cycle + tech.collisionImmuneCycles;
m.damage(damage)
simulation.drawList.push({ //add dmg to draw queue
@@ -802,29 +819,24 @@ const level = {
});
}
}
-
//float
- if (!isOptical) {
- if (player.velocity.y > 3) player.force.y -= 0.96 * player.mass * simulation.g
- const slowY = (player.velocity.y > 0) ? Math.max(0.3, 1 - 0.0015 * player.velocity.y * player.velocity.y) : Math.max(0.98, 1 - 0.001 * Math.abs(player.velocity.y)) //down : up
- Matter.Body.setVelocity(player, {
- x: Math.max(0.6, 1 - 0.07 * Math.abs(player.velocity.x)) * player.velocity.x,
- y: slowY * player.velocity.y
- });
- }
+ if (player.velocity.y > 5) player.force.y -= 0.95 * player.mass * simulation.g
+ const slowY = (player.velocity.y > 0) ? Math.max(0.4, 1 - 0.001 * player.velocity.y * player.velocity.y) : Math.max(0.98, 1 - 0.001 * Math.abs(player.velocity.y)) //down : up
+ Matter.Body.setVelocity(player, {
+ x: Math.max(0.6, 1 - 0.07 * Math.abs(player.velocity.x)) * player.velocity.x,
+ y: slowY * player.velocity.y
+ });
}
//float power ups
- if (!isOptical) {
- powerUpCollide = Matter.Query.region(powerUp, this)
- for (let i = 0, len = powerUpCollide.length; i < len; i++) {
- const diameter = 2 * powerUpCollide[i].size
- const buoyancy = 1 - 0.2 * Math.max(0, Math.min(diameter, this.min.y - powerUpCollide[i].position.y + powerUpCollide[i].size)) / diameter
- powerUpCollide[i].force.y -= buoyancy * 1.1 * powerUpCollide[i].mass * simulation.g;
- Matter.Body.setVelocity(powerUpCollide[i], {
- x: powerUpCollide[i].velocity.x,
- y: 0.95 * powerUpCollide[i].velocity.y
- });
- }
+ powerUpCollide = Matter.Query.region(powerUp, this)
+ for (let i = 0, len = powerUpCollide.length; i < len; i++) {
+ const diameter = 2 * powerUpCollide[i].size
+ const buoyancy = 1 - 0.2 * Math.max(0, Math.min(diameter, this.min.y - powerUpCollide[i].position.y + powerUpCollide[i].size)) / diameter
+ powerUpCollide[i].force.y -= buoyancy * 1.1 * powerUpCollide[i].mass * simulation.g;
+ Matter.Body.setVelocity(powerUpCollide[i], {
+ x: powerUpCollide[i].velocity.x,
+ y: 0.95 * powerUpCollide[i].velocity.y
+ });
}
},
draw() {
@@ -1117,9 +1129,9 @@ const level = {
};
level.customTopLayer = () => {};
level.setPosToSpawn(0, -50); //normal spawn
- spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
level.exit.x = 1500;
level.exit.y = -1875;
+ spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
level.defaultZoom = 1800
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#dcdcde";
@@ -1482,8 +1494,8 @@ const level = {
spawn.mapRect(1225, -1955, 175, 30);
const removeIndex2 = map.length - 1 //so much work to catch blocks caught at the bottom of the vertical portals
- const hazard = level.hazard(350, -2025, 700, 10, 0.4, "hsl(0, 100%, 50%)", true) //laser
- const hazard2 = level.hazard(1775, -2550, 150, 10, 0.4, "hsl(0, 100%, 50%)", true) //laser
+ const hazard = level.hazard(350, -2025, 700, 10, 0.4, "hsl(0, 100%, 50%)") //laser
+ const hazard2 = level.hazard(1775, -2550, 150, 10, 0.4, "hsl(0, 100%, 50%)") //laser
const button = level.button(2100, -2600)
@@ -1533,8 +1545,8 @@ const level = {
portal2[3].query()
portal3[2].query()
portal3[3].query()
- hazard.query();
- hazard2.query();
+ hazard.opticalQuery();
+ hazard2.opticalQuery();
if (button.isUp) {
hazard.isOn = false;
hazard2.isOn = false;
@@ -2971,6 +2983,42 @@ const level = {
});
World.add(engine.world, cons[cons.length - 1]);
+
+
+
+ // spawn.bodyRect(-2775, 1300, 400, 100, 1); //hoist
+ // cons[cons.length] = Constraint.create({
+ // pointA: {
+ // x: -2375,
+ // y: 150
+ // },
+ // bodyB: body[body.length - 1],
+ // pointB: {
+ // x: 190,
+ // y: -50
+ // },
+ // stiffness: 0.0001,
+ // damping: 0.2,
+ // length: 1
+ // });
+ // cons[cons.length] = Constraint.create({
+ // pointA: {
+ // x: -2775,
+ // y: 150
+ // },
+ // bodyB: body[body.length - 1],
+ // pointB: {
+ // x: -190,
+ // y: -50
+ // },
+ // stiffness: 0.0001,
+ // damping: 0.2,
+ // length: 1
+ // });
+ // World.add(engine.world, [cons[cons.length - 1], cons[cons.length - 2]]);
+
+
+
//blocks
spawn.bodyRect(-165, -150, 30, 35, 1);
spawn.bodyRect(-165, -115, 30, 35, 1);
@@ -4019,7 +4067,7 @@ const level = {
// // tether ball
// spawn.tetherBoss(8000, 630, { x: 8550, y: 680 })
// let me = mob[mob.length - 1];
- // me.onDeath = function() {
+ // me.onDeath = function() { //please don't edit the onDeath function this causes serious bugs
// this.removeCons(); //remove constraint
// spawnCouloirEnHaut()
// doorSortieSalle.isOpen = false;
@@ -4033,7 +4081,7 @@ const level = {
if (mob[i].isBoss) me = mob[i]
}
if (me) {
- me.onDeath = function() {
+ me.onDeath = function() { //please don't edit the onDeath function this causes serious bugs
spawnCouloirEnHaut()
doorSortieSalle.isOpen = false;
};
@@ -4049,7 +4097,7 @@ const level = {
if (mob[i].isBoss) me = mob[i]
}
if (me) {
- me.onDeath = function() {
+ me.onDeath = function() { //please don't edit the onDeath function this causes serious bugs
spawnCouloirEnHaut()
doorSortieSalle.isOpen = false;
};
@@ -4624,5 +4672,247 @@ const level = {
spawn.randomLevelBoss(3100, -1850, ["shooterBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "snakeBoss", "laserBoss"]);
}
}
- }
+ },
+ testChamber2() {
+ level.setPosToSpawn(-600, 400);
+ spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
+ level.exit.x = 550;
+ level.exit.y = -2730;
+ spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20);
+
+ const portal = level.portal({ //main portals
+ x: -1000,
+ y: 50
+ }, -Math.PI / 2, { //up
+ x: 1000,
+ y: 50
+ }, -Math.PI / 2) //up
+ const portal2 = level.portal({ //portals in upper right corner
+ x: 1400,
+ y: -2200
+ }, -Math.PI / 2, { //up
+ x: 1700,
+ y: -1700
+ }, -Math.PI / 2) //up
+ const rotor = level.rotor(-200, -1950, -0.001)
+
+ level.custom = () => {
+ level.playerExitCheck();
+
+ portal[2].query()
+ portal[3].query()
+ portal2[2].query()
+ portal2[3].query()
+ rotor.rotate();
+ };
+
+ level.customTopLayer = () => {
+ portal[0].draw();
+ portal[1].draw();
+ portal[2].draw();
+ portal[3].draw();
+ portal2[0].draw();
+ portal2[1].draw();
+ portal2[2].draw();
+ portal2[3].draw();
+ };
+
+ level.defaultZoom = 1700 // 4500 // 1400
+ simulation.zoomTransition(level.defaultZoom)
+
+ //section 1: before portals
+ spawn.mapRect(-925, 450, 1850, 250); //1-1 base
+ spawn.mapRect(-925, -300, 55, 755); //1 left wall
+ spawn.mapRect(-875, 50, 1100, 50); //1-1 ceiling
+ spawn.mapRect(620, -300, 305, 755); //1-1 and 1-2 right wall
+ spawn.bodyRect(200, 350, 230, 100);
+ spawn.bodyRect(300, 250, 150, 100);
+ spawn.mapRect(-875, -300, 580, 50); //1-2 ceiling on left
+ spawn.mapRect(0, -300, 625, 50); //1-2 ceiling on right
+ spawn.mapRect(0, -650, 150, 350); //1-3 right wall
+ spawn.mapRect(-925, -650, 975, 150); //1-3 ceiling
+ spawn.mapRect(-1280, 100, 205, 150); //1-4 floor
+ spawn.mapRect(-1280, 245, 360, 455); //bottom left corner
+ spawn.mapRect(-1600, -200, 200, 50); //1-4 platform 1
+ level.fill.push({
+ x: -875,
+ y: -250,
+ width: 1500,
+ height: 700,
+ color: "rgba(0,0,0,0.1)"
+ });
+ level.fill.push({
+ x: -925,
+ y: -505,
+ width: 930,
+ height: 255,
+ color: "rgba(0,0,0,0.1)"
+ });
+
+ //section 2: lower central room (gone through main portals 1 time)
+ spawn.mapRect(920, 245, 160, 455); //below right portal
+ spawn.mapRect(1075, -300, 500, 1000); //2-1 right floor
+ spawn.mapRect(1075, -2005, 550, 1055); //shute right wall
+ spawn.mapRect(875, -1000, 50, 300); //shute left 1
+ spawn.mapRect(860, -1030, 50, 300); //shute left 2
+ spawn.mapRect(850, -1100, 50, 300); //shute left 3
+ spawn.mapRect(830, -980, 50, 50); //shute left 4
+ spawn.mapRect(1075, -1000, 50, 300); //shute right 1
+ spawn.mapRect(1090, -1030, 50, 300); //shute right 2
+ spawn.mapRect(1100, -1100, 50, 300); //shute right 3
+ spawn.mapRect(1120, -980, 50, 50); //shute right 4
+ spawn.bodyRect(100, -1000, 50, 350);
+ spawn.bodyRect(100, -1015, 250, 15);
+ spawn.mapRect(-925, -1600, 100, 1000); //2-2 left wall
+ spawn.mapRect(725, -2150, 200, 750); //2-2 right wall
+ spawn.mapRect(725, -1200, 200, 200); //2-2 right wall 2
+ spawn.mapRect(300, -1000, 625, 50); //2 central ledge
+ level.fill.push({
+ x: 725,
+ y: -1400,
+ width: 200,
+ height: 200,
+ color: "rgba(0,0,0,0.1)"
+ });
+ level.fill.push({
+ x: 925,
+ y: -2150,
+ width: 150,
+ height: 2175,
+ color: "rgba(0,0,0,0.1)"
+ });
+ level.fill.push({
+ x: 925,
+ y: -3450,
+ width: 150,
+ height: 900,
+ color: "rgba(0,0,0,0.1)"
+ });
+
+ //section 3: upper left room and upper central room (gone through main portals 2 times)
+ spawn.mapRect(-1775, -1000, 700, 300); //3-1 floor
+ spawn.mapRect(-1900, -2300, 175, 1600); //3-1 left wall
+ spawn.mapRect(-1375, -1300, 300, 50); //3-1 platform 1
+ spawn.mapRect(-1600, -1650, 300, 50); //3-1 platform 2
+ spawn.mapRect(-1775, -2300, 700, 300); //3-1 ceiling
+ spawn.mapRect(-830, -1600, 300, 50); //2 upper left ledge
+ spawn.mapRect(250, -2150, 675, 50); //2 upper right ledge
+ spawn.mapRect(-925, -2300, 100, 400); //3-2 left wall
+ spawn.mapRect(-600, -2700, 1525, 150); //3-2 ceiling
+ spawn.mapRect(1075, -2150, 250, 150); //next to upper portal
+ level.fill.push({
+ x: -1730,
+ y: -2300,
+ width: 870,
+ height: 1600,
+ color: "rgba(0,0,0,0.1)"
+ });
+
+ //section 4: upper right portals
+ spawn.mapRect(1475, -2700, 150, 700); //4-1 left wall
+ spawn.mapRect(1775, -1650, 250, 150); //4-1 floor-ish
+ spawn.mapRect(1575, -1505, 450, 555); //below upper right portal
+ spawn.mapRect(1800, -2250, 400, 50); //4-1 platform 2
+ spawn.bodyRect(2200, -2250, 25, 300);
+ spawn.mapRect(2200, -1950, 400, 50); //4-1 platform 1
+ //spawn.bodyRect(2575, -2600, 25, 650);
+ spawn.mapRect(2600, -1650, 400, 50); //4-1 platform 0
+ spawn.mapRect(2200, -1350, 400, 50); //4-1 platform -1
+ spawn.bodyRect(2200, -1900, 25, 550);
+ spawn.bodyRect(2575, -1650, 25, 300);
+
+ spawn.mapRect(1780, -4200, 820, 1600); //top right corner
+ spawn.mapRect(800, -4200, 1800, -500); //4-2 ceiling
+ spawn.mapRect(1075, -3450, 250, 900); //4-2 center block
+ spawn.mapRect(800, -3450, 125, 900); //4-2 left wall
+ spawn.mapRect(1550, -4200, 310, 600); //4-2 upper right wall
+ level.fill.push({
+ x: 1800,
+ y: -2200,
+ width: 225,
+ height: 550,
+ color: "rgba(0,0,0,0.1)"
+ });
+ level.fill.push({
+ x: 1800,
+ y: -2600,
+ width: 400,
+ height: 400,
+ color: "rgba(0,0,0,0.1)"
+ });
+ level.fill.push({
+ x: 2200,
+ y: -2600,
+ width: 400,
+ height: 1250,
+ color: "rgba(0,0,0,0.1)"
+ });
+
+ //section 5: after portals (gone through main portals 3 times)
+ spawn.mapRect(-700, -2700, 100, 450); //5-1 right wall
+ spawn.mapRect(-1450, -2700, 900, 50); //5-1 ceiling
+ spawn.mapRect(-925, -2300, 325, 50); //5-1 right floor
+ level.fill.push({
+ x: -1450,
+ y: -2655,
+ width: 755,
+ height: 355,
+ color: "rgba(0,0,0,0.1)"
+ });
+
+ //top left corner stuff
+ if (true) {
+ spawn.mapRect(-1900, -2450, 250, 450); //
+ } else {
+ spawn.boost(-1650, -2310, 400);
+ spawn.mapRect(-2200, -2700, 450, 50); //
+ spawn.mapRect(-1850, -3000, 500, 50); //
+ }
+
+ //exit room
+ spawn.mapRect(350, -3000, 50, 100); //exit room left wall
+ spawn.mapRect(350, -3000, 450, -1700); //exit room ceiling
+ spawn.bodyRect(350, -2900, 50, 50); //door
+ spawn.bodyRect(350, -2850, 50, 50); //door
+ spawn.bodyRect(350, -2800, 50, 50); //door
+ spawn.bodyRect(350, -2750, 50, 50); //door
+ level.fillBG.push({
+ x: 375,
+ y: -3000,
+ width: 450,
+ height: 300,
+ color: "#d4f4f4"
+ });
+
+ spawn.debris(-800, -50, 400, 6); //16 debris per level
+ spawn.debris(-1650, -2300, 250, 4); //16 debris per level
+ spawn.debris(-750, -650, 750, 6); //16 debris per level
+
+ //mobs
+ spawn.randomMob(-650, -100, 0.7); //1-2 left
+ spawn.randomMob(100, -150, 0.3); //1-2 right
+ spawn.randomMob(-100, -400, 0); //1-3 right
+ //spawn.randomMob(-1500, -300, 0.3); //1-4 platform
+ spawn.randomMob(1450, -450, 0); //2-1 right
+ spawn.randomMob(1700, -800, 1); //2-1 off the edge. chance is 1 because some enemies just fall
+ spawn.randomGroup(-550, -1000, -0.3); //2-2
+ spawn.randomMob(-1550, -1800, 0.7); //3-1 upper platform
+ //spawn.randomMob(-1225, -1400, 0.3); //3-1 lower platform
+ spawn.randomMob(450, -2350, 0.3); //3-2 right ledge
+ //spawn.randomMob(1150, -2250, 0); //3-2 far right
+ spawn.randomGroup(2400, -2300, -0.3); //4-1 floating
+ spawn.randomMob(2400, -1450, 0); //4-1 platform -1
+ spawn.randomMob(2800, -1800, 0.5); //4-1 platform 0
+ spawn.randomMob(-1100, -2800, 0.5); //5-2 left
+ spawn.randomMob(-550, -2800, 0.5); //5-2 middle
+ if (simulation.difficulty > 3) {
+ if (Math.random() < 0.5) {
+ spawn.randomLevelBoss(450, -1350, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "streamBoss", "shieldingBoss", "pulsarBoss", "laserBoss"]);
+ } else {
+ spawn.randomLevelBoss(-300, -3200, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "streamBoss", "shieldingBoss", "pulsarBoss", "laserBoss"]);
+ }
+ }
+ powerUps.addRerollToLevel() //needs to run after mobs are spawned
+ if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) spawn.randomLevelBoss(7725, 2275);
+ },
};
\ No newline at end of file
diff --git a/js/player.js b/js/player.js
index 78b6258..6575a3d 100644
--- a/js/player.js
+++ b/js/player.js
@@ -647,7 +647,6 @@ const m = {
m.energy -= dmg;
if (m.energy < 0 || isNaN(m.energy)) { //taking deadly damage
if (tech.isDeathAvoid && powerUps.research.count && !tech.isDeathAvoidedThisLevel) {
-
tech.isDeathAvoidedThisLevel = true
powerUps.research.changeRerolls(-1)
simulation.makeTextLog(`m.research--
${powerUps.research.count}`)
diff --git a/js/powerup.js b/js/powerup.js
index 4f5ba6d..c2c5668 100644
--- a/js/powerup.js
+++ b/js/powerup.js
@@ -112,11 +112,6 @@ const powerUps = {
document.getElementById("tech-anthropic").innerHTML = `-${powerUps.research.count}`
}
if (tech.renormalization && Math.random() < 0.37 && amount < 0) powerUps.spawn(m.pos.x, m.pos.y, "research");
- if (tech.isResearchReality && amount < 0) {
- m.switchWorlds()
- simulation.trails()
- simulation.makeTextLog(`simulation.amplitude = ${Math.random()}`);
- }
if (tech.isRerollHaste) {
if (powerUps.research.count === 0) {
tech.researchHaste = 0.66;
@@ -141,6 +136,11 @@ const powerUps = {
// simulation.makeTextLog(`${Math.max(0,powerUps.tech.lastTotalChoices - powerUps.tech.banishLog.length)} estimated tech choices remaining`)
simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - powerUps.tech.banishLog.length)}`)
}
+ if (tech.isResearchReality) {
+ m.switchWorlds()
+ simulation.trails()
+ simulation.makeTextLog(`simulation.amplitude = ${Math.random()}`);
+ }
powerUps[type].effect();
},
},
diff --git a/js/simulation.js b/js/simulation.js
index dd0dc5c..d940daf 100644
--- a/js/simulation.js
+++ b/js/simulation.js
@@ -525,7 +525,9 @@ const simulation = {
level.levels.push("basement");
level.levels.push("detours");
level.levels.push("house");
- level.levels.splice(0, 4); //remove 4 random levels to make up for adding the 4 community levels
+ level.levels.push("testChamber2");
+ // level.levels.push("vats");
+ level.levels.splice(0, 5); //remove some random levels to make up for adding the community levels
}
level.levels = shuffle(level.levels); //shuffles order of maps
level.levels.unshift("intro"); //add level to the start of the randomized levels list
@@ -699,6 +701,7 @@ const simulation = {
let holdTarget; //if player is holding something this remembers it before it gets deleted
if (m.holdingTarget) holdTarget = m.holdingTarget;
+ simulation.fallHeight = 3000;
m.fireCDcycle = 0
m.drop();
m.hole.isOn = false;
@@ -993,6 +996,7 @@ const simulation = {
for (let i = 0, len = cons.length; i < len; ++i) {
ctx.moveTo(cons[i].pointA.x, cons[i].pointA.y);
ctx.lineTo(cons[i].bodyB.position.x, cons[i].bodyB.position.y);
+ // ctx.lineTo(cons[i].bodyB.position.x + cons[i].pointB.x, cons[i].bodyB.position.y + cons[i].pointB.y);
}
for (let i = 0, len = consBB.length; i < len; ++i) {
ctx.moveTo(consBB[i].bodyA.position.x, consBB[i].bodyA.position.y);
diff --git a/js/spawn.js b/js/spawn.js
index 6b3428f..386c57e 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -1579,7 +1579,7 @@ const spawn = {
}
};
},
- pulsar(x, y, radius = 30) {
+ pulsar(x, y, radius = 40) {
mobs.spawn(x, y, 3, radius, "#f08");
let me = mob[mob.length - 1];
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
@@ -1587,10 +1587,11 @@ const spawn = {
me.radius *= 2
me.vertices[1].x = me.position.x + Math.cos(me.angle) * me.radius; //make one end of the triangle longer
me.vertices[1].y = me.position.y + Math.sin(me.angle) * me.radius;
- me.fireCycle = 0
+ Matter.Body.setDensity(me, 0.002); //extra dense //normal is 0.001 //makes effective life much larger
+ me.fireCycle = Infinity
me.fireTarget = { x: 0, y: 0 }
- me.pulseRadius = Math.min(400, 150 + simulation.difficulty * 3)
- me.fireDelay = Math.max(70, 180 - simulation.difficulty)
+ me.pulseRadius = Math.min(400, 165 + simulation.difficulty * 3)
+ me.fireDelay = Math.max(75, 150 - simulation.difficulty * 0.5)
me.isFiring = false
me.onHit = function() {};
me.canSeeTarget = function() {
@@ -1681,7 +1682,7 @@ const spawn = {
this.torque += 0.000001 * this.inertia;
} else if (dot < -threshold) {
this.torque -= 0.000001 * this.inertia;
- } else if (this.fireCycle > 90) { // aim
+ } else if (this.fireCycle > 60) { // aim
unit = Vector.mult(Vector.normalise(Vector.sub(this.vertices[1], this.position)), this.distanceToPlayer() - 100)
this.fireTarget = Vector.add(this.vertices[1], unit)
if (!this.canSeeTarget()) return
diff --git a/js/tech.js b/js/tech.js
index a763c8e..97cf91a 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -67,7 +67,7 @@
if (index === 'random') {
let options = [];
for (let i = 0; i < tech.tech.length; i++) {
- if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed()) options.push(i);
+ if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isJunk && !tech.tech[i].isLore) options.push(i);
}
// give a random tech from the tech I don't have
if (options.length > 0) {
@@ -86,6 +86,12 @@
}
if (!found) return //if name not found don't give any tech
}
+ if (tech.isMetaAnalysis && tech.tech[index].isJunk) {
+ tech.giveTech('random', true)
+ for (let i = 0; i < 2; i++) powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "research");
+ return
+ }
+
if (tech.tech[index].isLost) tech.tech[index].isLost = false; //give specific tech
tech.tech[index].effect(); //give specific tech
tech.tech[index].count++
@@ -1176,8 +1182,8 @@
tech.isBotDamage = false
}
}, {
- name: "bot replication",
- description: "duplicate your permanent bots
remove all of your guns",
+ name: "ersatz bots",
+ description: "double your permanent bots
remove all of your guns",
maxCount: 1,
count: 0,
frequency: 1,
@@ -2000,7 +2006,7 @@
frequency: 1,
isHealTech: true,
allowed() {
- return m.maxHealth > 1 || tech.isArmorFromPowerUps
+ return m.health > 0.1 && (m.maxHealth > 1 || tech.isArmorFromPowerUps)
},
requires: "increased max health",
effect() {
@@ -2134,9 +2140,9 @@
count: 0,
frequency: 1,
allowed() {
- return !tech.isImmortal && !tech.isResearchReality
+ return !tech.isImmortal && !tech.isResearchReality && level.onLevel < 6
},
- requires: "not quantum immortality, perturbation theory",
+ requires: "before level 6, not quantum immortality, perturbation theory",
effect() {
tech.isSwitchReality = true;
},
@@ -2150,9 +2156,9 @@
count: 0,
frequency: 1,
allowed() {
- return !tech.isImmortal && !tech.isSwitchReality
+ return !tech.isImmortal && !tech.isSwitchReality && (powerUps.research.count > 2 || build.isExperimentSelection)
},
- requires: "not quantum immortality, many-worlds",
+ requires: "at least 2 research, not quantum immortality, many-worlds",
effect() {
tech.isResearchReality = true;
for (let i = 0; i < 11; i++) powerUps.spawn(m.pos.x + Math.random() * 10, m.pos.y + Math.random() * 10, "research", false);
@@ -2167,9 +2173,9 @@
count: 0,
frequency: 1,
allowed() {
- return (powerUps.research.count > 1 || build.isExperimentSelection) && !tech.isSuperDeterminism && !tech.isRerollHaste
+ return (powerUps.research.count > 2 || build.isExperimentSelection) && !tech.isSuperDeterminism && !tech.isRerollHaste
},
- requires: "not superdeterminism or Ψ(t) collapse
at least 2 research",
+ requires: "not superdeterminism or Ψ(t) collapse
at least 3 research",
effect() {
tech.renormalization = true;
},
@@ -2313,26 +2319,25 @@
remove() {
tech.isShieldAmmo = false;
}
- }, {
- name: "stimulated emission",
- description: "20% chance to duplicate spawned power ups
but, after a collision eject 1 tech",
+ },
+ {
+ name: "meta-analysis",
+ description: "if you choose a junk tech you instead get a
random non-junk tech and spawn 2 research",
maxCount: 1,
count: 0,
- frequency: 1,
+ frequency: 2,
allowed() {
- return tech.duplicationChance() < 1
+ return tech.duplicateChance
},
- requires: "below 100% duplication chance",
- effect: () => {
- tech.isBayesian = true
- simulation.draw.powerUp = simulation.draw.powerUpBonus //change power up draw
- tech.maxDuplicationEvent()
+ requires: "replication",
+ effect() {
+ tech.isMetaAnalysis = true
},
remove() {
- tech.isBayesian = false
- if (tech.duplicationChance() === 0) simulation.draw.powerUp = simulation.draw.powerUpNormal
+ tech.isMetaAnalysis = false
}
- }, {
+ },
+ {
name: "replication",
description: "7% chance to duplicate spawned power ups
add 12 junk tech to the potential pool",
maxCount: 9,
@@ -2354,7 +2359,28 @@
if (tech.duplicationChance() === 0) simulation.draw.powerUp = simulation.draw.powerUpNormal
if (this.count > 1) tech.removeJunkTechFromPool(12)
}
- }, {
+ },
+ {
+ name: "stimulated emission",
+ description: "20% chance to duplicate spawned power ups
but, after a collision eject 1 tech",
+ maxCount: 1,
+ count: 0,
+ frequency: 1,
+ allowed() {
+ return tech.duplicationChance() < 1
+ },
+ requires: "below 100% duplication chance",
+ effect: () => {
+ tech.isBayesian = true
+ simulation.draw.powerUp = simulation.draw.powerUpBonus //change power up draw
+ tech.maxDuplicationEvent()
+ },
+ remove() {
+ tech.isBayesian = false
+ if (tech.duplicationChance() === 0) simulation.draw.powerUp = simulation.draw.powerUpNormal
+ }
+ },
+ {
name: "futures exchange",
description: "clicking × to cancel a field, tech, or gun
adds 4.5% power up duplication chance",
maxCount: 1,
@@ -2682,27 +2708,6 @@
tech.isSuperDeterminism = false;
}
},
- // {
- // name: "ammo technology",
- // description: "double the frequency of finding gun tech
spawn 6 ammo",
- // maxCount: 1,
- // count: 0,
- // frequency: 1,
- // isNonRefundable: true,
- // // isExperimentHide: true,
- // // isBadRandomOption: true,
- // allowed() {
- // return !tech.isEnergyNoAmmo
- // },
- // requires: "not exciton lattice",
- // effect() {
- // for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "ammo");
- // for (let i = 0, len = tech.tech.length; i < len; i++) {
- // if (tech.tech[i].isGunTech) tech.tech[i].frequency *= 2
- // }
- // },
- // remove() {}
- // },
//**************************************************
//************************************************** gun
//************************************************** tech
@@ -4352,23 +4357,6 @@
// }
// },
{
- name: "plasma jet",
- description: "increase plasma torch's range by 27%",
- isFieldTech: true,
- maxCount: 9,
- count: 0,
- frequency: 1,
- allowed() {
- return m.fieldUpgrades[m.fieldMode].name === "plasma torch"
- },
- requires: "plasma torch",
- effect() {
- tech.isPlasmaRange += 0.27;
- },
- remove() {
- tech.isPlasmaRange = 1;
- }
- }, {
name: "plasma-bot",
description: "a bot uses energy to emit plasma
that damages and pushes mobs",
isFieldTech: true,
@@ -4388,7 +4376,26 @@
remove() {
tech.plasmaBotCount = 0;
}
- }, {
+ },
+ {
+ name: "plasma jet",
+ description: "increase plasma torch's range by 30%",
+ isFieldTech: true,
+ maxCount: 9,
+ count: 0,
+ frequency: 1,
+ allowed() {
+ return m.fieldUpgrades[m.fieldMode].name === "plasma torch" && !tech.isExtruder
+ },
+ requires: "plasma torch, not micro-extruder",
+ effect() {
+ tech.isPlasmaRange += 0.3;
+ },
+ remove() {
+ tech.isPlasmaRange = 1;
+ }
+ },
+ {
name: "micro-extruder",
description: "plasma torch extrudes a thin hot wire
increases damage, and energy drain",
isFieldTech: true,
@@ -4396,9 +4403,9 @@
count: 0,
frequency: 1,
allowed() {
- return m.fieldUpgrades[m.fieldMode].name === "plasma torch"
+ return m.fieldUpgrades[m.fieldMode].name === "plasma torch" && tech.isPlasmaRange === 1
},
- requires: "plasma torch",
+ requires: "plasma torch, not plasma jet",
effect() {
tech.isExtruder = true;
},
@@ -5790,5 +5797,6 @@
isFlipFlopOn: null,
isFlipFlopLevelReset: null,
isFlipFlopDamage: null,
- isFlipFlopEnergy: null
+ isFlipFlopEnergy: null,
+ isMetaAnalysis: null
}
\ No newline at end of file
diff --git a/todo.txt b/todo.txt
index 84bd6d1..f644ede 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,29 +1,19 @@
******************************************************** NEXT PATCH ********************************************************
+meta-analysis - if you choose a junk tech you instead get a random tech and spawn 2 research
+micro-extruder should have 50% less lag
+
+new community level testChamber2! by Oranger on n-gon discord
+(be sure to enable community levels in settings)
******************************************************** BUGS ********************************************************
-inductive + MEE + 1st ion + negentrophy + electrolytes + tranceiver chip + dupe chance is ridiculously op
-
-micro-extruder is laggy?
+fix issue where you have to press z once to get copy to work for simulation.enableConstructMode()
mouse event e.which is deprecated
fix door.isOpen actually meaning isClosed?
-(once for me, and a few times for discord) player gets stuck in crouch animation
- occurred after rerolling a power up (which triggered a switchWorlds)
- can't jump, move slow
- m.crouch = false
- only fixed itself when you click fire (drones, so no recoil)
- fire fixes:
- if (m.holdingTarget) m.drop()
- so probably the player is getting stuck holding a block, but the block is removed
- what removes blocks?
- fixed? I added: if (m.holdingTarget) m.drop(); to powerUps.endDraft and to m.switchWorlds
-
-use the floor of portal sensor on the player? to unstuck player
-
(only once on my computer) once every 7 second check isn't running code
power ups don't teleport to exit
complex spin statistics isn't activating
@@ -48,19 +38,19 @@ use the floor of portal sensor on the player? to unstuck player
******************************************************** TODO ********************************************************
-add a delay between each fire for pulsar mobs
-mob bullets that blow up
- draw outline of exploded region, 2 seconds later damage player in region and remove bullet
+allow levels to adjust the teleport limit in simulation.checks
-holding down the field button on fields that don't have a normal field graphic shows a field arc outline to indicate grabbing blocks
+copy time-like foam to shotgun
mob sniper: draw aim graphics before fire
tech laser: photon - laser, but it can only move 100 pixels a cycle
-mob - grows after taking damage
-mob - attack outwardly after taking damage
+mob - after taking damage
+ attack outwardly
+ grows
+ teleports
tech- foam is attracted to mobs
use a gravitational attraction model?
@@ -78,15 +68,6 @@ mobile requirements:
tap screen regions to move (WASD)
reduce font size
-tech: removes itself after a few levels
- gives extra duplication for 2 levels, then removes all duplication
-
-use ship tech to make a mob mode
- differences from ship to mob
- graphics
- take no damage from mob collision
- It would be cool if you could exit mob mode
-
decrease healing effects by 50%
decrease level scaling healing reduction
net effect: healing at difficulty 40 (level 10 hard) should be 25% higher then current levels
@@ -99,8 +80,6 @@ bosses should have 2x health, but only do about 50 health damage
boss flag cut damage done to boss by 20x <----
make bosses not have extra density
-tech: spawn a bot after taking collision damage
-
map: laboratory
rooms with switches that change physics
gravity room
@@ -110,11 +89,6 @@ map: laboratory
portal + rotor + falling blocks = perpetual motion room
a button that spawns a heal.
-copy time-like foam to other guns?
- wave gun
- shotgun
- nail gun
-
lore: a tutorial / lore intro
needs to be optional so it doesn't slow experienced players
put something on the intro map
@@ -346,6 +320,7 @@ possible names for tech
genetic algorithm
metaheuristic - is a higher-level procedure or heuristic designed to find, generate, or select a heuristic (partial search algorithm) that may provide a sufficiently good solution to an optimization problem, especially with incomplete or imperfect information or limited computation capacity
stochastic optimization
+ meta-analysis
plot script: