refactor(logic): replace arbitrary action hooks with typed events
This commit is contained in:
@@ -11,10 +11,11 @@ import {
|
||||
resolveWarBattle,
|
||||
createItemActionModules,
|
||||
createItemModuleRegistry,
|
||||
createRefOrderedActionStack,
|
||||
ITEM_KEYS,
|
||||
loadItemModules,
|
||||
createInheritBuffModules,
|
||||
createTraitModuleRegistry,
|
||||
createTraitCatalog,
|
||||
createOfficerLevelActionModules,
|
||||
DOMESTIC_TRAIT_KEYS,
|
||||
loadDomesticTraitModules,
|
||||
@@ -30,6 +31,7 @@ import {
|
||||
type City,
|
||||
type General,
|
||||
type Nation,
|
||||
type RefOrderedActionStack,
|
||||
type UnitSetDefinition,
|
||||
type WarBattleOutcome,
|
||||
type WarActionModule,
|
||||
@@ -48,23 +50,31 @@ const itemWarModules: WarActionModule[] = createItemActionModules(
|
||||
createItemModuleRegistry(await loadItemModules([...ITEM_KEYS]))
|
||||
).war;
|
||||
const crewTypeWarTriggerRegistry = createCrewTypeWarTriggerRegistry();
|
||||
const traitRegistry = createTraitModuleRegistry({
|
||||
const traitCatalog = createTraitCatalog({
|
||||
domestic: await loadDomesticTraitModules([...DOMESTIC_TRAIT_KEYS]),
|
||||
war: await loadWarTraitModules([...WAR_TRAIT_KEYS]),
|
||||
personality: await loadPersonalityTraitModules([...PERSONALITY_TRAIT_KEYS]),
|
||||
nation: await loadNationTraitModules([...NATION_TRAIT_KEYS]),
|
||||
});
|
||||
const traitWarModules: WarActionModule[] = [
|
||||
new TraitWarActionRouter('nation', traitRegistry),
|
||||
createOfficerLevelActionModules().war,
|
||||
new TraitWarActionRouter('domestic', traitRegistry),
|
||||
new TraitWarActionRouter('war', traitRegistry),
|
||||
new TraitWarActionRouter('personality', traitRegistry),
|
||||
];
|
||||
const nationWarModule = new TraitWarActionRouter('nation', traitCatalog);
|
||||
const officerWarModule = createOfficerLevelActionModules().war;
|
||||
const domesticWarModule = new TraitWarActionRouter('domestic', traitCatalog);
|
||||
const warTraitModule = new TraitWarActionRouter('war', traitCatalog);
|
||||
const personalityWarModule = new TraitWarActionRouter('personality', traitCatalog);
|
||||
|
||||
const buildWarActionModules = (unitSet: UnitSetDefinition): WarActionModule[] => {
|
||||
const buildWarActionModules = (unitSet: UnitSetDefinition): RefOrderedActionStack<WarActionModule> => {
|
||||
const crewTypeCatalog = compileCrewTypeCatalog(unitSet, crewTypeWarTriggerRegistry);
|
||||
return [...traitWarModules, crewTypeCatalog.warActionModule, inheritBuffModules.war, ...itemWarModules];
|
||||
return createRefOrderedActionStack<WarActionModule>({
|
||||
nation: nationWarModule,
|
||||
officer: officerWarModule,
|
||||
domestic: domesticWarModule,
|
||||
war: warTraitModule,
|
||||
personality: personalityWarModule,
|
||||
crewType: crewTypeCatalog.warActionModule,
|
||||
inheritance: inheritBuffModules.war,
|
||||
scenario: null,
|
||||
items: itemWarModules,
|
||||
});
|
||||
};
|
||||
|
||||
const normalizeItemCode = (value: string | null): string | null => (value === 'None' ? null : value);
|
||||
|
||||
@@ -22,7 +22,11 @@ const DISASTER_TEXT_BY_MONTH: Readonly<Record<number, DisasterText[]>> = {
|
||||
1: [
|
||||
{ title: '<M><b>【재난】</b></>', stateCode: 4, body: '역병이 발생하여 도시가 황폐해지고 있습니다.' },
|
||||
{ title: '<M><b>【재난】</b></>', stateCode: 5, body: '지진으로 피해가 속출하고 있습니다.' },
|
||||
{ title: '<M><b>【재난】</b></>', stateCode: 3, body: '추위가 풀리지 않아 얼어죽는 백성들이 늘어나고 있습니다.' },
|
||||
{
|
||||
title: '<M><b>【재난】</b></>',
|
||||
stateCode: 3,
|
||||
body: '추위가 풀리지 않아 얼어죽는 백성들이 늘어나고 있습니다.',
|
||||
},
|
||||
{ title: '<M><b>【재난】</b></>', stateCode: 9, body: '황건적이 출현해 도시를 습격하고 있습니다.' },
|
||||
],
|
||||
4: [
|
||||
@@ -67,7 +71,7 @@ const roundLegacyIntegerColumn = (value: number): number => Math.round(value);
|
||||
|
||||
export const createRaiseDisasterHandler = (options: {
|
||||
getWorld: () => InMemoryTurnWorld | null;
|
||||
generalActionModules?: GeneralActionModule[];
|
||||
generalActionModules?: ReadonlyArray<GeneralActionModule>;
|
||||
}): MonthlyEventActionHandler => {
|
||||
const generalPipeline = new GeneralActionPipeline(options.generalActionModules ?? []);
|
||||
|
||||
@@ -95,9 +99,7 @@ export const createRaiseDisasterHandler = (options: {
|
||||
throw new Error(`Unsupported month for RaiseDisaster: ${environment.month}`);
|
||||
}
|
||||
const rng = new RandUtil(
|
||||
new LiteHashDRBG(
|
||||
simpleSerialize(resolveHiddenSeed(world), 'disater', environment.year, environment.month)
|
||||
)
|
||||
new LiteHashDRBG(simpleSerialize(resolveHiddenSeed(world), 'disater', environment.year, environment.month))
|
||||
);
|
||||
const isGood = rng.nextBool(boomingRate);
|
||||
const targetCities = cities.filter((city) => {
|
||||
@@ -135,9 +137,7 @@ export const createRaiseDisasterHandler = (options: {
|
||||
world.updateCity(city.id, {
|
||||
state: picked.stateCode,
|
||||
population: roundLegacyIntegerColumn(
|
||||
isGood
|
||||
? Math.min(city.population * affectRatio, city.populationMax)
|
||||
: city.population * affectRatio
|
||||
isGood ? Math.min(city.population * affectRatio, city.populationMax) : city.population * affectRatio
|
||||
),
|
||||
agriculture: roundLegacyIntegerColumn(
|
||||
isGood
|
||||
@@ -171,8 +171,7 @@ export const createRaiseDisasterHandler = (options: {
|
||||
nation: world.getNationById(general.nationId),
|
||||
worldView: {
|
||||
listGenerals: () => allGenerals,
|
||||
listGeneralsByCity: (cityId) =>
|
||||
allGenerals.filter((candidate) => candidate.cityId === cityId),
|
||||
listGeneralsByCity: (cityId) => allGenerals.filter((candidate) => candidate.cityId === cityId),
|
||||
},
|
||||
rng,
|
||||
});
|
||||
|
||||
@@ -186,8 +186,8 @@ export const buildReservedTurnDefinitions = async (options: {
|
||||
},
|
||||
])
|
||||
);
|
||||
options.env.generalActionModules = [...(options.env.generalActionModules ?? []), ...moduleBundle.general];
|
||||
options.env.warActionModules = [...(options.env.warActionModules ?? []), ...moduleBundle.war];
|
||||
options.env.generalActionModules ??= moduleBundle.general;
|
||||
options.env.warActionModules ??= moduleBundle.war;
|
||||
options.env.nationTraitModules = moduleBundle.nationTraitModules;
|
||||
|
||||
const generalSpecs = await loadGeneralTurnCommandSpecs(options.commandProfile.general);
|
||||
|
||||
@@ -976,6 +976,11 @@ export const createReservedTurnHandler = async (options: {
|
||||
getAdditionalOccupiedUniqueItemKeys: options.getAdditionalOccupiedUniqueItemKeys,
|
||||
});
|
||||
let actionRng = sharedActionRng ?? buildRng(actionKey);
|
||||
const actionTime = {
|
||||
year: context.world.currentYear,
|
||||
month: context.world.currentMonth,
|
||||
startYear: resolveStartYear(context.world, options.scenarioMeta),
|
||||
};
|
||||
let baseContext: ActionContextBase = {
|
||||
general: currentGeneral,
|
||||
city: currentCity,
|
||||
@@ -991,6 +996,7 @@ export const createReservedTurnHandler = async (options: {
|
||||
}
|
||||
: {}),
|
||||
rng: actionRng,
|
||||
time: actionTime,
|
||||
uniqueLottery,
|
||||
};
|
||||
let specificContext = buildActionContext(
|
||||
@@ -1023,6 +1029,7 @@ export const createReservedTurnHandler = async (options: {
|
||||
city: currentCity,
|
||||
nation: currentNation,
|
||||
rng: actionRng,
|
||||
time: actionTime,
|
||||
};
|
||||
specificContext = baseContext;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user