diff --git a/js/bullet.js b/js/bullet.js
index 77c9e2e..2141f4f 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -164,23 +164,25 @@ const b = {
}
}
},
- explosion(where, radius) {
- radius *= mod.explosionRadius
- // typically explode is used for some bullets with .onEnd
- //add dmg to draw queue
- game.drawList.push({
+ explosion(where, radius) { // typically explode is used for some bullets with .onEnd
+ let dist, sub, knock;
+ let dmg = radius * 0.01;
+ if (mod.isExplosionHarm) radius *= 1.35
+ if (mod.isSmallExplosion) {
+ radius *= 0.5
+ dmg *= 1.5
+ }
+
+ game.drawList.push({ //add dmg to draw queue
x: where.x,
y: where.y,
radius: radius,
color: "rgba(255,25,0,0.6)",
time: game.drawTime
});
- let dist, sub, knock;
- let dmg = radius * 0.01;
const alertRange = 100 + radius * 2; //alert range
- //add alert to draw queue
- game.drawList.push({
+ game.drawList.push({ //add alert to draw queue
x: where.x,
y: where.y,
radius: alertRange,
@@ -193,8 +195,12 @@ const b = {
dist = Vector.magnitude(sub);
if (dist < radius) {
- if (!(mod.isImmuneExplosion && mech.energy > 0.75)) {
- mech.damage(radius * 0.0001); //normal player damage from explosions
+ if (!(mod.isImmuneExplosion && mech.energy > 0.97)) {
+ if (mod.isExplosionHarm) {
+ mech.damage(radius * 0.0004); //300% more player damage from explosions
+ } else {
+ mech.damage(radius * 0.0001); //normal player damage from explosions
+ }
mech.drop();
}
knock = Vector.mult(Vector.normalise(sub), -Math.sqrt(dmg) * player.mass * 0.015);
@@ -276,8 +282,13 @@ const b = {
bullet[me].lookFrequency = Math.floor(21 + Math.random() * 7);
bullet[me].onEnd = function () {
b.explosion(this.position, this.explodeRad * size); //makes bullet do explosive damage at end
- for (let i = 0; i < spawn; i++) {
- b.missile(this.position, 2 * Math.PI * Math.random(), 0, 0.7 * size)
+ if (spawn) {
+ for (let i = 0; i < mod.recursiveMissiles; i++) {
+ if (0.3 - 0.03 * i > Math.random()) {
+ b.missile(this.position, this.angle + Math.PI + 0.5 * (Math.random() - 0.5), 0, 0.33 + size, mod.recursiveMissiles)
+ break;
+ }
+ }
}
}
bullet[me].onDmg = function () {
@@ -340,8 +351,8 @@ const b = {
//draw rocket
ctx.beginPath();
- ctx.arc(this.position.x - Math.cos(this.angle) * (30 * size - 3) + (Math.random() - 0.5) * 4,
- this.position.y - Math.sin(this.angle) * (30 * size - 3) + (Math.random() - 0.5) * 4,
+ ctx.arc(this.position.x - Math.cos(this.angle) * (25 * size - 3) + (Math.random() - 0.5) * 4,
+ this.position.y - Math.sin(this.angle) * (25 * size - 3) + (Math.random() - 0.5) * 4,
11 * size, 0, 2 * Math.PI);
ctx.fillStyle = "rgba(255,155,0,0.5)";
ctx.fill();
@@ -350,7 +361,7 @@ const b = {
ctx.beginPath();
ctx.arc(this.position.x - Math.cos(this.angle) * (30 * size - 3) + (Math.random() - 0.5) * 4,
this.position.y - Math.sin(this.angle) * (30 * size - 3) + (Math.random() - 0.5) * 4,
- 11 * size, 0, 2 * Math.PI);
+ 2 + 9 * size, 0, 2 * Math.PI);
ctx.fillStyle = "rgba(255,155,0,0.5)";
ctx.fill();
}
@@ -1042,7 +1053,7 @@ const b = {
onEnd() {},
do() {
if (this.lastLookCycle < game.cycle) {
- this.lastLookCycle = game.cycle + 80 - this.isUpgraded * 40
+ this.lastLookCycle = game.cycle + 80 - this.isUpgraded * 50
let target
for (let i = 0, len = mob.length; i < len; i++) {
const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position));
@@ -1107,7 +1118,7 @@ const b = {
const radius = 6 + 7 * Math.random()
const SPEED = 29 - radius * 0.5; //(mech.crouch ? 32 : 20) - radius * 0.7;
const velocity = Vector.mult(Vector.normalise(Vector.sub(target, this.position)), SPEED)
- b.foam(this.position, velocity, radius + 8 * this.isUpgraded)
+ b.foam(this.position, velocity, radius + 9 * this.isUpgraded)
break;
}
}
@@ -1207,7 +1218,7 @@ const b = {
bestVertexDistance = dist
}
}
- const dmg = b.dmgScale * (0.06 + 0.06 * this.isUpgraded);
+ const dmg = b.dmgScale * (0.06 + 0.075 * this.isUpgraded);
this.lockedOn.damage(dmg);
this.lockedOn.locatePlayer();
@@ -1257,7 +1268,7 @@ const b = {
explode: 0,
onDmg() {
if (this.lockedOn) {
- const explosionRadius = Math.min(170 + 110 * this.isUpgraded, Vector.magnitude(Vector.sub(this.position, mech.pos)) - 30)
+ const explosionRadius = Math.min(170 + 130 * this.isUpgraded, Vector.magnitude(Vector.sub(this.position, mech.pos)) - 30)
if (explosionRadius > 60) {
this.explode = explosionRadius
//
@@ -1995,7 +2006,7 @@ const b = {
b.missile({
x: mech.pos.x + 40 * direction.x,
y: mech.pos.y + 40 * direction.y
- }, mech.angle + 0.06 * (1 - i), 0, 0.7, mod.babyMissiles)
+ }, mech.angle + 0.06 * (1 - i), 0, 0.7, mod.recursiveMissiles)
bullet[bullet.length - 1].force.x += push.x * (i - 1);
bullet[bullet.length - 1].force.y += push.y * (i - 1);
}
@@ -2011,7 +2022,7 @@ const b = {
b.missile({
x: mech.pos.x + 40 * direction.x,
y: mech.pos.y + 40 * direction.y
- }, mech.angle, 0, 0.7, mod.babyMissiles)
+ }, mech.angle, 0, 0.7, mod.recursiveMissiles)
bullet[bullet.length - 1].force.x += push.x * (i - 1);
bullet[bullet.length - 1].force.y += push.y * (i - 1);
}
@@ -2024,7 +2035,7 @@ const b = {
},
mech.angle + (0.5 - Math.random()) * (mech.crouch ? 0 : 0.2),
-3 * (0.5 - Math.random()) + (mech.crouch ? 25 : -8) * b.fireCD,
- 1, mod.babyMissiles)
+ 1, mod.recursiveMissiles)
bullet[bullet.length - 1].force.y += 0.0006; //a small push down at first to make it seem like the missile is briefly falling
}
}
@@ -2196,14 +2207,14 @@ const b = {
suck(body, this.explodeRad * 2)
suck(powerUp, this.explodeRad * 1.5)
suck(bullet, this.explodeRad * 1.5)
- suck([player], this.explodeRad * 1.5)
+ suck([player], this.explodeRad * 1.3)
} else {
mag = 0.1
suck(mob, this.explodeRad * 3)
suck(body, this.explodeRad * 2)
suck(powerUp, this.explodeRad * 1.5)
suck(bullet, this.explodeRad * 1.5)
- suck([player], this.explodeRad * 1.5)
+ suck([player], this.explodeRad * 1.3)
}
//keep bomb in place
Matter.Body.setVelocity(this, {
diff --git a/js/engine.js b/js/engine.js
index 17daab8..2f066e9 100644
--- a/js/engine.js
+++ b/js/engine.js
@@ -159,6 +159,7 @@ function collisionChecks(event) {
mod.mods[choose].count = 0;
mod.mods[choose].remove(); // remove a random mod form the list of mods you have
game.updateModHUD();
+ mech.fieldCDcycle = mech.cycle + 30; //disable field so you can't pick up the ejected mod
}
if (mob[k].onHit) mob[k].onHit(k);
diff --git a/js/index.js b/js/index.js
index d58dcea..1d0c685 100644
--- a/js/index.js
+++ b/js/index.js
@@ -30,6 +30,12 @@ function shuffle(array) {
return array;
}
+// shrink power up selection menu to find window height
+if (screen.height < 800) {
+ document.getElementById("choose-grid").style.fontSize = "1em"; //1.3em is normal
+ if (screen.height < 600) document.getElementById("choose-grid").style.fontSize = "0.8em"; //1.3em is normal
+}
+
//example https://landgreen.github.io/sidescroller/index.html?
// &gun1=minigun&gun2=laser
// &mod1=laser-bot&mod2=mass%20driver&mod3=overcharge&mod4=laser-bot&mod5=laser-bot&field=phase%20decoherence%20field&difficulty=2
diff --git a/js/level.js b/js/level.js
index eccc23a..74f9363 100644
--- a/js/level.js
+++ b/js/level.js
@@ -20,6 +20,7 @@ const level = {
// mod.giveMod("quantum immortality");
level.intro(); //starting level
+ // level.house()
// level.testing(); //not in rotation
// level.template() //not in rotation
// level.testChamber() //less mobs, more puzzle
@@ -35,8 +36,6 @@ const level = {
// level.newLevel() //fan level
// level.basement(); //fan level
// level.stronghold() //fan level
-
-
} else {
spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
// spawn.pickList = ["focuser", "focuser"]
@@ -75,6 +74,488 @@ const level = {
//******************************************************************************************************************
//******************************************************************************************************************
//******************************************************************************************************************
+
+ house() {
+ const rotor = level.rotor(4315, -315, -0.0002, 120, 20, 200);
+ const hazard = level.hazard(4350, -1000, 300, 110);
+ const doorBedroom = level.door(1152, -1150, 25, 250, 250);
+ const doorGrenier = level.door(1152, -1625, 25, 150, 160);
+ const buttonBedroom = level.button(1250, -850);
+ const voletLucarne1 = level.door(1401, -2150, 20, 26, 28);
+ const voletLucarne2 = level.door(1401, -2125, 20, 26, 53);
+ const voletLucarne3 = level.door(1401, -2100, 20, 26, 78);
+ const voletLucarne4 = level.door(1401, -2075, 20, 26, 103);
+ const voletLucarne5 = level.door(1401, -2050, 20, 26, 128);
+ const voletLucarne6 = level.door(1401, -2025, 20, 26, 153);
+ let hasAlreadyBeenActivated = false;
+ let grd
+ level.setPosToSpawn(0, -50); //normal spawn
+ spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
+ level.exit.x = 9700;
+ level.exit.y = 2560;
+ level.defaultZoom = 1800
+ game.zoomTransition(level.defaultZoom)
+ document.body.style.backgroundColor = "#969696"
+
+ level.fillBG.push({ //lampadaire
+ x: 624,
+ y: -1150,
+ width: 28,
+ height: 1075,
+ color: "rgb(77, 76, 76)"
+ });
+ //tele
+ level.fillBG.push({ //zone 1
+ x: 3420,
+ y: -380,
+ width: 285,
+ height: 40,
+ color: "#ababab"
+ })
+ level.fillBG.push({ //poignée 1
+ x: 3555,
+ y: -367.5,
+ width: 15,
+ height: 15,
+ color: "#474747"
+ })
+ level.fillBG.push({ //entre-deux 1
+ x: 3418,
+ y: -344,
+ width: 288,
+ height: 8,
+ color: "#474747"
+ })
+ level.fillBG.push({ //zone 2
+ x: 3420,
+ y: -340,
+ width: 285,
+ height: 40,
+ color: "#ababab"
+ })
+ level.fillBG.push({ //poignée 2
+ x: 3555,
+ y: -327.5,
+ width: 15,
+ height: 15,
+ color: "#474747"
+ })
+ level.fillBG.push({ //entre-deux 2
+ x: 3418,
+ y: -304,
+ width: 288,
+ height: 8,
+ color: "#474747"
+ })
+ level.fillBG.push({ //zone 3
+ x: 3420,
+ y: -300,
+ width: 285,
+ height: 45,
+ color: "#ababab"
+ })
+ level.fillBG.push({ //poignée 3
+ x: 3555,
+ y: -285,
+ width: 15,
+ height: 15,
+ color: "#474747"
+ })
+ level.fillBG.push({ //door bathroom
+ x: 3800,
+ y: -1275,
+ width: 250,
+ height: 425,
+ color: "rgba(141, 141, 141,1)",
+ })
+ level.fillBG.push({ //door bathroom //top border
+ x: 3800,
+ y: -1275,
+ width: 250,
+ height: 3,
+ color: "#000",
+ })
+ level.fillBG.push({ //door bathroom //right border
+ x: 4048,
+ y: -1275,
+ width: 3,
+ height: 425,
+ color: "#000",
+ })
+ level.fillBG.push({ //door bathroom //left border
+ x: 3800,
+ y: -1275,
+ width: 3,
+ height: 425,
+ color: "#000",
+ })
+ level.fillBG.push({ //poignée door bathroom
+ x: 3830,
+ y: -1050,
+ width: 35,
+ height: 10,
+ color: "#000",
+ })
+ level.fillBG.push({ //background bathroom
+ x: 4050,
+ y: -1425,
+ width: 1125,
+ height: 600,
+ // color:"#c1d7db"
+ color: "rgba(225, 242, 245,0.6)"
+ })
+ level.fillBG.push({ //window
+ x: 1736,
+ y: -1300,
+ width: 3,
+ height: 150,
+ color: "#444"
+ })
+ level.fillBG.push({ //window
+ x: 1650,
+ y: -1224,
+ width: 175,
+ height: 3,
+ color: "#444"
+ })
+ let color = Math.random().toString(16).substr(-6);
+ level.fillBG.push({ //écran
+ x: 3375,
+ y: -625,
+ width: 375,
+ height: 175,
+ color: '#' + color
+ })
+ level.fill.push({ //hidden zone
+ x: 2800,
+ y: -400,
+ width: 275,
+ height: 175,
+ color: "rgba(64,64,64,0.96)"
+ })
+
+
+ function drawCarreaux(x, y, width, height) {
+ level.fillBG.push({ //carreaux
+ x: x,
+ y: y,
+ width: width,
+ height: height,
+ color: "rgba(166, 166, 166,0.8)"
+ })
+ }
+ for (let i = 0; i < 28; i++) {
+ drawCarreaux(4050 + i * 40, -1425, 1, 600);
+ }
+ for (let i = 0; i < 15; i++) {
+ drawCarreaux(4050, -1425 + i * 40, 1125, 2);
+ }
+
+ const part1 = Matter.Bodies.rectangle(4525, -455, 25, 200, {
+ density: 0.0005,
+ isNotHoldable: true,
+ });
+ const part2 = Matter.Bodies.rectangle(4562, -435, 100, 25, {
+ density: 0.0005,
+ isNotHoldable: true,
+ });
+ const part3 = Matter.Bodies.rectangle(4600, -402, 25, 91.5, {
+ density: 0.0005,
+ isNotHoldable: true,
+ });
+ const part4 = Matter.Bodies.rectangle(5100, -455, 25, 200, {
+ density: 0.0005,
+ isNotHoldable: true,
+ });
+ const part5 = Matter.Bodies.rectangle(5063, -435, 100, 25, {
+ density: 0.0005,
+ isNotHoldable: true,
+ });
+ const part6 = Matter.Bodies.rectangle(5025, -402, 25, 91.5, {
+ density: 0.0005,
+ isNotHoldable: true,
+ });
+ chair = Body.create({
+ parts: [part1, part2, part3],
+ });
+ chair2 = Body.create({
+ parts: [part4, part5, part6],
+ });
+ World.add(engine.world, [chair]);
+ World.add(engine.world, [chair2]);
+ composite[composite.length] = chair;
+ composite[composite.length] = chair2;
+ body[body.length] = part1;
+ body[body.length] = part2;
+ body[body.length] = part3;
+ body[body.length] = part4;
+ body[body.length] = part5;
+ body[body.length] = part6;
+ setTimeout(function () {
+ chair.collisionFilter.category = cat.body;
+ chair.collisionFilter.mask = cat.body | cat.player | cat.bullet | cat.mob | cat.mobBullet | cat.map
+ }, 1000);
+ setTimeout(function () {
+ chair2.collisionFilter.category = cat.body;
+ chair2.collisionFilter.mask = cat.body | cat.player | cat.bullet | cat.mob | cat.mobBullet | cat.map
+ }, 1000);
+ var head = Matter.Bodies.rectangle(300, -400 - 60, 34, 40, {
+ isNotHoldable: true,
+ });
+ var chest = Matter.Bodies.rectangle(300, -400, 55, 80, {
+ isNotHoldable: true,
+ });
+ var rightUpperArm = Matter.Bodies.rectangle(300 + 39, -400 - 15, 20, 40, {
+ isNotHoldable: true,
+ });
+ var rightLowerArm = Matter.Bodies.rectangle(300 + 39, -400 + 25, 20, 60, {
+ isNotHoldable: true,
+ });
+ var leftUpperArm = Matter.Bodies.rectangle(300 - 39, -400 - 15, 20, 40, {
+ isNotHoldable: true,
+ });
+ var leftLowerArm = Matter.Bodies.rectangle(300 - 39, -400 + 25, 20, 60, {
+ isNotHoldable: true,
+ });
+ var leftUpperLeg = Matter.Bodies.rectangle(300 - 20, -400 + 57, 20, 40, {
+ isNotHoldable: true,
+ });
+ var leftLowerLeg = Matter.Bodies.rectangle(300 - 20, -400 + 97, 20, 60, {
+ isNotHoldable: true,
+ });
+ var rightUpperLeg = Matter.Bodies.rectangle(300 + 20, -400 + 57, 20, 40, {
+ isNotHoldable: true,
+ });
+ var rightLowerLeg = Matter.Bodies.rectangle(300 + 20, -400 + 97, 20, 60, {
+ isNotHoldable: true,
+ });
+
+ var person = Body.create({
+ parts: [chest, head, leftLowerArm, leftUpperArm,
+ rightLowerArm, rightUpperArm, leftLowerLeg,
+ rightLowerLeg, leftUpperLeg, rightUpperLeg
+ ],
+ });
+ World.add(engine.world, [person]);
+ composite[composite.length] = person
+ body[body.length] = chest
+ body[body.length] = head
+ body[body.length] = part3
+ body[body.length] = leftLowerLeg
+ body[body.length] = leftUpperLeg
+ body[body.length] = leftUpperArm
+ body[body.length] = leftLowerArm
+ body[body.length] = rightLowerLeg
+ body[body.length] = rightUpperLeg
+ body[body.length] = rightLowerArm
+ body[body.length] = rightUpperArm
+ setTimeout(function () {
+ person.collisionFilter.category = cat.body;
+ person.collisionFilter.mask = cat.body | cat.player | cat.bullet | cat.mob | cat.mobBullet | cat.map
+ }, 1000);
+
+ level.custom = () => {
+ buttonBedroom.query();
+ buttonBedroom.draw();
+ if (buttonBedroom.isUp) {
+ if (hasAlreadyBeenActivated == false) {
+ doorBedroom.isOpen = true;
+ doorGrenier.isOpen = true;
+ voletLucarne1.isOpen = true;
+ voletLucarne2.isOpen = true;
+ voletLucarne3.isOpen = true;
+ voletLucarne4.isOpen = true;
+ voletLucarne5.isOpen = true;
+ voletLucarne6.isOpen = true;
+ }
+ } else {
+ doorBedroom.isOpen = false;
+ doorGrenier.isOpen = false;
+ voletLucarne1.isOpen = false;
+ voletLucarne2.isOpen = false;
+ voletLucarne3.isOpen = false;
+ voletLucarne4.isOpen = false;
+ voletLucarne5.isOpen = false;
+ voletLucarne6.isOpen = false;
+ if (hasAlreadyBeenActivated == false) {
+ hasAlreadyBeenActivated = true;
+ }
+ }
+ doorBedroom.openClose();
+ doorGrenier.openClose();
+ voletLucarne1.openClose();
+ voletLucarne2.openClose();
+ voletLucarne3.openClose();
+ voletLucarne4.openClose();
+ voletLucarne5.openClose();
+ voletLucarne6.openClose();
+ rotor.rotate();
+ hazard.query();
+ ///
+ grd = ctx.createRadialGradient(512.5, -1025, 5, 512.5, -1025, 100);
+ grd.addColorStop(0, "rgb(255, 199, 43)");
+ grd.addColorStop(1, "#969696");
+ ctx.fillStyle = grd;
+ ctx.fillRect(450, -1025, 125, 100);
+ ///
+ grd = ctx.createRadialGradient(762.5, -1025, 5, 762.5, -1025, 100);
+ grd.addColorStop(0, "rgb(255, 199, 43, 1)");
+ grd.addColorStop(1, "#969696");
+ ctx.fillStyle = grd;
+ ctx.fillRect(700, -1025, 125, 100);
+ ///
+ ctx.lineWidth = 7;
+ ctx.strokeStyle = "#444444"
+ ctx.strokeRect(1650, -1300, 175, 150);
+
+ chair.force.y += chair.mass * game.g;
+ chair2.force.y += chair2.mass * game.g;
+ person.force.y += person.mass * game.g;
+ };
+ level.customTopLayer = () => {
+ hazard.draw();
+ doorBedroom.draw();
+ doorGrenier.draw();
+ voletLucarne1.draw();
+ voletLucarne2.draw();
+ voletLucarne3.draw();
+ voletLucarne4.draw();
+ voletLucarne5.draw();
+ voletLucarne6.draw();
+ };
+
+ //rez de chaussée
+ spawn.mapRect(-200, 0, 5200, 100); //ground
+ spawn.mapRect(1150, -255, 4050, 355); //additionnal ground
+ spawn.mapRect(800, -255, 400, 90); //1st step
+ spawn.mapRect(650, -170, 550, 90); //2nd step
+ spawn.mapRect(500, -85, 700, 90); //3rd step
+ spawn.mapRect(1150, -850, 50, 175); //porte entrée
+ spawn.bodyRect(1162.5, -675, 25, 420) //porte entrée
+ spawn.mapRect(1150, -850, 1500, 50); //plafond 1
+ spawn.mapRect(3025, -850, 2175, 50); //plafond 2
+ spawn.mapRect(5150, -850, 50, 650); //mur cuisine
+ //lave-vaisselle
+ spawn.mapRect(4225, -400, 25, 150);
+ spawn.mapRect(4225, -400, 175, 25);
+ spawn.mapRect(4375, -400, 25, 150);
+ spawn.bodyRect(4350, -350, 20, 40);
+ spawn.bodyRect(4325, -325, 20, 20);
+ spawn.bodyRect(4325, -275, 20, 20);
+ /*escalier*/
+ spawn.mapRect(3025, -850, 50, 225);
+ spawn.mapRect(2925, -775, 150, 150);
+ spawn.mapRect(2800, -700, 275, 75);
+ spawn.mapRect(2575, -400, 175, 175);
+ spawn.mapRect(2475, -325, 175, 100);
+ // spawn.mapRect(2675, -475, 400, 250);
+ spawn.mapRect(2675, -475, 400, 100);
+ spawn.mapRect(2675, -475, 150, 250);
+ spawn.mapRect(4025, -850, 50, 175); //porte cuisine
+ /*table + chaises*/
+ spawn.mapRect(4025, -850, 50, 175);
+ spawn.mapRect(4650, -375, 325, 25);
+ spawn.mapRect(4700, -350, 25, 100);
+ spawn.mapRect(4900, -350, 25, 100);
+ spawn.bodyRect(4875, -400, 75, 25);
+ spawn.bodyRect(4700, -400, 75, 25);
+ /*murs télé*/
+ spawn.mapRect(3400, -400, 20, 150);
+ spawn.mapRect(3705, -400, 20, 150);
+ spawn.mapRect(3400, -400, 325, 20);
+ /*socle écran*/
+ spawn.mapRect(3500, -415, 125, 17);
+ spawn.mapRect(3550, -450, 25, 50);
+
+ //premier étage
+ spawn.mapRect(1150, -1450, 4050, 50);
+ spawn.mapRect(5150, -1450, 50, 650);
+ spawn.mapRect(1150, -1450, 50, 300);
+ spawn.mapRect(1150, -900, 50, 100);
+ spawn.mapVertex(1066, -730, "-200 60 0 -60 100 -60 100 60")
+ //chambre
+ spawn.mapRect(2350, -1450, 50, 175); //porte chambre
+ //lit
+ spawn.mapRect(1475, -1025, 25, 225); //pied de lit 1
+ spawn.mapRect(1850, -925, 25, 125); //pied de lit 2
+ spawn.mapRect(1475, -925, 400, 50); //sommier
+ spawn.bodyRect(1500, -950, 375, 25); //matelat
+ spawn.bodyRect(1500, -1000, 75, 50); //oreiller
+ //table
+ spawn.bodyRect(1950, -1000, 30, 150); //pied table
+ spawn.bodyRect(2250, -1000, 30, 150); //pied table
+ spawn.bodyRect(1920, -1025, 390, 25); //table
+ //salle de bain
+ spawn.mapRect(4025, -1450, 50, 175); //porte salle de bain
+ map[map.length] = Bodies.polygon(5050, -925, 0, 35.4);
+ spawn.mapRect(5015, -960, 125, 40);
+ spawn.mapRect(5050, -925, 90, 35.4);
+ spawn.mapVertex(5086.5, -875, "100 60 -30 60 20 0 100 0")
+ spawn.mapRect(5125, -1070, 15, 120)
+ spawn.bodyRect(5016, -965, 108, 15)
+ //baignoire
+ spawn.mapVertex(4316, -965, "30 100 0 100 -80 -50 30 -50") //bord 1
+ spawn.mapVertex(4675, -961.5, "30 100 0 100 0 -50 80 -50") //bord 2
+ spawn.mapVertex(4400, -860, "0 -20 -20 20 20 20 0 -20") //pied 1
+ spawn.mapVertex(4600, -860, "0 -20 -20 20 20 20 0 -20") //pied 2
+ spawn.mapRect(4325, -900, 350, 25); //fond baignoire
+ spawn.mapRect(4300, -1175, 25, 175);
+ spawn.mapRect(4300, -1175, 125, 25);
+ spawn.mapRect(4400, -1175, 25, 50); //pied pommeau de douche
+ spawn.mapVertex(4412.5, -1105, "-20 -20 -30 40 30 40 20 -20") //pommeau de douche
+
+ //grenier
+ // spawn.mapRect(1150, -1800, 50, 400);
+ spawn.mapRect(1150, -1475, 50, 50);
+ spawn.mapRect(1150, -1800, 50, 175);
+ spawn.mapRect(5150, -1800, 50, 400); //murs
+ spawn.mapVertex(1300, -1900, "-150 200 -200 200 50 0 100 0");
+ spawn.mapVertex(1800, -2300, "-150 200 -200 200 175 -100 225 -100");
+ spawn.mapRect(1390, -2180, 250, 30); //lucarne
+ spawn.mapVertex(5050, -1900, "150 200 200 200 -50 0 -100 0");
+ spawn.mapVertex(4550, -2300, "150 200 200 200 -175 -100 -225 -100");
+ spawn.mapRect(4710, -2175, 250, 25); //lucarne 2
+ //obstacles
+ spawn.mapRect(3775, -1800, 99, 50);
+ spawn.mapRect(2425, -2150, 50, 425);
+ spawn.mapRect(2150, -1775, 325, 50);
+ spawn.mapRect(3825, -2150, 50, 750);
+ spawn.mapRect(3826, -2150, 149, 50);
+ spawn.mapRect(4125, -2150, 149, 50);
+ spawn.mapRect(4225, -2150, 50, 450);
+ spawn.mapRect(4225, -1750, 250, 50);
+ // level.chain(2475, -2150, 2900, -2150, 8);
+ spawn.bodyRect(2350, -1850, 75, 75);
+ spawn.bodyRect(4275, -1900, 75, 100);
+ spawn.bodyRect(4825, -1650, 325, 200);
+ spawn.bodyRect(5025, -1725, 25, 25);
+ spawn.bodyRect(4900, -1700, 200, 75);
+ spawn.mapVertex(2975, -2096, "-75 -50 75 -50 75 0 0 100 -75 0")
+
+ /*cheminée + roof*/
+ spawn.mapRect(1963, -2450, 2425, 35);
+ spawn.mapRect(2925, -2900, 125, 480);
+ spawn.mapRect(2900, -2900, 175, 75);
+ spawn.mapRect(2900, -2975, 25, 100);
+ spawn.mapRect(3050, -2975, 25, 100);
+ spawn.mapRect(2875, -3000, 225, 25);
+ /*lampadaire + jump*/
+ spawn.mapRect(1000, -1450, 200, 25);
+ spawn.mapRect(500, -1150, 275, 25);
+ spawn.mapRect(750, -1150, 25, 75);
+ spawn.mapRect(500, -1150, 25, 75);
+ spawn.mapRect(450, -1075, 125, 50);
+ spawn.mapRect(700, -1075, 125, 50);
+ spawn.mapRect(2985, -4600, 0.1, 1700)
+
+ //Mobs
+ // spawn.mobBloc(3015, -315, 84.855, "#ffff");
+
+
+ },
+
+
+
testing() {
level.custom = () => {
level.playerExitCheck();
@@ -635,12 +1116,7 @@ const level = {
level.custom = () => {
level.playerExitCheck();
};
- // ctx.font = "30px Arial";
- // ctx.textAlign = "center";
- level.customTopLayer = () => {
- // ctx.fillStyle = '#000';
- // ctx.fillText(`${(localSettings.runCount >>> 0).toString(2)}`, 2850, -530);
- };
+ level.customTopLayer = () => {};
const binary = (localSettings.runCount >>> 0).toString(2)
const height = 25
const thick = 2
@@ -811,17 +1287,71 @@ const level = {
powerUps.spawn(1900, -150, "heal", false); //starting gun
powerUps.spawn(2050, -150, "heal", false); //starting gun
// powerUps.spawn(2050, -150, "field", false); //starting gun
- powerUps.spawnStartingPowerUps(2300, -150);
+ // localSettings.levelsClearedLastGame = 20
+ if (localSettings.levelsClearedLastGame < 5) {
+ spawn.wireFoot();
+ spawn.wireFootLeft();
+ spawn.wireKnee();
+ spawn.wireKneeLeft();
+ spawn.wireHead();
+ } else {
+ const say = []
+ if (localSettings.runCount > 200) { //experienced
+ say.push(
+ "I've been here before...",
+ "How many times have I done this?",
+ )
+ } else if (localSettings.runCount < 20) { //new
+ say.push(
+ "Am I still alive?",
+ "And I'm back here again...",
+ "Is this another simulation?",
+ "I'm alive...",
+ "Last time was a simulation. Is this one a simulation too?",
+ )
+ }
+ if (game.difficultyMode < 2 && localSettings.levelsClearedLastGame > 10) { //too easy
+ say.push(
+ "That felt too easy.
Maybe I should increase the difficulty of the simulation.",
+ "That was fun, but maybe I should increase the difficulty of the simulation.",
+ "I should increase the difficulty of the simulation, that didn't feel realistic.",
+ )
+ } else if (game.difficultyMode > 1 && localSettings.levelsClearedLastGame > 10) { //great run on a hard or why
+ say.push(
+ "I think I'm getting closer to to the end, but what will I find there?",
+ "I think I'm getting closer to something, but what?",
+ "I'm getting stronger.",
+ "What happens after I escape?",
+ )
+ } else { //resolve
+ say.push(
+ "I'll try some different mods this time.",
+ "I've got to escape.",
+ "I'll find a way out.",
+ )
+ }
+ game.makeTextLog(say[Math.floor(say.length * Math.random())], 1000)
- spawn.wireFoot();
- spawn.wireFootLeft();
- spawn.wireKnee();
- spawn.wireKneeLeft();
- spawn.wireHead();
+ const swapPeriod = 150
+ const len = 30
+ for (let i = 0; i < len; i++) {
+ setTimeout(function () {
+ game.wipe = function () { //set wipe to have trails
+ ctx.fillStyle = `rgba(221,221,221,${i*i*0.0005 +0.0025})`;
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+ }
+ }, (i) * swapPeriod);
+ }
+
+ setTimeout(function () {
+ game.wipe = function () { //set wipe to normal
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ }
+ }, len * swapPeriod);
+ }
+ powerUps.spawnStartingPowerUps(2300, -150);
},
satellite() {
- // level.chain(4025, -1175, 15, 20)
-
const elevator = level.platform(4210, -1325, 380, 30, -10)
level.custom = () => {
level.playerExitCheck();
@@ -2443,7 +2973,7 @@ const level = {
buttonDoor.query();
buttonPlateformEnd.draw();
buttonPlateformEnd.query();
- hazard.query();
+ // hazard.query(); //bug reported from discord?
if (buttonDoor.isUp) {
door.isOpen = false
} else {
@@ -3826,28 +4356,35 @@ const level = {
}
},
level(isFill) {
- const growSpeed = 1
- if (isFill) {
- if (this.height < this.maxHeight) {
- this.height += growSpeed
- this.min.y -= growSpeed
+ if (mech.isBodiesAsleep) {
+ const growSpeed = 1
+ if (isFill) {
+ if (this.height < this.maxHeight) {
+ this.height += growSpeed
+ this.min.y -= growSpeed
+ this.max.y = this.min.y + this.height
+ }
+ } else if (this.height > 0) {
+ this.height -= growSpeed
+ this.min.y += growSpeed
this.max.y = this.min.y + this.height
}
- } else if (this.height > 0) {
- this.height -= growSpeed
- this.min.y += growSpeed
- this.max.y = this.min.y + this.height
}
}
}
},
- chain(x, y, len = 15, radius = 20, stiffness = 0.4, damping = 0.01) {
+ chain(x, y, angle = 0, isAttached = true, len = 15, radius = 20, stiffness = 1, damping = 1) {
+ const gap = 2 * radius
+ const unit = {
+ x: Math.cos(angle),
+ y: Math.sin(angle)
+ }
for (let i = 0; i < len; i++) {
- body[body.length] = Bodies.polygon(x, y + 2 * radius * i, 12, radius, {
+ body[body.length] = Bodies.polygon(x + gap * unit.x * i, y + gap * unit.y * i, 12, radius, {
inertia: Infinity
});
}
- for (let i = 1; i < len; i++) {
+ for (let i = 1; i < len; i++) { //attach blocks to each other
consBB[consBB.length] = Constraint.create({
bodyA: body[body.length - i],
bodyB: body[body.length - i - 1],
@@ -3858,11 +4395,22 @@ const level = {
cons[cons.length] = Constraint.create({ //pin first block to a point in space
pointA: {
x: x,
- y: y - radius
+ y: y
},
bodyB: body[body.length - len],
- stiffness: stiffness,
+ stiffness: 1,
damping: damping
});
+ if (isAttached) {
+ cons[cons.length] = Constraint.create({ //pin last block to a point in space
+ pointA: {
+ x: x + gap * unit.x * (len - 1),
+ y: y + gap * unit.y * (len - 1)
+ },
+ bodyB: body[body.length - 1],
+ stiffness: 1,
+ damping: damping
+ });
+ }
},
};
\ No newline at end of file
diff --git a/js/mob.js b/js/mob.js
index d579395..7fec3d2 100644
--- a/js/mob.js
+++ b/js/mob.js
@@ -1042,7 +1042,7 @@ const mobs = {
}
}
if (Math.random() < mod.isBotSpawner) b.randomBot(this.position, false)
- if (mod.isExplodeMob) b.explosion(this.position, Math.min(450, Math.sqrt(this.mass + 3) * 80))
+ if (mod.isExplodeMob) b.explosion(this.position, Math.min(425, Math.sqrt(this.mass + 3) * 70))
if (mod.nailsDeathMob) b.targetedNail(this.position, mod.nailsDeathMob, 40 + 7 * Math.random())
} else if (mod.isShieldAmmo && this.shield) {
let type = "ammo"
diff --git a/js/mods.js b/js/mods.js
index 2dddce2..bd09bca 100644
--- a/js/mods.js
+++ b/js/mods.js
@@ -367,6 +367,22 @@ const mod = {
mod.sporesOnDeath = 0;
}
},
+ {
+ name: "impact shear",
+ description: "mobs release a nail when they die
nails target nearby mobs",
+ maxCount: 9,
+ count: 0,
+ allowed() {
+ return true
+ },
+ requires: "",
+ effect: () => {
+ mod.nailsDeathMob++
+ },
+ remove() {
+ mod.nailsDeathMob = 0;
+ }
+ },
{
name: "thermal runaway",
description: "mobs explode when they die
be careful",
@@ -384,19 +400,51 @@ const mod = {
}
},
{
- name: "impact shear",
- description: "mobs release 1-2 nails when they die
nails target nearby mobs",
- maxCount: 9,
+ name: "trinitrotoluene",
+ description: "increase explosive damage by 50%
decrease explosive area by 71%",
+ maxCount: 1,
count: 0,
allowed() {
- return true
+ return mod.haveGunCheck("missiles") || mod.haveGunCheck("flak") || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || mod.haveGunCheck("pulse") || mod.isMissileField || mod.boomBotCount > 1;
},
- requires: "",
+ requires: "an explosive damage source",
effect: () => {
- mod.nailsDeathMob += 2
+ mod.isSmallExplosion = true;
},
remove() {
- mod.nailsDeathMob = 0;
+ mod.isSmallExplosion = false;
+ }
+ },
+ {
+ name: "ammonium nitrate",
+ description: "increase explosive area by 60%, but
you take 300% more harm from explosions",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return mod.haveGunCheck("missiles") || mod.haveGunCheck("flak") || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || mod.haveGunCheck("pulse") || mod.isMissileField
+ },
+ requires: "an explosive damage source",
+ effect: () => {
+ mod.isExplosionHarm = true;
+ },
+ remove() {
+ mod.isExplosionHarm = false;
+ }
+ },
+ {
+ name: "electric reactive armor",
+ description: "explosions do no harm
while your energy is full",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return mod.haveGunCheck("missiles") || mod.haveGunCheck("flak") || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || mod.isMissileField || mod.isExplodeMob
+ },
+ requires: "an explosive gun",
+ effect: () => {
+ mod.isImmuneExplosion = true;
+ },
+ remove() {
+ mod.isImmuneExplosion = false;
}
},
{
@@ -612,9 +660,9 @@ const mod = {
// isNonRefundable: true,
isCustomHide: true,
allowed() {
- return mod.totalBots() > 2
+ return mod.totalBots() > 3
},
- requires: "3 or more bots",
+ requires: "at least 3 bots",
effect() {
b.removeAllGuns();
game.makeGunHUD();
@@ -1029,7 +1077,7 @@ const mod = {
},
{
name: "Bayesian statistics",
- description: "20% chance to duplicate spawned power ups
after a collision, eject one of your mods",
+ description: "17% chance to duplicate spawned power ups
after a collision, eject one of your mods",
maxCount: 1,
count: 0,
allowed() {
@@ -1111,9 +1159,9 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
- return true
+ return !mod.isEnergyNoAmmo
},
- requires: "",
+ requires: "not exciton-lattice",
effect() {
mod.isAmmoForGun = true;
},
@@ -1145,9 +1193,9 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
- return !mod.isEnergyHealth
+ return !mod.isEnergyHealth && !mod.isEnergyNoAmmo
},
- requires: "not mass-energy equivalence",
+ requires: "not mass-energy equivalence
not exciton-lattice",
effect: () => {
mod.isAmmoFromHealth = 0.023;
},
@@ -1691,52 +1739,20 @@ const mod = {
mod.isWaveReflect = false
}
},
- {
- name: "high explosives",
- description: "increase explosion damage by 20%
explosive area is 44% larger",
- maxCount: 3,
- count: 0,
- allowed() {
- return mod.haveGunCheck("missiles") || mod.haveGunCheck("flak") || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || mod.haveGunCheck("pulse") || mod.isMissileField;
- },
- requires: "an explosive gun",
- effect: () => {
- mod.explosionRadius += 0.2;
- },
- remove() {
- mod.explosionRadius = 1;
- }
- },
- {
- name: "electric reactive armor",
- description: "explosions do no harm
while your energy is above 75%",
- maxCount: 1,
- count: 0,
- allowed() {
- return mod.haveGunCheck("missiles") || mod.haveGunCheck("flak") || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || (mod.haveGunCheck("pulse") && mech.maxEnergy > 1) || mod.isMissileField || mod.isExplodeMob
- },
- requires: "an explosive gun",
- effect: () => {
- mod.isImmuneExplosion = true;
- },
- remove() {
- mod.isImmuneExplosion = false;
- }
- },
{
name: "recursion",
- description: "after missiles explode
they launch 1 smaller missile",
- maxCount: 9,
+ description: "after missiles explode they have a
30% chance to launch a larger missile",
+ maxCount: 6,
count: 0,
allowed() {
return mod.haveGunCheck("missiles") || mod.isMissileField
},
requires: "missiles",
effect() {
- mod.babyMissiles++
+ mod.recursiveMissiles++
},
remove() {
- mod.babyMissiles = 0;
+ mod.recursiveMissiles = 0;
}
},
{
@@ -2599,7 +2615,6 @@ const mod = {
],
//variables use for gun mod upgrades
fireRate: null,
- explosionRadius: null,
bulletSize: null,
energySiphon: null,
healthDrain: null,
@@ -2651,7 +2666,7 @@ const mod = {
isPlasmaRange: null,
isRailNails: null,
isFreezeMobs: null,
- babyMissiles: null,
+ recursiveMissiles: null,
isIceCrystals: null,
throwChargeRate: null,
isBlockStun: null,
@@ -2721,5 +2736,7 @@ const mod = {
nailInstantFireRate: null,
isCapacitor: null,
isEnergyNoAmmo: null,
- isFreezeHarmImmune: null
+ isFreezeHarmImmune: null,
+ isSmallExplosion: null,
+ isExplosionHarm: null
}
\ No newline at end of file
diff --git a/js/player.js b/js/player.js
index dddd6f9..7813f22 100644
--- a/js/player.js
+++ b/js/player.js
@@ -490,13 +490,13 @@ const mech = {
damage(dmg) {
mech.lastHarmCycle = mech.cycle
if (mod.isDroneOnDamage) { //chance to build a drone on damage from mod
- const len = (dmg - 0.06 * Math.random()) * 40
+ const len = Math.min((dmg - 0.06 * Math.random()) * 40, 40)
for (let i = 0; i < len; i++) {
if (Math.random() < 0.5) b.drone() //spawn drone
}
}
if (mod.isEnergyHealth) {
- mech.energy -= dmg * 1.2; //20% extra damage for energy as health for balance reasons
+ mech.energy -= dmg;
if (mech.energy < 0 || isNaN(mech.energy)) { //taking deadly damage
if (mod.isDeathAvoid && powerUps.reroll.rerolls) {
powerUps.reroll.changeRerolls(-1)
@@ -660,13 +660,6 @@ const mech = {
mech.knee.x = (l / d) * (mech.foot.x - mech.hip.x) - (h / d) * (mech.foot.y - mech.hip.y) + mech.hip.x + offset;
mech.knee.y = (l / d) * (mech.foot.y - mech.hip.y) + (h / d) * (mech.foot.x - mech.hip.x) + mech.hip.y;
},
- // collisionImmune: false,
- // beginCollisionImmune() {
-
- // },
- // endCollisionImmune() {
-
- // },
draw() {
ctx.fillStyle = mech.fillColor;
mech.walk_cycle += mech.flipLegs * mech.Vx;
@@ -1362,7 +1355,7 @@ const mech = {
},
mech.angle + (0.5 - Math.random()) * (mech.crouch ? 0 : 0.2),
-3 * (0.5 - Math.random()) + (mech.crouch ? 25 : -8) * b.fireCD,
- 1, mod.babyMissiles)
+ 1, mod.recursiveMissiles)
} else if (mod.isIceField) {
// mech.fieldCDcycle = mech.cycle + 17; // set cool down to prevent +energy from making huge numbers of drones
mech.energy -= 0.04;
@@ -1772,15 +1765,8 @@ const mech = {
mech.fieldPhase = 0;
mech.hold = function () {
- // function expandField() {
- // if (this.fieldRange < 2000) {
- // this.fieldRange += 100
- // drawField(this.fieldRange)
- // }
- // }
-
function drawField(radius) {
- radius *= 0.9 + 2.2 * mech.energy * mech.energy;
+ radius *= Math.min(4, 0.9 + 2.2 * mech.energy * mech.energy);
const rotate = mech.cycle * 0.005;
mech.fieldPhase += 0.5 - 0.5 * Math.sqrt(Math.max(0.01, Math.min(mech.energy, 1)));
const off1 = 1 + 0.06 * Math.sin(mech.fieldPhase);
diff --git a/js/powerup.js b/js/powerup.js
index 4d6721b..411837e 100644
--- a/js/powerup.js
+++ b/js/powerup.js
@@ -455,7 +455,7 @@ const powerUps = {
randomPowerUpCounter: 0,
spawnBossPowerUp(x, y) { //boss spawns field and gun mod upgrades
powerUps.randomPowerUpCounter++;
- if (game.difficultyMode === 4) spawnPowerUps() //why mode gets a free power up chance
+ if (game.difficultyMode === 4) powerUps.spawn(x, y, "mod") //why mode gets a free mod
const chanceToFail = Math.max(level.levelsCleared, 10) * 0.1 //1 until level 10, then 1.1, 1.2, 1.3, ...
if (Math.random() * chanceToFail < powerUps.randomPowerUpCounter) {
powerUps.randomPowerUpCounter = 0;
@@ -499,11 +499,12 @@ const powerUps = {
},
spawnStartingPowerUps(x, y) { //used for map specific power ups, mostly to give player a starting gun
if (level.levelsCleared < 4) { //runs 4 times on all difficulty levels
+ if (game.difficultyMode === 4 && level.levelsCleared > 1) powerUps.spawn(x, y, "mod")
//bonus power ups for clearing runs in the last game
if (level.levelsCleared === 0 && !game.isCheating) {
for (let i = 0; i < localSettings.levelsClearedLastGame / 5 - 1; i++) {
- powerUps.spawn(x, y, "mod", false); //spawn a mod for every 5 levels cleared in last game
+ powerUps.spawn(mech.pos.x, mech.pos.y, "mod", false); //spawn a mod for every 5 levels cleared in last game
}
localSettings.levelsClearedLastGame = 0 //after getting bonus power ups reset run history
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
@@ -569,7 +570,7 @@ const powerUps = {
!(mod.isEnergyNoAmmo && target === 'ammo')
) {
powerUps.directSpawn(x, y, target, moving, mode)
- if (mod.isBayesian && Math.random() < 0.2) powerUps.directSpawn(x, y, target, moving, mode)
+ if (mod.isBayesian && Math.random() < 0.17) powerUps.directSpawn(x, y, target, moving, mode)
}
},
};
\ No newline at end of file
diff --git a/js/spawn.js b/js/spawn.js
index 04f6743..38955bb 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -1146,18 +1146,20 @@ const spawn = {
});
Matter.Body.setPosition(this, this.startingPosition);
- ctx.beginPath();
- this.laser(this.vertices[0], this.angle + Math.PI / 3);
- this.laser(this.vertices[1], this.angle + Math.PI);
- this.laser(this.vertices[2], this.angle - Math.PI / 3);
- ctx.strokeStyle = "#50f";
- ctx.lineWidth = 1.5;
- ctx.setLineDash([70 + 300 * Math.random(), 55 * Math.random()]);
- ctx.stroke(); // Draw it
- ctx.setLineDash([0, 0]);
- ctx.lineWidth = 20;
- ctx.strokeStyle = "rgba(80,0,255,0.07)";
- ctx.stroke(); // Draw it
+ if (!this.isStunned) {
+ ctx.beginPath();
+ this.laser(this.vertices[0], this.angle + Math.PI / 3);
+ this.laser(this.vertices[1], this.angle + Math.PI);
+ this.laser(this.vertices[2], this.angle - Math.PI / 3);
+ ctx.strokeStyle = "#50f";
+ ctx.lineWidth = 1.5;
+ ctx.setLineDash([70 + 300 * Math.random(), 55 * Math.random()]);
+ ctx.stroke(); // Draw it
+ ctx.setLineDash([0, 0]);
+ ctx.lineWidth = 20;
+ ctx.strokeStyle = "rgba(80,0,255,0.07)";
+ ctx.stroke(); // Draw it
+ }
// this.laser(this.vertices[2], this.angle + Math.PI / 3);
this.checkStatus();
};
diff --git a/todo.txt b/todo.txt
index bf1dd82..d87ea93 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,6 +1,22 @@
+mod: recursion - gives missiles a 30% chance to spawn a larger missile when they explode
+mod: electric reactive armor - immune to harm from explosions while energy is full (was 80%)
+
+mod: ammonium nitrate - explosions are 60% bigger, but they do 300% more damage to you
+mod: trinitrotoluene - explosions are 50% smaller and do 71% more damage
+
************** TODO - n-gon **************
+mod: radiation effects can spread to nearby mobs
+
+mod: foam is attracted to mobs
+ use a gravitational attraction model?
+ could foam be attracted to other foam bullets too?
+ or foam is only attracted to foam bullets that are stuck to mobs
+ is this too computationally intense?
+ name - static cling
+ could also do bremsstrahlung radiation like damage on attachment
+
change player color based on harm reduction
standing wave harmonics mod - push things away