fix(engine): finalize united events and auctions compatibly
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
import { asNumber, asRecord, JosaUtil } from '@sammo-ts/common';
|
||||
import { LogCategory, LogFormat, LogScope, type LogEntryDraft } from '@sammo-ts/logic';
|
||||
|
||||
import type { InMemoryTurnWorld, TurnCalendarHandler } from './inMemoryWorld.js';
|
||||
import type { InMemoryTurnWorld, TurnCalendarContext, TurnCalendarHandler } from './inMemoryWorld.js';
|
||||
import type { PendingUnificationAuctionCancellation } from './types.js';
|
||||
import { queueYearbookSnapshot } from './yearbookHandler.js';
|
||||
|
||||
const UNIFIER_POINT = 2000;
|
||||
|
||||
const buildUnificationLog = (nationName: string): LogEntryDraft => ({
|
||||
scope: LogScope.SYSTEM,
|
||||
category: LogCategory.HISTORY,
|
||||
@@ -39,9 +42,11 @@ const resolveServerId = (world: InMemoryTurnWorld, fallback: string): string =>
|
||||
export const createUnificationHandler = (options: {
|
||||
profileName: string;
|
||||
getWorld: () => InMemoryTurnWorld | null;
|
||||
loadPendingUniqueAuctions?: () => Promise<PendingUnificationAuctionCancellation[]>;
|
||||
dispatchUnitedEvents: (context: TurnCalendarContext) => Promise<void>;
|
||||
}): { handler: TurnCalendarHandler } => ({
|
||||
handler: {
|
||||
onMonthChanged: (context) => {
|
||||
onMonthChanged: async (context) => {
|
||||
const world = options.getWorld();
|
||||
if (!world) return;
|
||||
|
||||
@@ -57,12 +62,57 @@ export const createUnificationHandler = (options: {
|
||||
if (cities.length === 0 || cities.some((city) => city.nationId !== winner.id)) return;
|
||||
|
||||
const serverId = resolveServerId(world, options.profileName);
|
||||
world.pushLog(buildNationHistoryLog(winner.id, winner.name));
|
||||
|
||||
const auctionCancellations = (await options.loadPendingUniqueAuctions?.()) ?? [];
|
||||
for (const cancellation of auctionCancellations) {
|
||||
if (cancellation.highestBidId === null) continue;
|
||||
const bidderId = cancellation.bidderGeneralId;
|
||||
const amount = cancellation.amount;
|
||||
if (bidderId === null || amount === null || amount <= 0) {
|
||||
throw new Error(`Unification auction ${cancellation.auctionId} has an invalid refund plan.`);
|
||||
}
|
||||
const bidder = world.getGeneralById(bidderId);
|
||||
if (!bidder?.userId) {
|
||||
throw new Error(`Unification auction ${cancellation.auctionId} bidder is unavailable.`);
|
||||
}
|
||||
const spentDynamic = asNumber(bidder.meta.inherit_spent_dyn, 0);
|
||||
if (cancellation.rankTrackedAmount > spentDynamic) {
|
||||
throw new Error(`Unification auction ${cancellation.auctionId} rank refund exceeds tracked spend.`);
|
||||
}
|
||||
world.updateGeneral(bidder.id, {
|
||||
inheritancePoints: {
|
||||
...bidder.inheritancePoints,
|
||||
previous: asNumber(bidder.inheritancePoints?.previous, 0) + amount,
|
||||
},
|
||||
meta: {
|
||||
...bidder.meta,
|
||||
inherit_spent_dyn: spentDynamic - cancellation.rankTrackedAmount,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
for (const general of world
|
||||
.listGenerals()
|
||||
.filter(
|
||||
(entry) =>
|
||||
entry.userId && entry.npcState < 2 && entry.nationId === winner.id && entry.officerLevel > 4
|
||||
)) {
|
||||
world.updateGeneral(general.id, {
|
||||
inheritancePoints: {
|
||||
...general.inheritancePoints,
|
||||
unifier: asNumber(general.inheritancePoints?.unifier, 0) + UNIFIER_POINT,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
await options.dispatchUnitedEvents(context);
|
||||
|
||||
world.updateWorldMeta({
|
||||
isUnited: 2,
|
||||
isunited: 2,
|
||||
refreshLimit: asNumber(meta.refreshLimit, 0) * 100,
|
||||
});
|
||||
world.pushLog(buildNationHistoryLog(winner.id, winner.name));
|
||||
for (const general of world.listGenerals().filter((entry) => entry.nationId === winner.id)) {
|
||||
world.pushLog(buildGeneralActionLog(general.id, winner.id, winner.name));
|
||||
}
|
||||
@@ -77,6 +127,7 @@ export const createUnificationHandler = (options: {
|
||||
year: context.currentYear,
|
||||
month: context.currentMonth,
|
||||
completedAt: new Date(state.lastTurnTime.getTime()),
|
||||
auctionCancellations,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user