fix(logic): 전투 특기의 비전투 커맨드 효과를 복구
모병에서도 실제 행동명을 특기 계산에 전달해 징병 특기의 훈련과 사기를 레거시 값으로 맞춘다. 의술의 환자별 기록 소유권과 PLAIN 형식, 다인 치료 요약 대상도 복구하고 전투 특기 비전투 hook 회귀를 추가한다.
This commit is contained in:
@@ -39,7 +39,7 @@ export interface RecruitEnvironment {
|
||||
defaultAtmos?: number;
|
||||
minAvailableRecruitPop?: number;
|
||||
defaultTrust?: number;
|
||||
actionName?: string;
|
||||
actionName?: '징병' | '모병';
|
||||
}
|
||||
|
||||
export interface RecruitResolveContext<
|
||||
@@ -229,6 +229,10 @@ export class CommandResolver<TriggerState extends GeneralTriggerState = GeneralT
|
||||
this.env = env;
|
||||
}
|
||||
|
||||
private get actionName(): '징병' | '모병' {
|
||||
return this.env.actionName ?? ACTION_NAME;
|
||||
}
|
||||
|
||||
resolveLeadership(context: RecruitCalcContext<TriggerState>): number {
|
||||
const general = context.general;
|
||||
const base = applyLegacyInjury(general.stats.leadership, general.injury);
|
||||
@@ -245,10 +249,10 @@ export class CommandResolver<TriggerState extends GeneralTriggerState = GeneralT
|
||||
): { gold: number; rice: number } {
|
||||
const techCost = getTechCost(readNationTech(context.nation ?? null));
|
||||
return {
|
||||
gold: this.pipeline.onCalcDomestic(context, ACTION_NAME, 'cost', crewType.cost * techCost, {
|
||||
gold: this.pipeline.onCalcDomestic(context, this.actionName, 'cost', crewType.cost * techCost, {
|
||||
armType: crewType.armType,
|
||||
}),
|
||||
rice: this.pipeline.onCalcDomestic(context, ACTION_NAME, 'rice', crewType.rice * techCost, {
|
||||
rice: this.pipeline.onCalcDomestic(context, this.actionName, 'rice', crewType.rice * techCost, {
|
||||
armType: crewType.armType,
|
||||
}),
|
||||
};
|
||||
@@ -281,7 +285,7 @@ export class CommandResolver<TriggerState extends GeneralTriggerState = GeneralT
|
||||
const baseGold = crewType ? (crewType.cost * getTechCost(tech) * plan.applied) / 100 : 0;
|
||||
const adjustedGold = this.pipeline.onCalcDomestic(
|
||||
context,
|
||||
ACTION_NAME,
|
||||
this.actionName,
|
||||
'cost',
|
||||
baseGold,
|
||||
crewType ? { armType: crewType.armType } : undefined
|
||||
@@ -289,7 +293,7 @@ export class CommandResolver<TriggerState extends GeneralTriggerState = GeneralT
|
||||
const baseRice = plan.applied / 100;
|
||||
const adjustedRice = this.pipeline.onCalcDomestic(
|
||||
context,
|
||||
ACTION_NAME,
|
||||
this.actionName,
|
||||
'rice',
|
||||
baseRice,
|
||||
crewType ? { armType: crewType.armType } : undefined
|
||||
@@ -306,7 +310,7 @@ export class CommandResolver<TriggerState extends GeneralTriggerState = GeneralT
|
||||
const base = this.env.defaultTrain ?? DEFAULT_TRAIN;
|
||||
return this.pipeline.onCalcDomestic(
|
||||
context,
|
||||
ACTION_NAME,
|
||||
this.actionName,
|
||||
'train',
|
||||
base,
|
||||
crewType ? { armType: crewType.armType } : undefined
|
||||
@@ -317,7 +321,7 @@ export class CommandResolver<TriggerState extends GeneralTriggerState = GeneralT
|
||||
const base = this.env.defaultAtmos ?? DEFAULT_ATMOS;
|
||||
return this.pipeline.onCalcDomestic(
|
||||
context,
|
||||
ACTION_NAME,
|
||||
this.actionName,
|
||||
'atmos',
|
||||
base,
|
||||
crewType ? { armType: crewType.armType } : undefined
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { General, GeneralTriggerState, Nation } from '@sammo-ts/logic/domain/entities.js';
|
||||
import type { RandomGenerator } from '@sammo-ts/common';
|
||||
import type { WorldStateRepository } from '@sammo-ts/logic/ports/world.js';
|
||||
import type { LogFormat } from '@sammo-ts/logic/logging/types.js';
|
||||
import { TriggerCaller, type Trigger } from './core.js';
|
||||
|
||||
export interface GeneralWorldView<TriggerState extends GeneralTriggerState = GeneralTriggerState> {
|
||||
@@ -10,7 +11,8 @@ export interface GeneralWorldView<TriggerState extends GeneralTriggerState = Gen
|
||||
}
|
||||
|
||||
export interface GeneralActionLogSink {
|
||||
push(message: string): void;
|
||||
push(message: string, options?: { format?: LogFormat }): void;
|
||||
pushForGeneral?(generalId: number, message: string, options?: { format?: LogFormat }): void;
|
||||
}
|
||||
|
||||
export interface GeneralSkillActivation {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { JosaUtil } from '@sammo-ts/common';
|
||||
|
||||
import type { General, GeneralTriggerState } from '@sammo-ts/logic/domain/entities.js';
|
||||
import { LogFormat } from '@sammo-ts/logic/logging/types.js';
|
||||
import { TriggerPriority } from '@sammo-ts/logic/triggers/core.js';
|
||||
import { BaseGeneralTrigger, type GeneralTriggerContext } from '@sammo-ts/logic/triggers/general.js';
|
||||
|
||||
@@ -47,7 +48,7 @@ export class CheUisulCityHealTrigger<
|
||||
if (general.injury > 0) {
|
||||
general.injury = 0;
|
||||
context.skill.activate('pre.부상경감', 'pre.치료');
|
||||
logger?.push('<C>의술</>을 펼쳐 스스로 치료합니다!');
|
||||
logger?.push('<C>의술</>을 펼쳐 스스로 치료합니다!', { format: LogFormat.PLAIN });
|
||||
}
|
||||
|
||||
const candidates = resolveCityGenerals(general, context).filter((candidate) => {
|
||||
@@ -64,19 +65,32 @@ export class CheUisulCityHealTrigger<
|
||||
|
||||
for (const patient of healed) {
|
||||
patient.injury = 0;
|
||||
const generalName = general.name;
|
||||
logger?.pushForGeneral?.(
|
||||
patient.id,
|
||||
`<Y>${generalName}</>${JosaUtil.pick(generalName, '이')} <C>의술</>로써 치료해줍니다!`,
|
||||
{ format: LogFormat.PLAIN }
|
||||
);
|
||||
}
|
||||
|
||||
if (healed.length === 0) {
|
||||
return env;
|
||||
}
|
||||
|
||||
const firstName = healed[0]?.name ?? '장수';
|
||||
// Ref overwrites `$curedPatientName` for each successful patient and
|
||||
// therefore names the last general in the ordered draw list.
|
||||
const curedPatientName = healed.at(-1)?.name ?? '장수';
|
||||
if (healed.length === 1) {
|
||||
const josa = JosaUtil.pick(firstName, '을');
|
||||
logger?.push(`<C>의술</>을 펼쳐 도시의 장수 <Y>${firstName}</>${josa} 치료합니다!`);
|
||||
const josa = JosaUtil.pick(curedPatientName, '을');
|
||||
logger?.push(`<C>의술</>을 펼쳐 도시의 장수 <Y>${curedPatientName}</>${josa} 치료합니다!`, {
|
||||
format: LogFormat.PLAIN,
|
||||
});
|
||||
} else {
|
||||
const otherCount = healed.length - 1;
|
||||
logger?.push(`<C>의술</>을 펼쳐 도시의 장수들 <Y>${firstName}</> 외 <C>${otherCount}</>명을 치료합니다!`);
|
||||
logger?.push(
|
||||
`<C>의술</>을 펼쳐 도시의 장수들 <Y>${curedPatientName}</> 외 <C>${otherCount}</>명을 치료합니다!`,
|
||||
{ format: LogFormat.PLAIN }
|
||||
);
|
||||
}
|
||||
|
||||
return env;
|
||||
|
||||
Reference in New Issue
Block a user