From 49a9494810c684a995d8b054f743fa87da59a73a Mon Sep 17 00:00:00 2001 From: hided62 Date: Sun, 26 Jul 2026 22:40:17 +0000 Subject: [PATCH] fix supply-retreat history parity --- packages/logic/src/war/engine.ts | 7 +++++++ packages/logic/test/warEngine.test.ts | 3 +++ .../test/turnCommandCoreReference.integration.test.ts | 8 ++++++++ 3 files changed, 18 insertions(+) diff --git a/packages/logic/src/war/engine.ts b/packages/logic/src/war/engine.ts index add7529..64297e9 100644 --- a/packages/logic/src/war/engine.ts +++ b/packages/logic/src/war/engine.ts @@ -414,6 +414,13 @@ export const resolveWarBattle = ${cityName}의 수비병들이 패퇴합니다.`, LogFormat.MONTH ); + const defenderNationName = input.defenderNation?.name ?? '재야'; + const josaYiDefenderNation = JosaUtil.pick(defenderNationName, '이'); + const josaUlCity = JosaUtil.pick(cityName, '을'); + attackerLogger.pushGlobalHistoryLog( + `【패퇴】${defenderNationName}${josaYiDefenderNation} 병량 부족으로 ${cityName}${josaUlCity} 뺏기고 말았습니다.`, + LogFormat.YEAR_MONTH + ); conquerCity = true; emitTrace('supply_retreat', defender); diff --git a/packages/logic/test/warEngine.test.ts b/packages/logic/test/warEngine.test.ts index 8f60c0b..9d183ac 100644 --- a/packages/logic/test/warEngine.test.ts +++ b/packages/logic/test/warEngine.test.ts @@ -417,5 +417,8 @@ describe('resolveWarBattle', () => { expect(outcome.conquered).toBe(true); expect(outcome.reports.length).toBeGreaterThan(0); + expect(outcome.logs.map((log) => log.text)).toContain( + '【패퇴】TestNation이 병량 부족으로 TestCity를 뺏기고 말았습니다.' + ); }); }); diff --git a/tools/integration-tests/test/turnCommandCoreReference.integration.test.ts b/tools/integration-tests/test/turnCommandCoreReference.integration.test.ts index d951ca5..a9b69de 100644 --- a/tools/integration-tests/test/turnCommandCoreReference.integration.test.ts +++ b/tools/integration-tests/test/turnCommandCoreReference.integration.test.ts @@ -81,6 +81,7 @@ integration('core ↔ legacy command-boundary differential', () => { 'live sortie against multiple defending generals', 'fixtures/turn-differential/live-sortie-multiple-defenders.json', ], + ['live sortie supply retreat', 'fixtures/turn-differential/live-sortie-supply-retreat.json'], ])( '%s matches command RNG and canonical state delta', async (_label, fixturePath) => { @@ -105,6 +106,13 @@ integration('core ↔ legacy command-boundary differential', () => { const afterCity = reference.after.cities.find((city) => city.id === 70); expect(Number(afterCity?.defence)).toBeLessThan(Number(beforeCity?.defence)); } + if (fixturePath.endsWith('live-sortie-supply-retreat.json')) { + const retreatLogs = reference.after.logs.filter( + (log) => (Number(log.id) || 0) > reference.before.watermarks.historyLogId + ); + expect(retreatLogs.some((log) => String(log.text).includes('병량 부족'))).toBe(true); + expect(reference.after.cities.find((city) => city.id === 70)?.nationId).toBe(1); + } expect(core.execution.outcome).toMatchObject({ requestedAction: request.action,