Fire the laser as light, and stop him jogging on the spot
The auto-fire jog was one guard. gameplay skipped the pose update in mgSteer mode, so the pose stuck on 'idle' -- and render covered for it by faking a run cycle off G.idleT, which animated whether he was moving or not. That fake is what read as "this hectic run animation... odd all the time". The pose follows MOVEMENT in every mode now and the fake is deleted, so auto-fire, the horde and the melee racket all use the ordinary run animation and standing still is standing still. The comment that justified the fake -- two rackets when idle -- was solving a smaller problem than it caused; at sprite scale the overlap does not read. The laser, second pass, all of it "it must read as light he fired": - it draws AFTER the net and every body. It was drawn before the far-side pass, so the net and the crowd painted over it, which is exactly why it looked like it was lying on the floor and sitting under the net. - beamLen 26 -> 34: at 26 it stopped just past the far baseline and read as cut off in mid-court. It carries into the courtside ads now. - beamW0 0.35 -> 0.06, a POINT at the strings. At 0.35 it left the racket as a 0.7 m bar hanging in mid-air instead of something emitted from it. - it DELETES ordinary bodies, hp irrelevant. A plane of light that left a roller man standing made it a worse ball, not a weapon. A boss is the exception and takes dmgBeam 8 -- severe, survivable. - four nested wedges composited 'lighter' (violet bloom, blue, cyan, white core), each fading along its length. One quad with a gradient was a coloured shape. Rocket: speed 17 -> 38, and a real jet plume laid tight ON the flight line rather than scattered sparks, which looked like a firework. Beacon: a finer one-pixel thread and a much brighter ball, so the BALL is the bright thing and the trail only says where it has been. And the bug in the middle of that: firePellet stamps a whitelist of fields onto the round, and jet/trailR went onto the WEAPONS rows without being added to the list -- so the rocket flew with no plume and nothing errored. Any new pellet field has to be added in both places. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
46e268973d
commit
91053b4c35
6 files changed
+151
-62
No files matched your search
+26
-12
@@ -314,10 +314,11 @@ export function fireBeam(dirX, dirZ) {
|
||||
const off = Math.abs(rx * uz - rz * ux); // lateral offset from the lane
|
||||
const halfW = TUNE.beamW0 + (TUNE.beamW1 - TUNE.beamW0) * (along / TUNE.beamLen);
|
||||
if (off > halfW + hitR(zb)) continue;
|
||||
// THE BEAM DELETES ORDINARY BODIES. hp does not enter into it: a plane of light that left a
|
||||
// roller man standing was the thing that made it feel like a worse ball rather than a weapon.
|
||||
// A BOSS is the exception and takes a heavy wound instead — "they also must suffer severely".
|
||||
if (isBoss(zb)) { if (wound(zb, TUNE.dmgBeam)) killZombie(i, true); }
|
||||
else if (zb.variant === 'o') killZombie(i, true); // it pops a barrel too, which is fair
|
||||
else if ((zb.hpMax || 0) > 1 && (zb.hp -= TUNE.dmgBeam) > 0) woundBurst(zb);
|
||||
else splatter(i);
|
||||
else killZombie(i, !!G.horde);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -573,7 +574,7 @@ export function firePellet(w = WEAPONS.gun) {
|
||||
const pe = { x: P.x, y: 0.9, z: P.z, vx: Math.sin(a) * s, vz: -Math.cos(a) * s,
|
||||
t: w.life ?? 1.2, r: w.r ?? TUNE.mgPelletR, dmg: w.dmg ?? TUNE.dmgPellet, hp: w.hp ?? TUNE.dmgPelletHp,
|
||||
pierce: !!w.pierce, boom: !!w.boom, ignite: w.ignite ? (w.igniteR ?? 1.8) : 0,
|
||||
trail: w.trail || 0, col: w.col, glow: w.glow };
|
||||
trail: w.trail || 0, trailR: w.trailR, jet: w.jet || 0, col: w.col, glow: w.glow };
|
||||
// A LOBBED round: it is thrown, not sprayed. Solved so it comes down about where the crowd is, so
|
||||
// "it throws itself" reads as aiming rather than as a flat stream that happens to be fat.
|
||||
if (w.arc) {
|
||||
@@ -952,15 +953,28 @@ export function updateZombies(dt) {
|
||||
pe.vy -= pe.g * dt; pe.y += pe.vy * dt;
|
||||
if (pe.y <= 0.05) { pe.y = 0.05; landed = true; }
|
||||
}
|
||||
// a colour dragged behind it — the beacon and the rocket are supposed to be seen from across
|
||||
// the court, and this is what makes a lobbed round read as a THROWN object rather than a dot
|
||||
if (pe.trail && parts.length < 220)
|
||||
// A JET PLUME, not a shower of sparks: the exhaust is laid down tight on the flight line,
|
||||
// barely moving, so it reads as a rocket motor drawing a line through the air. Scattered
|
||||
// sparks with their own velocities looked like a firework, which is not what a rocket does.
|
||||
if (pe.jet && parts.length < 240)
|
||||
for (let k = 0; k < pe.jet; k++) {
|
||||
const b = (k + Math.random()) / pe.jet; // spread ALONG this frame's step
|
||||
parts.push({
|
||||
x: pe.x - pe.vx * dt * b + (Math.random() * 2 - 1) * 0.05,
|
||||
y: pe.y - (pe.vy || 0) * dt * b + (Math.random() * 2 - 1) * 0.05,
|
||||
z: pe.z - pe.vz * dt * b + (Math.random() * 2 - 1) * 0.05,
|
||||
vx: 0, vy: 0.25, vz: 0, // it hangs and lifts, it does not fly off
|
||||
t: 0.30 + Math.random() * 0.30, jet: 1, spark: '#fff2c0' });
|
||||
}
|
||||
// ...and a FINE thread for the beacon: one small mote a frame, tight to the ball, so the ball
|
||||
// itself is the bright thing and the trail only says where it has been.
|
||||
if (pe.trail && parts.length < 240)
|
||||
for (let k = 0; k < pe.trail; k++) parts.push({
|
||||
x: pe.x + (Math.random() * 2 - 1) * 0.12, y: pe.y + (Math.random() * 2 - 1) * 0.12,
|
||||
z: pe.z + (Math.random() * 2 - 1) * 0.12,
|
||||
vx: (Math.random() * 2 - 1) * 0.5, vy: (Math.random() * 2 - 1) * 0.5 + 0.3,
|
||||
vz: (Math.random() * 2 - 1) * 0.5,
|
||||
t: 0.18 + Math.random() * 0.22, spark: pe.col || '#fff' });
|
||||
x: pe.x + (Math.random() * 2 - 1) * (pe.trailR ?? 0.12),
|
||||
y: pe.y + (Math.random() * 2 - 1) * (pe.trailR ?? 0.12),
|
||||
z: pe.z + (Math.random() * 2 - 1) * (pe.trailR ?? 0.12),
|
||||
vx: 0, vy: 0.12, vz: 0,
|
||||
t: 0.16 + Math.random() * 0.16, fine: 1, spark: pe.col || '#fff' });
|
||||
for (let j = zombies.length - 1; j >= 0; j--) {
|
||||
const zb = zombies[j];
|
||||
if (!zb) continue;
|
||||
|
||||
Reference in new issue
Block a user