빙의 군주의 외교권자 임명 권한을 복구
This commit is contained in:
@@ -249,9 +249,9 @@ describe('nation personnel router', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('keeps ambassador and auditor candidate pools mutually exclusive like Ref', async () => {
|
it('keeps ambassador and auditor candidate pools mutually exclusive like Ref', async () => {
|
||||||
const me = { ...baseGeneral, officerLevel: 12 };
|
const me = { ...baseGeneral, officerLevel: 12, npcState: 1 };
|
||||||
const rows = [
|
const rows = [
|
||||||
listRow({ id: 22, name: '군주', officerLevel: 12 }),
|
listRow({ id: 22, name: '군주', officerLevel: 12, npcState: 1 }),
|
||||||
listRow({ id: 30, name: '현 외교권자', meta: { belong: 5, permission: 'ambassador' } }),
|
listRow({ id: 30, name: '현 외교권자', meta: { belong: 5, permission: 'ambassador' } }),
|
||||||
listRow({ id: 31, name: '현 조언자', meta: { belong: 5, permission: 'auditor' } }),
|
listRow({ id: 31, name: '현 조언자', meta: { belong: 5, permission: 'auditor' } }),
|
||||||
listRow({ id: 32, name: '일반 후보' }),
|
listRow({ id: 32, name: '일반 후보' }),
|
||||||
@@ -283,6 +283,7 @@ describe('nation personnel router', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const result = await appRouter.createCaller(context).nation.getPersonnelInfo();
|
const result = await appRouter.createCaller(context).nation.getPersonnelInfo();
|
||||||
|
expect(result.me.canChangePermissions).toBe(true);
|
||||||
expect(result.permissionCandidates.ambassadors.map((candidate) => candidate.id)).toEqual([30, 32]);
|
expect(result.permissionCandidates.ambassadors.map((candidate) => candidate.id)).toEqual([30, 32]);
|
||||||
expect(result.permissionCandidates.auditors.map((candidate) => candidate.id)).toEqual([31, 32]);
|
expect(result.permissionCandidates.auditors.map((candidate) => candidate.id)).toEqual([31, 32]);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -288,6 +288,12 @@ export const seedScenarioToDatabase = async (options: ScenarioSeedOptions): Prom
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
seed.cities = applyInitialChangeCityEvents(seed.cities, seed.initialEvents);
|
seed.cities = applyInitialChangeCityEvents(seed.cities, seed.initialEvents);
|
||||||
|
const seededRulerIds = new Map<number, number>();
|
||||||
|
for (const general of [...seed.generals].sort((left, right) => left.id - right.id)) {
|
||||||
|
if (general.officerLevel === 12 && !seededRulerIds.has(general.nationId)) {
|
||||||
|
seededRulerIds.set(general.nationId, general.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const connector = createGamePostgresConnector({ url: options.databaseUrl });
|
const connector = createGamePostgresConnector({ url: options.databaseUrl });
|
||||||
const generalGold = options.defaultGeneralGold ?? DEFAULT_GENERAL_GOLD;
|
const generalGold = options.defaultGeneralGold ?? DEFAULT_GENERAL_GOLD;
|
||||||
@@ -556,6 +562,7 @@ export const seedScenarioToDatabase = async (options: ScenarioSeedOptions): Prom
|
|||||||
name: nation.name,
|
name: nation.name,
|
||||||
color: nation.color,
|
color: nation.color,
|
||||||
capitalCityId: nation.capitalCityId ?? null,
|
capitalCityId: nation.capitalCityId ?? null,
|
||||||
|
chiefGeneralId: seededRulerIds.get(nation.id) ?? null,
|
||||||
gold: nation.gold,
|
gold: nation.gold,
|
||||||
rice: nation.rice,
|
rice: nation.rice,
|
||||||
tech: nation.tech,
|
tech: nation.tech,
|
||||||
|
|||||||
@@ -2144,7 +2144,7 @@ async function handleChangePermission(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
const nation = world.getNationById(general.nationId);
|
const nation = world.getNationById(general.nationId);
|
||||||
if (!nation || general.officerLevel !== 12 || nation.chiefGeneralId !== general.id) {
|
if (!nation || general.officerLevel !== 12) {
|
||||||
return { type: 'changePermission', ok: false, generalId: command.generalId, reason: '군주가 아닙니다.' };
|
return { type: 'changePermission', ok: false, generalId: command.generalId, reason: '군주가 아닙니다.' };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ const buildGeneral = (id: number, overrides: Partial<TurnGeneral> = {}): TurnGen
|
|||||||
const buildWorld = (options: {
|
const buildWorld = (options: {
|
||||||
generals?: TurnGeneral[];
|
generals?: TurnGeneral[];
|
||||||
nationMeta?: Record<string, TriggerValue>;
|
nationMeta?: Record<string, TriggerValue>;
|
||||||
|
nationChiefGeneralId?: number | null;
|
||||||
cityMeta?: Record<string, TriggerValue>;
|
cityMeta?: Record<string, TriggerValue>;
|
||||||
currentYear?: number;
|
currentYear?: number;
|
||||||
scenarioConst?: Record<string, unknown>;
|
scenarioConst?: Record<string, unknown>;
|
||||||
@@ -106,7 +107,7 @@ const buildWorld = (options: {
|
|||||||
name: '위',
|
name: '위',
|
||||||
color: '#777777',
|
color: '#777777',
|
||||||
capitalCityId: 1,
|
capitalCityId: 1,
|
||||||
chiefGeneralId: 1,
|
chiefGeneralId: options.nationChiefGeneralId === undefined ? 1 : options.nationChiefGeneralId,
|
||||||
gold: 10_000,
|
gold: 10_000,
|
||||||
rice: 20_000,
|
rice: 20_000,
|
||||||
power: 0,
|
power: 0,
|
||||||
@@ -321,6 +322,26 @@ describe('nation personnel world commands', () => {
|
|||||||
expect(fixture.world.getGeneralById(3)?.meta.permission).toBe('normal');
|
expect(fixture.world.getGeneralById(3)?.meta.permission).toBe('normal');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('allows a possessed ruler to appoint an ambassador when a seeded nation has no chief pointer', async () => {
|
||||||
|
const fixture = buildWorld({
|
||||||
|
nationChiefGeneralId: null,
|
||||||
|
generals: [
|
||||||
|
buildGeneral(1, { officerLevel: 12, npcState: 1 }),
|
||||||
|
buildGeneral(2, { npcState: 2 }),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
await expect(
|
||||||
|
fixture.handler.handle({
|
||||||
|
type: 'changePermission',
|
||||||
|
userId: 'user-1',
|
||||||
|
generalId: 1,
|
||||||
|
isAmbassador: true,
|
||||||
|
targetGeneralIds: [2],
|
||||||
|
})
|
||||||
|
).resolves.toMatchObject({ ok: true });
|
||||||
|
expect(fixture.world.getGeneralById(2)?.meta.permission).toBe('ambassador');
|
||||||
|
});
|
||||||
|
|
||||||
it('kicks for an unlocked head officer with resource, troop, permission, and log side effects', async () => {
|
it('kicks for an unlocked head officer with resource, troop, permission, and log side effects', async () => {
|
||||||
const target = buildGeneral(3, {
|
const target = buildGeneral(3, {
|
||||||
troopId: 3,
|
troopId: 3,
|
||||||
|
|||||||
@@ -591,6 +591,11 @@ describeDb('scenario database seed', () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
expect(nationCount).toBe(seed.nations.length);
|
expect(nationCount).toBe(seed.nations.length);
|
||||||
|
const seededRuler = seed.generals.find((general) => general.officerLevel === 12 && general.nationId > 0);
|
||||||
|
expect(seededRuler).toBeDefined();
|
||||||
|
expect(
|
||||||
|
(await connector.prisma.nation.findUnique({ where: { id: seededRuler!.nationId } }))?.chiefGeneralId
|
||||||
|
).toBe(seededRuler!.id);
|
||||||
expect(cityCount).toBe(seed.cities.length);
|
expect(cityCount).toBe(seed.cities.length);
|
||||||
expect(generalCount).toBe(seed.generals.length);
|
expect(generalCount).toBe(seed.generals.length);
|
||||||
expect(diplomacyCount).toBe(seed.nations.length * Math.max(0, seed.nations.length - 1));
|
expect(diplomacyCount).toBe(seed.nations.length * Math.max(0, seed.nations.length - 1));
|
||||||
|
|||||||
Reference in New Issue
Block a user