refactor(logic): replace arbitrary action hooks with typed events
This commit is contained in:
@@ -2,7 +2,7 @@ import type { RandUtil } from '@sammo-ts/common';
|
||||
|
||||
import type { City, General, GeneralTriggerState, Nation } from '@sammo-ts/logic/domain/entities.js';
|
||||
import type { ActionLogger } from '@sammo-ts/logic/logging/actionLogger.js';
|
||||
import type { WarStatName } from '@sammo-ts/logic/triggers/types.js';
|
||||
import type { WarStatName } from '@sammo-ts/logic/actionModules/types.js';
|
||||
import type { WarUnit } from './units.js';
|
||||
import { WarTriggerCaller } from './triggers.js';
|
||||
|
||||
@@ -54,7 +54,7 @@ export class WarActionPipeline<TriggerState extends GeneralTriggerState = Genera
|
||||
// 전투용 iAction 파이프라인: 스탯/트리거/전투력 보정 흐름을 순서대로 적용한다.
|
||||
private readonly modules: WarActionModule<TriggerState>[];
|
||||
|
||||
constructor(modules: Array<WarActionModule<TriggerState> | null | undefined>) {
|
||||
constructor(modules: ReadonlyArray<WarActionModule<TriggerState> | null | undefined>) {
|
||||
this.modules = modules.filter(Boolean) as WarActionModule<TriggerState>[];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { JosaUtil, LiteHashDRBG, RandUtil } from '@sammo-ts/common';
|
||||
|
||||
import type { City, General, GeneralTriggerState, Nation } from '@sammo-ts/logic/domain/entities.js';
|
||||
import { createGeneralActionEvent } from '@sammo-ts/logic/actionModules/events.js';
|
||||
import { GeneralActionPipeline } from '@sammo-ts/logic/actionModules/general.js';
|
||||
import { ActionLogger } from '@sammo-ts/logic/logging/actionLogger.js';
|
||||
import { LogFormat, type LogEntryDraft } from '@sammo-ts/logic/logging/types.js';
|
||||
import { LogCategory, LogFormat, LogScope, type LogEntryDraft } from '@sammo-ts/logic/logging/types.js';
|
||||
import { buildCrewTypeIndex, getTechCost, getTechLevel } from '@sammo-ts/logic/world/unitSet.js';
|
||||
import type { WarUnitReport } from './types.js';
|
||||
import type {
|
||||
@@ -530,6 +532,49 @@ export const resolveWarAftermath = <TriggerState extends GeneralTriggerState = G
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// Legacy ConquerCity calls every general action module for every
|
||||
// defender-nation general stationed in the conquered city, before any
|
||||
// nation-collapse RNG is consumed. Keep that order and the same RNG
|
||||
// object instead of opening a second random stream.
|
||||
const pipeline = new GeneralActionPipeline(input.generalActionModules ?? []);
|
||||
const cityDefenders = input.generals.filter(
|
||||
(general) =>
|
||||
general.nationId !== 0 &&
|
||||
general.nationId === input.defenderCity.nationId &&
|
||||
general.cityId === input.defenderCity.id
|
||||
);
|
||||
for (const general of cityDefenders) {
|
||||
pipeline.dispatch(
|
||||
{
|
||||
general,
|
||||
nation: input.defenderNation,
|
||||
rng,
|
||||
worldView: {
|
||||
listGenerals: () => input.generals,
|
||||
listGeneralsByCity: (cityId) =>
|
||||
input.generals.filter((candidate) => candidate.cityId === cityId),
|
||||
listNations: () => input.nations,
|
||||
},
|
||||
log: {
|
||||
push: (text) =>
|
||||
logs.push({
|
||||
scope: LogScope.GENERAL,
|
||||
category: LogCategory.ACTION,
|
||||
format: LogFormat.MONTH,
|
||||
generalId: general.id,
|
||||
nationId: general.nationId,
|
||||
text,
|
||||
}),
|
||||
},
|
||||
},
|
||||
createGeneralActionEvent('city.conquered', {
|
||||
attacker: input.battle.attacker,
|
||||
})
|
||||
);
|
||||
affectedGenerals.add(general);
|
||||
}
|
||||
|
||||
conquest = resolveConquerCity(input, rng);
|
||||
logs.push(...conquest.logs);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { RandUtil } from '@sammo-ts/common';
|
||||
|
||||
import type { City, General, GeneralTriggerState, Nation } from '@sammo-ts/logic/domain/entities.js';
|
||||
import type { GeneralActionModule } from '@sammo-ts/logic/actionModules/general.js';
|
||||
import type { ActionLogger } from '@sammo-ts/logic/logging/actionLogger.js';
|
||||
import type { LogEntryDraft } from '@sammo-ts/logic/logging/types.js';
|
||||
import type { UnitSetDefinition } from '@sammo-ts/logic/world/types.js';
|
||||
@@ -39,7 +40,7 @@ export interface WarGeneralInput<TriggerState extends GeneralTriggerState = Gene
|
||||
city: City;
|
||||
nation: Nation | null;
|
||||
logger?: ActionLogger;
|
||||
modules?: Array<WarActionModule<TriggerState> | null | undefined>;
|
||||
modules?: ReadonlyArray<WarActionModule<TriggerState> | null | undefined>;
|
||||
}
|
||||
|
||||
export interface WarBattleInput<TriggerState extends GeneralTriggerState = GeneralTriggerState> {
|
||||
@@ -177,6 +178,7 @@ export interface WarAftermathInput<TriggerState extends GeneralTriggerState = Ge
|
||||
time: WarTimeContext;
|
||||
hiddenSeed?: string;
|
||||
rng?: RandUtil;
|
||||
generalActionModules?: ReadonlyArray<GeneralActionModule<TriggerState> | null | undefined>;
|
||||
calcNationTechGain?: (context: WarAftermathTechContext) => number;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import type {
|
||||
} from '@sammo-ts/logic/domain/entities.js';
|
||||
import type { ActionLogger } from '@sammo-ts/logic/logging/actionLogger.js';
|
||||
import { LogFormat } from '@sammo-ts/logic/logging/types.js';
|
||||
import type { WarStatName } from '@sammo-ts/logic/triggers/types.js';
|
||||
import type { WarStatName } from '@sammo-ts/logic/actionModules/types.js';
|
||||
import { getTechAbility, getTechCost } from '@sammo-ts/logic/world/unitSet.js';
|
||||
import type { WarActionPipeline, WarActionContext } from '../actions.js';
|
||||
import type { WarEngineConfig } from '../types.js';
|
||||
|
||||
Reference in New Issue
Block a user