fix nation symbol legacy boundaries

This commit is contained in:
2026-07-26 13:39:05 +00:00
parent 6d642bb759
commit 935f6ebe97
8 changed files with 399 additions and 17 deletions
@@ -3,6 +3,7 @@ import type { UniqueLotteryRunner } from '@sammo-ts/logic/rewards/uniqueLottery.
import type { ScenarioConfig } from '@sammo-ts/logic/scenario/types.js';
import type { ScenarioMeta } from '@sammo-ts/logic/world/types.js';
import type { MapDefinition, UnitSetDefinition } from '@sammo-ts/logic/world/types.js';
import type { GeneralWorldView } from '@sammo-ts/logic/triggers/general.js';
export interface ActionRandomSource {
nextFloat1(): number;
@@ -18,6 +19,7 @@ export type ActionContextBase = {
general: ActionContextGeneral;
city?: City;
nation?: Nation | null;
worldView?: GeneralWorldView;
rng: ActionRandomSource;
uniqueLottery?: UniqueLotteryRunner;
};
@@ -53,12 +53,28 @@ const NATION_COLORS = [
'#A9A9A9',
];
const resolveNationColorIndex = (value: number | string | boolean): number | null => {
let index: number;
if (typeof value === 'boolean') {
index = value ? 1 : 0;
} else if (typeof value === 'number') {
if (!Number.isFinite(value)) {
return null;
}
index = Math.trunc(value);
} else {
if (!/^(?:0|[1-9]\d*|-[1-9]\d*)$/.test(value)) {
return null;
}
index = Number(value);
}
return Number.isSafeInteger(index) && index >= 0 && index < NATION_COLORS.length ? index : null;
};
const ARGS_SCHEMA = z.object({
colorType: z
.number()
.int()
.min(0)
.max(NATION_COLORS.length - 1),
.union([z.number(), z.string(), z.boolean()])
.refine((value) => resolveNationColorIndex(value) !== null),
});
export type ChangeFlagArgs = z.infer<typeof ARGS_SCHEMA>;
@@ -100,7 +116,11 @@ export class ActionDefinition<
return { effects: [createLogEffect('국가 정보가 없습니다.', { scope: LogScope.GENERAL })] };
}
const color = NATION_COLORS[args.colorType];
const colorIndex = resolveNationColorIndex(args.colorType);
if (colorIndex === null) {
return { effects: [] };
}
const color = NATION_COLORS[colorIndex];
const generalName = general.name;
const nationName = nation.name;
@@ -120,11 +140,11 @@ export class ActionDefinition<
),
// Global Action Log
createLogEffect(
`<Y>${generalName}</>${josaYi} <span style='color:${color};'><b>국기</b></span>를 변경하였습니다.`,
`<Y>${generalName}</>${josaYi} <span style='color:${color};'><b>국기</b></span>를 변경하였습니다`,
{
scope: LogScope.SYSTEM,
category: LogCategory.ACTION,
format: LogFormat.PLAIN,
category: LogCategory.SUMMARY,
format: LogFormat.MONTH,
}
),
// Global History Log
@@ -138,7 +158,7 @@ export class ActionDefinition<
),
// Actor Nation History Log
createLogEffect(
`<Y>${generalName}</>${josaYi} <span style='color:${color};'><b>국기</b></span>를 변경하였습니다.`,
`<Y>${generalName}</>${josaYi} <span style='color:${color};'><b>국기</b></span>를 변경하였습니다`,
{
scope: LogScope.NATION,
nationId: nation.id,
@@ -14,9 +14,17 @@ import type { TurnCommandEnv } from '@sammo-ts/logic/actions/turn/commandEnv.js'
import type { NationTurnCommandSpec } from './index.js';
import { z } from 'zod';
import { parseArgsWithSchema } from '../parseArgs.js';
import { getLegacyStringWidth } from '@sammo-ts/logic/troop/management.js';
const ARGS_SCHEMA = z.object({
nationName: z.string().trim().min(1).max(8),
nationName: z.string().superRefine((nationName, ctx) => {
if (nationName === '' || getLegacyStringWidth(nationName) > 18) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: '국호는 전각 9자 또는 반각 18자 이하여야 합니다.',
});
}
}),
});
export type ChangeNationNameArgs = z.infer<typeof ARGS_SCHEMA>;
@@ -65,8 +73,21 @@ export class ActionDefinition<
const oldNationName = nation.name;
const newNationName = args.nationName;
if (context.worldView?.listNations?.().some((candidate) => candidate.name === newNationName)) {
return {
completed: false,
effects: [
createLogEffect(`이미 같은 국호를 가진 곳이 있습니다. ${ACTION_NAME} 실패`, {
scope: LogScope.GENERAL,
category: LogCategory.ACTION,
format: LogFormat.MONTH,
}),
],
};
}
const josaYi = JosaUtil.pick(generalName, '이');
const josaYiNation = JosaUtil.pick(newNationName, '이');
const josaYiNation = JosaUtil.pick(oldNationName, '이');
const josaRo = JosaUtil.pick(newNationName, '로');
const effects: Array<GeneralActionEffect<TriggerState>> = [
@@ -83,8 +104,8 @@ export class ActionDefinition<
// Global Action Log
createLogEffect(`<Y>${generalName}</>${josaYi} 국호를 <D><b>${newNationName}</b></>${josaRo} 변경합니다.`, {
scope: LogScope.SYSTEM,
category: LogCategory.ACTION,
format: LogFormat.PLAIN,
category: LogCategory.SUMMARY,
format: LogFormat.MONTH,
}),
// Global History Log
createLogEffect(
+1
View File
@@ -6,6 +6,7 @@ import { TriggerCaller, type Trigger } from './core.js';
export interface GeneralWorldView<TriggerState extends GeneralTriggerState = GeneralTriggerState> {
listGenerals(): General<TriggerState>[];
listGeneralsByCity?(cityId: number): General<TriggerState>[];
listNations?(): Nation[];
}
export interface GeneralActionLogSink {