feat: add atmos property to General entity and update related logic
- Added `atmos` property to the `General` interface in `entities.ts`. - Initialized `atmos` to 0 in the `buildGeneralSeeds` function in `bootstrap.ts`. - Updated exports in `index.ts` to include `unitSet.js`. - Introduced new types for crew types and their requirements in `types.ts`. - Implemented `unitSetLoader.ts` for loading unit set definitions from JSON files. - Created `che_징병.ts` action for recruiting crew types with cost and training calculations. - Developed `unitSet.ts` for handling crew type availability and requirements. - Added tests for crew type availability and unit set parsing in `crewType.test.ts`.
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import type { City, General, Nation } from '../src/domain/entities.js';
|
||||
import type { MapDefinition } from '../src/world/types.js';
|
||||
import {
|
||||
isCrewTypeAvailable,
|
||||
parseUnitSetDefinition,
|
||||
} from '../src/world/unitSet.js';
|
||||
|
||||
const buildMap = (): MapDefinition => ({
|
||||
id: 'test',
|
||||
name: 'test',
|
||||
cities: [
|
||||
{
|
||||
id: 1,
|
||||
name: 'A',
|
||||
level: 6,
|
||||
region: 1,
|
||||
position: { x: 0, y: 0 },
|
||||
connections: [],
|
||||
max: {
|
||||
population: 100000,
|
||||
agriculture: 1000,
|
||||
commerce: 1000,
|
||||
security: 1000,
|
||||
defence: 1000,
|
||||
wall: 1000,
|
||||
},
|
||||
initial: {
|
||||
population: 50000,
|
||||
agriculture: 500,
|
||||
commerce: 500,
|
||||
security: 500,
|
||||
defence: 500,
|
||||
wall: 500,
|
||||
},
|
||||
},
|
||||
],
|
||||
meta: {
|
||||
regionMap: {
|
||||
A: 1,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const buildNation = (): Nation => ({
|
||||
id: 1,
|
||||
name: 'TestNation',
|
||||
color: '#000000',
|
||||
capitalCityId: 1,
|
||||
chiefGeneralId: null,
|
||||
gold: 1000,
|
||||
rice: 1000,
|
||||
power: 0,
|
||||
level: 1,
|
||||
typeCode: 'test',
|
||||
meta: {
|
||||
tech: 3000,
|
||||
},
|
||||
});
|
||||
|
||||
const buildGeneral = (): General => ({
|
||||
id: 1,
|
||||
name: 'TestGeneral',
|
||||
nationId: 1,
|
||||
cityId: 1,
|
||||
troopId: 0,
|
||||
stats: { leadership: 50, strength: 50, intelligence: 50 },
|
||||
experience: 0,
|
||||
dedication: 0,
|
||||
officerLevel: 3,
|
||||
role: {
|
||||
personality: null,
|
||||
specialDomestic: null,
|
||||
specialWar: null,
|
||||
items: {
|
||||
horse: null,
|
||||
weapon: null,
|
||||
book: null,
|
||||
item: null,
|
||||
},
|
||||
},
|
||||
injury: 0,
|
||||
gold: 1000,
|
||||
rice: 1000,
|
||||
crew: 0,
|
||||
crewTypeId: 1100,
|
||||
train: 0,
|
||||
atmos: 0,
|
||||
age: 20,
|
||||
npcState: 0,
|
||||
triggerState: {
|
||||
flags: {},
|
||||
counters: {},
|
||||
modifiers: {},
|
||||
meta: {},
|
||||
},
|
||||
meta: {},
|
||||
});
|
||||
|
||||
const buildCities = (): City[] => [
|
||||
{
|
||||
id: 1,
|
||||
name: 'A',
|
||||
nationId: 1,
|
||||
level: 6,
|
||||
population: 50000,
|
||||
populationMax: 100000,
|
||||
agriculture: 500,
|
||||
agricultureMax: 1000,
|
||||
commerce: 500,
|
||||
commerceMax: 1000,
|
||||
security: 500,
|
||||
securityMax: 1000,
|
||||
supplyState: 1,
|
||||
frontState: 0,
|
||||
defence: 500,
|
||||
defenceMax: 1000,
|
||||
wall: 500,
|
||||
wallMax: 1000,
|
||||
meta: {},
|
||||
},
|
||||
];
|
||||
|
||||
describe('crew type availability', () => {
|
||||
it('parses unit set data and normalizes coefficients', () => {
|
||||
const parsed = parseUnitSetDefinition({
|
||||
id: 'test',
|
||||
name: 'test',
|
||||
defaultCrewTypeId: 1100,
|
||||
crewTypes: [
|
||||
{
|
||||
id: 1100,
|
||||
armType: 1,
|
||||
name: '보병',
|
||||
attack: 100,
|
||||
defence: 100,
|
||||
speed: 7,
|
||||
avoid: 10,
|
||||
magicCoef: 0,
|
||||
cost: 9,
|
||||
rice: 9,
|
||||
requirements: [],
|
||||
attackCoef: [],
|
||||
defenceCoef: { 1: 1.2 },
|
||||
info: ['테스트'],
|
||||
initSkillTrigger: null,
|
||||
phaseSkillTrigger: null,
|
||||
iActionList: null,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expect(parsed.defaultCrewTypeId).toBe(1100);
|
||||
expect(parsed.crewTypes?.[0]?.attackCoef).toEqual({});
|
||||
});
|
||||
|
||||
it('checks tech/region/city requirements', () => {
|
||||
const unitSet = parseUnitSetDefinition({
|
||||
id: 'test',
|
||||
name: 'test',
|
||||
crewTypes: [
|
||||
{
|
||||
id: 1100,
|
||||
armType: 1,
|
||||
name: '기본',
|
||||
attack: 100,
|
||||
defence: 100,
|
||||
speed: 7,
|
||||
avoid: 10,
|
||||
magicCoef: 0,
|
||||
cost: 9,
|
||||
rice: 9,
|
||||
requirements: [],
|
||||
attackCoef: {},
|
||||
defenceCoef: {},
|
||||
info: [],
|
||||
initSkillTrigger: null,
|
||||
phaseSkillTrigger: null,
|
||||
iActionList: null,
|
||||
},
|
||||
{
|
||||
id: 1200,
|
||||
armType: 1,
|
||||
name: '기술병',
|
||||
attack: 100,
|
||||
defence: 100,
|
||||
speed: 7,
|
||||
avoid: 10,
|
||||
magicCoef: 0,
|
||||
cost: 9,
|
||||
rice: 9,
|
||||
requirements: [
|
||||
{ type: 'ReqTech', tech: 2000 },
|
||||
{ type: 'ReqRegions', regions: ['A'] },
|
||||
],
|
||||
attackCoef: {},
|
||||
defenceCoef: {},
|
||||
info: [],
|
||||
initSkillTrigger: null,
|
||||
phaseSkillTrigger: null,
|
||||
iActionList: null,
|
||||
},
|
||||
{
|
||||
id: 1300,
|
||||
armType: 1,
|
||||
name: '도시병',
|
||||
attack: 100,
|
||||
defence: 100,
|
||||
speed: 7,
|
||||
avoid: 10,
|
||||
magicCoef: 0,
|
||||
cost: 9,
|
||||
rice: 9,
|
||||
requirements: [
|
||||
{ type: 'ReqCitiesWithCityLevel', level: 7, cities: ['A'] },
|
||||
],
|
||||
attackCoef: {},
|
||||
defenceCoef: {},
|
||||
info: [],
|
||||
initSkillTrigger: null,
|
||||
phaseSkillTrigger: null,
|
||||
iActionList: null,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const context = {
|
||||
general: buildGeneral(),
|
||||
nation: buildNation(),
|
||||
map: buildMap(),
|
||||
cities: buildCities(),
|
||||
currentYear: 10,
|
||||
startYear: 1,
|
||||
};
|
||||
|
||||
expect(isCrewTypeAvailable(unitSet, 1100, context)).toBe(true);
|
||||
expect(isCrewTypeAvailable(unitSet, 1200, context)).toBe(true);
|
||||
expect(isCrewTypeAvailable(unitSet, 1300, context)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user