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:
462
js/bullet.js
462
js/bullet.js
@@ -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,89 +2600,96 @@ 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() {
|
||||||
const me = bullet.length;
|
if (mod.isCapacitor) {
|
||||||
bullet[me] = Bodies.rectangle(0, 0, 0.015, 0.0015, {
|
if (mech.energy > 0.15) {
|
||||||
density: 0.01, //0.001 is normal
|
mech.energy -= 0.15
|
||||||
//frictionAir: 0.01, //restitution: 0,
|
mech.fireCDcycle = mech.cycle + Math.floor(30 * b.fireCD);
|
||||||
// angle: 0,
|
const me = bullet.length;
|
||||||
// friction: 0.5,
|
bullet[me] = Bodies.rectangle(mech.pos.x + 50 * Math.cos(mech.angle), mech.pos.y + 50 * Math.sin(mech.angle), 60, 14, {
|
||||||
restitution: 0,
|
density: 0.005, //0.001 is normal
|
||||||
frictionAir: 0,
|
restitution: 0,
|
||||||
dmg: 0, //damage done in addition to the damage from momentum
|
frictionAir: 0,
|
||||||
classType: "bullet",
|
angle: mech.angle,
|
||||||
collisionFilter: {
|
dmg: 0, //damage done in addition to the damage from momentum
|
||||||
category: 0,
|
classType: "bullet",
|
||||||
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
|
collisionFilter: {
|
||||||
},
|
category: cat.bullet,
|
||||||
minDmgSpeed: 5,
|
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
|
||||||
onDmg(who) {
|
},
|
||||||
if (who.shield) {
|
minDmgSpeed: 5,
|
||||||
for (let i = 0, len = mob.length; i < len; i++) {
|
endCycle: game.cycle + 140,
|
||||||
if (mob[i].id === who.shieldTargetID) { //apply some knock back to shield mob before shield breaks
|
onDmg(who) {
|
||||||
Matter.Body.setVelocity(mob[i], Vector.mult(Vector.normalise(this.velocity), 10));
|
if (who.shield) {
|
||||||
break
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Matter.Body.setVelocity(this, {
|
});
|
||||||
x: -0.1 * this.velocity.x,
|
World.add(engine.world, bullet[me]); //add bullet to world
|
||||||
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)
|
|
||||||
this.endCycle = 0 //triggers despawn
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onEnd() {}
|
|
||||||
});
|
|
||||||
mech.fireCDcycle = Infinity; // cool down
|
|
||||||
World.add(engine.world, bullet[me]); //add bullet to world
|
|
||||||
bullet[me].endCycle = Infinity
|
|
||||||
bullet[me].charge = 0;
|
|
||||||
bullet[me].do = function () {
|
|
||||||
if (mech.energy < 0.005 && !mod.isRailTimeSlow) {
|
|
||||||
mech.energy += 0.05 + this.charge * 0.3
|
|
||||||
mech.fireCDcycle = mech.cycle + 120; // cool down if out of energy
|
|
||||||
this.endCycle = 0;
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!game.mouseDown && this.charge > 0.6)) { //fire on mouse release or on low energy
|
const speed = 67
|
||||||
mech.fireCDcycle = mech.cycle + 2; // set fire cool down
|
Matter.Body.setVelocity(bullet[me], {
|
||||||
//normal bullet behavior occurs after firing, overwrites this function
|
x: mech.Vx / 2 + speed * Math.cos(mech.angle),
|
||||||
this.do = function () {
|
y: mech.Vy / 2 + speed * Math.sin(mech.angle)
|
||||||
this.force.y += this.mass * 0.0003 / this.charge; // low gravity that scales with charge
|
|
||||||
}
|
|
||||||
if (mod.isRailTimeSlow) {
|
|
||||||
game.fpsCap = game.fpsCapDefault
|
|
||||||
game.fpsInterval = 1000 / game.fpsCap;
|
|
||||||
}
|
|
||||||
|
|
||||||
Matter.Body.scale(this, 8000, 8000) // show the bullet by scaling it up (don't judge me... I know this is a bad way to do it)
|
|
||||||
this.endCycle = game.cycle + 140
|
|
||||||
this.collisionFilter.category = cat.bullet
|
|
||||||
Matter.Body.setPosition(this, {
|
|
||||||
x: mech.pos.x,
|
|
||||||
y: mech.pos.y
|
|
||||||
})
|
|
||||||
Matter.Body.setAngle(this, mech.angle)
|
|
||||||
const speed = 90
|
|
||||||
Matter.Body.setVelocity(this, {
|
|
||||||
x: mech.Vx / 2 + speed * this.charge * Math.cos(mech.angle),
|
|
||||||
y: mech.Vy / 2 + speed * this.charge * Math.sin(mech.angle)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//knock back
|
//knock back
|
||||||
const KNOCK = ((mech.crouch) ? 0.1 : 0.5) * this.charge * this.charge
|
const KNOCK = mech.crouch ? 0.08 : 0.34
|
||||||
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.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 = 450
|
||||||
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)
|
||||||
@@ -2700,7 +2704,6 @@ const b = {
|
|||||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||||
const SUB = Vector.sub(mob[i].position, mech.pos)
|
const SUB = Vector.sub(mob[i].position, mech.pos)
|
||||||
const DISTANCE = Vector.magnitude(SUB)
|
const DISTANCE = Vector.magnitude(SUB)
|
||||||
|
|
||||||
if (DISTANCE < range) {
|
if (DISTANCE < range) {
|
||||||
const DEPTH = Math.min(range - DISTANCE, 300)
|
const DEPTH = Math.min(range - DISTANCE, 300)
|
||||||
const FORCE = Vector.mult(Vector.normalise(SUB), 0.003 * Math.sqrt(DEPTH) * mob[i].mass)
|
const FORCE = Vector.mult(Vector.normalise(SUB), 0.003 * Math.sqrt(DEPTH) * mob[i].mass)
|
||||||
@@ -2708,38 +2711,161 @@ const b = {
|
|||||||
mob[i].force.y += 1.5 * FORCE.y;
|
mob[i].force.y += 1.5 * FORCE.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // charging on mouse down
|
} else {
|
||||||
mech.fireCDcycle = Infinity //can't fire until mouse is released
|
mech.fireCDcycle = mech.cycle + Math.floor(120);
|
||||||
const lastCharge = this.charge
|
}
|
||||||
let chargeRate = (mech.crouch) ? 0.98 : 0.984
|
} else {
|
||||||
chargeRate *= Math.pow(b.fireCD, 0.03)
|
const me = bullet.length;
|
||||||
this.charge = this.charge * chargeRate + (1 - chargeRate) // this.charge converges to 1
|
bullet[me] = Bodies.rectangle(0, 0, 0.015, 0.0015, {
|
||||||
if (mod.isRailTimeSlow) {
|
density: 0.008, //0.001 is normal
|
||||||
game.fpsCap = 30 //new fps
|
//frictionAir: 0.01, //restitution: 0,
|
||||||
game.fpsInterval = 1000 / game.fpsCap;
|
// angle: 0,
|
||||||
} else {
|
// friction: 0.5,
|
||||||
mech.energy -= (this.charge - lastCharge) * 0.28 //energy drain is proportional to charge gained, but doesn't stop normal mech.fieldRegen
|
restitution: 0,
|
||||||
|
frictionAir: 0,
|
||||||
|
dmg: 0, //damage done in addition to the damage from momentum
|
||||||
|
classType: "bullet",
|
||||||
|
collisionFilter: {
|
||||||
|
category: 0,
|
||||||
|
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
|
||||||
|
},
|
||||||
|
minDmgSpeed: 5,
|
||||||
|
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)
|
||||||
|
this.endCycle = 0 //triggers despawn
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onEnd() {}
|
||||||
|
});
|
||||||
|
mech.fireCDcycle = Infinity; // cool down
|
||||||
|
World.add(engine.world, bullet[me]); //add bullet to world
|
||||||
|
bullet[me].endCycle = Infinity
|
||||||
|
bullet[me].charge = 0;
|
||||||
|
bullet[me].do = function () {
|
||||||
|
if (mech.energy < 0.005 && !mod.isRailTimeSlow) {
|
||||||
|
mech.energy += 0.05 + this.charge * 0.3
|
||||||
|
mech.fireCDcycle = mech.cycle + 120; // cool down if out of energy
|
||||||
|
this.endCycle = 0;
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//draw targeting
|
if ((!game.mouseDown && this.charge > 0.6)) { //fire on mouse release or on low energy
|
||||||
let best;
|
mech.fireCDcycle = mech.cycle + 2; // set fire cool down
|
||||||
let range = 3000
|
//normal bullet behavior occurs after firing, overwrites this function
|
||||||
const dir = mech.angle
|
this.do = function () {
|
||||||
const path = [{
|
this.force.y += this.mass * 0.0003 / this.charge; // low gravity that scales with charge
|
||||||
x: mech.pos.x + 20 * Math.cos(dir),
|
|
||||||
y: mech.pos.y + 20 * Math.sin(dir)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
x: mech.pos.x + range * Math.cos(dir),
|
|
||||||
y: mech.pos.y + range * Math.sin(dir)
|
|
||||||
}
|
}
|
||||||
];
|
if (mod.isRailTimeSlow) {
|
||||||
const vertexCollision = function (v1, v1End, domain) {
|
game.fpsCap = game.fpsCapDefault
|
||||||
for (let i = 0; i < domain.length; ++i) {
|
game.fpsInterval = 1000 / game.fpsCap;
|
||||||
let vertices = domain[i].vertices;
|
}
|
||||||
const len = vertices.length - 1;
|
|
||||||
for (let j = 0; j < len; j++) {
|
Matter.Body.scale(this, 8000, 8000) // show the bullet by scaling it up (don't judge me... I know this is a bad way to do it)
|
||||||
results = game.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
|
this.endCycle = game.cycle + 140
|
||||||
|
this.collisionFilter.category = cat.bullet
|
||||||
|
Matter.Body.setPosition(this, {
|
||||||
|
x: mech.pos.x,
|
||||||
|
y: mech.pos.y
|
||||||
|
})
|
||||||
|
Matter.Body.setAngle(this, mech.angle)
|
||||||
|
const speed = 90
|
||||||
|
Matter.Body.setVelocity(this, {
|
||||||
|
x: mech.Vx / 2 + speed * this.charge * Math.cos(mech.angle),
|
||||||
|
y: mech.Vy / 2 + speed * this.charge * Math.sin(mech.angle)
|
||||||
|
});
|
||||||
|
|
||||||
|
//knock back
|
||||||
|
const KNOCK = ((mech.crouch) ? 0.1 : 0.5) * this.charge * this.charge
|
||||||
|
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 = 900 * this.charge
|
||||||
|
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 { // charging on mouse down
|
||||||
|
mech.fireCDcycle = Infinity //can't fire until mouse is released
|
||||||
|
const lastCharge = this.charge
|
||||||
|
let chargeRate = (mech.crouch) ? 0.98 : 0.984
|
||||||
|
chargeRate *= Math.pow(b.fireCD, 0.03)
|
||||||
|
this.charge = this.charge * chargeRate + (1 - chargeRate) // this.charge converges to 1
|
||||||
|
if (mod.isRailTimeSlow) {
|
||||||
|
game.fpsCap = 30 //new fps
|
||||||
|
game.fpsInterval = 1000 / game.fpsCap;
|
||||||
|
} else {
|
||||||
|
mech.energy -= (this.charge - lastCharge) * 0.28 //energy drain is proportional to charge gained, but doesn't stop normal mech.fieldRegen
|
||||||
|
}
|
||||||
|
|
||||||
|
//draw targeting
|
||||||
|
let best;
|
||||||
|
let range = 3000
|
||||||
|
const dir = mech.angle
|
||||||
|
const path = [{
|
||||||
|
x: mech.pos.x + 20 * Math.cos(dir),
|
||||||
|
y: mech.pos.y + 20 * Math.sin(dir)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
x: mech.pos.x + range * Math.cos(dir),
|
||||||
|
y: mech.pos.y + range * Math.sin(dir)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
const vertexCollision = function (v1, v1End, domain) {
|
||||||
|
for (let i = 0; i < domain.length; ++i) {
|
||||||
|
let vertices = domain[i].vertices;
|
||||||
|
const len = vertices.length - 1;
|
||||||
|
for (let j = 0; j < len; j++) {
|
||||||
|
results = game.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
|
||||||
|
if (results.onLine1 && results.onLine2) {
|
||||||
|
const dx = v1.x - results.x;
|
||||||
|
const dy = v1.y - results.y;
|
||||||
|
const dist2 = dx * dx + dy * dy;
|
||||||
|
if (dist2 < best.dist2) {
|
||||||
|
best = {
|
||||||
|
x: results.x,
|
||||||
|
y: results.y,
|
||||||
|
dist2: dist2,
|
||||||
|
who: domain[i],
|
||||||
|
v1: vertices[j],
|
||||||
|
v2: vertices[j + 1]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
results = game.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
|
||||||
if (results.onLine1 && results.onLine2) {
|
if (results.onLine1 && results.onLine2) {
|
||||||
const dx = v1.x - results.x;
|
const dx = v1.x - results.x;
|
||||||
const dy = v1.y - results.y;
|
const dy = v1.y - results.y;
|
||||||
@@ -2750,85 +2876,69 @@ const b = {
|
|||||||
y: results.y,
|
y: results.y,
|
||||||
dist2: dist2,
|
dist2: dist2,
|
||||||
who: domain[i],
|
who: domain[i],
|
||||||
v1: vertices[j],
|
v1: vertices[0],
|
||||||
v2: vertices[j + 1]
|
v2: vertices[len]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
results = game.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
|
|
||||||
if (results.onLine1 && results.onLine2) {
|
|
||||||
const dx = v1.x - results.x;
|
|
||||||
const dy = v1.y - results.y;
|
|
||||||
const dist2 = dx * dx + dy * dy;
|
|
||||||
if (dist2 < best.dist2) {
|
|
||||||
best = {
|
|
||||||
x: results.x,
|
|
||||||
y: results.y,
|
|
||||||
dist2: dist2,
|
|
||||||
who: domain[i],
|
|
||||||
v1: vertices[0],
|
|
||||||
v2: vertices[len]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//check for collisions
|
|
||||||
best = {
|
|
||||||
x: null,
|
|
||||||
y: null,
|
|
||||||
dist2: Infinity,
|
|
||||||
who: null,
|
|
||||||
v1: null,
|
|
||||||
v2: null
|
|
||||||
};
|
|
||||||
vertexCollision(path[0], path[1], mob);
|
|
||||||
vertexCollision(path[0], path[1], map);
|
|
||||||
vertexCollision(path[0], path[1], body);
|
|
||||||
if (best.dist2 != Infinity) { //if hitting something
|
|
||||||
path[path.length - 1] = {
|
|
||||||
x: best.x,
|
|
||||||
y: best.y
|
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
//draw beam
|
//check for collisions
|
||||||
ctx.beginPath();
|
best = {
|
||||||
ctx.moveTo(path[0].x, path[0].y);
|
x: null,
|
||||||
ctx.lineTo(path[1].x, path[1].y);
|
y: null,
|
||||||
ctx.strokeStyle = `rgba(100,0,180,0.7)`;
|
dist2: Infinity,
|
||||||
ctx.lineWidth = this.charge * 1
|
who: null,
|
||||||
ctx.setLineDash([10, 20]);
|
v1: null,
|
||||||
ctx.stroke();
|
v2: null
|
||||||
ctx.setLineDash([0, 0]);
|
};
|
||||||
|
vertexCollision(path[0], path[1], mob);
|
||||||
|
vertexCollision(path[0], path[1], map);
|
||||||
|
vertexCollision(path[0], path[1], body);
|
||||||
|
if (best.dist2 != Infinity) { //if hitting something
|
||||||
|
path[path.length - 1] = {
|
||||||
|
x: best.x,
|
||||||
|
y: best.y
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
//draw magnetic field
|
//draw beam
|
||||||
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 * this.charge * (0.93 + 0.07 * Math.random())
|
|
||||||
const ARC = 6 * i * i * this.charge * (0.93 + 0.07 * Math.random())
|
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
magField(MAG, ARC)
|
ctx.moveTo(path[0].x, path[0].y);
|
||||||
magField(MAG, -ARC)
|
ctx.lineTo(path[1].x, path[1].y);
|
||||||
ctx.fill();
|
ctx.strokeStyle = `rgba(100,0,180,0.7)`;
|
||||||
|
ctx.lineWidth = this.charge * 1
|
||||||
|
ctx.setLineDash([10, 20]);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.setLineDash([0, 0]);
|
||||||
|
|
||||||
|
//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 * this.charge * (0.93 + 0.07 * Math.random())
|
||||||
|
const ARC = 6 * i * i * this.charge * (0.93 + 0.07 * Math.random())
|
||||||
|
ctx.beginPath();
|
||||||
|
magField(MAG, ARC)
|
||||||
|
magField(MAG, -ARC)
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
16
js/mob.js
16
js/mob.js
@@ -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,
|
||||||
|
|||||||
27
js/mods.js
27
js/mods.js
@@ -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
|
||||||
}
|
}
|
||||||
@@ -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 <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 <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
|
||||||
|
|||||||
23
todo.txt
23
todo.txt
@@ -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);})()
|
||||||
Reference in New Issue
Block a user