feat: 군대 관련 기능 추가 및 명령어 정의 업데이트
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
import type {
|
||||
General,
|
||||
GeneralTriggerState,
|
||||
} from '@sammo-ts/logic/domain/entities.js';
|
||||
import type {
|
||||
Constraint,
|
||||
ConstraintContext,
|
||||
} from '@sammo-ts/logic/constraints/types.js';
|
||||
import {
|
||||
alwaysFail,
|
||||
beChief,
|
||||
existsDestGeneral,
|
||||
friendlyDestGeneral,
|
||||
notBeNeutral,
|
||||
} from '@sammo-ts/logic/constraints/presets.js';
|
||||
import type { GeneralActionDefinition } from '@sammo-ts/logic/actions/definition.js';
|
||||
import type {
|
||||
GeneralActionEffect,
|
||||
GeneralActionOutcome,
|
||||
GeneralActionResolveContext,
|
||||
} from '@sammo-ts/logic/actions/engine.js';
|
||||
import {
|
||||
createGeneralPatchEffect,
|
||||
createLogEffect,
|
||||
} from '@sammo-ts/logic/actions/engine.js';
|
||||
import type { ActionContextBuilder } from '@sammo-ts/logic/actions/turn/actionContext.js';
|
||||
import type { TurnCommandEnv } from '@sammo-ts/logic/actions/turn/commandEnv.js';
|
||||
import type { NationTurnCommandSpec } from './index.js';
|
||||
import { LogCategory, LogFormat, LogScope } from '@sammo-ts/logic/logging/types.js';
|
||||
import { JosaUtil } from '@sammo-ts/common';
|
||||
|
||||
export interface TroopKickArgs {
|
||||
destGeneralId: number;
|
||||
}
|
||||
|
||||
export interface TroopKickResolveContext<
|
||||
TriggerState extends GeneralTriggerState = GeneralTriggerState
|
||||
> extends GeneralActionResolveContext<TriggerState> {
|
||||
destGeneral: General<TriggerState>;
|
||||
}
|
||||
|
||||
const ACTION_NAME = '부대 탈퇴 지시';
|
||||
|
||||
export class ActionDefinition<
|
||||
TriggerState extends GeneralTriggerState = GeneralTriggerState
|
||||
> implements GeneralActionDefinition<
|
||||
TriggerState,
|
||||
TroopKickArgs,
|
||||
TroopKickResolveContext<TriggerState>
|
||||
> {
|
||||
public readonly key = 'che_부대탈퇴지시';
|
||||
public readonly name = ACTION_NAME;
|
||||
|
||||
parseArgs(raw: unknown): TroopKickArgs | null {
|
||||
if (!raw || typeof raw !== 'object') {
|
||||
return null;
|
||||
}
|
||||
const data = raw as { destGeneralId?: unknown };
|
||||
if (typeof data.destGeneralId !== 'number') {
|
||||
return null;
|
||||
}
|
||||
if (data.destGeneralId <= 0) {
|
||||
return null;
|
||||
}
|
||||
return { destGeneralId: data.destGeneralId };
|
||||
}
|
||||
|
||||
buildConstraints(
|
||||
ctx: ConstraintContext,
|
||||
_args: TroopKickArgs
|
||||
): Constraint[] {
|
||||
if (ctx.destGeneralId !== undefined && ctx.destGeneralId === ctx.actorId) {
|
||||
return [alwaysFail('본인입니다')];
|
||||
}
|
||||
return [
|
||||
notBeNeutral(),
|
||||
beChief(),
|
||||
existsDestGeneral(),
|
||||
friendlyDestGeneral(),
|
||||
];
|
||||
}
|
||||
|
||||
resolve(
|
||||
context: TroopKickResolveContext<TriggerState>,
|
||||
_args: TroopKickArgs
|
||||
): GeneralActionOutcome<TriggerState> {
|
||||
const general = context.general;
|
||||
const destGeneral = context.destGeneral;
|
||||
const destGeneralName = destGeneral.name;
|
||||
const josaUn = JosaUtil.pick(destGeneralName, '은');
|
||||
const effects: Array<GeneralActionEffect<TriggerState>> = [];
|
||||
|
||||
if (destGeneral.troopId === 0) {
|
||||
context.addLog(
|
||||
`<Y>${destGeneralName}</>${josaUn} 부대원이 아닙니다.`
|
||||
);
|
||||
return { effects };
|
||||
}
|
||||
|
||||
if (destGeneral.troopId === destGeneral.id) {
|
||||
context.addLog(
|
||||
`<Y>${destGeneralName}</>${josaUn} 부대장입니다.`
|
||||
);
|
||||
return { effects };
|
||||
}
|
||||
|
||||
effects.push(
|
||||
createGeneralPatchEffect(
|
||||
{ troopId: 0 } as Partial<General<TriggerState>>,
|
||||
destGeneral.id
|
||||
)
|
||||
);
|
||||
|
||||
effects.push(
|
||||
createLogEffect(
|
||||
`<Y>${destGeneralName}</>에게 부대 탈퇴를 지시했습니다.`,
|
||||
{
|
||||
scope: LogScope.GENERAL,
|
||||
category: LogCategory.ACTION,
|
||||
format: LogFormat.MONTH,
|
||||
}
|
||||
)
|
||||
);
|
||||
effects.push(
|
||||
createLogEffect(
|
||||
`<Y>${general.name}</>에게 부대 탈퇴를 지시 받았습니다.`,
|
||||
{
|
||||
scope: LogScope.GENERAL,
|
||||
category: LogCategory.ACTION,
|
||||
format: LogFormat.PLAIN,
|
||||
generalId: destGeneral.id,
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
return { effects };
|
||||
}
|
||||
}
|
||||
|
||||
export const actionContextBuilder: ActionContextBuilder = (base, options) => {
|
||||
const destGeneralId = options.actionArgs.destGeneralId;
|
||||
if (typeof destGeneralId !== 'number') {
|
||||
return null;
|
||||
}
|
||||
const destGeneral = options.worldRef?.getGeneralById(destGeneralId);
|
||||
if (!destGeneral) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
...base,
|
||||
destGeneral,
|
||||
};
|
||||
};
|
||||
|
||||
export const commandSpec: NationTurnCommandSpec = {
|
||||
key: 'che_부대탈퇴지시',
|
||||
category: '인사',
|
||||
reqArg: true,
|
||||
args: { destGeneralId: 0 },
|
||||
createDefinition: (_env: TurnCommandEnv) => new ActionDefinition(),
|
||||
};
|
||||
@@ -3,6 +3,7 @@ import type { TurnCommandModule, TurnCommandSpecBase } from '@sammo-ts/logic/act
|
||||
export const NATION_TURN_COMMAND_KEYS = [
|
||||
'휴식',
|
||||
'che_포상',
|
||||
'che_부대탈퇴지시',
|
||||
'che_발령',
|
||||
'che_선전포고',
|
||||
'che_불가침제의',
|
||||
@@ -33,6 +34,7 @@ const defaultImporters: Record<
|
||||
> = {
|
||||
휴식: async () => import('./휴식.js'),
|
||||
che_포상: async () => import('./che_포상.js'),
|
||||
che_부대탈퇴지시: async () => import('./che_부대탈퇴지시.js'),
|
||||
che_발령: async () => import('./che_발령.js'),
|
||||
che_선전포고: async () => import('./che_선전포고.js'),
|
||||
che_불가침제의: async () => import('./che_불가침제의.js'),
|
||||
|
||||
Reference in New Issue
Block a user