rail gun mod

rail gun mod: capacitor bank - no charge time, but smaller bullets

stunned mobs now still display health bar
when you hit a mob hard with a block they get stunned
  blocks do about 15% less collision damage
  stuns lasts longer for larger and faster blocks
This commit is contained in:
landgreen
2020-09-01 18:45:45 -07:00
parent ce96cd37ef
commit b9aaa4423b
7 changed files with 352 additions and 196 deletions

View File

@@ -1562,7 +1562,7 @@ const b = {
} }
mech.fireCDcycle = mech.cycle + Math.floor(CD * b.fireCD); // cool down mech.fireCDcycle = mech.cycle + Math.floor(CD * b.fireCD); // cool down
const speed = 28 + 7 * Math.random() + 9 * mod.nailInstantFireRate const speed = 30 + 6 * Math.random() + 9 * mod.nailInstantFireRate
const angle = mech.angle + (Math.random() - 0.5) * (Math.random() - 0.5) * (mech.crouch ? 1.35 : 3.2) / CD const angle = mech.angle + (Math.random() - 0.5) * (Math.random() - 0.5) * (mech.crouch ? 1.35 : 3.2) / CD
const dmg = 0.9 const dmg = 0.9
b.nail({ b.nail({
@@ -1769,13 +1769,11 @@ const b = {
if (!immune) { if (!immune) {
this.immuneList.push(who.id) this.immuneList.push(who.id)
who.foundPlayer(); who.foundPlayer();
if (mod.isFastDot) { if (mod.isFastDot) {
mobs.statusDoT(who, 3.9, 30) mobs.statusDoT(who, 3.9, 30)
} else { } else {
mobs.statusDoT(who, 0.65, mod.isSlowDot ? 360 : 180) mobs.statusDoT(who, 0.65, mod.isSlowDot ? 360 : 180)
} }
game.drawList.push({ //add dmg to draw queue game.drawList.push({ //add dmg to draw queue
x: this.position.x, x: this.position.x,
y: this.position.y, y: this.position.y,
@@ -1813,7 +1811,6 @@ const b = {
this.force.y += this.mass * 0.0007; //no gravity until it slows down to improve aiming this.force.y += this.mass * 0.0007; //no gravity until it slows down to improve aiming
} }
}; };
const SPEED = 50 const SPEED = 50
Matter.Body.setVelocity(bullet[me], { Matter.Body.setVelocity(bullet[me], {
x: mech.Vx / 2 + SPEED * Math.cos(angle), x: mech.Vx / 2 + SPEED * Math.cos(angle),
@@ -2603,12 +2600,124 @@ const b = {
name: "rail gun", name: "rail gun",
description: "use <strong class='color-f'>energy</strong> to launch a high-speed <strong>dense</strong> rod<br><strong>hold</strong> left mouse to charge, <strong>release</strong> to fire", description: "use <strong class='color-f'>energy</strong> to launch a high-speed <strong>dense</strong> rod<br><strong>hold</strong> left mouse to charge, <strong>release</strong> to fire",
ammo: 0, ammo: 0,
ammoPack: 2.6, ammoPack: 3,
have: false, have: false,
fire() { fire() {
if (mod.isCapacitor) {
if (mech.energy > 0.15) {
mech.energy -= 0.15
mech.fireCDcycle = mech.cycle + Math.floor(30 * b.fireCD);
const me = bullet.length;
bullet[me] = Bodies.rectangle(mech.pos.x + 50 * Math.cos(mech.angle), mech.pos.y + 50 * Math.sin(mech.angle), 60, 14, {
density: 0.005, //0.001 is normal
restitution: 0,
frictionAir: 0,
angle: mech.angle,
dmg: 0, //damage done in addition to the damage from momentum
classType: "bullet",
collisionFilter: {
category: cat.bullet,
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
},
minDmgSpeed: 5,
endCycle: game.cycle + 140,
onDmg(who) {
if (who.shield) {
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
Matter.Body.setVelocity(mob[i], Vector.mult(Vector.normalise(this.velocity), 10));
break
}
}
Matter.Body.setVelocity(this, {
x: -0.1 * this.velocity.x,
y: -0.1 * this.velocity.y
});
Matter.Body.setDensity(this, 0.001);
}
if (mod.isRailNails && this.speed > 10) {
b.targetedNail(this.position, (Math.min(40, this.speed) - 10) * 0.6) // 0.6 as many nails as the normal rail gun
this.endCycle = 0 //triggers despawn
}
},
onEnd() {},
drawCycle: Math.floor(10 * b.fireCD),
do() {
this.force.y += this.mass * 0.0003; // low gravity that scales with charge
if (this.drawCycle > 0) {
this.drawCycle--
//draw magnetic field
const X = mech.pos.x
const Y = mech.pos.y
const unitVector = Vector.normalise(Vector.sub(game.mouseInGame, mech.pos))
const unitVectorPerp = Vector.perp(unitVector)
function magField(mag, arc) {
ctx.moveTo(X, Y);
ctx.bezierCurveTo(
X + unitVector.x * mag, Y + unitVector.y * mag,
X + unitVector.x * mag + unitVectorPerp.x * arc, Y + unitVector.y * mag + unitVectorPerp.y * arc,
X + unitVectorPerp.x * arc, Y + unitVectorPerp.y * arc)
ctx.bezierCurveTo(
X - unitVector.x * mag + unitVectorPerp.x * arc, Y - unitVector.y * mag + unitVectorPerp.y * arc,
X - unitVector.x * mag, Y - unitVector.y * mag,
X, Y)
}
ctx.fillStyle = `rgba(50,0,100,0.05)`;
for (let i = 3; i < 7; i++) {
const MAG = 8 * i * i * (0.93 + 0.07 * Math.random()) * (0.95 + 0.1 * Math.random())
const ARC = 6 * i * i * (0.93 + 0.07 * Math.random()) * (0.95 + 0.1 * Math.random())
ctx.beginPath();
magField(MAG, ARC)
magField(MAG, -ARC)
ctx.fill();
}
}
}
});
World.add(engine.world, bullet[me]); //add bullet to world
const speed = 67
Matter.Body.setVelocity(bullet[me], {
x: mech.Vx / 2 + speed * Math.cos(mech.angle),
y: mech.Vy / 2 + speed * Math.sin(mech.angle)
});
//knock back
const KNOCK = mech.crouch ? 0.08 : 0.34
player.force.x -= KNOCK * Math.cos(mech.angle)
player.force.y -= KNOCK * Math.sin(mech.angle) * 0.35 //reduce knock back in vertical direction to stop super jumps
//push away blocks when firing
let range = 450
for (let i = 0, len = body.length; i < len; ++i) {
const SUB = Vector.sub(body[i].position, mech.pos)
const DISTANCE = Vector.magnitude(SUB)
if (DISTANCE < range) {
const DEPTH = Math.min(range - DISTANCE, 300)
const FORCE = Vector.mult(Vector.normalise(SUB), 0.003 * Math.sqrt(DEPTH) * body[i].mass)
body[i].force.x += FORCE.x;
body[i].force.y += FORCE.y - body[i].mass * (game.g * 1.5); //kick up a bit to give them some arc
}
}
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 = Math.min(range - DISTANCE, 300)
const FORCE = Vector.mult(Vector.normalise(SUB), 0.003 * Math.sqrt(DEPTH) * mob[i].mass)
mob[i].force.x += 1.5 * FORCE.x;
mob[i].force.y += 1.5 * FORCE.y;
}
}
} else {
mech.fireCDcycle = mech.cycle + Math.floor(120);
}
} else {
const me = bullet.length; const me = bullet.length;
bullet[me] = Bodies.rectangle(0, 0, 0.015, 0.0015, { bullet[me] = Bodies.rectangle(0, 0, 0.015, 0.0015, {
density: 0.01, //0.001 is normal density: 0.008, //0.001 is normal
//frictionAir: 0.01, //restitution: 0, //frictionAir: 0.01, //restitution: 0,
// angle: 0, // angle: 0,
// friction: 0.5, // friction: 0.5,
@@ -2685,7 +2794,7 @@ const b = {
player.force.y -= KNOCK * Math.sin(mech.angle) * 0.35 //reduce knock back in vertical direction to stop super jumps player.force.y -= KNOCK * Math.sin(mech.angle) * 0.35 //reduce knock back in vertical direction to stop super jumps
//push away blocks when firing //push away blocks when firing
let range = 700 * this.charge let range = 900 * this.charge
for (let i = 0, len = body.length; i < len; ++i) { for (let i = 0, len = body.length; i < len; ++i) {
const SUB = Vector.sub(body[i].position, mech.pos) const SUB = Vector.sub(body[i].position, mech.pos)
const DISTANCE = Vector.magnitude(SUB) const DISTANCE = Vector.magnitude(SUB)
@@ -2833,6 +2942,7 @@ const b = {
} }
} }
} }
}
}, },
{ {
name: "laser", name: "laser",

View File

@@ -220,9 +220,11 @@ function collisionChecks(event) {
if (obj.classType === "body" && obj.speed > 6) { if (obj.classType === "body" && obj.speed > 6) {
const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)); const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity));
if (v > 9) { if (v > 9) {
let dmg = 0.06 * b.dmgScale * v * obj.mass * mod.throwChargeRate; let dmg = 0.05 * b.dmgScale * v * obj.mass * mod.throwChargeRate;
if (mob[k].isShielded) dmg *= 0.35 if (mob[k].isShielded) dmg *= 0.35
mob[k].damage(dmg, true); mob[k].damage(dmg, true);
const stunTime = dmg / Math.sqrt(obj.mass)
if (stunTime > 0.5) mobs.statusStun(mob[k], 30 + 60 * Math.sqrt(stunTime))
if (mob[k].distanceToPlayer2() < 1000000) mob[k].foundPlayer(); if (mob[k].distanceToPlayer2() < 1000000) mob[k].foundPlayer();
game.drawList.push({ game.drawList.push({
x: pairs[i].activeContacts[0].vertex.x, x: pairs[i].activeContacts[0].vertex.x,

View File

@@ -16,9 +16,9 @@ const level = {
// game.zoomScale = 1000; // game.zoomScale = 1000;
// game.setZoom(); // game.setZoom();
// mech.isStealth = true; // mech.isStealth = true;
// b.giveGuns("nail gun")
// mech.setField("standing wave harmonics") // mech.setField("standing wave harmonics")
// mod.giveMod("pneumatic actuator"); // b.giveGuns("rail gun")
// mod.giveMod("capacitor bank");
level.intro(); //starting level level.intro(); //starting level
// level.testing(); //not in rotation // level.testing(); //not in rotation
@@ -372,7 +372,7 @@ const level = {
spawn.mapRect(350, -3260, 50, 60); spawn.mapRect(350, -3260, 50, 60);
// spawn.bodyRect(362, -3400, 25, 140); // spawn.bodyRect(362, -3400, 25, 140);
spawn.mapRect(200, -3250, 1250, 50); spawn.mapRect(200, -3250, 1240, 50);
spawn.mapRect(1400, -3260, 50, 310); spawn.mapRect(1400, -3260, 50, 310);
spawn.bodyRect(1412, -3425, 25, 165); spawn.bodyRect(1412, -3425, 25, 165);

View File

@@ -115,6 +115,18 @@ const mobs = {
y: who.position.y + 100 * (Math.random() - 0.5) y: who.position.y + 100 * (Math.random() - 0.5)
} }
if (who.velocity.y < 2) who.force.y += who.mass * 0.0004 //extra gravity if (who.velocity.y < 2) who.force.y += who.mass * 0.0004 //extra gravity
//draw health bar
const h = who.radius * 0.3;
const w = who.radius * 2;
const x = who.position.x - w / 2;
const y = who.position.y - w * 0.7;
ctx.fillStyle = "rgba(100, 100, 100, 0.3)";
ctx.fillRect(x, y, w, h);
ctx.fillStyle = `rgba(${Math.floor(255*Math.random())},${Math.floor(255*Math.random())},${Math.floor(255*Math.random())},0.5)`
ctx.fillRect(x, y, w * who.health, h);
//draw fill inside mob
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(who.vertices[0].x, who.vertices[0].y); ctx.moveTo(who.vertices[0].x, who.vertices[0].y);
for (let j = 1, len = who.vertices.length; j < len; ++j) { for (let j = 1, len = who.vertices.length; j < len; ++j) {
@@ -122,9 +134,9 @@ const mobs = {
} }
ctx.lineTo(who.vertices[0].x, who.vertices[0].y); ctx.lineTo(who.vertices[0].x, who.vertices[0].y);
ctx.stroke(); ctx.stroke();
ctx.fillStyle = `rgba(${Math.floor(255*Math.random())},${Math.floor(255*Math.random())},${Math.floor(255*Math.random())},0.5)`
// ctx.fillStyle = `rgba(255,255,255,${Math.random()})`
ctx.fill(); ctx.fill();
}, },
type: "stun", type: "stun",
endCycle: game.cycle + cycles, endCycle: game.cycle + cycles,

View File

@@ -1871,7 +1871,7 @@ const mod = {
}, },
{ {
name: "railroad ties", name: "railroad ties",
description: "<strong>nails</strong> are <strong>80%</strong> <strong>larger</strong><br>increases physical <strong class='color-d'>damage</strong> by about <strong>25%</strong>", description: "<strong>nails</strong> are <strong>70%</strong> <strong>larger</strong><br>increases physical <strong class='color-d'>damage</strong> by about <strong>25%</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
@@ -1879,7 +1879,7 @@ const mod = {
}, },
requires: "nails", requires: "nails",
effect() { effect() {
mod.biggerNails += 0.8 mod.biggerNails += 0.7
}, },
remove() { remove() {
mod.biggerNails = 1 mod.biggerNails = 1
@@ -2084,7 +2084,7 @@ const mod = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
return game.fpsCapDefault > 45 && mod.haveGunCheck("rail gun") && !mod.isSlowFPS return game.fpsCapDefault > 45 && mod.haveGunCheck("rail gun") && !mod.isSlowFPS && !mod.isCapacitor
}, },
requires: "rail gun and FPS above 45", requires: "rail gun and FPS above 45",
effect() { effect() {
@@ -2096,9 +2096,25 @@ const mod = {
game.fpsInterval = 1000 / game.fpsCap; game.fpsInterval = 1000 / game.fpsCap;
} }
}, },
{
name: "capacitor bank",
description: "the <strong>rail gun</strong> no longer takes time to <strong>charge</strong><br><strong>rail gun</strong> rods are <strong>66%</strong> less massive",
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("rail gun") && !mod.isRailTimeSlow
},
requires: "rail gun",
effect() {
mod.isCapacitor = true;
},
remove() {
mod.isCapacitor = false;
}
},
{ {
name: "fragmenting projectiles", name: "fragmenting projectiles",
description: "<strong>rail gun</strong> fragments into <strong>nails</strong><br>after hitting mobs at high speeds", description: "<strong>rail gun</strong> rods fragment into <strong>nails</strong><br>after hitting mobs at high speeds",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
@@ -2700,5 +2716,6 @@ const mod = {
isSporeGrowth: null, isSporeGrowth: null,
isBayesian: null, isBayesian: null,
nailGun: null, nailGun: null,
nailInstantFireRate: null nailInstantFireRate: null,
isCapacitor: null
} }

View File

@@ -1212,9 +1212,9 @@ const mech = {
}, },
{ {
name: "standing wave harmonics", name: "standing wave harmonics",
description: "three oscillating <strong>shields</strong> are permanently active<br>reduce <strong class='color-harm'>harm</strong> by <strong>33%</strong>", description: "three oscillating <strong>shields</strong> are permanently active<br>reduce <strong class='color-harm'>harm</strong> by <strong>30%</strong>",
effect: () => { effect: () => {
mech.fieldHarmReduction = 0.67; mech.fieldHarmReduction = 0.70;
mech.fieldBlockCD = 0; mech.fieldBlockCD = 0;
mech.hold = function () { mech.hold = function () {
if (mech.isHolding) { if (mech.isHolding) {
@@ -1365,13 +1365,13 @@ const mech = {
}, },
{ {
name: "negative mass field", name: "negative mass field",
description: "use <strong class='color-f'>energy</strong> to nullify &nbsp; <strong style='letter-spacing: 12px;'>gravity</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>50%</strong>", description: "use <strong class='color-f'>energy</strong> to nullify &nbsp; <strong style='letter-spacing: 12px;'>gravity</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>45%</strong>",
fieldDrawRadius: 0, fieldDrawRadius: 0,
effect: () => { effect: () => {
mech.fieldFire = true; mech.fieldFire = true;
mech.holdingMassScale = 0.03; //can hold heavier blocks with lower cost to jumping mech.holdingMassScale = 0.03; //can hold heavier blocks with lower cost to jumping
mech.fieldMeterColor = "#000" mech.fieldMeterColor = "#000"
mech.fieldHarmReduction = 0.5; mech.fieldHarmReduction = 0.55;
mech.hold = function () { mech.hold = function () {
mech.airSpeedLimit = 125 //5 * player.mass * player.mass mech.airSpeedLimit = 125 //5 * player.mass * player.mass
mech.FxAir = 0.016 mech.FxAir = 0.016

View File

@@ -1,7 +1,22 @@
rail gun mod: capacitor bank - no charge time, but smaller bullets
stunned mobs now still display health bar
when you hit a mob hard with a block they get stunned
blocks do about 15% less collision damage
stuns lasts longer for larger and faster blocks
************** TODO - n-gon ************** ************** TODO - n-gon **************
player goes intangible while immune after getting hit?
getting stuck above a mob can immobilize player
add a minimum knock from player mob collisions?
when crouched make it harder for mobs to see player
reduce arc size of mob vision cone
reduce look range
* (mech.crouch ? 0.7 : 1)
map element - player rotates a rotor that makes a platform go up or down map element - player rotates a rotor that makes a platform go up or down
reduce damage by 80%, but lose ammo when you get hit reduce damage by 80%, but lose ammo when you get hit
@@ -15,10 +30,6 @@ removing supersaturation sets total health to 1
this cancels the health benefits from crystallized armor this cancels the health benefits from crystallized armor
produce a method that calculates max health based on mods produce a method that calculates max health based on mods
player goes intangible while immune after getting hit?
getting stuck above a mob can immobilize player
add a minimum knock from player mob collisions?
use mac automator to speed up your n-gon -> git sync use mac automator to speed up your n-gon -> git sync
considering removing the perfect diamagnetism field from the game considering removing the perfect diamagnetism field from the game
@@ -216,3 +227,7 @@ n-gon outreach ideas
blips - errant signal on youtube blips - errant signal on youtube
reddit - r/IndieGaming reddit - r/IndieGaming
hacker news - show hacker news post hacker news - show hacker news post
paste this into console to see fps
javascript:(function(){var script=document.createElement('script');script.onload=function(){var stats=new Stats();document.body.appendChild(stats.dom);requestAnimationFrame(function loop(){stats.update();requestAnimationFrame(loop)});};script.src='//mrdoob.github.io/stats.js/build/stats.min.js';document.head.appendChild(script);})()