gunnery
Shot flight and hit resolution for *Ninja Pirates of the Baltic*, in both directions. Part of SLICE A (the raid); `game.raid` is the only thing that requires it.
gunnery
Shot flight and hit resolution for Ninja Pirates of the Baltic, in both
directions. Part of SLICE A (the raid); game.raid is the only thing that
requires it.
local Gunnery = require("game.raid.gunnery")
local g = Gunnery.create(NPB, hooks)
hooks supplies the world the shots resolve against:
| hook | |
|---|---|
raiders() | the live raider records |
boatPos() | the player's position, or nil |
hitRaider(rec, amount) | a shot from the player connected |
hitPlayer(amount, x, z) | a shot from a raider connected |
What it does
playerVolley(fx, fz, dx, dz, cfg) and raiderVolley(fx, fz, tx, tz, tvx, tvz, cfg)
each put cfg.count round shot in the air, fanned across cfg.spread either
side of the bearing. A raider's volley is laid on where the player will be when
the shot arrives rather than where the player is.
update(dt) flies every shot, resolves it against the other side, and retires
it when it connects, runs out of range, or leaves the play area. Shots ride the
same waves everything else does.
Two things it is careful about
Each shot keeps its own logical x / z. What goes onto the entity is that
plus the wave's horizontal displacement; the entity is never read back, because
the shove would compound into the shot's course.
A hit can end the run, and ending the run clears every shot in flight — from inside the loop that is walking them. The loop stops as soon as it finds the list gone from under it, and the raid slice defers the clear to after the update for the same reason.
Scoped to this part · feeds back into the world's score.