railgun default harpoon
harpoon's crouch is now a harpoon sized railgun tech: halfwave rectifier now gives energy on harpoon/railgun charge and also stops harpoon from draining energy when it retracts toggling harpoon does 800 -> 600% more damage perfect diamagnetism default field is a bit larger bug fix with several periodic checks running off simulation time they now run on player time and will be active during time dilation fixed a bug where lore wasn't working
This commit is contained in:
428
js/bullet.js
428
js/bullet.js
@@ -1406,7 +1406,7 @@ const b = {
|
|||||||
this.caughtPowerUp.effect();
|
this.caughtPowerUp.effect();
|
||||||
Matter.Composite.remove(engine.world, this.caughtPowerUp);
|
Matter.Composite.remove(engine.world, this.caughtPowerUp);
|
||||||
powerUp.splice(index, 1);
|
powerUp.splice(index, 1);
|
||||||
if (tech.isHarpoonPowerUp) tech.harpoonDensity = 0.008 * 8 //0.006 is normal
|
if (tech.isHarpoonPowerUp) tech.harpoonDensity = 0.008 * 6 //0.006 is normal
|
||||||
} else {
|
} else {
|
||||||
this.dropCaughtPowerUp()
|
this.dropCaughtPowerUp()
|
||||||
}
|
}
|
||||||
@@ -1468,7 +1468,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (m.energy > 0.005) m.energy -= 0.005
|
if (!tech.isRailEnergyGain && m.energy > 0.005) m.energy -= 0.005
|
||||||
const sub = Vector.sub(this.position, m.pos)
|
const sub = Vector.sub(this.position, m.pos)
|
||||||
const rangeScale = 1 + 0.000001 * Vector.magnitude(sub) * Vector.magnitude(sub) //return faster when far from player
|
const rangeScale = 1 + 0.000001 * Vector.magnitude(sub) * Vector.magnitude(sub) //return faster when far from player
|
||||||
const returnForce = Vector.mult(Vector.normalise(sub), rangeScale * this.thrustMag * this.mass)
|
const returnForce = Vector.mult(Vector.normalise(sub), rangeScale * this.thrustMag * this.mass)
|
||||||
@@ -5597,160 +5597,141 @@ const b = {
|
|||||||
const dir = { x: Math.cos(m.angle), y: Math.sin(m.angle) }; //make a vector for the player's direction of length 1; used in dot product
|
const dir = { x: Math.cos(m.angle), y: Math.sin(m.angle) }; //make a vector for the player's direction of length 1; used in dot product
|
||||||
const harpoonSize = tech.isLargeHarpoon ? 1 + 0.1 * Math.sqrt(this.ammo) : 1
|
const harpoonSize = tech.isLargeHarpoon ? 1 + 0.1 * Math.sqrt(this.ammo) : 1
|
||||||
const totalCycles = 7 * (tech.isFilament ? 1 + 0.01 * Math.min(110, this.ammo) : 1) * Math.sqrt(harpoonSize)
|
const totalCycles = 7 * (tech.isFilament ? 1 + 0.01 * Math.min(110, this.ammo) : 1) * Math.sqrt(harpoonSize)
|
||||||
if (input.down) {
|
if (input.down) { //railgun
|
||||||
|
// if (true) {
|
||||||
if (tech.isRailGun) {
|
function pushAway(range) { //push away blocks when firing
|
||||||
function pushAway(range) { //push away blocks when firing
|
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, m.pos)
|
||||||
const SUB = Vector.sub(mob[i].position, m.pos)
|
const DISTANCE = Vector.magnitude(SUB)
|
||||||
const DISTANCE = Vector.magnitude(SUB)
|
if (DISTANCE < range) {
|
||||||
if (DISTANCE < range) {
|
const DEPTH = Math.min(range - DISTANCE, 1500)
|
||||||
const DEPTH = Math.min(range - DISTANCE, 1500)
|
const FORCE = Vector.mult(Vector.normalise(SUB), 0.001 * Math.sqrt(DEPTH) * mob[i].mass)
|
||||||
const FORCE = Vector.mult(Vector.normalise(SUB), 0.001 * Math.sqrt(DEPTH) * mob[i].mass)
|
mob[i].force.x += FORCE.x;
|
||||||
mob[i].force.x += FORCE.x;
|
mob[i].force.y += FORCE.y;
|
||||||
mob[i].force.y += FORCE.y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let i = 0, len = body.length; i < len; ++i) {
|
|
||||||
const SUB = Vector.sub(body[i].position, m.pos)
|
|
||||||
const DISTANCE = Vector.magnitude(SUB)
|
|
||||||
if (DISTANCE < range) {
|
|
||||||
const DEPTH = Math.min(range - DISTANCE, 500)
|
|
||||||
const FORCE = Vector.mult(Vector.normalise(SUB), 0.002 * Math.sqrt(DEPTH) * body[i].mass)
|
|
||||||
body[i].force.x += FORCE.x;
|
|
||||||
body[i].force.y += FORCE.y - body[i].mass * simulation.g * 1.5; //kick up a bit to give them some arc
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (let i = 0, len = body.length; i < len; ++i) {
|
||||||
|
const SUB = Vector.sub(body[i].position, m.pos)
|
||||||
|
const DISTANCE = Vector.magnitude(SUB)
|
||||||
|
if (DISTANCE < range) {
|
||||||
|
const DEPTH = Math.min(range - DISTANCE, 500)
|
||||||
|
const FORCE = Vector.mult(Vector.normalise(SUB), 0.002 * Math.sqrt(DEPTH) * body[i].mass)
|
||||||
|
body[i].force.x += FORCE.x;
|
||||||
|
body[i].force.y += FORCE.y - body[i].mass * simulation.g * 1.5; //kick up a bit to give them some arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
const size = 3 + tech.isLargeHarpoon * 0.1 * Math.sqrt(this.ammo)
|
bullet[me] = Bodies.rectangle(0, 0, 0.015, 0.0015, { //start as a small shape that can't even be seen
|
||||||
bullet[me] = Bodies.rectangle(0, 0, 0.015, 0.0015, { //start as a small shape that can't even be seen
|
vertexGoal: [{ x: -40 * harpoonSize, y: 2 * harpoonSize, index: 0, isInternal: false }, { x: -40 * harpoonSize, y: -2 * harpoonSize, index: 1, isInternal: false }, { x: 50 * harpoonSize, y: -3 * harpoonSize, index: 3, isInternal: false }, { x: 30 * harpoonSize, y: 2 * harpoonSize, index: 4, isInternal: false }],
|
||||||
vertexGoal: [{ x: -40 * size, y: 2 * size, index: 0, isInternal: false }, { x: -40 * size, y: -2 * size, index: 1, isInternal: false }, { x: 50 * size, y: -3 * size, index: 3, isInternal: false }, { x: 30 * size, y: 2 * size, index: 4, isInternal: false }],
|
density: 0.03, //0.001 is normal
|
||||||
density: 0.03, //0.001 is normal
|
restitution: 0,
|
||||||
restitution: 0,
|
frictionAir: 0,
|
||||||
frictionAir: 0,
|
dmg: 0, //damage done in addition to the damage from momentum
|
||||||
dmg: 0, //damage done in addition to the damage from momentum
|
classType: "bullet",
|
||||||
classType: "bullet",
|
collisionFilter: {
|
||||||
collisionFilter: {
|
category: 0,
|
||||||
category: 0,
|
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
|
||||||
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
|
},
|
||||||
},
|
minDmgSpeed: 5,
|
||||||
minDmgSpeed: 5,
|
beforeDmg(who) {
|
||||||
beforeDmg(who) {
|
if (tech.isShieldPierce && who.isShielded) { //disable shields
|
||||||
if (tech.isShieldPierce && who.isShielded) { //disable shields
|
who.isShielded = false
|
||||||
who.isShielded = false
|
requestAnimationFrame(() => { who.isShielded = true });
|
||||||
requestAnimationFrame(() => { who.isShielded = true });
|
}
|
||||||
}
|
if (who.shield && !tech.isShieldPierce) {
|
||||||
if (who.shield && !tech.isShieldPierce) {
|
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
|
Matter.Body.setVelocity(mob[i], Vector.mult(Vector.normalise(this.velocity), 10));
|
||||||
Matter.Body.setVelocity(mob[i], Vector.mult(Vector.normalise(this.velocity), 10));
|
break
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Matter.Body.setVelocity(this, { x: -0.4 * this.velocity.x, y: -0.4 * this.velocity.y });
|
|
||||||
} else {
|
|
||||||
if (tech.fragments && this.speed > 10) {
|
|
||||||
b.targetedNail(this.position, tech.fragments * 17)
|
|
||||||
this.endCycle = 0 //triggers despawn
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
Matter.Body.setVelocity(this, { x: -0.4 * this.velocity.x, y: -0.4 * this.velocity.y });
|
||||||
onEnd() {}
|
} else {
|
||||||
});
|
if (tech.fragments && this.speed > 10) {
|
||||||
m.fireCDcycle = Infinity; // cool down
|
b.targetedNail(this.position, tech.fragments * 17)
|
||||||
Composite.add(engine.world, bullet[me]); //add bullet to world
|
this.endCycle = 0 //triggers despawn
|
||||||
bullet[me].endCycle = Infinity
|
}
|
||||||
bullet[me].charge = 0;
|
}
|
||||||
bullet[me].do = function() {
|
},
|
||||||
if (m.energy < 0.005 && !tech.isRailEnergyGain) {
|
onEnd() {}
|
||||||
m.energy += 0.05 + this.charge * 0.2
|
});
|
||||||
m.fireCDcycle = m.cycle + 120; // cool down if out of energy
|
m.fireCDcycle = Infinity; // cool down
|
||||||
this.endCycle = 0;
|
Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||||
b.refundAmmo()
|
bullet[me].endCycle = Infinity
|
||||||
return
|
bullet[me].charge = 0;
|
||||||
|
bullet[me].do = function() {
|
||||||
|
if (m.energy < 0.005 && !tech.isRailEnergyGain) {
|
||||||
|
m.energy += 0.05 + this.charge * 0.2
|
||||||
|
m.fireCDcycle = m.cycle + 120; // cool down if out of energy
|
||||||
|
this.endCycle = 0;
|
||||||
|
b.refundAmmo()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!input.fire && this.charge > 0.6)) { //fire on mouse release or on low energy
|
||||||
|
// if (tech.isDarts) {
|
||||||
|
// for (let i = 0; i < 5; i++) {
|
||||||
|
// b.dart(where, m.angle + 0.1 * i)
|
||||||
|
// b.dart(where, m.angle - 0.1 * i)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
Matter.Body.setVertices(this, this.vertexGoal) //take on harpoon shape
|
||||||
|
m.fireCDcycle = m.cycle + 2; // set fire cool down
|
||||||
|
//normal bullet behavior occurs after firing, overwrites this function
|
||||||
|
this.endCycle = simulation.cycle + 140
|
||||||
|
this.collisionFilter.category = cat.bullet
|
||||||
|
Matter.Body.setPosition(this, { x: m.pos.x, y: m.pos.y })
|
||||||
|
Matter.Body.setAngle(this, m.angle)
|
||||||
|
const speed = 120
|
||||||
|
Matter.Body.setVelocity(this, {
|
||||||
|
x: m.Vx / 2 + speed * this.charge * Math.cos(m.angle),
|
||||||
|
y: m.Vy / 2 + speed * this.charge * Math.sin(m.angle)
|
||||||
|
});
|
||||||
|
this.do = function() {
|
||||||
|
this.force.y += this.mass * 0.0003 / this.charge; // low gravity that scales with charge
|
||||||
|
}
|
||||||
|
const KNOCK = ((input.down) ? 0.1 : 0.5) * this.charge * this.charge
|
||||||
|
player.force.x -= KNOCK * Math.cos(m.angle)
|
||||||
|
player.force.y -= KNOCK * Math.sin(m.angle) * 0.35 //reduce knock back in vertical direction to stop super jumps
|
||||||
|
pushAway(1200 * this.charge)
|
||||||
|
} else { // charging on mouse down
|
||||||
|
if (tech.isFireMoveLock) {
|
||||||
|
Matter.Body.setVelocity(player, {
|
||||||
|
x: 0,
|
||||||
|
y: -55 * player.mass * simulation.g //undo gravity before it is added
|
||||||
|
});
|
||||||
|
player.force.x = 0
|
||||||
|
player.force.y = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!input.fire && this.charge > 0.6)) { //fire on mouse release or on low energy
|
m.fireCDcycle = Infinity //can't fire until mouse is released
|
||||||
// if (tech.isDarts) {
|
const previousCharge = this.charge
|
||||||
// for (let i = 0; i < 5; i++) {
|
//small b.fireCDscale = faster shots, b.fireCDscale=1 = normal shot, big b.fireCDscale = slower chot
|
||||||
// b.dart(where, m.angle + 0.1 * i)
|
let smoothRate = tech.isCapacitor ? 0.93 : Math.min(0.998, 0.985 * (0.98 + 0.02 * b.fireCDscale))
|
||||||
// b.dart(where, m.angle - 0.1 * i)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
Matter.Body.setVertices(this, this.vertexGoal) //take on harpoon shape
|
|
||||||
m.fireCDcycle = m.cycle + 2; // set fire cool down
|
|
||||||
//normal bullet behavior occurs after firing, overwrites this function
|
|
||||||
this.endCycle = simulation.cycle + 140
|
|
||||||
this.collisionFilter.category = cat.bullet
|
|
||||||
Matter.Body.setPosition(this, { x: m.pos.x, y: m.pos.y })
|
|
||||||
Matter.Body.setAngle(this, m.angle)
|
|
||||||
const speed = 120
|
|
||||||
Matter.Body.setVelocity(this, {
|
|
||||||
x: m.Vx / 2 + speed * this.charge * Math.cos(m.angle),
|
|
||||||
y: m.Vy / 2 + speed * this.charge * Math.sin(m.angle)
|
|
||||||
});
|
|
||||||
this.do = function() {
|
|
||||||
this.force.y += this.mass * 0.0003 / this.charge; // low gravity that scales with charge
|
|
||||||
}
|
|
||||||
const KNOCK = ((input.down) ? 0.1 : 0.5) * this.charge * this.charge
|
|
||||||
player.force.x -= KNOCK * Math.cos(m.angle)
|
|
||||||
player.force.y -= KNOCK * Math.sin(m.angle) * 0.35 //reduce knock back in vertical direction to stop super jumps
|
|
||||||
pushAway(1200 * this.charge)
|
|
||||||
} else { // charging on mouse down
|
|
||||||
if (tech.isFireMoveLock) {
|
|
||||||
Matter.Body.setVelocity(player, {
|
|
||||||
x: 0,
|
|
||||||
y: -55 * player.mass * simulation.g //undo gravity before it is added
|
|
||||||
});
|
|
||||||
player.force.x = 0
|
|
||||||
player.force.y = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
m.fireCDcycle = Infinity //can't fire until mouse is released
|
this.charge = this.charge * smoothRate + 1 - smoothRate
|
||||||
const previousCharge = this.charge
|
m.energy += (this.charge - previousCharge) * (tech.isRailEnergyGain ? 10 : -0.5) //energy drain is proportional to charge gained, but doesn't stop normal m.fieldRegen
|
||||||
//small b.fireCDscale = faster shots, b.fireCDscale=1 = normal shot, big b.fireCDscale = slower chot
|
//draw targeting
|
||||||
let smoothRate = tech.isCapacitor ? 0.93 : Math.min(0.998, 0.985 * (0.98 + 0.02 * b.fireCDscale))
|
let best;
|
||||||
|
let range = 3000
|
||||||
this.charge = this.charge * smoothRate + 1 - smoothRate
|
const dir = m.angle
|
||||||
m.energy += (this.charge - previousCharge) * (tech.isRailEnergyGain ? 10 : -0.5) //energy drain is proportional to charge gained, but doesn't stop normal m.fieldRegen
|
const path = [{
|
||||||
//draw targeting
|
x: m.pos.x + 20 * Math.cos(dir),
|
||||||
let best;
|
y: m.pos.y + 20 * Math.sin(dir)
|
||||||
let range = 3000
|
},
|
||||||
const dir = m.angle
|
{
|
||||||
const path = [{
|
x: m.pos.x + range * Math.cos(dir),
|
||||||
x: m.pos.x + 20 * Math.cos(dir),
|
y: m.pos.y + range * Math.sin(dir)
|
||||||
y: m.pos.y + 20 * Math.sin(dir)
|
}
|
||||||
},
|
];
|
||||||
{
|
const vertexCollision = function(v1, v1End, domain) {
|
||||||
x: m.pos.x + range * Math.cos(dir),
|
for (let i = 0; i < domain.length; ++i) {
|
||||||
y: m.pos.y + range * Math.sin(dir)
|
let vertices = domain[i].vertices;
|
||||||
}
|
const len = vertices.length - 1;
|
||||||
];
|
for (let j = 0; j < len; j++) {
|
||||||
const vertexCollision = function(v1, v1End, domain) {
|
results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
|
||||||
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 = simulation.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 = simulation.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;
|
||||||
@@ -5761,82 +5742,99 @@ const b = {
|
|||||||
y: results.y,
|
y: results.y,
|
||||||
dist2: dist2,
|
dist2: dist2,
|
||||||
who: domain[i],
|
who: domain[i],
|
||||||
v1: vertices[0],
|
v1: vertices[j],
|
||||||
v2: vertices[len]
|
v2: vertices[j + 1]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
results = simulation.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
|
//check for collisions
|
||||||
best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null };
|
best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null };
|
||||||
vertexCollision(path[0], path[1], mob);
|
vertexCollision(path[0], path[1], mob);
|
||||||
vertexCollision(path[0], path[1], map);
|
vertexCollision(path[0], path[1], map);
|
||||||
vertexCollision(path[0], path[1], body);
|
vertexCollision(path[0], path[1], body);
|
||||||
if (best.dist2 != Infinity) path[path.length - 1] = { x: best.x, y: best.y }; //if hitting something
|
if (best.dist2 != Infinity) path[path.length - 1] = { x: best.x, y: best.y }; //if hitting something
|
||||||
//draw beam
|
//draw beam
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(path[0].x, path[0].y);
|
||||||
|
ctx.lineTo(path[1].x, path[1].y);
|
||||||
|
ctx.strokeStyle = `rgba(100,0,180,0.7)`;
|
||||||
|
ctx.lineWidth = this.charge * 1
|
||||||
|
ctx.setLineDash([10, 20]);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.setLineDash([]);
|
||||||
|
//draw magnetic field
|
||||||
|
const X = m.pos.x
|
||||||
|
const Y = m.pos.y
|
||||||
|
const unitVector = { x: Math.cos(m.angle), y: Math.sin(m.angle) }
|
||||||
|
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();
|
||||||
ctx.moveTo(path[0].x, path[0].y);
|
magField(MAG, ARC)
|
||||||
ctx.lineTo(path[1].x, path[1].y);
|
magField(MAG, -ARC)
|
||||||
ctx.strokeStyle = `rgba(100,0,180,0.7)`;
|
ctx.fill();
|
||||||
ctx.lineWidth = this.charge * 1
|
|
||||||
ctx.setLineDash([10, 20]);
|
|
||||||
ctx.stroke();
|
|
||||||
ctx.setLineDash([]);
|
|
||||||
//draw magnetic field
|
|
||||||
const X = m.pos.x
|
|
||||||
const Y = m.pos.y
|
|
||||||
const unitVector = { x: Math.cos(m.angle), y: Math.sin(m.angle) }
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
|
||||||
// if (true) { //grappling hook, not working really
|
|
||||||
// if (m.immuneCycle < m.cycle + 60) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles
|
|
||||||
// b.harpoon(where, closest.target, m.angle, harpoonSize, false, 15)
|
|
||||||
// m.fireCDcycle = m.cycle + 50 * b.fireCDscale; // cool down
|
|
||||||
// const speed = 50
|
|
||||||
// const velocity = { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }
|
|
||||||
// Matter.Body.setVelocity(player, velocity);
|
|
||||||
|
|
||||||
// } else {
|
|
||||||
|
|
||||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
|
||||||
if (mob[i].alive && !mob[i].isBadTarget && Matter.Query.ray(map, m.pos, mob[i].position).length === 0) {
|
|
||||||
const dot = Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, m.pos))) //the dot product of diff and dir will return how much over lap between the vectors
|
|
||||||
const dist = Vector.magnitude(Vector.sub(where, mob[i].position))
|
|
||||||
if (dist < closest.distance && dot > 0.95 && dist * dot * dot * dot * dot > 880) { //target closest mob that player is looking at and isn't too close to target
|
|
||||||
closest.distance = dist
|
|
||||||
closest.target = mob[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b.harpoon(where, closest.target, m.angle, harpoonSize, false, 15)
|
|
||||||
m.fireCDcycle = m.cycle + 50 * b.fireCDscale; // cool down
|
|
||||||
}
|
}
|
||||||
|
// } else {
|
||||||
|
|
||||||
|
// // if (true) { //grappling hook, not working really
|
||||||
|
// // if (m.immuneCycle < m.cycle + 60) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles
|
||||||
|
// // b.harpoon(where, closest.target, m.angle, harpoonSize, false, 15)
|
||||||
|
// // m.fireCDcycle = m.cycle + 50 * b.fireCDscale; // cool down
|
||||||
|
// // const speed = 50
|
||||||
|
// // const velocity = { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }
|
||||||
|
// // Matter.Body.setVelocity(player, velocity);
|
||||||
|
|
||||||
|
// // } else {
|
||||||
|
|
||||||
|
// for (let i = 0, len = mob.length; i < len; ++i) {
|
||||||
|
// if (mob[i].alive && !mob[i].isBadTarget && Matter.Query.ray(map, m.pos, mob[i].position).length === 0) {
|
||||||
|
// const dot = Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, m.pos))) //the dot product of diff and dir will return how much over lap between the vectors
|
||||||
|
// const dist = Vector.magnitude(Vector.sub(where, mob[i].position))
|
||||||
|
// if (dist < closest.distance && dot > 0.95 && dist * dot * dot * dot * dot > 880) { //target closest mob that player is looking at and isn't too close to target
|
||||||
|
// closest.distance = dist
|
||||||
|
// closest.target = mob[i]
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// b.harpoon(where, closest.target, m.angle, harpoonSize, false, 15)
|
||||||
|
// m.fireCDcycle = m.cycle + 50 * b.fireCDscale; // cool down
|
||||||
|
// }
|
||||||
} else if (tech.extraHarpoons) {
|
} else if (tech.extraHarpoons) {
|
||||||
const range = 450 * (tech.isFilament ? 1 + 0.005 * Math.min(110, this.ammo) : 1)
|
const range = 450 * (tech.isFilament ? 1 + 0.005 * Math.min(110, this.ammo) : 1)
|
||||||
let targetCount = 0
|
let targetCount = 0
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ const level = {
|
|||||||
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
|
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
|
||||||
// simulation.isHorizontalFlipped = true
|
// simulation.isHorizontalFlipped = true
|
||||||
// m.setField("standing wave")
|
// m.setField("standing wave")
|
||||||
// b.giveGuns("laser")
|
// b.giveGuns("harpoon")
|
||||||
// for (let i = 0; i < 100; i++) tech.giveTech("slow light")
|
// for (let i = 0; i < 100; i++) tech.giveTech("slow light")
|
||||||
// tech.giveTech("eject")
|
// tech.giveTech("recycling")
|
||||||
// for (let i = 0; i < 2; i++) powerUps.directSpawn(0, 0, "tech");
|
// for (let i = 0; i < 2; i++) powerUps.directSpawn(0, 0, "tech");
|
||||||
// tech.giveTech("tinsellated flagella")
|
// tech.giveTech("tinsellated flagella")
|
||||||
// for (let i = 0; i < 3; i++) tech.giveTech("undefined")
|
// for (let i = 0; i < 3; i++) tech.giveTech("undefined")
|
||||||
@@ -2374,8 +2374,8 @@ const level = {
|
|||||||
},
|
},
|
||||||
null() {
|
null() {
|
||||||
level.levels.pop(); //remove lore level from rotation
|
level.levels.pop(); //remove lore level from rotation
|
||||||
level.onLevel--
|
// level.onLevel--
|
||||||
console.log(level.onLevel, level.levels)
|
// console.log(level.onLevel, level.levels)
|
||||||
//start a conversation based on the number of conversations seen
|
//start a conversation based on the number of conversations seen
|
||||||
if (localSettings.loreCount < lore.conversation.length && !simulation.isCheating) {
|
if (localSettings.loreCount < lore.conversation.length && !simulation.isCheating) {
|
||||||
lore.testSpeechAPI() //see if speech is working
|
lore.testSpeechAPI() //see if speech is working
|
||||||
|
|||||||
@@ -1723,8 +1723,8 @@ const m = {
|
|||||||
}
|
}
|
||||||
m.hold = function() {
|
m.hold = function() {
|
||||||
const wave = Math.sin(m.cycle * 0.022);
|
const wave = Math.sin(m.cycle * 0.022);
|
||||||
m.fieldRange = 160 + 12 * wave + 100 * tech.isBigField
|
m.fieldRange = 180 + 12 * wave + 100 * tech.isBigField
|
||||||
m.fieldArc = 0.34 + 0.04 * wave + 0.065 * tech.isBigField //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
|
m.fieldArc = 0.35 + 0.045 * wave + 0.065 * tech.isBigField //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
|
||||||
m.calculateFieldThreshold();
|
m.calculateFieldThreshold();
|
||||||
if (m.isHolding) {
|
if (m.isHolding) {
|
||||||
m.drawHold(m.holdingTarget);
|
m.drawHold(m.holdingTarget);
|
||||||
|
|||||||
@@ -888,7 +888,7 @@ const simulation = {
|
|||||||
// }
|
// }
|
||||||
// },
|
// },
|
||||||
checks() {
|
checks() {
|
||||||
if (!(simulation.cycle % 60)) { //once a second
|
if (!(m.cycle % 60)) { //once a second
|
||||||
//energy overfill
|
//energy overfill
|
||||||
if (m.energy > m.maxEnergy) m.energy = m.maxEnergy + (m.energy - m.maxEnergy) * tech.overfillDrain //every second energy above max energy loses 25%
|
if (m.energy > m.maxEnergy) m.energy = m.maxEnergy + (m.energy - m.maxEnergy) * tech.overfillDrain //every second energy above max energy loses 25%
|
||||||
if (tech.isFlipFlopEnergy && m.immuneCycle < m.cycle) {
|
if (tech.isFlipFlopEnergy && m.immuneCycle < m.cycle) {
|
||||||
@@ -942,12 +942,13 @@ const simulation = {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if (m.lastKillCycle + 300 > simulation.cycle) { //effects active for 5 seconds after killing a mob
|
if (m.lastKillCycle + 300 > m.cycle) { //effects active for 5 seconds after killing a mob
|
||||||
if (tech.isEnergyRecovery && m.immuneCycle < m.cycle) m.energy += m.maxEnergy * 0.05
|
if (tech.isEnergyRecovery && m.immuneCycle < m.cycle) m.energy += m.maxEnergy * 0.05
|
||||||
|
console.log(`lastKill = ${m.lastKillCycle}, cycle = ${m.cycle}, health = ${m.health}, maxHealth = ${m.maxHealth}`)
|
||||||
if (tech.isHealthRecovery) m.addHealth(0.01 * m.maxHealth)
|
if (tech.isHealthRecovery) m.addHealth(0.01 * m.maxHealth)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(simulation.cycle % 420)) { //once every 7 seconds
|
if (!(m.cycle % 420)) { //once every 7 seconds
|
||||||
if (tech.isZeno) {
|
if (tech.isZeno) {
|
||||||
m.health *= 0.9167 //remove 1/12
|
m.health *= 0.9167 //remove 1/12
|
||||||
m.displayHealth();
|
m.displayHealth();
|
||||||
|
|||||||
50
js/tech.js
50
js/tech.js
@@ -5330,16 +5330,16 @@ const tech = {
|
|||||||
{
|
{
|
||||||
name: "capacitor bank",
|
name: "capacitor bank",
|
||||||
// description: "<strong>charge</strong> effects build up almost <strong>instantly</strong><br><em style = 'font-size:97%;'>throwing <strong class='color-block'>blocks</strong>, foam, railgun, pulse, tokamak</em>",
|
// description: "<strong>charge</strong> effects build up almost <strong>instantly</strong><br><em style = 'font-size:97%;'>throwing <strong class='color-block'>blocks</strong>, foam, railgun, pulse, tokamak</em>",
|
||||||
descriptionFunction() { return `<strong>charge</strong> effects build up almost <strong>instantly</strong><br><em style = 'font-size:97%;'>throwing <strong class='color-block'>blocks</strong>, ${tech.haveGunCheck("foam", false) ? "<strong>foam</strong>" : "foam"}, ${tech.isRailGun ? "<strong>railgun</strong>" : "railgun"}, ${tech.isPulseLaser ? "<strong>pulse</strong>" : "pulse"}, ${tech.isTokamak ? "<strong>tokamak</strong>" : "tokamak"}</em>` },
|
descriptionFunction() { return `<strong>charge</strong> effects build up almost <strong>instantly</strong><br><em style = 'font-size:97%;'>throwing <strong class='color-block'>blocks</strong>, ${tech.haveGunCheck("foam", false) ? "<strong>foam</strong>" : "foam"}, ${tech.haveGunCheck("harpoon", false) ? "<strong>railgun</strong>" : "railgun"}, ${tech.isPulseLaser ? "<strong>pulse</strong>" : "pulse"}, ${tech.isTokamak ? "<strong>tokamak</strong>" : "tokamak"}</em>` },
|
||||||
isGunTech: true,
|
isGunTech: true,
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
frequency: 2,
|
frequency: 2,
|
||||||
frequencyDefault: 2,
|
frequencyDefault: 2,
|
||||||
allowed() {
|
allowed() {
|
||||||
return tech.blockDamage > 0.075 || tech.haveGunCheck("foam") || tech.isRailGun || tech.isTokamak || tech.isPulseLaser
|
return tech.blockDamage > 0.075 || tech.haveGunCheck("foam") || tech.isTokamak || tech.isPulseLaser
|
||||||
},
|
},
|
||||||
requires: "throwing blocks, foam, railgun, pulse, tokamak",
|
requires: "throwing blocks, foam, pulse, tokamak",
|
||||||
effect() {
|
effect() {
|
||||||
tech.isCapacitor = true;
|
tech.isCapacitor = true;
|
||||||
},
|
},
|
||||||
@@ -5537,7 +5537,7 @@ const tech = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "toggling harpoon",
|
name: "toggling harpoon",
|
||||||
description: "increase the <strong class='color-d'>damage</strong> of your next <strong>harpoon</strong><br>by <strong>800%</strong> after using it to collect a <strong>power up</strong>",
|
description: "increase the <strong class='color-d'>damage</strong> of your next <strong>harpoon</strong><br>by <strong>600%</strong> after using it to collect a <strong>power up</strong>",
|
||||||
isGunTech: true,
|
isGunTech: true,
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
@@ -5574,9 +5574,28 @@ const tech = {
|
|||||||
tech.extraHarpoons = 0;
|
tech.extraHarpoons = 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// name: "railgun",
|
||||||
|
// description: "firing the <strong>harpoon</strong> while crouched launches<br>a rod that is <strong>faster</strong>, <strong>larger</strong>, and more <strong>dense</strong>",
|
||||||
|
// isGunTech: true,
|
||||||
|
// maxCount: 1,
|
||||||
|
// count: 0,
|
||||||
|
// frequency: 2,
|
||||||
|
// frequencyDefault: 2,
|
||||||
|
// allowed() {
|
||||||
|
// return tech.haveGunCheck("harpoon")
|
||||||
|
// },
|
||||||
|
// requires: "railgun",
|
||||||
|
// effect() {
|
||||||
|
// tech.isRailGun = true;
|
||||||
|
// },
|
||||||
|
// remove() {
|
||||||
|
// tech.isRailGun = false;
|
||||||
|
// }
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
name: "railgun",
|
name: "half-wave rectifier",
|
||||||
description: "firing the <strong>harpoon</strong> while crouched launches<br>a rod that is <strong>faster</strong>, <strong>larger</strong>, and more <strong>dense</strong>",
|
description: "<strong>harpoons</strong> drain no <strong class='color-f'>energy</strong> as they <strong>retract</strong><br><strong>crouch</strong> firing <strong>harpoon</strong> generates <strong class='color-f'>energy</strong>",
|
||||||
isGunTech: true,
|
isGunTech: true,
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
@@ -5586,25 +5605,6 @@ const tech = {
|
|||||||
return tech.haveGunCheck("harpoon")
|
return tech.haveGunCheck("harpoon")
|
||||||
},
|
},
|
||||||
requires: "railgun",
|
requires: "railgun",
|
||||||
effect() {
|
|
||||||
tech.isRailGun = true;
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
tech.isRailGun = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "half-wave rectifier",
|
|
||||||
description: "charging the <strong>railgun</strong> gives you <strong class='color-f'>energy</strong><br><em>instead of draining it</em>",
|
|
||||||
isGunTech: true,
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
frequency: 2,
|
|
||||||
frequencyDefault: 2,
|
|
||||||
allowed() {
|
|
||||||
return tech.isRailGun
|
|
||||||
},
|
|
||||||
requires: "harpoon, railgun",
|
|
||||||
effect() {
|
effect() {
|
||||||
tech.isRailEnergyGain = true;
|
tech.isRailEnergyGain = true;
|
||||||
},
|
},
|
||||||
|
|||||||
16
todo.txt
16
todo.txt
@@ -1,15 +1,17 @@
|
|||||||
******************************************************** NEXT PATCH **************************************************
|
******************************************************** NEXT PATCH **************************************************
|
||||||
|
|
||||||
seeds are displayed in pause menu and intro map
|
harpoon's crouch is now a harpoon sized railgun
|
||||||
seeds from your previous run is displayed in settings after you die
|
tech: halfwave rectifier now gives energy on harpoon/railgun charge and also stops harpoon from draining energy when it retracts
|
||||||
fixed some minor seed inconsistency
|
toggling harpoon does 800 -> 600% more damage
|
||||||
|
|
||||||
|
perfect diamagnetism default field is a bit larger
|
||||||
|
|
||||||
|
bug fix with several periodic checks running off simulation time
|
||||||
|
they now run on player time and will be active during time dilation
|
||||||
|
fixed a bug where lore wasn't working
|
||||||
|
|
||||||
******************************************************** TODO ********************************************************
|
******************************************************** TODO ********************************************************
|
||||||
|
|
||||||
make railgun default fire mode for crouch harpoon?
|
|
||||||
|
|
||||||
buff perfect diamagnetism
|
|
||||||
|
|
||||||
make a seed/hash system that controls only the tech/guns/fields shown
|
make a seed/hash system that controls only the tech/guns/fields shown
|
||||||
URL sharing could include a seed
|
URL sharing could include a seed
|
||||||
seed will control:
|
seed will control:
|
||||||
|
|||||||
Reference in New Issue
Block a user