fix general status transition parity
This commit is contained in:
@@ -106,6 +106,7 @@ export type GeneralActionEffect<TriggerState extends GeneralTriggerState = Gener
|
||||
export interface GeneralActionOutcome<TriggerState extends GeneralTriggerState = GeneralTriggerState> {
|
||||
effects: GeneralActionEffect<TriggerState>[];
|
||||
completed?: boolean;
|
||||
deletedTroopIds?: number[];
|
||||
alternative?: {
|
||||
commandKey: string;
|
||||
args: unknown;
|
||||
@@ -146,6 +147,7 @@ export interface GeneralActionResolution {
|
||||
commandKey: string;
|
||||
args: unknown;
|
||||
};
|
||||
deletedTroopIds?: number[];
|
||||
}
|
||||
|
||||
export const createGeneralPatchEffect = <TriggerState extends GeneralTriggerState = GeneralTriggerState>(
|
||||
@@ -388,6 +390,7 @@ export const resolveGeneralAction = <TriggerState extends GeneralTriggerState =
|
||||
logs,
|
||||
effects: pendingEffects,
|
||||
...(outcome?.alternative ? { alternative: outcome.alternative } : {}),
|
||||
...(outcome?.deletedTroopIds?.length ? { deletedTroopIds: outcome.deletedTroopIds } : {}),
|
||||
};
|
||||
if (nextWorld.city) {
|
||||
resolution.city = nextWorld.city as City;
|
||||
|
||||
@@ -7,7 +7,11 @@ import type {
|
||||
GeneralActionOutcome,
|
||||
GeneralActionResolveContext,
|
||||
} from '@sammo-ts/logic/actions/engine.js';
|
||||
import { createGeneralPatchEffect, createLogEffect } from '@sammo-ts/logic/actions/engine.js';
|
||||
import {
|
||||
createGeneralPatchEffect,
|
||||
createLogEffect,
|
||||
createNationPatchEffect,
|
||||
} from '@sammo-ts/logic/actions/engine.js';
|
||||
import { LogCategory, LogFormat, LogScope } from '@sammo-ts/logic/logging/types.js';
|
||||
import { JosaUtil } from '@sammo-ts/common';
|
||||
import { z } from 'zod';
|
||||
@@ -49,6 +53,15 @@ export class ActionDefinition<
|
||||
}
|
||||
|
||||
buildConstraints(_ctx: ConstraintContext, _args: AbdicationArgs): Constraint[] {
|
||||
if (_ctx.actorId === _args.destGeneralID) {
|
||||
return [
|
||||
{
|
||||
name: 'differentDestGeneral',
|
||||
requires: () => [],
|
||||
test: () => ({ kind: 'deny', reason: '본인입니다' }),
|
||||
},
|
||||
];
|
||||
}
|
||||
return [beLord(), existsDestGeneral(), friendlyDestGeneral()];
|
||||
}
|
||||
|
||||
@@ -66,7 +79,8 @@ export class ActionDefinition<
|
||||
throw new Error('선양 대상 장수가 없습니다.');
|
||||
}
|
||||
|
||||
const penaltyRaw = destGeneral.meta.penalty;
|
||||
const penaltyRaw =
|
||||
(destGeneral as General<TriggerState> & { penalty?: unknown }).penalty ?? destGeneral.meta.penalty;
|
||||
if (penaltyRaw && typeof penaltyRaw === 'object' && !Array.isArray(penaltyRaw)) {
|
||||
const penaltyMap = penaltyRaw as Record<string, unknown>;
|
||||
for (const penaltyKey of blockedPenaltyKeys) {
|
||||
@@ -79,6 +93,7 @@ export class ActionDefinition<
|
||||
format: LogFormat.MONTH,
|
||||
}),
|
||||
],
|
||||
completed: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -135,7 +150,7 @@ export class ActionDefinition<
|
||||
createGeneralPatchEffect(
|
||||
{
|
||||
officerLevel: 1,
|
||||
experience: Math.floor(general.experience * 0.7),
|
||||
experience: Math.round(general.experience * 0.7),
|
||||
meta: {
|
||||
...general.meta,
|
||||
officer_city: 0,
|
||||
@@ -143,7 +158,8 @@ export class ActionDefinition<
|
||||
},
|
||||
},
|
||||
general.id
|
||||
)
|
||||
),
|
||||
createNationPatchEffect({ chiefGeneralId: destGeneral.id }, nation.id)
|
||||
);
|
||||
|
||||
return { effects };
|
||||
|
||||
@@ -48,8 +48,10 @@ export class ActionResolver<
|
||||
const value = typeof nextMeta[key] === 'number' ? nextMeta[key] : 0;
|
||||
nextMeta[key] = Math.round(value * 0.5);
|
||||
}
|
||||
nextMeta.specAge = 0;
|
||||
nextMeta.specAge2 = 0;
|
||||
delete nextMeta.specAge;
|
||||
delete nextMeta.specAge2;
|
||||
nextMeta.specage = 0;
|
||||
nextMeta.specage2 = 0;
|
||||
for (const type of LEGACY_RANK_DATA_TYPES) {
|
||||
nextMeta[rankDataMetaKey(type)] = 0;
|
||||
}
|
||||
@@ -57,7 +59,7 @@ export class ActionResolver<
|
||||
const josaYi = JosaUtil.pick(general.name, '이');
|
||||
context.addLog(`<Y>${general.name}</>${josaYi} <R>은퇴</>하고 그 자손이 유지를 이어받았습니다.`, {
|
||||
scope: LogScope.SYSTEM,
|
||||
category: LogCategory.ACTION,
|
||||
category: LogCategory.SUMMARY,
|
||||
format: LogFormat.RAWTEXT,
|
||||
});
|
||||
context.addLog('나이가 들어 <R>은퇴</>하고 자손에게 자리를 물려줍니다.', {
|
||||
|
||||
@@ -66,8 +66,8 @@ export class ActionResolver<
|
||||
// Penalty
|
||||
const betrayal = typeof general.meta.betray === 'number' ? general.meta.betray : 0;
|
||||
const penaltyRatio = betrayal * 0.1;
|
||||
const nextExp = Math.floor(general.experience * (1 - penaltyRatio));
|
||||
const nextDed = Math.floor(general.dedication * (1 - penaltyRatio));
|
||||
const nextExp = Math.round(general.experience * (1 - penaltyRatio));
|
||||
const nextDed = Math.round(general.dedication * (1 - penaltyRatio));
|
||||
|
||||
context.addLog(`<D><b>${nation.name}</b></>에서 하야했습니다.`, {
|
||||
category: LogCategory.ACTION,
|
||||
@@ -80,7 +80,7 @@ export class ActionResolver<
|
||||
const josaYi = JosaUtil.pick(general.name, '이');
|
||||
context.addLog(`<Y>${general.name}</>${josaYi} <D><b>${nation.name}</b></>에서 <R>하야</>했습니다.`, {
|
||||
scope: LogScope.SYSTEM,
|
||||
category: LogCategory.ACTION,
|
||||
category: LogCategory.SUMMARY,
|
||||
format: LogFormat.RAWTEXT,
|
||||
});
|
||||
|
||||
@@ -125,7 +125,10 @@ export class ActionResolver<
|
||||
)
|
||||
);
|
||||
|
||||
return { effects };
|
||||
return {
|
||||
effects,
|
||||
...(general.troopId === general.id ? { deletedTroopIds: [general.id] } : {}),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -223,6 +223,7 @@ describe('migrated general commands', () => {
|
||||
expect(updatedHeir.officerLevel).toBe(12);
|
||||
expect(updatedLord.officerLevel).toBe(1);
|
||||
expect(updatedLord.experience).toBe(700);
|
||||
expect(world.getNation(1)!.chiefGeneralId).toBe(heir.id);
|
||||
});
|
||||
|
||||
it('che_증여: 금은 레거시 최소 보유량 0을 적용해 요청한 금액을 이전한다', async () => {
|
||||
|
||||
Reference in New Issue
Block a user