diff --git a/src/mobile-hud.js b/src/mobile-hud.js index 5e86af3..777da56 100644 --- a/src/mobile-hud.js +++ b/src/mobile-hud.js @@ -263,6 +263,29 @@ if (!isDesktopPointer.matches) { clip-path: circle(49% at 50% 50%); } + .steam-reload-track { + position: absolute; + left: 12%; + right: 12%; + bottom: -7%; + height: 5px; + border: 1px solid rgba(232, 184, 91, .42); + border-radius: 999px; + background: rgba(8, 25, 31, .72); + overflow: hidden; + pointer-events: none; + } + + .steam-reload-fill { + display: block; + width: 100%; + height: 100%; + transform: scaleX(1); + transform-origin: left center; + background: rgba(255, 224, 140, .92); + transition: transform 60ms linear; + } + .steam-action-label { position: absolute; left: 50%; @@ -566,7 +589,7 @@ if (!isDesktopPointer.matches) { `); const enemyHealthPiece = addHealthPiece('steam-enemy-card', enemyHealthSrc, ` - PIRATE + PIRATE CLEAR `); @@ -601,10 +624,12 @@ if (!isDesktopPointer.matches) { addPiece('steam-cannon-port', cannonRoundelSrc, ` PORT + `); addPiece('steam-cannon-starboard', cannonRoundelSrc, ` STBD + `); const status = document.createElement('div'); @@ -713,6 +738,8 @@ if (!isDesktopPointer.matches) { const range = nearest.range; const playerHull = Math.max(0, scene.playerHull ?? 100); const enemyHull = pirate ? Math.max(0, pirate.getData?.('hull') ?? 0) : 0; + const enemyMaxHull = pirate ? Math.max(1, pirate.getData?.('maxHull') ?? 120) : 120; + const enemyName = pirate ? (pirate.getData?.('classLabel') || 'PIRATE') : 'PIRATE'; fields.speed.textContent = `${Math.abs(scene.playerSpeed || 0).toFixed(0)}${scene.playerSpeed < 0 ? 'R' : ''}`; fields.heading.textContent = `${heading.toFixed(0).padStart(3, '0')}°`; @@ -721,7 +748,8 @@ if (!isDesktopPointer.matches) { fields.kills.textContent = String(scene.defeated || 0); fields.range.textContent = Number.isFinite(range) ? `${Math.round(range)}m` : '--'; fields['player-hull'].textContent = `${playerHull}/100`; - fields['enemy-hull'].textContent = pirate ? `${enemyHull}/120` : 'CLEAR'; + fields['enemy-name'].textContent = enemyName; + fields['enemy-hull'].textContent = pirate ? `${enemyHull}/${enemyMaxHull}` : 'CLEAR'; const playerPct = clamp01(playerHull / 100); fields['player-health-cover'].style.width = `${(1 - playerPct) * 49}%`; fields['player-health-tint'].style.transform = `scaleX(${playerPct})`; @@ -730,7 +758,14 @@ if (!isDesktopPointer.matches) { : playerPct > 0.33 ? 'rgba(255, 210, 0, .58)' : 'rgba(255, 45, 18, .72)'; - setHealthFrame(enemyHealthPiece, pirate ? healthFrame(enemyHull, 120) : 11); + setHealthFrame(enemyHealthPiece, pirate ? healthFrame(enemyHull, enemyMaxHull) : 11); + + const reloadMs = Math.max(1, scene.playerBroadsideReloadMs || 850); + const now = scene.time?.now ?? 0; + const portReady = clamp01((now - (scene.lastPlayerShot?.port ?? -Infinity)) / reloadMs); + const starboardReady = clamp01((now - (scene.lastPlayerShot?.starboard ?? -Infinity)) / reloadMs); + fields['port-reload'].style.transform = `scaleX(${portReady})`; + fields['starboard-reload'].style.transform = `scaleX(${starboardReady})`; const statusText = scene.status?.text?.trim?.() || ''; fields.status.textContent = statusText;