fix(game): 국가 수 판정에서 합성 재야를 제외한다
Ref nation table에 없는 id=0 행이 정찰 차단과 월간 경매 난수 소비에 관여하지 않도록 모집단을 맞춘다. Ref의 maxnation 건국 표시 제한도 실행 제약을 늘리지 않고 명령표에 이관한다.
This commit is contained in:
@@ -119,7 +119,8 @@ export const createNeutralAuctionRegistrar = async (options: {
|
||||
hiddenSeed,
|
||||
seedYear: context.previousYear,
|
||||
seedMonth: context.previousMonth,
|
||||
nationCount: options.getNationPowerRollCount?.() ?? world.listNations().length,
|
||||
nationCount:
|
||||
options.getNationPowerRollCount?.() ?? world.listNations().filter((nation) => nation.id > 0).length,
|
||||
consumeTournamentRoll,
|
||||
averageGold: average(eligibleGenerals.map((general) => general.gold)),
|
||||
averageRice: average(eligibleGenerals.map((general) => general.rice)),
|
||||
|
||||
@@ -25,7 +25,10 @@ export const createScoutBlockHandler = (options: {
|
||||
// changing nation or game state. No provided scenario invokes it.
|
||||
throw new Error('update(): at least 3 arguments expected');
|
||||
}
|
||||
for (const nation of world.listNations()) {
|
||||
// Ref updates every row in its nation table. Core additionally keeps a
|
||||
// synthetic id=0 neutral row, which is not a Ref nation row and must
|
||||
// remain outside the last-nation scout policy.
|
||||
for (const nation of world.listNations().filter((entry) => entry.id > 0)) {
|
||||
world.updateNation(nation.id, {
|
||||
meta: {
|
||||
...nation.meta,
|
||||
|
||||
@@ -414,7 +414,8 @@ const createMonthlyCalendarRuntime = async (options: {
|
||||
clock: Clock;
|
||||
}) => {
|
||||
const cache: MonthlyRuntimeCache = {
|
||||
nationPowerRollCount: options.snapshot.nations.length,
|
||||
// Ref's monthly nation query has no Core-only id=0 neutral row.
|
||||
nationPowerRollCount: options.snapshot.nations.filter((nation) => nation.id > 0).length,
|
||||
tournamentRollConsumed: false,
|
||||
};
|
||||
const unification = options.calendarHandlerOverride
|
||||
|
||||
@@ -87,16 +87,18 @@ const buildWorld = (
|
||||
describe('monthly scout block actions', () => {
|
||||
it('blocks joining for all nations and globally locks policy changes', async () => {
|
||||
const world = buildWorld(0);
|
||||
world.addNation(buildNation(0, 0));
|
||||
await createScoutBlockHandler({ actionName: 'BlockScoutAction', getWorld: () => world })(
|
||||
[true],
|
||||
{ year: 200, month: 1, startyear: 190, currentEventID: 1, turnTime: new Date() },
|
||||
event
|
||||
);
|
||||
|
||||
expect(world.listNations().map((nation) => nation.meta)).toEqual([
|
||||
{ scout: 1, marker: 1 },
|
||||
{ scout: 1, marker: 2 },
|
||||
]);
|
||||
expect(Object.fromEntries(world.listNations().map((nation) => [nation.id, nation.meta]))).toEqual({
|
||||
0: { scout: 0, marker: 0 },
|
||||
1: { scout: 1, marker: 1 },
|
||||
2: { scout: 1, marker: 2 },
|
||||
});
|
||||
expect(world.getState().meta.block_change_scout).toBe(true);
|
||||
});
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import type { TurnEvent, TurnWorldSnapshot, TurnWorldState } from '../src/turn/t
|
||||
const databaseUrl = process.env.INPUT_EVENT_DATABASE_URL;
|
||||
const integration = describe.skipIf(!databaseUrl);
|
||||
const nationIds = [990_081, 990_082] as const;
|
||||
const neutralNationId = 0;
|
||||
|
||||
const buildNation = (id: number): Nation => ({
|
||||
id,
|
||||
@@ -49,7 +50,7 @@ integration('monthly scout block persistence', () => {
|
||||
OR: [{ srcNationId: { in: [...nationIds] } }, { destNationId: { in: [...nationIds] } }],
|
||||
},
|
||||
});
|
||||
await db.nation.deleteMany({ where: { id: { in: [...nationIds] } } });
|
||||
await db.nation.deleteMany({ where: { id: { in: [neutralNationId, ...nationIds] } } });
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
@@ -58,12 +59,13 @@ integration('monthly scout block persistence', () => {
|
||||
OR: [{ srcNationId: { in: [...nationIds] } }, { destNationId: { in: [...nationIds] } }],
|
||||
},
|
||||
});
|
||||
await db.nation.deleteMany({ where: { id: { in: [...nationIds] } } });
|
||||
await db.nation.deleteMany({ where: { id: { in: [neutralNationId, ...nationIds] } } });
|
||||
await closeDb?.();
|
||||
});
|
||||
|
||||
it('persists every nation scout flag and the global policy lock in one flush', async () => {
|
||||
const nations = nationIds.map(buildNation);
|
||||
const neutralNation = { ...buildNation(neutralNationId), name: '재야', level: 0 };
|
||||
const nations = [neutralNation, ...nationIds.map(buildNation)];
|
||||
await db.nation.createMany({
|
||||
data: nations.map((nation) => ({
|
||||
id: nation.id,
|
||||
@@ -146,6 +148,9 @@ integration('monthly scout block persistence', () => {
|
||||
{ power: 0, scout: 1 },
|
||||
{ power: 0, scout: 1 },
|
||||
]);
|
||||
expect(await db.nation.findUniqueOrThrow({ where: { id: neutralNationId } })).toMatchObject({
|
||||
meta: { scout: 0 },
|
||||
});
|
||||
expect(await db.worldState.findUniqueOrThrow({ where: { id: row.id } })).toMatchObject({
|
||||
meta: { block_change_scout: true },
|
||||
});
|
||||
|
||||
@@ -41,7 +41,9 @@ const buildSnapshot = (): TurnWorldSnapshot => ({
|
||||
buildGeneral(2, 2, 99_999, 99_999),
|
||||
],
|
||||
cities: [],
|
||||
nations: [1, 2, 3].map((id) => ({
|
||||
// Core persists a synthetic id=0 row that Ref's nation-power loop never
|
||||
// sees. The registrar fallback must therefore still consume three rolls.
|
||||
nations: [0, 1, 2, 3].map((id) => ({
|
||||
id,
|
||||
name: `Nation_${id}`,
|
||||
color: '#000000',
|
||||
@@ -151,7 +153,7 @@ describe('neutral auction monthly registrar', () => {
|
||||
loadNeutralAuctionCounts: async () => [],
|
||||
});
|
||||
const snapshot = buildSnapshot();
|
||||
snapshot.nations = snapshot.nations.slice(0, 2);
|
||||
snapshot.nations = snapshot.nations.slice(1, 3);
|
||||
snapshot.generals = [buildGeneral(1, 0, 5_000, 7_000), buildGeneral(2, 0, 6_000, 8_000)];
|
||||
const state: TurnWorldState = {
|
||||
id: 1,
|
||||
|
||||
Reference in New Issue
Block a user