Merge branch 'main' into feature/best-general-data-parity
This commit is contained in:
@@ -16,7 +16,7 @@ import { defaultActionContextBuilder } from '@sammo-ts/logic/actions/turn/action
|
||||
import { tryApplyUniqueLottery } from '@sammo-ts/logic/rewards/uniqueLottery.js';
|
||||
import type { GeneralTurnCommandSpec } from './index.js';
|
||||
import { parseArgsWithSchema } from '../parseArgs.js';
|
||||
import { normalizeResourceActionAmount } from './resourceAmount.js';
|
||||
import { normalizeResourceActionAmount } from '../resourceAmount.js';
|
||||
|
||||
export interface TradeEnvironment {
|
||||
exchangeFee?: number;
|
||||
|
||||
@@ -20,7 +20,7 @@ import type { TurnCommandEnv } from '@sammo-ts/logic/actions/turn/commandEnv.js'
|
||||
import { tryApplyUniqueLottery } from '@sammo-ts/logic/rewards/uniqueLottery.js';
|
||||
import type { GeneralTurnCommandSpec } from './index.js';
|
||||
import { parseArgsWithSchema } from '../parseArgs.js';
|
||||
import { normalizeResourceActionAmount } from './resourceAmount.js';
|
||||
import { normalizeResourceActionAmount } from '../resourceAmount.js';
|
||||
|
||||
const ACTION_NAME = '증여';
|
||||
const ACTION_KEY = 'che_증여';
|
||||
|
||||
@@ -21,7 +21,7 @@ import { defaultActionContextBuilder } from '@sammo-ts/logic/actions/turn/action
|
||||
import { tryApplyUniqueLottery } from '@sammo-ts/logic/rewards/uniqueLottery.js';
|
||||
import type { GeneralTurnCommandSpec } from './index.js';
|
||||
import { parseArgsWithSchema } from '../parseArgs.js';
|
||||
import { normalizeResourceActionAmount } from './resourceAmount.js';
|
||||
import { normalizeResourceActionAmount } from '../resourceAmount.js';
|
||||
|
||||
const ACTION_NAME = '헌납';
|
||||
const ACTION_KEY = 'che_헌납';
|
||||
|
||||
@@ -24,13 +24,11 @@ import type { ActionContextBuilder } from '@sammo-ts/logic/actions/turn/actionCo
|
||||
import { clamp } from 'es-toolkit';
|
||||
import { z } from 'zod';
|
||||
import { parseArgsWithSchema } from '../parseArgs.js';
|
||||
import { normalizeResourceActionAmount } from '../resourceAmount.js';
|
||||
|
||||
const ARGS_SCHEMA = z.object({
|
||||
isGold: z.boolean(),
|
||||
amount: z.preprocess(
|
||||
(value) => (typeof value === 'number' ? Math.floor(value / 100) * 100 : value),
|
||||
z.number().int().positive()
|
||||
),
|
||||
amount: z.number(),
|
||||
destGeneralID: z.number(),
|
||||
});
|
||||
export type SeizureArgs = z.infer<typeof ARGS_SCHEMA>;
|
||||
@@ -56,9 +54,13 @@ export class ActionDefinition<
|
||||
if (!data) {
|
||||
return null;
|
||||
}
|
||||
const amount = normalizeResourceActionAmount(data.amount, this.env.maxResourceActionAmount);
|
||||
if (amount === null) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
...data,
|
||||
amount: clamp(data.amount, 100, this.env.maxResourceActionAmount ?? 10000),
|
||||
amount,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -144,10 +144,10 @@ export class ActionResolver<
|
||||
createLogEffect(
|
||||
`<Y>${context.destGeneral.name}</>에게 ${label} <C>${amountText}</>${amountJosa} 수여했습니다.`,
|
||||
{
|
||||
scope: LogScope.GENERAL,
|
||||
category: LogCategory.ACTION,
|
||||
format: LogFormat.MONTH,
|
||||
}
|
||||
scope: LogScope.GENERAL,
|
||||
category: LogCategory.ACTION,
|
||||
format: LogFormat.MONTH,
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
@@ -199,7 +199,7 @@ export class ActionDefinition<
|
||||
requirements.push({ kind: 'destGeneral', id: ctx.destGeneralId });
|
||||
}
|
||||
|
||||
if (ctx.destGeneralId === ctx.actorId) {
|
||||
if (args.destGeneralId === ctx.actorId) {
|
||||
return [denyWithReason('본인입니다')];
|
||||
}
|
||||
|
||||
|
||||
@@ -124,8 +124,11 @@ export const parsePercent = (value: string): number | null => {
|
||||
export type CompareOperator = '>' | '>=' | '==' | '<=' | '<' | '!=' | '===' | '!==';
|
||||
|
||||
export const compareValues = (target: unknown, op: CompareOperator, source: unknown): boolean => {
|
||||
const lhs = target as any;
|
||||
const rhs = source as any;
|
||||
// The cast is type-only: JavaScript still applies its native relational
|
||||
// coercion rules to the original runtime values, matching the legacy
|
||||
// constraint evaluator without opting the whole comparison into `any`.
|
||||
const lhs = target as number;
|
||||
const rhs = source as number;
|
||||
switch (op) {
|
||||
case '<':
|
||||
return lhs < rhs;
|
||||
|
||||
@@ -196,10 +196,7 @@ const resolveUnitReport = (unit: WarUnit): WarUnitReport => {
|
||||
};
|
||||
};
|
||||
|
||||
const buildTraceUnitSnapshot = (
|
||||
unit: WarUnit,
|
||||
defenderCity: City
|
||||
): WarBattleTraceUnitSnapshot => {
|
||||
const buildTraceUnitSnapshot = (unit: WarUnit, defenderCity: City): WarBattleTraceUnitSnapshot => {
|
||||
const common = {
|
||||
kind: unit instanceof WarUnitGeneral ? ('general' as const) : ('city' as const),
|
||||
id: unit instanceof WarUnitGeneral ? unit.getGeneral().id : (unit as WarUnitCity).getCityId(),
|
||||
@@ -339,7 +336,6 @@ export const resolveWarBattle = <TriggerState extends GeneralTriggerState = Gene
|
||||
);
|
||||
|
||||
const iter = defenderUnits.values();
|
||||
let defender: WarUnit<TriggerState> | null = null;
|
||||
|
||||
const getNextDefender = (
|
||||
_prevDefender: WarUnit<TriggerState> | null,
|
||||
@@ -359,7 +355,7 @@ export const resolveWarBattle = <TriggerState extends GeneralTriggerState = Gene
|
||||
return candidate;
|
||||
};
|
||||
|
||||
defender = getNextDefender(null, true);
|
||||
let defender = getNextDefender(null, true);
|
||||
let conquerCity = false;
|
||||
let logWritten = false;
|
||||
let traceSeq = 0;
|
||||
|
||||
Reference in New Issue
Block a user