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,
};
}