laserLayer

mob: laserLayer - leaves behind lasers that persist for a few seconds
ghoster mobs do 66% less damage, but they eject your ammo

grappling hook tech rupture renamed swarf
  fires several nails at nearby mobs, not explosions
grappling hook 6->9 energy per second
CIWS 18->10 energy
reel +40->75 energy reeling blocks
wormhole 5->7% duplication
cloaking no longer drains energy, this fixes a can't cloak bug
  dazzler no longer drains energy
    dazzler range reduced by 15%
    dazzler stuns for 3->2 seconds
zero point energy 100->166 max energy
expansion 40->77 max energy
annihilation -33% of max energy -> 10 energy
dynamical systems is no longer a field tech  35->30 damage
tessellation is no longer a field tech  50->35 defense
yield stress removed
  topological defect 80->111% damage
  brittle 80->111% damage
commodities exchange  6-12 -> 10-14 power ups
heat engine 50->40% damage
flame test grenades clusters explode 40% faster
alternator uses 10->0% energy for harpoon

finally made a shared vertexCollision function
  this might cause some bugs with laser-like effects...
This commit is contained in:
landgreen
2024-02-24 15:09:35 -08:00
parent b5e4b0db03
commit 38d993154c
13 changed files with 684 additions and 1808 deletions

197
js/mob.js
View File

@@ -505,89 +505,48 @@ const mobs = {
ctx.fill();
}
},
laser() {
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 = 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 && (!domain[i].mob || domain[i].alive)) {
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) {
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]
};
}
}
}
};
if (this.seePlayer.recall && !this.isSlowed) {
const seeRange = 2500;
best = {
x: null,
y: null,
dist2: Infinity,
who: null,
v1: null,
v2: null
};
const look = {
x: this.position.x + seeRange * Math.cos(this.angle),
y: this.position.y + seeRange * Math.sin(this.angle)
};
vertexCollision(this.position, look, map);
vertexCollision(this.position, look, body);
if (!m.isCloak) vertexCollision(this.position, look, [player]);
// hitting player
if (best.who === player) {
if (m.immuneCycle < m.cycle) {
const dmg = 0.0014 * simulation.dmgScale;
m.damage(dmg);
ctx.fillStyle = "#f00"; //draw damage
ctx.beginPath();
ctx.arc(best.x, best.y, dmg * 10000, 0, 2 * Math.PI);
ctx.fill();
}
}
//draw beam
if (best.dist2 === Infinity) {
best = look;
}
ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y);
ctx.lineTo(best.x, best.y);
ctx.strokeStyle = "#f00"; // Purple path
ctx.lineWidth = 1;
ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
ctx.stroke(); // Draw it
ctx.setLineDash([]);
}
},
// laser() {
// if (this.seePlayer.recall && !this.isSlowed) {
// const seeRange = 2500;
// best = {
// x: null,
// y: null,
// dist2: Infinity,
// who: null,
// v1: null,
// v2: null
// };
// const look = {
// x: this.position.x + seeRange * Math.cos(this.angle),
// y: this.position.y + seeRange * Math.sin(this.angle)
// };
// best = vertexCollision(this.position, look, m.isCloak ? [map, body] : [map, body, [player]]);
// // hitting player
// if (best.who === player) {
// if (m.immuneCycle < m.cycle) {
// const dmg = 0.0014 * simulation.dmgScale;
// m.damage(dmg);
// ctx.fillStyle = "#f00"; //draw damage
// ctx.beginPath();
// ctx.arc(best.x, best.y, dmg * 10000, 0, 2 * Math.PI);
// ctx.fill();
// }
// }
// //draw beam
// if (best.dist2 === Infinity) {
// best = look;
// }
// ctx.beginPath();
// ctx.moveTo(this.position.x, this.position.y);
// ctx.lineTo(best.x, best.y);
// ctx.strokeStyle = "#f00"; // Purple path
// ctx.lineWidth = 1;
// ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
// ctx.stroke(); // Draw it
// ctx.setLineDash([]);
// }
// },
wing(a, radius = 250, ellipticity = 0.4, dmg = 0.0006) {
const minorRadius = radius * ellipticity
const perp = { x: Math.cos(a), y: Math.sin(a) } //
@@ -658,47 +617,6 @@ const mobs = {
ctx.fillStyle = "rgba(0,0,0,0.07)";
ctx.fill();
//spring to random place on map
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 = 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 && (!domain[i].mob || domain[i].alive)) {
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) {
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]
};
}
}
}
};
//move to a random location
if (!(simulation.cycle % (this.seePlayerFreq * 4))) {
best = {
x: null,
@@ -713,8 +631,7 @@ const mobs = {
x: this.position.x + seeRange * Math.cos(this.angle),
y: this.position.y + seeRange * Math.sin(this.angle)
};
vertexCollision(this.position, look, map);
vertexCollision(this.position, look, body);
best = vertexCollision(this.position, look, [map, body]);
if (best.dist2 != Infinity) {
if (Math.random() > 0.5) {
this.springTarget.x = best.x;
@@ -1135,32 +1052,8 @@ const mobs = {
dmg *= tech.damageFromTech()
if (this.isDropPowerUp) {
if (this.health === 1) {
if (tech.isMobFullHealth) {
dmg *= 1.55
simulation.ephemera.push({
name: "damage outline",
count: 5, //cycles before it self removes
vertices: this.vertices,
do() {
this.count--
if (this.count < 0) simulation.removeEphemera(this.name)
//draw body
ctx.beginPath();
const vertices = this.vertices;
ctx.moveTo(vertices[0].x, vertices[0].y);
for (let j = 1, len = vertices.length; j < len; ++j) {
ctx.lineTo(vertices[j].x, vertices[j].y);
}
ctx.lineTo(vertices[0].x, vertices[0].y);
ctx.lineWidth = 3 //60 * (0.25 - this.damageReductionGoal)
ctx.strokeStyle = `#f05` //"rgba(150,150,225,0.5)";
ctx.stroke();
},
})
} else if (tech.isMobFullHealthCloak) {
dmg *= 1.88
if (tech.isMobFullHealthCloak) {
dmg *= 2.11
simulation.ephemera.push({
name: "damage outline",
count: 7, //cycles before it self removes