feat: 예약 턴 명령별 중간 외교 전이와 실행 정보를 기록

This commit is contained in:
2026-09-16 06:09:24 +00:00
parent 248d457dd5
commit 0691c502fa
6 changed files with 153 additions and 11 deletions
+14 -1
View File
@@ -1,3 +1,4 @@
import { recordTurnAuditDiplomacy, type AuditDiplomacyAction } from '../playAudit/diplomacy.js';
import type { AuditDiplomacyEventDraft } from '@sammo-ts/infra';
import { initializeNationAuditPolicies, type PendingAuditPolicy } from '../playAudit/policy.js';
import type { PendingAuditMonth } from '../playAudit/persistence.js';
@@ -71,6 +72,7 @@ export interface GeneralTurnResult {
srcNationId: number;
destNationId: number;
patch: DiplomacyPatch;
audit?: AuditDiplomacyAction;
}>;
created?: {
generals: TurnGeneral[];
@@ -1940,6 +1942,7 @@ export class InMemoryTurnWorld {
executeGeneralTurn(general: TurnGeneral): GeneralTurnExecution {
assertGameplayCommitAllowed(this.getGameClock().phase);
const currentGeneral = this.generals.get(general.id) ?? general;
const executionTick = currentGeneral.turnTick ?? this.getGameClock().dateToTick(currentGeneral.turnTime);
const executionYear = this.state.currentYear;
const executionMonth = this.state.currentMonth;
const city = this.cities.get(currentGeneral.cityId);
@@ -2064,12 +2067,22 @@ export class InMemoryTurnWorld {
}
}
if (result.diplomacyPatches) {
for (const patch of result.diplomacyPatches) {
for (const [index, patch] of result.diplomacyPatches.entries()) {
const key = buildDiplomacyKey(patch.srcNationId, patch.destNationId);
const before = this.diplomacy.get(key) ?? buildDefaultDiplomacy(patch.srcNationId, patch.destNationId);
this.applyDiplomacyPatch({
srcNationId: patch.srcNationId,
destNationId: patch.destNationId,
patch: patch.patch,
});
const after = this.diplomacy.get(key);
if (patch.audit && after) {
recordTurnAuditDiplomacy(this, before, after, patch.audit, {
generalId: currentGeneral.id,
tick: executionTick,
ordinal: index + 1,
});
}
}
}
if (result.created) {
@@ -1056,11 +1056,8 @@ export const createReservedTurnHandler = async (options: {
nations: [] as Array<{ id: number; patch: Partial<Nation> }>,
troops: [] as Array<{ id: number; patch: Partial<Troop> }>,
};
const diplomacyPatches: Array<{
srcNationId: number;
destNationId: number;
patch: DiplomacyPatch;
}> = [];
const diplomacyPatches: NonNullable<GeneralTurnResult['diplomacyPatches']> = [];
let auditActionOrdinal = 0;
const createdGenerals: TurnGeneral[] = [];
const createdNations: Nation[] = [];
const commandDeletedTroopIds = new Set<number>();
@@ -1333,6 +1330,15 @@ export const createReservedTurnHandler = async (options: {
const lastTurnBeforeExecution = JSON.stringify(currentGeneral.lastTurn ?? {});
const generalBeforeExecution = currentGeneral;
const actionOrdinal = ++auditActionOrdinal;
const auditActor = {
generalId: currentGeneral.id,
userId: currentGeneral.userId ?? null,
name: currentGeneral.name,
nationId: currentGeneral.nationId,
officerLevel: currentGeneral.officerLevel,
npcState: currentGeneral.npcState,
};
const cityNationIdsBeforeExecution = new Map(
(worldView?.listCities() ?? []).map((city) => [city.id, city.nationId] as const)
);
@@ -1574,6 +1580,9 @@ export const createReservedTurnHandler = async (options: {
srcNationId: effect.srcNationId,
destNationId: effect.destNationId,
patch: effect.patch,
...(typeof context.world.meta.serverId === 'string'
? { audit: { actionKey, kind, actionOrdinal, actor: auditActor } }
: {}),
});
worldOverlay?.applyDiplomacyPatch(effect.srcNationId, effect.destNationId, effect.patch);
}