Add live update for player menu (#511)

## Description:

UX Improvement - Make the player menu options update live, like
donations and re-offering alliance if it was rejected previously. Now
player doesn't have to keep re-opening the menu to see the options
updated.

Fixes #521 

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors

## Please put your Discord username so you can be contacted if a bug or
regression is found:

eyeseeem

---------

Co-authored-by: Max Dohme <max.dohme@gmail.com>
Co-authored-by: Scott Anderson <scottanderson@users.noreply.github.com>
Co-authored-by: APuddle210 <david.eskin@gmail.com>
This commit is contained in:
Max Dohme
2025-04-17 23:21:16 +02:00
committed by GitHub
parent a0edae88f2
commit 9aa933b676
2 changed files with 42 additions and 16 deletions
+8 -2
View File
@@ -145,8 +145,14 @@ export class PlayerPanel extends LitElement implements Layer {
this.eventBus.on(MouseUpEvent, (e: MouseEvent) => this.hide());
}
tick() {
this.requestUpdate();
async tick() {
if (this.isVisible && this.tile) {
const myPlayer = this.g.myPlayer();
if (myPlayer !== null && myPlayer.isAlive()) {
this.actions = await myPlayer.actions(this.tile);
this.requestUpdate();
}
}
}
getTotalNukesSent(otherId: PlayerID): number {
+34 -14
View File
@@ -8,7 +8,7 @@ import swordIcon from "../../../../resources/images/SwordIconWhite.svg";
import traitorIcon from "../../../../resources/images/TraitorIconWhite.svg";
import { consolex } from "../../../core/Consolex";
import { EventBus } from "../../../core/EventBus";
import { Cell, PlayerActions } from "../../../core/game/Game";
import { Cell, PlayerActions, TerraNullius } from "../../../core/game/Game";
import { TileRef } from "../../../core/game/GameMap";
import { GameView, PlayerView } from "../../../core/game/GameView";
import { ClientID } from "../../../core/Schemas";
@@ -44,6 +44,7 @@ export class RadialMenu implements Layer {
private clickedCell: Cell | null = null;
private lastClosed: number = 0;
private originalTileOwner: PlayerView | TerraNullius;
private menuElement: d3.Selection<HTMLDivElement, unknown, null, undefined>;
private isVisible: boolean = false;
private readonly menuItems = new Map([
@@ -267,8 +268,26 @@ export class RadialMenu implements Layer {
.style("pointer-events", "none");
}
tick() {
// Update logic if needed
async tick() {
// Only update when menu is visible
if (!this.isVisible || this.clickedCell === null) return;
const myPlayer = this.g.myPlayer();
if (myPlayer === null || !myPlayer.isAlive()) return;
const tile = this.g.ref(this.clickedCell.x, this.clickedCell.y);
if (this.originalTileOwner.isPlayer()) {
if (this.g.owner(tile) != this.originalTileOwner) {
this.closeMenu();
return;
}
} else {
if (this.g.owner(tile).isPlayer() || this.g.owner(tile) == myPlayer) {
this.closeMenu();
return;
}
}
const actions = await myPlayer.actions(tile);
this.disableAllButtons();
this.handlePlayerActions(myPlayer, actions, tile);
}
renderLayer(context: CanvasRenderingContext2D) {
@@ -291,12 +310,7 @@ export class RadialMenu implements Layer {
} else {
this.showRadialMenu(event.x, event.y);
}
this.enableCenterButton(false);
for (const item of this.menuItems.values()) {
item.disabled = true;
this.updateMenuItemState(item);
}
this.disableAllButtons();
this.clickedCell = this.transformHandler.screenToWorldCoordinates(
event.x,
event.y,
@@ -305,7 +319,7 @@ export class RadialMenu implements Layer {
return;
}
const tile = this.g.ref(this.clickedCell.x, this.clickedCell.y);
this.originalTileOwner = this.g.owner(tile);
if (this.g.inSpawnPhase()) {
if (this.g.isLand(tile) && !this.g.hasOwner(tile)) {
this.enableCenterButton(true);
@@ -313,10 +327,8 @@ export class RadialMenu implements Layer {
return;
}
const myPlayer = this.g
.playerViews()
.find((p) => p.clientID() == this.clientID);
if (!myPlayer) {
const myPlayer = this.g.myPlayer();
if (myPlayer === null) {
consolex.warn("my player not found");
return;
}
@@ -430,6 +442,14 @@ export class RadialMenu implements Layer {
this.hideRadialMenu();
}
private disableAllButtons() {
this.enableCenterButton(false);
for (const item of this.menuItems.values()) {
item.disabled = true;
this.updateMenuItemState(item);
}
}
private activateMenuElement(
slot: Slot,
color: string,