feat: port scenario action effects

This commit is contained in:
2026-07-30 19:00:04 +00:00
parent 7f31459385
commit c68d992046
39 changed files with 1131 additions and 95 deletions
+5 -1
View File
@@ -1,7 +1,7 @@
import type { WorldStateRow } from '../context.js';
import type { BattleSimJobPayload, BattleSimRequestPayload } from './types.js';
import { loadUnitSetDefinitionByName } from './unitSetLoader.js';
import type { WarEngineConfig } from '@sammo-ts/logic';
import { normalizeScenarioEffect, type ScenarioEffectKey, type WarEngineConfig } from '@sammo-ts/logic';
import { asRecord } from '@sammo-ts/common';
import type { UnitSetDefinition } from '@sammo-ts/logic';
@@ -79,6 +79,7 @@ export interface BattleSimEnvironment {
unitSet: UnitSetDefinition;
config: WarEngineConfig;
startYear: number;
scenarioEffect: ScenarioEffectKey | null;
}
export const buildBattleSimEnvironment = async (
@@ -89,6 +90,7 @@ export const buildBattleSimEnvironment = async (
const unitSet = await loadUnitSetDefinitionByName(unitSetName);
const configRecord = asRecord(worldState.config);
const scenarioEnvironment = asRecord(configRecord.environment ?? configRecord.map);
const constValues = asRecord(configRecord.const ?? configRecord.consts);
const castleCrewTypeId = resolveNumber(constValues, ['castleCrewTypeId'], resolveCastleCrewTypeId(unitSet));
const castleArmType = resolveCastleArmType(unitSet, castleCrewTypeId);
@@ -117,6 +119,7 @@ export const buildBattleSimEnvironment = async (
unitSet,
config,
startYear: resolveStartYear(worldState),
scenarioEffect: normalizeScenarioEffect(scenarioEnvironment.scenarioEffect),
};
};
@@ -136,5 +139,6 @@ export const buildBattleSimJobPayload = async (
month: request.month,
startYear: environment.startYear,
},
scenarioEffect: environment.scenarioEffect,
};
};
+9 -4
View File
@@ -12,6 +12,7 @@ import {
createItemActionModules,
createItemModuleRegistry,
createRefOrderedActionStack,
createScenarioEffectActionModules,
ITEM_KEYS,
loadItemModules,
createInheritBuffModules,
@@ -62,8 +63,12 @@ const domesticWarModule = new TraitWarActionRouter('domestic', traitCatalog);
const warTraitModule = new TraitWarActionRouter('war', traitCatalog);
const personalityWarModule = new TraitWarActionRouter('personality', traitCatalog);
const buildWarActionModules = (unitSet: UnitSetDefinition): RefOrderedActionStack<WarActionModule> => {
const buildWarActionModules = (
unitSet: UnitSetDefinition,
scenarioEffect?: string | null
): RefOrderedActionStack<WarActionModule> => {
const crewTypeCatalog = compileCrewTypeCatalog(unitSet, crewTypeWarTriggerRegistry);
const scenario = createScenarioEffectActionModules(scenarioEffect);
return createRefOrderedActionStack<WarActionModule>({
nation: nationWarModule,
officer: officerWarModule,
@@ -72,7 +77,7 @@ const buildWarActionModules = (unitSet: UnitSetDefinition): RefOrderedActionStac
personality: personalityWarModule,
crewType: crewTypeCatalog.warActionModule,
inheritance: inheritBuffModules.war,
scenario: null,
scenario: scenario.war,
items: itemWarModules,
});
};
@@ -296,7 +301,7 @@ const resolveDefenderOrderPayload = (payload: BattleSimJobPayload): number[] =>
const defenderCity = mapCityPayload(payload.defenderCity);
const attacker = mapGeneralPayload(payload.attackerGeneral);
const defenders = payload.defenderGenerals.map(mapGeneralPayload);
const warActionModules = buildWarActionModules(payload.unitSet);
const warActionModules = buildWarActionModules(payload.unitSet, payload.scenarioEffect);
return resolveDefenderOrder({
unitSet: payload.unitSet,
@@ -338,7 +343,7 @@ export const processBattleSimJob = (
}
let repeatCnt = payload.repeatCnt;
const warActionModules = buildWarActionModules(payload.unitSet);
const warActionModules = buildWarActionModules(payload.unitSet, payload.scenarioEffect);
const baseSeed = payload.seed ?? '';
if (baseSeed) {
repeatCnt = 1;
+1
View File
@@ -100,6 +100,7 @@ export interface BattleSimJobPayload extends BattleSimRequestPayload {
unitSet: UnitSetDefinition;
config: WarEngineConfig;
time: WarTimeContext;
scenarioEffect?: string | null;
}
export interface BattleSimLogBuckets {
+9
View File
@@ -1,6 +1,7 @@
import { z } from 'zod';
import type { GameSessionTokenPayload } from '@sammo-ts/common/auth/gameToken';
import type { DatabaseClient as InfraDatabaseClient, RedisConnector, GamePrisma } from '@sammo-ts/infra';
import { normalizeScenarioEffect, SCENARIO_EFFECT_KEYS } from '@sammo-ts/logic';
import type { TurnDaemonTransport } from './daemon/transport.js';
import type { BattleSimTransport } from './battleSim/transport.js';
@@ -25,6 +26,14 @@ export const zWorldStateConfig = z.object({
extendedGeneral: z.boolean().optional(),
turnTermMinutes: z.number().optional(),
syncTurnTime: z.boolean().optional(),
environment: z
.object({
scenarioEffect: z
.union([z.enum(SCENARIO_EFFECT_KEYS), z.literal(''), z.literal('None'), z.null()])
.transform(normalizeScenarioEffect)
.optional(),
})
.optional(),
});
export type WorldStateConfig = z.infer<typeof zWorldStateConfig>;