diff --git a/.prettierignore b/.prettierignore index 8ae3f9b70..584bf56da 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,5 @@ *.bin +*.svg *.png *.jpg *.jpeg @@ -6,4 +7,4 @@ *.webp *.txt .prettierignore -.gitignore \ No newline at end of file +.gitignore diff --git a/resources/images/AllianceRequestIcon.svg b/resources/images/AllianceRequestIcon.svg new file mode 100755 index 000000000..f5981e241 --- /dev/null +++ b/resources/images/AllianceRequestIcon.svg @@ -0,0 +1,14 @@ + + + + + + + \ No newline at end of file diff --git a/src/client/graphics/layers/NameLayer.ts b/src/client/graphics/layers/NameLayer.ts index 555627039..734507917 100644 --- a/src/client/graphics/layers/NameLayer.ts +++ b/src/client/graphics/layers/NameLayer.ts @@ -11,6 +11,7 @@ import { Layer } from "./Layer"; import { TransformHandler } from "../TransformHandler"; import traitorIcon from "../../../../resources/images/TraitorIcon.svg"; import allianceIcon from "../../../../resources/images/AllianceIcon.svg"; +import allianceRequestIcon from "../../../../resources/images/AllianceRequestIcon.svg"; import crownIcon from "../../../../resources/images/CrownIcon.svg"; import targetIcon from "../../../../resources/images/TargetIcon.svg"; import { ClientID } from "../../../core/Schemas"; @@ -40,6 +41,7 @@ export class NameLayer implements Layer { private renders: RenderInfo[] = []; private seenPlayers: Set = new Set(); private traitorIconImage: HTMLImageElement; + private allianceRequestIconImage: HTMLImageElement; private allianceIconImage: HTMLImageElement; private targetIconImage: HTMLImageElement; private crownIconImage: HTMLImageElement; @@ -57,6 +59,8 @@ export class NameLayer implements Layer { this.traitorIconImage.src = traitorIcon; this.allianceIconImage = new Image(); this.allianceIconImage.src = allianceIcon; + this.allianceRequestIconImage = new Image(); + this.allianceRequestIconImage.src = allianceRequestIcon; this.crownIconImage = new Image(); this.crownIconImage.src = crownIcon; this.targetIconImage = new Image(); @@ -314,6 +318,23 @@ export class NameLayer implements Layer { existingAlliance.remove(); } + // Alliance request icon + const data = '[data-icon="alliance-request"]'; + const existingRequestAlliance = iconsDiv.querySelector(data); + if (myPlayer != null && render.player.isRequestingAllianceWith(myPlayer)) { + if (!existingRequestAlliance) { + iconsDiv.appendChild( + this.createIconElement( + this.allianceRequestIconImage.src, + iconSize, + "alliance-request", + ), + ); + } + } else if (existingRequestAlliance) { + existingRequestAlliance.remove(); + } + // Target icon const existingTarget = iconsDiv.querySelector('[data-icon="target"]'); if ( diff --git a/src/core/game/GameUpdates.ts b/src/core/game/GameUpdates.ts index 815136884..d3896eee0 100644 --- a/src/core/game/GameUpdates.ts +++ b/src/core/game/GameUpdates.ts @@ -1,5 +1,6 @@ import { ClientID } from "../Schemas"; import { + AllianceRequest, EmojiMessage, GameUpdates, MapPos, @@ -99,6 +100,7 @@ export interface PlayerUpdate { outgoingEmojis: EmojiMessage[]; outgoingAttacks: AttackUpdate[]; incomingAttacks: AttackUpdate[]; + outgoingAllianceRequests: PlayerID[]; } export interface AllianceRequestUpdate { diff --git a/src/core/game/GameView.ts b/src/core/game/GameView.ts index 9370c8895..ad1e9622a 100644 --- a/src/core/game/GameView.ts +++ b/src/core/game/GameView.ts @@ -187,6 +187,10 @@ export class PlayerView { return this.data.allies.some((n) => other.smallID() == n); } + isRequestingAllianceWith(other: PlayerView) { + return this.data.outgoingAllianceRequests.some((id) => other.id() == id); + } + profile(): Promise { return this.game.worker.playerProfile(this.smallID()); } diff --git a/src/core/game/PlayerImpl.ts b/src/core/game/PlayerImpl.ts index c1019c59a..0ca8e55ee 100644 --- a/src/core/game/PlayerImpl.ts +++ b/src/core/game/PlayerImpl.ts @@ -102,6 +102,10 @@ export class PlayerImpl implements Player { largestClusterBoundingBox: { min: Cell; max: Cell } | null; toUpdate(): PlayerUpdate { + const outgoingAllianceRequests = this.outgoingAllianceRequests().map((ar) => + ar.recipient().id(), + ); + return { type: GameUpdateType.Player, clientID: this.clientID(), @@ -138,6 +142,7 @@ export class PlayerImpl implements Player { troops: a.troops(), }) as AttackUpdate, ), + outgoingAllianceRequests: outgoingAllianceRequests, }; }