fix(turn): preserve zero-balance seizure flow
This commit is contained in:
@@ -141,20 +141,8 @@ export class ActionDefinition<
|
|||||||
|
|
||||||
const actualAmount = clamp(args.amount, 0, destGeneral[resKey] ?? 0);
|
const actualAmount = clamp(args.amount, 0, destGeneral[resKey] ?? 0);
|
||||||
|
|
||||||
if (actualAmount <= 0) {
|
|
||||||
return {
|
|
||||||
effects: [
|
|
||||||
createLogEffect(`${destGeneral.name}에게서 몰수할 ${resName}이 없습니다.`, {
|
|
||||||
scope: LogScope.GENERAL,
|
|
||||||
category: LogCategory.ACTION,
|
|
||||||
format: LogFormat.MONTH,
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const amountText = actualAmount.toLocaleString();
|
const amountText = actualAmount.toLocaleString();
|
||||||
const josaUl = JosaUtil.pick(amountText, '을');
|
const josaUl = actualAmount === 0 ? '를' : JosaUtil.pick(amountText, '을');
|
||||||
const destGeneralName = destGeneral.name;
|
const destGeneralName = destGeneral.name;
|
||||||
|
|
||||||
const effects: Array<GeneralActionEffect<TriggerState>> = [
|
const effects: Array<GeneralActionEffect<TriggerState>> = [
|
||||||
|
|||||||
@@ -673,3 +673,81 @@ integration('nation seizure NPC public message parity', () => {
|
|||||||
});
|
});
|
||||||
}, 120_000);
|
}, 120_000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
integration('nation seizure zero target balance parity', () => {
|
||||||
|
it('matches the legacy zero-amount logs for a user target', async () => {
|
||||||
|
const request = buildRequest(
|
||||||
|
'che_몰수',
|
||||||
|
{ isGold: true, amount: 100, destGeneralID: 3 },
|
||||||
|
{ generals: { 3: { name: '무자원장수', gold: 0, npcState: 0 } } }
|
||||||
|
);
|
||||||
|
const reference = runReferenceTurnCommandTraceRequest(
|
||||||
|
workspaceRoot!,
|
||||||
|
request as unknown as Record<string, unknown>
|
||||||
|
);
|
||||||
|
const core = await runCoreTurnCommandTrace(request, reference.before);
|
||||||
|
const referenceLogs = reference.after.logs.slice(reference.before.logs.length);
|
||||||
|
|
||||||
|
expect(reference.execution.outcome).toMatchObject({ completed: true });
|
||||||
|
expect(core.execution.outcome).toMatchObject({
|
||||||
|
requestedAction: 'che_몰수',
|
||||||
|
actionKey: 'che_몰수',
|
||||||
|
usedFallback: false,
|
||||||
|
});
|
||||||
|
expect(reference.rng).toEqual([]);
|
||||||
|
expect(core.rng).toEqual(reference.rng);
|
||||||
|
expect(referenceLogs.map((entry) => entry.text)).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.stringContaining('금 0를 몰수 당했습니다.'),
|
||||||
|
expect.stringContaining('금 <C>0</>를 몰수했습니다.'),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
expect(core.after.logs.map((entry) => entry.text)).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.stringContaining('금 0를 몰수 당했습니다.'),
|
||||||
|
expect.stringContaining('금 <C>0</>를 몰수했습니다.'),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
compareTurnSnapshotDeltas(reference.before, reference.after, core.before, core.after, {
|
||||||
|
ignoredPathPatterns: ignoredLifecyclePaths,
|
||||||
|
})
|
||||||
|
).toEqual([]);
|
||||||
|
}, 120_000);
|
||||||
|
|
||||||
|
it('preserves NPC message RNG and side effects before applying a zero delta', async () => {
|
||||||
|
const request = buildRequest(
|
||||||
|
'che_몰수',
|
||||||
|
{ isGold: true, amount: 100, destGeneralID: 3 },
|
||||||
|
{
|
||||||
|
world: { hiddenSeed: 'seizure-message-37' },
|
||||||
|
generals: { 3: { name: '무자원NPC', gold: 0, npcState: 2 } },
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const reference = runReferenceTurnCommandTraceRequest(
|
||||||
|
workspaceRoot!,
|
||||||
|
request as unknown as Record<string, unknown>
|
||||||
|
);
|
||||||
|
const core = await runCoreTurnCommandTrace(request, reference.before);
|
||||||
|
const referenceMessages = reference.after.messages.slice(reference.before.messages.length);
|
||||||
|
|
||||||
|
expect(reference.execution.outcome).toMatchObject({ completed: true });
|
||||||
|
expect(reference.rng.map((call) => call.operation)).toEqual(['nextFloat1', 'nextInt']);
|
||||||
|
expect(core.rng).toEqual(reference.rng);
|
||||||
|
expect(referenceMessages).toHaveLength(1);
|
||||||
|
expect(core.after.messages).toHaveLength(1);
|
||||||
|
expect(referenceMessages[0]).toMatchObject({
|
||||||
|
type: 'public',
|
||||||
|
sourceId: 3,
|
||||||
|
payload: { text: NPC_SEIZURE_MESSAGE_TEXT },
|
||||||
|
});
|
||||||
|
expect(core.after.messages[0]).toMatchObject({
|
||||||
|
payload: { msgType: 'public', text: NPC_SEIZURE_MESSAGE_TEXT },
|
||||||
|
});
|
||||||
|
expect(
|
||||||
|
compareTurnSnapshotDeltas(reference.before, reference.after, core.before, core.after, {
|
||||||
|
ignoredPathPatterns: ignoredLifecyclePaths,
|
||||||
|
})
|
||||||
|
).toEqual([]);
|
||||||
|
}, 120_000);
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user