멸망 후 등용장에 현재 임관 모드 적용

This commit is contained in:
2026-09-22 23:24:15 +00:00
parent e34c24c74d
commit 908ae72cba
5 changed files with 87 additions and 3 deletions
+40 -2
View File
@@ -2,7 +2,7 @@ import { describe, expect, it } from 'vitest';
import type { City, General, Nation } from '../src/domain/entities.js';
import { resolveGeneralAction } from '../src/actions/engine.js';
import { ActionDefinition, orderDefenderGenerals } from '../src/actions/turn/general/che_출병.js';
import { ActionDefinition, actionContextBuilder, orderDefenderGenerals } from '../src/actions/turn/general/che_출병.js';
import type { DispatchResolveContext } from '../src/actions/turn/general/che_출병.js';
import type { TurnSchedule } from '../src/turn/calendar.js';
import type { WarAftermathConfig, WarEngineConfig } from '../src/war/types.js';
@@ -192,6 +192,44 @@ const uniqueItem: ItemModule = {
};
describe('che_출병', () => {
it.each(['full', 'onlyRandom'] as const)(
'reads %s join mode from current world config for collapse aftermath',
(joinMode) => {
const general = { ...buildGeneral(1, 1, 1), turnTime: new Date('0200-01-01T00:00:00.000Z') };
const destination = buildCity(2, 2);
const context = actionContextBuilder(
{ general, rng },
{
world: { currentYear: 200, currentMonth: 1, tickSeconds: 3600, meta: { joinMode: 'full' } },
worldConfig: { joinMode },
scenarioConfig: {
stat: { total: 0, min: 0, max: 0, npcTotal: 0, npcMin: 0, npcMax: 0, chiefMin: 0 },
iconPath: '',
map: {},
const: {},
environment: { mapName: 'test', unitSet: 'test' },
},
map: { id: 'test', name: 'test', cities: [] },
unitSet,
worldRef: {
getCityById: () => destination,
getNationById: () => buildNation(2),
listCities: () => [destination],
listNations: () => [buildNation(2)],
listGenerals: () => [general],
listDiplomacy: () => [],
} as never,
actionArgs: { destCityId: destination.id },
createGeneralId: () => 3,
createNationId: () => 3,
seedBase: 'test',
}
);
expect(context?.aftermathConfig).toMatchObject({ joinMode });
}
);
it('runs war battle and emits patches/logs', () => {
const attackerNation = buildNation(1);
const defenderNation = buildNation(2);
@@ -494,7 +532,7 @@ describe('che_출병', () => {
// assignment, so the aftermath alone would not patch it).
const defenderPatch = resolution.patches?.generals.find((patch) => patch.id === defender.id);
expect(defenderPatch).toBeDefined();
expect((defenderPatch?.patch.crew ?? defender.crew)).toBeLessThan(1500);
expect(defenderPatch?.patch.crew ?? defender.crew).toBeLessThan(1500);
});
it('orders equal-priority defender inputs by general number before the stable battle sort', () => {
+39
View File
@@ -726,6 +726,45 @@ describe('war aftermath', () => {
]);
});
it('does not draw or send collapse recruitment in random-only mode', () => {
const attackerNation = buildNation(1);
const defenderNation = buildNation(2);
defenderNation.chiefGeneralId = 2;
const attackerCity = buildCity(1, 1);
const defenderCity = buildCity(2, 2);
const attacker = buildGeneral(1, 1, 1);
const lord = buildGeneral(2, 2, 2);
lord.officerLevel = 12;
lord.npcState = 2;
const rng = {
nextRange: vi.fn(() => 0.2),
nextBool: vi.fn(() => true),
nextRangeInt: vi.fn(() => 1),
} as unknown as RandUtil;
const outcome = resolveWarAftermath({
battle: { attacker, defenders: [], defenderCity, logs: [], conquered: true, reports: [] },
attackerNation,
defenderNation,
attackerCity,
defenderCity,
nations: [attackerNation, defenderNation],
cities: [attackerCity, defenderCity],
generals: [attacker, lord],
unitSet: buildUnitSet(),
map: DEFAULT_MAP,
config: { ...buildConfig(), joinMode: 'onlyRandom' },
time: { year: 186, month: 1, startYear: 179 },
messageTime: MESSAGE_TIME,
rng,
});
expect(outcome.conquest?.nationCollapsed).toBe(true);
expect(outcome.conquest?.messages).toEqual([]);
expect(outcome.conquest?.ruinedNpcJoinPlans).toEqual([]);
expect(rng.nextBool).not.toHaveBeenCalled();
});
it('dispatches city conquest to every stationed defender before collapse RNG', () => {
const rng = new RandUtil(new ConstantRNG(0));
const draws = [0.01, 0.02, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7];