feat: complete legacy unique item battle parity

This commit is contained in:
2026-07-25 06:47:56 +00:00
parent 35935c9eca
commit 0d7ede3d93
45 changed files with 1143 additions and 174 deletions
@@ -25,6 +25,8 @@ import type { ActionContextBase, ActionContextOptions } from '@sammo-ts/logic/ac
import type { GeneralTurnCommandSpec } from './index.js';
import { JosaUtil } from '@sammo-ts/common';
import { parseArgsWithSchema } from '../parseArgs.js';
import { GeneralActionPipeline, type GeneralActionModule } from '@sammo-ts/logic/triggers/general-action.js';
import { consumeSuccessfulStrategyItem } from './strategyItemConsumption.js';
export interface AgitateResolveContext<
TriggerState extends GeneralTriggerState = GeneralTriggerState,
@@ -44,6 +46,11 @@ export class ActionResolver<
TriggerState extends GeneralTriggerState = GeneralTriggerState,
> implements GeneralActionResolver<TriggerState, AgitateArgs> {
readonly key = ACTION_KEY;
private readonly pipeline: GeneralActionPipeline<TriggerState>;
constructor(modules: Array<GeneralActionModule<TriggerState> | null | undefined> = []) {
this.pipeline = new GeneralActionPipeline(modules);
}
resolve(context: GeneralActionResolveContext<TriggerState>, args: AgitateArgs): GeneralActionOutcome<TriggerState> {
const ctx = context as AgitateResolveContext<TriggerState>;
@@ -86,8 +93,8 @@ export class ActionResolver<
1
)}</>만큼 감소하고, 장수 <C>${injuryCount}</>명이 부상 당했습니다.`,
{
category: LogCategory.ACTION,
format: LogFormat.PLAIN,
category: LogCategory.ACTION,
format: LogFormat.PLAIN,
}
);
@@ -107,6 +114,8 @@ export class ActionResolver<
)
);
consumeSuccessfulStrategyItem(this.pipeline, context);
// General Update (Cost + Exp + LeaderExp)
effects.push(
createGeneralPatchEffect(
@@ -137,8 +146,10 @@ export class ActionDefinition<
public readonly name = ACTION_NAME;
private readonly resolver: ActionResolver<TriggerState>;
constructor(_env: TurnCommandEnv) {
this.resolver = new ActionResolver();
constructor(env: TurnCommandEnv) {
this.resolver = new ActionResolver<TriggerState>(
(env.generalActionModules ?? []) as GeneralActionModule<TriggerState>[]
);
}
parseArgs(raw: unknown): AgitateArgs | null {
@@ -29,6 +29,8 @@ import type { ActionContextBase, ActionContextOptions } from '@sammo-ts/logic/ac
import type { GeneralTurnCommandSpec } from './index.js';
import { JosaUtil } from '@sammo-ts/common';
import { parseArgsWithSchema } from '../parseArgs.js';
import { GeneralActionPipeline, type GeneralActionModule } from '@sammo-ts/logic/triggers/general-action.js';
import { consumeSuccessfulStrategyItem } from './strategyItemConsumption.js';
export interface SeizeResolveContext<
TriggerState extends GeneralTriggerState = GeneralTriggerState,
@@ -50,6 +52,11 @@ export class ActionResolver<
TriggerState extends GeneralTriggerState = GeneralTriggerState,
> implements GeneralActionResolver<TriggerState, SeizeArgs> {
readonly key = ACTION_KEY;
private readonly pipeline: GeneralActionPipeline<TriggerState>;
constructor(modules: Array<GeneralActionModule<TriggerState> | null | undefined> = []) {
this.pipeline = new GeneralActionPipeline(modules);
}
resolve(context: GeneralActionResolveContext<TriggerState>, args: SeizeArgs): GeneralActionOutcome<TriggerState> {
const ctx = context as SeizeResolveContext<TriggerState>;
@@ -166,6 +173,8 @@ export class ActionResolver<
format: LogFormat.PLAIN,
});
consumeSuccessfulStrategyItem(this.pipeline, context);
effects.push(
createGeneralPatchEffect(
{
@@ -195,8 +204,10 @@ export class ActionDefinition<
public readonly name = ACTION_NAME;
private readonly resolver: ActionResolver<TriggerState>;
constructor(_env: TurnCommandEnv) {
this.resolver = new ActionResolver();
constructor(env: TurnCommandEnv) {
this.resolver = new ActionResolver<TriggerState>(
(env.generalActionModules ?? []) as GeneralActionModule<TriggerState>[]
);
}
parseArgs(raw: unknown): SeizeArgs | null {
@@ -25,6 +25,8 @@ import type { ActionContextBase, ActionContextOptions } from '@sammo-ts/logic/ac
import type { GeneralTurnCommandSpec } from './index.js';
import { JosaUtil } from '@sammo-ts/common';
import { parseArgsWithSchema } from '../parseArgs.js';
import { GeneralActionPipeline, type GeneralActionModule } from '@sammo-ts/logic/triggers/general-action.js';
import { consumeSuccessfulStrategyItem } from './strategyItemConsumption.js';
export interface DestroyResolveContext<
TriggerState extends GeneralTriggerState = GeneralTriggerState,
@@ -44,6 +46,11 @@ export class ActionResolver<
TriggerState extends GeneralTriggerState = GeneralTriggerState,
> implements GeneralActionResolver<TriggerState, DestroyArgs> {
readonly key = ACTION_KEY;
private readonly pipeline: GeneralActionPipeline<TriggerState>;
constructor(modules: Array<GeneralActionModule<TriggerState> | null | undefined> = []) {
this.pipeline = new GeneralActionPipeline(modules);
}
resolve(context: GeneralActionResolveContext<TriggerState>, args: DestroyArgs): GeneralActionOutcome<TriggerState> {
const ctx = context as DestroyResolveContext<TriggerState>;
@@ -102,6 +109,8 @@ export class ActionResolver<
)
);
consumeSuccessfulStrategyItem(this.pipeline, context);
// General Update (Cost + Exp)
effects.push(
createGeneralPatchEffect(
@@ -132,8 +141,10 @@ export class ActionDefinition<
public readonly name = ACTION_NAME;
private readonly resolver: ActionResolver<TriggerState>;
constructor(_env: TurnCommandEnv) {
this.resolver = new ActionResolver();
constructor(env: TurnCommandEnv) {
this.resolver = new ActionResolver<TriggerState>(
(env.generalActionModules ?? []) as GeneralActionModule<TriggerState>[]
);
}
parseArgs(raw: unknown): DestroyArgs | null {
@@ -36,6 +36,7 @@ import { defaultActionContextBuilder } from '@sammo-ts/logic/actions/turn/action
import type { GeneralTurnCommandSpec } from './index.js';
import { clamp } from 'es-toolkit';
import { parseArgsWithSchema } from '../parseArgs.js';
import { consumeSuccessfulStrategyItem } from './strategyItemConsumption.js';
export interface FireAttackEnvironment {
develCost: number;
@@ -251,9 +252,11 @@ export class ActionResolver<
> implements GeneralActionResolver<TriggerState, FireAttackArgs> {
readonly key = 'che_화계';
private readonly command: CommandResolver<TriggerState>;
private readonly pipeline: GeneralActionPipeline<TriggerState>;
constructor(modules: Array<GeneralActionModule<TriggerState> | null | undefined>, env: FireAttackEnvironment) {
this.command = new CommandResolver(modules, env);
this.pipeline = new GeneralActionPipeline(modules);
}
resolve(
@@ -334,7 +337,7 @@ export class ActionResolver<
context.addLog(
`<G><b>${context.destCity.name}</b></>에 ${commandName}${JosaUtil.pick(commandName, '이')} 성공했습니다.`,
{
format: LogFormat.MONTH,
format: LogFormat.MONTH,
}
);
context.addLog(
@@ -345,7 +348,9 @@ export class ActionResolver<
);
const itemCode = general.role.items.item;
if (typeof itemCode === 'string' && itemCode.length > 0) {
const actionResult = consumeSuccessfulStrategyItem(this.pipeline, context);
const consumedItems = Array.isArray(actionResult?.['consumedItems']) ? actionResult['consumedItems'] : [];
if (typeof itemCode === 'string' && consumedItems.includes(itemCode)) {
context.addLog(`<C>${itemCode}</>${JosaUtil.pick(itemCode, '을')} 사용!`, {
format: LogFormat.PLAIN,
});
@@ -383,13 +388,7 @@ export class ActionDefinition<
buildMinConstraints(_ctx: ConstraintContext, _args: FireAttackArgs): Constraint[] {
const { gold, rice } = this.command.getCost();
return [
notBeNeutral(),
occupiedCity(),
suppliedCity(),
reqGeneralGold(() => gold),
reqGeneralRice(() => rice),
];
return [notBeNeutral(), occupiedCity(), suppliedCity(), reqGeneralGold(() => gold), reqGeneralRice(() => rice)];
}
buildConstraints(_ctx: ConstraintContext, _args: FireAttackArgs): Constraint[] {
@@ -0,0 +1,12 @@
import type { GeneralTriggerState } from '@sammo-ts/logic/domain/entities.js';
import type { GeneralActionResolveContext } from '@sammo-ts/logic/actions/engine.js';
import type { GeneralActionPipeline } from '@sammo-ts/logic/triggers/general-action.js';
export const consumeSuccessfulStrategyItem = <TriggerState extends GeneralTriggerState>(
pipeline: GeneralActionPipeline<TriggerState>,
context: GeneralActionResolveContext<TriggerState>
): Record<string, unknown> | null =>
pipeline.onArbitraryAction(context, 'GeneralCommand', null, {
command: '계략',
success: true,
});