mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-17 05:49:24 +00:00
Add filters tabs to EvensDisplay to let users filter events (#1080)
## Description: Big update to the EventsDisplay - Style update for EventsDisplay, look & feel similar to other windows - Component now hidden during spawn phase - Adds new functionality for filtering events by category. Allows the player to remove specific event types - Displays latest gold amount, decays after 5 seconds <img width="1147" alt="Screenshot 2025-06-07 at 20 18 55" src="https://github.com/user-attachments/assets/11c39818-55ad-4ba1-a998-360057e2856c" /> <img width="422" alt="Screenshot 2025-06-07 at 19 01 55" src="https://github.com/user-attachments/assets/09c0b998-6046-49fb-9fba-33b4f57f337b" /> <img width="444" alt="Screenshot 2025-06-07 at 20 20 25" src="https://github.com/user-attachments/assets/022deadc-3a49-442a-85f5-f1cd128a5805" />  ## 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 - [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: maxion_ Fixes #1025 Fixes #1034
This commit is contained in:
@@ -180,7 +180,7 @@ export class AttackExecution implements Execution {
|
||||
if (deaths) {
|
||||
this.mg.displayMessage(
|
||||
`Attack cancelled, ${renderTroops(deaths)} soldiers killed during retreat.`,
|
||||
MessageType.SUCCESS,
|
||||
MessageType.ATTACK_CANCELLED,
|
||||
this._owner.id(),
|
||||
);
|
||||
}
|
||||
@@ -340,8 +340,9 @@ export class AttackExecution implements Execution {
|
||||
`Conquered ${this.target.displayName()} received ${renderNumber(
|
||||
gold,
|
||||
)} gold`,
|
||||
MessageType.SUCCESS,
|
||||
MessageType.CONQUERED_PLAYER,
|
||||
this._owner.id(),
|
||||
gold,
|
||||
);
|
||||
this.target.removeGold(gold);
|
||||
this._owner.addGold(gold);
|
||||
|
||||
@@ -67,8 +67,9 @@ export class MirvExecution implements Execution {
|
||||
|
||||
this.mg.displayIncomingUnit(
|
||||
this.nuke.id(),
|
||||
// TODO TranslateText
|
||||
`⚠️⚠️⚠️ ${this.player.name()} - MIRV INBOUND ⚠️⚠️⚠️`,
|
||||
MessageType.ERROR,
|
||||
MessageType.MIRV_INBOUND,
|
||||
this.targetPlayer.id(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -111,16 +111,18 @@ export class NukeExecution implements Execution {
|
||||
} else if (this.nukeType === UnitType.AtomBomb) {
|
||||
this.mg.displayIncomingUnit(
|
||||
this.nuke.id(),
|
||||
// TODO TranslateText
|
||||
`${this.player.name()} - atom bomb inbound`,
|
||||
MessageType.ERROR,
|
||||
MessageType.NUKE_INBOUND,
|
||||
target.id(),
|
||||
);
|
||||
this.breakAlliances(this.tilesToDestroy());
|
||||
} else if (this.nukeType === UnitType.HydrogenBomb) {
|
||||
this.mg.displayIncomingUnit(
|
||||
this.nuke.id(),
|
||||
// TODO TranslateText
|
||||
`${this.player.name()} - hydrogen bomb inbound`,
|
||||
MessageType.ERROR,
|
||||
MessageType.HYDROGEN_BOMB_INBOUND,
|
||||
target.id(),
|
||||
);
|
||||
this.breakAlliances(this.tilesToDestroy());
|
||||
|
||||
@@ -207,8 +207,9 @@ export class PlayerExecution implements Execution {
|
||||
`Conquered ${this.player.displayName()} received ${renderNumber(
|
||||
gold,
|
||||
)} gold`,
|
||||
MessageType.SUCCESS,
|
||||
MessageType.CONQUERED_PLAYER,
|
||||
capturing.id(),
|
||||
gold,
|
||||
);
|
||||
capturing.addGold(gold);
|
||||
this.player.removeGold(gold);
|
||||
|
||||
@@ -174,7 +174,7 @@ export class SAMLauncherExecution implements Execution {
|
||||
if (!hit) {
|
||||
this.mg.displayMessage(
|
||||
`Missile failed to intercept ${type}`,
|
||||
MessageType.ERROR,
|
||||
MessageType.SAM_MISS,
|
||||
this.sam.owner().id(),
|
||||
);
|
||||
} else {
|
||||
@@ -182,7 +182,7 @@ export class SAMLauncherExecution implements Execution {
|
||||
// Message
|
||||
this.mg.displayMessage(
|
||||
`${mirvWarheadTargets.length} MIRV warheads intercepted`,
|
||||
MessageType.SUCCESS,
|
||||
MessageType.SAM_HIT,
|
||||
this.sam.owner().id(),
|
||||
);
|
||||
// Delete warheads
|
||||
|
||||
@@ -62,7 +62,7 @@ export class SAMMissileExecution implements Execution {
|
||||
if (result === true) {
|
||||
this.mg.displayMessage(
|
||||
`Missile intercepted ${this.target.type()}`,
|
||||
MessageType.SUCCESS,
|
||||
MessageType.SAM_HIT,
|
||||
this._owner.id(),
|
||||
);
|
||||
this.active = false;
|
||||
|
||||
@@ -131,21 +131,24 @@ export class TradeShipExecution implements Execution {
|
||||
this.tradeShip!.owner().addGold(gold);
|
||||
this.mg.displayMessage(
|
||||
`Received ${renderNumber(gold)} gold from ship captured from ${this.origOwner.displayName()}`,
|
||||
MessageType.SUCCESS,
|
||||
MessageType.CAPTURED_ENEMY_UNIT,
|
||||
this.tradeShip!.owner().id(),
|
||||
gold,
|
||||
);
|
||||
} else {
|
||||
this.srcPort.owner().addGold(gold);
|
||||
this._dstPort.owner().addGold(gold);
|
||||
this.mg.displayMessage(
|
||||
`Received ${renderNumber(gold)} gold from trade with ${this.srcPort.owner().displayName()}`,
|
||||
MessageType.SUCCESS,
|
||||
MessageType.RECEIVED_GOLD_FROM_TRADE,
|
||||
this._dstPort.owner().id(),
|
||||
gold,
|
||||
);
|
||||
this.mg.displayMessage(
|
||||
`Received ${renderNumber(gold)} gold from trade with ${this._dstPort.owner().displayName()}`,
|
||||
MessageType.SUCCESS,
|
||||
MessageType.RECEIVED_GOLD_FROM_TRADE,
|
||||
this.srcPort.owner().id(),
|
||||
gold,
|
||||
);
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -62,7 +62,7 @@ export class TransportShipExecution implements Execution {
|
||||
) {
|
||||
mg.displayMessage(
|
||||
`No boats available, max ${mg.config().boatMaxNumber()}`,
|
||||
MessageType.WARN,
|
||||
MessageType.ATTACK_FAILED,
|
||||
this.attacker.id(),
|
||||
);
|
||||
this.active = false;
|
||||
@@ -130,8 +130,9 @@ export class TransportShipExecution implements Execution {
|
||||
if (this.targetID && this.targetID !== mg.terraNullius().id()) {
|
||||
mg.displayIncomingUnit(
|
||||
this.boat.id(),
|
||||
// TODO TranslateText
|
||||
`Naval invasion incoming from ${this.attacker.displayName()}`,
|
||||
MessageType.WARN,
|
||||
MessageType.NAVAL_INVASION_INBOUND,
|
||||
this.targetID,
|
||||
);
|
||||
}
|
||||
|
||||
+67
-4
@@ -587,6 +587,7 @@ export interface Game extends GameMap {
|
||||
message: string,
|
||||
type: MessageType,
|
||||
playerID: PlayerID | null,
|
||||
goldAmount?: bigint,
|
||||
): void;
|
||||
displayIncomingUnit(
|
||||
unitID: number,
|
||||
@@ -653,13 +654,75 @@ export interface EmojiMessage {
|
||||
}
|
||||
|
||||
export enum MessageType {
|
||||
SUCCESS,
|
||||
INFO,
|
||||
WARN,
|
||||
ERROR,
|
||||
ATTACK_FAILED,
|
||||
ATTACK_CANCELLED,
|
||||
ATTACK_REQUEST,
|
||||
CONQUERED_PLAYER,
|
||||
MIRV_INBOUND,
|
||||
NUKE_INBOUND,
|
||||
HYDROGEN_BOMB_INBOUND,
|
||||
NAVAL_INVASION_INBOUND,
|
||||
SAM_MISS,
|
||||
SAM_HIT,
|
||||
CAPTURED_ENEMY_UNIT,
|
||||
UNIT_CAPTURED_BY_ENEMY,
|
||||
UNIT_DESTROYED,
|
||||
ALLIANCE_ACCEPTED,
|
||||
ALLIANCE_REJECTED,
|
||||
ALLIANCE_REQUEST,
|
||||
ALLIANCE_BROKEN,
|
||||
ALLIANCE_EXPIRED,
|
||||
SENT_GOLD_TO_PLAYER,
|
||||
RECEIVED_GOLD_FROM_PLAYER,
|
||||
RECEIVED_GOLD_FROM_TRADE,
|
||||
SENT_TROOPS_TO_PLAYER,
|
||||
RECEIVED_TROOPS_FROM_PLAYER,
|
||||
CHAT,
|
||||
}
|
||||
|
||||
// Message categories used for filtering events in the EventsDisplay
|
||||
export enum MessageCategory {
|
||||
ATTACK = "ATTACK",
|
||||
ALLIANCE = "ALLIANCE",
|
||||
TRADE = "TRADE",
|
||||
CHAT = "CHAT",
|
||||
}
|
||||
|
||||
// Ensures that all message types are included in a category
|
||||
export const MESSAGE_TYPE_CATEGORIES: Record<MessageType, MessageCategory> = {
|
||||
[MessageType.ATTACK_FAILED]: MessageCategory.ATTACK,
|
||||
[MessageType.ATTACK_CANCELLED]: MessageCategory.ATTACK,
|
||||
[MessageType.ATTACK_REQUEST]: MessageCategory.ATTACK,
|
||||
[MessageType.CONQUERED_PLAYER]: MessageCategory.ATTACK,
|
||||
[MessageType.MIRV_INBOUND]: MessageCategory.ATTACK,
|
||||
[MessageType.NUKE_INBOUND]: MessageCategory.ATTACK,
|
||||
[MessageType.HYDROGEN_BOMB_INBOUND]: MessageCategory.ATTACK,
|
||||
[MessageType.NAVAL_INVASION_INBOUND]: MessageCategory.ATTACK,
|
||||
[MessageType.SAM_MISS]: MessageCategory.ATTACK,
|
||||
[MessageType.SAM_HIT]: MessageCategory.ATTACK,
|
||||
[MessageType.CAPTURED_ENEMY_UNIT]: MessageCategory.ATTACK,
|
||||
[MessageType.UNIT_CAPTURED_BY_ENEMY]: MessageCategory.ATTACK,
|
||||
[MessageType.UNIT_DESTROYED]: MessageCategory.ATTACK,
|
||||
[MessageType.ALLIANCE_ACCEPTED]: MessageCategory.ALLIANCE,
|
||||
[MessageType.ALLIANCE_REJECTED]: MessageCategory.ALLIANCE,
|
||||
[MessageType.ALLIANCE_REQUEST]: MessageCategory.ALLIANCE,
|
||||
[MessageType.ALLIANCE_BROKEN]: MessageCategory.ALLIANCE,
|
||||
[MessageType.ALLIANCE_EXPIRED]: MessageCategory.ALLIANCE,
|
||||
[MessageType.SENT_GOLD_TO_PLAYER]: MessageCategory.TRADE,
|
||||
[MessageType.RECEIVED_GOLD_FROM_PLAYER]: MessageCategory.TRADE,
|
||||
[MessageType.RECEIVED_GOLD_FROM_TRADE]: MessageCategory.TRADE,
|
||||
[MessageType.SENT_TROOPS_TO_PLAYER]: MessageCategory.TRADE,
|
||||
[MessageType.RECEIVED_TROOPS_FROM_PLAYER]: MessageCategory.TRADE,
|
||||
[MessageType.CHAT]: MessageCategory.CHAT,
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Get the category of a message type
|
||||
*/
|
||||
export function getMessageCategory(messageType: MessageType): MessageCategory {
|
||||
return MESSAGE_TYPE_CATEGORIES[messageType];
|
||||
}
|
||||
|
||||
export interface NameViewData {
|
||||
x: number;
|
||||
y: number;
|
||||
|
||||
@@ -612,6 +612,7 @@ export class GameImpl implements Game {
|
||||
message: string,
|
||||
type: MessageType,
|
||||
playerID: PlayerID | null,
|
||||
goldAmount?: bigint,
|
||||
): void {
|
||||
let id: number | null = null;
|
||||
if (playerID !== null) {
|
||||
@@ -622,6 +623,7 @@ export class GameImpl implements Game {
|
||||
messageType: type,
|
||||
message: message,
|
||||
playerID: id,
|
||||
goldAmount: goldAmount,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -162,6 +162,7 @@ export interface DisplayMessageUpdate {
|
||||
type: GameUpdateType.DisplayEvent;
|
||||
message: string;
|
||||
messageType: MessageType;
|
||||
goldAmount?: bigint;
|
||||
playerID: number | null;
|
||||
}
|
||||
|
||||
|
||||
@@ -558,12 +558,12 @@ export class PlayerImpl implements Player {
|
||||
this.sentDonations.push(new Donation(recipient, this.mg.ticks()));
|
||||
this.mg.displayMessage(
|
||||
`Sent ${renderTroops(troops)} troops to ${recipient.name()}`,
|
||||
MessageType.INFO,
|
||||
MessageType.SENT_TROOPS_TO_PLAYER,
|
||||
this.id(),
|
||||
);
|
||||
this.mg.displayMessage(
|
||||
`Received ${renderTroops(troops)} troops from ${this.name()}`,
|
||||
MessageType.SUCCESS,
|
||||
MessageType.RECEIVED_TROOPS_FROM_PLAYER,
|
||||
recipient.id(),
|
||||
);
|
||||
return true;
|
||||
@@ -578,13 +578,14 @@ export class PlayerImpl implements Player {
|
||||
this.sentDonations.push(new Donation(recipient, this.mg.ticks()));
|
||||
this.mg.displayMessage(
|
||||
`Sent ${renderNumber(gold)} gold to ${recipient.name()}`,
|
||||
MessageType.INFO,
|
||||
MessageType.SENT_GOLD_TO_PLAYER,
|
||||
this.id(),
|
||||
);
|
||||
this.mg.displayMessage(
|
||||
`Received ${renderNumber(gold)} gold from ${this.name()}`,
|
||||
MessageType.SUCCESS,
|
||||
MessageType.RECEIVED_GOLD_FROM_PLAYER,
|
||||
recipient.id(),
|
||||
gold,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -160,6 +160,7 @@ export class UnitImpl implements Unit {
|
||||
case UnitType.City:
|
||||
this.mg.stats().unitCapture(newOwner, this._type);
|
||||
this.mg.stats().unitLose(this._owner, this._type);
|
||||
break;
|
||||
}
|
||||
this._lastOwner = this._owner;
|
||||
this._lastOwner._units = this._lastOwner._units.filter((u) => u !== this);
|
||||
@@ -168,12 +169,12 @@ export class UnitImpl implements Unit {
|
||||
this.mg.addUpdate(this.toUpdate());
|
||||
this.mg.displayMessage(
|
||||
`Your ${this.type()} was captured by ${newOwner.displayName()}`,
|
||||
MessageType.ERROR,
|
||||
MessageType.UNIT_CAPTURED_BY_ENEMY,
|
||||
this._lastOwner.id(),
|
||||
);
|
||||
this.mg.displayMessage(
|
||||
`Captured ${this.type()} from ${this._lastOwner.displayName()}`,
|
||||
MessageType.SUCCESS,
|
||||
MessageType.CAPTURED_ENEMY_UNIT,
|
||||
newOwner.id(),
|
||||
);
|
||||
}
|
||||
@@ -200,7 +201,7 @@ export class UnitImpl implements Unit {
|
||||
if (displayMessage !== false && this._type !== UnitType.MIRVWarhead) {
|
||||
this.mg.displayMessage(
|
||||
`Your ${this._type} was destroyed`,
|
||||
MessageType.ERROR,
|
||||
MessageType.UNIT_DESTROYED,
|
||||
this.owner().id(),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user