Fix replay error alert, plan attack visualization feature
Replace native alert() calls in replay.ts URL/file load error handlers with inline error display in the no-replay div. Add combat attack direction visualization to §16.9 of the plan: engine emits combat_death events with killer bot list; viewer draws directed arrows on kills. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
a312a9bf3d
commit
250140d0f7
2 changed files with 8 additions and 2 deletions
|
|
@ -4994,6 +4994,7 @@ smoothly between grid positions instead of teleporting.
|
|||
| Bot idle | Subtle 2% scale pulse, 2s cycle. Stops on movement. | Continuous |
|
||||
| Bot movement | 1-tile motion trail fading behind the bot, indicates direction of travel. At high speed, trails create visible flow patterns. | 150ms fade |
|
||||
| Combat threat | Thin dashed line between bots within attack range (red). Shows who threatens whom. | 1 turn |
|
||||
| Attack event | Directed arrows from each attacker to the dying bot's tile on the turn a combat kill lands. The Go engine's `executeCombat()` needs to emit a `combat_death` event (type constant already exists: `EventCombatDeath`) alongside each `bot_died`, listing `killers: [{bot_id, owner, position}]` — the enemies within attack radius that triggered the outnumbering condition. The web viewer reads `combat_death` events and draws a solid line (attacker player color, arrowhead) from each killer's tile center to the defender's tile center, fading over 300ms. Old replays lacking `combat_death` events keep the existing proximity-inference lines. Distinct from the ambient threat dashes — these fire only on actual kills and encode exact participants rather than spatial proximity. | 300ms fade |
|
||||
| Bot death | Burst of 6–8 particles scattering outward from death position, fading to transparent. | 400ms |
|
||||
| Energy collection | 4-line starburst radiating from the energy node + small "+1" text floating upward. | 200ms |
|
||||
| Core capture | Radial shockwave ring expanding from the core. Core color transitions from loser to capturer. | 500ms |
|
||||
|
|
|
|||
|
|
@ -1349,6 +1349,11 @@ function initReplayViewer(ReplayViewerClass: any, initialUrl?: string): void {
|
|||
prevCriticalBtn.addEventListener('click', navigateToPrevCriticalMoment);
|
||||
nextCriticalBtn.addEventListener('click', navigateToNextCriticalMoment);
|
||||
|
||||
function showLoadError(msg: string): void {
|
||||
noReplayDiv.style.display = '';
|
||||
noReplayDiv.innerHTML = `<span style="color:#f87171">${escapeHtml(String(msg))}</span>`;
|
||||
}
|
||||
|
||||
fileInput.addEventListener('change', async (e) => {
|
||||
const file = (e.target as HTMLInputElement).files?.[0];
|
||||
if (!file) return;
|
||||
|
|
@ -1357,7 +1362,7 @@ function initReplayViewer(ReplayViewerClass: any, initialUrl?: string): void {
|
|||
const replay = JSON.parse(text) as Replay;
|
||||
loadReplay(replay);
|
||||
} catch (err) {
|
||||
alert('Failed to load replay: ' + err);
|
||||
showLoadError('Failed to load replay: ' + err);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -1370,7 +1375,7 @@ function initReplayViewer(ReplayViewerClass: any, initialUrl?: string): void {
|
|||
const replay = await response.json() as Replay;
|
||||
loadReplay(replay);
|
||||
} catch (err) {
|
||||
alert('Failed to load replay from URL: ' + err);
|
||||
showLoadError('Failed to load replay from URL: ' + err);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue