shield rebalance, difficulty rebalance, piezo and static mods
This commit is contained in:
258
js/bullets.js
258
js/bullets.js
@@ -29,6 +29,8 @@ const b = {
|
|||||||
isModFourOptions: null,
|
isModFourOptions: null,
|
||||||
modGuardianCount: null,
|
modGuardianCount: null,
|
||||||
modCollisionImmuneCycles: null,
|
modCollisionImmuneCycles: null,
|
||||||
|
modBlockDmg: null,
|
||||||
|
modPiezo: null,
|
||||||
setModDefaults() {
|
setModDefaults() {
|
||||||
b.modCount = 0;
|
b.modCount = 0;
|
||||||
b.modFireRate = 1;
|
b.modFireRate = 1;
|
||||||
@@ -55,6 +57,8 @@ const b = {
|
|||||||
b.isModMassEnergy = false;
|
b.isModMassEnergy = false;
|
||||||
b.modGuardianCount = 0;
|
b.modGuardianCount = 0;
|
||||||
b.modCollisionImmuneCycles = 30;
|
b.modCollisionImmuneCycles = 30;
|
||||||
|
b.modBlockDmg = 0;
|
||||||
|
b.modPiezo = 0;
|
||||||
mech.Fx = 0.015;
|
mech.Fx = 0.015;
|
||||||
mech.jumpForce = 0.38;
|
mech.jumpForce = 0.38;
|
||||||
mech.maxHealth = 1;
|
mech.maxHealth = 1;
|
||||||
@@ -64,9 +68,8 @@ const b = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mods: [{
|
mods: [{
|
||||||
name: "depleted uranium rounds",
|
name: "depleted uranium rounds", //0
|
||||||
description: `your <strong>bullets</strong> are +11% larger<br>increased mass and physical <strong class='color-d'>damage</strong>`,
|
description: `your <strong>bullets</strong> are +11% larger<br>increased mass and physical <strong class='color-d'>damage</strong>`,
|
||||||
//0
|
|
||||||
count: 0,
|
count: 0,
|
||||||
maxCount: 4,
|
maxCount: 4,
|
||||||
effect() {
|
effect() {
|
||||||
@@ -74,131 +77,127 @@ const b = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "fluoroantimonic acid",
|
name: "fluoroantimonic acid", //1
|
||||||
description: "each <strong>bullet</strong> does extra chemical <strong class='color-d'>damage</strong><br>instant damage, unaffected by momentum",
|
description: "each <strong>bullet</strong> does extra chemical <strong class='color-d'>damage</strong><br>instant damage, unaffected by momentum",
|
||||||
//1
|
|
||||||
maxCount: 4,
|
maxCount: 4,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect() { //good with guns that fire many bullets at low speeds, minigun, drones, junk-bots, shotgun, superballs, wavebeam
|
effect() {
|
||||||
b.modExtraDmg += 0.25
|
b.modExtraDmg += 0.25
|
||||||
game.playerDmgColor = "rgba(0,80,80,0.9)"
|
game.playerDmgColor = "rgba(0,80,80,0.9)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "fracture analysis",
|
name: "fracture analysis", //2
|
||||||
description: "<strong>5x</strong> physical <strong class='color-d'>damage</strong> to unaware enemies<br><em>unaware enemies don't have a health bar</em>",
|
description: "<strong>5x</strong> physical <strong class='color-d'>damage</strong> to unaware enemies<br><em>unaware enemies don't have a health bar</em>",
|
||||||
//2
|
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect() { // good with high damage guns that strike from a distance: rail gun, drones, flechettes, spores, grenade, vacuum bomb
|
effect() {
|
||||||
b.isModCrit = true;
|
b.isModCrit = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "kinetic bombardment",
|
name: "kinetic bombardment", //3
|
||||||
description: "do extra <strong class='color-d'>damage</strong> from a distance<br><em>up to 50% increase at about 30 steps away</em>",
|
description: "do extra <strong class='color-d'>damage</strong> from a distance<br><em>up to 50% increase at about 30 steps away</em>",
|
||||||
//3
|
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect() { // good with annihilation, melee builds
|
effect() {
|
||||||
b.isModFarAwayDmg = true; //used in mob.damage()
|
b.isModFarAwayDmg = true; //used in mob.damage()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "quasistatic equilibrium",
|
name: "quasistatic equilibrium", //4
|
||||||
description: "do extra <strong class='color-d'>damage</strong> at low health<br><em>up to 50% increase when near death</em>",
|
description: "do extra <strong class='color-d'>damage</strong> at low health<br><em>up to 50% increase when near death</em>",
|
||||||
//4
|
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect() { // good with annihilation, melee builds
|
effect() {
|
||||||
b.isModLowHealthDmg = true; //used in mob.damage()
|
b.isModLowHealthDmg = true; //used in mob.damage()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "auto-loading heuristics",
|
name: "auto-loading heuristics", //5
|
||||||
description: "your <strong>delay</strong> after firing is +12% <strong>shorter</strong>",
|
description: "your <strong>delay</strong> after firing is +12% <strong>shorter</strong>",
|
||||||
//5
|
|
||||||
maxCount: 4,
|
maxCount: 4,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect() { //good for guns with extra ammo: needles, M80, rapid fire, flak, super balls
|
effect() {
|
||||||
b.modFireRate *= 0.88
|
b.modFireRate *= 0.88
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "desublimated ammunition",
|
name: "desublimated ammunition", //6
|
||||||
description: "use 50% less <strong>ammo</strong> when <strong>crouching</strong>",
|
description: "use 50% less <strong>ammo</strong> when <strong>crouching</strong>",
|
||||||
//6
|
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect() { //good with guns that have less ammo: one shot, grenades, missiles, super balls, spray
|
effect() {
|
||||||
b.modNoAmmo = 1
|
b.modNoAmmo = 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Lorentzian topology",
|
name: "Lorentzian topology", //7
|
||||||
description: "your <strong>bullets</strong> last +33% <strong>longer</strong>",
|
description: "your <strong>bullets</strong> last +33% <strong>longer</strong>",
|
||||||
//7
|
|
||||||
maxCount: 4,
|
maxCount: 4,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect() { //good with: drones, super balls, spore, missiles, wave beam(range), rapid fire(range), flak(range)
|
effect() {
|
||||||
b.isModBulletsLastLonger += 0.33
|
b.isModBulletsLastLonger += 0.33
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "zoospore vector",
|
name: "zoospore vector", //8
|
||||||
description: "enemies discharge <strong style='letter-spacing: 2px;'>spores</strong> on <strong>death</strong><br>+11% chance",
|
description: "enemies discharge <strong style='letter-spacing: 2px;'>spores</strong> on <strong>death</strong><br>+11% chance",
|
||||||
//8
|
|
||||||
maxCount: 4,
|
maxCount: 4,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect() { //good late game maybe?
|
effect() {
|
||||||
b.modSpores += 0.11;
|
b.modSpores += 0.11;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ablative synthesis",
|
name: "ablative synthesis", //9
|
||||||
description: "rebuild your broken parts as <strong>drones</strong><br>chance to occur after being <strong>harmed</strong>",
|
description: "rebuild your broken parts as <strong>drones</strong><br>chance to occur after being <strong>harmed</strong>",
|
||||||
//9
|
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect() { //makes dangerous situations more survivable
|
effect() {
|
||||||
b.isModDroneOnDamage = true;
|
b.isModDroneOnDamage = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "guardian",
|
name: "guardian", //10
|
||||||
description: "a bot <strong>protects</strong> the space around you<br>uses a <strong>short range</strong> laser that drains <strong class='color-f'>energy</strong>",
|
description: "a bot <strong>protects</strong> the space around you<br>uses a <strong>short range</strong> laser that drains <strong class='color-f'>energy</strong>",
|
||||||
//10
|
|
||||||
maxCount: 4,
|
maxCount: 4,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect() { // good with melee builds, content skipping builds
|
effect() {
|
||||||
b.modGuardianCount++;
|
b.modGuardianCount++;
|
||||||
b.guardian();
|
b.guardian();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "piezoelectric plating",
|
name: "electrostatic repulsion", //11
|
||||||
description: "<strong>immune</strong> to harm from <strong>collisions</strong> for +2 seconds<br>activates after being <strong>harmed</strong> from a collision",
|
description: "<strong>immune</strong> to harm from <strong>collisions</strong> for +2 seconds<br>activates after being <strong>harmed</strong> from a collision",
|
||||||
//11
|
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect() { // good with melee builds, content skipping builds
|
effect() {
|
||||||
b.modCollisionImmuneCycles += 120;
|
b.modCollisionImmuneCycles += 120;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "annihilation",
|
name: "bremsstrahlung radiation", //12
|
||||||
|
description: "when your <strong>field blocks</strong> it also does <strong class='color-d'>damage</strong>",
|
||||||
|
maxCount: 4,
|
||||||
|
count: 0,
|
||||||
|
effect() {
|
||||||
|
b.modBlockDmg += 0.7
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "annihilation", //13
|
||||||
description: "after <strong>touching</strong> enemies, they are annihilated",
|
description: "after <strong>touching</strong> enemies, they are annihilated",
|
||||||
//12
|
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect() { //good with mods that heal: superconductive healing, entropy transfer
|
effect() {
|
||||||
b.isModAnnihilation = true
|
b.isModAnnihilation = true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "high explosives",
|
name: "high explosives", //14
|
||||||
description: "the radius of <strong class='color-e'>explosions</strong> are +20% <strong>larger</strong><br>immune to <strong>harm</strong> from <strong class='color-e'>explosions</strong>",
|
description: "the radius of <strong class='color-e'>explosions</strong> are +20% <strong>larger</strong><br>immune to <strong>harm</strong> from <strong class='color-e'>explosions</strong>",
|
||||||
//13
|
|
||||||
maxCount: 4,
|
maxCount: 4,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect: () => {
|
effect: () => {
|
||||||
@@ -207,39 +206,44 @@ const b = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "entanglement",
|
name: "entanglement", //15
|
||||||
description: "using your first gun reduces <strong>harm</strong><br>scales by <strong>7%</strong> for each gun in your inventory",
|
description: "using your first gun reduces <strong>harm</strong><br>scales by <strong>7%</strong> for each gun in your inventory",
|
||||||
//14
|
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect() { // good with laser-bots
|
effect() {
|
||||||
b.isModEntanglement = true
|
b.isModEntanglement = true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "energy transfer",
|
name: "piezoelectricity", //16
|
||||||
description: "gain <strong class='color-f'>energy</strong> proportional to <strong class='color-d'>damage</strong> done",
|
description: "gain <strong class='color-f'>energy</strong> proportional to <strong>harm</strong> received",
|
||||||
//15
|
|
||||||
maxCount: 4,
|
maxCount: 4,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect() { //good with laser, and all fields
|
effect() {
|
||||||
|
b.modPiezo += 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "energy conservation", //17
|
||||||
|
description: "gain <strong class='color-f'>energy</strong> proportional to <strong class='color-d'>damage</strong> done",
|
||||||
|
maxCount: 4,
|
||||||
|
count: 0,
|
||||||
|
effect() {
|
||||||
b.modEnergySiphon += 0.18;
|
b.modEnergySiphon += 0.18;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "entropy transfer",
|
name: "entropy exchange", //18
|
||||||
description: "<strong class='color-h'>heal</strong> proportional to <strong class='color-d'>damage</strong> done",
|
description: "<strong class='color-h'>heal</strong> proportional to <strong class='color-d'>damage</strong> done",
|
||||||
//16
|
|
||||||
maxCount: 4,
|
maxCount: 4,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect() { //good with guns that overkill: one shot, grenade
|
effect() {
|
||||||
b.modHealthDrain += 0.015;
|
b.modHealthDrain += 0.015;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "overcharge",
|
name: "overcharge", //19
|
||||||
description: "charge <strong class='color-f'>energy</strong> <strong>+33%</strong> beyond your <strong>maximum</strong>",
|
description: "charge <strong class='color-f'>energy</strong> <strong>+33%</strong> beyond your <strong>maximum</strong>",
|
||||||
//17
|
|
||||||
maxCount: 4,
|
maxCount: 4,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect() {
|
effect() {
|
||||||
@@ -247,9 +251,8 @@ const b = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "supersaturation",
|
name: "supersaturation", //20
|
||||||
description: "<strong class='color-h'>heal</strong> <strong>+33%</strong> beyond your <strong>max health</strong>",
|
description: "<strong class='color-h'>heal</strong> <strong>+33%</strong> beyond your <strong>max health</strong>",
|
||||||
//18
|
|
||||||
maxCount: 4,
|
maxCount: 4,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect() {
|
effect() {
|
||||||
@@ -257,19 +260,17 @@ const b = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "recursive healing",
|
name: "recursive healing", //21
|
||||||
description: "<strong class='color-h'>healing</strong> power ups trigger an extra time.",
|
description: "<strong class='color-h'>healing</strong> power ups trigger an extra time.",
|
||||||
//19
|
|
||||||
maxCount: 4,
|
maxCount: 4,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect() { // good with ablative synthesis, melee builds
|
effect() {
|
||||||
b.modRecursiveHealing += 1
|
b.modRecursiveHealing += 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "mass-energy equivalence",
|
name: "mass-energy equivalence", //22
|
||||||
description: "convert the mass of <strong>power ups</strong> into <strong class='color-f'>energy</strong><br>power ups fill your <strong class='color-f'>energy</strong> and <strong class='color-h'>heal</strong> for +5%",
|
description: "convert the mass of <strong>power ups</strong> into <strong class='color-f'>energy</strong><br>power ups fill your <strong class='color-f'>energy</strong> and <strong class='color-h'>heal</strong> for +5%",
|
||||||
//20
|
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect: () => {
|
effect: () => {
|
||||||
@@ -277,9 +278,8 @@ const b = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "+1 cardinality",
|
name: "+1 cardinality", //23
|
||||||
description: "one extra <strong>choice</strong> when selecting <strong>power ups</strong>",
|
description: "one extra <strong>choice</strong> when selecting <strong>power ups</strong>",
|
||||||
//21
|
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect: () => {
|
effect: () => {
|
||||||
@@ -287,31 +287,17 @@ const b = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Bayesian inference",
|
name: "Bayesian inference", //24
|
||||||
description: "<strong>20%</strong> chance for double <strong>power ups</strong> to drop<br>one fewer <strong>choice</strong> when selecting <strong>power ups</strong>",
|
description: "<strong>20%</strong> chance for double <strong>power ups</strong> to drop<br>one fewer <strong>choice</strong> when selecting <strong>power ups</strong>",
|
||||||
//22
|
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect: () => {
|
effect: () => {
|
||||||
b.isModBayesian = 0.20;
|
b.isModBayesian = 0.20;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// name: "Gauss rifle",
|
|
||||||
// description: "<strong>launch blocks</strong> at much higher speeds<br><em>hold onto larger blocks even after getting hit</em>",
|
|
||||||
// //23
|
|
||||||
// maxCount: 1,
|
|
||||||
// count: 0,
|
|
||||||
// effect() { // good with guns that run out of ammo
|
|
||||||
// mech.throwChargeRate = 4;
|
|
||||||
// mech.throwChargeMax = 150;
|
|
||||||
// mech.holdingMassScale = 0.05; //can hold heavier blocks with lower cost to jumping
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
name: "squirrel-cage rotor",
|
name: "squirrel-cage rotor", //25
|
||||||
description: "<strong>jump</strong> higher and <strong>move</strong> faster<br>reduced <strong>harm</strong> from <strong>falling</strong> ",
|
description: "<strong>jump</strong> higher and <strong>move</strong> faster<br>reduced <strong>harm</strong> from <strong>falling</strong> ",
|
||||||
//23
|
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect() { // good with melee builds, content skipping builds
|
effect() { // good with melee builds, content skipping builds
|
||||||
@@ -321,9 +307,8 @@ const b = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "quantum immortality",
|
name: "quantum immortality", //26
|
||||||
description: "after <strong>dying</strong>, continue in an <strong>alternate reality</strong><br><em>guns, ammo, and field are randomized</em>",
|
description: "after <strong>dying</strong>, continue in an <strong>alternate reality</strong><br><em>guns, ammo, and field are randomized</em>",
|
||||||
//24
|
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
effect() {
|
effect() {
|
||||||
@@ -488,7 +473,7 @@ const b = {
|
|||||||
time: game.drawTime
|
time: game.drawTime
|
||||||
});
|
});
|
||||||
let dist, sub, knock;
|
let dist, sub, knock;
|
||||||
const dmg = b.dmgScale * radius * 0.009;
|
let dmg = b.dmgScale * radius * 0.009;
|
||||||
|
|
||||||
const alertRange = 100 + radius * 2; //alert range
|
const alertRange = 100 + radius * 2; //alert range
|
||||||
//add alert to draw queue
|
//add alert to draw queue
|
||||||
@@ -549,20 +534,21 @@ const b = {
|
|||||||
//mob damage and knock back with alert
|
//mob damage and knock back with alert
|
||||||
let damageScale = 1.5; // reduce dmg for each new target to limit total AOE damage
|
let damageScale = 1.5; // reduce dmg for each new target to limit total AOE damage
|
||||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||||
if (mob[i].alive) {
|
if (mob[i].alive && !mob[i].isShielded) {
|
||||||
sub = Vector.sub(where, mob[i].position);
|
sub = Vector.sub(where, mob[i].position);
|
||||||
dist = Vector.magnitude(sub) - mob[i].radius;
|
dist = Vector.magnitude(sub) - mob[i].radius;
|
||||||
if (dist < radius) {
|
if (dist < radius) {
|
||||||
|
if (mob[i].shield) dmg *= 3 //balancing explosion dmg to shields
|
||||||
mob[i].damage(dmg * damageScale);
|
mob[i].damage(dmg * damageScale);
|
||||||
mob[i].locatePlayer();
|
mob[i].locatePlayer();
|
||||||
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) / 30);
|
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) / 50);
|
||||||
mob[i].force.x += knock.x;
|
mob[i].force.x += knock.x;
|
||||||
mob[i].force.y += knock.y;
|
mob[i].force.y += knock.y;
|
||||||
radius *= 0.93 //reduced range for each additional explosion target
|
radius *= 0.93 //reduced range for each additional explosion target
|
||||||
damageScale *= 0.8 //reduced damage for each additional explosion target
|
damageScale *= 0.8 //reduced damage for each additional explosion target
|
||||||
} else if (!mob[i].seePlayer.recall && dist < alertRange) {
|
} else if (!mob[i].seePlayer.recall && dist < alertRange) {
|
||||||
mob[i].locatePlayer();
|
mob[i].locatePlayer();
|
||||||
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) / 50);
|
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) / 80);
|
||||||
mob[i].force.x += knock.x;
|
mob[i].force.x += knock.x;
|
||||||
mob[i].force.y += knock.y;
|
mob[i].force.y += knock.y;
|
||||||
}
|
}
|
||||||
@@ -581,7 +567,7 @@ const b = {
|
|||||||
time: game.drawTime
|
time: game.drawTime
|
||||||
});
|
});
|
||||||
let dist, sub, knock;
|
let dist, sub, knock;
|
||||||
const dmg = b.dmgScale * radius * 0.009;
|
let dmg = b.dmgScale * radius * 0.009;
|
||||||
|
|
||||||
const alertRange = 100 + radius * 2; //alert range
|
const alertRange = 100 + radius * 2; //alert range
|
||||||
//add alert to draw queue
|
//add alert to draw queue
|
||||||
@@ -642,20 +628,21 @@ const b = {
|
|||||||
//mob damage and knock back with alert
|
//mob damage and knock back with alert
|
||||||
let damageScale = 1.5; // reduce dmg for each new target to limit total AOE damage
|
let damageScale = 1.5; // reduce dmg for each new target to limit total AOE damage
|
||||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||||
if (mob[i].alive) {
|
if (mob[i].alive && !mob[i].isShielded) {
|
||||||
sub = Vector.sub(bullet[me].position, mob[i].position);
|
sub = Vector.sub(bullet[me].position, mob[i].position);
|
||||||
dist = Vector.magnitude(sub) - mob[i].radius;
|
dist = Vector.magnitude(sub) - mob[i].radius;
|
||||||
if (dist < radius) {
|
if (dist < radius) {
|
||||||
|
if (mob[i].shield) dmg *= 3 //balancing explosion dmg to shields
|
||||||
mob[i].damage(dmg * damageScale);
|
mob[i].damage(dmg * damageScale);
|
||||||
mob[i].locatePlayer();
|
mob[i].locatePlayer();
|
||||||
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) / 30);
|
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) / 50);
|
||||||
mob[i].force.x += knock.x;
|
mob[i].force.x += knock.x;
|
||||||
mob[i].force.y += knock.y;
|
mob[i].force.y += knock.y;
|
||||||
radius *= 0.93 //reduced range for each additional explosion target
|
radius *= 0.93 //reduced range for each additional explosion target
|
||||||
damageScale *= 0.8 //reduced damage for each additional explosion target
|
damageScale *= 0.8 //reduced damage for each additional explosion target
|
||||||
} else if (!mob[i].seePlayer.recall && dist < alertRange) {
|
} else if (!mob[i].seePlayer.recall && dist < alertRange) {
|
||||||
mob[i].locatePlayer();
|
mob[i].locatePlayer();
|
||||||
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) / 50);
|
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) / 80);
|
||||||
mob[i].force.x += knock.x;
|
mob[i].force.x += knock.x;
|
||||||
mob[i].force.y += knock.y;
|
mob[i].force.y += knock.y;
|
||||||
}
|
}
|
||||||
@@ -837,7 +824,7 @@ const b = {
|
|||||||
restitution: 0.5 + 0.5 * Math.random(),
|
restitution: 0.5 + 0.5 * Math.random(),
|
||||||
dmg: 0, // 0.14 //damage done in addition to the damage from momentum
|
dmg: 0, // 0.14 //damage done in addition to the damage from momentum
|
||||||
minDmgSpeed: 2,
|
minDmgSpeed: 2,
|
||||||
lookFrequency: 37 + Math.floor(17 * Math.random()),
|
lookFrequency: 31 + Math.floor(17 * Math.random()),
|
||||||
acceleration: 0.0015 + 0.0013 * Math.random(),
|
acceleration: 0.0015 + 0.0013 * Math.random(),
|
||||||
range: 500 + Math.floor(200 * Math.random()),
|
range: 500 + Math.floor(200 * Math.random()),
|
||||||
endCycle: Infinity,
|
endCycle: Infinity,
|
||||||
@@ -858,6 +845,7 @@ const b = {
|
|||||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||||
const DIST = Vector.magnitude(Vector.sub(this.vertices[0], mob[i].position));
|
const DIST = Vector.magnitude(Vector.sub(this.vertices[0], mob[i].position));
|
||||||
if (DIST - mob[i].radius < closeDist &&
|
if (DIST - mob[i].radius < closeDist &&
|
||||||
|
!mob[i].isShielded &&
|
||||||
Matter.Query.ray(map, this.vertices[0], mob[i].position).length === 0 &&
|
Matter.Query.ray(map, this.vertices[0], mob[i].position).length === 0 &&
|
||||||
Matter.Query.ray(body, this.vertices[0], mob[i].position).length === 0) {
|
Matter.Query.ray(body, this.vertices[0], mob[i].position).length === 0) {
|
||||||
closeDist = DIST;
|
closeDist = DIST;
|
||||||
@@ -951,17 +939,18 @@ const b = {
|
|||||||
name: "minigun", //0
|
name: "minigun", //0
|
||||||
description: "rapidly fire a stream of small <strong>bullets</strong>",
|
description: "rapidly fire a stream of small <strong>bullets</strong>",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: 50,
|
ammoPack: 55,
|
||||||
have: false,
|
have: false,
|
||||||
isStarterGun: true,
|
isStarterGun: true,
|
||||||
fire() {
|
fire() {
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
b.muzzleFlash(15);
|
b.muzzleFlash(15);
|
||||||
// if (Math.random() > 0.2) mobs.alert(500);
|
// if (Math.random() > 0.2) mobs.alert(500);
|
||||||
const dir = mech.angle + (Math.random() - 0.5) * ((mech.crouch) ? 0.04 : 0.12);
|
const dir = mech.angle + (Math.random() - 0.5) * ((mech.crouch) ? 0.03 : 0.1);
|
||||||
bullet[me] = Bodies.rectangle(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 17 * b.modBulletSize, 5 * b.modBulletSize, b.fireAttributes(dir));
|
bullet[me] = Bodies.rectangle(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 20 * b.modBulletSize, 6 * b.modBulletSize, b.fireAttributes(dir));
|
||||||
b.fireProps(mech.crouch ? 10 : 5, mech.crouch ? 50 : 36, dir, me); //cd , speed
|
b.fireProps(mech.crouch ? 8 : 4, mech.crouch ? 52 : 38, dir, me); //cd , speed
|
||||||
bullet[me].endCycle = game.cycle + 65;
|
bullet[me].endCycle = game.cycle + 70;
|
||||||
|
bullet[me].dmg = 0.07;
|
||||||
bullet[me].frictionAir = mech.crouch ? 0.007 : 0.01;
|
bullet[me].frictionAir = mech.crouch ? 0.007 : 0.01;
|
||||||
bullet[me].do = function () {
|
bullet[me].do = function () {
|
||||||
this.force.y += this.mass * 0.0005;
|
this.force.y += this.mass * 0.0005;
|
||||||
@@ -972,7 +961,7 @@ const b = {
|
|||||||
name: "shotgun", //1
|
name: "shotgun", //1
|
||||||
description: "fire a <strong>burst</strong> of short range bullets<br><em>crouch to reduce recoil</em>",
|
description: "fire a <strong>burst</strong> of short range bullets<br><em>crouch to reduce recoil</em>",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: 4,
|
ammoPack: 5,
|
||||||
have: false,
|
have: false,
|
||||||
isStarterGun: true,
|
isStarterGun: true,
|
||||||
fire() {
|
fire() {
|
||||||
@@ -999,7 +988,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//knock back
|
//knock back
|
||||||
const KNOCK = ((mech.crouch) ? 0.017 : 0.17) * b.modBulletSize * b.modBulletSize
|
const KNOCK = ((mech.crouch) ? 0.013 : 0.15) * b.modBulletSize * b.modBulletSize
|
||||||
player.force.x -= KNOCK * Math.cos(mech.angle)
|
player.force.x -= KNOCK * Math.cos(mech.angle)
|
||||||
player.force.y -= KNOCK * Math.sin(mech.angle) * 0.3 //reduce knock back in vertical direction to stop super jumps
|
player.force.y -= KNOCK * Math.sin(mech.angle) * 0.3 //reduce knock back in vertical direction to stop super jumps
|
||||||
}
|
}
|
||||||
@@ -1043,7 +1032,7 @@ const b = {
|
|||||||
name: "fléchettes", //3
|
name: "fléchettes", //3
|
||||||
description: "fire a volley of <strong>precise</strong> high velocity needles",
|
description: "fire a volley of <strong>precise</strong> high velocity needles",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: 22,
|
ammoPack: 20,
|
||||||
have: false,
|
have: false,
|
||||||
isStarterGun: true,
|
isStarterGun: true,
|
||||||
count: 0, //used to track how many shots are in a volley before a big CD
|
count: 0, //used to track how many shots are in a volley before a big CD
|
||||||
@@ -1095,7 +1084,7 @@ const b = {
|
|||||||
inertia: Infinity,
|
inertia: Infinity,
|
||||||
frictionAir: 0,
|
frictionAir: 0,
|
||||||
minDmgSpeed: 0,
|
minDmgSpeed: 0,
|
||||||
dmg: 0.13, //damage done in addition to the damage from momentum
|
dmg: 0.2, //damage done in addition to the damage from momentum
|
||||||
classType: "bullet",
|
classType: "bullet",
|
||||||
collisionFilter: {
|
collisionFilter: {
|
||||||
category: cat.bullet,
|
category: cat.bullet,
|
||||||
@@ -1134,7 +1123,7 @@ const b = {
|
|||||||
name: "rail gun", //5
|
name: "rail gun", //5
|
||||||
description: "electro-magnetically launch a dense rod<br><strong>hold</strong> left mouse to charge, <strong>release</strong> to fire", //and <strong>repel</strong> enemies
|
description: "electro-magnetically launch a dense rod<br><strong>hold</strong> left mouse to charge, <strong>release</strong> to fire", //and <strong>repel</strong> enemies
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: 2,
|
ammoPack: 1,
|
||||||
have: false,
|
have: false,
|
||||||
isStarterGun: false,
|
isStarterGun: false,
|
||||||
fire() {
|
fire() {
|
||||||
@@ -1208,18 +1197,6 @@ const b = {
|
|||||||
mob[i].force.y += 1.5 * FORCE.y;
|
mob[i].force.y += 1.5 * FORCE.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//push mobs around player when firing
|
|
||||||
// range = 600 * this.charge
|
|
||||||
// for (let i = 0, len = mob.length; i < len; ++i) {
|
|
||||||
// const SUB = Vector.sub(mob[i].position, mech.pos)
|
|
||||||
// const DISTANCE = Vector.magnitude(SUB)
|
|
||||||
// if (DISTANCE < range) {
|
|
||||||
// const DEPTH = range - DISTANCE
|
|
||||||
// const FORCE = Vector.mult(Vector.normalise(SUB), 0.00000001 * DEPTH * DEPTH * DEPTH * Math.sqrt(mob[i].mass))
|
|
||||||
// mob[i].force.x += FORCE.x
|
|
||||||
// mob[i].force.y += FORCE.y
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
} else { // charging on mouse down
|
} else { // charging on mouse down
|
||||||
mech.fireCDcycle = Infinity //can't fire until mouse is released
|
mech.fireCDcycle = Infinity //can't fire until mouse is released
|
||||||
if (mech.crouch) {
|
if (mech.crouch) {
|
||||||
@@ -1227,25 +1204,6 @@ const b = {
|
|||||||
} else {
|
} else {
|
||||||
this.charge = this.charge * 0.985 + 0.015 // this.charge converges to 1
|
this.charge = this.charge * 0.985 + 0.015 // this.charge converges to 1
|
||||||
}
|
}
|
||||||
|
|
||||||
//gently push away mobs while charging
|
|
||||||
// const RANGE = 270 * this.charge
|
|
||||||
// for (let i = 0, len = mob.length; i < len; ++i) {
|
|
||||||
// const SUB = Vector.sub(mob[i].position, mech.pos)
|
|
||||||
// const DISTANCE = Vector.magnitude(SUB)
|
|
||||||
// // if (DISTANCE < RANGE) {
|
|
||||||
// // Matter.Body.setVelocity(mob[i], Vector.rotate(mob[i].velocity, 0.1))
|
|
||||||
// // }
|
|
||||||
// // const DRAIN = 0.0002 //&& mech.fieldMeter > DRAIN
|
|
||||||
// if (DISTANCE < RANGE) {
|
|
||||||
// // mech.fieldMeter -= DRAIN + mech.fieldRegen;
|
|
||||||
// const DEPTH = RANGE - DISTANCE
|
|
||||||
// const FORCE = Vector.mult(Vector.normalise(SUB), 0.000000001 * DEPTH * DEPTH * DEPTH * Math.sqrt(mob[i].mass))
|
|
||||||
// mob[i].force.x += FORCE.x
|
|
||||||
// mob[i].force.y += FORCE.y
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
//draw laser targeting
|
//draw laser targeting
|
||||||
let best;
|
let best;
|
||||||
let range = 3000
|
let range = 3000
|
||||||
@@ -1377,30 +1335,25 @@ const b = {
|
|||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
bullet[me] = Bodies.rectangle(mech.pos.x + 40 * Math.cos(mech.angle), mech.pos.y + 40 * Math.sin(mech.angle) - 3, 30 * b.modBulletSize, 4 * b.modBulletSize, b.fireAttributes(dir));
|
bullet[me] = Bodies.rectangle(mech.pos.x + 40 * Math.cos(mech.angle), mech.pos.y + 40 * Math.sin(mech.angle) - 3, 30 * b.modBulletSize, 4 * b.modBulletSize, b.fireAttributes(dir));
|
||||||
b.fireProps(mech.crouch ? 55 : 30, -3 * (0.5 - Math.random()) + (mech.crouch ? 25 : -8), dir, me); //cd , speed
|
b.fireProps(mech.crouch ? 55 : 30, -3 * (0.5 - Math.random()) + (mech.crouch ? 25 : -8), dir, me); //cd , speed
|
||||||
|
// bullet[me].collisionFilter.mask = cat.map | cat.body | cat.mobBullet
|
||||||
// Matter.Body.setDensity(bullet[me], 0.01) //doesn't help with reducing explosion knock backs
|
// Matter.Body.setDensity(bullet[me], 0.01) //doesn't help with reducing explosion knock backs
|
||||||
bullet[me].force.y += 0.0005; //a small push down at first to make it seem like the missile is briefly falling
|
bullet[me].force.y += 0.0005; //a small push down at first to make it seem like the missile is briefly falling
|
||||||
bullet[me].frictionAir = 0.023
|
bullet[me].frictionAir = 0.023
|
||||||
bullet[me].endCycle = game.cycle + Math.floor((280 + 40 * Math.random()) * b.isModBulletsLastLonger);
|
bullet[me].endCycle = game.cycle + Math.floor((280 + 40 * Math.random()) * b.isModBulletsLastLonger);
|
||||||
bullet[me].explodeRad = 160 + 60 * Math.random();
|
bullet[me].explodeRad = 170 + 60 * Math.random();
|
||||||
bullet[me].lookFrequency = Math.floor(15 + Math.random() * 5);
|
bullet[me].lookFrequency = Math.floor(31 + Math.random() * 11);
|
||||||
bullet[me].onEnd = b.explode; //makes bullet do explosive damage at end
|
bullet[me].onEnd = b.explode; //makes bullet do explosive damage at end
|
||||||
bullet[me].onDmg = function () {
|
bullet[me].onDmg = function () {
|
||||||
this.endCycle = 0; //bullet ends cycle after doing damage // also triggers explosion
|
this.tryToLockOn();
|
||||||
|
// this.endCycle = 0; //bullet ends cycle after doing damage // also triggers explosion
|
||||||
};
|
};
|
||||||
bullet[me].lockedOn = null;
|
bullet[me].lockedOn = null;
|
||||||
bullet[me].do = function () {
|
bullet[me].tryToLockOn = function () {
|
||||||
if (!mech.isBodiesAsleep) {
|
|
||||||
if (!(mech.cycle % this.lookFrequency)) {
|
|
||||||
this.lockedOn = null;
|
this.lockedOn = null;
|
||||||
let closeDist = Infinity;
|
let closeDist = Infinity;
|
||||||
|
|
||||||
//look for closest target to where the missile will be in 30 cycles
|
//look for closest target to where the missile will be in 30 cycles
|
||||||
const futurePos = Vector.add(this.position, Vector.mult(this.velocity, 30))
|
const futurePos = Vector.add(this.position, Vector.mult(this.velocity, 30))
|
||||||
// ctx.beginPath(); //draw future pos
|
|
||||||
// ctx.arc(futurePos.x, futurePos.y, 20, 0, 2 * Math.PI);
|
|
||||||
// ctx.fillStyle = "rgba(0,0,0,0.5)";
|
|
||||||
// ctx.fill();
|
|
||||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||||
if (
|
if (
|
||||||
mob[i].alive && mob[i].dropPowerUp &&
|
mob[i].alive && mob[i].dropPowerUp &&
|
||||||
@@ -1416,11 +1369,17 @@ const b = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//explode when bullet is close enough to target
|
//explode when bullet is close enough to target
|
||||||
if (this.lockedOn && Vector.magnitude(Vector.sub(this.position, this.lockedOn.position)) < this.explodeRad * 0.7) {
|
if (this.lockedOn && Vector.magnitude(Vector.sub(this.position, this.lockedOn.position)) < this.explodeRad * 0.95) {
|
||||||
|
// console.log('hit')
|
||||||
this.endCycle = 0; //bullet ends cycle after doing damage //also triggers explosion
|
this.endCycle = 0; //bullet ends cycle after doing damage //also triggers explosion
|
||||||
const dmg = b.dmgScale * 3;
|
const dmg = b.dmgScale * 5;
|
||||||
this.lockedOn.damage(dmg); //does extra damage to target
|
this.lockedOn.damage(dmg); //does extra damage to target
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
bullet[me].do = function () {
|
||||||
|
if (!mech.isBodiesAsleep) {
|
||||||
|
if (!(mech.cycle % this.lookFrequency)) {
|
||||||
|
this.tryToLockOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
//rotate missile towards the target
|
//rotate missile towards the target
|
||||||
@@ -1754,12 +1713,12 @@ const b = {
|
|||||||
name: "drones", //12
|
name: "drones", //12
|
||||||
description: "deploy drones that <strong>crash</strong> into enemies<br>collisions reduce drone <strong>cycles</strong> by 1 second",
|
description: "deploy drones that <strong>crash</strong> into enemies<br>collisions reduce drone <strong>cycles</strong> by 1 second",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: 6,
|
ammoPack: 5,
|
||||||
have: false,
|
have: false,
|
||||||
isStarterGun: true,
|
isStarterGun: true,
|
||||||
fire() {
|
fire() {
|
||||||
b.drone(mech.crouch ? 45 : 1)
|
b.drone(mech.crouch ? 45 : 1)
|
||||||
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 25 : 10) * b.modFireRate); // cool down
|
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 25 : 5) * b.modFireRate); // cool down
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
@@ -2155,7 +2114,7 @@ const b = {
|
|||||||
const RADIUS = (8 + 16 * Math.random()) * b.modBulletSize
|
const RADIUS = (8 + 16 * Math.random()) * b.modBulletSize
|
||||||
bullet[me] = Bodies.polygon(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 25, RADIUS, {
|
bullet[me] = Bodies.polygon(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 25, RADIUS, {
|
||||||
angle: dir,
|
angle: dir,
|
||||||
density: 0.00004, // 0.001 is normal density
|
density: 0.00005, // 0.001 is normal density
|
||||||
inertia: Infinity,
|
inertia: Infinity,
|
||||||
frictionAir: 0.003,
|
frictionAir: 0.003,
|
||||||
friction: 0.2,
|
friction: 0.2,
|
||||||
@@ -2173,7 +2132,7 @@ const b = {
|
|||||||
target: null,
|
target: null,
|
||||||
targetVertex: null,
|
targetVertex: null,
|
||||||
onDmg(who) {
|
onDmg(who) {
|
||||||
if (!this.target && who.alive && who.dropPowerUp) {
|
if (!this.target && who.alive && who.dropPowerUp && !who.isShielded) {
|
||||||
this.target = who;
|
this.target = who;
|
||||||
this.collisionFilter.category = cat.body;
|
this.collisionFilter.category = cat.body;
|
||||||
this.collisionFilter.mask = null;
|
this.collisionFilter.mask = null;
|
||||||
@@ -2216,9 +2175,9 @@ const b = {
|
|||||||
|
|
||||||
if (this.target && this.target.alive) { //if stuck to a target
|
if (this.target && this.target.alive) { //if stuck to a target
|
||||||
Matter.Body.setPosition(this, this.target.vertices[this.targetVertex])
|
Matter.Body.setPosition(this, this.target.vertices[this.targetVertex])
|
||||||
Matter.Body.setVelocity(this.target, Vector.mult(this.target.velocity, 0.94))
|
Matter.Body.setVelocity(this.target, Vector.mult(this.target.velocity, 0.9))
|
||||||
Matter.Body.setAngularVelocity(this.target, this.target.angularVelocity * 0.94)
|
Matter.Body.setAngularVelocity(this.target, this.target.angularVelocity * 0.9)
|
||||||
this.target.damage(b.dmgScale * 0.0045);
|
this.target.damage(b.dmgScale * 0.005);
|
||||||
} else if (this.target !== null) { //look for a new target
|
} else if (this.target !== null) { //look for a new target
|
||||||
this.target = null
|
this.target = null
|
||||||
this.collisionFilter.category = cat.bullet;
|
this.collisionFilter.category = cat.bullet;
|
||||||
@@ -2301,6 +2260,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkForCollisions = function () {
|
const checkForCollisions = function () {
|
||||||
best = {
|
best = {
|
||||||
x: null,
|
x: null,
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ function mobCollisionChecks(event) {
|
|||||||
let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * game.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0
|
let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * game.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0
|
||||||
mech.damage(dmg);
|
mech.damage(dmg);
|
||||||
if (mob[k].onHit) mob[k].onHit(k);
|
if (mob[k].onHit) mob[k].onHit(k);
|
||||||
if (b.isModAnnihilation && mob[k].dropPowerUp) {
|
if (b.isModAnnihilation && mob[k].dropPowerUp && !mob[k].isShielded) {
|
||||||
mob[k].death();
|
mob[k].death();
|
||||||
game.drawList.push({
|
game.drawList.push({
|
||||||
//add dmg to draw queue
|
//add dmg to draw queue
|
||||||
@@ -164,8 +164,7 @@ function mobCollisionChecks(event) {
|
|||||||
if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) {
|
if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) {
|
||||||
// const dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)));
|
// const dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)));
|
||||||
let dmg = b.dmgScale * (obj.dmg + b.modExtraDmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)))
|
let dmg = b.dmgScale * (obj.dmg + b.modExtraDmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)))
|
||||||
if (mob[k].shield) dmg *= 0.3
|
if (b.isModCrit && !mob[k].seePlayer.recall && !mob[k].shield) dmg *= 5
|
||||||
if (b.isModCrit && !mob[k].seePlayer.recall) dmg *= 5
|
|
||||||
mob[k].foundPlayer();
|
mob[k].foundPlayer();
|
||||||
mob[k].damage(dmg);
|
mob[k].damage(dmg);
|
||||||
obj.onDmg(mob[k]); //some bullets do actions when they hits things, like despawn
|
obj.onDmg(mob[k]); //some bullets do actions when they hits things, like despawn
|
||||||
|
|||||||
89
js/game.js
89
js/game.js
@@ -81,7 +81,8 @@ const game = {
|
|||||||
isBodyDamage: true,
|
isBodyDamage: true,
|
||||||
levelsCleared: 0,
|
levelsCleared: 0,
|
||||||
difficultyMode: 1,
|
difficultyMode: 1,
|
||||||
difficulty: 1,
|
isEasyMode: false,
|
||||||
|
difficulty: 0,
|
||||||
dmgScale: null, //set in levels.setDifficulty
|
dmgScale: null, //set in levels.setDifficulty
|
||||||
healScale: 1,
|
healScale: 1,
|
||||||
accelScale: null, //set in levels.setDifficulty
|
accelScale: null, //set in levels.setDifficulty
|
||||||
@@ -416,24 +417,6 @@ const game = {
|
|||||||
},
|
},
|
||||||
wipe() {
|
wipe() {
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
// ctx.fillStyle = "rgba(255,255,255,1)";
|
|
||||||
// ctx.globalCompositeOperation = "difference";
|
|
||||||
// ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
||||||
// ctx.globalCompositeOperation = "source-over";
|
|
||||||
|
|
||||||
// ctx.globalAlpha = (mech.health < 0.7) ? (mech.health+0.3)*(mech.health+0.3) : 1
|
|
||||||
// if (mech.health < 0.7) {
|
|
||||||
// ctx.globalAlpha= 0.3 + mech.health
|
|
||||||
// ctx.fillStyle = document.body.style.backgroundColor
|
|
||||||
// ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
||||||
// ctx.globalAlpha=1;
|
|
||||||
// } else {
|
|
||||||
// ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
||||||
// }
|
|
||||||
//ctx.fillStyle = "rgba(255,255,255," + (1 - Math.sqrt(player.speed)*0.1) + ")";
|
|
||||||
//ctx.fillStyle = "rgba(255,255,255,0.4)";
|
|
||||||
//ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
||||||
},
|
},
|
||||||
gravity() {
|
gravity() {
|
||||||
function addGravity(bodies, magnitude) {
|
function addGravity(bodies, magnitude) {
|
||||||
@@ -474,8 +457,10 @@ const game = {
|
|||||||
game.accelScale = 1;
|
game.accelScale = 1;
|
||||||
game.lookFreqScale = 1;
|
game.lookFreqScale = 1;
|
||||||
game.CDScale = 1;
|
game.CDScale = 1;
|
||||||
|
game.difficulty = 0;
|
||||||
game.difficultyMode = Number(document.getElementById("difficulty-select").value)
|
game.difficultyMode = Number(document.getElementById("difficulty-select").value)
|
||||||
if (game.difficultyMode === 0) {
|
if (game.difficultyMode === 0) {
|
||||||
|
game.isEasyMode = true;
|
||||||
game.difficultyMode = 1
|
game.difficultyMode = 1
|
||||||
level.difficultyDecrease(6);
|
level.difficultyDecrease(6);
|
||||||
}
|
}
|
||||||
@@ -693,7 +678,7 @@ const game = {
|
|||||||
testingOutput() {
|
testingOutput() {
|
||||||
ctx.textAlign = "right";
|
ctx.textAlign = "right";
|
||||||
ctx.fillStyle = "#000";
|
ctx.fillStyle = "#000";
|
||||||
let line = 140;
|
let line = 500;
|
||||||
const x = canvas.width - 5;
|
const x = canvas.width - 5;
|
||||||
ctx.fillText("T: exit testing mode", x, line);
|
ctx.fillText("T: exit testing mode", x, line);
|
||||||
line += 20;
|
line += 20;
|
||||||
@@ -712,38 +697,38 @@ const game = {
|
|||||||
ctx.fillText("1-7: spawn things", x, line);
|
ctx.fillText("1-7: spawn things", x, line);
|
||||||
line += 30;
|
line += 30;
|
||||||
|
|
||||||
ctx.fillText("cycle: " + game.cycle, x, line);
|
// ctx.fillText("cycle: " + game.cycle, x, line);
|
||||||
line += 20;
|
// line += 20;
|
||||||
ctx.fillText("player cycle: " + mech.cycle, x, line);
|
// ctx.fillText("player cycle: " + mech.cycle, x, line);
|
||||||
line += 20;
|
// line += 20;
|
||||||
ctx.fillText("x: " + player.position.x.toFixed(0), x, line);
|
// ctx.fillText("x: " + player.position.x.toFixed(0), x, line);
|
||||||
line += 20;
|
// line += 20;
|
||||||
ctx.fillText("y: " + player.position.y.toFixed(0), x, line);
|
// ctx.fillText("y: " + player.position.y.toFixed(0), x, line);
|
||||||
line += 20;
|
// line += 20;
|
||||||
ctx.fillText("Vx: " + mech.Vx.toFixed(2), x, line);
|
// ctx.fillText("Vx: " + mech.Vx.toFixed(2), x, line);
|
||||||
line += 20;
|
// line += 20;
|
||||||
ctx.fillText("Vy: " + mech.Vy.toFixed(2), x, line);
|
// ctx.fillText("Vy: " + mech.Vy.toFixed(2), x, line);
|
||||||
line += 20;
|
// line += 20;
|
||||||
ctx.fillText("Fx: " + player.force.x.toFixed(3), x, line);
|
// ctx.fillText("Fx: " + player.force.x.toFixed(3), x, line);
|
||||||
line += 20;
|
// line += 20;
|
||||||
ctx.fillText("Fy: " + player.force.y.toFixed(3), x, line);
|
// ctx.fillText("Fy: " + player.force.y.toFixed(3), x, line);
|
||||||
line += 20;
|
// line += 20;
|
||||||
ctx.fillText("yOff: " + mech.yOff.toFixed(1), x, line);
|
// ctx.fillText("yOff: " + mech.yOff.toFixed(1), x, line);
|
||||||
line += 20;
|
// line += 20;
|
||||||
ctx.fillText("mass: " + player.mass.toFixed(1), x, line);
|
// ctx.fillText("mass: " + player.mass.toFixed(1), x, line);
|
||||||
line += 20;
|
// line += 20;
|
||||||
ctx.fillText("onGround: " + mech.onGround, x, line);
|
// ctx.fillText("onGround: " + mech.onGround, x, line);
|
||||||
line += 20;
|
// line += 20;
|
||||||
ctx.fillText("crouch: " + mech.crouch, x, line);
|
// ctx.fillText("crouch: " + mech.crouch, x, line);
|
||||||
line += 20;
|
// line += 20;
|
||||||
ctx.fillText("isHeadClear: " + mech.isHeadClear, x, line);
|
// ctx.fillText("isHeadClear: " + mech.isHeadClear, x, line);
|
||||||
line += 20;
|
// line += 20;
|
||||||
ctx.fillText("frictionAir: " + player.frictionAir.toFixed(3), x, line);
|
// ctx.fillText("frictionAir: " + player.frictionAir.toFixed(3), x, line);
|
||||||
line += 20;
|
// line += 20;
|
||||||
ctx.fillText("stepSize: " + mech.stepSize.toFixed(2), x, line);
|
// ctx.fillText("stepSize: " + mech.stepSize.toFixed(2), x, line);
|
||||||
line += 20;
|
// line += 20;
|
||||||
ctx.fillText("zoom: " + game.zoom.toFixed(4), x, line);
|
// ctx.fillText("zoom: " + game.zoom.toFixed(4), x, line);
|
||||||
line += 20;
|
// line += 20;
|
||||||
ctx.textAlign = "center";
|
ctx.textAlign = "center";
|
||||||
ctx.fillText(`(${game.mouseInGame.x.toFixed(1)}, ${game.mouseInGame.y.toFixed(1)})`, game.mouse.x, game.mouse.y - 20);
|
ctx.fillText(`(${game.mouseInGame.x.toFixed(1)}, ${game.mouseInGame.y.toFixed(1)})`, game.mouse.x, game.mouse.y - 20);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,8 +2,12 @@
|
|||||||
/* TODO: *******************************************
|
/* TODO: *******************************************
|
||||||
*****************************************************
|
*****************************************************
|
||||||
|
|
||||||
mod: fields do damage on blocking
|
add new power up class: rerolls
|
||||||
name: something about radiation?
|
let you repopulate a power up selection menu
|
||||||
|
|
||||||
|
weekly random challenge where everyone playing each week gets the same random setup.
|
||||||
|
The randomness would be determined by the date so it would sync everyone.
|
||||||
|
powerups still drop, but the drops are determined by a preset list that changes each week.
|
||||||
|
|
||||||
mod: do something at the end of each level
|
mod: do something at the end of each level
|
||||||
heal to full
|
heal to full
|
||||||
|
|||||||
37
js/level.js
37
js/level.js
@@ -16,7 +16,7 @@ const level = {
|
|||||||
// game.difficulty = 6; //for testing to simulate possible mobs spawns
|
// game.difficulty = 6; //for testing to simulate possible mobs spawns
|
||||||
// b.giveGuns(15)
|
// b.giveGuns(15)
|
||||||
// mech.setField(3)
|
// mech.setField(3)
|
||||||
// b.giveMod(10);
|
b.giveMod(16);
|
||||||
|
|
||||||
level.intro(); //starting level
|
level.intro(); //starting level
|
||||||
// level.testingMap();
|
// level.testingMap();
|
||||||
@@ -45,18 +45,18 @@ const level = {
|
|||||||
// if (level.isBuildRun) num++
|
// if (level.isBuildRun) num++
|
||||||
for (let i = 0; i < num; i++) {
|
for (let i = 0; i < num; i++) {
|
||||||
game.difficulty++
|
game.difficulty++
|
||||||
game.dmgScale += 0.1; //damage done by mobs increases each level
|
game.dmgScale += 0.11; //damage done by mobs increases each level
|
||||||
b.dmgScale *= 0.94; //damage done by player decreases each level
|
b.dmgScale *= 0.94; //damage done by player decreases each level
|
||||||
game.accelScale *= 1.03 //mob acceleration increases each level
|
game.accelScale *= 1.03 //mob acceleration increases each level
|
||||||
game.lookFreqScale *= 0.97 //mob cycles between looks decreases each level
|
game.lookFreqScale *= 0.97 //mob cycles between looks decreases each level
|
||||||
game.CDScale *= 0.97 //mob CD time decreases each level
|
game.CDScale *= 0.97 //mob CD time decreases each level
|
||||||
}
|
}
|
||||||
game.healScale = 1 / (1 + game.difficulty * 0.05)
|
game.healScale = 1 / (1 + game.difficulty * 0.06) //a higher denominator makes for lower heals // mech.health += heal * game.healScale;
|
||||||
},
|
},
|
||||||
difficultyDecrease(num = 1) { //used in easy mode for game.reset()
|
difficultyDecrease(num = 1) { //used in easy mode for game.reset()
|
||||||
for (let i = 0; i < num; i++) {
|
for (let i = 0; i < num; i++) {
|
||||||
game.difficulty--
|
game.difficulty--
|
||||||
game.dmgScale -= 0.1; //damage done by mobs increases each level
|
game.dmgScale -= 0.11; //damage done by mobs increases each level
|
||||||
if (game.dmgScale < 0.1) game.dmgScale = 0.1;
|
if (game.dmgScale < 0.1) game.dmgScale = 0.1;
|
||||||
b.dmgScale /= 0.94; //damage done by player decreases each level
|
b.dmgScale /= 0.94; //damage done by player decreases each level
|
||||||
game.accelScale /= 1.03 //mob acceleration increases each level
|
game.accelScale /= 1.03 //mob acceleration increases each level
|
||||||
@@ -64,14 +64,14 @@ const level = {
|
|||||||
game.CDScale /= 0.97 //mob CD time decreases each level
|
game.CDScale /= 0.97 //mob CD time decreases each level
|
||||||
}
|
}
|
||||||
if (game.difficulty < 1) game.difficulty = 1;
|
if (game.difficulty < 1) game.difficulty = 1;
|
||||||
game.healScale = 1 / (1 + game.difficulty * 0.05)
|
game.healScale = 1 / (1 + game.difficulty * 0.06)
|
||||||
},
|
},
|
||||||
//******************************************************************************************************************
|
//******************************************************************************************************************
|
||||||
//******************************************************************************************************************
|
//******************************************************************************************************************
|
||||||
testingMap() {
|
testingMap() {
|
||||||
//start with all guns
|
//start with all guns
|
||||||
level.difficultyIncrease(8)
|
level.difficultyIncrease(9) //level 7 on normal, level 4 on hard, level 1.2 on why?
|
||||||
game.zoomScale = 1400 //1400 is normal
|
game.zoomScale = 1700 //1400 is normal
|
||||||
spawn.setSpawnList();
|
spawn.setSpawnList();
|
||||||
mech.setPosToSpawn(-75, -60); //normal spawn
|
mech.setPosToSpawn(-75, -60); //normal spawn
|
||||||
level.enter.x = mech.spawnPos.x - 50;
|
level.enter.x = mech.spawnPos.x - 50;
|
||||||
@@ -114,17 +114,17 @@ const level = {
|
|||||||
// spawn.lineBoss(-500, -600, spawn.allowedBossList[Math.floor(Math.random() * spawn.allowedBossList.length)]);
|
// spawn.lineBoss(-500, -600, spawn.allowedBossList[Math.floor(Math.random() * spawn.allowedBossList.length)]);
|
||||||
// spawn.bodyRect(-135, -50, 50, 50);
|
// spawn.bodyRect(-135, -50, 50, 50);
|
||||||
// spawn.bodyRect(-140, -100, 50, 50);
|
// spawn.bodyRect(-140, -100, 50, 50);
|
||||||
powerUps.spawn(420, -400, "gun", false);
|
// powerUps.spawn(420, -400, "gun", false);
|
||||||
// powerUps.spawn(420, -400, "field", false);
|
// powerUps.spawn(420, -400, "field", false);
|
||||||
// powerUps.spawn(420, -400, "field", false);
|
// powerUps.spawn(420, -400, "field", false);
|
||||||
// powerUps.spawn(420, -400, "field", false);
|
// powerUps.spawn(420, -400, "field", false);
|
||||||
// powerUps.spawn(450, -400, "mod", false, 6);
|
// powerUps.spawn(450, -400, "mod", false, 6);
|
||||||
// powerUps.spawn(450, -400, "mod", false);
|
// powerUps.spawn(450, -400, "mod", false);
|
||||||
// spawn.bodyRect(-45, -100, 40, 50);
|
// spawn.bodyRect(-45, -100, 40, 50);
|
||||||
// spawn.groupBoss(800, -1050);
|
// spawn.bomber(800, -450);
|
||||||
// spawn.starter(400, -1050);
|
spawn.hopper(400, -1050);
|
||||||
// spawn.starter(1200, -1050);
|
// spawn.starter(1200, -1050);
|
||||||
// spawn.groupBoss(-600, -550);
|
// spawn.nodeBoss(-600, -550, "starter");
|
||||||
// spawn.starter(800, -150);
|
// spawn.starter(800, -150);
|
||||||
// spawn.beamer(800, -150);
|
// spawn.beamer(800, -150);
|
||||||
// spawn.grower(800, -250);
|
// spawn.grower(800, -250);
|
||||||
@@ -203,14 +203,14 @@ const level = {
|
|||||||
spawn.mapRect(6700, -1800, 800, 2600); //right wall
|
spawn.mapRect(6700, -1800, 800, 2600); //right wall
|
||||||
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
|
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
|
||||||
|
|
||||||
for (let i = 0; i < 5; ++i) {
|
for (let i = 0; i < 3; ++i) {
|
||||||
if (game.difficulty * Math.random() > 3 * i) {
|
if (game.difficulty * Math.random() > 15 * i) {
|
||||||
spawn.randomBoss(2000 + 500 * (Math.random() - 0.5), -800 + 200 * (Math.random() - 0.5), Infinity);
|
spawn.randomBoss(2000 + 500 * (Math.random() - 0.5), -800 + 200 * (Math.random() - 0.5), Infinity);
|
||||||
}
|
}
|
||||||
if (game.difficulty * Math.random() > 2.6 * i) {
|
if (game.difficulty * Math.random() > 10 * i) {
|
||||||
spawn.randomBoss(3500 + 500 * (Math.random() - 0.5), -800 + 200 * (Math.random() - 0.5), Infinity);
|
spawn.randomBoss(3500 + 500 * (Math.random() - 0.5), -800 + 200 * (Math.random() - 0.5), Infinity);
|
||||||
}
|
}
|
||||||
if (game.difficulty * Math.random() > 2.4 * i) {
|
if (game.difficulty * Math.random() > 7 * i) {
|
||||||
spawn.randomBoss(5000 + 500 * (Math.random() - 0.5), -800 + 200 * (Math.random() - 0.5), Infinity);
|
spawn.randomBoss(5000 + 500 * (Math.random() - 0.5), -800 + 200 * (Math.random() - 0.5), Infinity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1468,13 +1468,12 @@ const level = {
|
|||||||
nextLevel() {
|
nextLevel() {
|
||||||
//enter when player isn't falling
|
//enter when player isn't falling
|
||||||
if (player.velocity.y < 0.1) {
|
if (player.velocity.y < 0.1) {
|
||||||
//increase difficulty based on modes
|
|
||||||
level.difficultyIncrease(game.difficultyMode + level.isBuildRun)
|
|
||||||
//cycles map to next level
|
|
||||||
level.levelsCleared++;
|
level.levelsCleared++;
|
||||||
level.onLevel++;
|
level.onLevel++; //cycles map to next level
|
||||||
if (level.onLevel > level.levels.length - 1) level.onLevel = 0;
|
if (level.onLevel > level.levels.length - 1) level.onLevel = 0;
|
||||||
|
|
||||||
|
level.difficultyIncrease(game.difficultyMode + level.isBuildRun) //increase difficulty based on modes
|
||||||
|
if (game.isEasyMode && level.levelsCleared % 2) level.difficultyDecrease(1);
|
||||||
game.clearNow = true; //triggers in game.clearMap to remove all physics bodies and setup for new map
|
game.clearNow = true; //triggers in game.clearMap to remove all physics bodies and setup for new map
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
11
js/mobs.js
11
js/mobs.js
@@ -932,17 +932,18 @@ const mobs = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
damage(dmg) {
|
damage(dmg) {
|
||||||
|
if (!this.isShielded) {
|
||||||
dmg /= Math.sqrt(this.mass)
|
dmg /= Math.sqrt(this.mass)
|
||||||
|
if (this.shield) dmg *= 0.04
|
||||||
if (b.isModLowHealthDmg) dmg *= (3 / (2 + mech.health)) //up to 50% dmg at zero player health
|
if (b.isModLowHealthDmg) dmg *= (3 / (2 + mech.health)) //up to 50% dmg at zero player health
|
||||||
if (b.isModFarAwayDmg) dmg *= 1 + Math.sqrt(Math.max(1000, Math.min(3500, this.distanceToPlayer())) - 1000) * 0.01 //up to 50% dmg at max range of 3500
|
if (b.isModFarAwayDmg) dmg *= 1 + Math.sqrt(Math.max(1000, Math.min(3500, this.distanceToPlayer())) - 1000) * 0.01 //up to 50% dmg at max range of 3500
|
||||||
if (dmg !== Infinity) {
|
if (b.modEnergySiphon && dmg !== Infinity) mech.fieldMeter += Math.min(this.health, dmg) * b.modEnergySiphon
|
||||||
if (b.modEnergySiphon) mech.fieldMeter += Math.min(this.health, dmg) * b.modEnergySiphon
|
if (b.modHealthDrain && dmg !== Infinity) mech.addHealth(Math.min(this.health, dmg) * b.modHealthDrain)
|
||||||
if (b.modHealthDrain) mech.addHealth(Math.min(this.health, dmg) * b.modHealthDrain)
|
|
||||||
}
|
|
||||||
this.health -= dmg
|
this.health -= dmg
|
||||||
//this.fill = this.color + this.health + ')';
|
//this.fill = this.color + this.health + ')';
|
||||||
if (this.health < 0.05) this.death();
|
|
||||||
this.onDamage(this); //custom damage effects
|
this.onDamage(this); //custom damage effects
|
||||||
|
if (this.health < 0.05) this.death();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onDamage() {
|
onDamage() {
|
||||||
// a placeholder for custom effects on mob damage
|
// a placeholder for custom effects on mob damage
|
||||||
|
|||||||
16
js/player.js
16
js/player.js
@@ -326,11 +326,7 @@ const mech = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function randomizeField() {
|
function randomizeField() {
|
||||||
if (game.difficulty * (Math.random() + 0.27) > 2) {
|
|
||||||
mech.setField(Math.floor(Math.random() * (mech.fieldUpgrades.length)))
|
mech.setField(Math.floor(Math.random() * (mech.fieldUpgrades.length)))
|
||||||
} else {
|
|
||||||
mech.setField(0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function randomizeHealth() {
|
function randomizeHealth() {
|
||||||
@@ -446,6 +442,9 @@ const mech = {
|
|||||||
dmg *= 0.93
|
dmg *= 0.93
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (b.modPiezo) {
|
||||||
|
mech.fieldMeter += dmg * b.modPiezo
|
||||||
|
}
|
||||||
mech.health -= dmg;
|
mech.health -= dmg;
|
||||||
if (mech.health < 0) {
|
if (mech.health < 0) {
|
||||||
mech.health = 0;
|
mech.health = 0;
|
||||||
@@ -792,8 +791,8 @@ const mech = {
|
|||||||
mech.fieldCDcycle = mech.cycle + 15;
|
mech.fieldCDcycle = mech.cycle + 15;
|
||||||
mech.isHolding = false;
|
mech.isHolding = false;
|
||||||
//bullet-like collisions
|
//bullet-like collisions
|
||||||
mech.holdingTarget.collisionFilter.category = cat.body;
|
mech.holdingTarget.collisionFilter.category = cat.bullet;
|
||||||
mech.holdingTarget.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet;
|
mech.holdingTarget.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield;
|
||||||
//check every second to see if player is away from thrown body, and make solid
|
//check every second to see if player is away from thrown body, and make solid
|
||||||
const solid = function (that) {
|
const solid = function (that) {
|
||||||
const dx = that.position.x - player.position.x;
|
const dx = that.position.x - player.position.x;
|
||||||
@@ -900,6 +899,9 @@ const mech = {
|
|||||||
mech.drawHold(who);
|
mech.drawHold(who);
|
||||||
mech.fieldCDcycle = mech.cycle + 10;
|
mech.fieldCDcycle = mech.cycle + 10;
|
||||||
mech.holdingTarget = null
|
mech.holdingTarget = null
|
||||||
|
if (b.modBlockDmg) {
|
||||||
|
who.damage(b.modBlockDmg)
|
||||||
|
}
|
||||||
//knock backs
|
//knock backs
|
||||||
const unit = Vector.normalise(Vector.sub(player.position, who.position))
|
const unit = Vector.normalise(Vector.sub(player.position, who.position))
|
||||||
const massRoot = Math.sqrt(Math.min(12, Math.max(0.15, who.mass))); // masses above 12 can start to overcome the push back
|
const massRoot = Math.sqrt(Math.min(12, Math.max(0.15, who.mass))); // masses above 12 can start to overcome the push back
|
||||||
@@ -1327,7 +1329,7 @@ const mech = {
|
|||||||
mech.holding();
|
mech.holding();
|
||||||
mech.throwBlock();
|
mech.throwBlock();
|
||||||
} else if ((keys[32] || game.mouseDownRight) && mech.fieldCDcycle < mech.cycle) { //push away
|
} else if ((keys[32] || game.mouseDownRight) && mech.fieldCDcycle < mech.cycle) { //push away
|
||||||
const DRAIN = 0.00025
|
const DRAIN = 0.00035
|
||||||
if (mech.fieldMeter > DRAIN) {
|
if (mech.fieldMeter > DRAIN) {
|
||||||
mech.grabPowerUp();
|
mech.grabPowerUp();
|
||||||
mech.lookForPickUp(150);
|
mech.lookForPickUp(150);
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ const powerUps = {
|
|||||||
size: size
|
size: size
|
||||||
});
|
});
|
||||||
if (mode) {
|
if (mode) {
|
||||||
console.log(mode)
|
// console.log(mode)
|
||||||
powerUp[index].mode = mode
|
powerUp[index].mode = mode
|
||||||
}
|
}
|
||||||
if (moving) {
|
if (moving) {
|
||||||
|
|||||||
133
js/spawn.js
133
js/spawn.js
@@ -19,23 +19,25 @@ const spawn = {
|
|||||||
"sneaker",
|
"sneaker",
|
||||||
],
|
],
|
||||||
allowedBossList: ["chaser", "spinner", "striker", "springer", "laser", "focuser", "beamer", "exploder", "spawner", "shooter"],
|
allowedBossList: ["chaser", "spinner", "striker", "springer", "laser", "focuser", "beamer", "exploder", "spawner", "shooter"],
|
||||||
setSpawnList() {
|
setSpawnList() { //this is run at the start of each new level to determine the possible mobs for the level
|
||||||
//this is run at the start of each new level to determine the possible mobs for the level
|
|
||||||
//each level has 2 mobs: one new mob and one from the last level
|
//each level has 2 mobs: one new mob and one from the last level
|
||||||
spawn.pickList.splice(0, 1);
|
spawn.pickList.splice(0, 1);
|
||||||
spawn.pickList.push(spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]);
|
spawn.pickList.push(spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]);
|
||||||
},
|
},
|
||||||
|
spawnChance(chance) {
|
||||||
|
return Math.random() < chance + 0.07 * game.difficulty && mob.length < -1 + 16 * Math.log10(game.difficulty + 1)
|
||||||
|
},
|
||||||
randomMob(x, y, chance = 1) {
|
randomMob(x, y, chance = 1) {
|
||||||
if (Math.random() < chance + 0.09 * (game.difficulty - 1) && mob.length < 4 + game.difficulty * 1.7) {
|
if (spawn.spawnChance(chance)) {
|
||||||
const pick = this.pickList[Math.floor(Math.random() * this.pickList.length)];
|
const pick = this.pickList[Math.floor(Math.random() * this.pickList.length)];
|
||||||
this[pick](x, y);
|
this[pick](x, y);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
randomSmallMob(x, y,
|
randomSmallMob(x, y,
|
||||||
num = Math.max(Math.min(Math.round(Math.random() * (game.difficulty - 1) * 0.45 - 0.4), 4), 0),
|
num = Math.max(Math.min(Math.round(Math.random() * game.difficulty * 0.2), 4), 0),
|
||||||
size = 16 + Math.ceil(Math.random() * 15),
|
size = 16 + Math.ceil(Math.random() * 15),
|
||||||
chance = 1) {
|
chance = 1) {
|
||||||
if (Math.random() < chance + (game.difficulty - 1) * 0.03 && mob.length < 4 + game.difficulty * 1.7) {
|
if (spawn.spawnChance(chance)) {
|
||||||
for (let i = 0; i < num; ++i) {
|
for (let i = 0; i < num; ++i) {
|
||||||
const pick = this.pickList[Math.floor(Math.random() * this.pickList.length)];
|
const pick = this.pickList[Math.floor(Math.random() * this.pickList.length)];
|
||||||
this[pick](x + Math.round((Math.random() - 0.5) * 20) + i * size * 2.5, y + Math.round((Math.random() - 0.5) * 20), size);
|
this[pick](x + Math.round((Math.random() - 0.5) * 20) + i * size * 2.5, y + Math.round((Math.random() - 0.5) * 20), size);
|
||||||
@@ -43,7 +45,7 @@ const spawn = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
randomBoss(x, y, chance = 1) {
|
randomBoss(x, y, chance = 1) {
|
||||||
if (Math.random() < chance + (game.difficulty - 1) * 0.14 && game.difficulty !== 1 && mob.length < 4 + game.difficulty * 2 || chance == Infinity) {
|
if (spawn.spawnChance(chance) && game.difficulty > 2 || chance == Infinity) {
|
||||||
//choose from the possible picklist
|
//choose from the possible picklist
|
||||||
let pick = this.pickList[Math.floor(Math.random() * this.pickList.length)];
|
let pick = this.pickList[Math.floor(Math.random() * this.pickList.length)];
|
||||||
//is the pick able to be a boss?
|
//is the pick able to be a boss?
|
||||||
@@ -233,7 +235,7 @@ const spawn = {
|
|||||||
me.accelMag = 0.001 * game.accelScale;;
|
me.accelMag = 0.001 * game.accelScale;;
|
||||||
me.g = me.accelMag * 0.6; //required if using 'gravity'
|
me.g = me.accelMag * 0.6; //required if using 'gravity'
|
||||||
me.memory = 50;
|
me.memory = 50;
|
||||||
if (Math.random() < Math.min((game.difficulty - 1) * 0.05, 0.3)) spawn.shield(me, x, y);
|
spawn.shield(me, x, y);
|
||||||
me.do = function () {
|
me.do = function () {
|
||||||
this.gravity();
|
this.gravity();
|
||||||
this.seePlayerCheck();
|
this.seePlayerCheck();
|
||||||
@@ -293,32 +295,12 @@ const spawn = {
|
|||||||
me.onDeath = function () {
|
me.onDeath = function () {
|
||||||
this.removeCons();
|
this.removeCons();
|
||||||
};
|
};
|
||||||
if (Math.random() < Math.min((game.difficulty - 1) * 0.05, 0.3)) spawn.shield(me, x, y);
|
spawn.shield(me, x, y);
|
||||||
me.do = function () {
|
me.do = function () {
|
||||||
this.gravity();
|
this.gravity();
|
||||||
this.searchSpring();
|
this.searchSpring();
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
// zoomer(x, y, radius = 20 + Math.ceil(Math.random() * 30)) {
|
|
||||||
// mobs.spawn(x, y, 6, radius, "#ffe2fd");
|
|
||||||
// let me = mob[mob.length - 1];
|
|
||||||
// me.trailLength = 20; //required for trails
|
|
||||||
// me.setupTrail(); //fill trails array up with the current position of mob
|
|
||||||
// me.trailFill = "#ff00f0";
|
|
||||||
// me.g = 0.001; //required if using 'gravity'
|
|
||||||
// me.frictionAir = 0.02;
|
|
||||||
// me.accelMag = 0.004 * game.accelScale;
|
|
||||||
// me.memory = 30;
|
|
||||||
// me.zoomMode = 150;
|
|
||||||
// me.onHit = function () {
|
|
||||||
// this.zoomMode = 150;
|
|
||||||
// };
|
|
||||||
// me.do = function () {
|
|
||||||
// this.seePlayerByDistAndLOS();
|
|
||||||
// this.zoom();
|
|
||||||
// this.gravity();
|
|
||||||
// };
|
|
||||||
// },
|
|
||||||
hopper(x, y, radius = 30 + Math.ceil(Math.random() * 30)) {
|
hopper(x, y, radius = 30 + Math.ceil(Math.random() * 30)) {
|
||||||
mobs.spawn(x, y, 5, radius, "rgb(0,200,180)");
|
mobs.spawn(x, y, 5, radius, "rgb(0,200,180)");
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
@@ -329,6 +311,7 @@ const spawn = {
|
|||||||
me.delay = 110;
|
me.delay = 110;
|
||||||
me.randomHopFrequency = 50 + Math.floor(Math.random() * 1000);
|
me.randomHopFrequency = 50 + Math.floor(Math.random() * 1000);
|
||||||
me.randomHopCD = game.cycle + me.randomHopFrequency;
|
me.randomHopCD = game.cycle + me.randomHopFrequency;
|
||||||
|
spawn.shield(me, x, y);
|
||||||
me.do = function () {
|
me.do = function () {
|
||||||
this.gravity();
|
this.gravity();
|
||||||
this.seePlayerCheck();
|
this.seePlayerCheck();
|
||||||
@@ -361,6 +344,7 @@ const spawn = {
|
|||||||
me.frictionAir = 0.022;
|
me.frictionAir = 0.022;
|
||||||
me.lookTorque = 0.0000014;
|
me.lookTorque = 0.0000014;
|
||||||
me.restitution = 0;
|
me.restitution = 0;
|
||||||
|
spawn.shield(me, x, y);
|
||||||
me.do = function () {
|
me.do = function () {
|
||||||
this.seePlayerByLookingAt();
|
this.seePlayerByLookingAt();
|
||||||
//accelerate towards the player after a delay
|
//accelerate towards the player after a delay
|
||||||
@@ -464,7 +448,7 @@ const spawn = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
suckerBoss(x, y, radius = 20) {
|
suckerBoss(x, y, radius = 25) {
|
||||||
mobs.spawn(x, y, 12, radius, "#000");
|
mobs.spawn(x, y, 12, radius, "#000");
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
me.stroke = "transparent"; //used for drawSneaker
|
me.stroke = "transparent"; //used for drawSneaker
|
||||||
@@ -493,16 +477,11 @@ const spawn = {
|
|||||||
toMe(mob, this.position, this.eventHorizon)
|
toMe(mob, this.position, this.eventHorizon)
|
||||||
toMe(bullet, this.position, this.eventHorizon)
|
toMe(bullet, this.position, this.eventHorizon)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//push everything away
|
//push everything away
|
||||||
|
|
||||||
// function push(who, pos, range) {
|
// function push(who, pos, range) {
|
||||||
// for (let i = 0, len = who.length; i < len; ++i) {
|
// for (let i = 0, len = who.length; i < len; ++i) {
|
||||||
// const SUB = Vector.sub(who[i].position, pos)
|
// const SUB = Vector.sub(who[i].position, pos)
|
||||||
// const DISTANCE = Vector.magnitude(SUB)
|
// const DISTANCE = Vector.magnitude(SUB)
|
||||||
|
|
||||||
// if (DISTANCE < range) {
|
// if (DISTANCE < range) {
|
||||||
// const depth = range - DISTANCE
|
// const depth = range - DISTANCE
|
||||||
// const force = Vector.mult(Vector.normalise(SUB), 30 * who[i].mass / depth)
|
// const force = Vector.mult(Vector.normalise(SUB), 30 * who[i].mass / depth)
|
||||||
@@ -515,8 +494,6 @@ const spawn = {
|
|||||||
// push(mob, this.position, this.eventHorizon)
|
// push(mob, this.position, this.eventHorizon)
|
||||||
// push(bullet, this.position, this.eventHorizon)
|
// push(bullet, this.position, this.eventHorizon)
|
||||||
// push([player], this.position, this.eventHorizon)
|
// push([player], this.position, this.eventHorizon)
|
||||||
|
|
||||||
|
|
||||||
// for (let i = 0; i < (game.difficulty - 3); ++i) {
|
// for (let i = 0; i < (game.difficulty - 3); ++i) {
|
||||||
// spawn.sucker(this.position.x + (Math.random() - 0.5) * radius * 2, this.position.y + (Math.random() - 0.5) * radius * 2, 70 * Math.random());
|
// spawn.sucker(this.position.x + (Math.random() - 0.5) * radius * 2, this.position.y + (Math.random() - 0.5) * radius * 2, 70 * Math.random());
|
||||||
// Matter.Body.setVelocity(mob[mob.length - 1], {
|
// Matter.Body.setVelocity(mob[mob.length - 1], {
|
||||||
@@ -600,7 +577,7 @@ const spawn = {
|
|||||||
me.accelMag = 0.0005 * game.accelScale;
|
me.accelMag = 0.0005 * game.accelScale;
|
||||||
me.frictionStatic = 0;
|
me.frictionStatic = 0;
|
||||||
me.friction = 0;
|
me.friction = 0;
|
||||||
if (Math.random() < Math.min(0.2 + (game.difficulty - 1) * 0.05, 0.3)) spawn.shield(me, x, y);
|
spawn.shield(me, x, y);
|
||||||
me.do = function () {
|
me.do = function () {
|
||||||
this.seePlayerByLookingAt();
|
this.seePlayerByLookingAt();
|
||||||
this.attraction();
|
this.attraction();
|
||||||
@@ -623,7 +600,7 @@ const spawn = {
|
|||||||
me.onDamage = function () {
|
me.onDamage = function () {
|
||||||
this.laserPos = this.position;
|
this.laserPos = this.position;
|
||||||
};
|
};
|
||||||
// if (Math.random() < Math.min(0.2 + game.difficulty * 0.1, 0.7)) spawn.shield(me, x, y);
|
spawn.shield(me, x, y);
|
||||||
me.do = function () {
|
me.do = function () {
|
||||||
if (!mech.isBodiesAsleep) {
|
if (!mech.isBodiesAsleep) {
|
||||||
this.seePlayerByLookingAt();
|
this.seePlayerByLookingAt();
|
||||||
@@ -698,6 +675,7 @@ const spawn = {
|
|||||||
me.friction = 0;
|
me.friction = 0;
|
||||||
me.delay = 100;
|
me.delay = 100;
|
||||||
Matter.Body.rotate(me, Math.PI * 0.1);
|
Matter.Body.rotate(me, Math.PI * 0.1);
|
||||||
|
spawn.shield(me, x, y);
|
||||||
me.onDamage = function () {
|
me.onDamage = function () {
|
||||||
this.cd = game.cycle + this.delay;
|
this.cd = game.cycle + this.delay;
|
||||||
};
|
};
|
||||||
@@ -858,7 +836,7 @@ const spawn = {
|
|||||||
//boss that drops bombs from above and holds a set distance from player
|
//boss that drops bombs from above and holds a set distance from player
|
||||||
mobs.spawn(x, y, 3, radius, "transparent");
|
mobs.spawn(x, y, 3, radius, "transparent");
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
Matter.Body.setDensity(me, 0.0015 + 0.0005 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
Matter.Body.setDensity(me, 0.0015 + 0.0004 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||||
|
|
||||||
me.stroke = "rgba(255,0,200)"; //used for drawGhost
|
me.stroke = "rgba(255,0,200)"; //used for drawGhost
|
||||||
me.seeAtDistance2 = 1500000;
|
me.seeAtDistance2 = 1500000;
|
||||||
@@ -874,7 +852,7 @@ const spawn = {
|
|||||||
// me.memory = 300;
|
// me.memory = 300;
|
||||||
// Matter.Body.setDensity(me, 0.0015); //extra dense //normal is 0.001
|
// Matter.Body.setDensity(me, 0.0015); //extra dense //normal is 0.001
|
||||||
me.collisionFilter.mask = cat.player | cat.bullet
|
me.collisionFilter.mask = cat.player | cat.bullet
|
||||||
spawn.shield(me, x, y);
|
spawn.shield(me, x, y, 1);
|
||||||
me.onDeath = function () {
|
me.onDeath = function () {
|
||||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||||
};
|
};
|
||||||
@@ -900,30 +878,30 @@ const spawn = {
|
|||||||
x: 0,
|
x: 0,
|
||||||
y: 0
|
y: 0
|
||||||
};
|
};
|
||||||
if (Math.random() < Math.min(0.15 + (game.difficulty - 1) * 0.05, 0.3)) spawn.shield(me, x, y);
|
// spawn.shield(me, x, y);
|
||||||
me.do = function () {
|
me.do = function () {
|
||||||
this.seePlayerByLookingAt();
|
this.seePlayerByLookingAt();
|
||||||
this.fire();
|
this.fire();
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
shooterBoss(x, y, radius = 85 + Math.ceil(Math.random() * 50)) {
|
shooterBoss(x, y, radius = 130) {
|
||||||
//boss spawns on skyscraper level
|
//boss spawns on skyscraper level
|
||||||
mobs.spawn(x, y, 3, radius, "rgb(255,70,180)");
|
mobs.spawn(x, y, 3, radius, "rgb(255,70,180)");
|
||||||
let me = mob[mob.length - 1];
|
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
|
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
|
||||||
me.memory = 240;
|
me.memory = 240;
|
||||||
me.fireFreq = 0.02;
|
me.fireFreq = 0.025;
|
||||||
me.noseLength = 0;
|
me.noseLength = 0;
|
||||||
me.fireAngle = 0;
|
me.fireAngle = 0;
|
||||||
me.accelMag = 0.005 * game.accelScale;
|
me.accelMag = 0.005 * game.accelScale;
|
||||||
me.frictionAir = 0.1;
|
me.frictionAir = 0.1;
|
||||||
me.lookTorque = 0.000005 * (Math.random() > 0.5 ? -1 : 1);
|
me.lookTorque = 0.000007 * (Math.random() > 0.5 ? -1 : 1);
|
||||||
me.fireDir = {
|
me.fireDir = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0
|
y: 0
|
||||||
};
|
};
|
||||||
Matter.Body.setDensity(me, 0.001 + 0.0005 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
Matter.Body.setDensity(me, 0.02 + 0.001 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||||
spawn.shield(me, x, y);
|
// spawn.shield(me, x, y, 1);
|
||||||
me.onDeath = function () {
|
me.onDeath = function () {
|
||||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||||
};
|
};
|
||||||
@@ -970,7 +948,7 @@ const spawn = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (Math.random() < Math.min((game.difficulty - 1) * 0.04, 0.2)) spawn.shield(me, x, y);
|
spawn.shield(me, x, y);
|
||||||
me.do = function () {
|
me.do = function () {
|
||||||
this.gravity();
|
this.gravity();
|
||||||
this.seePlayerCheck();
|
this.seePlayerCheck();
|
||||||
@@ -1018,8 +996,7 @@ const spawn = {
|
|||||||
me.memory = 200;
|
me.memory = 200;
|
||||||
me.laserRange = 500;
|
me.laserRange = 500;
|
||||||
Matter.Body.setDensity(me, 0.001 + 0.0005 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
Matter.Body.setDensity(me, 0.001 + 0.0005 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||||
spawn.shield(me, x, y);
|
spawn.shield(me, x, y, 1);
|
||||||
if (Math.random() < Math.min((game.difficulty - 1) * 0.05, 0.3)) spawn.shield(me, x, y);
|
|
||||||
me.onDeath = function () {
|
me.onDeath = function () {
|
||||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||||
};
|
};
|
||||||
@@ -1059,9 +1036,7 @@ const spawn = {
|
|||||||
me.accelMag = 0.002 * game.accelScale;
|
me.accelMag = 0.002 * game.accelScale;
|
||||||
me.memory = 20;
|
me.memory = 20;
|
||||||
Matter.Body.setDensity(me, 0.001 + 0.0005 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
Matter.Body.setDensity(me, 0.001 + 0.0005 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||||
spawn.shield(me, x, y);
|
spawn.shield(me, x, y, 1);
|
||||||
if (Math.random() < Math.min((game.difficulty - 1) * 0.05, 0.3)) spawn.shield(me, x, y);
|
|
||||||
|
|
||||||
me.onDeath = function () {
|
me.onDeath = function () {
|
||||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||||
this.removeCons(); //remove constraint
|
this.removeCons(); //remove constraint
|
||||||
@@ -1072,46 +1047,57 @@ const spawn = {
|
|||||||
this.attraction();
|
this.attraction();
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
shield(target, x, y, stiffness = 0.4) {
|
shield(target, x, y, chance = Math.min(0.01 + game.difficulty * 0.01, 0.3)) {
|
||||||
if (this.allowShields) {
|
if (this.allowShields && Math.random() < chance) {
|
||||||
mobs.spawn(x, y, 9, target.radius + 20, "rgba(220,220,255,0.6)");
|
mobs.spawn(x, y, 9, target.radius + 30, "rgba(220,220,255,0.9)");
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
me.stroke = "rgb(220,220,255)";
|
me.stroke = "rgb(220,220,255)";
|
||||||
Matter.Body.setDensity(me, 0.0001) //very low density to not mess with the original mob's motion
|
Matter.Body.setDensity(me, 0.00001) //very low density to not mess with the original mob's motion
|
||||||
me.shield = true;
|
me.shield = true;
|
||||||
me.collisionFilter.category = cat.mobShield
|
me.collisionFilter.category = cat.mobShield
|
||||||
me.collisionFilter.mask = cat.bullet;
|
me.collisionFilter.mask = cat.bullet;
|
||||||
consBB[consBB.length] = Constraint.create({
|
consBB[consBB.length] = Constraint.create({
|
||||||
//attach shield to last spawned mob
|
|
||||||
bodyA: me,
|
bodyA: me,
|
||||||
bodyB: target,
|
bodyB: target, //attach shield to target
|
||||||
stiffness: stiffness,
|
stiffness: 0.4,
|
||||||
damping: 0.1
|
damping: 0.1
|
||||||
});
|
});
|
||||||
me.onDamage = function () {
|
me.onDamage = function () {
|
||||||
//make sure the mob that owns the shield can tell when damage is done
|
//make sure the mob that owns the shield can tell when damage is done
|
||||||
this.alertNearByMobs();
|
this.alertNearByMobs();
|
||||||
|
this.fill = `rgba(220,220,255,${0.3 + 0.6 *this.health})`
|
||||||
};
|
};
|
||||||
me.leaveBody = false;
|
me.leaveBody = false;
|
||||||
me.dropPowerUp = false;
|
me.dropPowerUp = false;
|
||||||
me.showHealthBar = false;
|
me.showHealthBar = false;
|
||||||
|
|
||||||
|
me.shieldTargetID = target.id
|
||||||
|
target.isShielded = true;
|
||||||
|
me.onDeath = function () {
|
||||||
|
//clear isShielded status from target
|
||||||
|
for (let i = 0, len = mob.length; i < len; i++) {
|
||||||
|
if (mob[i].id === this.shieldTargetID) mob[i].isShielded = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
//swap order of shield and mob, so that mob is behind shield graphically
|
//swap order of shield and mob, so that mob is behind shield graphically
|
||||||
mob[mob.length - 1] = mob[mob.length - 2];
|
mob[mob.length - 1] = mob[mob.length - 2];
|
||||||
mob[mob.length - 2] = me;
|
mob[mob.length - 2] = me;
|
||||||
me.do = function () {};
|
me.do = function () {};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
bossShield(nodes, x, y, radius) {
|
bossShield(targets, x, y, radius) {
|
||||||
mobs.spawn(x, y, 9, radius, "rgba(220,220,255,0.65)");
|
const nodes = targets.length
|
||||||
|
mobs.spawn(x, y, 9, radius, "rgba(220,220,255,0.9)");
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
me.stroke = "rgb(220,220,255)";
|
me.stroke = "rgb(220,220,255)";
|
||||||
Matter.Body.setDensity(me, 0.00005) //very low density to not mess with the original mob's motion
|
Matter.Body.setDensity(me, 0.00001) //very low density to not mess with the original mob's motion
|
||||||
me.frictionAir = 0;
|
me.frictionAir = 0;
|
||||||
me.shield = true;
|
me.shield = true;
|
||||||
me.collisionFilter.category = cat.mobShield
|
me.collisionFilter.category = cat.mobShield
|
||||||
me.collisionFilter.mask = cat.bullet;
|
me.collisionFilter.mask = cat.bullet;
|
||||||
//constrain to all mob nodes in boss
|
|
||||||
for (let i = 0; i < nodes; ++i) {
|
for (let i = 0; i < nodes; ++i) {
|
||||||
|
mob[mob.length - i - 2].isShielded = true;
|
||||||
|
//constrain to all mob nodes in boss
|
||||||
consBB[consBB.length] = Constraint.create({
|
consBB[consBB.length] = Constraint.create({
|
||||||
bodyA: me,
|
bodyA: me,
|
||||||
bodyB: mob[mob.length - i - 2],
|
bodyB: mob[mob.length - i - 2],
|
||||||
@@ -1120,8 +1106,16 @@ const spawn = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
me.onDamage = function () {
|
me.onDamage = function () {
|
||||||
//make sure the mob that owns the shield can tell when damage is done
|
this.alertNearByMobs(); //makes sure the mob that owns the shield can tell when damage is done
|
||||||
this.alertNearByMobs();
|
this.fill = `rgba(220,220,255,${0.3 + 0.6 *this.health})`
|
||||||
|
};
|
||||||
|
me.onDeath = function () {
|
||||||
|
//clear isShielded status from target
|
||||||
|
for (let j = 0; j < targets.length; j++) {
|
||||||
|
for (let i = 0, len = mob.length; i < len; i++) {
|
||||||
|
if (mob[i].id === targets[j]) mob[i].isShielded = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
me.leaveBody = false;
|
me.leaveBody = false;
|
||||||
me.dropPowerUp = false;
|
me.dropPowerUp = false;
|
||||||
@@ -1143,8 +1137,9 @@ const spawn = {
|
|||||||
sideLength = Math.ceil(Math.random() * 100) + 70, // distance between each node mob
|
sideLength = Math.ceil(Math.random() * 100) + 70, // distance between each node mob
|
||||||
stiffness = Math.random() * 0.03 + 0.005
|
stiffness = Math.random() * 0.03 + 0.005
|
||||||
) {
|
) {
|
||||||
this.allowShields = false; //don't want shields on boss mobs
|
this.allowShields = false; //don't want shields on individual boss mobs
|
||||||
const angle = 2 * Math.PI / nodes
|
const angle = 2 * Math.PI / nodes
|
||||||
|
let targets = []
|
||||||
for (let i = 0; i < nodes; ++i) {
|
for (let i = 0; i < nodes; ++i) {
|
||||||
let whoSpawn = spawn;
|
let whoSpawn = spawn;
|
||||||
if (spawn === "random") {
|
if (spawn === "random") {
|
||||||
@@ -1153,6 +1148,7 @@ const spawn = {
|
|||||||
whoSpawn = this.pickList[Math.floor(Math.random() * this.pickList.length)];
|
whoSpawn = this.pickList[Math.floor(Math.random() * this.pickList.length)];
|
||||||
}
|
}
|
||||||
this[whoSpawn](x + sideLength * Math.sin(i * angle), y + sideLength * Math.cos(i * angle), radius);
|
this[whoSpawn](x + sideLength * Math.sin(i * angle), y + sideLength * Math.cos(i * angle), radius);
|
||||||
|
targets.push(mob[mob.length - 1].id) //track who is in the node boss, for shields
|
||||||
}
|
}
|
||||||
if (Math.random() < 0.3) {
|
if (Math.random() < 0.3) {
|
||||||
this.constrain2AdjacentMobs(nodes, stiffness * 2, true);
|
this.constrain2AdjacentMobs(nodes, stiffness * 2, true);
|
||||||
@@ -1161,8 +1157,7 @@ const spawn = {
|
|||||||
}
|
}
|
||||||
//spawn shield for entire boss
|
//spawn shield for entire boss
|
||||||
if (nodes > 2 && Math.random() < 0.998) {
|
if (nodes > 2 && Math.random() < 0.998) {
|
||||||
this.bossShield(nodes, x, y, sideLength + 2.5 * radius + nodes * 6 - 25);
|
this.bossShield(targets, x, y, sideLength + 2.5 * radius + nodes * 6 - 25);
|
||||||
// this.bossShield(nodes, x, y, sideLength / (2 * Math.sin(Math.PI / nodes)));
|
|
||||||
}
|
}
|
||||||
this.allowShields = true;
|
this.allowShields = true;
|
||||||
},
|
},
|
||||||
@@ -1176,7 +1171,7 @@ const spawn = {
|
|||||||
l = Math.ceil(Math.random() * 80) + 30,
|
l = Math.ceil(Math.random() * 80) + 30,
|
||||||
stiffness = Math.random() * 0.06 + 0.01
|
stiffness = Math.random() * 0.06 + 0.01
|
||||||
) {
|
) {
|
||||||
this.allowShields = false; //don't want shields on boss mobs
|
this.allowShields = false; //don't want shields on individual boss mobs
|
||||||
for (let i = 0; i < nodes; ++i) {
|
for (let i = 0; i < nodes; ++i) {
|
||||||
let whoSpawn = spawn;
|
let whoSpawn = spawn;
|
||||||
if (spawn === "random") {
|
if (spawn === "random") {
|
||||||
|
|||||||
Reference in New Issue
Block a user