wip: 바보 젬3플. type 재정의 준비
This commit is contained in:
@@ -34,31 +34,19 @@ export const createStatItemModule = (options: StatItemOptions): ItemModule => {
|
|||||||
const name = `${options.rawName}(+${options.statValue})`;
|
const name = `${options.rawName}(+${options.statValue})`;
|
||||||
const baseInfo = `${statLabel} +${options.statValue}`;
|
const baseInfo = `${statLabel} +${options.statValue}`;
|
||||||
const info = options.extraInfo ? `${baseInfo}<br>${options.extraInfo}` : baseInfo;
|
const info = options.extraInfo ? `${baseInfo}<br>${options.extraInfo}` : baseInfo;
|
||||||
function onCalcStat(
|
const 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,
|
_context: GeneralActionContext | WarActionContext,
|
||||||
statName: GeneralStatName | WarStatName,
|
statName: GeneralStatName | WarStatName,
|
||||||
value: number | [number, number]
|
value: number | [number, number]
|
||||||
): number | [number, number] {
|
): number | [number, number] => {
|
||||||
if (statName !== options.statName) {
|
if (statName !== options.statName) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
if (Array.isArray(value)) {
|
if (typeof value === 'number') {
|
||||||
return value;
|
return value + options.statValue;
|
||||||
}
|
}
|
||||||
return value + options.statValue;
|
return value;
|
||||||
}
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
key: options.key,
|
key: options.key,
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import type { GeneralTriggerState } from '@sammo-ts/logic/domain/entities.js';
|
import type { GeneralTriggerState } from '@sammo-ts/logic/domain/entities.js';
|
||||||
import { type GeneralActionContext, GeneralTriggerCaller } from './general.js';
|
import { type GeneralActionContext, GeneralTriggerCaller } from './general.js';
|
||||||
import type {
|
import type {
|
||||||
|
GeneralStatBundleMap,
|
||||||
GeneralStatName,
|
GeneralStatName,
|
||||||
|
WarStatBundleMap,
|
||||||
TriggerActionPhase,
|
TriggerActionPhase,
|
||||||
TriggerActionType,
|
TriggerActionType,
|
||||||
TriggerDomesticActionType,
|
TriggerDomesticActionType,
|
||||||
@@ -16,58 +18,58 @@ export interface GeneralActionModule<TriggerState extends GeneralTriggerState =
|
|||||||
getInfo?: (() => string) | undefined;
|
getInfo?: (() => string) | undefined;
|
||||||
|
|
||||||
getPreTurnExecuteTriggerList?:
|
getPreTurnExecuteTriggerList?:
|
||||||
| ((context: GeneralActionContext<TriggerState>) => GeneralTriggerCaller<TriggerState> | null)
|
| ((context: GeneralActionContext<TriggerState>) => GeneralTriggerCaller<TriggerState> | null)
|
||||||
| undefined;
|
| undefined;
|
||||||
|
|
||||||
onCalcDomestic?:
|
onCalcDomestic?:
|
||||||
| ((
|
| ((
|
||||||
context: GeneralActionContext<TriggerState>,
|
context: GeneralActionContext<TriggerState>,
|
||||||
turnType: TriggerDomesticActionType,
|
turnType: TriggerDomesticActionType,
|
||||||
varType: TriggerDomesticVarType,
|
varType: TriggerDomesticVarType,
|
||||||
value: number,
|
value: number,
|
||||||
aux?: unknown
|
aux?: unknown
|
||||||
) => number)
|
) => number)
|
||||||
| undefined;
|
| undefined;
|
||||||
|
|
||||||
onCalcStat?:
|
onCalcStat?:
|
||||||
| ((
|
| (<T extends GeneralStatName>(
|
||||||
context: GeneralActionContext<TriggerState>,
|
context: GeneralActionContext<TriggerState>,
|
||||||
statName: GeneralStatName,
|
statName: T,
|
||||||
value: number,
|
value: GeneralStatBundleMap[T]['value'],
|
||||||
aux?: unknown
|
aux?: GeneralStatBundleMap[T]['aux']
|
||||||
) => number)
|
) => GeneralStatBundleMap[T]['return'])
|
||||||
| undefined;
|
| undefined;
|
||||||
|
|
||||||
onCalcOpposeStat?:
|
onCalcOpposeStat?:
|
||||||
| ((
|
| (<T extends GeneralStatName>(
|
||||||
context: GeneralActionContext<TriggerState>,
|
context: GeneralActionContext<TriggerState>,
|
||||||
statName: GeneralStatName,
|
statName: T,
|
||||||
value: number,
|
value: GeneralStatBundleMap[T]['value'],
|
||||||
aux?: unknown
|
aux?: GeneralStatBundleMap[T]['aux']
|
||||||
) => number)
|
) => GeneralStatBundleMap[T]['return'])
|
||||||
| undefined;
|
| undefined;
|
||||||
|
|
||||||
onCalcStrategic?:
|
onCalcStrategic?:
|
||||||
| ((
|
| ((
|
||||||
context: GeneralActionContext<TriggerState>,
|
context: GeneralActionContext<TriggerState>,
|
||||||
turnType: TriggerStrategicActionType,
|
turnType: TriggerStrategicActionType,
|
||||||
varType: TriggerStrategicVarType,
|
varType: TriggerStrategicVarType,
|
||||||
value: number
|
value: number
|
||||||
) => number)
|
) => number)
|
||||||
| undefined;
|
| undefined;
|
||||||
|
|
||||||
onCalcNationalIncome?:
|
onCalcNationalIncome?:
|
||||||
| ((context: GeneralActionContext<TriggerState>, type: TriggerNationalIncomeType, amount: number) => number)
|
| ((context: GeneralActionContext<TriggerState>, type: TriggerNationalIncomeType, amount: number) => number)
|
||||||
| undefined;
|
| undefined;
|
||||||
|
|
||||||
onArbitraryAction?:
|
onArbitraryAction?:
|
||||||
| ((
|
| ((
|
||||||
context: GeneralActionContext<TriggerState>,
|
context: GeneralActionContext<TriggerState>,
|
||||||
actionType: TriggerActionType,
|
actionType: TriggerActionType,
|
||||||
phase?: TriggerActionPhase | null,
|
phase?: TriggerActionPhase | null,
|
||||||
aux?: Record<string, unknown> | null
|
aux?: Record<string, unknown> | null
|
||||||
) => Record<string, unknown> | null)
|
) => Record<string, unknown> | null)
|
||||||
| undefined;
|
| undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GeneralActionPipeline<TriggerState extends GeneralTriggerState = GeneralTriggerState> {
|
export class GeneralActionPipeline<TriggerState extends GeneralTriggerState = GeneralTriggerState> {
|
||||||
@@ -107,12 +109,12 @@ export class GeneralActionPipeline<TriggerState extends GeneralTriggerState = Ge
|
|||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
onCalcStat(
|
onCalcStat<T extends GeneralStatName>(
|
||||||
context: GeneralActionContext<TriggerState>,
|
context: GeneralActionContext<TriggerState>,
|
||||||
statName: GeneralStatName,
|
statName: T,
|
||||||
value: number,
|
value: GeneralStatBundleMap[T]['value'],
|
||||||
aux?: unknown
|
aux?: GeneralStatBundleMap[T]['aux']
|
||||||
): number {
|
): GeneralStatBundleMap[T]['return'] {
|
||||||
let current = value;
|
let current = value;
|
||||||
for (const module of this.modules) {
|
for (const module of this.modules) {
|
||||||
if (!module.onCalcStat) {
|
if (!module.onCalcStat) {
|
||||||
@@ -123,12 +125,12 @@ export class GeneralActionPipeline<TriggerState extends GeneralTriggerState = Ge
|
|||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
onCalcOpposeStat(
|
onCalcOpposeStat<T extends GeneralStatName>(
|
||||||
context: GeneralActionContext<TriggerState>,
|
context: GeneralActionContext<TriggerState>,
|
||||||
statName: GeneralStatName,
|
statName: T,
|
||||||
value: number,
|
value: GeneralStatBundleMap[T]['value'],
|
||||||
aux?: unknown
|
aux?: GeneralStatBundleMap[T]['aux']
|
||||||
): number {
|
): GeneralStatBundleMap[T]['return'] {
|
||||||
let current = value;
|
let current = value;
|
||||||
for (const module of this.modules) {
|
for (const module of this.modules) {
|
||||||
if (!module.onCalcOpposeStat) {
|
if (!module.onCalcOpposeStat) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import type { GeneralTriggerState } from '@sammo-ts/logic/domain/entities.js';
|
|||||||
import type { GeneralActionContext } from '@sammo-ts/logic/triggers/general.js';
|
import type { GeneralActionContext } from '@sammo-ts/logic/triggers/general.js';
|
||||||
import type { GeneralActionModule } from '@sammo-ts/logic/triggers/general-action.js';
|
import type { GeneralActionModule } from '@sammo-ts/logic/triggers/general-action.js';
|
||||||
import type {
|
import type {
|
||||||
|
GeneralStatBundleMap,
|
||||||
GeneralStatName,
|
GeneralStatName,
|
||||||
TriggerActionPhase,
|
TriggerActionPhase,
|
||||||
TriggerActionType,
|
TriggerActionType,
|
||||||
@@ -10,6 +11,7 @@ import type {
|
|||||||
TriggerNationalIncomeType,
|
TriggerNationalIncomeType,
|
||||||
TriggerStrategicActionType,
|
TriggerStrategicActionType,
|
||||||
TriggerStrategicVarType,
|
TriggerStrategicVarType,
|
||||||
|
WarStatBundleMap,
|
||||||
WarStatName,
|
WarStatName,
|
||||||
} from '@sammo-ts/logic/triggers/types.js';
|
} from '@sammo-ts/logic/triggers/types.js';
|
||||||
import type { WarActionContext, WarActionModule } from '@sammo-ts/logic/war/actions.js';
|
import type { WarActionContext, WarActionModule } from '@sammo-ts/logic/war/actions.js';
|
||||||
@@ -64,7 +66,7 @@ export class TraitGeneralActionRouter<
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly kind: TraitKind,
|
private readonly kind: TraitKind,
|
||||||
private readonly registry: TraitModuleRegistry<TriggerState>
|
private readonly registry: TraitModuleRegistry<TriggerState>
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
private getModule(context: GeneralActionContext<TriggerState>): TraitModule<TriggerState> | null {
|
private getModule(context: GeneralActionContext<TriggerState>): TraitModule<TriggerState> | null {
|
||||||
const key = resolveTraitKey(context, this.kind);
|
const key = resolveTraitKey(context, this.kind);
|
||||||
@@ -87,24 +89,32 @@ export class TraitGeneralActionRouter<
|
|||||||
return module?.onCalcDomestic?.(context, turnType, varType, value, aux) ?? value;
|
return module?.onCalcDomestic?.(context, turnType, varType, value, aux) ?? value;
|
||||||
}
|
}
|
||||||
|
|
||||||
onCalcStat(
|
onCalcStat<T extends GeneralStatName>(
|
||||||
context: GeneralActionContext<TriggerState>,
|
context: GeneralActionContext<TriggerState>,
|
||||||
statName: GeneralStatName,
|
statName: T,
|
||||||
value: number,
|
value: GeneralStatBundleMap[T]['value'],
|
||||||
aux?: unknown
|
aux?: GeneralStatBundleMap[T]['aux']
|
||||||
): number {
|
): GeneralStatBundleMap[T]['return'] {
|
||||||
const module = this.getModule(context);
|
const module = this.getModule(context);
|
||||||
return module?.onCalcStat?.(context, statName, value, aux) ?? value;
|
const onCalcStat = module?.onCalcStat;
|
||||||
|
if (onCalcStat) {
|
||||||
|
return onCalcStat(context, statName, value as never, aux as never) as never;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
onCalcOpposeStat(
|
onCalcOpposeStat<T extends GeneralStatName>(
|
||||||
context: GeneralActionContext<TriggerState>,
|
context: GeneralActionContext<TriggerState>,
|
||||||
statName: GeneralStatName,
|
statName: T,
|
||||||
value: number,
|
value: GeneralStatBundleMap[T]['value'],
|
||||||
aux?: unknown
|
aux?: GeneralStatBundleMap[T]['aux']
|
||||||
): number {
|
): GeneralStatBundleMap[T]['return'] {
|
||||||
const module = this.getModule(context);
|
const module = this.getModule(context);
|
||||||
return module?.onCalcOpposeStat?.(context, statName, value, aux) ?? value;
|
const onCalcOpposeStat = module?.onCalcOpposeStat;
|
||||||
|
if (onCalcOpposeStat) {
|
||||||
|
return onCalcOpposeStat(context, statName, value as never, aux as never) as never;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
onCalcStrategic(
|
onCalcStrategic(
|
||||||
@@ -145,7 +155,7 @@ export class TraitWarActionRouter<
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly kind: TraitKind,
|
private readonly kind: TraitKind,
|
||||||
private readonly registry: TraitModuleRegistry<TriggerState>
|
private readonly registry: TraitModuleRegistry<TriggerState>
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
private getModule(context: WarActionContext<TriggerState>): TraitModule<TriggerState> | null {
|
private getModule(context: WarActionContext<TriggerState>): TraitModule<TriggerState> | null {
|
||||||
const key = resolveTraitKey(context, this.kind);
|
const key = resolveTraitKey(context, this.kind);
|
||||||
@@ -162,24 +172,32 @@ export class TraitWarActionRouter<
|
|||||||
return module?.getBattlePhaseTriggerList?.(context) ?? null;
|
return module?.getBattlePhaseTriggerList?.(context) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
onCalcStat(
|
onCalcStat<T extends WarStatName>(
|
||||||
context: WarActionContext<TriggerState>,
|
context: WarActionContext<TriggerState>,
|
||||||
statName: WarStatName,
|
statName: T,
|
||||||
value: number | [number, number],
|
value: WarStatBundleMap[T]['value'],
|
||||||
aux?: unknown
|
aux?: WarStatBundleMap[T]['aux']
|
||||||
): number | [number, number] {
|
): WarStatBundleMap[T]['return'] {
|
||||||
const module = this.getModule(context);
|
const module = this.getModule(context);
|
||||||
return module?.onCalcStat?.(context, statName, value, aux) ?? value;
|
const onCalcStat = module?.onCalcStat;
|
||||||
|
if (onCalcStat) {
|
||||||
|
return onCalcStat(context, statName, value as never, aux as never) as never;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
onCalcOpposeStat(
|
onCalcOpposeStat<T extends WarStatName>(
|
||||||
context: WarActionContext<TriggerState>,
|
context: WarActionContext<TriggerState>,
|
||||||
statName: WarStatName,
|
statName: T,
|
||||||
value: number | [number, number],
|
value: WarStatBundleMap[T]['value'],
|
||||||
aux?: unknown
|
aux?: WarStatBundleMap[T]['aux']
|
||||||
): number | [number, number] {
|
): WarStatBundleMap[T]['return'] {
|
||||||
const module = this.getModule(context);
|
const module = this.getModule(context);
|
||||||
return module?.onCalcOpposeStat?.(context, statName, value, aux) ?? value;
|
const onCalcOpposeStat = module?.onCalcOpposeStat;
|
||||||
|
if (onCalcOpposeStat) {
|
||||||
|
return onCalcOpposeStat(context, statName, value as never, aux as never) as never;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
getWarPowerMultiplier(
|
getWarPowerMultiplier(
|
||||||
|
|||||||
@@ -13,24 +13,41 @@ export interface TraitSpec {
|
|||||||
kind: TraitKind;
|
kind: TraitKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import type {
|
||||||
|
GeneralStatName,
|
||||||
|
GeneralStatBundleMap,
|
||||||
|
WarStatName,
|
||||||
|
WarStatBundleMap,
|
||||||
|
} from '../types.js';
|
||||||
|
|
||||||
export interface TraitOnCalcStat<TriggerState extends GeneralTriggerState = GeneralTriggerState> {
|
export interface TraitOnCalcStat<TriggerState extends GeneralTriggerState = GeneralTriggerState> {
|
||||||
(context: GeneralActionContext<TriggerState>, statName: GeneralStatName, value: number, aux?: unknown): number;
|
<T extends GeneralStatName>(
|
||||||
(
|
context: GeneralActionContext<TriggerState>,
|
||||||
|
statName: T,
|
||||||
|
value: GeneralStatBundleMap[T]['value'],
|
||||||
|
aux?: GeneralStatBundleMap[T]['aux']
|
||||||
|
): GeneralStatBundleMap[T]['return'];
|
||||||
|
<T extends WarStatName>(
|
||||||
context: WarActionContext<TriggerState>,
|
context: WarActionContext<TriggerState>,
|
||||||
statName: WarStatName,
|
statName: T,
|
||||||
value: number | [number, number],
|
value: WarStatBundleMap[T]['value'],
|
||||||
aux?: unknown
|
aux?: WarStatBundleMap[T]['aux']
|
||||||
): number | [number, number];
|
): WarStatBundleMap[T]['return'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TraitOnCalcOpposeStat<TriggerState extends GeneralTriggerState = GeneralTriggerState> {
|
export interface TraitOnCalcOpposeStat<TriggerState extends GeneralTriggerState = GeneralTriggerState> {
|
||||||
(context: GeneralActionContext<TriggerState>, statName: GeneralStatName, value: number, aux?: unknown): number;
|
<T extends GeneralStatName>(
|
||||||
(
|
context: GeneralActionContext<TriggerState>,
|
||||||
|
statName: T,
|
||||||
|
value: GeneralStatBundleMap[T]['value'],
|
||||||
|
aux?: GeneralStatBundleMap[T]['aux']
|
||||||
|
): GeneralStatBundleMap[T]['return'];
|
||||||
|
<T extends WarStatName>(
|
||||||
context: WarActionContext<TriggerState>,
|
context: WarActionContext<TriggerState>,
|
||||||
statName: WarStatName,
|
statName: T,
|
||||||
value: number | [number, number],
|
value: WarStatBundleMap[T]['value'],
|
||||||
aux?: unknown
|
aux?: WarStatBundleMap[T]['aux']
|
||||||
): number | [number, number];
|
): WarStatBundleMap[T]['return'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TraitModule<TriggerState extends GeneralTriggerState = GeneralTriggerState> = TraitSpec &
|
export type TraitModule<TriggerState extends GeneralTriggerState = GeneralTriggerState> = TraitSpec &
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
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 TriggerActionType = '장비매매';
|
||||||
|
|
||||||
export type TriggerActionPhase = '판매' | '구매';
|
export type TriggerActionPhase = '판매' | '구매';
|
||||||
@@ -28,17 +31,71 @@ export type TriggerNationalIncomeType = 'gold' | 'rice';
|
|||||||
|
|
||||||
export type GeneralStatName = 'leadership' | 'strength' | 'intelligence' | 'experience' | 'dedication';
|
export type GeneralStatName = 'leadership' | 'strength' | 'intelligence' | 'experience' | 'dedication';
|
||||||
|
|
||||||
export type WarStatName =
|
export type GeneralStatBundle =
|
||||||
| GeneralStatName
|
| { statName: 'leadership'; value: number; aux: undefined; return: number }
|
||||||
| 'cityBattleOrder'
|
| { statName: 'strength'; value: number; aux: undefined; return: number }
|
||||||
| 'initWarPhase'
|
| { statName: 'intelligence'; value: number; aux: undefined; return: number }
|
||||||
| 'bonusTrain'
|
| { statName: 'experience'; value: number; aux: undefined; return: number }
|
||||||
| 'bonusAtmos'
|
| { statName: 'dedication'; value: number; aux: undefined; return: number };
|
||||||
| 'warCriticalRatio'
|
|
||||||
| 'warAvoidRatio'
|
export type GeneralStatBundleMap = {
|
||||||
| 'killRice'
|
[T in GeneralStatBundle as T['statName']]: T;
|
||||||
| 'criticalDamageRange'
|
};
|
||||||
| 'warMagicSuccessDamage'
|
|
||||||
| 'warMagicTrialProb'
|
export type WarStatBundle =
|
||||||
| 'warMagicSuccessProb'
|
| GeneralStatBundle
|
||||||
| `dex${number}`;
|
| { 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<TriggerState extends GeneralTriggerState = GeneralTriggerState> {
|
||||||
|
<T extends GeneralStatName>(
|
||||||
|
context: GeneralActionContext<TriggerState>,
|
||||||
|
statName: T,
|
||||||
|
value: GeneralStatBundleMap[T]['value'],
|
||||||
|
aux?: GeneralStatBundleMap[T]['aux']
|
||||||
|
): GeneralStatBundleMap[T]['return'];
|
||||||
|
<T extends WarStatName>(
|
||||||
|
context: WarActionContext<TriggerState>,
|
||||||
|
statName: T,
|
||||||
|
value: WarStatBundleMap[T]['value'],
|
||||||
|
aux?: WarStatBundleMap[T]['aux']
|
||||||
|
): WarStatBundleMap[T]['return'];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TraitOnCalcOpposeStat<TriggerState extends GeneralTriggerState = GeneralTriggerState> {
|
||||||
|
<T extends GeneralStatName>(
|
||||||
|
context: GeneralActionContext<TriggerState>,
|
||||||
|
statName: T,
|
||||||
|
value: GeneralStatBundleMap[T]['value'],
|
||||||
|
aux?: GeneralStatBundleMap[T]['aux']
|
||||||
|
): GeneralStatBundleMap[T]['return'];
|
||||||
|
<T extends WarStatName>(
|
||||||
|
context: WarActionContext<TriggerState>,
|
||||||
|
statName: T,
|
||||||
|
value: WarStatBundleMap[T]['value'],
|
||||||
|
aux?: WarStatBundleMap[T]['aux']
|
||||||
|
): WarStatBundleMap[T]['return'];
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TriggerActionType = '장비매매';
|
||||||
|
|||||||
@@ -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 { City, General, GeneralTriggerState, Nation } from '@sammo-ts/logic/domain/entities.js';
|
||||||
import type { ActionLogger } from '@sammo-ts/logic/logging/actionLogger.js';
|
import type { ActionLogger } from '@sammo-ts/logic/logging/actionLogger.js';
|
||||||
import type { WarStatName } from '@sammo-ts/logic/triggers/types.js';
|
import type { WarStatBundleMap, WarStatName } from '@sammo-ts/logic/triggers/types.js';
|
||||||
import type { WarUnit } from './units.js';
|
import type { WarUnit } from './units.js';
|
||||||
import { WarTriggerCaller } from './triggers.js';
|
import { WarTriggerCaller } from './triggers.js';
|
||||||
|
|
||||||
@@ -24,30 +24,30 @@ export interface WarActionModule<TriggerState extends GeneralTriggerState = Gene
|
|||||||
getBattlePhaseTriggerList?: ((context: WarActionContext<TriggerState>) => WarTriggerCaller | null) | undefined;
|
getBattlePhaseTriggerList?: ((context: WarActionContext<TriggerState>) => WarTriggerCaller | null) | undefined;
|
||||||
|
|
||||||
onCalcStat?:
|
onCalcStat?:
|
||||||
| ((
|
| (<T extends WarStatName>(
|
||||||
context: WarActionContext<TriggerState>,
|
context: WarActionContext<TriggerState>,
|
||||||
statName: WarStatName,
|
statName: T,
|
||||||
value: number | [number, number],
|
value: WarStatBundleMap[T]['value'],
|
||||||
aux?: unknown
|
aux?: WarStatBundleMap[T]['aux']
|
||||||
) => number | [number, number])
|
) => WarStatBundleMap[T]['return'])
|
||||||
| undefined;
|
| undefined;
|
||||||
|
|
||||||
onCalcOpposeStat?:
|
onCalcOpposeStat?:
|
||||||
| ((
|
| (<T extends WarStatName>(
|
||||||
context: WarActionContext<TriggerState>,
|
context: WarActionContext<TriggerState>,
|
||||||
statName: WarStatName,
|
statName: T,
|
||||||
value: number | [number, number],
|
value: WarStatBundleMap[T]['value'],
|
||||||
aux?: unknown
|
aux?: WarStatBundleMap[T]['aux']
|
||||||
) => number | [number, number])
|
) => WarStatBundleMap[T]['return'])
|
||||||
| undefined;
|
| undefined;
|
||||||
|
|
||||||
getWarPowerMultiplier?:
|
getWarPowerMultiplier?:
|
||||||
| ((
|
| ((
|
||||||
context: WarActionContext<TriggerState>,
|
context: WarActionContext<TriggerState>,
|
||||||
unit: WarUnit<TriggerState>,
|
unit: WarUnit<TriggerState>,
|
||||||
oppose: WarUnit<TriggerState>
|
oppose: WarUnit<TriggerState>
|
||||||
) => [number, number])
|
) => [number, number])
|
||||||
| undefined;
|
| undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class WarActionPipeline<TriggerState extends GeneralTriggerState = GeneralTriggerState> {
|
export class WarActionPipeline<TriggerState extends GeneralTriggerState = GeneralTriggerState> {
|
||||||
@@ -80,36 +80,36 @@ export class WarActionPipeline<TriggerState extends GeneralTriggerState = Genera
|
|||||||
return caller;
|
return caller;
|
||||||
}
|
}
|
||||||
|
|
||||||
onCalcStat<T extends number | [number, number]>(
|
onCalcStat<T extends WarStatName>(
|
||||||
context: WarActionContext<TriggerState>,
|
context: WarActionContext<TriggerState>,
|
||||||
statName: WarStatName,
|
statName: T,
|
||||||
value: T,
|
value: WarStatBundleMap[T]['value'],
|
||||||
aux?: unknown
|
aux?: WarStatBundleMap[T]['aux']
|
||||||
): T {
|
): WarStatBundleMap[T]['return'] {
|
||||||
let current: number | [number, number] = value;
|
let current = value;
|
||||||
for (const module of this.modules) {
|
for (const module of this.modules) {
|
||||||
if (!module.onCalcStat) {
|
if (!module.onCalcStat) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
current = module.onCalcStat(context, statName, current, aux);
|
current = module.onCalcStat(context, statName, current as never, aux as never) as never;
|
||||||
}
|
}
|
||||||
return current as T;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
onCalcOpposeStat<T extends number | [number, number]>(
|
onCalcOpposeStat<T extends WarStatName>(
|
||||||
context: WarActionContext<TriggerState>,
|
context: WarActionContext<TriggerState>,
|
||||||
statName: WarStatName,
|
statName: T,
|
||||||
value: T,
|
value: WarStatBundleMap[T]['value'],
|
||||||
aux?: unknown
|
aux?: WarStatBundleMap[T]['aux']
|
||||||
): T {
|
): WarStatBundleMap[T]['return'] {
|
||||||
let current: number | [number, number] = value;
|
let current = value;
|
||||||
for (const module of this.modules) {
|
for (const module of this.modules) {
|
||||||
if (!module.onCalcOpposeStat) {
|
if (!module.onCalcOpposeStat) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
current = module.onCalcOpposeStat(context, statName, current, aux);
|
current = module.onCalcOpposeStat(context, statName, current as never, aux as never) as never;
|
||||||
}
|
}
|
||||||
return current as T;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
getWarPowerMultiplier(
|
getWarPowerMultiplier(
|
||||||
|
|||||||
@@ -466,8 +466,8 @@ export class WarUnitGeneral<
|
|||||||
const baseTurnTime = this.isAttacker()
|
const baseTurnTime = this.isAttacker()
|
||||||
? getMetaString(this.general.meta, META_TURN_TIME)
|
? getMetaString(this.general.meta, META_TURN_TIME)
|
||||||
: oppose instanceof WarUnitGeneral
|
: oppose instanceof WarUnitGeneral
|
||||||
? getMetaString(oppose.general.meta, META_TURN_TIME)
|
? getMetaString(oppose.general.meta, META_TURN_TIME)
|
||||||
: getMetaString(this.general.meta, META_TURN_TIME);
|
: getMetaString(this.general.meta, META_TURN_TIME);
|
||||||
if (!baseTurnTime) {
|
if (!baseTurnTime) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -480,9 +480,8 @@ export class WarUnitGeneral<
|
|||||||
|
|
||||||
public override getMaxPhase(): number {
|
public override getMaxPhase(): number {
|
||||||
const base = this.getCrewType().speed;
|
const base = this.getCrewType().speed;
|
||||||
const aux = { isAttacker: this.isAttacker() };
|
|
||||||
const context = this.getActionContext();
|
const context = this.getActionContext();
|
||||||
const phase = this.actionPipeline.onCalcStat(context, 'initWarPhase', base, aux);
|
const phase = this.actionPipeline.onCalcStat(context, 'initWarPhase', base, { isAttacker: this.isAttacker() });
|
||||||
return phase + this.bonusPhase;
|
return phase + this.bonusPhase;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,12 +506,16 @@ export class WarUnitGeneral<
|
|||||||
return strength;
|
return strength;
|
||||||
}
|
}
|
||||||
|
|
||||||
private resolveOpposeStatValue(statName: WarStatName, value: number, aux?: Record<string, unknown>): number {
|
private resolveOpposeStatValue(statName: WarStatName, value: number, aux?: any): number {
|
||||||
const oppose = this.getOppose();
|
const oppose = this.getOppose();
|
||||||
if (!(oppose instanceof WarUnitGeneral)) {
|
if (!(oppose instanceof WarUnitGeneral)) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
return oppose.getActionPipeline().onCalcOpposeStat(this.getActionContext(), statName, value, aux);
|
const result = oppose.getActionPipeline().onCalcOpposeStat(this.getActionContext(), statName, value, aux);
|
||||||
|
if (typeof result === 'number') {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override getDex(crewType: WarCrewType): number {
|
public override getDex(crewType: WarCrewType): number {
|
||||||
@@ -527,8 +530,10 @@ export class WarUnitGeneral<
|
|||||||
};
|
};
|
||||||
const statName = toDexStatName(armType);
|
const statName = toDexStatName(armType);
|
||||||
let dex = this.actionPipeline.onCalcStat(this.getActionContext(), statName, base, aux);
|
let dex = this.actionPipeline.onCalcStat(this.getActionContext(), statName, base, aux);
|
||||||
dex = this.resolveOpposeStatValue(statName, dex, aux);
|
if (typeof dex === 'number') {
|
||||||
return dex;
|
dex = this.resolveOpposeStatValue(statName, dex, aux);
|
||||||
|
}
|
||||||
|
return typeof dex === 'number' ? dex : base;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override getComputedAttack(): number {
|
public override getComputedAttack(): number {
|
||||||
@@ -578,8 +583,8 @@ export class WarUnitGeneral<
|
|||||||
const mainStat = this.resolveMainStat(armType);
|
const mainStat = this.resolveMainStat(armType);
|
||||||
const coef =
|
const coef =
|
||||||
armType === this.config.armTypes.wizard ||
|
armType === this.config.armTypes.wizard ||
|
||||||
armType === this.config.armTypes.siege ||
|
armType === this.config.armTypes.siege ||
|
||||||
armType === this.config.armTypes.misc
|
armType === this.config.armTypes.misc
|
||||||
? 0.4
|
? 0.4
|
||||||
: 0.5;
|
: 0.5;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user