merge: 최신 main을 유산 포인트 정합화 작업에 반영한다
This commit is contained in:
@@ -282,7 +282,12 @@ export const createRaiseInvaderHandler = (options: {
|
|||||||
world.updateCity(city.id, { nationId: 0, frontState: 0, supplyState: 1 });
|
world.updateCity(city.id, { nationId: 0, frontState: 0, supplyState: 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const existingNationIds = world.listNations().map((nation) => nation.id);
|
// Ref nation table에는 Core의 `id=0 재야` row가 없으므로, 이민족과
|
||||||
|
// 전쟁 관계를 만들 실제 국가만 ID 증가와 외교 생성의 기준으로 삼는다.
|
||||||
|
const existingNationIds = world
|
||||||
|
.listNations()
|
||||||
|
.filter((nation) => nation.id > 0)
|
||||||
|
.map((nation) => nation.id);
|
||||||
const currentLastNationId = readNumber(world.getState().meta.lastNationId);
|
const currentLastNationId = readNumber(world.getState().meta.lastNationId);
|
||||||
const liveNationMaxId = existingNationIds.reduce((maxId, id) => Math.max(maxId, id), 0);
|
const liveNationMaxId = existingNationIds.reduce((maxId, id) => Math.max(maxId, id), 0);
|
||||||
let lastNationId = Math.max(currentLastNationId, liveNationMaxId);
|
let lastNationId = Math.max(currentLastNationId, liveNationMaxId);
|
||||||
@@ -499,12 +504,13 @@ export const createInvaderEndingHandler = (options: {
|
|||||||
if (isUnited === 0 || isUnited === 2) {
|
if (isUnited === 0 || isUnited === 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const nations = world.listNations();
|
// Ref의 nation table에는 Core가 domain/DB에 유지하는 `id=0 재야` row가
|
||||||
// Ref는 국가명 `ⓞ` prefix로 이벤트 승자를 구분한다. 전체 국가 수로
|
// 없다. 실제 승패 국가만 남긴 뒤 `ⓞ` prefix로 이벤트 승자를 구분한다.
|
||||||
// 막으면 서로 불가침 중인 이민족이 여럿 남았을 때 일반국 전멸 뒤에도
|
// 전체 국가 수로 막으면 서로 불가침 중인 이민족이 여럿 남았을 때
|
||||||
// 종료할 수 없으므로, 일반국의 부재를 직접 판정한다.
|
// 일반국 전멸 뒤에도 종료할 수 없으므로, 일반국의 부재를 직접 판정한다.
|
||||||
const ordinaryNations = nations.filter((nation) => !nation.name.startsWith(INVADER_PREFIX));
|
const activeNations = world.listNations().filter((nation) => nation.id > 0);
|
||||||
const invaderNations = nations.filter((nation) => nation.name.startsWith(INVADER_PREFIX));
|
const ordinaryNations = activeNations.filter((nation) => !nation.name.startsWith(INVADER_PREFIX));
|
||||||
|
const invaderNations = activeNations.filter((nation) => nation.name.startsWith(INVADER_PREFIX));
|
||||||
const cities = world.listCities();
|
const cities = world.listCities();
|
||||||
const neutralCityCount = cities.filter((city) => city.nationId === 0).length;
|
const neutralCityCount = cities.filter((city) => city.nationId === 0).length;
|
||||||
const userWin = ordinaryNations.length === 1 && invaderNations.length === 0 && neutralCityCount === 0;
|
const userWin = ordinaryNations.length === 1 && invaderNations.length === 0 && neutralCityCount === 0;
|
||||||
|
|||||||
@@ -49,6 +49,14 @@ const buildNation = (id: number, capitalCityId = 1, name = `국가${id}`): Natio
|
|||||||
meta: { tech: 100, war: 1, scout: 1 },
|
meta: { tech: 100, war: 1, scout: 1 },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const buildNeutralNation = (): Nation => ({
|
||||||
|
...buildNation(0, 0, '재야'),
|
||||||
|
chiefGeneralId: null,
|
||||||
|
level: 0,
|
||||||
|
typeCode: 'che_중립',
|
||||||
|
meta: {},
|
||||||
|
});
|
||||||
|
|
||||||
const buildGeneral = (overrides: Partial<TurnGeneral> = {}): TurnGeneral => ({
|
const buildGeneral = (overrides: Partial<TurnGeneral> = {}): TurnGeneral => ({
|
||||||
id: 1,
|
id: 1,
|
||||||
userId: null,
|
userId: null,
|
||||||
@@ -347,6 +355,7 @@ describe('invader monthly actions', () => {
|
|||||||
};
|
};
|
||||||
const harness = buildHarness({
|
const harness = buildHarness({
|
||||||
cities: [buildCity(1, 1, 3)],
|
cities: [buildCity(1, 1, 3)],
|
||||||
|
nations: [buildNeutralNation(), buildNation(1)],
|
||||||
events: [endingEvent],
|
events: [endingEvent],
|
||||||
meta: { isunited: 1, refreshLimit: 3 },
|
meta: { isunited: 1, refreshLimit: 3 },
|
||||||
});
|
});
|
||||||
@@ -387,7 +396,7 @@ describe('invader monthly actions', () => {
|
|||||||
];
|
];
|
||||||
const harness = buildHarness({
|
const harness = buildHarness({
|
||||||
cities: [buildCity(1, 2, 4), buildCity(2, 3, 4)],
|
cities: [buildCity(1, 2, 4), buildCity(2, 3, 4)],
|
||||||
nations: invaderNations,
|
nations: [buildNeutralNation(), ...invaderNations],
|
||||||
generals: [],
|
generals: [],
|
||||||
events: [endingEvent],
|
events: [endingEvent],
|
||||||
meta: { isunited: 1, refreshLimit: 3 },
|
meta: { isunited: 1, refreshLimit: 3 },
|
||||||
@@ -427,7 +436,12 @@ describe('invader monthly actions', () => {
|
|||||||
};
|
};
|
||||||
const harness = buildHarness({
|
const harness = buildHarness({
|
||||||
cities: [buildCity(1, 1, 3), buildCity(2, 2, 4), buildCity(3, 3, 4)],
|
cities: [buildCity(1, 1, 3), buildCity(2, 2, 4), buildCity(3, 3, 4)],
|
||||||
nations: [buildNation(1), buildNation(2, 2, 'ⓞ남만족'), buildNation(3, 3, 'ⓞ산월족')],
|
nations: [
|
||||||
|
buildNeutralNation(),
|
||||||
|
buildNation(1),
|
||||||
|
buildNation(2, 2, 'ⓞ남만족'),
|
||||||
|
buildNation(3, 3, 'ⓞ산월족'),
|
||||||
|
],
|
||||||
events: [endingEvent],
|
events: [endingEvent],
|
||||||
meta: { isunited: 1, refreshLimit: 3 },
|
meta: { isunited: 1, refreshLimit: 3 },
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -109,6 +109,19 @@ const buildCity = (id: number, nationId: number, level: number, name: string): C
|
|||||||
|
|
||||||
const ordinaryCity = buildCity(ordinaryCityId, existingNationId, 3, '기준도시');
|
const ordinaryCity = buildCity(ordinaryCityId, existingNationId, 3, '기준도시');
|
||||||
const invaderCity = buildCity(invaderCityId, 0, 4, '남만');
|
const invaderCity = buildCity(invaderCityId, 0, 4, '남만');
|
||||||
|
const neutralNation: Nation = {
|
||||||
|
id: 0,
|
||||||
|
name: '재야',
|
||||||
|
color: '#000000',
|
||||||
|
capitalCityId: null,
|
||||||
|
chiefGeneralId: null,
|
||||||
|
gold: 0,
|
||||||
|
rice: 0,
|
||||||
|
power: 0,
|
||||||
|
level: 0,
|
||||||
|
typeCode: 'che_중립',
|
||||||
|
meta: {},
|
||||||
|
};
|
||||||
const existingNation: Nation = {
|
const existingNation: Nation = {
|
||||||
id: existingNationId,
|
id: existingNationId,
|
||||||
name: '기준국',
|
name: '기준국',
|
||||||
@@ -199,7 +212,9 @@ integration('RaiseInvader database persistence', () => {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await db.nation.deleteMany({ where: { id: { in: [existingNationId, createdNationId] } } });
|
await db.nation.deleteMany({
|
||||||
|
where: { id: { in: [neutralNation.id, existingNationId, createdNationId] } },
|
||||||
|
});
|
||||||
await db.city.deleteMany({ where: { id: { in: [ordinaryCityId, invaderCityId] } } });
|
await db.city.deleteMany({ where: { id: { in: [ordinaryCityId, invaderCityId] } } });
|
||||||
await db.event.deleteMany({ where: { id: { in: [sourceEventId, ...createdEventIds] } } });
|
await db.event.deleteMany({ where: { id: { in: [sourceEventId, ...createdEventIds] } } });
|
||||||
await db.worldState.deleteMany({ where: { scenarioCode: 'monthly-invader-persistence' } });
|
await db.worldState.deleteMany({ where: { scenarioCode: 'monthly-invader-persistence' } });
|
||||||
@@ -251,6 +266,21 @@ integration('RaiseInvader database persistence', () => {
|
|||||||
});
|
});
|
||||||
await createCity(ordinaryCity);
|
await createCity(ordinaryCity);
|
||||||
await createCity(invaderCity);
|
await createCity(invaderCity);
|
||||||
|
await db.nation.create({
|
||||||
|
data: {
|
||||||
|
id: neutralNation.id,
|
||||||
|
name: neutralNation.name,
|
||||||
|
color: neutralNation.color,
|
||||||
|
capitalCityId: neutralNation.capitalCityId,
|
||||||
|
chiefGeneralId: neutralNation.chiefGeneralId,
|
||||||
|
gold: neutralNation.gold,
|
||||||
|
rice: neutralNation.rice,
|
||||||
|
tech: 0,
|
||||||
|
level: neutralNation.level,
|
||||||
|
typeCode: neutralNation.typeCode,
|
||||||
|
meta: neutralNation.meta,
|
||||||
|
},
|
||||||
|
});
|
||||||
await db.nation.create({
|
await db.nation.create({
|
||||||
data: {
|
data: {
|
||||||
id: existingNationId,
|
id: existingNationId,
|
||||||
@@ -343,7 +373,7 @@ integration('RaiseInvader database persistence', () => {
|
|||||||
map: { id: 'test', name: 'test', cities: [] },
|
map: { id: 'test', name: 'test', cities: [] },
|
||||||
generals: [existingGeneral],
|
generals: [existingGeneral],
|
||||||
cities: [ordinaryCity, invaderCity],
|
cities: [ordinaryCity, invaderCity],
|
||||||
nations: [existingNation],
|
nations: [neutralNation, existingNation],
|
||||||
troops: [],
|
troops: [],
|
||||||
diplomacy: [],
|
diplomacy: [],
|
||||||
events: [sourceEvent],
|
events: [sourceEvent],
|
||||||
@@ -406,7 +436,22 @@ integration('RaiseInvader database persistence', () => {
|
|||||||
OR: [{ srcNationId: createdNationId }, { destNationId: createdNationId }],
|
OR: [{ srcNationId: createdNationId }, { destNationId: createdNationId }],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
).toBe(2);
|
).toBe(4);
|
||||||
|
expect(
|
||||||
|
await db.diplomacy.findMany({
|
||||||
|
where: {
|
||||||
|
OR: [
|
||||||
|
{ srcNationId: neutralNation.id, destNationId: createdNationId },
|
||||||
|
{ srcNationId: createdNationId, destNationId: neutralNation.id },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
orderBy: [{ srcNationId: 'asc' }, { destNationId: 'asc' }],
|
||||||
|
select: { srcNationId: true, destNationId: true, stateCode: true, term: true },
|
||||||
|
})
|
||||||
|
).toEqual([
|
||||||
|
{ srcNationId: neutralNation.id, destNationId: createdNationId, stateCode: 2, term: 0 },
|
||||||
|
{ srcNationId: createdNationId, destNationId: neutralNation.id, stateCode: 2, term: 0 },
|
||||||
|
]);
|
||||||
expect(
|
expect(
|
||||||
await db.event.findMany({
|
await db.event.findMany({
|
||||||
where: { id: { in: createdEventIds } },
|
where: { id: { in: createdEventIds } },
|
||||||
|
|||||||
Reference in New Issue
Block a user