mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 09:30:45 +00:00
Colored SVG smiley icons next to nation names based on relation 😊 (#3746)
## Description: Instead of coloring nation names based on diplomatic relation, small inline SVG face icons are now shown next to the nation name in the player info overlay: - 😠 **Hostile** - red angry face (furrowed brows, downturned mouth) - 😟 **Distrustful** - orange slightly-sad face (flat mouth) - 😊 **Friendly** - green happy face (upturned smile) - **Neutral** - no icon shown <img width="509" height="80" alt="Screenshot 2026-04-23 013151" src="https://github.com/user-attachments/assets/85dc3f29-0a84-45d1-902e-e75c6cad4a44" /> <img width="511" height="82" alt="Screenshot 2026-04-23 012809" src="https://github.com/user-attachments/assets/7a37c8a3-08d0-448e-9eaa-16f254a296ad" /> <img width="511" height="88" alt="Screenshot 2026-04-23 012741" src="https://github.com/user-attachments/assets/d617f8ca-2315-467a-85f5-63f769bd0341" /> No longer conflicts with green text color because of alliance now. ## Please complete the following: - [X] I have added screenshots for all UI updates - [X] I process any text displayed to the user through translateText() and I've added it to the en.json file - [X] I have added relevant tests to the test directory - [X] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced ## Please put your Discord username so you can be contacted if a bug or regression is found: FloPinguin
This commit is contained in:
@@ -34,6 +34,7 @@ import { TransformHandler } from "../TransformHandler";
|
||||
import { ImmunityBarVisibleEvent } from "./ImmunityTimer";
|
||||
import { Layer } from "./Layer";
|
||||
import { CloseRadialMenuEvent } from "./RadialMenu";
|
||||
import "./RelationSmiley";
|
||||
import { SpawnBarVisibleEvent } from "./SpawnTimer";
|
||||
const allianceIcon = assetUrl("images/AllianceIcon.svg");
|
||||
const warshipIcon = assetUrl("images/BattleshipIconWhite.svg");
|
||||
@@ -182,37 +183,21 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
this.requestUpdate();
|
||||
}
|
||||
|
||||
private getPlayerNameColor(
|
||||
player: PlayerView,
|
||||
myPlayer: PlayerView | null | undefined,
|
||||
isFriendly: boolean,
|
||||
): string {
|
||||
private getPlayerNameColor(isFriendly: boolean): string {
|
||||
if (isFriendly) return "text-green-500";
|
||||
if (
|
||||
myPlayer &&
|
||||
myPlayer !== player &&
|
||||
player.type() === PlayerType.Nation
|
||||
) {
|
||||
const relation =
|
||||
this.playerProfile?.relations[myPlayer.smallID()] ?? Relation.Neutral;
|
||||
return this.getRelationClass(relation);
|
||||
}
|
||||
return "text-white";
|
||||
}
|
||||
|
||||
private getRelationClass(relation: Relation): string {
|
||||
switch (relation) {
|
||||
case Relation.Hostile:
|
||||
return "text-red-500";
|
||||
case Relation.Distrustful:
|
||||
return "text-red-300";
|
||||
case Relation.Neutral:
|
||||
return "text-white";
|
||||
case Relation.Friendly:
|
||||
return "text-green-500";
|
||||
default:
|
||||
return "text-white";
|
||||
}
|
||||
private getRelationSmiley(
|
||||
player: PlayerView,
|
||||
myPlayer: PlayerView | null | undefined,
|
||||
): TemplateResult | string {
|
||||
if (!myPlayer || myPlayer === player || player.type() !== PlayerType.Nation)
|
||||
return "";
|
||||
const relation =
|
||||
this.playerProfile?.relations[myPlayer.smallID()] ?? Relation.Neutral;
|
||||
if (relation === Relation.Neutral) return "";
|
||||
return html`<relation-smiley .relation=${relation}></relation-smiley>`;
|
||||
}
|
||||
|
||||
private getRelationName(relation: Relation): string {
|
||||
@@ -363,8 +348,6 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
<div class="flex flex-col justify-between self-stretch">
|
||||
<div
|
||||
class="flex items-center gap-2 font-bold text-sm lg:text-lg ${this.getPlayerNameColor(
|
||||
player,
|
||||
myPlayer,
|
||||
isFriendly ?? false,
|
||||
)}"
|
||||
>
|
||||
@@ -375,6 +358,7 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
/>`
|
||||
: html``}
|
||||
<span>${player.displayName()}</span>
|
||||
${this.getRelationSmiley(player, myPlayer)}
|
||||
${playerTeam !== "" && player.type() !== PlayerType.Bot
|
||||
? html`<div class="flex flex-col leading-tight">
|
||||
<span class="text-gray-400 text-xs font-normal"
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
import { html, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { Relation } from "../../../core/game/Game";
|
||||
|
||||
type FaceData = {
|
||||
color: string;
|
||||
eyeCy: number;
|
||||
mouth: string;
|
||||
brows?: string[];
|
||||
};
|
||||
const RELATION_FACES: Partial<Record<Relation, FaceData>> = {
|
||||
[Relation.Hostile]: {
|
||||
color: "#ef4444",
|
||||
eyeCy: 7.5,
|
||||
mouth: "M5 12 Q8 9 11 12",
|
||||
brows: ["M4 5.5 L6.5 7", "M12 5.5 L9.5 7"],
|
||||
},
|
||||
[Relation.Distrustful]: {
|
||||
color: "#f97316",
|
||||
eyeCy: 6.8,
|
||||
mouth: "M5.5 11 Q8 9.2 10.5 11",
|
||||
},
|
||||
[Relation.Friendly]: {
|
||||
color: "#22c55e",
|
||||
eyeCy: 6.5,
|
||||
mouth: "M5 10 Q8 13 11 10",
|
||||
},
|
||||
};
|
||||
|
||||
@customElement("relation-smiley")
|
||||
export class RelationSmiley extends LitElement {
|
||||
@property({ type: Number })
|
||||
relation: Relation = Relation.Neutral;
|
||||
|
||||
createRenderRoot() {
|
||||
return this;
|
||||
}
|
||||
|
||||
render() {
|
||||
const face = RELATION_FACES[this.relation];
|
||||
if (!face) return html``;
|
||||
const { color, eyeCy, mouth, brows } = face;
|
||||
return html`<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
style="flex-shrink:0"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<circle
|
||||
cx="8"
|
||||
cy="8"
|
||||
r="6.5"
|
||||
stroke="${color}"
|
||||
stroke-width="1.4"
|
||||
fill="none"
|
||||
/>
|
||||
${brows?.map(
|
||||
(d) =>
|
||||
html`<path
|
||||
d="${d}"
|
||||
stroke="${color}"
|
||||
stroke-width="1.4"
|
||||
stroke-linecap="round"
|
||||
/>`,
|
||||
)}
|
||||
<circle cx="5.8" cy="${eyeCy}" r="0.9" fill="${color}" />
|
||||
<circle cx="10.2" cy="${eyeCy}" r="0.9" fill="${color}" />
|
||||
<path
|
||||
d="${mouth}"
|
||||
stroke="${color}"
|
||||
stroke-width="1.4"
|
||||
fill="none"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
</svg>`;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user