From da6a095151e54478234c5f753ce8fb77fbedff3a Mon Sep 17 00:00:00 2001 From: Hide_D Date: Mon, 5 Jan 2026 19:53:22 +0000 Subject: [PATCH] =?UTF-8?q?Revert=20"wip:=20=EB=B0=94=EB=B3=B4=20=EC=A0=AC?= =?UTF-8?q?3=ED=94=8C.=20=20type=20=EC=9E=AC=EC=A0=95=EC=9D=98=20=EC=A4=80?= =?UTF-8?q?=EB=B9=84"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 6bddbc3aa0502e92aa4fa90c7c14ffd05f7bd4d5. --- packages/logic/src/items/base.ts | 24 +++-- packages/logic/src/triggers/general-action.ts | 102 +++++++++--------- .../logic/src/triggers/special/registry.ts | 70 +++++------- packages/logic/src/triggers/special/types.ts | 41 +++---- packages/logic/src/triggers/types.ts | 85 +++------------ packages/logic/src/war/actions.ts | 74 ++++++------- packages/logic/src/war/units.ts | 25 ++--- 7 files changed, 167 insertions(+), 254 deletions(-) diff --git a/packages/logic/src/items/base.ts b/packages/logic/src/items/base.ts index 6837c67..2e97847 100644 --- a/packages/logic/src/items/base.ts +++ b/packages/logic/src/items/base.ts @@ -34,19 +34,31 @@ export const createStatItemModule = (options: StatItemOptions): ItemModule => { const name = `${options.rawName}(+${options.statValue})`; const baseInfo = `${statLabel} +${options.statValue}`; const info = options.extraInfo ? `${baseInfo}
${options.extraInfo}` : baseInfo; - const onCalcStat = ( + function onCalcStat( + _context: GeneralActionContext, + statName: GeneralStatName, + value: number, + _aux?: unknown + ): number; + function onCalcStat( + _context: WarActionContext, + statName: WarStatName, + value: number | [number, number], + _aux?: unknown + ): number | [number, number]; + function onCalcStat( _context: GeneralActionContext | WarActionContext, statName: GeneralStatName | WarStatName, value: number | [number, number] - ): number | [number, number] => { + ): number | [number, number] { if (statName !== options.statName) { return value; } - if (typeof value === 'number') { - return value + options.statValue; + if (Array.isArray(value)) { + return value; } - return value; - }; + return value + options.statValue; + } return { key: options.key, diff --git a/packages/logic/src/triggers/general-action.ts b/packages/logic/src/triggers/general-action.ts index 6fed42e..a77bb00 100644 --- a/packages/logic/src/triggers/general-action.ts +++ b/packages/logic/src/triggers/general-action.ts @@ -1,9 +1,7 @@ import type { GeneralTriggerState } from '@sammo-ts/logic/domain/entities.js'; import { type GeneralActionContext, GeneralTriggerCaller } from './general.js'; import type { - GeneralStatBundleMap, GeneralStatName, - WarStatBundleMap, TriggerActionPhase, TriggerActionType, TriggerDomesticActionType, @@ -18,58 +16,58 @@ export interface GeneralActionModule string) | undefined; getPreTurnExecuteTriggerList?: - | ((context: GeneralActionContext) => GeneralTriggerCaller | null) - | undefined; + | ((context: GeneralActionContext) => GeneralTriggerCaller | null) + | undefined; onCalcDomestic?: - | (( - context: GeneralActionContext, - turnType: TriggerDomesticActionType, - varType: TriggerDomesticVarType, - value: number, - aux?: unknown - ) => number) - | undefined; + | (( + context: GeneralActionContext, + turnType: TriggerDomesticActionType, + varType: TriggerDomesticVarType, + value: number, + aux?: unknown + ) => number) + | undefined; onCalcStat?: - | (( - context: GeneralActionContext, - statName: T, - value: GeneralStatBundleMap[T]['value'], - aux?: GeneralStatBundleMap[T]['aux'] - ) => GeneralStatBundleMap[T]['return']) - | undefined; + | (( + context: GeneralActionContext, + statName: GeneralStatName, + value: number, + aux?: unknown + ) => number) + | undefined; onCalcOpposeStat?: - | (( - context: GeneralActionContext, - statName: T, - value: GeneralStatBundleMap[T]['value'], - aux?: GeneralStatBundleMap[T]['aux'] - ) => GeneralStatBundleMap[T]['return']) - | undefined; + | (( + context: GeneralActionContext, + statName: GeneralStatName, + value: number, + aux?: unknown + ) => number) + | undefined; onCalcStrategic?: - | (( - context: GeneralActionContext, - turnType: TriggerStrategicActionType, - varType: TriggerStrategicVarType, - value: number - ) => number) - | undefined; + | (( + context: GeneralActionContext, + turnType: TriggerStrategicActionType, + varType: TriggerStrategicVarType, + value: number + ) => number) + | undefined; onCalcNationalIncome?: - | ((context: GeneralActionContext, type: TriggerNationalIncomeType, amount: number) => number) - | undefined; + | ((context: GeneralActionContext, type: TriggerNationalIncomeType, amount: number) => number) + | undefined; onArbitraryAction?: - | (( - context: GeneralActionContext, - actionType: TriggerActionType, - phase?: TriggerActionPhase | null, - aux?: Record | null - ) => Record | null) - | undefined; + | (( + context: GeneralActionContext, + actionType: TriggerActionType, + phase?: TriggerActionPhase | null, + aux?: Record | null + ) => Record | null) + | undefined; } export class GeneralActionPipeline { @@ -109,12 +107,12 @@ export class GeneralActionPipeline( + onCalcStat( context: GeneralActionContext, - statName: T, - value: GeneralStatBundleMap[T]['value'], - aux?: GeneralStatBundleMap[T]['aux'] - ): GeneralStatBundleMap[T]['return'] { + statName: GeneralStatName, + value: number, + aux?: unknown + ): number { let current = value; for (const module of this.modules) { if (!module.onCalcStat) { @@ -125,12 +123,12 @@ export class GeneralActionPipeline( + onCalcOpposeStat( context: GeneralActionContext, - statName: T, - value: GeneralStatBundleMap[T]['value'], - aux?: GeneralStatBundleMap[T]['aux'] - ): GeneralStatBundleMap[T]['return'] { + statName: GeneralStatName, + value: number, + aux?: unknown + ): number { let current = value; for (const module of this.modules) { if (!module.onCalcOpposeStat) { diff --git a/packages/logic/src/triggers/special/registry.ts b/packages/logic/src/triggers/special/registry.ts index 1036242..44a84d4 100644 --- a/packages/logic/src/triggers/special/registry.ts +++ b/packages/logic/src/triggers/special/registry.ts @@ -2,7 +2,6 @@ import type { GeneralTriggerState } from '@sammo-ts/logic/domain/entities.js'; import type { GeneralActionContext } from '@sammo-ts/logic/triggers/general.js'; import type { GeneralActionModule } from '@sammo-ts/logic/triggers/general-action.js'; import type { - GeneralStatBundleMap, GeneralStatName, TriggerActionPhase, TriggerActionType, @@ -11,7 +10,6 @@ import type { TriggerNationalIncomeType, TriggerStrategicActionType, TriggerStrategicVarType, - WarStatBundleMap, WarStatName, } from '@sammo-ts/logic/triggers/types.js'; import type { WarActionContext, WarActionModule } from '@sammo-ts/logic/war/actions.js'; @@ -66,7 +64,7 @@ export class TraitGeneralActionRouter< constructor( private readonly kind: TraitKind, private readonly registry: TraitModuleRegistry - ) { } + ) {} private getModule(context: GeneralActionContext): TraitModule | null { const key = resolveTraitKey(context, this.kind); @@ -89,32 +87,24 @@ export class TraitGeneralActionRouter< return module?.onCalcDomestic?.(context, turnType, varType, value, aux) ?? value; } - onCalcStat( + onCalcStat( context: GeneralActionContext, - statName: T, - value: GeneralStatBundleMap[T]['value'], - aux?: GeneralStatBundleMap[T]['aux'] - ): GeneralStatBundleMap[T]['return'] { + statName: GeneralStatName, + value: number, + aux?: unknown + ): number { const module = this.getModule(context); - const onCalcStat = module?.onCalcStat; - if (onCalcStat) { - return onCalcStat(context, statName, value as never, aux as never) as never; - } - return value; + return module?.onCalcStat?.(context, statName, value, aux) ?? value; } - onCalcOpposeStat( + onCalcOpposeStat( context: GeneralActionContext, - statName: T, - value: GeneralStatBundleMap[T]['value'], - aux?: GeneralStatBundleMap[T]['aux'] - ): GeneralStatBundleMap[T]['return'] { + statName: GeneralStatName, + value: number, + aux?: unknown + ): number { const module = this.getModule(context); - const onCalcOpposeStat = module?.onCalcOpposeStat; - if (onCalcOpposeStat) { - return onCalcOpposeStat(context, statName, value as never, aux as never) as never; - } - return value; + return module?.onCalcOpposeStat?.(context, statName, value, aux) ?? value; } onCalcStrategic( @@ -155,7 +145,7 @@ export class TraitWarActionRouter< constructor( private readonly kind: TraitKind, private readonly registry: TraitModuleRegistry - ) { } + ) {} private getModule(context: WarActionContext): TraitModule | null { const key = resolveTraitKey(context, this.kind); @@ -172,32 +162,24 @@ export class TraitWarActionRouter< return module?.getBattlePhaseTriggerList?.(context) ?? null; } - onCalcStat( + onCalcStat( context: WarActionContext, - statName: T, - value: WarStatBundleMap[T]['value'], - aux?: WarStatBundleMap[T]['aux'] - ): WarStatBundleMap[T]['return'] { + statName: WarStatName, + value: number | [number, number], + aux?: unknown + ): number | [number, number] { const module = this.getModule(context); - const onCalcStat = module?.onCalcStat; - if (onCalcStat) { - return onCalcStat(context, statName, value as never, aux as never) as never; - } - return value; + return module?.onCalcStat?.(context, statName, value, aux) ?? value; } - onCalcOpposeStat( + onCalcOpposeStat( context: WarActionContext, - statName: T, - value: WarStatBundleMap[T]['value'], - aux?: WarStatBundleMap[T]['aux'] - ): WarStatBundleMap[T]['return'] { + statName: WarStatName, + value: number | [number, number], + aux?: unknown + ): number | [number, number] { const module = this.getModule(context); - const onCalcOpposeStat = module?.onCalcOpposeStat; - if (onCalcOpposeStat) { - return onCalcOpposeStat(context, statName, value as never, aux as never) as never; - } - return value; + return module?.onCalcOpposeStat?.(context, statName, value, aux) ?? value; } getWarPowerMultiplier( diff --git a/packages/logic/src/triggers/special/types.ts b/packages/logic/src/triggers/special/types.ts index f7f7a36..2cddcce 100644 --- a/packages/logic/src/triggers/special/types.ts +++ b/packages/logic/src/triggers/special/types.ts @@ -13,41 +13,24 @@ export interface TraitSpec { kind: TraitKind; } -import type { - GeneralStatName, - GeneralStatBundleMap, - WarStatName, - WarStatBundleMap, -} from '../types.js'; - export interface TraitOnCalcStat { - ( - context: GeneralActionContext, - statName: T, - value: GeneralStatBundleMap[T]['value'], - aux?: GeneralStatBundleMap[T]['aux'] - ): GeneralStatBundleMap[T]['return']; - ( + (context: GeneralActionContext, statName: GeneralStatName, value: number, aux?: unknown): number; + ( context: WarActionContext, - statName: T, - value: WarStatBundleMap[T]['value'], - aux?: WarStatBundleMap[T]['aux'] - ): WarStatBundleMap[T]['return']; + statName: WarStatName, + value: number | [number, number], + aux?: unknown + ): number | [number, number]; } export interface TraitOnCalcOpposeStat { - ( - context: GeneralActionContext, - statName: T, - value: GeneralStatBundleMap[T]['value'], - aux?: GeneralStatBundleMap[T]['aux'] - ): GeneralStatBundleMap[T]['return']; - ( + (context: GeneralActionContext, statName: GeneralStatName, value: number, aux?: unknown): number; + ( context: WarActionContext, - statName: T, - value: WarStatBundleMap[T]['value'], - aux?: WarStatBundleMap[T]['aux'] - ): WarStatBundleMap[T]['return']; + statName: WarStatName, + value: number | [number, number], + aux?: unknown + ): number | [number, number]; } export type TraitModule = TraitSpec & diff --git a/packages/logic/src/triggers/types.ts b/packages/logic/src/triggers/types.ts index 088d365..c355eaf 100644 --- a/packages/logic/src/triggers/types.ts +++ b/packages/logic/src/triggers/types.ts @@ -1,6 +1,3 @@ -import type { GeneralTriggerState } from '@sammo-ts/logic/domain/entities.js'; -import type { GeneralActionContext } from './general.js'; -import type { WarActionContext } from '../war/actions.js'; export type TriggerActionType = '장비매매'; export type TriggerActionPhase = '판매' | '구매'; @@ -31,71 +28,17 @@ export type TriggerNationalIncomeType = 'gold' | 'rice'; export type GeneralStatName = 'leadership' | 'strength' | 'intelligence' | 'experience' | 'dedication'; -export type GeneralStatBundle = - | { statName: 'leadership'; value: number; aux: undefined; return: number } - | { statName: 'strength'; value: number; aux: undefined; return: number } - | { statName: 'intelligence'; value: number; aux: undefined; return: number } - | { statName: 'experience'; value: number; aux: undefined; return: number } - | { statName: 'dedication'; value: number; aux: undefined; return: number }; - -export type GeneralStatBundleMap = { - [T in GeneralStatBundle as T['statName']]: T; -}; - -export type WarStatBundle = - | GeneralStatBundle - | { statName: 'cityBattleOrder'; value: number; aux: undefined; return: number } - | { statName: 'initWarPhase'; value: number; aux: { isAttacker: boolean }; return: number } - | { statName: 'bonusTrain'; value: number; aux: { isAttacker: boolean }; return: number } - | { statName: 'bonusAtmos'; value: number; aux: { isAttacker: boolean }; return: number } - | { statName: 'warCriticalRatio'; value: number; aux: { isAttacker: boolean }; return: number } - | { statName: 'warAvoidRatio'; value: number; aux: { isAttacker: boolean }; return: number } - | { statName: 'killRice'; value: number; aux: undefined; return: number } - | { statName: 'criticalDamageRange'; value: [number, number]; aux: undefined; return: [number, number] } - | { statName: 'warMagicSuccessDamage'; value: number; aux: undefined; return: number } - | { statName: 'warMagicTrialProb'; value: number; aux: undefined; return: number } - | { statName: 'warMagicSuccessProb'; value: number; aux: undefined; return: number } - | { - statName: `dex${number}`; - value: number; - aux: { isAttacker: boolean; opposeType: { armType: number } | null }; - return: number; - }; - -export type WarStatBundleMap = { - [T in WarStatBundle as T['statName']]: T; -}; - -export type WarStatName = WarStatBundle['statName']; - -export interface TraitOnCalcStat { - ( - context: GeneralActionContext, - statName: T, - value: GeneralStatBundleMap[T]['value'], - aux?: GeneralStatBundleMap[T]['aux'] - ): GeneralStatBundleMap[T]['return']; - ( - context: WarActionContext, - statName: T, - value: WarStatBundleMap[T]['value'], - aux?: WarStatBundleMap[T]['aux'] - ): WarStatBundleMap[T]['return']; -} - -export interface TraitOnCalcOpposeStat { - ( - context: GeneralActionContext, - statName: T, - value: GeneralStatBundleMap[T]['value'], - aux?: GeneralStatBundleMap[T]['aux'] - ): GeneralStatBundleMap[T]['return']; - ( - context: WarActionContext, - statName: T, - value: WarStatBundleMap[T]['value'], - aux?: WarStatBundleMap[T]['aux'] - ): WarStatBundleMap[T]['return']; -} - -export type TriggerActionType = '장비매매'; +export type WarStatName = + | GeneralStatName + | 'cityBattleOrder' + | 'initWarPhase' + | 'bonusTrain' + | 'bonusAtmos' + | 'warCriticalRatio' + | 'warAvoidRatio' + | 'killRice' + | 'criticalDamageRange' + | 'warMagicSuccessDamage' + | 'warMagicTrialProb' + | 'warMagicSuccessProb' + | `dex${number}`; diff --git a/packages/logic/src/war/actions.ts b/packages/logic/src/war/actions.ts index 33a0ffd..996537a 100644 --- a/packages/logic/src/war/actions.ts +++ b/packages/logic/src/war/actions.ts @@ -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 { WarStatBundleMap, WarStatName } from '@sammo-ts/logic/triggers/types.js'; +import type { WarStatName } from '@sammo-ts/logic/triggers/types.js'; import type { WarUnit } from './units.js'; import { WarTriggerCaller } from './triggers.js'; @@ -24,30 +24,30 @@ export interface WarActionModule) => WarTriggerCaller | null) | undefined; onCalcStat?: - | (( - context: WarActionContext, - statName: T, - value: WarStatBundleMap[T]['value'], - aux?: WarStatBundleMap[T]['aux'] - ) => WarStatBundleMap[T]['return']) - | undefined; + | (( + context: WarActionContext, + statName: WarStatName, + value: number | [number, number], + aux?: unknown + ) => number | [number, number]) + | undefined; onCalcOpposeStat?: - | (( - context: WarActionContext, - statName: T, - value: WarStatBundleMap[T]['value'], - aux?: WarStatBundleMap[T]['aux'] - ) => WarStatBundleMap[T]['return']) - | undefined; + | (( + context: WarActionContext, + statName: WarStatName, + value: number | [number, number], + aux?: unknown + ) => number | [number, number]) + | undefined; getWarPowerMultiplier?: - | (( - context: WarActionContext, - unit: WarUnit, - oppose: WarUnit - ) => [number, number]) - | undefined; + | (( + context: WarActionContext, + unit: WarUnit, + oppose: WarUnit + ) => [number, number]) + | undefined; } export class WarActionPipeline { @@ -80,36 +80,36 @@ export class WarActionPipeline( + onCalcStat( context: WarActionContext, - statName: T, - value: WarStatBundleMap[T]['value'], - aux?: WarStatBundleMap[T]['aux'] - ): WarStatBundleMap[T]['return'] { - let current = value; + statName: WarStatName, + value: T, + aux?: unknown + ): T { + let current: number | [number, number] = value; for (const module of this.modules) { if (!module.onCalcStat) { continue; } - current = module.onCalcStat(context, statName, current as never, aux as never) as never; + current = module.onCalcStat(context, statName, current, aux); } - return current; + return current as T; } - onCalcOpposeStat( + onCalcOpposeStat( context: WarActionContext, - statName: T, - value: WarStatBundleMap[T]['value'], - aux?: WarStatBundleMap[T]['aux'] - ): WarStatBundleMap[T]['return'] { - let current = value; + statName: WarStatName, + value: T, + aux?: unknown + ): T { + let current: number | [number, number] = value; for (const module of this.modules) { if (!module.onCalcOpposeStat) { continue; } - current = module.onCalcOpposeStat(context, statName, current as never, aux as never) as never; + current = module.onCalcOpposeStat(context, statName, current, aux); } - return current; + return current as T; } getWarPowerMultiplier( diff --git a/packages/logic/src/war/units.ts b/packages/logic/src/war/units.ts index 4b81451..6e4e128 100644 --- a/packages/logic/src/war/units.ts +++ b/packages/logic/src/war/units.ts @@ -466,8 +466,8 @@ export class WarUnitGeneral< const baseTurnTime = this.isAttacker() ? getMetaString(this.general.meta, META_TURN_TIME) : oppose instanceof WarUnitGeneral - ? getMetaString(oppose.general.meta, META_TURN_TIME) - : getMetaString(this.general.meta, META_TURN_TIME); + ? getMetaString(oppose.general.meta, META_TURN_TIME) + : getMetaString(this.general.meta, META_TURN_TIME); if (!baseTurnTime) { return; } @@ -480,8 +480,9 @@ export class WarUnitGeneral< public override getMaxPhase(): number { const base = this.getCrewType().speed; + const aux = { isAttacker: this.isAttacker() }; const context = this.getActionContext(); - const phase = this.actionPipeline.onCalcStat(context, 'initWarPhase', base, { isAttacker: this.isAttacker() }); + const phase = this.actionPipeline.onCalcStat(context, 'initWarPhase', base, aux); return phase + this.bonusPhase; } @@ -506,16 +507,12 @@ export class WarUnitGeneral< return strength; } - private resolveOpposeStatValue(statName: WarStatName, value: number, aux?: any): number { + private resolveOpposeStatValue(statName: WarStatName, value: number, aux?: Record): number { const oppose = this.getOppose(); if (!(oppose instanceof WarUnitGeneral)) { return value; } - const result = oppose.getActionPipeline().onCalcOpposeStat(this.getActionContext(), statName, value, aux); - if (typeof result === 'number') { - return result; - } - return value; + return oppose.getActionPipeline().onCalcOpposeStat(this.getActionContext(), statName, value, aux); } public override getDex(crewType: WarCrewType): number { @@ -530,10 +527,8 @@ export class WarUnitGeneral< }; const statName = toDexStatName(armType); let dex = this.actionPipeline.onCalcStat(this.getActionContext(), statName, base, aux); - if (typeof dex === 'number') { - dex = this.resolveOpposeStatValue(statName, dex, aux); - } - return typeof dex === 'number' ? dex : base; + dex = this.resolveOpposeStatValue(statName, dex, aux); + return dex; } public override getComputedAttack(): number { @@ -583,8 +578,8 @@ export class WarUnitGeneral< const mainStat = this.resolveMainStat(armType); const coef = armType === this.config.armTypes.wizard || - armType === this.config.armTypes.siege || - armType === this.config.armTypes.misc + armType === this.config.armTypes.siege || + armType === this.config.armTypes.misc ? 0.4 : 0.5;