bug fixes, pulse stun mod
This commit is contained in:
129
js/bullets.js
129
js/bullets.js
@@ -37,7 +37,6 @@ const b = {
|
|||||||
isModPiezo: null,
|
isModPiezo: null,
|
||||||
isModDroneCollide: null,
|
isModDroneCollide: null,
|
||||||
isModFastSpores: null,
|
isModFastSpores: null,
|
||||||
isModStomp: null,
|
|
||||||
modSuperBallNumber: null,
|
modSuperBallNumber: null,
|
||||||
modOneSuperBall: null,
|
modOneSuperBall: null,
|
||||||
modLaserReflections: null,
|
modLaserReflections: null,
|
||||||
@@ -79,6 +78,7 @@ const b = {
|
|||||||
isModSporeFollow: null,
|
isModSporeFollow: null,
|
||||||
isModNailPoison: null,
|
isModNailPoison: null,
|
||||||
isModEnergyHealth: null,
|
isModEnergyHealth: null,
|
||||||
|
isModPulseStun: null,
|
||||||
modOnHealthChange() { //used with acid mod
|
modOnHealthChange() { //used with acid mod
|
||||||
if (b.isModAcidDmg && mech.health > 0.8) {
|
if (b.isModAcidDmg && mech.health > 0.8) {
|
||||||
b.modAcidDmg = 0.5
|
b.modAcidDmg = 0.5
|
||||||
@@ -144,13 +144,13 @@ const b = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "fracture analysis",
|
name: "fracture analysis",
|
||||||
description: "<strong>5x</strong> physical <strong class='color-d'>damage</strong> to unaware mobs<br><em>unaware mobs don't have a health bar</em>",
|
description: "<strong>bullets</strong> do <strong>5x</strong> <strong class='color-d'>damage</strong> to <strong>unaware</strong> mobs<br><em>unaware mobs don't have a health bar</em>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
return b.isModFarAwayDmg
|
return true
|
||||||
},
|
},
|
||||||
requires: "kinetic bombardment",
|
requires: "",
|
||||||
effect() {
|
effect() {
|
||||||
b.isModCrit = true;
|
b.isModCrit = true;
|
||||||
},
|
},
|
||||||
@@ -201,9 +201,9 @@ const b = {
|
|||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
return b.isModLowHealthDmg
|
return true
|
||||||
},
|
},
|
||||||
requires: "negative feedback",
|
requires: "",
|
||||||
effect() {
|
effect() {
|
||||||
b.isModHarmDamage = true;
|
b.isModHarmDamage = true;
|
||||||
},
|
},
|
||||||
@@ -261,7 +261,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "mass driver",
|
name: "mass driver",
|
||||||
description: "<strong>blocks</strong> do <strong>3x</strong> more <strong class='color-d'>damage</strong> to mobs<br>charge <strong>throws</strong> in <strong>3x</strong> less time",
|
description: "<strong>blocks</strong> do <strong>2x</strong> more <strong class='color-d'>damage</strong> to mobs<br>charge <strong>throws</strong> more <strong>quickly</strong> for less <strong class='color-f'>energy</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
@@ -269,7 +269,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
requires: "",
|
requires: "",
|
||||||
effect() {
|
effect() {
|
||||||
b.modThrowChargeRate = 3
|
b.modThrowChargeRate = 2
|
||||||
},
|
},
|
||||||
remove() {
|
remove() {
|
||||||
b.modThrowChargeRate = 1
|
b.modThrowChargeRate = 1
|
||||||
@@ -402,6 +402,22 @@ const b = {
|
|||||||
b.modMobDieAtHealth = 0.05;
|
b.modMobDieAtHealth = 0.05;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "scrap recycling",
|
||||||
|
description: "<strong class='color-h'>heal</strong> up to <strong>1%</strong> of max health every second<br>active for <strong>5 seconds</strong> after a mob <strong>dies</strong>",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
allowed() {
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
requires: "",
|
||||||
|
effect() {
|
||||||
|
b.isModHealthRecovery = true;
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
b.isModHealthRecovery = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "waste energy recovery",
|
name: "waste energy recovery",
|
||||||
description: "regen <strong>7%</strong> of max <strong class='color-f'>energy</strong> every second<br>active for <strong>5 seconds</strong> after a mob <strong>dies</strong>",
|
description: "regen <strong>7%</strong> of max <strong class='color-f'>energy</strong> every second<br>active for <strong>5 seconds</strong> after a mob <strong>dies</strong>",
|
||||||
@@ -418,31 +434,15 @@ const b = {
|
|||||||
b.isModEnergyRecovery = false;
|
b.isModEnergyRecovery = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "scrap recycling",
|
|
||||||
description: "<strong class='color-h'>heal</strong> up to <strong>1%</strong> of max health every second<br>active for <strong>5 seconds</strong> after a mob <strong>dies</strong>",
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
allowed() {
|
|
||||||
return b.isModEnergyRecovery
|
|
||||||
},
|
|
||||||
requires: "waste energy recovery",
|
|
||||||
effect() {
|
|
||||||
b.isModHealthRecovery = true;
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
b.isModHealthRecovery = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "acute stress response",
|
name: "acute stress response",
|
||||||
description: "increase <strong class='color-d'>damage</strong> by <strong>33%</strong><br>but, after a mob <strong>dies</strong> lose <strong>1/2</strong> your <strong class='color-f'>energy</strong>",
|
description: "increase <strong class='color-d'>damage</strong> by <strong>33%</strong><br>but, after a mob <strong>dies</strong> lose <strong>1/2</strong> your <strong class='color-f'>energy</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
return b.isModEnergyRecovery
|
return true
|
||||||
},
|
},
|
||||||
requires: "waste energy recovery",
|
requires: "",
|
||||||
effect() {
|
effect() {
|
||||||
b.isModEnergyLoss = true;
|
b.isModEnergyLoss = true;
|
||||||
},
|
},
|
||||||
@@ -470,22 +470,6 @@ const b = {
|
|||||||
mech.jumpForce = 0.42; //was 0.38 at 0.0019 gravity
|
mech.jumpForce = 0.42; //was 0.38 at 0.0019 gravity
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "basidio-stomp",
|
|
||||||
description: "hard <strong>landings</strong> disrupt <strong class='color-p' style='letter-spacing: 2px;'>spores</strong> in the ground<br>immune to <strong>harm</strong> from <strong>falling</strong>",
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
allowed() {
|
|
||||||
return b.modSquirrelFx > 1
|
|
||||||
},
|
|
||||||
requires: "squirrel-cage rotor",
|
|
||||||
effect() {
|
|
||||||
b.isModStomp = true
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
b.isModStomp = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "Pauli exclusion",
|
name: "Pauli exclusion",
|
||||||
description: `unable to <strong>collide</strong> with mobs for <strong>+2</strong> seconds<br>activates after being <strong>harmed</strong> from a collision`,
|
description: `unable to <strong>collide</strong> with mobs for <strong>+2</strong> seconds<br>activates after being <strong>harmed</strong> from a collision`,
|
||||||
@@ -525,9 +509,9 @@ const b = {
|
|||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
return b.isModImmortal
|
return true
|
||||||
},
|
},
|
||||||
requires: "quantum immortality",
|
requires: "",
|
||||||
effect() {
|
effect() {
|
||||||
b.isModDeathAvoid = true;
|
b.isModDeathAvoid = true;
|
||||||
b.isModDeathAvoidOnCD = false;
|
b.isModDeathAvoidOnCD = false;
|
||||||
@@ -560,7 +544,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "mass-energy equivalence",
|
name: "mass-energy equivalence",
|
||||||
description: "your <strong class='color-f'>energy</strong> replaces your <strong>health</strong><br>you can't <strong>die</strong> if your <strong class='color-f'>energy</strong> is above <strong>zero</strong>",
|
description: "you can't <strong>die</strong> if your <strong class='color-f'>energy</strong> is above <strong>zero</strong><br>your <strong>health</strong> is permanently set to <strong>zero</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
@@ -1175,7 +1159,7 @@ const b = {
|
|||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
return b.haveGunCheck("spores") || b.modSporesOnDeath > 0 || b.isModStomp || b.isModSporeField
|
return b.haveGunCheck("spores") || b.modSporesOnDeath > 0 || b.isModSporeField
|
||||||
},
|
},
|
||||||
requires: "spores",
|
requires: "spores",
|
||||||
effect() {
|
effect() {
|
||||||
@@ -1191,7 +1175,7 @@ const b = {
|
|||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
return b.haveGunCheck("spores") || b.modSporesOnDeath > 0 || b.isModStomp || b.isModSporeField
|
return b.haveGunCheck("spores") || b.modSporesOnDeath > 0 || b.isModSporeField
|
||||||
},
|
},
|
||||||
requires: "spores",
|
requires: "spores",
|
||||||
effect() {
|
effect() {
|
||||||
@@ -1301,6 +1285,22 @@ const b = {
|
|||||||
b.modLaserFieldDrain = 0.002;
|
b.modLaserFieldDrain = 0.002;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "shock wave",
|
||||||
|
description: "mobs caught in <strong>pulse's</strong> explosion are <strong>stunned</strong>",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
allowed() {
|
||||||
|
return b.haveGunCheck("pulse")
|
||||||
|
},
|
||||||
|
requires: "pulse",
|
||||||
|
effect() {
|
||||||
|
b.isModPulseStun = true;
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
b.isModPulseStun = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "flux pinning",
|
name: "flux pinning",
|
||||||
description: "blocking with <strong>perfect diamagnetism</strong><br><strong>stuns</strong> mobs for <strong>+1</strong> second",
|
description: "blocking with <strong>perfect diamagnetism</strong><br><strong>stuns</strong> mobs for <strong>+1</strong> second",
|
||||||
@@ -1568,14 +1568,21 @@ const b = {
|
|||||||
game.updateGunHUD();
|
game.updateGunHUD();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (b.isModAmmoFromHealth && mech.health > 0.05) {
|
if (b.isModAmmoFromHealth) {
|
||||||
mech.damage(Math.max(0.01, b.isModAmmoFromHealth * mech.health));
|
if (mech.health > 0.05) {
|
||||||
powerUps.spawn(mech.pos.x, mech.pos.y, "ammo");
|
mech.damage(Math.max(0.01, b.isModAmmoFromHealth * mech.health));
|
||||||
if (Math.random() < b.isModBayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "ammo");
|
powerUps.spawn(mech.pos.x, mech.pos.y, "ammo");
|
||||||
|
if (Math.random() < b.isModBayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "ammo");
|
||||||
|
} else {
|
||||||
|
game.replaceTextLog = true;
|
||||||
|
game.makeTextLog("not enough health for catabolism to produce ammo", 120);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
game.replaceTextLog = true;
|
||||||
|
game.makeTextLog("<div style='font-size:140%;'>NO AMMO</div> <p style='font-size:90%;'><strong>Q</strong>, <strong>E</strong>, and <strong>mouse wheel</strong> change weapons</p>", 200);
|
||||||
}
|
}
|
||||||
mech.fireCDcycle = mech.cycle + 30; //fire cooldown
|
mech.fireCDcycle = mech.cycle + 30; //fire cooldown
|
||||||
game.replaceTextLog = true;
|
|
||||||
game.makeTextLog("<div style='font-size:140%;'>NO AMMO</div> <p style='font-size:90%;'><strong>Q</strong>, <strong>E</strong>, and <strong>mouse wheel</strong> change weapons</p>", 200);
|
|
||||||
}
|
}
|
||||||
if (mech.holdingTarget) {
|
if (mech.holdingTarget) {
|
||||||
mech.drop();
|
mech.drop();
|
||||||
@@ -2117,7 +2124,7 @@ const b = {
|
|||||||
friction: 0,
|
friction: 0,
|
||||||
frictionAir: 0.10,
|
frictionAir: 0.10,
|
||||||
restitution: 0.3,
|
restitution: 0.3,
|
||||||
dmg: 0.18, //damage done in addition to the damage from momentum
|
dmg: 0.17, //damage done in addition to the damage from momentum
|
||||||
lookFrequency: 10 + Math.floor(7 * Math.random()),
|
lookFrequency: 10 + Math.floor(7 * Math.random()),
|
||||||
endCycle: game.cycle + 120 * b.isModBulletsLastLonger, //Math.floor((1200 + 420 * Math.random()) * b.isModBulletsLastLonger),
|
endCycle: game.cycle + 120 * b.isModBulletsLastLonger, //Math.floor((1200 + 420 * Math.random()) * b.isModBulletsLastLonger),
|
||||||
classType: "bullet",
|
classType: "bullet",
|
||||||
@@ -3286,7 +3293,7 @@ const b = {
|
|||||||
if (who.shield) {
|
if (who.shield) {
|
||||||
for (let i = 0, len = mob.length; i < len; i++) {
|
for (let i = 0, len = mob.length; i < len; i++) {
|
||||||
if (mob[i].id === who.shieldTargetID) { //apply some knock back to shield mob before shield breaks
|
if (mob[i].id === who.shieldTargetID) { //apply some knock back to shield mob before shield breaks
|
||||||
const force = Matter.Vector.mult(this.velocity, 15 / mob[i].mass)
|
const force = Matter.Vector.mult(this.velocity, 7 / mob[i].mass)
|
||||||
Matter.Body.setVelocity(mob[i], {
|
Matter.Body.setVelocity(mob[i], {
|
||||||
x: mob[i].velocity.x + force.x,
|
x: mob[i].velocity.x + force.x,
|
||||||
y: mob[i].velocity.y + force.y
|
y: mob[i].velocity.y + force.y
|
||||||
@@ -3757,6 +3764,16 @@ const b = {
|
|||||||
if (best.who) b.explosion(path[1], 1000 * energy, true)
|
if (best.who) b.explosion(path[1], 1000 * energy, true)
|
||||||
mech.fireCDcycle = mech.cycle + Math.floor(60 * b.modFireRate); // cool down
|
mech.fireCDcycle = mech.cycle + Math.floor(60 * b.modFireRate); // cool down
|
||||||
|
|
||||||
|
if (b.isModPulseStun) {
|
||||||
|
const range = 100 + 2000 * energy
|
||||||
|
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||||
|
if (mob[i].alive && !mob[i].isShielded) {
|
||||||
|
dist = Vector.magnitude(Vector.sub(path[1], mob[i].position)) - mob[i].radius;
|
||||||
|
if (dist < range) mobs.statusStun(mob[i], 30 + Math.floor(energy * 60))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//draw laser beam
|
//draw laser beam
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(path[0].x, path[0].y);
|
ctx.moveTo(path[0].x, path[0].y);
|
||||||
|
|||||||
12
js/level.js
12
js/level.js
@@ -146,9 +146,9 @@ const level = {
|
|||||||
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
|
||||||
|
|
||||||
// spawn.laserBoss(2900, -500)
|
// spawn.laserBoss(2900, -500)
|
||||||
// spawn.sucker(1200, -500)
|
spawn.striker(1200, -500)
|
||||||
// spawn.timeSkipBoss(2900, -500)
|
// spawn.timeSkipBoss(2900, -500)
|
||||||
spawn.randomMob(1600, -500)
|
// spawn.randomMob(1600, -500)
|
||||||
|
|
||||||
},
|
},
|
||||||
bosses() {
|
bosses() {
|
||||||
@@ -492,12 +492,12 @@ const level = {
|
|||||||
spawn.mapRect(5200, -775, 100, 920);
|
spawn.mapRect(5200, -775, 100, 920);
|
||||||
spawn.mapRect(5300, -1075, 350, 1220);
|
spawn.mapRect(5300, -1075, 350, 1220);
|
||||||
spawn.boost(5825, 235, 1400);
|
spawn.boost(5825, 235, 1400);
|
||||||
level.fillBG.push({
|
level.fill.push({
|
||||||
x: 5200,
|
x: 5200,
|
||||||
y: 125,
|
y: 125,
|
||||||
width: 450,
|
width: 450,
|
||||||
height: 200,
|
height: 200,
|
||||||
color: "rgba(0,20,40,0.2)"
|
color: "rgba(0,20,40,0.25)"
|
||||||
});
|
});
|
||||||
|
|
||||||
//structure bellow tall stairs
|
//structure bellow tall stairs
|
||||||
@@ -522,12 +522,12 @@ const level = {
|
|||||||
spawn.mapRect(4100, -3450, 100, 700); //left top shelf
|
spawn.mapRect(4100, -3450, 100, 700); //left top shelf
|
||||||
spawn.mapRect(4200, -3450, 100, 400); //left top shelf
|
spawn.mapRect(4200, -3450, 100, 400); //left top shelf
|
||||||
spawn.mapRect(4300, -3450, 100, 100); //left top shelf
|
spawn.mapRect(4300, -3450, 100, 100); //left top shelf
|
||||||
level.fillBG.push({
|
level.fill.push({
|
||||||
x: 4100,
|
x: 4100,
|
||||||
y: -3450,
|
y: -3450,
|
||||||
width: 500,
|
width: 500,
|
||||||
height: 1750,
|
height: 1750,
|
||||||
color: "#d0d4d6"
|
color: "rgba(0,20,40,0.1)"
|
||||||
});
|
});
|
||||||
level.fill.push({
|
level.fill.push({
|
||||||
x: 4100,
|
x: 4100,
|
||||||
|
|||||||
545
js/player.js
545
js/player.js
@@ -886,8 +886,8 @@ const mech = {
|
|||||||
throwBlock() {
|
throwBlock() {
|
||||||
if (mech.holdingTarget) {
|
if (mech.holdingTarget) {
|
||||||
if (keys[32] || game.mouseDownRight) {
|
if (keys[32] || game.mouseDownRight) {
|
||||||
if (mech.energy > 0.0007) {
|
if (mech.energy > 0.001) {
|
||||||
mech.energy -= 0.0007;
|
mech.energy -= 0.001 / b.modThrowChargeRate;
|
||||||
mech.throwCharge += 0.5 * b.modThrowChargeRate / mech.holdingTarget.mass
|
mech.throwCharge += 0.5 * b.modThrowChargeRate / mech.holdingTarget.mass
|
||||||
//draw charge
|
//draw charge
|
||||||
const x = mech.pos.x + 15 * Math.cos(mech.angle);
|
const x = mech.pos.x + 15 * Math.cos(mech.angle);
|
||||||
@@ -1261,6 +1261,46 @@ const mech = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "standing wave harmonics",
|
||||||
|
description: "three oscillating <strong>shields</strong> are permanently active<br><strong class='color-f'>energy</strong> regenerates while field is active",
|
||||||
|
isEasyToAim: true,
|
||||||
|
effect: () => {
|
||||||
|
mech.hold = function () {
|
||||||
|
if (mech.isHolding) {
|
||||||
|
mech.drawHold(mech.holdingTarget);
|
||||||
|
mech.holding();
|
||||||
|
mech.throwBlock();
|
||||||
|
} else if ((keys[32] || game.mouseDownRight) && mech.fieldCDcycle < mech.cycle) { //not hold but field button is pressed
|
||||||
|
mech.grabPowerUp();
|
||||||
|
mech.lookForPickUp();
|
||||||
|
} else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding, but field button is released
|
||||||
|
mech.pickUp();
|
||||||
|
} else {
|
||||||
|
mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
|
||||||
|
}
|
||||||
|
if (mech.energy > 0.1 && mech.fieldCDcycle < mech.cycle) {
|
||||||
|
const fieldRange1 = (0.55 + 0.35 * Math.sin(mech.cycle / 23)) * mech.fieldRange
|
||||||
|
const fieldRange2 = (0.5 + 0.4 * Math.sin(mech.cycle / 37)) * mech.fieldRange
|
||||||
|
const fieldRange3 = (0.45 + 0.45 * Math.sin(mech.cycle / 47)) * mech.fieldRange
|
||||||
|
const netfieldRange = Math.max(fieldRange1, fieldRange2, fieldRange3)
|
||||||
|
ctx.fillStyle = "rgba(110,170,200," + (0.04 + mech.energy * (0.12 + 0.13 * Math.random())) + ")";
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(mech.pos.x, mech.pos.y, fieldRange1, 0, 2 * Math.PI);
|
||||||
|
ctx.fill();
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(mech.pos.x, mech.pos.y, fieldRange2, 0, 2 * Math.PI);
|
||||||
|
ctx.fill();
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(mech.pos.x, mech.pos.y, fieldRange3, 0, 2 * Math.PI);
|
||||||
|
ctx.fill();
|
||||||
|
mech.pushMobs360(netfieldRange);
|
||||||
|
// mech.pushBody360(netfieldRange); //can't throw block when pushhing blocks away
|
||||||
|
}
|
||||||
|
mech.drawFieldMeter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "perfect diamagnetism",
|
name: "perfect diamagnetism",
|
||||||
// description: "gain <strong class='color-f'>energy</strong> when <strong>blocking</strong><br>no <strong>recoil</strong> when <strong>blocking</strong>",
|
// description: "gain <strong class='color-f'>energy</strong> when <strong>blocking</strong><br>no <strong>recoil</strong> when <strong>blocking</strong>",
|
||||||
@@ -1320,97 +1360,192 @@ const mech = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "time dilation field",
|
name: "nano-scale manufacturing",
|
||||||
description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 1px;'>stop time</strong><br><em>you can move and fire while time is stopped</em>",
|
description: "excess <strong class='color-f'>energy</strong> used to build <strong>drones</strong><br><strong>2x</strong> <strong class='color-f'>energy</strong> regeneration",
|
||||||
isEasyToAim: true,
|
isEasyToAim: true,
|
||||||
effect: () => {
|
effect: () => {
|
||||||
// mech.fieldMeterColor = "#000"
|
// mech.fieldRegen *= 2;
|
||||||
mech.fieldFire = true;
|
|
||||||
mech.isBodiesAsleep = false;
|
|
||||||
mech.hold = function () {
|
mech.hold = function () {
|
||||||
|
if (mech.energy > mech.fieldEnergyMax - 0.02 && mech.fieldCDcycle < mech.cycle) {
|
||||||
|
if (b.isModSporeField) {
|
||||||
|
// mech.fieldCDcycle = mech.cycle + 10; // set cool down to prevent +energy from making huge numbers of drones
|
||||||
|
const len = Math.floor(6 + 4 * Math.random())
|
||||||
|
mech.energy -= len * 0.074;
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
b.spore(player)
|
||||||
|
}
|
||||||
|
} else if (b.isModMissileField) {
|
||||||
|
// mech.fieldCDcycle = mech.cycle + 10; // set cool down to prevent +energy from making huge numbers of drones
|
||||||
|
mech.energy -= 0.5;
|
||||||
|
b.missile({
|
||||||
|
x: mech.pos.x + 40 * Math.cos(mech.angle),
|
||||||
|
y: mech.pos.y + 40 * Math.sin(mech.angle) - 3
|
||||||
|
},
|
||||||
|
mech.angle + (0.5 - Math.random()) * (mech.crouch ? 0 : 0.2),
|
||||||
|
-3 * (0.5 - Math.random()) + (mech.crouch ? 25 : -8) * b.modFireRate,
|
||||||
|
1, b.modBabyMissiles)
|
||||||
|
} else if (b.isModIceField) {
|
||||||
|
// mech.fieldCDcycle = mech.cycle + 17; // set cool down to prevent +energy from making huge numbers of drones
|
||||||
|
mech.energy -= 0.061;
|
||||||
|
b.iceIX(1)
|
||||||
|
} else {
|
||||||
|
// mech.fieldCDcycle = mech.cycle + 10; // set cool down to prevent +energy from making huge numbers of drones
|
||||||
|
mech.energy -= 0.33;
|
||||||
|
b.drone(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
if (mech.isHolding) {
|
if (mech.isHolding) {
|
||||||
mech.wakeCheck();
|
|
||||||
mech.drawHold(mech.holdingTarget);
|
mech.drawHold(mech.holdingTarget);
|
||||||
mech.holding();
|
mech.holding();
|
||||||
mech.throwBlock();
|
mech.throwBlock();
|
||||||
} else if ((keys[32] || game.mouseDownRight) && mech.fieldCDcycle < mech.cycle) {
|
} else if ((keys[32] || game.mouseDownRight && mech.fieldCDcycle < mech.cycle)) { //not hold but field button is pressed
|
||||||
mech.grabPowerUp();
|
mech.grabPowerUp();
|
||||||
mech.lookForPickUp(180);
|
mech.lookForPickUp();
|
||||||
|
if (mech.energy > 0.05) {
|
||||||
const DRAIN = 0.0017
|
mech.drawField();
|
||||||
if (mech.energy > DRAIN) {
|
mech.pushMobsFacing();
|
||||||
mech.energy -= DRAIN;
|
|
||||||
if (mech.energy < DRAIN) {
|
|
||||||
mech.fieldCDcycle = mech.cycle + 120;
|
|
||||||
mech.energy = 0;
|
|
||||||
mech.wakeCheck();
|
|
||||||
}
|
|
||||||
//draw field everywhere
|
|
||||||
ctx.globalCompositeOperation = "saturation"
|
|
||||||
// ctx.fillStyle = "rgba(100,200,230," + (0.25 + 0.06 * Math.random()) + ")";
|
|
||||||
ctx.fillStyle = "#ccc";
|
|
||||||
ctx.fillRect(-100000, -100000, 200000, 200000)
|
|
||||||
ctx.globalCompositeOperation = "source-over"
|
|
||||||
//stop time
|
|
||||||
mech.isBodiesAsleep = true;
|
|
||||||
|
|
||||||
function sleep(who) {
|
|
||||||
for (let i = 0, len = who.length; i < len; ++i) {
|
|
||||||
if (!who[i].isSleeping) {
|
|
||||||
who[i].storeVelocity = who[i].velocity
|
|
||||||
who[i].storeAngularVelocity = who[i].angularVelocity
|
|
||||||
}
|
|
||||||
Matter.Sleeping.set(who[i], true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sleep(mob);
|
|
||||||
sleep(body);
|
|
||||||
sleep(bullet);
|
|
||||||
//doesn't really work, just slows down constraints
|
|
||||||
for (let i = 0, len = cons.length; i < len; i++) {
|
|
||||||
if (cons[i].stiffness !== 0) {
|
|
||||||
cons[i].storeStiffness = cons[i].stiffness;
|
|
||||||
cons[i].stiffness = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
game.cycle--; //pause all functions that depend on game cycle increasing
|
|
||||||
if (b.isModTimeSkip) {
|
|
||||||
game.isTimeSkipping = true;
|
|
||||||
mech.cycle++;
|
|
||||||
game.gravity();
|
|
||||||
Engine.update(engine, game.delta);
|
|
||||||
// level.checkZones();
|
|
||||||
// level.checkQuery();
|
|
||||||
mech.move();
|
|
||||||
game.checks();
|
|
||||||
// mobs.loop();
|
|
||||||
// mech.draw();
|
|
||||||
mech.walk_cycle += mech.flipLegs * mech.Vx;
|
|
||||||
// mech.hold();
|
|
||||||
mech.energy += 0.5 * DRAIN; //x1 to undo the energy drain from time speed up, x1.5 to cut energy drain in half
|
|
||||||
b.fire();
|
|
||||||
// b.bulletRemove();
|
|
||||||
b.bulletDo();
|
|
||||||
game.isTimeSkipping = false;
|
|
||||||
}
|
|
||||||
// game.cycle--; //pause all functions that depend on game cycle increasing
|
|
||||||
// if (b.isModTimeSkip && !game.isTimeSkipping) { //speed up the rate of time
|
|
||||||
// game.timeSkip(1)
|
|
||||||
// mech.energy += 1.5 * DRAIN; //x1 to undo the energy drain from time speed up, x1.5 to cut energy drain in half
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
} else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding, but field button is released
|
} else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding, but field button is released
|
||||||
mech.wakeCheck();
|
|
||||||
mech.pickUp();
|
mech.pickUp();
|
||||||
} else {
|
} else {
|
||||||
mech.wakeCheck();
|
|
||||||
mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
|
mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
|
||||||
}
|
}
|
||||||
|
mech.energy += mech.fieldRegen;
|
||||||
mech.drawFieldMeter()
|
mech.drawFieldMeter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "negative mass field",
|
||||||
|
description: "use <strong class='color-f'>energy</strong> to nullify <strong style='letter-spacing: 12px;'>gravity</strong><br>reduce <strong>harm</strong> by <strong>80%</strong> while field is active", //<br><strong>launch</strong> larger blocks at much higher speeds
|
||||||
|
fieldDrawRadius: 0,
|
||||||
|
isEasyToAim: true,
|
||||||
|
effect: () => {
|
||||||
|
mech.fieldFire = true;
|
||||||
|
mech.holdingMassScale = 0.03; //can hold heavier blocks with lower cost to jumping
|
||||||
|
mech.fieldMeterColor = "#000"
|
||||||
|
|
||||||
|
mech.hold = function () {
|
||||||
|
mech.fieldDamageResistance = 1;
|
||||||
|
if (mech.isHolding) {
|
||||||
|
mech.drawHold(mech.holdingTarget);
|
||||||
|
mech.holding();
|
||||||
|
mech.throwBlock();
|
||||||
|
} else if ((keys[32] || game.mouseDownRight) && mech.fieldCDcycle < mech.cycle) { //push away
|
||||||
|
mech.grabPowerUp();
|
||||||
|
mech.lookForPickUp();
|
||||||
|
const DRAIN = 0.00035
|
||||||
|
if (mech.energy > DRAIN) {
|
||||||
|
mech.fieldDamageResistance = 0.2; // 1 - 0.8
|
||||||
|
// mech.pushMobs360();
|
||||||
|
|
||||||
|
//repulse mobs
|
||||||
|
// for (let i = 0, len = mob.length; i < len; ++i) {
|
||||||
|
// sub = Vector.sub(mob[i].position, mech.pos);
|
||||||
|
// dist2 = Vector.magnitudeSquared(sub);
|
||||||
|
// if (dist2 < this.fieldDrawRadius * this.fieldDrawRadius && mob[i].speed > 6) {
|
||||||
|
// const force = Vector.mult(Vector.perp(Vector.normalise(sub)), 0.00004 * mob[i].speed * mob[i].mass)
|
||||||
|
// mob[i].force.x = force.x
|
||||||
|
// mob[i].force.y = force.y
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
//look for nearby objects to make zero-g
|
||||||
|
function zeroG(who, range, mag = 1.06) {
|
||||||
|
for (let i = 0, len = who.length; i < len; ++i) {
|
||||||
|
sub = Vector.sub(who[i].position, mech.pos);
|
||||||
|
dist = Vector.magnitude(sub);
|
||||||
|
if (dist < range) {
|
||||||
|
who[i].force.y -= who[i].mass * (game.g * mag); //add a bit more then standard gravity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// zeroG(bullet); //works fine, but not that noticeable and maybe not worth the possible performance hit
|
||||||
|
// zeroG(mob); //mobs are too irregular to make this work?
|
||||||
|
|
||||||
|
if (keys[83] || keys[40]) { //down
|
||||||
|
player.force.y -= 0.5 * player.mass * mech.gravity;
|
||||||
|
this.fieldDrawRadius = this.fieldDrawRadius * 0.97 + 400 * 0.03;
|
||||||
|
zeroG(powerUp, this.fieldDrawRadius, 0.7);
|
||||||
|
zeroG(body, this.fieldDrawRadius, 0.7);
|
||||||
|
} else if (keys[87] || keys[38]) { //up
|
||||||
|
mech.energy -= 5 * DRAIN;
|
||||||
|
this.fieldDrawRadius = this.fieldDrawRadius * 0.97 + 850 * 0.03;
|
||||||
|
player.force.y -= 1.45 * player.mass * mech.gravity;
|
||||||
|
zeroG(powerUp, this.fieldDrawRadius, 1.38);
|
||||||
|
zeroG(body, this.fieldDrawRadius, 1.38);
|
||||||
|
} else {
|
||||||
|
mech.energy -= DRAIN;
|
||||||
|
this.fieldDrawRadius = this.fieldDrawRadius * 0.97 + 650 * 0.03;
|
||||||
|
player.force.y -= 1.07 * player.mass * mech.gravity; // slow upward drift
|
||||||
|
zeroG(powerUp, this.fieldDrawRadius);
|
||||||
|
zeroG(body, this.fieldDrawRadius);
|
||||||
|
}
|
||||||
|
if (mech.energy < 0.001) {
|
||||||
|
mech.fieldCDcycle = mech.cycle + 120;
|
||||||
|
mech.energy = 0;
|
||||||
|
}
|
||||||
|
//add extra friction for horizontal motion
|
||||||
|
if (keys[65] || keys[68] || keys[37] || keys[39]) {
|
||||||
|
Matter.Body.setVelocity(player, {
|
||||||
|
x: player.velocity.x * 0.99,
|
||||||
|
y: player.velocity.y * 0.97
|
||||||
|
});
|
||||||
|
} else { //slow rise and fall
|
||||||
|
Matter.Body.setVelocity(player, {
|
||||||
|
x: player.velocity.x,
|
||||||
|
y: player.velocity.y * 0.97
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//draw zero-G range
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(mech.pos.x, mech.pos.y, this.fieldDrawRadius, 0, 2 * Math.PI);
|
||||||
|
ctx.fillStyle = "#f5f5ff";
|
||||||
|
ctx.globalCompositeOperation = "difference";
|
||||||
|
ctx.fill();
|
||||||
|
if (b.isModHawking) {
|
||||||
|
for (let i = 0, len = mob.length; i < len; i++) {
|
||||||
|
if (mob[i].distanceToPlayer2() < this.fieldDrawRadius * this.fieldDrawRadius && Matter.Query.ray(map, mech.pos, mob[i].position).length === 0 && Matter.Query.ray(body, mech.pos, mob[i].position).length === 0) {
|
||||||
|
mob[i].damage(b.dmgScale * 0.085);
|
||||||
|
mob[i].locatePlayer();
|
||||||
|
|
||||||
|
//draw electricity
|
||||||
|
const sub = Vector.sub(mob[i].position, mech.pos)
|
||||||
|
const unit = Vector.normalise(sub);
|
||||||
|
const steps = 6
|
||||||
|
const step = Vector.magnitude(sub) / steps;
|
||||||
|
ctx.beginPath();
|
||||||
|
let x = mech.pos.x + 30 * unit.x;
|
||||||
|
let y = mech.pos.y + 30 * unit.y;
|
||||||
|
ctx.moveTo(x, y);
|
||||||
|
for (let i = 0; i < steps; i++) {
|
||||||
|
x += step * (unit.x + 0.7 * (Math.random() - 0.5))
|
||||||
|
y += step * (unit.y + 0.7 * (Math.random() - 0.5))
|
||||||
|
ctx.lineTo(x, y);
|
||||||
|
}
|
||||||
|
ctx.lineWidth = 1;
|
||||||
|
ctx.strokeStyle = "rgba(0,255,0,0.5)" //"#fff";
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.globalCompositeOperation = "source-over";
|
||||||
|
}
|
||||||
|
} else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding, but field button is released
|
||||||
|
mech.pickUp();
|
||||||
|
this.fieldDrawRadius = 0
|
||||||
|
} else {
|
||||||
|
mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
|
||||||
|
this.fieldDrawRadius = 0
|
||||||
|
}
|
||||||
|
mech.drawFieldMeter("rgba(0,0,0,0.2)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "plasma torch",
|
name: "plasma torch",
|
||||||
description: "use <strong class='color-f'>energy</strong> to emit <strong class='color-d'>damaging</strong> plasma<br><em>effective at close range</em>",
|
description: "use <strong class='color-f'>energy</strong> to emit <strong class='color-d'>damaging</strong> plasma<br><em>effective at close range</em>",
|
||||||
@@ -1578,228 +1713,93 @@ const mech = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "negative mass field",
|
name: "time dilation field",
|
||||||
description: "use <strong class='color-f'>energy</strong> to nullify <strong style='letter-spacing: 12px;'>gravity</strong><br>reduce <strong>harm</strong> by <strong>80%</strong> while field is active", //<br><strong>launch</strong> larger blocks at much higher speeds
|
description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 1px;'>stop time</strong><br><em>you can move and fire while time is stopped</em>",
|
||||||
fieldDrawRadius: 0,
|
|
||||||
isEasyToAim: true,
|
isEasyToAim: true,
|
||||||
effect: () => {
|
effect: () => {
|
||||||
|
// mech.fieldMeterColor = "#000"
|
||||||
mech.fieldFire = true;
|
mech.fieldFire = true;
|
||||||
mech.holdingMassScale = 0.03; //can hold heavier blocks with lower cost to jumping
|
mech.isBodiesAsleep = false;
|
||||||
mech.fieldMeterColor = "#000"
|
|
||||||
|
|
||||||
mech.hold = function () {
|
mech.hold = function () {
|
||||||
mech.fieldDamageResistance = 1;
|
|
||||||
if (mech.isHolding) {
|
if (mech.isHolding) {
|
||||||
|
mech.wakeCheck();
|
||||||
mech.drawHold(mech.holdingTarget);
|
mech.drawHold(mech.holdingTarget);
|
||||||
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) {
|
||||||
mech.grabPowerUp();
|
mech.grabPowerUp();
|
||||||
mech.lookForPickUp();
|
mech.lookForPickUp(180);
|
||||||
const DRAIN = 0.00035
|
|
||||||
|
const DRAIN = 0.0017
|
||||||
if (mech.energy > DRAIN) {
|
if (mech.energy > DRAIN) {
|
||||||
mech.fieldDamageResistance = 0.2; // 1 - 0.8
|
mech.energy -= DRAIN;
|
||||||
// mech.pushMobs360();
|
if (mech.energy < DRAIN) {
|
||||||
|
|
||||||
//repulse mobs
|
|
||||||
// for (let i = 0, len = mob.length; i < len; ++i) {
|
|
||||||
// sub = Vector.sub(mob[i].position, mech.pos);
|
|
||||||
// dist2 = Vector.magnitudeSquared(sub);
|
|
||||||
// if (dist2 < this.fieldDrawRadius * this.fieldDrawRadius && mob[i].speed > 6) {
|
|
||||||
// const force = Vector.mult(Vector.perp(Vector.normalise(sub)), 0.00004 * mob[i].speed * mob[i].mass)
|
|
||||||
// mob[i].force.x = force.x
|
|
||||||
// mob[i].force.y = force.y
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
//look for nearby objects to make zero-g
|
|
||||||
function zeroG(who, range, mag = 1.06) {
|
|
||||||
for (let i = 0, len = who.length; i < len; ++i) {
|
|
||||||
sub = Vector.sub(who[i].position, mech.pos);
|
|
||||||
dist = Vector.magnitude(sub);
|
|
||||||
if (dist < range) {
|
|
||||||
who[i].force.y -= who[i].mass * (game.g * mag); //add a bit more then standard gravity
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// zeroG(bullet); //works fine, but not that noticeable and maybe not worth the possible performance hit
|
|
||||||
// zeroG(mob); //mobs are too irregular to make this work?
|
|
||||||
|
|
||||||
if (keys[83] || keys[40]) { //down
|
|
||||||
player.force.y -= 0.5 * player.mass * mech.gravity;
|
|
||||||
this.fieldDrawRadius = this.fieldDrawRadius * 0.97 + 400 * 0.03;
|
|
||||||
zeroG(powerUp, this.fieldDrawRadius, 0.7);
|
|
||||||
zeroG(body, this.fieldDrawRadius, 0.7);
|
|
||||||
} else if (keys[87] || keys[38]) { //up
|
|
||||||
mech.energy -= 5 * DRAIN;
|
|
||||||
this.fieldDrawRadius = this.fieldDrawRadius * 0.97 + 850 * 0.03;
|
|
||||||
player.force.y -= 1.45 * player.mass * mech.gravity;
|
|
||||||
zeroG(powerUp, this.fieldDrawRadius, 1.38);
|
|
||||||
zeroG(body, this.fieldDrawRadius, 1.38);
|
|
||||||
} else {
|
|
||||||
mech.energy -= DRAIN;
|
|
||||||
this.fieldDrawRadius = this.fieldDrawRadius * 0.97 + 650 * 0.03;
|
|
||||||
player.force.y -= 1.07 * player.mass * mech.gravity; // slow upward drift
|
|
||||||
zeroG(powerUp, this.fieldDrawRadius);
|
|
||||||
zeroG(body, this.fieldDrawRadius);
|
|
||||||
}
|
|
||||||
if (mech.energy < 0.001) {
|
|
||||||
mech.fieldCDcycle = mech.cycle + 120;
|
mech.fieldCDcycle = mech.cycle + 120;
|
||||||
mech.energy = 0;
|
mech.energy = 0;
|
||||||
|
mech.wakeCheck();
|
||||||
}
|
}
|
||||||
//add extra friction for horizontal motion
|
//draw field everywhere
|
||||||
if (keys[65] || keys[68] || keys[37] || keys[39]) {
|
ctx.globalCompositeOperation = "saturation"
|
||||||
Matter.Body.setVelocity(player, {
|
// ctx.fillStyle = "rgba(100,200,230," + (0.25 + 0.06 * Math.random()) + ")";
|
||||||
x: player.velocity.x * 0.99,
|
ctx.fillStyle = "#ccc";
|
||||||
y: player.velocity.y * 0.97
|
ctx.fillRect(-100000, -100000, 200000, 200000)
|
||||||
});
|
ctx.globalCompositeOperation = "source-over"
|
||||||
} else { //slow rise and fall
|
//stop time
|
||||||
Matter.Body.setVelocity(player, {
|
mech.isBodiesAsleep = true;
|
||||||
x: player.velocity.x,
|
|
||||||
y: player.velocity.y * 0.97
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//draw zero-G range
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(mech.pos.x, mech.pos.y, this.fieldDrawRadius, 0, 2 * Math.PI);
|
|
||||||
ctx.fillStyle = "#f5f5ff";
|
|
||||||
ctx.globalCompositeOperation = "difference";
|
|
||||||
ctx.fill();
|
|
||||||
if (b.isModHawking) {
|
|
||||||
for (let i = 0, len = mob.length; i < len; i++) {
|
|
||||||
if (mob[i].distanceToPlayer2() < this.fieldDrawRadius * this.fieldDrawRadius && Matter.Query.ray(map, mech.pos, mob[i].position).length === 0 && Matter.Query.ray(body, mech.pos, mob[i].position).length === 0) {
|
|
||||||
mob[i].damage(b.dmgScale * 0.085);
|
|
||||||
mob[i].locatePlayer();
|
|
||||||
|
|
||||||
//draw electricity
|
|
||||||
const sub = Vector.sub(mob[i].position, mech.pos)
|
|
||||||
const unit = Vector.normalise(sub);
|
|
||||||
const steps = 6
|
|
||||||
const step = Vector.magnitude(sub) / steps;
|
|
||||||
ctx.beginPath();
|
|
||||||
let x = mech.pos.x + 30 * unit.x;
|
|
||||||
let y = mech.pos.y + 30 * unit.y;
|
|
||||||
ctx.moveTo(x, y);
|
|
||||||
for (let i = 0; i < steps; i++) {
|
|
||||||
x += step * (unit.x + 0.7 * (Math.random() - 0.5))
|
|
||||||
y += step * (unit.y + 0.7 * (Math.random() - 0.5))
|
|
||||||
ctx.lineTo(x, y);
|
|
||||||
}
|
|
||||||
ctx.lineWidth = 1;
|
|
||||||
ctx.strokeStyle = "rgba(0,255,0,0.5)" //"#fff";
|
|
||||||
ctx.stroke();
|
|
||||||
|
|
||||||
|
function sleep(who) {
|
||||||
|
for (let i = 0, len = who.length; i < len; ++i) {
|
||||||
|
if (!who[i].isSleeping) {
|
||||||
|
who[i].storeVelocity = who[i].velocity
|
||||||
|
who[i].storeAngularVelocity = who[i].angularVelocity
|
||||||
}
|
}
|
||||||
|
Matter.Sleeping.set(who[i], true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.globalCompositeOperation = "source-over";
|
sleep(mob);
|
||||||
}
|
sleep(body);
|
||||||
} else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding, but field button is released
|
sleep(bullet);
|
||||||
mech.pickUp();
|
//doesn't really work, just slows down constraints
|
||||||
this.fieldDrawRadius = 0
|
for (let i = 0, len = cons.length; i < len; i++) {
|
||||||
} else {
|
if (cons[i].stiffness !== 0) {
|
||||||
mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
|
cons[i].storeStiffness = cons[i].stiffness;
|
||||||
this.fieldDrawRadius = 0
|
cons[i].stiffness = 0;
|
||||||
}
|
}
|
||||||
mech.drawFieldMeter("rgba(0,0,0,0.2)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "standing wave harmonics",
|
|
||||||
description: "three oscillating <strong>shields</strong> are permanently active<br><strong class='color-f'>energy</strong> regenerates while field is active",
|
|
||||||
isEasyToAim: true,
|
|
||||||
effect: () => {
|
|
||||||
mech.hold = function () {
|
|
||||||
if (mech.isHolding) {
|
|
||||||
mech.drawHold(mech.holdingTarget);
|
|
||||||
mech.holding();
|
|
||||||
mech.throwBlock();
|
|
||||||
} else if ((keys[32] || game.mouseDownRight) && mech.fieldCDcycle < mech.cycle) { //not hold but field button is pressed
|
|
||||||
mech.grabPowerUp();
|
|
||||||
mech.lookForPickUp();
|
|
||||||
} else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding, but field button is released
|
|
||||||
mech.pickUp();
|
|
||||||
} else {
|
|
||||||
mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
|
|
||||||
}
|
|
||||||
if (mech.energy > 0.1 && mech.fieldCDcycle < mech.cycle) {
|
|
||||||
const fieldRange1 = (0.55 + 0.35 * Math.sin(mech.cycle / 23)) * mech.fieldRange
|
|
||||||
const fieldRange2 = (0.5 + 0.4 * Math.sin(mech.cycle / 37)) * mech.fieldRange
|
|
||||||
const fieldRange3 = (0.45 + 0.45 * Math.sin(mech.cycle / 47)) * mech.fieldRange
|
|
||||||
const netfieldRange = Math.max(fieldRange1, fieldRange2, fieldRange3)
|
|
||||||
ctx.fillStyle = "rgba(110,170,200," + (0.04 + mech.energy * (0.12 + 0.13 * Math.random())) + ")";
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(mech.pos.x, mech.pos.y, fieldRange1, 0, 2 * Math.PI);
|
|
||||||
ctx.fill();
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(mech.pos.x, mech.pos.y, fieldRange2, 0, 2 * Math.PI);
|
|
||||||
ctx.fill();
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(mech.pos.x, mech.pos.y, fieldRange3, 0, 2 * Math.PI);
|
|
||||||
ctx.fill();
|
|
||||||
mech.pushMobs360(netfieldRange);
|
|
||||||
// mech.pushBody360(netfieldRange); //can't throw block when pushhing blocks away
|
|
||||||
}
|
|
||||||
mech.drawFieldMeter()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "nano-scale manufacturing",
|
|
||||||
description: "excess <strong class='color-f'>energy</strong> used to build <strong>drones</strong><br><strong>2x</strong> <strong class='color-f'>energy</strong> regeneration",
|
|
||||||
isEasyToAim: true,
|
|
||||||
effect: () => {
|
|
||||||
// mech.fieldRegen *= 2;
|
|
||||||
mech.hold = function () {
|
|
||||||
if (mech.energy > mech.fieldEnergyMax - 0.02 && mech.fieldCDcycle < mech.cycle) {
|
|
||||||
if (b.isModSporeField) {
|
|
||||||
// mech.fieldCDcycle = mech.cycle + 10; // set cool down to prevent +energy from making huge numbers of drones
|
|
||||||
const len = Math.floor(6 + 4 * Math.random())
|
|
||||||
mech.energy -= len * 0.074;
|
|
||||||
for (let i = 0; i < len; i++) {
|
|
||||||
b.spore(player)
|
|
||||||
}
|
}
|
||||||
} else if (b.isModMissileField) {
|
|
||||||
// mech.fieldCDcycle = mech.cycle + 10; // set cool down to prevent +energy from making huge numbers of drones
|
|
||||||
mech.energy -= 0.5;
|
|
||||||
b.missile({
|
|
||||||
x: mech.pos.x + 40 * Math.cos(mech.angle),
|
|
||||||
y: mech.pos.y + 40 * Math.sin(mech.angle) - 3
|
|
||||||
},
|
|
||||||
mech.angle + (0.5 - Math.random()) * (mech.crouch ? 0 : 0.2),
|
|
||||||
-3 * (0.5 - Math.random()) + (mech.crouch ? 25 : -8) * b.modFireRate,
|
|
||||||
1, b.modBabyMissiles)
|
|
||||||
} else if (b.isModIceField) {
|
|
||||||
// mech.fieldCDcycle = mech.cycle + 17; // set cool down to prevent +energy from making huge numbers of drones
|
|
||||||
mech.energy -= 0.061;
|
|
||||||
b.iceIX(1)
|
|
||||||
} else {
|
|
||||||
// mech.fieldCDcycle = mech.cycle + 10; // set cool down to prevent +energy from making huge numbers of drones
|
|
||||||
mech.energy -= 0.33;
|
|
||||||
b.drone(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
game.cycle--; //pause all functions that depend on game cycle increasing
|
||||||
if (mech.isHolding) {
|
if (b.isModTimeSkip) {
|
||||||
mech.drawHold(mech.holdingTarget);
|
game.isTimeSkipping = true;
|
||||||
mech.holding();
|
mech.cycle++;
|
||||||
mech.throwBlock();
|
game.gravity();
|
||||||
} else if ((keys[32] || game.mouseDownRight && mech.fieldCDcycle < mech.cycle)) { //not hold but field button is pressed
|
Engine.update(engine, game.delta);
|
||||||
mech.grabPowerUp();
|
// level.checkZones();
|
||||||
mech.lookForPickUp();
|
// level.checkQuery();
|
||||||
if (mech.energy > 0.05) {
|
mech.move();
|
||||||
mech.drawField();
|
game.checks();
|
||||||
mech.pushMobsFacing();
|
// mobs.loop();
|
||||||
|
// mech.draw();
|
||||||
|
mech.walk_cycle += mech.flipLegs * mech.Vx;
|
||||||
|
// mech.hold();
|
||||||
|
mech.energy += 0.5 * DRAIN; //x1 to undo the energy drain from time speed up, x1.5 to cut energy drain in half
|
||||||
|
b.fire();
|
||||||
|
// b.bulletRemove();
|
||||||
|
b.bulletDo();
|
||||||
|
game.isTimeSkipping = false;
|
||||||
|
}
|
||||||
|
// game.cycle--; //pause all functions that depend on game cycle increasing
|
||||||
|
// if (b.isModTimeSkip && !game.isTimeSkipping) { //speed up the rate of time
|
||||||
|
// game.timeSkip(1)
|
||||||
|
// mech.energy += 1.5 * DRAIN; //x1 to undo the energy drain from time speed up, x1.5 to cut energy drain in half
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
} else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding, but field button is released
|
} else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding, but field button is released
|
||||||
|
mech.wakeCheck();
|
||||||
mech.pickUp();
|
mech.pickUp();
|
||||||
} else {
|
} else {
|
||||||
|
mech.wakeCheck();
|
||||||
mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
|
mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
|
||||||
}
|
}
|
||||||
mech.energy += mech.fieldRegen;
|
|
||||||
mech.drawFieldMeter()
|
mech.drawFieldMeter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2009,6 +2009,7 @@ const mech = {
|
|||||||
if (mech.energy > DRAIN) {
|
if (mech.energy > DRAIN) {
|
||||||
mech.energy -= DRAIN;
|
mech.energy -= DRAIN;
|
||||||
Matter.Body.setVelocity(body[i], velocity); //give block mouse velocity
|
Matter.Body.setVelocity(body[i], velocity); //give block mouse velocity
|
||||||
|
Matter.Body.setAngularVelocity(body[i], body[i].angularVelocity * 0.8)
|
||||||
body[i].force.y -= body[i].mass * game.g; //remove gravity effects
|
body[i].force.y -= body[i].mass * game.g; //remove gravity effects
|
||||||
} else {
|
} else {
|
||||||
mech.fieldOn = false
|
mech.fieldOn = false
|
||||||
|
|||||||
18
js/spawn.js
18
js/spawn.js
@@ -942,7 +942,8 @@ const spawn = {
|
|||||||
me.g = 0.0002; //required if using 'gravity'
|
me.g = 0.0002; //required if using 'gravity'
|
||||||
me.frictionStatic = 0;
|
me.frictionStatic = 0;
|
||||||
me.friction = 0;
|
me.friction = 0;
|
||||||
me.delay = 100;
|
me.delay = 120 * game.CDScale;
|
||||||
|
me.cd = Infinity;
|
||||||
Matter.Body.rotate(me, Math.PI * 0.1);
|
Matter.Body.rotate(me, Math.PI * 0.1);
|
||||||
spawn.shield(me, x, y);
|
spawn.shield(me, x, y);
|
||||||
me.onDamage = function () {
|
me.onDamage = function () {
|
||||||
@@ -950,7 +951,20 @@ const spawn = {
|
|||||||
};
|
};
|
||||||
me.do = function () {
|
me.do = function () {
|
||||||
this.gravity();
|
this.gravity();
|
||||||
this.seePlayerCheck();
|
if (!(game.cycle % this.seePlayerFreq)) { // this.seePlayerCheck(); from mobs
|
||||||
|
if (
|
||||||
|
this.distanceToPlayer2() < this.seeAtDistance2 &&
|
||||||
|
Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 &&
|
||||||
|
Matter.Query.ray(body, this.position, this.mechPosRange()).length === 0 &&
|
||||||
|
!mech.isStealth
|
||||||
|
) {
|
||||||
|
this.foundPlayer();
|
||||||
|
if (this.cd === Infinity) this.cd = game.cycle + this.delay;
|
||||||
|
} else if (this.seePlayer.recall) {
|
||||||
|
this.lostPlayer();
|
||||||
|
this.cd = Infinity
|
||||||
|
}
|
||||||
|
}
|
||||||
this.checkStatus();
|
this.checkStatus();
|
||||||
this.attraction();
|
this.attraction();
|
||||||
this.strike();
|
this.strike();
|
||||||
|
|||||||
27
todo.txt
27
todo.txt
@@ -3,26 +3,19 @@
|
|||||||
|
|
||||||
************** TODO - n-gon **************
|
************** TODO - n-gon **************
|
||||||
|
|
||||||
|
an effect when canceling a power up
|
||||||
|
ammo? heals?
|
||||||
|
50% chance for a mod, 25% heal, 25% ammo
|
||||||
|
|
||||||
|
liquid nitrogen cooling
|
||||||
|
Mobs freeze on contact with the player
|
||||||
|
|
||||||
|
uranium reactor core
|
||||||
|
Mobs get irradiated on contact with the player
|
||||||
|
|
||||||
add player Scent Trails for mod navigation
|
add player Scent Trails for mod navigation
|
||||||
https://abitawake.com/news/articles/enemy-ai-chasing-a-player-without-navigation2d-or-a-star-pathfinding
|
https://abitawake.com/news/articles/enemy-ai-chasing-a-player-without-navigation2d-or-a-star-pathfinding
|
||||||
|
|
||||||
mod - energy replaces your health,
|
|
||||||
|
|
||||||
field - pilot wave
|
|
||||||
while mouse is down blocks (and mobs?) are move with the mouse
|
|
||||||
players can do serious damage by flicking the mouse and firing blocks
|
|
||||||
on mouse down calculate relative position of block to mouse and maintain that as mouse moves
|
|
||||||
on mouse up give blocks the computed mouse velocity
|
|
||||||
use a gravity effect that pulls blocks in range towards the center of the mouse
|
|
||||||
maybe no force in the very center to prevent clumping
|
|
||||||
draw a ellipse around the mouse that wobbles like phase decoherence field, and changes color maybe like negative mass field
|
|
||||||
|
|
||||||
make flurooantimonic acid mod a damage over time
|
|
||||||
rename to radiation damage?
|
|
||||||
|
|
||||||
mod - radiation damage over time effects can spread to nearby mobs
|
|
||||||
do a check for nearby mobs on each tick
|
|
||||||
|
|
||||||
try adding a subtile shift of color towards red, green or blue
|
try adding a subtile shift of color towards red, green or blue
|
||||||
block, map, background, text? color
|
block, map, background, text? color
|
||||||
could be random as each level loads
|
could be random as each level loads
|
||||||
|
|||||||
Reference in New Issue
Block a user