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 19:44:27 +01: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,
} from "../../core/Util";
import { ZoomEvent, DragEvent, CenterCameraEvent } from "../InputHandler";
import { GoToPlayerEvent } from "./layers/Leaderboard";
import { GoToPlayerEvent, GoToUnitEvent } from "./layers/Leaderboard";
import { placeName } from "./NameBoxCalculator";
import { GameView } from "../../core/game/GameView";
@@ -27,6 +27,7 @@ export class TransformHandler {
this.eventBus.on(ZoomEvent, (e) => this.onZoom(e));
this.eventBus.on(DragEvent, (e) => this.onMove(e));
this.eventBus.on(GoToPlayerEvent, (e) => this.onGoToPlayer(e));
this.eventBus.on(GoToUnitEvent, (e) => this.onGoToUnit(e));
this.eventBus.on(CenterCameraEvent, () => this.centerCamera());
}
@@ -149,6 +150,15 @@ export class TransformHandler {
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() {
this.clearTarget();
const player = this.game.myPlayer();
+43 -4
View File
@@ -6,6 +6,7 @@ import {
MessageType,
PlayerType,
Tick,
UnitType,
} from "../../../core/game/Game";
import {
AttackUpdate,
@@ -28,9 +29,9 @@ import { unsafeHTML, UnsafeHTMLDirective } from "lit/directives/unsafe-html.js";
import { DirectiveResult } from "lit/directive.js";
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 { GoToPlayerEvent } from "./Leaderboard";
import { GoToPlayerEvent, GoToUnitEvent } from "./Leaderboard";
interface Event {
description: string;
@@ -60,6 +61,7 @@ export class EventsDisplay extends LitElement implements Layer {
private events: Event[] = [];
@state() private incomingAttacks: AttackUpdate[] = [];
@state() private outgoingAttacks: AttackUpdate[] = [];
@state() private outgoingBoats: UnitView[] = [];
@state() private _hidden: boolean = false;
@state() private newEvents: number = 0;
@@ -88,6 +90,7 @@ export class EventsDisplay extends LitElement implements Layer {
this.events = [];
this.incomingAttacks = [];
this.outgoingAttacks = [];
this.outgoingBoats = [];
}
init() {}
@@ -131,6 +134,11 @@ export class EventsDisplay extends LitElement implements Layer {
.outgoingAttacks()
.filter((a) => a.targetID != 0);
this.outgoingBoats = myPlayer
.units()
.filter((u) => u.type() === UnitType.TransportShip);
console.log("loan", this.outgoingBoats);
this.requestUpdate();
}
@@ -322,6 +330,10 @@ export class EventsDisplay extends LitElement implements Layer {
this.eventBus.emit(new GoToPlayerEvent(attacker));
}
emitGoToUnitEvent(unit: UnitView) {
this.eventBus.emit(new GoToUnitEvent(unit));
}
onEmojiMessageEvent(update: EmojiUpdate) {
const myPlayer = this.game.playerByClientID(this.clientID);
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() {
if (
this.events.length === 0 &&
this.incomingAttacks.length === 0 &&
this.outgoingAttacks.length === 0
this.outgoingAttacks.length === 0 &&
this.outgoingBoats.length === 0
) {
return html``;
}
@@ -553,7 +592,7 @@ export class EventsDisplay extends LitElement implements Layer {
</tr>
`,
)}
${this.renderAttacks()}
${this.renderAttacks()} ${this.renderBoats()}
</tbody>
</table>
</div>
+7 -3
View File
@@ -2,7 +2,7 @@ import { LitElement, css, html } from "lit";
import { customElement, state } from "lit/decorators.js";
import { unsafeHTML } from "lit/directives/unsafe-html.js";
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 { renderNumber } from "../../Utils";
import { Layer } from "./Layer";
@@ -21,6 +21,10 @@ export class GoToPlayerEvent implements GameEvent {
constructor(public player: PlayerView) {}
}
export class GoToUnitEvent implements GameEvent {
constructor(public unit: UnitView) {}
}
@customElement("leader-board")
export class Leaderboard extends LitElement implements Layer {
public game: GameView;
@@ -116,7 +120,7 @@ export class Leaderboard extends LitElement implements Layer {
this.requestUpdate();
}
private handleRowClick(player: PlayerView) {
private handleRowClickPlayer(player: PlayerView) {
this.eventBus.emit(new GoToPlayerEvent(player));
}
@@ -274,7 +278,7 @@ export class Leaderboard extends LitElement implements Layer {
(player) => html`
<tr
class="${player.isMyPlayer ? "myPlayer" : "otherPlayer"}"
@click=${() => this.handleRowClick(player.player)}
@click=${() => this.handleRowClickPlayer(player.player)}
>
<td>${player.position}</td>
<td class="player-name">${unsafeHTML(player.name)}</td>