feat: add killturn to general meta and update related tests

- Introduced a new meta property `killturn` to the GeneralMeta interface.
- Implemented a function `readMetaNumber` to handle the retrieval of numeric values from meta.
- Updated the `mapGeneralRow` function to ensure `killturn` is required and properly handled.
- Modified various tests to include the `killturn` property in the general's meta data.
- Adjusted related action files to utilize the new GeneralMeta type for better type safety.
- Ensured backward compatibility by updating existing test cases across multiple scenarios.
This commit is contained in:
2026-01-25 05:48:56 +00:00
parent 340cadb8ce
commit 5d5ed9ee2a
39 changed files with 164 additions and 99 deletions
+1
View File
@@ -122,6 +122,7 @@ const mapGeneralPayload = (payload: BattleSimJobPayload['attackerGeneral']): Gen
meta: payload.inheritBuff ? { inheritBuff: JSON.stringify(payload.inheritBuff) } : {}, meta: payload.inheritBuff ? { inheritBuff: JSON.stringify(payload.inheritBuff) } : {},
}, },
meta: { meta: {
killturn: 24,
explevel: payload.explevel, explevel: payload.explevel,
turnTime: payload.turntime, turnTime: payload.turntime,
recentWar: payload.recent_war ?? '', recentWar: payload.recent_war ?? '',
+23 -1
View File
@@ -77,6 +77,28 @@ const DEFAULT_CREW_TYPE_ID = 1100;
const asTriggerRecord = (value: unknown): Record<string, TriggerValue> => const asTriggerRecord = (value: unknown): Record<string, TriggerValue> =>
isRecord(value) ? (value as Record<string, TriggerValue>) : {}; isRecord(value) ? (value as Record<string, TriggerValue>) : {};
const readMetaNumber = (meta: Record<string, TriggerValue>, key: string): number | null => {
const value = meta[key];
if (typeof value === 'number' && Number.isFinite(value)) {
return value;
}
if (typeof value === 'string') {
const parsed = Number(value);
if (Number.isFinite(parsed)) {
return parsed;
}
}
return null;
};
const ensureGeneralMeta = (meta: Record<string, TriggerValue>, generalId: number): General['meta'] => {
const killturn = readMetaNumber(meta, 'killturn');
if (killturn === null) {
throw new Error(`general.meta.killturn is required (generalId=${generalId}).`);
}
return { ...meta, killturn } as General['meta'];
};
const normalizeCode = (value: string | null | undefined): string | null => { const normalizeCode = (value: string | null | undefined): string | null => {
if (!value || value === 'None') { if (!value || value === 'None') {
return null; return null;
@@ -238,7 +260,7 @@ const mapGeneralRow = (row: GeneralRow): General => ({
modifiers: {}, modifiers: {},
meta: {}, meta: {},
}, },
meta: asTriggerRecord(row.meta), meta: ensureGeneralMeta(asTriggerRecord(row.meta), row.id),
}); });
const mapCityRow = (row: CityRow): City => { const mapCityRow = (row: CityRow): City => {
+23 -1
View File
@@ -38,6 +38,20 @@ const normalizeCode = (value: string | null | undefined): string | null => {
return value; return value;
}; };
const readMetaNumber = (meta: Record<string, unknown>, key: string): number | null => {
const value = meta[key];
if (typeof value === 'number' && Number.isFinite(value)) {
return value;
}
if (typeof value === 'string') {
const parsed = Number(value);
if (Number.isFinite(parsed)) {
return parsed;
}
}
return null;
};
const zScenarioStatBlock = z.object({ const zScenarioStatBlock = z.object({
total: z.number(), total: z.number(),
min: z.number(), min: z.number(),
@@ -120,6 +134,14 @@ const mapScenarioConfig = (raw: JsonValue): ScenarioConfig => {
}; };
const mapGeneralRow = (row: TurnEngineGeneralRow): TurnGeneral => ({ const mapGeneralRow = (row: TurnEngineGeneralRow): TurnGeneral => ({
...((): { meta: TurnGeneral['meta'] } => {
const meta = asTriggerRecord(row.meta) as Record<string, unknown>;
const killturn = readMetaNumber(meta, 'killturn');
if (killturn === null) {
throw new Error(`general.meta.killturn is required (generalId=${row.id}).`);
}
return { meta: { ...meta, killturn } as TurnGeneral['meta'] };
})(),
id: row.id, id: row.id,
name: row.name, name: row.name,
nationId: row.nationId, nationId: row.nationId,
@@ -159,7 +181,7 @@ const mapGeneralRow = (row: TurnEngineGeneralRow): TurnGeneral => ({
modifiers: {}, modifiers: {},
meta: {}, meta: {},
}, },
meta: asTriggerRecord(row.meta), // meta는 상단에서 보장 처리됨.
turnTime: row.turnTime, turnTime: row.turnTime,
recentWarTime: row.recentWarTime ?? null, recentWarTime: row.recentWarTime ?? null,
}); });
@@ -30,7 +30,7 @@ const createNpcGeneral = (
specialWar: null, specialWar: null,
}, },
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 800 },
officerLevel, officerLevel,
experience: 0, experience: 0,
dedication: 0, dedication: 0,
@@ -40,7 +40,7 @@ const createNpcGeneral = (
specialWar: null, specialWar: null,
}, },
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 800 },
officerLevel: 1, officerLevel: 1,
experience: 0, experience: 0,
dedication: 0, dedication: 0,
@@ -30,7 +30,7 @@ const createNpcGeneral = (
specialWar: null, specialWar: null,
}, },
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 800 },
officerLevel, officerLevel,
experience: 0, experience: 0,
dedication: 0, dedication: 0,
@@ -27,7 +27,7 @@ const createNpcGeneral = (
specialWar: null, specialWar: null,
}, },
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 800 },
officerLevel: 1, officerLevel: 1,
experience: 0, experience: 0,
dedication: 0, dedication: 0,
@@ -29,7 +29,7 @@ const createNpcGeneral = (
specialWar: null, specialWar: null,
}, },
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 800 },
officerLevel, officerLevel,
experience: 0, experience: 0,
dedication: 0, dedication: 0,
+1 -1
View File
@@ -28,7 +28,7 @@ const createNpcGeneral = (
specialWar: null, specialWar: null,
}, },
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 800 },
officerLevel, officerLevel,
experience: 0, experience: 0,
dedication: 0, dedication: 0,
@@ -93,7 +93,7 @@ describe('Reserved Turn Execution Integration', () => {
specialWar: null, specialWar: null,
}, },
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 800 },
officerLevel: 5, officerLevel: 5,
experience: 0, experience: 0,
dedication: 0, dedication: 0,
@@ -122,7 +122,7 @@ describe('Reserved Turn Execution Integration', () => {
specialWar: null, specialWar: null,
}, },
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 800 },
officerLevel: 5, officerLevel: 5,
experience: 0, experience: 0,
dedication: 0, dedication: 0,
@@ -340,7 +340,7 @@ describe('Reserved Turn Execution Integration', () => {
specialWar: null, specialWar: null,
}, },
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 800 },
officerLevel: 5, officerLevel: 5,
experience: 0, experience: 0,
dedication: 0, dedication: 0,
@@ -480,7 +480,7 @@ describe('Reserved Turn Execution Integration', () => {
specialWar: null, specialWar: null,
}, },
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 800 },
officerLevel: 5, officerLevel: 5,
experience: 0, experience: 0,
dedication: 0, dedication: 0,
@@ -646,7 +646,7 @@ describe('Reserved Turn Execution Integration', () => {
specialWar: null, specialWar: null,
}, },
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
officerLevel: 5, officerLevel: 5,
experience: 0, experience: 0,
dedication: 0, dedication: 0,
@@ -675,7 +675,7 @@ describe('Reserved Turn Execution Integration', () => {
specialWar: null, specialWar: null,
}, },
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
officerLevel: 5, officerLevel: 5,
experience: 0, experience: 0,
dedication: 0, dedication: 0,
@@ -947,7 +947,7 @@ describe('Reserved Turn Execution Integration', () => {
specialWar: null, specialWar: null,
}, },
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
officerLevel: 5, officerLevel: 5,
experience: 0, experience: 0,
dedication: 0, dedication: 0,
@@ -976,7 +976,7 @@ describe('Reserved Turn Execution Integration', () => {
specialWar: null, specialWar: null,
}, },
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
officerLevel: 5, officerLevel: 5,
experience: 0, experience: 0,
dedication: 0, dedication: 0,
+1 -1
View File
@@ -21,7 +21,7 @@ const buildGeneral = (id: number, turnTime: Date): TurnGeneral => ({
specialWar: null, specialWar: null,
}, },
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
officerLevel: 5, officerLevel: 5,
experience: 0, experience: 0,
dedication: 0, dedication: 0,
@@ -1,5 +1,5 @@
import type { RandomGenerator } from '@sammo-ts/common'; import type { RandomGenerator } from '@sammo-ts/common';
import type { City, General, GeneralTriggerState, Nation } from '@sammo-ts/logic/domain/entities.js'; import type { City, General, GeneralMeta, GeneralTriggerState, Nation } from '@sammo-ts/logic/domain/entities.js';
import type { Constraint, ConstraintContext, RequirementKey, StateView } from '@sammo-ts/logic/constraints/types.js'; import type { Constraint, ConstraintContext, RequirementKey, StateView } from '@sammo-ts/logic/constraints/types.js';
import { import {
notBeNeutral, notBeNeutral,
@@ -85,7 +85,7 @@ const pickByWeight = (rng: RandomGenerator, weights: Record<DomesticCriticalPick
return 'normal'; return 'normal';
}; };
const addMetaNumber = (meta: Record<string, unknown>, key: string, delta: number): Record<string, unknown> => { const addMetaNumber = (meta: GeneralMeta, key: string, delta: number): GeneralMeta => {
const current = getMetaNumber(meta, key) ?? 0; const current = getMetaNumber(meta, key) ?? 0;
return { ...meta, [key]: current + delta }; return { ...meta, [key]: current + delta };
}; };
@@ -1,5 +1,12 @@
import type { RandomGenerator } from '@sammo-ts/common'; import type { RandomGenerator } from '@sammo-ts/common';
import type { City, General, GeneralTriggerState, StatBlock, TriggerValue } from '@sammo-ts/logic/domain/entities.js'; import type {
City,
General,
GeneralMeta,
GeneralTriggerState,
StatBlock,
TriggerValue,
} from '@sammo-ts/logic/domain/entities.js';
import type { Constraint, ConstraintContext } from '@sammo-ts/logic/constraints/types.js'; import type { Constraint, ConstraintContext } from '@sammo-ts/logic/constraints/types.js';
import { reqGeneralGold, reqGeneralRice } from '@sammo-ts/logic/constraints/presets.js'; import { reqGeneralGold, reqGeneralRice } from '@sammo-ts/logic/constraints/presets.js';
import { GeneralActionPipeline, type GeneralActionModule } from '@sammo-ts/logic/triggers/general-action.js'; import { GeneralActionPipeline, type GeneralActionModule } from '@sammo-ts/logic/triggers/general-action.js';
@@ -90,11 +97,7 @@ const addMetaValue = (
meta[key] = value; meta[key] = value;
}; };
const addMetaNumber = ( const addMetaNumber = (meta: GeneralMeta, key: StatExpKey, delta: number): GeneralMeta => {
meta: Record<string, TriggerValue>,
key: StatExpKey,
delta: number
): Record<string, TriggerValue> => {
const current = typeof meta[key] === 'number' ? (meta[key] as number) : 0; const current = typeof meta[key] === 'number' ? (meta[key] as number) : 0;
return { ...meta, [key]: current + delta }; return { ...meta, [key]: current + delta };
}; };
@@ -298,7 +301,8 @@ export class ActionResolver<
const name = this.env.decorateName const name = this.env.decorateName
? this.env.decorateName(resolvedCandidate.name, NPC_TYPE) ? this.env.decorateName(resolvedCandidate.name, NPC_TYPE)
: resolvedCandidate.name; : resolvedCandidate.name;
const meta: Record<string, TriggerValue> = { const meta: GeneralMeta = {
killturn: context.general.meta.killturn,
npcType: NPC_TYPE, npcType: NPC_TYPE,
crewTypeId: this.env.defaultCrewTypeId, crewTypeId: this.env.defaultCrewTypeId,
}; };
@@ -1,5 +1,5 @@
import type { RandomGenerator } from '@sammo-ts/common'; import type { RandomGenerator } from '@sammo-ts/common';
import type { City, General, GeneralTriggerState, Nation } from '@sammo-ts/logic/domain/entities.js'; import type { City, General, GeneralMeta, GeneralTriggerState, Nation } from '@sammo-ts/logic/domain/entities.js';
import type { Constraint, ConstraintContext, RequirementKey } from '@sammo-ts/logic/constraints/types.js'; import type { Constraint, ConstraintContext, RequirementKey } from '@sammo-ts/logic/constraints/types.js';
import { import {
notBeNeutral, notBeNeutral,
@@ -42,7 +42,7 @@ const getMetaNumber = (meta: Record<string, unknown>, key: string): number | nul
return typeof raw === 'number' ? raw : null; return typeof raw === 'number' ? raw : null;
}; };
const addMetaNumber = (meta: Record<string, unknown>, key: string, delta: number): Record<string, unknown> => { const addMetaNumber = (meta: GeneralMeta, key: string, delta: number): GeneralMeta => {
const current = getMetaNumber(meta, key) ?? 0; const current = getMetaNumber(meta, key) ?? 0;
return { ...meta, [key]: current + delta }; return { ...meta, [key]: current + delta };
}; };
@@ -1,4 +1,4 @@
import type { City, General, GeneralTriggerState, Nation, TriggerValue } from '@sammo-ts/logic/domain/entities.js'; import type { City, General, GeneralMeta, GeneralTriggerState, Nation } from '@sammo-ts/logic/domain/entities.js';
import type { Constraint, ConstraintContext, RequirementKey, StateView } from '@sammo-ts/logic/constraints/types.js'; import type { Constraint, ConstraintContext, RequirementKey, StateView } from '@sammo-ts/logic/constraints/types.js';
import { import {
notBeNeutral, notBeNeutral,
@@ -105,11 +105,7 @@ const readCityTrust = (city: City, fallback: number): number => {
return typeof trust === 'number' ? trust : fallback; return typeof trust === 'number' ? trust : fallback;
}; };
const addMetaNumber = ( const addMetaNumber = (meta: GeneralMeta, key: string, delta: number): GeneralMeta => {
meta: Record<string, TriggerValue>,
key: string,
delta: number
): Record<string, TriggerValue> => {
const current = typeof meta[key] === 'number' ? (meta[key] as number) : 0; const current = typeof meta[key] === 'number' ? (meta[key] as number) : 0;
return { ...meta, [key]: current + delta }; return { ...meta, [key]: current + delta };
}; };
@@ -1,5 +1,12 @@
import type { RandomGenerator } from '@sammo-ts/common'; import type { RandomGenerator } from '@sammo-ts/common';
import type { City, General, GeneralTriggerState, Nation, TriggerValue } from '@sammo-ts/logic/domain/entities.js'; import type {
City,
General,
GeneralMeta,
GeneralTriggerState,
Nation,
TriggerValue,
} from '@sammo-ts/logic/domain/entities.js';
import type { Constraint, ConstraintContext } from '@sammo-ts/logic/constraints/types.js'; import type { Constraint, ConstraintContext } from '@sammo-ts/logic/constraints/types.js';
import { import {
disallowDiplomacyBetweenStatus, disallowDiplomacyBetweenStatus,
@@ -103,11 +110,7 @@ const getStatValue = (general: General, statKey: 'leadership' | 'strength' | 'in
return general.stats.intelligence; return general.stats.intelligence;
}; };
const addMetaNumber = ( const addMetaNumber = (meta: GeneralMeta, key: string, delta: number): GeneralMeta => {
meta: Record<string, TriggerValue>,
key: string,
delta: number
): Record<string, TriggerValue> => {
const current = typeof meta[key] === 'number' ? (meta[key] as number) : 0; const current = typeof meta[key] === 'number' ? (meta[key] as number) : 0;
return { ...meta, [key]: current + delta }; return { ...meta, [key]: current + delta };
}; };
@@ -1,9 +1,9 @@
import type { import type {
General, General,
GeneralMeta,
GeneralRole, GeneralRole,
GeneralTriggerState, GeneralTriggerState,
StatBlock, StatBlock,
TriggerValue,
} from '@sammo-ts/logic/domain/entities.js'; } from '@sammo-ts/logic/domain/entities.js';
export interface GeneralRecruitmentInput<TriggerState extends GeneralTriggerState = GeneralTriggerState> { export interface GeneralRecruitmentInput<TriggerState extends GeneralTriggerState = GeneralTriggerState> {
@@ -26,7 +26,7 @@ export interface GeneralRecruitmentInput<TriggerState extends GeneralTriggerStat
specialDomestic: string | null; specialDomestic: string | null;
specialWar: string | null; specialWar: string | null;
}; };
meta?: Record<string, TriggerValue>; meta: GeneralMeta;
triggerState?: TriggerState; triggerState?: TriggerState;
} }
@@ -76,5 +76,5 @@ export const buildRecruitmentGeneral = <TriggerState extends GeneralTriggerState
age: input.age, age: input.age,
npcState: input.npcState, npcState: input.npcState,
triggerState: input.triggerState ?? (createEmptyTriggerState() as TriggerState), triggerState: input.triggerState ?? (createEmptyTriggerState() as TriggerState),
meta: input.meta ?? {}, meta: input.meta,
}); });
@@ -1,4 +1,10 @@
import type { City, General, GeneralTriggerState, TriggerValue } from '@sammo-ts/logic/domain/entities.js'; import type {
City,
General,
GeneralMeta,
GeneralTriggerState,
TriggerValue,
} from '@sammo-ts/logic/domain/entities.js';
import type { Constraint, ConstraintContext } from '@sammo-ts/logic/constraints/types.js'; import type { Constraint, ConstraintContext } from '@sammo-ts/logic/constraints/types.js';
import { import {
alwaysFail, alwaysFail,
@@ -72,11 +78,7 @@ const resolveLastAssignment = (context: AssignmentResolveContext): number => {
return yearMonth; return yearMonth;
}; };
const addMetaValue = ( const addMetaValue = (meta: GeneralMeta, key: string, value: TriggerValue): GeneralMeta => ({
meta: Record<string, TriggerValue>,
key: string,
value: TriggerValue
): Record<string, TriggerValue> => ({
...meta, ...meta,
[key]: value, [key]: value,
}); });
@@ -1,5 +1,5 @@
import type { RandomGenerator } from '@sammo-ts/common'; import type { RandomGenerator } from '@sammo-ts/common';
import type { GeneralTriggerState, StatBlock, TriggerValue } from '@sammo-ts/logic/domain/entities.js'; import type { GeneralMeta, GeneralTriggerState, StatBlock, TriggerValue } from '@sammo-ts/logic/domain/entities.js';
import type { Constraint, ConstraintContext } from '@sammo-ts/logic/constraints/types.js'; import type { Constraint, ConstraintContext } from '@sammo-ts/logic/constraints/types.js';
import { import {
availableStrategicCommand, availableStrategicCommand,
@@ -268,7 +268,8 @@ export class ActionResolver<
const birthYear = context.currentYear - baseAge; const birthYear = context.currentYear - baseAge;
const deathYear = context.currentYear + deathYears; const deathYear = context.currentYear + deathYears;
const stats = resolveStats(context, context.rng, this.env, candidate); const stats = resolveStats(context, context.rng, this.env, candidate);
const meta: Record<string, TriggerValue> = { const meta: GeneralMeta = {
killturn: randomRangeInt(context.rng, killTurnMin, killTurnMax),
npcType: NPC_TYPE, npcType: NPC_TYPE,
crewTypeId: this.env.defaultCrewTypeId, crewTypeId: this.env.defaultCrewTypeId,
}; };
@@ -278,7 +279,7 @@ export class ActionResolver<
addMetaValue(meta, 'deathYear', deathYear); addMetaValue(meta, 'deathYear', deathYear);
addMetaValue(meta, 'specAge', DEFAULT_SPEC_AGE); addMetaValue(meta, 'specAge', DEFAULT_SPEC_AGE);
addMetaValue(meta, 'specAge2', DEFAULT_SPEC_AGE); addMetaValue(meta, 'specAge2', DEFAULT_SPEC_AGE);
addMetaValue(meta, 'killturn', randomRangeInt(context.rng, killTurnMin, killTurnMax)); addMetaValue(meta, 'killturn', meta.killturn);
addMetaValue(meta, 'text', candidate.text ?? null); addMetaValue(meta, 'text', candidate.text ?? null);
const newGeneral = buildRecruitmentGeneral<TriggerState>({ const newGeneral = buildRecruitmentGeneral<TriggerState>({
+5 -1
View File
@@ -44,6 +44,10 @@ export interface GeneralRole {
items: GeneralItemSlots; items: GeneralItemSlots;
} }
export type GeneralMeta = Record<string, TriggerValue> & {
killturn: number;
};
export interface General<TriggerState extends GeneralTriggerState = GeneralTriggerState> { export interface General<TriggerState extends GeneralTriggerState = GeneralTriggerState> {
id: GeneralId; id: GeneralId;
name: string; name: string;
@@ -65,7 +69,7 @@ export interface General<TriggerState extends GeneralTriggerState = GeneralTrigg
age: number; age: number;
npcState: number; npcState: number;
triggerState: TriggerState; triggerState: TriggerState;
meta: Record<string, TriggerValue>; meta: GeneralMeta;
} }
export interface City { export interface City {
+1 -1
View File
@@ -82,7 +82,7 @@ export const createIncomeActionContext = (nation: Nation): GeneralActionContext
modifiers: {}, modifiers: {},
meta: {}, meta: {},
}, },
meta: {}, meta: { killturn: 0 },
}; };
return { general, nation }; return { general, nation };
}; };
+11 -2
View File
@@ -1,4 +1,11 @@
import type { City, General, GeneralTriggerState, Nation, TriggerValue } from '@sammo-ts/logic/domain/entities.js'; import type {
City,
General,
GeneralMeta,
GeneralTriggerState,
Nation,
TriggerValue,
} from '@sammo-ts/logic/domain/entities.js';
import type { ScenarioDefinition, ScenarioGeneral } from '@sammo-ts/logic/scenario/types.js'; import type { ScenarioDefinition, ScenarioGeneral } from '@sammo-ts/logic/scenario/types.js';
import type { import type {
CitySeed, CitySeed,
@@ -56,6 +63,7 @@ const DEFAULT_NEUTRAL_NATION_COLOR = '#000000';
const DEFAULT_GENERAL_GOLD = 1000; const DEFAULT_GENERAL_GOLD = 1000;
const DEFAULT_GENERAL_RICE = 1000; const DEFAULT_GENERAL_RICE = 1000;
const DEFAULT_CREWTYPE_ID = 1100; const DEFAULT_CREWTYPE_ID = 1100;
const DEFAULT_GENERAL_KILLTURN = 24;
const DEFAULT_CITY_TRUST = 50; const DEFAULT_CITY_TRUST = 50;
const DEFAULT_CITY_TRADE = 100; const DEFAULT_CITY_TRADE = 100;
const DEFAULT_CITY_SUPPLY_STATE = 1; const DEFAULT_CITY_SUPPLY_STATE = 1;
@@ -290,7 +298,8 @@ const buildGeneralSeeds = (
}; };
seeds.push(seed); seeds.push(seed);
const generalMeta: Record<string, TriggerValue> = { const generalMeta: GeneralMeta = {
killturn: DEFAULT_GENERAL_KILLTURN,
npcType, npcType,
crewTypeId: defaultCrewTypeId, crewTypeId: defaultCrewTypeId,
}; };
@@ -85,7 +85,7 @@ const buildGeneral = (id: number, nationId: number, cityId: number, name = 'Test
modifiers: {}, modifiers: {},
meta: {}, meta: {},
}, },
meta: {}, meta: { killturn: 24 },
}); });
const buildCity = (id: number, nationId: number): City => ({ const buildCity = (id: number, nationId: number): City => ({
@@ -50,7 +50,7 @@ const buildGeneral = (id: number, nationId: number, cityId: number, name = 'Test
modifiers: {}, modifiers: {},
meta: {}, meta: {},
}, },
meta: {}, meta: { killturn: 24 },
}); });
const buildCity = (id: number, nationId: number): City => ({ const buildCity = (id: number, nationId: number): City => ({
@@ -105,7 +105,7 @@ const buildGeneral = (id: number, nationId: number, cityId: number, name = 'Test
modifiers: {}, modifiers: {},
meta: {}, meta: {},
}, },
meta: {}, meta: { killturn: 24 },
}); });
const buildCity = (id: number, nationId: number, name = `City${id}`): City => ({ const buildCity = (id: number, nationId: number, name = `City${id}`): City => ({
+1 -1
View File
@@ -92,7 +92,7 @@ const buildGeneral = (): General => ({
modifiers: {}, modifiers: {},
meta: {}, meta: {},
}, },
meta: {}, meta: { killturn: 24 },
}); });
const buildCities = (): City[] => [ const buildCities = (): City[] => [
@@ -48,7 +48,7 @@ const buildGeneral = (id: number, nationId: number, cityId: number): General =>
modifiers: {}, modifiers: {},
meta: {}, meta: {},
}, },
meta: {}, meta: { killturn: 24 },
}); });
const buildCity = (id: number, nationId: number): City => ({ const buildCity = (id: number, nationId: number): City => ({
@@ -117,7 +117,7 @@ describe('Diplomacy Scenario', () => {
items: { horse: null, weapon: null, book: null, item: null }, items: { horse: null, weapon: null, book: null, item: null },
}, },
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
const snapshot: WorldSnapshot = { const snapshot: WorldSnapshot = {
@@ -74,7 +74,7 @@ describe('Domestic Affairs Scenario', () => {
items: { horse: null, weapon: null, book: null, item: null }, items: { horse: null, weapon: null, book: null, item: null },
}, },
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
const snapshot: WorldSnapshot = { const snapshot: WorldSnapshot = {
@@ -208,7 +208,7 @@ describe('Domestic Affairs Scenario', () => {
items: { horse: null, weapon: null, book: null, item: null }, items: { horse: null, weapon: null, book: null, item: null },
}, },
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
const snapshot: WorldSnapshot = { const snapshot: WorldSnapshot = {
@@ -140,7 +140,7 @@ describe('che_NPC능동', () => {
age: 20, age: 20,
npcState: 2, // NPC npcState: 2, // NPC
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
world.snapshot.generals.push(general); world.snapshot.generals.push(general);
@@ -195,7 +195,7 @@ describe('che_NPC능동', () => {
age: 20, age: 20,
npcState: 0, // Human npcState: 0, // Human
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
world.snapshot.generals.push(general); world.snapshot.generals.push(general);
@@ -201,7 +201,7 @@ describe('che_강행', () => {
age: 20, age: 20,
npcState: 0, npcState: 0,
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
const nation: Nation = { const nation: Nation = {
id: 1, id: 1,
@@ -214,7 +214,7 @@ describe('che_강행', () => {
power: 0, power: 0,
level: 1, level: 1,
typeCode: 'che_def', typeCode: 'che_def',
meta: {}, meta: { killturn: 24 },
}; };
world.snapshot.generals.push(general); world.snapshot.generals.push(general);
world.snapshot.nations.push(nation); world.snapshot.nations.push(nation);
@@ -285,7 +285,7 @@ describe('che_강행', () => {
age: 20, age: 20,
npcState: 0, npcState: 0,
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
const nation: Nation = { const nation: Nation = {
id: 1, id: 1,
@@ -298,7 +298,7 @@ describe('che_강행', () => {
power: 0, power: 0,
level: 1, level: 1,
typeCode: 'che_def', typeCode: 'che_def',
meta: {}, meta: { killturn: 24 },
}; };
world.snapshot.generals.push(general); world.snapshot.generals.push(general);
world.snapshot.nations.push(nation); world.snapshot.nations.push(nation);
@@ -362,7 +362,7 @@ describe('che_강행', () => {
age: 20, age: 20,
npcState: 0, npcState: 0,
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
const sub: General = { const sub: General = {
@@ -391,7 +391,7 @@ describe('che_강행', () => {
age: 20, age: 20,
npcState: 0, npcState: 0,
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
const nation: Nation = { const nation: Nation = {
@@ -180,7 +180,7 @@ describe('che_귀환', () => {
age: 20, age: 20,
npcState: 0, npcState: 0,
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
const nation: Nation = { const nation: Nation = {
id: 1, id: 1,
@@ -193,7 +193,7 @@ describe('che_귀환', () => {
power: 0, power: 0,
level: 1, level: 1,
typeCode: 'che_def', typeCode: 'che_def',
meta: {}, meta: { killturn: 24 },
}; };
world.snapshot.generals.push(general); world.snapshot.generals.push(general);
world.snapshot.nations.push(nation); world.snapshot.nations.push(nation);
@@ -252,7 +252,7 @@ describe('che_귀환', () => {
age: 20, age: 20,
npcState: 0, npcState: 0,
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: { officer_city: 103 }, meta: { killturn: 24, officer_city: 103 },
}; };
const nation: Nation = { const nation: Nation = {
id: 1, id: 1,
@@ -265,7 +265,7 @@ describe('che_귀환', () => {
power: 0, power: 0,
level: 1, level: 1,
typeCode: 'che_def', typeCode: 'che_def',
meta: {}, meta: { killturn: 24 },
}; };
world.snapshot.generals.push(general); world.snapshot.generals.push(general);
world.snapshot.nations.push(nation); world.snapshot.nations.push(nation);
@@ -318,7 +318,7 @@ describe('che_귀환', () => {
age: 20, age: 20,
npcState: 0, npcState: 0,
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
const nation: Nation = { const nation: Nation = {
id: 1, id: 1,
@@ -331,7 +331,7 @@ describe('che_귀환', () => {
power: 0, power: 0,
level: 1, level: 1,
typeCode: 'che_def', typeCode: 'che_def',
meta: {}, meta: { killturn: 24 },
}; };
world.snapshot.generals.push(general); world.snapshot.generals.push(general);
world.snapshot.nations.push(nation); world.snapshot.nations.push(nation);
@@ -400,7 +400,7 @@ describe('che_귀환', () => {
age: 20, age: 20,
npcState: 0, npcState: 0,
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: { officer_city: 103 }, meta: { killturn: 24, officer_city: 103 },
}; };
const nation: Nation = { const nation: Nation = {
id: 1, id: 1,
@@ -413,7 +413,7 @@ describe('che_귀환', () => {
power: 0, power: 0,
level: 1, level: 1,
typeCode: 'che_def', typeCode: 'che_def',
meta: {}, meta: { killturn: 24 },
}; };
world.snapshot.generals.push(general); world.snapshot.generals.push(general);
world.snapshot.nations.push(nation); world.snapshot.nations.push(nation);
@@ -172,7 +172,7 @@ describe('che_등용수락', () => {
age: 20, age: 20,
npcState: 0, npcState: 0,
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
const recruiterGen: General = { const recruiterGen: General = {
@@ -201,7 +201,7 @@ describe('che_등용수락', () => {
age: 20, age: 20,
npcState: 0, npcState: 0,
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
const nation2: Nation = { const nation2: Nation = {
@@ -215,7 +215,7 @@ describe('che_등용수락', () => {
power: 0, power: 0,
level: 1, level: 1,
typeCode: 'che_def', typeCode: 'che_def',
meta: {}, meta: { killturn: 24 },
}; };
world.snapshot.generals.push(neutralGen); world.snapshot.generals.push(neutralGen);
@@ -284,7 +284,7 @@ describe('che_등용수락', () => {
age: 20, age: 20,
npcState: 0, npcState: 0,
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: { betray: 1 }, meta: { killturn: 24, betray: 1 },
}; };
const nation1: Nation = { const nation1: Nation = {
id: 1, id: 1,
@@ -297,7 +297,7 @@ describe('che_등용수락', () => {
power: 0, power: 0,
level: 1, level: 1,
typeCode: 'che_def', typeCode: 'che_def',
meta: {}, meta: { killturn: 24 },
}; };
const recruiterGen: General = { const recruiterGen: General = {
@@ -326,7 +326,7 @@ describe('che_등용수락', () => {
age: 20, age: 20,
npcState: 0, npcState: 0,
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
const nation2: Nation = { const nation2: Nation = {
id: 2, id: 2,
@@ -339,7 +339,7 @@ describe('che_등용수락', () => {
power: 0, power: 0,
level: 1, level: 1,
typeCode: 'che_def', typeCode: 'che_def',
meta: {}, meta: { killturn: 24 },
}; };
world.snapshot.generals.push(betrayer); world.snapshot.generals.push(betrayer);
@@ -408,7 +408,7 @@ describe('che_등용수락', () => {
age: 20, age: 20,
npcState: 0, npcState: 0,
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
const nation1: Nation = { const nation1: Nation = {
id: 1, id: 1,
@@ -421,7 +421,7 @@ describe('che_등용수락', () => {
power: 0, power: 0,
level: 1, level: 1,
typeCode: 'che_def', typeCode: 'che_def',
meta: {}, meta: { killturn: 24 },
}; };
const recruiterGen: General = { const recruiterGen: General = {
id: 2, id: 2,
@@ -444,7 +444,7 @@ describe('che_등용수락', () => {
age: 20, age: 20,
npcState: 0, npcState: 0,
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
const nation2: Nation = { const nation2: Nation = {
id: 2, id: 2,
@@ -457,7 +457,7 @@ describe('che_등용수락', () => {
power: 0, power: 0,
level: 1, level: 1,
typeCode: 'che_def', typeCode: 'che_def',
meta: {}, meta: { killturn: 24 },
}; };
world.snapshot.generals.push(monarch); world.snapshot.generals.push(monarch);
@@ -512,7 +512,7 @@ describe('che_등용수락', () => {
age: 20, age: 20,
npcState: 0, npcState: 0,
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
const nation1: Nation = { const nation1: Nation = {
id: 1, id: 1,
@@ -525,7 +525,7 @@ describe('che_등용수락', () => {
power: 0, power: 0,
level: 1, level: 1,
typeCode: 'che_def', typeCode: 'che_def',
meta: {}, meta: { killturn: 24 },
}; };
const recruiterGen: General = { const recruiterGen: General = {
id: 2, id: 2,
@@ -548,7 +548,7 @@ describe('che_등용수락', () => {
age: 20, age: 20,
npcState: 0, npcState: 0,
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
world.snapshot.generals.push(general); world.snapshot.generals.push(general);
@@ -92,7 +92,7 @@ describe('che_이동', () => {
age: 20, age: 20,
npcState: 0, npcState: 0,
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
const nation: Nation = { const nation: Nation = {
id: 1, id: 1,
@@ -131,7 +131,7 @@ describe('General Commands New Scenario', () => {
items: { horse: null, weapon: null, book: null, item: null }, items: { horse: null, weapon: null, book: null, item: null },
}, },
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
const snapshot: WorldSnapshot = { const snapshot: WorldSnapshot = {
+1 -1
View File
@@ -76,7 +76,7 @@ describe('Troop Management Scenario', () => {
items: { horse: null, weapon: null, book: null, item: null }, items: { horse: null, weapon: null, book: null, item: null },
}, },
triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} }, triggerState: { flags: {}, counters: {}, modifiers: {}, meta: {} },
meta: {}, meta: { killturn: 24 },
}; };
const snapshot: WorldSnapshot = { const snapshot: WorldSnapshot = {
+1 -1
View File
@@ -60,7 +60,7 @@ const buildGeneral = (overrides: Partial<General> = {}): General => ({
modifiers: {}, modifiers: {},
meta: {}, meta: {},
}, },
meta: {}, meta: { killturn: 24 },
...overrides, ...overrides,
}); });
+1 -1
View File
@@ -123,7 +123,7 @@ const buildGeneral = (id: number, nationId: number, cityId: number): General =>
modifiers: {}, modifiers: {},
meta: {}, meta: {},
}, },
meta: {}, meta: { killturn: 24 },
}); });
describe('war aftermath', () => { describe('war aftermath', () => {
+1
View File
@@ -153,6 +153,7 @@ const buildGeneral = (strength: number): General => ({
meta: {}, meta: {},
}, },
meta: { meta: {
killturn: 24,
dex1: 5000, dex1: 5000,
}, },
}); });