Skip to content

Commit cbea32d

Browse files
committed
Add ramming events, ordnance shortcuts, velocity labels, and ship type sizing
- Separate 'ramming' event type from 'crash' for clearer log messages - Ramming events now show die roll and damage result in log and toast - Ship icons scaled by combat value (larger ships render bigger) - Enemy velocity vectors show speed label at midpoint - Keyboard shortcuts for ordnance: N=mine, T=torpedo, K=nuke - Help overlay updated with ordnance section - Ghost ship at destination uses correct ship type sizing
1 parent 9f0e5eb commit cbea32d

File tree

7 files changed

+39
-6
lines changed

7 files changed

+39
-6
lines changed

src/client/main.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ class GameClient {
115115
this.sendSkipCombat();
116116
}
117117
}
118+
} else if (e.key.toLowerCase() === 'n' && this.state === 'playing_ordnance') {
119+
this.sendOrdnanceLaunch('mine');
120+
} else if (e.key.toLowerCase() === 't' && this.state === 'playing_ordnance') {
121+
this.sendOrdnanceLaunch('torpedo');
122+
} else if (e.key.toLowerCase() === 'k' && this.state === 'playing_ordnance') {
123+
this.sendOrdnanceLaunch('nuke');
118124
} else if (e.key >= '1' && e.key <= '6' && this.state === 'playing_astrogation') {
119125
// Number keys 1-6 for burn directions
120126
this.setBurnDirection(parseInt(e.key) - 1);

src/client/renderer.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,10 @@ export class Renderer {
754754
const to = hexToPixel(predicted, HEX_SIZE);
755755

756756
// Velocity vector — thin dashed line
757+
const speed = hexVecLength(ship.velocity);
757758
if (predicted.q !== ship.position.q || predicted.r !== ship.position.r) {
758-
ctx.strokeStyle = ship.owner === this.playerId
759+
const isOwn = ship.owner === this.playerId;
760+
ctx.strokeStyle = isOwn
759761
? 'rgba(79, 195, 247, 0.3)'
760762
: 'rgba(255, 152, 0, 0.3)';
761763
ctx.lineWidth = 1;
@@ -765,6 +767,16 @@ export class Renderer {
765767
ctx.lineTo(to.x, to.y);
766768
ctx.stroke();
767769
ctx.setLineDash([]);
770+
771+
// Speed label at midpoint for detected enemy ships
772+
if (!isOwn && speed >= 1) {
773+
const mx = (from.x + to.x) / 2;
774+
const my = (from.y + to.y) / 2;
775+
ctx.fillStyle = 'rgba(255, 152, 0, 0.5)';
776+
ctx.font = '7px monospace';
777+
ctx.textAlign = 'center';
778+
ctx.fillText(`v${Math.round(speed)}`, mx, my - 5);
779+
}
768780
}
769781
}
770782

@@ -823,7 +835,7 @@ export class Renderer {
823835

824836
// Ghost ship at destination
825837
if (!course.crashed) {
826-
this.drawShipIcon(ctx, to.x, to.y, ship.owner, 0.4, 0);
838+
this.drawShipIcon(ctx, to.x, to.y, ship.owner, 0.4, 0, 0, ship.type);
827839
}
828840

829841
// Burn direction arrows (when selected)
@@ -1493,6 +1505,10 @@ export class Renderer {
14931505
text = `${shipName}: CRASHED`;
14941506
color = '#ff4444';
14951507
break;
1508+
case 'ramming':
1509+
text = `${shipName}: RAMMED [${ev.dieRoll}] — ${ev.damageType === 'eliminated' ? 'ELIMINATED' : ev.damageType === 'disabled' ? `DISABLED ${ev.disabledTurns}T` : 'NO DAMAGE'}`;
1510+
color = ev.damageType === 'eliminated' ? '#ff4444' : ev.damageType === 'disabled' ? '#ffaa00' : '#88ff88';
1511+
break;
14961512
case 'asteroidHit':
14971513
text = `${shipName}: Asteroid hit [${ev.dieRoll}] — ${ev.damageType === 'eliminated' ? 'ELIMINATED' : ev.damageType === 'disabled' ? `DISABLED ${ev.disabledTurns}T` : 'MISS'}`;
14981514
color = ev.damageType === 'eliminated' ? '#ff4444' : ev.damageType === 'disabled' ? '#ffaa00' : '#88ff88';

src/client/ui.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,10 @@ export class UIManager {
379379
text = `${name} crashed!`;
380380
cls = 'log-eliminated';
381381
break;
382+
case 'ramming':
383+
text = `${name}: RAMMED [${ev.dieRoll}] ${ev.damageType === 'eliminated' ? '— ELIMINATED' : ev.damageType === 'disabled' ? `— D${ev.disabledTurns}` : '— no damage'}`;
384+
cls = ev.damageType === 'eliminated' ? 'log-eliminated' : ev.damageType === 'disabled' ? 'log-damage' : '';
385+
break;
382386
case 'asteroidHit':
383387
text = `${name}: asteroid [${ev.dieRoll}] ${ev.damageType === 'eliminated' ? '— ELIMINATED' : ev.damageType === 'disabled' ? `— D${ev.disabledTurns}` : '— miss'}`;
384388
cls = ev.damageType === 'eliminated' ? 'log-eliminated' : ev.damageType === 'disabled' ? 'log-damage' : '';

src/shared/__tests__/game-engine.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -648,8 +648,8 @@ describe('ramming', () => {
648648
const s1 = result.state.ships[1];
649649
if (hexEqual(s0.position, s1.position)) {
650650
// Should have ram events
651-
const crashEvents = result.events.filter(e => e.type === 'crash');
652-
expect(crashEvents.length).toBeGreaterThan(0);
651+
const ramEvents = result.events.filter(e => e.type === 'ramming');
652+
expect(ramEvents.length).toBeGreaterThan(0);
653653
}
654654
});
655655
});

src/shared/game-engine.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,7 @@ function checkRamming(
655655
const dieRoll = rollD6(rng);
656656
const result = lookupOtherDamage(dieRoll);
657657
events.push({
658-
type: 'crash',
658+
type: 'ramming',
659659
shipId: ship.id,
660660
hex: ship.position,
661661
dieRoll,

src/shared/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ export interface CombatResult {
163163
// --- Movement events (asteroid hazards, etc.) ---
164164

165165
export interface MovementEvent {
166-
type: 'asteroidHit' | 'crash' | 'mineDetonation' | 'torpedoHit' | 'nukeDetonation';
166+
type: 'asteroidHit' | 'crash' | 'ramming' | 'mineDetonation' | 'torpedoHit' | 'nukeDetonation';
167167
shipId: string;
168168
hex: HexCoord;
169169
dieRoll: number;

static/index.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,13 @@ <h3>Astrogation</h3>
131131
<div class="help-row"><span class="help-key">Tab</span> Cycle ships</div>
132132
<div class="help-row"><span class="help-key">Enter</span> Confirm</div>
133133
</div>
134+
<div class="help-section">
135+
<h3>Ordnance</h3>
136+
<div class="help-row"><span class="help-key">N</span> Launch mine</div>
137+
<div class="help-row"><span class="help-key">T</span> Launch torpedo</div>
138+
<div class="help-row"><span class="help-key">K</span> Launch nuke</div>
139+
<div class="help-row"><span class="help-key">Enter</span> Skip</div>
140+
</div>
134141
<div class="help-section">
135142
<h3>Combat</h3>
136143
<div class="help-row"><span class="help-key">Click enemy</span> Target</div>

0 commit comments

Comments
 (0)