fix: 장수 런타임 레벨 상한을 Ref 기준으로 복구

가입 능력치 배분 상한과 런타임 레벨 상한을 분리하고, Ref 기본값 255를 공유 상수로 통합한다. 모병 후 레벨 유지와 국가 장수 목록의 고레벨 표시를 회귀 테스트로 고정한다.
This commit is contained in:
2026-08-21 08:37:38 +00:00
parent bba0d3b5c0
commit deb01f7f2b
21 changed files with 124 additions and 49 deletions
@@ -1,5 +1,6 @@
import type { General } from '@sammo-ts/logic/domain/entities.js';
import type { ScenarioConfig } from '@sammo-ts/logic/scenario/types.js';
import { LEGACY_DEFAULT_MAX_LEVEL } from '@sammo-ts/logic/scenario/constants.js';
import type { ScenarioMeta } from '@sammo-ts/logic/world/types.js';
import type { WarAftermathConfig, WarEngineConfig, WarTimeContext } from '@sammo-ts/logic/war/types.js';
import type { UnitSetDefinition } from '@sammo-ts/logic/world/types.js';
@@ -208,7 +209,7 @@ export const buildWarConfig = (scenarioConfig: ScenarioConfig, unitSet: UnitSetD
maxAtmosByCommand: resolveNumber(constValues, ['maxAtmosByCommand'], DEFAULT_WAR_CONFIG.maxAtmosByCommand),
maxTrainByWar: resolveNumber(constValues, ['maxTrainByWar'], DEFAULT_WAR_CONFIG.maxTrainByWar),
maxAtmosByWar: resolveNumber(constValues, ['maxAtmosByWar'], DEFAULT_WAR_CONFIG.maxAtmosByWar),
maxGeneralStat: resolveNumber(constValues, ['maxLevel'], 255),
maxGeneralStat: resolveNumber(constValues, ['maxLevel'], LEGACY_DEFAULT_MAX_LEVEL),
statUpgradeLimit: resolveNumber(constValues, ['upgradeLimit'], 30),
castleCrewTypeId,
armTypes: {
@@ -26,6 +26,7 @@ import type { TurnCommandEnv } from '@sammo-ts/logic/actions/turn/commandEnv.js'
import type { ActionContextBuilder } from '@sammo-ts/logic/actions/turn/actionContext.js';
import type { GeneralTurnCommandSpec } from './index.js';
import { parseArgsWithSchema } from '../parseArgs.js';
import { LEGACY_DEFAULT_MAX_LEVEL } from '@sammo-ts/logic/scenario/constants.js';
const ACTION_NAME = '등용수락';
const ACTION_KEY = 'che_등용수락';
@@ -103,7 +104,7 @@ export class ActionResolver<
const recruiterExpLevel = Math.max(
0,
Math.min(
this.env.maxStatLevel ?? 255,
this.env.maxStatLevel ?? LEGACY_DEFAULT_MAX_LEVEL,
recruiterExperience < 1_000
? Math.trunc(recruiterExperience / 100)
: Math.trunc(Math.sqrt(recruiterExperience / 10))
@@ -13,6 +13,7 @@ import { LogCategory, LogFormat } from '@sammo-ts/logic/logging/types.js';
import type { TurnCommandEnv } from '@sammo-ts/logic/actions/turn/commandEnv.js';
import type { ActionContextBuilder } from '@sammo-ts/logic/actions/turn/actionContext.js';
import { tryApplyUniqueLottery } from '@sammo-ts/logic/rewards/uniqueLottery.js';
import { LEGACY_DEFAULT_MAX_LEVEL } from '@sammo-ts/logic/scenario/constants.js';
import type { GeneralTurnCommandSpec } from './index.js';
export interface ProcureArgs {}
@@ -32,7 +33,10 @@ export const roundLegacyAccumulatedInteger = (current: number, delta: number): n
export const resolveLegacyExperienceLevel = (experience: number): number =>
Math.max(
0,
Math.min(255, experience < 1_000 ? Math.trunc(experience / 100) : Math.trunc(Math.sqrt(experience / 10)))
Math.min(
LEGACY_DEFAULT_MAX_LEVEL,
experience < 1_000 ? Math.trunc(experience / 100) : Math.trunc(Math.sqrt(experience / 10))
)
);
export const resolveLegacyDedicationLevel = (dedication: number): number =>
Math.max(0, Math.min(30, Math.ceil(Math.sqrt(dedication) / 10)));
@@ -65,7 +69,7 @@ export class ActionResolver<
const rawLeadership = general.stats.leadership * injuryMultiplier;
const rawStrength = general.stats.strength * injuryMultiplier;
const rawIntelligence = general.stats.intelligence * injuryMultiplier;
const maxStat = 255;
const maxStat = LEGACY_DEFAULT_MAX_LEVEL;
const legacyStat = (stat: 'leadership' | 'strength' | 'intelligence', value: number): number =>
Math.trunc(Math.max(0, Math.min(maxStat, this.pipeline.onCalcStat(context, stat, value))));
let score =
@@ -27,6 +27,7 @@ import type {
ActionResolveContext,
} from '@sammo-ts/logic/actions/turn/actionContext.js';
import { tryApplyUniqueLottery } from '@sammo-ts/logic/rewards/uniqueLottery.js';
import { LEGACY_DEFAULT_MAX_LEVEL } from '@sammo-ts/logic/scenario/constants.js';
import type { GeneralTurnCommandSpec } from './index.js';
import { clamp } from 'es-toolkit';
@@ -203,7 +204,7 @@ export class CommandResolver<TriggerState extends GeneralTriggerState = GeneralT
} else if (this.config.statKey === 'intelligence') {
rawStats.intelligence += Math.round(rawStats.strength / 4);
}
const maxStatLevel = this.env.maxStatLevel ?? 255;
const maxStatLevel = this.env.maxStatLevel ?? LEGACY_DEFAULT_MAX_LEVEL;
let score = clamp(rawStats[this.config.statKey], 0, maxStatLevel);
score = this.pipeline.onCalcStat(context, this.config.statKey, score);
@@ -234,7 +235,7 @@ export class CommandResolver<TriggerState extends GeneralTriggerState = GeneralT
strength: context.general.stats.strength + Math.round(context.general.stats.intelligence / 4),
intelligence: context.general.stats.intelligence + Math.round(context.general.stats.strength / 4),
};
const maxStatLevel = this.env.maxStatLevel ?? 255;
const maxStatLevel = this.env.maxStatLevel ?? LEGACY_DEFAULT_MAX_LEVEL;
const leadership = this.pipeline.onCalcStat(
context,
'leadership',