mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 11:50:42 +00:00
Rename/fix: change Bots to Tribes (#3290)
## Description: Resolves #3285. As discussed on Discord. However, in at least one instance "Tribes" feels a bit off: in Humans vs Nations, team "Tribes" feels as human too while they are just bots. This PR changes Bots to Tribes outwardly by - Changing default EN translation. - Changing (untranslated) alt text in PlayerPanel. - To change "Team Bot" into "Team Tribes" too in PlayerInfoOverlay and TeamStats (team leaderboard in-game), translate team names in there from now on too. - This way we also fix a bug where team names were not translated yet in there. To add to that fix, also translate team names in LobbyPlayerView in the same way. For this we re-use the existing getTranslatedPlayerTeamLabel function from GameLeftSideBar by moving it to Utils. - No translation key was present yet for Humans and Nations teams, so added those to now be used in PlayerInfoOverlay, LobbyPlayerView and TeamStats for completeness. - No internal code changes so nothing breaks. **BEFORE (showing old team name Bot and also that team names weren't translated yet in TeamStats)**   **AFTER** (translations in Dutch only shown as proof here, did not include nl.json in the PR)      ## 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: tryout33
This commit is contained in:
@@ -115,7 +115,7 @@
|
||||
"ui_options": "Options",
|
||||
"ui_options_desc": "The following elements can be found inside:",
|
||||
"ui_playeroverlay": "Player info overlay",
|
||||
"ui_playeroverlay_desc": "When you hover over a country, the Player info overlay is displayed under Options. It shows the type of player: Human, Nation (smart bot), or Bot. A Nation's attitude towards you, ranging from Hostile to Friendly. And defending troops, gold, plus the number of Warships and various buildings the player has.",
|
||||
"ui_playeroverlay_desc": "When you hover over a country, the Player info overlay is displayed under Options. It shows the type of player: Human, Nation, or Tribe. A Nation's attitude towards you, ranging from Hostile to Friendly. And defending troops, gold, plus the number of Warships and various buildings the player has.",
|
||||
"ui_wilderness": "Wilderness",
|
||||
"option_pause": "Pause/Unpause the game - Only available in single player mode.",
|
||||
"option_timer": "Timer - Time passed since the start of the game.",
|
||||
@@ -137,7 +137,7 @@
|
||||
"info_trade": "Use \"Stop trading\" to stop giving the player gold and receiving their gold via trade ships. If you both click \"Start trading\" it will start again.",
|
||||
"info_ally_panel": "Ally info panel",
|
||||
"info_ally_desc": "When you ally with a player, the following new icons become available:",
|
||||
"ally_betray": "Betray your ally, ending the alliance, halting trade, and weakening your defense. Trading between you is paused for 5 minutes (or until you become allies again) and others may stop trading too. And unless the other player was a traitor themselves, you'll be marked a traitor for 30 seconds. During this time an icon will be above your name and you will have a 50% defense debuff. Bots are less likely to ally with you and players will think twice before doing so.",
|
||||
"ally_betray": "Betray your ally, ending the alliance, halting trade, and weakening your defense. Trading between you is paused for 5 minutes (or until you become allies again) and others may stop trading too. And unless the other player was a traitor themselves, you'll be marked a traitor for 30 seconds. During this time an icon will be above your name and you will have a 50% defense debuff. Tribes are less likely to ally with you and players will think twice before doing so.",
|
||||
"ally_donate": "Donate some of your troops to your ally. Used when they're low on troops and are being attacked, or when they need that extra power to crush an enemy.",
|
||||
"ally_donate_gold": "Donate some of your gold to your ally. Used when they're low on gold and need it for buildings, or when your team member is saving for that MIRV.",
|
||||
"build_menu_title": "Build menu",
|
||||
@@ -184,7 +184,7 @@
|
||||
"toggle_achievements": "Toggle achievements",
|
||||
"sign_in_for_achievements": "Sign in for achievements",
|
||||
"options_title": "Options",
|
||||
"bots": "Bots: ",
|
||||
"bots": "Tribes: ",
|
||||
"bots_disabled": "Disabled",
|
||||
"disable_nations": "Disable Nations",
|
||||
"instant_build": "Instant build",
|
||||
@@ -264,7 +264,7 @@
|
||||
"conquest_gold": "Conquered player gold",
|
||||
"stolen_gold": "Stolen with warships",
|
||||
"num_of_conquests_humans": "Player kills",
|
||||
"num_of_conquests_bots": "Bot kills",
|
||||
"num_of_conquests_bots": "Tribe kills",
|
||||
"duration": "Duration",
|
||||
"survival_time": "Survival time",
|
||||
"war": "War",
|
||||
@@ -399,7 +399,7 @@
|
||||
"team_count": "Number of Teams",
|
||||
"team_type": "Team Type",
|
||||
"options_title": "Options",
|
||||
"bots": "Bots: ",
|
||||
"bots": "Tribes: ",
|
||||
"bots_disabled": "Disabled",
|
||||
"player_immunity_duration": "PVP immunity duration (minutes)",
|
||||
"disable_nations": "Disable Nations",
|
||||
@@ -440,7 +440,9 @@
|
||||
"yellow": "Yellow",
|
||||
"orange": "Orange",
|
||||
"green": "Green",
|
||||
"bot": "Bot"
|
||||
"bot": "Tribes",
|
||||
"humans": "Humans",
|
||||
"nations": "Nations"
|
||||
},
|
||||
"game_starting_modal": {
|
||||
"title": "Game is Starting...",
|
||||
@@ -779,7 +781,7 @@
|
||||
"player_type": {
|
||||
"player": "Player",
|
||||
"nation": "Nation",
|
||||
"bot": "Bot"
|
||||
"bot": "Tribe"
|
||||
},
|
||||
"relation": {
|
||||
"hostile": "Hostile",
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
MessageType,
|
||||
PublicGameModifiers,
|
||||
Quads,
|
||||
Team,
|
||||
Trios,
|
||||
} from "../core/game/Game";
|
||||
import { GameConfig } from "../core/Schemas";
|
||||
@@ -408,6 +409,13 @@ export const translateText = (
|
||||
}
|
||||
};
|
||||
|
||||
export function getTranslatedPlayerTeamLabel(team: Team | null): string {
|
||||
if (!team) return "";
|
||||
const translationKey = `team_colors.${team.toLowerCase()}`;
|
||||
const translated = translateText(translationKey);
|
||||
return translated === translationKey ? team : translated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Severity colors mapping for message types
|
||||
*/
|
||||
|
||||
@@ -18,7 +18,7 @@ import { assignTeamsLobbyPreview } from "../../core/game/TeamAssignment";
|
||||
import { UserSettings } from "../../core/game/UserSettings";
|
||||
import { ClientInfo, TeamCountConfig } from "../../core/Schemas";
|
||||
import { createRandomName } from "../../core/Util";
|
||||
import { translateText } from "../Utils";
|
||||
import { getTranslatedPlayerTeamLabel, translateText } from "../Utils";
|
||||
|
||||
export interface TeamPreviewData {
|
||||
team: Team;
|
||||
@@ -193,6 +193,8 @@ export class LobbyTeamView extends LitElement {
|
||||
? effectiveNationCount
|
||||
: this.teamMaxSize;
|
||||
|
||||
const teamLabel = getTranslatedPlayerTeamLabel(preview.team);
|
||||
|
||||
return html`
|
||||
<div class="bg-gray-800 border border-gray-700 rounded-xl flex flex-col">
|
||||
<div
|
||||
@@ -204,7 +206,7 @@ export class LobbyTeamView extends LitElement {
|
||||
style="--bg:${this.teamHeaderColor(preview.team)};"
|
||||
></span>`
|
||||
: null}
|
||||
<span class="truncate">${preview.team}</span>
|
||||
<span class="truncate">${teamLabel}</span>
|
||||
<span class="text-white/90">${displayCount}/${maxTeamSize}</span>
|
||||
</div>
|
||||
<div class="p-2 ${isEmpty ? "" : "flex flex-col gap-1.5"}">
|
||||
|
||||
@@ -2,10 +2,10 @@ import { Colord } from "colord";
|
||||
import { html, LitElement } from "lit";
|
||||
import { customElement, state } from "lit/decorators.js";
|
||||
import { EventBus } from "../../../core/EventBus";
|
||||
import { GameMode } from "../../../core/game/Game";
|
||||
import { GameMode, Team } from "../../../core/game/Game";
|
||||
import { GameView } from "../../../core/game/GameView";
|
||||
import { Platform } from "../../Platform";
|
||||
import { translateText } from "../../Utils";
|
||||
import { getTranslatedPlayerTeamLabel, translateText } from "../../Utils";
|
||||
import { ImmunityBarVisibleEvent } from "./ImmunityTimer";
|
||||
import { Layer } from "./Layer";
|
||||
import { SpawnBarVisibleEvent } from "./SpawnTimer";
|
||||
@@ -25,7 +25,7 @@ export class GameLeftSidebar extends LitElement implements Layer {
|
||||
@state()
|
||||
private isPlayerTeamLabelVisible = false;
|
||||
@state()
|
||||
private playerTeam: string | null = null;
|
||||
private playerTeam: Team | null = null;
|
||||
@state()
|
||||
private spawnBarVisible = false;
|
||||
@state()
|
||||
@@ -99,13 +99,6 @@ export class GameLeftSidebar extends LitElement implements Layer {
|
||||
return this.game?.config().gameConfig().gameMode === GameMode.Team;
|
||||
}
|
||||
|
||||
private getTranslatedPlayerTeamLabel(): string {
|
||||
if (!this.playerTeam) return "";
|
||||
const translationKey = `team_colors.${this.playerTeam.toLowerCase()}`;
|
||||
const translated = translateText(translationKey);
|
||||
return translated === translationKey ? this.playerTeam : translated;
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<aside
|
||||
@@ -180,7 +173,8 @@ export class GameLeftSidebar extends LitElement implements Layer {
|
||||
style="--color: ${this.playerColor.toRgbString()}"
|
||||
class="text-(--color)"
|
||||
>
|
||||
${this.getTranslatedPlayerTeamLabel()} ⦿
|
||||
${getTranslatedPlayerTeamLabel(this.playerTeam)}
|
||||
⦿
|
||||
</span>
|
||||
</div>
|
||||
`
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
TouchEvent,
|
||||
} from "../../InputHandler";
|
||||
import {
|
||||
getTranslatedPlayerTeamLabel,
|
||||
renderDuration,
|
||||
renderNumber,
|
||||
renderTroops,
|
||||
@@ -314,6 +315,7 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
playerType = translateText("player_type.player");
|
||||
break;
|
||||
}
|
||||
const playerTeam = getTranslatedPlayerTeamLabel(player.team());
|
||||
|
||||
return html`
|
||||
<div class="flex items-start gap-2 lg:gap-3 p-1.5 lg:p-2">
|
||||
@@ -357,7 +359,7 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
/>`
|
||||
: html``}
|
||||
<span>${player.name()}</span>
|
||||
${player.team() !== null && player.type() !== PlayerType.Bot
|
||||
${playerTeam !== "" && player.type() !== PlayerType.Bot
|
||||
? html`<div class="flex flex-col leading-tight">
|
||||
<span class="text-gray-400 text-xs font-normal"
|
||||
>${playerType}</span
|
||||
@@ -369,7 +371,7 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
.theme()
|
||||
.teamColor(player.team()!)
|
||||
.toHex()}"
|
||||
>${player.team()}</span
|
||||
>${playerTeam}</span
|
||||
>]</span
|
||||
>
|
||||
</div>`
|
||||
|
||||
@@ -340,22 +340,19 @@ export class PlayerPanel extends LitElement implements Layer {
|
||||
case PlayerType.Nation:
|
||||
return {
|
||||
labelKey: "player_type.nation",
|
||||
aria: "Nation player",
|
||||
classes: "border-indigo-400/25 bg-indigo-500/10 text-indigo-200",
|
||||
icon: "🏛️",
|
||||
};
|
||||
case PlayerType.Bot:
|
||||
return {
|
||||
labelKey: "player_type.bot",
|
||||
aria: "Bot",
|
||||
classes: "border-purple-400/25 bg-purple-500/10 text-purple-200",
|
||||
icon: "🤖",
|
||||
icon: "⚔️",
|
||||
};
|
||||
case PlayerType.Human:
|
||||
default:
|
||||
return {
|
||||
labelKey: "player_type.player",
|
||||
aria: "Human player",
|
||||
classes: "border-zinc-400/20 bg-zinc-500/5 text-zinc-300",
|
||||
icon: "👤",
|
||||
};
|
||||
@@ -517,7 +514,7 @@ export class PlayerPanel extends LitElement implements Layer {
|
||||
? html`<span
|
||||
class=${`inline-flex items-center gap-1.5 rounded-full border px-2 py-0.5 text-xs font-semibold ${chip.classes}`}
|
||||
role="status"
|
||||
aria-label=${chip.aria}
|
||||
aria-label=${translateText(chip.labelKey)}
|
||||
title=${translateText(chip.labelKey)}
|
||||
>
|
||||
<span aria-hidden="true" class="leading-none">${chip.icon}</span>
|
||||
|
||||
@@ -69,14 +69,18 @@ export class TeamStats extends LitElement implements Layer {
|
||||
}
|
||||
|
||||
for (const player of players) {
|
||||
const team = player.team();
|
||||
if (team === null) continue;
|
||||
grouped[team] ??= [];
|
||||
grouped[team].push(player);
|
||||
const rawTeam = player.team();
|
||||
if (rawTeam === null) continue;
|
||||
grouped[rawTeam] ??= [];
|
||||
grouped[rawTeam].push(player);
|
||||
}
|
||||
|
||||
this.teams = Object.entries(grouped)
|
||||
.map(([teamStr, teamPlayers]) => {
|
||||
.map(([rawTeam, teamPlayers]) => {
|
||||
const key = `team_colors.${rawTeam.toLowerCase()}`;
|
||||
const translated = translateText(key);
|
||||
const teamName = translated !== key ? translated : rawTeam;
|
||||
|
||||
let totalGold = 0n;
|
||||
let totalMaxTroops = 0;
|
||||
let totalScoreSort = 0;
|
||||
@@ -102,8 +106,8 @@ export class TeamStats extends LitElement implements Layer {
|
||||
const totalScorePercent = totalScoreSort / numTilesWithoutFallout;
|
||||
|
||||
return {
|
||||
teamName: teamStr,
|
||||
isMyTeam: teamStr === this._myTeam,
|
||||
teamName,
|
||||
isMyTeam: rawTeam === this._myTeam,
|
||||
totalScoreStr: formatPercentage(totalScorePercent),
|
||||
totalScoreSort,
|
||||
totalGold: renderNumber(totalGold),
|
||||
|
||||
Reference in New Issue
Block a user