fix: 단일 잔존 국가 임관 금지를 연결한다

마지막 도시 점령으로 국가가 삭제되면 destroy_nation 시나리오 이벤트를 같은 턴 경계에서 실행한다. Ref와 같이 잔존국 scout를 금지로 바꾸고 일회성 이벤트를 삭제하되 정책 변경 잠금은 설정하지 않는다.
This commit is contained in:
2026-08-23 11:08:30 +00:00
parent 51ca5e9d70
commit 4d424d16c6
11 changed files with 209 additions and 6 deletions
@@ -2,6 +2,8 @@ import { describe, expect, it } from 'vitest';
import type { TurnSchedule, UnitSetDefinition } from '@sammo-ts/logic';
import { DIPLOMACY_STATE } from '@sammo-ts/logic';
import type { InMemoryTurnWorld } from '../src/turn/inMemoryWorld.js';
import { createMonthlyEventHandler } from '../src/turn/monthlyEventHandler.js';
import { createScoutBlockHandler } from '../src/turn/monthlyScoutBlockAction.js';
import type { TurnGeneral, TurnWorldSnapshot, TurnWorldState } from '../src/turn/types.js';
import { LARGE_TEST_MAP, buildLargeTestCities } from './fixtures/largeTestMap.js';
import { createTurnTestHarness } from './helpers/turnTestHarness.js';
@@ -209,7 +211,16 @@ describe('도시 점령 시 국가 멸망 처리', () => {
{ fromNationId: 1, toNationId: 2, state: DIPLOMACY_STATE.WAR, term: 12, dead: 0, meta: {} },
{ fromNationId: 2, toNationId: 1, state: DIPLOMACY_STATE.WAR, term: 12, dead: 0, meta: {} },
],
events: [],
events: [
{
id: 1,
targetCode: 'destroy_nation',
priority: 1_000,
condition: ['and', ['Date', '>=', 183, 1], ['RemainNation', '==', 1]],
action: [['BlockScoutAction'], ['DeleteEvent']],
meta: {},
},
],
initialEvents: [],
map: LARGE_TEST_MAP as any,
scenarioConfig: {
@@ -244,12 +255,25 @@ describe('도시 점령 시 국가 멸망 처리', () => {
};
const worldRef = { current: null as InMemoryTurnWorld | null };
const blockScoutHandler = createScoutBlockHandler({
actionName: 'BlockScoutAction',
getWorld: () => worldRef.current,
});
const scenarioEventHandler = createMonthlyEventHandler({
getWorld: () => worldRef.current,
startYear: 180,
actions: new Map([['BlockScoutAction', blockScoutHandler]]),
});
const { world, reservedTurnStore, runOneTick } = await createTurnTestHarness({
snapshot,
state,
schedule,
map: LARGE_TEST_MAP,
worldRef,
turnProcessorOptions: {
tickMinutes: 10,
dispatchScenarioEvent: scenarioEventHandler.dispatchTarget,
},
});
const turns = reservedTurnStore.getGeneralTurns(strongLeader.id);
@@ -263,6 +287,9 @@ describe('도시 점령 시 국가 멸망 처리', () => {
expect(world.getCityById(weakCityId)?.nationId).toBe(1);
expect(world.getNationById(2)).toBeNull();
expect(world.listNations().some((nation) => nation.id === 2)).toBe(false);
expect(world.getNationById(1)?.meta.scout).toBe(1);
expect(world.listEvents('destroy_nation')).toEqual([]);
expect(world.getState().meta.block_change_scout).toBeUndefined();
expect(world.getCityById(conflictCity.id)?.conflict).toEqual({ 1: 50 });
const updatedWeakGeneral = world.getGeneralById(weakGeneral.id);