Boat attack event (#177)

Allow user to focus on outgoing boats

Partial #133 


https://github.com/user-attachments/assets/0e287bf5-71bb-4def-a3ca-f0b652ed6d69
This commit is contained in:
Maeght Loan
2025-03-08 10:44:27 -08:00
committed by GitHub
parent afe4f85919
commit e1ed8dbe36
3 changed files with 61 additions and 8 deletions
+11 -1
View File
@@ -6,7 +6,7 @@ import {
calculateBoundingBoxCenter, calculateBoundingBoxCenter,
} from "../../core/Util"; } from "../../core/Util";
import { ZoomEvent, DragEvent, CenterCameraEvent } from "../InputHandler"; import { ZoomEvent, DragEvent, CenterCameraEvent } from "../InputHandler";
import { GoToPlayerEvent } from "./layers/Leaderboard"; import { GoToPlayerEvent, GoToUnitEvent } from "./layers/Leaderboard";
import { placeName } from "./NameBoxCalculator"; import { placeName } from "./NameBoxCalculator";
import { GameView } from "../../core/game/GameView"; import { GameView } from "../../core/game/GameView";
@@ -27,6 +27,7 @@ export class TransformHandler {
this.eventBus.on(ZoomEvent, (e) => this.onZoom(e)); this.eventBus.on(ZoomEvent, (e) => this.onZoom(e));
this.eventBus.on(DragEvent, (e) => this.onMove(e)); this.eventBus.on(DragEvent, (e) => this.onMove(e));
this.eventBus.on(GoToPlayerEvent, (e) => this.onGoToPlayer(e)); this.eventBus.on(GoToPlayerEvent, (e) => this.onGoToPlayer(e));
this.eventBus.on(GoToUnitEvent, (e) => this.onGoToUnit(e));
this.eventBus.on(CenterCameraEvent, () => this.centerCamera()); this.eventBus.on(CenterCameraEvent, () => this.centerCamera());
} }
@@ -149,6 +150,15 @@ export class TransformHandler {
this.intervalID = setInterval(() => this.goTo(), 1); this.intervalID = setInterval(() => this.goTo(), 1);
} }
onGoToUnit(event: GoToUnitEvent) {
this.clearTarget();
this.target = new Cell(
this.game.x(event.unit.lastTile()),
this.game.y(event.unit.lastTile()),
);
this.intervalID = setInterval(() => this.goTo(), 1);
}
centerCamera() { centerCamera() {
this.clearTarget(); this.clearTarget();
const player = this.game.myPlayer(); const player = this.game.myPlayer();
+43 -4
View File
@@ -6,6 +6,7 @@ import {
MessageType, MessageType,
PlayerType, PlayerType,
Tick, Tick,
UnitType,
} from "../../../core/game/Game"; } from "../../../core/game/Game";
import { import {
AttackUpdate, AttackUpdate,
@@ -28,9 +29,9 @@ import { unsafeHTML, UnsafeHTMLDirective } from "lit/directives/unsafe-html.js";
import { DirectiveResult } from "lit/directive.js"; import { DirectiveResult } from "lit/directive.js";
import { onlyImages, sanitize } from "../../../core/Util"; import { onlyImages, sanitize } from "../../../core/Util";
import { GameView, PlayerView } from "../../../core/game/GameView"; import { GameView, PlayerView, UnitView } from "../../../core/game/GameView";
import { renderTroops } from "../../Utils"; import { renderTroops } from "../../Utils";
import { GoToPlayerEvent } from "./Leaderboard"; import { GoToPlayerEvent, GoToUnitEvent } from "./Leaderboard";
interface Event { interface Event {
description: string; description: string;
@@ -60,6 +61,7 @@ export class EventsDisplay extends LitElement implements Layer {
private events: Event[] = []; private events: Event[] = [];
@state() private incomingAttacks: AttackUpdate[] = []; @state() private incomingAttacks: AttackUpdate[] = [];
@state() private outgoingAttacks: AttackUpdate[] = []; @state() private outgoingAttacks: AttackUpdate[] = [];
@state() private outgoingBoats: UnitView[] = [];
@state() private _hidden: boolean = false; @state() private _hidden: boolean = false;
@state() private newEvents: number = 0; @state() private newEvents: number = 0;
@@ -88,6 +90,7 @@ export class EventsDisplay extends LitElement implements Layer {
this.events = []; this.events = [];
this.incomingAttacks = []; this.incomingAttacks = [];
this.outgoingAttacks = []; this.outgoingAttacks = [];
this.outgoingBoats = [];
} }
init() {} init() {}
@@ -131,6 +134,11 @@ export class EventsDisplay extends LitElement implements Layer {
.outgoingAttacks() .outgoingAttacks()
.filter((a) => a.targetID != 0); .filter((a) => a.targetID != 0);
this.outgoingBoats = myPlayer
.units()
.filter((u) => u.type() === UnitType.TransportShip);
console.log("loan", this.outgoingBoats);
this.requestUpdate(); this.requestUpdate();
} }
@@ -322,6 +330,10 @@ export class EventsDisplay extends LitElement implements Layer {
this.eventBus.emit(new GoToPlayerEvent(attacker)); this.eventBus.emit(new GoToPlayerEvent(attacker));
} }
emitGoToUnitEvent(unit: UnitView) {
this.eventBus.emit(new GoToUnitEvent(unit));
}
onEmojiMessageEvent(update: EmojiUpdate) { onEmojiMessageEvent(update: EmojiUpdate) {
const myPlayer = this.game.playerByClientID(this.clientID); const myPlayer = this.game.playerByClientID(this.clientID);
if (!myPlayer) return; if (!myPlayer) return;
@@ -448,11 +460,38 @@ export class EventsDisplay extends LitElement implements Layer {
`; `;
} }
private renderBoats() {
if (this.outgoingBoats.length === 0) {
return html``;
}
return html`
${this.outgoingBoats.length > 0
? html`
<tr class="border-t border-gray-700">
<td
class="lg:p-3 p-1 text-left text-blue-400 grid grid-cols-3 gap-2"
>
${this.outgoingBoats.map(
(boats) => html`
<button @click=${() => this.emitGoToUnitEvent(boats)}>
Boat: ${renderTroops(boats.troops())}
</button>
`,
)}
</td>
</tr>
`
: ""}
`;
}
render() { render() {
if ( if (
this.events.length === 0 && this.events.length === 0 &&
this.incomingAttacks.length === 0 && this.incomingAttacks.length === 0 &&
this.outgoingAttacks.length === 0 this.outgoingAttacks.length === 0 &&
this.outgoingBoats.length === 0
) { ) {
return html``; return html``;
} }
@@ -553,7 +592,7 @@ export class EventsDisplay extends LitElement implements Layer {
</tr> </tr>
`, `,
)} )}
${this.renderAttacks()} ${this.renderAttacks()} ${this.renderBoats()}
</tbody> </tbody>
</table> </table>
</div> </div>
+7 -3
View File
@@ -2,7 +2,7 @@ import { LitElement, css, html } from "lit";
import { customElement, state } from "lit/decorators.js"; import { customElement, state } from "lit/decorators.js";
import { unsafeHTML } from "lit/directives/unsafe-html.js"; import { unsafeHTML } from "lit/directives/unsafe-html.js";
import { EventBus, GameEvent } from "../../../core/EventBus"; import { EventBus, GameEvent } from "../../../core/EventBus";
import { GameView, PlayerView } from "../../../core/game/GameView"; import { GameView, PlayerView, UnitView } from "../../../core/game/GameView";
import { ClientID } from "../../../core/Schemas"; import { ClientID } from "../../../core/Schemas";
import { renderNumber } from "../../Utils"; import { renderNumber } from "../../Utils";
import { Layer } from "./Layer"; import { Layer } from "./Layer";
@@ -21,6 +21,10 @@ export class GoToPlayerEvent implements GameEvent {
constructor(public player: PlayerView) {} constructor(public player: PlayerView) {}
} }
export class GoToUnitEvent implements GameEvent {
constructor(public unit: UnitView) {}
}
@customElement("leader-board") @customElement("leader-board")
export class Leaderboard extends LitElement implements Layer { export class Leaderboard extends LitElement implements Layer {
public game: GameView; public game: GameView;
@@ -116,7 +120,7 @@ export class Leaderboard extends LitElement implements Layer {
this.requestUpdate(); this.requestUpdate();
} }
private handleRowClick(player: PlayerView) { private handleRowClickPlayer(player: PlayerView) {
this.eventBus.emit(new GoToPlayerEvent(player)); this.eventBus.emit(new GoToPlayerEvent(player));
} }
@@ -274,7 +278,7 @@ export class Leaderboard extends LitElement implements Layer {
(player) => html` (player) => html`
<tr <tr
class="${player.isMyPlayer ? "myPlayer" : "otherPlayer"}" class="${player.isMyPlayer ? "myPlayer" : "otherPlayer"}"
@click=${() => this.handleRowClick(player.player)} @click=${() => this.handleRowClickPlayer(player.player)}
> >
<td>${player.position}</td> <td>${player.position}</td>
<td class="player-name">${unsafeHTML(player.name)}</td> <td class="player-name">${unsafeHTML(player.name)}</td>