diff --git a/src/client/graphics/layers/EventsDisplay.ts b/src/client/graphics/layers/EventsDisplay.ts
index d1d705502..34eb7ee02 100644
--- a/src/client/graphics/layers/EventsDisplay.ts
+++ b/src/client/graphics/layers/EventsDisplay.ts
@@ -21,6 +21,7 @@ import {
EmojiUpdate,
GameUpdateType,
TargetPlayerUpdate,
+ UnitIncomingUpdate,
} from "../../../core/game/GameUpdates";
import { ClientID } from "../../../core/Schemas";
import {
@@ -53,6 +54,7 @@ interface Event {
priority?: number;
duration?: Tick;
focusID?: number;
+ unitView?: UnitView;
}
@customElement("events-display")
@@ -89,6 +91,7 @@ export class EventsDisplay extends LitElement implements Layer {
[GameUpdateType.BrokeAlliance, (u) => this.onBrokeAllianceEvent(u)],
[GameUpdateType.TargetPlayer, (u) => this.onTargetPlayerEvent(u)],
[GameUpdateType.Emoji, (u) => this.onEmojiMessageEvent(u)],
+ [GameUpdateType.UnitIncoming, (u) => this.onUnitIncomingEvent(u)],
]);
constructor() {
@@ -421,6 +424,28 @@ export class EventsDisplay extends LitElement implements Layer {
}
}
+ onUnitIncomingEvent(event: UnitIncomingUpdate) {
+ const myPlayer = this.game.playerByClientID(this.clientID);
+
+ if (
+ event.playerID != null &&
+ (!myPlayer || myPlayer.smallID() !== event.playerID)
+ ) {
+ return;
+ }
+
+ const unitView = this.game.unit(event.unitID);
+
+ this.addEvent({
+ description: event.message,
+ type: event.messageType,
+ unsafeDescription: false,
+ highlight: true,
+ createdAt: this.game.ticks(),
+ unitView: unitView,
+ });
+ }
+
private getMessageTypeClasses(type: MessageType): string {
switch (type) {
case MessageType.SUCCESS:
@@ -645,7 +670,15 @@ export class EventsDisplay extends LitElement implements Layer {
>
${this.getEventDescription(event)}
`
- : this.getEventDescription(event)}
+ : event.unitView
+ ? html``
+ : this.getEventDescription(event)}
${event.buttons
? html`
diff --git a/src/core/execution/MIRVExecution.ts b/src/core/execution/MIRVExecution.ts
index 61b38df81..3a960d86a 100644
--- a/src/core/execution/MIRVExecution.ts
+++ b/src/core/execution/MIRVExecution.ts
@@ -81,7 +81,8 @@ export class MirvExecution implements Execution {
this.separateDst = this.mg.ref(x, y);
this.pathFinder.computeControlPoints(spawn, this.separateDst);
- this.mg.displayMessage(
+ this.mg.displayIncomingUnit(
+ this.nuke.id(),
`⚠️⚠️⚠️ ${this.player.name()} - MIRV INBOUND ⚠️⚠️⚠️`,
MessageType.ERROR,
this.targetPlayer.id(),
diff --git a/src/core/execution/NukeExecution.ts b/src/core/execution/NukeExecution.ts
index 4572eefc5..e0333f626 100644
--- a/src/core/execution/NukeExecution.ts
+++ b/src/core/execution/NukeExecution.ts
@@ -106,14 +106,16 @@ export class NukeExecution implements Execution {
if (this.mg.hasOwner(this.dst)) {
const target = this.mg.owner(this.dst) as Player;
if (this.type == UnitType.AtomBomb) {
- this.mg.displayMessage(
+ this.mg.displayIncomingUnit(
+ this.nuke.id(),
`${this.player.name()} - atom bomb inbound`,
MessageType.ERROR,
target.id(),
);
}
if (this.type == UnitType.HydrogenBomb) {
- this.mg.displayMessage(
+ this.mg.displayIncomingUnit(
+ this.nuke.id(),
`${this.player.name()} - hydrogen bomb inbound`,
MessageType.ERROR,
target.id(),
@@ -129,7 +131,7 @@ export class NukeExecution implements Execution {
);
}
- // after sending an nuke set the missilesilo on cooldown
+ // after sending a nuke set the missilesilo on cooldown
const silo = this.player
.units(UnitType.MissileSilo)
.find((silo) => silo.tile() === spawn);
diff --git a/src/core/execution/TransportShipExecution.ts b/src/core/execution/TransportShipExecution.ts
index 0194c895d..9b8dfc27d 100644
--- a/src/core/execution/TransportShipExecution.ts
+++ b/src/core/execution/TransportShipExecution.ts
@@ -67,15 +67,6 @@ export class TransportShipExecution implements Execution {
this.attacker = mg.player(this.attackerID);
- // Notify the target player about the incoming naval invasion
- if (this.targetID && this.targetID !== mg.terraNullius().id()) {
- mg.displayMessage(
- `Naval invasion incoming from ${this.attacker.displayName()}`,
- MessageType.WARN,
- this.targetID,
- );
- }
-
if (
this.attacker.units(UnitType.TransportShip).length >=
mg.config().boatMaxNumber()
@@ -142,6 +133,16 @@ export class TransportShipExecution implements Execution {
this.boat = this.attacker.buildUnit(UnitType.TransportShip, this.src, {
troops: this.troops,
});
+
+ // Notify the target player about the incoming naval invasion
+ if (this.targetID && this.targetID !== mg.terraNullius().id()) {
+ mg.displayIncomingUnit(
+ this.boat.id(),
+ `Naval invasion incoming from ${this.attacker.displayName()}`,
+ MessageType.WARN,
+ this.targetID,
+ );
+ }
}
tick(ticks: number) {
diff --git a/src/core/game/Game.ts b/src/core/game/Game.ts
index 8eec8c263..bb57ca831 100644
--- a/src/core/game/Game.ts
+++ b/src/core/game/Game.ts
@@ -544,6 +544,12 @@ export interface Game extends GameMap {
type: MessageType,
playerID: PlayerID | null,
): void;
+ displayIncomingUnit(
+ unitID: number,
+ message: string,
+ type: MessageType,
+ playerID: PlayerID,
+ ): void;
displayChat(
message: string,
diff --git a/src/core/game/GameImpl.ts b/src/core/game/GameImpl.ts
index 698689537..1b88abad0 100644
--- a/src/core/game/GameImpl.ts
+++ b/src/core/game/GameImpl.ts
@@ -628,6 +628,24 @@ export class GameImpl implements Game {
recipient: recipient,
});
}
+
+ displayIncomingUnit(
+ unitID: number,
+ message: string,
+ type: MessageType,
+ playerID: PlayerID,
+ ): void {
+ const id = this.player(playerID).smallID();
+
+ this.addUpdate({
+ type: GameUpdateType.UnitIncoming,
+ unitID: unitID,
+ message: message,
+ messageType: type,
+ playerID: id,
+ });
+ }
+
addUnit(u: Unit) {
this.unitGrid.addUnit(u);
}
diff --git a/src/core/game/GameUpdates.ts b/src/core/game/GameUpdates.ts
index dc9b3e313..f9b3087d9 100644
--- a/src/core/game/GameUpdates.ts
+++ b/src/core/game/GameUpdates.ts
@@ -38,6 +38,7 @@ export enum GameUpdateType {
Emoji,
Win,
Hash,
+ UnitIncoming,
}
export type GameUpdate =
@@ -53,7 +54,8 @@ export type GameUpdate =
| TargetPlayerUpdate
| EmojiUpdate
| WinUpdate
- | HashUpdate;
+ | HashUpdate
+ | UnitIncomingUpdate;
export interface TileUpdateWrapper {
type: GameUpdateType.Tile;
@@ -182,3 +184,11 @@ export interface HashUpdate {
tick: Tick;
hash: number;
}
+
+export interface UnitIncomingUpdate {
+ type: GameUpdateType.UnitIncoming;
+ unitID: number;
+ message: string;
+ messageType: MessageType;
+ playerID: number;
+}