fix: 기본 등용과 대상 임관 명령을 복구
Ref 기본 일반장 명령 46개 exact-set 검사를 추가하고 등용 및 장수대상임관을 사용자 명령표에 복원한다. 실제 DB와 API, 데몬, Chromium을 연결해 등용 서신 수신과 수락 임관까지 검증하며 내부 등용수락 명령의 profile 로딩도 바로잡는다.
This commit is contained in:
@@ -2204,9 +2204,18 @@ export const createImmediateGeneralActionExecutor = async (options: {
|
||||
}): Promise<ImmediateGeneralActionExecutor> => {
|
||||
const env = buildCommandEnv(options.world.getScenarioConfig(), options.world.getUnitSet());
|
||||
const commandProfile = options.commandProfile ?? DEFAULT_TURN_COMMAND_PROFILE;
|
||||
// 등용수락은 예약 화면에 노출되는 명령이 아니라 등용 서신의 응답이
|
||||
// 직접 실행하는 내부 명령이다. 선택 가능 명령 프로필에 없더라도 등용
|
||||
// 서신을 수락할 수 있도록 즉시 행동 정의에는 항상 포함한다.
|
||||
const immediateCommandProfile: TurnCommandProfile = commandProfile.general.includes('che_등용수락')
|
||||
? commandProfile
|
||||
: {
|
||||
...commandProfile,
|
||||
general: [...commandProfile.general, 'che_등용수락'],
|
||||
};
|
||||
const { general: definitions } = await buildReservedTurnDefinitions({
|
||||
env,
|
||||
commandProfile,
|
||||
commandProfile: immediateCommandProfile,
|
||||
defaultActionKey: DEFAULT_ACTION,
|
||||
});
|
||||
const generalModuleLoader = new GeneralTurnCommandLoader();
|
||||
|
||||
@@ -133,6 +133,7 @@ const buildWorld = (
|
||||
|
||||
const buildImmediateActionWorld = (options: {
|
||||
general: TurnGeneral;
|
||||
additionalGenerals?: TurnGeneral[];
|
||||
cities: TurnWorldSnapshot['cities'];
|
||||
nations: TurnWorldSnapshot['nations'];
|
||||
map: MapDefinition;
|
||||
@@ -162,7 +163,7 @@ const buildImmediateActionWorld = (options: {
|
||||
ignoreDefaultEvents: false,
|
||||
};
|
||||
const snapshot: TurnWorldSnapshot = {
|
||||
generals: [options.general],
|
||||
generals: [options.general, ...(options.additionalGenerals ?? [])],
|
||||
cities: options.cities,
|
||||
nations: options.nations,
|
||||
troops: [],
|
||||
@@ -480,6 +481,81 @@ describe('my information world commands', () => {
|
||||
expect(nextIntInclusive).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('loads the internal recruitment acceptance action outside the selectable command profile', async () => {
|
||||
const recipient = buildGeneral({
|
||||
id: 8,
|
||||
userId: 'user-8',
|
||||
name: '재야장수',
|
||||
nationId: 0,
|
||||
cityId: 1,
|
||||
officerLevel: 0,
|
||||
});
|
||||
const recruiter = buildGeneral({
|
||||
id: 9,
|
||||
userId: 'user-9',
|
||||
name: '등용장수',
|
||||
nationId: 2,
|
||||
cityId: 2,
|
||||
});
|
||||
const map = {
|
||||
id: 'test',
|
||||
name: 'test',
|
||||
cities: [buildMapCity(1, [2]), buildMapCity(2, [1])],
|
||||
};
|
||||
const fixture = buildImmediateActionWorld({
|
||||
general: recipient,
|
||||
additionalGenerals: [recruiter],
|
||||
cities: [
|
||||
{ id: 1, name: '낙양', nationId: 0, supplyState: 1, meta: {} },
|
||||
{ id: 2, name: '장안', nationId: 2, supplyState: 1, meta: {} },
|
||||
] as TurnWorldSnapshot['cities'],
|
||||
nations: [
|
||||
{
|
||||
id: 2,
|
||||
name: '등용국',
|
||||
color: '#222222',
|
||||
typeCode: 'che_중립',
|
||||
level: 1,
|
||||
capitalCityId: 2,
|
||||
chiefGeneralId: recruiter.id,
|
||||
gold: 0,
|
||||
rice: 0,
|
||||
power: 0,
|
||||
meta: { gennum: 1 },
|
||||
},
|
||||
] as TurnWorldSnapshot['nations'],
|
||||
map,
|
||||
});
|
||||
const executor = await createImmediateGeneralActionExecutor({
|
||||
world: fixture.world,
|
||||
reservedTurns: fixture.reservedTurns,
|
||||
scenarioMeta: fixture.scenarioMeta,
|
||||
map,
|
||||
commandProfile: {
|
||||
general: ['che_등용'],
|
||||
nation: [],
|
||||
},
|
||||
});
|
||||
|
||||
await expect(
|
||||
executor.execute({
|
||||
actionKey: 'che_등용수락',
|
||||
generalId: recipient.id,
|
||||
rng: new RandUtil(new LiteHashDRBG('accept-recruitment-letter')),
|
||||
args: { destNationId: 2, destGeneralId: recruiter.id },
|
||||
})
|
||||
).resolves.toEqual({ ok: true });
|
||||
expect(fixture.world.getGeneralById(recipient.id)).toMatchObject({
|
||||
nationId: 2,
|
||||
cityId: 2,
|
||||
officerLevel: 1,
|
||||
});
|
||||
expect(fixture.world.getGeneralById(recruiter.id)).toMatchObject({
|
||||
experience: recruiter.experience + 100,
|
||||
dedication: recruiter.dedication + 100,
|
||||
});
|
||||
});
|
||||
|
||||
it('preserves the Ref uprising precheck order and messages after the game starts', async () => {
|
||||
const general = buildGeneral({ nationId: 1, cityId: 1 });
|
||||
const fixture = buildImmediateActionWorld({
|
||||
|
||||
Reference in New Issue
Block a user