mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-30 12:02:12 +00:00
## Description: About 30s before an alliance is about to expire, both players receive a prompt to extend the alliance. If both players agree the alliance is extended. ## 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: evan
This commit is contained in:
@@ -67,6 +67,10 @@ export class SendAllianceReplyIntentEvent implements GameEvent {
|
||||
) {}
|
||||
}
|
||||
|
||||
export class SendAllianceExtensionIntentEvent implements GameEvent {
|
||||
constructor(public readonly recipient: PlayerView) {}
|
||||
}
|
||||
|
||||
export class SendSpawnIntentEvent implements GameEvent {
|
||||
constructor(public readonly cell: Cell) {}
|
||||
}
|
||||
@@ -194,6 +198,9 @@ export class Transport {
|
||||
this.eventBus.on(SendAllianceReplyIntentEvent, (e) =>
|
||||
this.onAllianceRequestReplyUIEvent(e),
|
||||
);
|
||||
this.eventBus.on(SendAllianceExtensionIntentEvent, (e) =>
|
||||
this.onSendAllianceExtensionIntent(e),
|
||||
);
|
||||
this.eventBus.on(SendBreakAllianceIntentEvent, (e) =>
|
||||
this.onBreakAllianceRequestUIEvent(e),
|
||||
);
|
||||
@@ -419,6 +426,16 @@ export class Transport {
|
||||
});
|
||||
}
|
||||
|
||||
private onSendAllianceExtensionIntent(
|
||||
event: SendAllianceExtensionIntentEvent,
|
||||
) {
|
||||
this.sendIntent({
|
||||
type: "allianceExtension",
|
||||
clientID: this.lobbyConfig.clientID,
|
||||
recipient: event.recipient.id(),
|
||||
});
|
||||
}
|
||||
|
||||
private onSendSpawnIntentEvent(event: SendSpawnIntentEvent) {
|
||||
this.sendIntent({
|
||||
type: "spawn",
|
||||
|
||||
@@ -141,6 +141,7 @@ export function getMessageTypeClasses(type: MessageType): string {
|
||||
case MessageType.SAM_MISS:
|
||||
case MessageType.ALLIANCE_EXPIRED:
|
||||
case MessageType.NAVAL_INVASION_INBOUND:
|
||||
case MessageType.RENEW_ALLIANCE:
|
||||
return severityColors["warn"];
|
||||
case MessageType.CHAT:
|
||||
case MessageType.ALLIANCE_REQUEST:
|
||||
|
||||
@@ -32,6 +32,7 @@ import {
|
||||
import {
|
||||
CancelAttackIntentEvent,
|
||||
CancelBoatIntentEvent,
|
||||
SendAllianceExtensionIntentEvent,
|
||||
SendAllianceReplyIntentEvent,
|
||||
} from "../../Transport";
|
||||
import { Layer } from "./Layer";
|
||||
@@ -45,7 +46,6 @@ import {
|
||||
GoToUnitEvent,
|
||||
} from "./Leaderboard";
|
||||
|
||||
import { UserSettings } from "../../../core/game/UserSettings";
|
||||
import { getMessageTypeClasses, translateText } from "../../Utils";
|
||||
|
||||
interface GameEvent {
|
||||
@@ -73,9 +73,11 @@ export class EventsDisplay extends LitElement implements Layer {
|
||||
public eventBus: EventBus;
|
||||
public game: GameView;
|
||||
|
||||
private userSettings: UserSettings = new UserSettings();
|
||||
private active: boolean = false;
|
||||
private events: GameEvent[] = [];
|
||||
|
||||
// allianceID -> last checked at tick
|
||||
private alliancesCheckedAt = new Map<number, Tick>();
|
||||
@state() private incomingAttacks: AttackUpdate[] = [];
|
||||
@state() private outgoingAttacks: AttackUpdate[] = [];
|
||||
@state() private outgoingLandAttacks: AttackUpdate[] = [];
|
||||
@@ -182,6 +184,8 @@ export class EventsDisplay extends LitElement implements Layer {
|
||||
return;
|
||||
}
|
||||
|
||||
this.checkForAllianceExpirations();
|
||||
|
||||
const updates = this.game.updatesSinceLastTick();
|
||||
if (updates) {
|
||||
for (const [ut, fn] of this.updateMap) {
|
||||
@@ -235,6 +239,64 @@ export class EventsDisplay extends LitElement implements Layer {
|
||||
}
|
||||
}
|
||||
|
||||
private checkForAllianceExpirations() {
|
||||
const myPlayer = this.game.myPlayer();
|
||||
if (!myPlayer) return;
|
||||
|
||||
for (const alliance of myPlayer.alliances()) {
|
||||
if (
|
||||
alliance.expiresAt >
|
||||
this.game.ticks() + this.game.config().allianceExtensionPromptOffset()
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
(this.alliancesCheckedAt.get(alliance.id) ?? 0) >=
|
||||
this.game.ticks() - this.game.config().allianceExtensionPromptOffset()
|
||||
) {
|
||||
// We've already displayed a message for this alliance.
|
||||
continue;
|
||||
}
|
||||
|
||||
this.alliancesCheckedAt.set(alliance.id, this.game.ticks());
|
||||
|
||||
const other = this.game.player(alliance.other) as PlayerView;
|
||||
|
||||
this.addEvent({
|
||||
description: translateText("events_display.about_to_expire", {
|
||||
name: other.name(),
|
||||
}),
|
||||
type: MessageType.RENEW_ALLIANCE,
|
||||
duration: this.game.config().allianceExtensionPromptOffset() - 3 * 10, // 3 second buffer
|
||||
buttons: [
|
||||
{
|
||||
text: translateText("events_display.focus"),
|
||||
className: "btn-gray",
|
||||
action: () => this.eventBus.emit(new GoToPlayerEvent(other)),
|
||||
preventClose: true,
|
||||
},
|
||||
{
|
||||
text: translateText("events_display.renew_alliance", {
|
||||
name: other.name(),
|
||||
}),
|
||||
className: "btn",
|
||||
action: () =>
|
||||
this.eventBus.emit(new SendAllianceExtensionIntentEvent(other)),
|
||||
},
|
||||
{
|
||||
text: translateText("events_display.ignore"),
|
||||
className: "btn-info",
|
||||
action: () => {},
|
||||
},
|
||||
],
|
||||
highlight: true,
|
||||
createdAt: this.game.ticks(),
|
||||
focusID: other.smallID(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private addEvent(event: GameEvent) {
|
||||
this.events = [...this.events, event];
|
||||
if (this._hidden === true) {
|
||||
|
||||
@@ -176,11 +176,9 @@ export class PlayerPanel extends LitElement implements Layer {
|
||||
if (myPlayer !== null && myPlayer.isAlive()) {
|
||||
this.actions = await myPlayer.actions(this.tile);
|
||||
|
||||
if (this.actions?.interaction?.allianceCreatedAtTick !== undefined) {
|
||||
const createdAt = this.actions.interaction.allianceCreatedAtTick;
|
||||
const durationTicks = this.g.config().allianceDuration();
|
||||
const expiryTick = createdAt + durationTicks;
|
||||
const remainingTicks = expiryTick - this.g.ticks();
|
||||
if (this.actions?.interaction?.allianceExpiresAt !== undefined) {
|
||||
const expiresAt = this.actions.interaction.allianceExpiresAt;
|
||||
const remainingTicks = expiresAt - this.g.ticks();
|
||||
|
||||
if (remainingTicks > 0) {
|
||||
const remainingSeconds = Math.max(
|
||||
|
||||
Reference in New Issue
Block a user