explosions mods rework

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
This commit is contained in:
landgreen
2020-09-12 06:49:49 -07:00
parent 1b522551ce
commit 5c2319cc75
10 changed files with 731 additions and 143 deletions

View File

@@ -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)) {
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, {

View File

@@ -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);

View File

@@ -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

View File

@@ -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.<br>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)
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,6 +4356,7 @@ const level = {
}
},
level(isFill) {
if (mech.isBodiesAsleep) {
const growSpeed = 1
if (isFill) {
if (this.height < this.maxHeight) {
@@ -3840,14 +4371,20 @@ const level = {
}
}
}
}
},
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
});
}
},
};

View File

@@ -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"

View File

@@ -367,6 +367,22 @@ const mod = {
mod.sporesOnDeath = 0;
}
},
{
name: "impact shear",
description: "mobs release a <strong>nail</strong> when they <strong>die</strong><br>nails target nearby mobs",
maxCount: 9,
count: 0,
allowed() {
return true
},
requires: "",
effect: () => {
mod.nailsDeathMob++
},
remove() {
mod.nailsDeathMob = 0;
}
},
{
name: "thermal runaway",
description: "mobs <strong class='color-e'>explode</strong> when they <strong>die</strong><br><em>be careful</em>",
@@ -384,19 +400,51 @@ const mod = {
}
},
{
name: "impact shear",
description: "mobs release <strong>1-2</strong> <strong>nails</strong> when they <strong>die</strong><br>nails target nearby mobs",
maxCount: 9,
name: "trinitrotoluene",
description: "increase <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong> by <strong>50%</strong><br>decrease <strong class='color-e'>explosive</strong> <strong>area</strong> by <strong>71%</strong>",
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 <strong class='color-e'>explosive</strong> <strong>area</strong> by <strong>60%</strong>, but<br>you take <strong>300%</strong> more <strong class='color-harm'>harm</strong> from <strong class='color-e'>explosions</strong>",
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: "<strong class='color-e'>explosions</strong> do no <strong class='color-harm'>harm</strong><br> while your <strong class='color-f'>energy</strong> is <strong>full</strong>",
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: "<strong>20%</strong> chance to <strong>duplicate</strong> spawned <strong>power ups</strong><br>after a <strong>collision</strong>, <strong>eject</strong> one of your <strong class='color-m'>mods</strong>",
description: "<strong>17%</strong> chance to <strong>duplicate</strong> spawned <strong>power ups</strong><br>after a <strong>collision</strong>, <strong>eject</strong> one of your <strong class='color-m'>mods</strong>",
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<br>not exciton-lattice",
effect: () => {
mod.isAmmoFromHealth = 0.023;
},
@@ -1691,52 +1739,20 @@ const mod = {
mod.isWaveReflect = false
}
},
{
name: "high explosives",
description: "increase <strong class='color-e'>explosion</strong> <strong class='color-d'>damage</strong> by <strong>20%</strong><br><strong class='color-e'>explosive</strong> area is <strong>44% larger</strong>",
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: "<strong class='color-e'>explosions</strong> do no <strong class='color-harm'>harm</strong><br> while your <strong class='color-f'>energy</strong> is above <strong>75%</strong>",
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 <strong>missiles</strong> <strong class='color-e'>explode</strong><br>they launch <strong>1</strong> smaller <strong>missile</strong>",
maxCount: 9,
description: "after <strong>missiles</strong> <strong class='color-e'>explode</strong> they have a<br><strong>30%</strong> chance to launch a larger <strong>missile</strong>",
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
}

View File

@@ -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);

View File

@@ -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)
}
},
};

View File

@@ -1146,6 +1146,7 @@ const spawn = {
});
Matter.Body.setPosition(this, this.startingPosition);
if (!this.isStunned) {
ctx.beginPath();
this.laser(this.vertices[0], this.angle + Math.PI / 3);
this.laser(this.vertices[1], this.angle + Math.PI);
@@ -1158,6 +1159,7 @@ const spawn = {
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();
};

View File

@@ -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