feat: Implement general and nation turn commands with command specifications

- Added command specifications for various general turn commands including talent scouting, appointments, and military actions.
- Introduced command specifications for nation turn commands such as assignments and declarations of war.
- Created a command environment interface to encapsulate command-related parameters.
- Developed a command profile loader to manage default and custom command profiles.
- Established a reserved turn action context to facilitate command execution with necessary context data.
- Updated the default command profile JSON to include new commands and their configurations.
This commit is contained in:
2026-01-01 15:17:30 +00:00
parent 49942cea5e
commit bfbcb4472e
36 changed files with 1089 additions and 750 deletions
@@ -28,6 +28,8 @@ import type {
import { createGeneralPatchEffect, createLogEffect } from '../../engine.js';
import { LogCategory, LogFormat, LogScope } from '../../../logging/types.js';
import { JosaUtil } from '@sammo-ts/common';
import type { TurnCommandEnv } from '../commandEnv.js';
import type { NationTurnCommandSpec } from './index.js';
export interface AssignmentArgs {
destGeneralId: number;
@@ -206,3 +208,11 @@ export class ActionDefinition<
return this.resolver.resolve(context, args);
}
}
export const commandSpec: NationTurnCommandSpec = {
key: 'che_발령',
category: '인사',
reqArg: true,
args: { destGeneralId: 0, destCityId: 0 },
createDefinition: (_env: TurnCommandEnv) => new ActionDefinition({}),
};
@@ -14,6 +14,8 @@ import type {
} from '../../engine.js';
import { createLogEffect } from '../../engine.js';
import { LogCategory, LogFormat, LogScope } from '../../../logging/types.js';
import type { TurnCommandEnv } from '../commandEnv.js';
import type { NationTurnCommandSpec } from './index.js';
export interface DeclareWarArgs {
destNationId: number;
@@ -72,3 +74,11 @@ export class ActionDefinition<
};
}
}
export const commandSpec: NationTurnCommandSpec = {
key: 'che_선전포고',
category: '외교',
reqArg: true,
args: { destNationId: 0 },
createDefinition: (_env: TurnCommandEnv) => new ActionDefinition(),
};
@@ -32,6 +32,8 @@ import {
createNationPatchEffect,
} from '../../engine.js';
import { LogCategory, LogFormat, LogScope } from '../../../logging/types.js';
import type { TurnCommandEnv } from '../commandEnv.js';
import type { NationTurnCommandSpec } from './index.js';
import { JosaUtil } from '@sammo-ts/common';
export interface AwardArgs {
@@ -266,3 +268,21 @@ export class ActionDefinition<
return this.resolver.resolve(context, args);
}
}
export const commandSpec: NationTurnCommandSpec = {
key: 'che_포상',
category: '인사',
reqArg: true,
args: { isGold: true, amount: 1, destGeneralId: 0 },
createDefinition: (env: TurnCommandEnv) => {
const maxAmount =
env.maxResourceActionAmount > 0
? env.maxResourceActionAmount
: Math.max(env.baseGold, env.baseRice, 1000);
return new ActionDefinition({
baseGold: env.baseGold,
baseRice: env.baseRice,
maxAmount,
});
},
};
@@ -1,13 +1,35 @@
import type { GeneralActionDefinition } from '../../definition.js';
import type { TurnCommandEnv } from '../commandEnv.js';
import type * as NationRestModule from './휴식.js';
import type * as AwardModule from './che_포상.js';
import type * as AssignmentModule from './che_발령.js';
import type * as DeclarationModule from './che_선전포고.js';
export type NationTurnCommandKey =
| '휴식'
| 'che_포상'
| 'che_발령'
| 'che_선전포고';
import type * as NationRestModule from './휴식.js';
import type * as AwardModule from './che_포상.js';
import type * as AssignmentModule from './che_발령.js';
import type * as DeclarationModule from './che_선전포고.js';
export const NATION_TURN_COMMAND_KEYS: NationTurnCommandKey[] = [
'휴식',
'che_포상',
'che_발령',
'che_선전포고',
];
export const isNationTurnCommandKey = (
value: string
): value is NationTurnCommandKey =>
(NATION_TURN_COMMAND_KEYS as string[]).includes(value);
export interface NationTurnCommandSpec {
key: NationTurnCommandKey;
category: string;
reqArg: boolean;
args: Record<string, unknown>;
createDefinition(env: TurnCommandEnv): GeneralActionDefinition;
}
export type NationTurnCommandModule =
| typeof NationRestModule
@@ -46,6 +68,26 @@ export class NationTurnCommandLoader {
}
}
export const loadNationTurnCommandSpecs = async (
keys: NationTurnCommandKey[],
loader: NationTurnCommandLoader = new NationTurnCommandLoader()
): Promise<NationTurnCommandSpec[]> => {
const specs: NationTurnCommandSpec[] = [];
const seen = new Set<string>();
for (const key of keys) {
if (seen.has(key)) {
continue;
}
seen.add(key);
const module = await loader.load(key);
if (!('commandSpec' in module)) {
throw new Error(`Missing commandSpec for nation command: ${key}`);
}
specs.push(module.commandSpec);
}
return specs;
};
export {
ActionDefinition as NationRestActionDefinition,
ActionResolver as NationRestActionResolver,
@@ -10,6 +10,8 @@ import type {
GeneralActionOutcome,
GeneralActionResolveContext,
} from '../../engine.js';
import type { TurnCommandEnv } from '../commandEnv.js';
import type { NationTurnCommandSpec } from './index.js';
export interface NationRestArgs {}
@@ -56,3 +58,11 @@ export class ActionDefinition<
return this.resolver.resolve(context, args);
}
}
export const commandSpec: NationTurnCommandSpec = {
key: '휴식',
category: '휴식',
reqArg: false,
args: {},
createDefinition: (_env: TurnCommandEnv) => new ActionDefinition(),
};