Orange betrayal button for no-debuff-betrayals 🖌️ (#3161)

Resolves #1276

## Description:

Orange betrayal button if the player is a traitor or disconnected.
So people can easier tell that this is a betrayal without consequences.
The color changes back to red without reopening the menu (live) when the
traitor debuff ends or the player reconnects.

<img width="268" height="257" alt="image"
src="https://github.com/user-attachments/assets/276e91ce-e49d-474c-afaa-ffa18d45a2c7"
/>

## 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

---------

Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
This commit is contained in:
FloPinguin
2026-02-09 23:23:20 +00:00
committed by GitHub
co-authored by Ryan
parent 3cd4ffff0c
commit c212735f09
4 changed files with 51 additions and 12 deletions
+15 -8
View File
@@ -11,6 +11,16 @@ import {
} from "./RadialMenuElements";
import backIcon from "/images/BackIconWhite.svg?url";
function resolveColor(
item: MenuElement,
params: MenuElementParams | null,
): string | undefined {
if (typeof item.color === "function") {
return params ? item.color(params) : undefined;
}
return item.color;
}
export class CloseRadialMenuEvent implements GameEvent {
constructor() {}
}
@@ -322,7 +332,7 @@ export class RadialMenu implements Layer {
const disabled = this.params === null || d.data.disabled(this.params);
const color = disabled
? this.config.disabledColor
: (d.data.color ?? "#333333");
: (resolveColor(d.data, this.params) ?? "#333333");
const opacity = disabled ? 0.5 : 0.7;
if (d.data.id === this.selectedItemId && this.currentLevel > level) {
@@ -365,7 +375,7 @@ export class RadialMenu implements Layer {
const color =
this.params === null || d.data.disabled(this.params)
? this.config.disabledColor
: (d.data.color ?? "#333333");
: (resolveColor(d.data, this.params) ?? "#333333");
path.attr("fill", color);
}
});
@@ -431,7 +441,7 @@ export class RadialMenu implements Layer {
path.attr("stroke-width", "2");
const color = disabled
? this.config.disabledColor
: (d.data.color ?? "#333333");
: (resolveColor(d.data, this.params) ?? "#333333");
const opacity = disabled ? 0.5 : 0.7;
path.attr(
"fill",
@@ -848,10 +858,7 @@ export class RadialMenu implements Layer {
public disableAllButtons() {
this.updateCenterButtonState("default");
for (const item of this.currentMenuItems) {
item.color = this.config.disabledColor;
}
this.refresh();
}
public updateCenterButtonState(state: CenterButtonState) {
@@ -1043,7 +1050,7 @@ export class RadialMenu implements Layer {
const disabled = this.isItemDisabled(item);
const color = disabled
? this.config.disabledColor
: (item.color ?? "#333333");
: (resolveColor(item, this.params) ?? "#333333");
const opacity = disabled ? 0.5 : 0.7;
// Update path appearance
@@ -46,7 +46,7 @@ export interface MenuElement {
id: string;
name: string;
displayed?: boolean | ((params: MenuElementParams) => boolean);
color?: string;
color?: string | ((params: MenuElementParams) => string);
icon?: string;
text?: string;
fontSize?: string;
@@ -76,6 +76,7 @@ export const COLORS = {
boat: "#3f6ab1",
ally: "#53ac75",
breakAlly: "#c74848",
breakAllyNoDebuff: "#d4882b",
delete: "#ff0000",
info: "#64748B",
target: "#ff0000",
@@ -216,7 +217,10 @@ const allyBreakElement: MenuElement = {
!params.playerActions?.interaction?.canBreakAlliance,
displayed: (params: MenuElementParams) =>
!!params.playerActions?.interaction?.canBreakAlliance,
color: COLORS.breakAlly,
color: (params: MenuElementParams) =>
params.selected?.isTraitor() || params.selected?.isDisconnected()
? COLORS.breakAllyNoDebuff
: COLORS.breakAlly,
icon: traitorIcon,
action: (params: MenuElementParams) => {
params.playerActionHandler.handleBreakAlliance(