Skip to content
3 changes: 3 additions & 0 deletions resources/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,8 @@
"cursor_cost_label_desc": "Show a cost pill under the build cursor icon",
"anonymous_names_label": "Hidden Names",
"anonymous_names_desc": "Hide real player names with random ones on your screen.",
"player_name_opacity_label": "Player Name Opacity",
"player_name_opacity_desc": "Adjust on-map player label opacity. At 0, names and flags are hidden.",
"lobby_id_visibility_label": "Hidden Lobby IDs",
"lobby_id_visibility_desc": "Hide Lobby ID in private lobby creation",
"toggle_visibility": "Toggle Visibility",
Expand Down Expand Up @@ -626,6 +628,7 @@
"unbind": "Unbind",
"on": "On",
"off": "Off",
"hidden": "Hidden",
"toggle_terrain": "Toggle Terrain",
"exit_game_label": "Exit Game",
"exit_game_info": "Return to main menu",
Expand Down
19 changes: 19 additions & 0 deletions src/client/UserSettingModal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,15 @@ export class UserSettingModal extends BaseModal {
}
}

private sliderPlayerNameOpacity(e: CustomEvent<{ value: number }>) {
const value = e.detail?.value;
if (typeof value !== "number") {
console.warn("Slider event missing detail.value", e);
return;
}
this.userSettings.setPlayerNameOpacity(value);
}

private changeAttackRatioIncrement(
e: CustomEvent<{ value: number | string }>,
) {
Expand Down Expand Up @@ -921,6 +930,16 @@ export class UserSettingModal extends BaseModal {
@change=${this.toggleAnonymousNames}
></setting-toggle>

<setting-slider
label="${translateText("user_setting.player_name_opacity_label")}"
description="${translateText("user_setting.player_name_opacity_desc")}"
min="0"
max="100"
.value=${this.userSettings.playerNameOpacity()}
.zeroLabelKey=${"user_setting.hidden"}
@change=${this.sliderPlayerNameOpacity}
></setting-slider>

<!-- 👁️ Hidden Lobby IDs -->
<setting-toggle
label="${translateText("user_setting.lobby_id_visibility_label")}"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { LitElement, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { translateText } from "../../../Utils";

@customElement("setting-slider")
export class SettingSlider extends LitElement {
Expand All @@ -9,6 +10,7 @@ export class SettingSlider extends LitElement {
@property({ type: Number }) min = 0;
@property({ type: Number }) max = 100;
@property({ type: Boolean }) easter = false;
@property() zeroLabelKey = "";

createRenderRoot() {
return this;
Expand Down Expand Up @@ -45,6 +47,10 @@ export class SettingSlider extends LitElement {
const rainbowClass = this.easter
? "bg-[linear-gradient(270deg,#990033,#996600,#336600,#008080,#1c3f99,#5e0099,#990033)] bg-[length:1400%_1400%] animate-rainbow-bg text-white hover:bg-[linear-gradient(270deg,#990033,#996600,#336600,#008080,#1c3f99,#5e0099,#990033)]"
: "";
const valueText =
this.value === 0 && this.zeroLabelKey
? translateText(this.zeroLabelKey)
: `${this.value}%`;

return html`
<div
Expand Down Expand Up @@ -78,7 +84,7 @@ export class SettingSlider extends LitElement {
/>
<span
class="text-white font-bold text-sm shrink-0 text-right min-w-[3ch]"
>${this.value}%</span
>${valueText}</span
>
</div>
</div>
Expand Down
11 changes: 10 additions & 1 deletion src/client/graphics/layers/NameLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,17 +303,26 @@ export class NameLayer implements Layer {
}
render.lastRenderCalc = now + this.rand.nextInt(0, 100);

// Update text sizes
// Update text sizes and opacity
render.fontSize = Math.max(4, Math.floor(baseSize * 0.4));
render.fontColor = this.theme.textColor(render.player);
const nameOpacityPercent = this.userSettings.playerNameOpacity();
const nameOpacity = nameOpacityPercent / 100;
const hideFlag = nameOpacityPercent === 0;

render.nameDiv.style.fontSize = `${render.fontSize}px`;
render.nameDiv.style.lineHeight = `${render.fontSize}px`;
render.nameDiv.style.color = render.fontColor;
if (render.nameSpan) {
render.nameSpan.textContent = render.player.displayName();
render.nameSpan.style.opacity = `${nameOpacity}`;
}
if (render.flagDiv) {
render.flagDiv.style.height = `${render.fontSize}px`;
render.flagDiv.style.display = hideFlag ? "none" : "";
}
render.troopsDiv.style.fontSize = `${render.fontSize}px`;
render.troopsDiv.style.opacity = `${nameOpacity}`;
render.troopsDiv.style.color = render.fontColor;
render.troopsDiv.textContent = renderTroops(render.player.troops());

Expand Down
38 changes: 38 additions & 0 deletions src/client/graphics/layers/SettingsModal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,12 @@ export class SettingsModal extends LitElement implements Layer {
this.requestUpdate();
}

private onPlayerNameOpacityChange(event: Event) {
const opacity = parseFloat((event.target as HTMLInputElement).value);
this.userSettings.setPlayerNameOpacity(opacity);
this.requestUpdate();
}

render() {
if (!this.isVisible) {
return null;
Expand Down Expand Up @@ -481,6 +487,38 @@ export class SettingsModal extends LitElement implements Layer {
</div>
</button>

<div
class="flex gap-3 items-center w-full text-left p-3 hover:bg-slate-700 rounded-sm text-white transition-colors"
>
<img
src=${settingsIcon}
alt="nameOpacity"
width="20"
height="20"
/>
<div class="flex-1">
<div class="font-medium">
${translateText("user_setting.player_name_opacity_label")}
</div>
<div class="text-sm text-slate-400">
${translateText("user_setting.player_name_opacity_desc")}
</div>
<input
type="range"
min="0"
max="100"
.value=${this.userSettings.playerNameOpacity()}
@input=${this.onPlayerNameOpacityChange}
class="w-full border border-slate-500 rounded-lg"
/>
</div>
<div class="text-sm text-slate-400">
${this.userSettings.playerNameOpacity() === 0
? translateText("user_setting.hidden")
: `${this.userSettings.playerNameOpacity()}%`}
</div>
</div>

<button
class="flex gap-3 items-center w-full text-left p-3 hover:bg-slate-700 rounded-sm text-white transition-colors"
@click="${this.onToggleLeftClickOpensMenu}"
Expand Down
14 changes: 14 additions & 0 deletions src/core/game/UserSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,4 +245,18 @@ export class UserSettings {
setSoundEffectsVolume(volume: number): void {
this.setFloat("settings.soundEffectsVolume", volume);
}

playerNameOpacity(): number {
const opacity = Math.round(
this.getFloat("settings.playerNameOpacity", 100),
);
if (!Number.isFinite(opacity)) return 100;
return Math.max(0, Math.min(100, opacity));
}

setPlayerNameOpacity(opacity: number): void {
if (!Number.isFinite(opacity)) return;
const clampedOpacity = Math.max(0, Math.min(100, Math.round(opacity)));
this.setFloat("settings.playerNameOpacity", clampedOpacity);
}
}
Loading