export const PLAYER_MAX_HULL = 100; export const DEFAULT_PIRATE_SHOT_DAMAGE = 6; export const normalizePlayerDamage = ( rawDamage, fallback = DEFAULT_PIRATE_SHOT_DAMAGE, ) => { const parsed = Number(rawDamage); const value = Number.isFinite(parsed) ? parsed : fallback; return Math.max(1, Math.min(25, value)); }; export const reducePlayerProjectileHits = ({ hull, hits, maxHull = PLAYER_MAX_HULL, fallbackDamage = DEFAULT_PIRATE_SHOT_DAMAGE, }) => { const currentHull = Number.isFinite(hull) ? hull : maxHull; const totalDamage = hits.reduce( (sum, hit) => sum + normalizePlayerDamage(hit?.damage, fallbackDamage), 0, ); const nextHull = Math.max(0, currentHull - totalDamage); return { hull: nextHull, totalDamage, appliedHits: hits.length, gameOver: nextHull <= 0, }; }; export const resolveTaggedProjectile = (first, second, owner) => { for (const candidate of [first, second]) { if (!candidate || typeof candidate.getData !== 'function') continue; if (candidate.getData('projectileOwner') === owner) return candidate; } return null; };