feat: 여러 커맨드의 제약 조건 개선 및 새로운 제약 조건 추가
This commit is contained in:
@@ -5,7 +5,6 @@ import {
|
||||
nearCity,
|
||||
reqGeneralGold,
|
||||
reqGeneralRice,
|
||||
existsDestCity,
|
||||
} from '@sammo-ts/logic/constraints/presets.js';
|
||||
import type { GeneralActionDefinition } from '@sammo-ts/logic/actions/definition.js';
|
||||
import type {
|
||||
@@ -173,7 +172,6 @@ export class ActionDefinition<
|
||||
|
||||
buildConstraints(ctx: ConstraintContext, _args: ForcedMoveArgs): Constraint[] {
|
||||
return [
|
||||
existsDestCity(),
|
||||
notSameDestCity(),
|
||||
nearCity(3),
|
||||
reqGeneralGold((_c, _v) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { GeneralTriggerState, Nation } from '@sammo-ts/logic/domain/entities.js';
|
||||
import type { Constraint, ConstraintContext } from '@sammo-ts/logic/constraints/types.js';
|
||||
import { beNeutral } from '@sammo-ts/logic/constraints/presets.js';
|
||||
import { allowJoinAction, beNeutral, beOpeningPart, noPenalty } from '@sammo-ts/logic/constraints/presets.js';
|
||||
import type { GeneralActionDefinition } from '@sammo-ts/logic/actions/definition.js';
|
||||
import type { GeneralActionOutcome, GeneralActionResolveContext } from '@sammo-ts/logic/actions/engine.js';
|
||||
import {
|
||||
@@ -33,7 +33,7 @@ export class ActionDefinition<
|
||||
}
|
||||
|
||||
buildConstraints(_ctx: ConstraintContext, _args: UprisingArgs): Constraint[] {
|
||||
return [beNeutral()];
|
||||
return [beNeutral(), beOpeningPart(), allowJoinAction(), noPenalty('noFoundNation')];
|
||||
}
|
||||
|
||||
resolve(
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import type { GeneralTriggerState } from '@sammo-ts/logic/domain/entities.js';
|
||||
import type { Constraint, ConstraintContext } from '@sammo-ts/logic/constraints/types.js';
|
||||
import { occupiedCity, reqGeneralGold, reqGeneralRice, suppliedCity } from '@sammo-ts/logic/constraints/presets.js';
|
||||
import {
|
||||
occupiedCity,
|
||||
reqCityTrader,
|
||||
reqGeneralGold,
|
||||
reqGeneralRice,
|
||||
suppliedCity,
|
||||
} from '@sammo-ts/logic/constraints/presets.js';
|
||||
import type { GeneralActionDefinition } from '@sammo-ts/logic/actions/definition.js';
|
||||
import type { GeneralActionOutcome, GeneralActionResolveContext } from '@sammo-ts/logic/actions/engine.js';
|
||||
import { LogFormat } from '@sammo-ts/logic/logging/types.js';
|
||||
@@ -39,11 +45,11 @@ export class ActionDefinition<
|
||||
}
|
||||
|
||||
buildMinConstraints(_ctx: ConstraintContext, _args: TradeArgs): Constraint[] {
|
||||
return [occupiedCity(), suppliedCity()];
|
||||
return [reqCityTrader(), occupiedCity({ allowNeutral: true }), suppliedCity()];
|
||||
}
|
||||
|
||||
buildConstraints(_ctx: ConstraintContext, args: TradeArgs): Constraint[] {
|
||||
const constraints: Constraint[] = [occupiedCity(), suppliedCity()];
|
||||
const constraints: Constraint[] = [reqCityTrader(), occupiedCity({ allowNeutral: true }), suppliedCity()];
|
||||
if (args.buyRice) {
|
||||
constraints.push(reqGeneralGold(() => 1));
|
||||
} else {
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
notWanderingNation,
|
||||
occupiedCity,
|
||||
reqGeneralGold,
|
||||
reqGeneralRice,
|
||||
suppliedCity,
|
||||
} from '@sammo-ts/logic/constraints/presets.js';
|
||||
import type { GeneralActionDefinition } from '@sammo-ts/logic/actions/definition.js';
|
||||
@@ -52,7 +53,14 @@ export class ActionDefinition<
|
||||
|
||||
buildConstraints(_ctx: ConstraintContext, _args: TechResearchArgs): Constraint[] {
|
||||
const getRequiredGold = (_context: ConstraintContext, _view: StateView): number => this.env.costGold ?? 0;
|
||||
return [notBeNeutral(), notWanderingNation(), occupiedCity(), suppliedCity(), reqGeneralGold(getRequiredGold)];
|
||||
return [
|
||||
notBeNeutral(),
|
||||
notWanderingNation(),
|
||||
occupiedCity(),
|
||||
suppliedCity(),
|
||||
reqGeneralGold(getRequiredGold),
|
||||
reqGeneralRice(() => 0),
|
||||
];
|
||||
}
|
||||
|
||||
resolve(
|
||||
|
||||
@@ -15,8 +15,8 @@ const ACTION_NAME = '내정 특기 초기화';
|
||||
const hasSpecial = (value: string | null | undefined): boolean =>
|
||||
value !== null && value !== undefined && value !== 'None';
|
||||
|
||||
const reqDomesticSpecial = (): Constraint => ({
|
||||
name: 'ReqGeneralDomesticSpecial',
|
||||
const reqGeneralValue = (): Constraint => ({
|
||||
name: 'reqGeneralValue',
|
||||
requires: (ctx) => [{ kind: 'general', id: ctx.actorId }],
|
||||
test: (ctx, view) => {
|
||||
const general = readGeneral(ctx, view);
|
||||
@@ -42,8 +42,12 @@ export class ActionDefinition<
|
||||
return {};
|
||||
}
|
||||
|
||||
buildMinConstraints(_ctx: ConstraintContext, _args: ResetSpecialDomesticArgs): Constraint[] {
|
||||
return [reqGeneralValue()];
|
||||
}
|
||||
|
||||
buildConstraints(_ctx: ConstraintContext, _args: ResetSpecialDomesticArgs): Constraint[] {
|
||||
return [reqDomesticSpecial()];
|
||||
return [reqGeneralValue()];
|
||||
}
|
||||
|
||||
resolve(
|
||||
|
||||
@@ -62,8 +62,8 @@ const pickByWeight = <T extends string>(rng: DrillContext['rng'], weights: Recor
|
||||
return last ? last[0] : first[0];
|
||||
};
|
||||
|
||||
const reqGeneralStat = (key: 'train' | 'atmos', label: string, minValue: number): Constraint => ({
|
||||
name: `ReqGeneral${label}`,
|
||||
const reqGeneralValue = (key: 'train' | 'atmos', label: string, minValue: number): Constraint => ({
|
||||
name: 'reqGeneralValue',
|
||||
requires: (ctx) => [{ kind: 'general', id: ctx.actorId }],
|
||||
test: (ctx, view) => {
|
||||
const general = readGeneral(ctx, view);
|
||||
@@ -103,8 +103,8 @@ export class ActionDefinition<
|
||||
return [
|
||||
notBeNeutral(),
|
||||
reqGeneralCrew(),
|
||||
reqGeneralStat('train', '훈련', trainLow),
|
||||
reqGeneralStat('atmos', '사기', atmosLow),
|
||||
reqGeneralValue('train', '훈련', trainLow),
|
||||
reqGeneralValue('atmos', '사기', atmosLow),
|
||||
reqGeneralGold(getRequiredGold),
|
||||
reqGeneralRice(getRequiredRice),
|
||||
];
|
||||
|
||||
@@ -4,8 +4,10 @@ import {
|
||||
notBeNeutral,
|
||||
notWanderingNation,
|
||||
occupiedCity,
|
||||
reqGeneralAtmosMargin,
|
||||
reqGeneralCrew,
|
||||
reqGeneralGold,
|
||||
reqGeneralRice,
|
||||
} from '@sammo-ts/logic/constraints/presets.js';
|
||||
import type { GeneralActionDefinition } from '@sammo-ts/logic/actions/definition.js';
|
||||
import type { GeneralActionOutcome, GeneralActionResolveContext } from '@sammo-ts/logic/actions/engine.js';
|
||||
@@ -49,7 +51,19 @@ export class ActionDefinition<
|
||||
|
||||
buildConstraints(_ctx: ConstraintContext, _args: BoostMoraleArgs): Constraint[] {
|
||||
const getRequiredGold = (_context: ConstraintContext, _view: StateView): number => this.env.costGold ?? 0;
|
||||
return [notBeNeutral(), notWanderingNation(), occupiedCity(), reqGeneralCrew(), reqGeneralGold(getRequiredGold)];
|
||||
const maxAtmos =
|
||||
this.env.maxAtmosByCommand && this.env.maxAtmosByCommand > 0
|
||||
? this.env.maxAtmosByCommand
|
||||
: DEFAULT_MAX_ATMOS;
|
||||
return [
|
||||
notBeNeutral(),
|
||||
notWanderingNation(),
|
||||
occupiedCity(),
|
||||
reqGeneralCrew(),
|
||||
reqGeneralGold(getRequiredGold),
|
||||
reqGeneralRice(() => 0),
|
||||
reqGeneralAtmosMargin(maxAtmos),
|
||||
];
|
||||
}
|
||||
|
||||
resolve(
|
||||
|
||||
@@ -52,6 +52,12 @@ export class ActionDefinition<
|
||||
return parseArgsWithSchema(ARGS_SCHEMA, raw);
|
||||
}
|
||||
|
||||
buildMinConstraints(_ctx: ConstraintContext, _args: DexTransferArgs): Constraint[] {
|
||||
const getRequiredGold = (_context: ConstraintContext, _view: StateView): number => this.env.develCost ?? 0;
|
||||
const getRequiredRice = (_context: ConstraintContext, _view: StateView): number => this.env.develCost ?? 0;
|
||||
return [notBeNeutral(), occupiedCity(), reqGeneralGold(getRequiredGold), reqGeneralRice(getRequiredRice)];
|
||||
}
|
||||
|
||||
buildConstraints(_ctx: ConstraintContext, _args: DexTransferArgs): Constraint[] {
|
||||
const getRequiredGold = (_context: ConstraintContext, _view: StateView): number => this.env.develCost ?? 0;
|
||||
const getRequiredRice = (_context: ConstraintContext, _view: StateView): number => this.env.develCost ?? 0;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { GeneralTriggerState } from '@sammo-ts/logic/domain/entities.js';
|
||||
import type { Constraint, ConstraintContext, StateView } from '@sammo-ts/logic/constraints/types.js';
|
||||
import { notBeNeutral, reqGeneralGold } from '@sammo-ts/logic/constraints/presets.js';
|
||||
import type { Constraint, ConstraintContext } from '@sammo-ts/logic/constraints/types.js';
|
||||
import type { GeneralActionDefinition } from '@sammo-ts/logic/actions/definition.js';
|
||||
import type { GeneralActionOutcome, GeneralActionResolveContext } from '@sammo-ts/logic/actions/engine.js';
|
||||
import type { TurnCommandEnv } from '@sammo-ts/logic/actions/turn/commandEnv.js';
|
||||
@@ -34,8 +33,7 @@ export class ActionDefinition<
|
||||
}
|
||||
|
||||
buildConstraints(_ctx: ConstraintContext, _args: RecoveryArgs): Constraint[] {
|
||||
const getRequiredGold = (_context: ConstraintContext, _view: StateView): number => this.env.costGold ?? 0;
|
||||
return [notBeNeutral(), reqGeneralGold(getRequiredGold)];
|
||||
return [];
|
||||
}
|
||||
|
||||
resolve(
|
||||
|
||||
@@ -22,8 +22,8 @@ const ACTION_KEY = 'che_은퇴';
|
||||
|
||||
const REQ_AGE = 60;
|
||||
|
||||
const reqAge = (): Constraint => ({
|
||||
name: 'ReqAge',
|
||||
const reqGeneralValue = (): Constraint => ({
|
||||
name: 'reqGeneralValue',
|
||||
requires: (ctx) => [{ kind: 'general', id: ctx.actorId }],
|
||||
test: (ctx, view) => {
|
||||
const generalKey: RequirementKey = { kind: 'general', id: ctx.actorId };
|
||||
@@ -118,7 +118,7 @@ export class ActionDefinition<
|
||||
}
|
||||
|
||||
buildConstraints(_ctx: ConstraintContext, _args: RetireArgs): Constraint[] {
|
||||
return [reqAge()];
|
||||
return [reqGeneralValue()];
|
||||
}
|
||||
|
||||
resolve(context: GeneralActionResolveContext<TriggerState>, args: RetireArgs): GeneralActionOutcome<TriggerState> {
|
||||
|
||||
@@ -16,8 +16,8 @@ const ACTION_NAME = '전투 특기 초기화';
|
||||
const hasSpecial = (value: string | null | undefined): boolean =>
|
||||
value !== null && value !== undefined && value !== 'None';
|
||||
|
||||
const reqWarSpecial = (): Constraint => ({
|
||||
name: 'ReqGeneralWarSpecial',
|
||||
const reqGeneralValue = (): Constraint => ({
|
||||
name: 'reqGeneralValue',
|
||||
requires: (ctx) => [{ kind: 'general', id: ctx.actorId }],
|
||||
test: (ctx, view) => {
|
||||
const general = readGeneral(ctx, view);
|
||||
@@ -43,8 +43,12 @@ export class ActionDefinition<
|
||||
return {};
|
||||
}
|
||||
|
||||
buildMinConstraints(_ctx: ConstraintContext, _args: ResetSpecialWarArgs): Constraint[] {
|
||||
return [reqGeneralValue()];
|
||||
}
|
||||
|
||||
buildConstraints(_ctx: ConstraintContext, _args: ResetSpecialWarArgs): Constraint[] {
|
||||
return [reqWarSpecial()];
|
||||
return [reqGeneralValue()];
|
||||
}
|
||||
|
||||
resolve(
|
||||
|
||||
@@ -4,7 +4,8 @@ import {
|
||||
notBeNeutral,
|
||||
notWanderingNation,
|
||||
occupiedCity,
|
||||
remainCityCapacityByMax,
|
||||
remainCityCapacity,
|
||||
reqGeneralGold,
|
||||
reqGeneralRice,
|
||||
suppliedCity,
|
||||
} from '@sammo-ts/logic/constraints/presets.js';
|
||||
@@ -76,7 +77,8 @@ export class ActionDefinition<
|
||||
notWanderingNation(),
|
||||
occupiedCity(),
|
||||
suppliedCity(),
|
||||
remainCityCapacityByMax('population', 'populationMax', '인구'),
|
||||
reqGeneralGold(() => 0),
|
||||
remainCityCapacity('population', '인구'),
|
||||
reqGeneralRice(getRequiredRice),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
notBeNeutral,
|
||||
notWanderingNation,
|
||||
occupiedCity,
|
||||
reqGeneralGold,
|
||||
reqGeneralRice,
|
||||
suppliedCity,
|
||||
} from '@sammo-ts/logic/constraints/presets.js';
|
||||
@@ -134,6 +135,7 @@ export class ActionDefinition<
|
||||
notWanderingNation(),
|
||||
occupiedCity(),
|
||||
suppliedCity(),
|
||||
reqGeneralGold(() => 0, requirements),
|
||||
reqGeneralRice(getRiceCost, requirements),
|
||||
remainCityTrust(),
|
||||
];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { GeneralTriggerState } from '@sammo-ts/logic/domain/entities.js';
|
||||
import type { Constraint, ConstraintContext } from '@sammo-ts/logic/constraints/types.js';
|
||||
import { notBeNeutral } from '@sammo-ts/logic/constraints/presets.js';
|
||||
import { notBeNeutral, notLord } from '@sammo-ts/logic/constraints/presets.js';
|
||||
import type { GeneralActionDefinition } from '@sammo-ts/logic/actions/definition.js';
|
||||
import type {
|
||||
GeneralActionOutcome,
|
||||
@@ -106,7 +106,7 @@ export class ActionDefinition<
|
||||
}
|
||||
|
||||
buildConstraints(_ctx: ConstraintContext, _args: ResignArgs): Constraint[] {
|
||||
return [notBeNeutral()];
|
||||
return [notBeNeutral(), notLord()];
|
||||
}
|
||||
|
||||
resolve(context: GeneralActionResolveContext<TriggerState>, args: ResignArgs): GeneralActionOutcome<TriggerState> {
|
||||
|
||||
@@ -2,7 +2,6 @@ import type { GeneralTriggerState } from '@sammo-ts/logic/domain/entities.js';
|
||||
import type { Constraint, ConstraintContext } from '@sammo-ts/logic/constraints/types.js';
|
||||
import {
|
||||
notBeNeutral,
|
||||
notWanderingNation,
|
||||
occupiedCity,
|
||||
reqGeneralGold,
|
||||
reqGeneralRice,
|
||||
@@ -107,9 +106,9 @@ export class ActionDefinition<
|
||||
|
||||
buildConstraints(_ctx: ConstraintContext, args: DonateArgs): Constraint[] {
|
||||
if (args.isGold) {
|
||||
return [notBeNeutral(), notWanderingNation(), occupiedCity(), suppliedCity(), reqGeneralGold(() => args.amount)];
|
||||
return [notBeNeutral(), occupiedCity(), suppliedCity(), reqGeneralGold(() => args.amount)];
|
||||
}
|
||||
return [notBeNeutral(), notWanderingNation(), occupiedCity(), suppliedCity(), reqGeneralRice(() => args.amount)];
|
||||
return [notBeNeutral(), occupiedCity(), suppliedCity(), reqGeneralRice(() => args.amount)];
|
||||
}
|
||||
|
||||
resolve(context: GeneralActionResolveContext<TriggerState>, args: DonateArgs): GeneralActionOutcome<TriggerState> {
|
||||
|
||||
@@ -10,7 +10,6 @@ import type {
|
||||
import type { Constraint, ConstraintContext } from '@sammo-ts/logic/constraints/types.js';
|
||||
import {
|
||||
disallowDiplomacyBetweenStatus,
|
||||
existsDestCity,
|
||||
notBeNeutral,
|
||||
notNeutralDestCity,
|
||||
notOccupiedDestCity,
|
||||
@@ -393,7 +392,6 @@ export class ActionDefinition<
|
||||
notBeNeutral(),
|
||||
occupiedCity(),
|
||||
suppliedCity(),
|
||||
existsDestCity(),
|
||||
notOccupiedDestCity(),
|
||||
notNeutralDestCity(),
|
||||
reqGeneralGold(() => gold),
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import type { GeneralTriggerState } from '@sammo-ts/logic/domain/entities.js';
|
||||
import type { Constraint, ConstraintContext, StateView } from '@sammo-ts/logic/constraints/types.js';
|
||||
import { notBeNeutral, notWanderingNation, occupiedCity, reqGeneralCrew, reqGeneralGold } from '@sammo-ts/logic/constraints/presets.js';
|
||||
import type { Constraint, ConstraintContext } from '@sammo-ts/logic/constraints/types.js';
|
||||
import {
|
||||
notBeNeutral,
|
||||
notWanderingNation,
|
||||
occupiedCity,
|
||||
reqGeneralCrew,
|
||||
reqGeneralTrainMargin,
|
||||
} from '@sammo-ts/logic/constraints/presets.js';
|
||||
import type { GeneralActionDefinition } from '@sammo-ts/logic/actions/definition.js';
|
||||
import type { GeneralActionOutcome, GeneralActionResolveContext } from '@sammo-ts/logic/actions/engine.js';
|
||||
import type { TurnCommandEnv } from '@sammo-ts/logic/actions/turn/commandEnv.js';
|
||||
@@ -42,8 +48,11 @@ export class ActionDefinition<
|
||||
}
|
||||
|
||||
buildConstraints(_ctx: ConstraintContext, _args: TrainingArgs): Constraint[] {
|
||||
const getRequiredGold = (_context: ConstraintContext, _view: StateView): number => this.env.costGold ?? 0;
|
||||
return [notBeNeutral(), notWanderingNation(), occupiedCity(), reqGeneralCrew(), reqGeneralGold(getRequiredGold)];
|
||||
const maxTrain =
|
||||
this.env.maxTrainByCommand && this.env.maxTrainByCommand > 0
|
||||
? this.env.maxTrainByCommand
|
||||
: DEFAULT_MAX_TRAIN;
|
||||
return [notBeNeutral(), notWanderingNation(), occupiedCity(), reqGeneralCrew(), reqGeneralTrainMargin(maxTrain)];
|
||||
}
|
||||
|
||||
resolve(
|
||||
|
||||
@@ -24,8 +24,8 @@ export interface EventResearchConfig {
|
||||
category?: string;
|
||||
}
|
||||
|
||||
const requireNationAux = (auxKey: string, actionName: string): Constraint => ({
|
||||
name: 'requireNationAux',
|
||||
const reqNationAuxValue = (auxKey: string, actionName: string): Constraint => ({
|
||||
name: 'reqNationAuxValue',
|
||||
requires: (ctx) => (ctx.nationId !== undefined ? [{ kind: 'nation', id: ctx.nationId }] : []),
|
||||
test: (ctx: ConstraintContext, view: StateView) => {
|
||||
if (ctx.nationId === undefined) {
|
||||
@@ -69,13 +69,25 @@ export const createEventResearchCommand = (config: EventResearchConfig): {
|
||||
return {};
|
||||
}
|
||||
|
||||
buildMinConstraints(_ctx: ConstraintContext, _args: Record<string, never>): Constraint[] {
|
||||
void _ctx;
|
||||
void _args;
|
||||
return [
|
||||
occupiedCity(),
|
||||
beChief(),
|
||||
reqNationAuxValue(config.auxKey, ACTION_NAME),
|
||||
reqNationGold(() => this.env.baseGold + COST),
|
||||
reqNationRice(() => this.env.baseRice + COST),
|
||||
];
|
||||
}
|
||||
|
||||
buildConstraints(_ctx: ConstraintContext, _args: Record<string, never>): Constraint[] {
|
||||
void _ctx;
|
||||
void _args;
|
||||
return [
|
||||
occupiedCity(),
|
||||
beChief(),
|
||||
requireNationAux(config.auxKey, ACTION_NAME),
|
||||
reqNationAuxValue(config.auxKey, ACTION_NAME),
|
||||
reqNationGold(() => this.env.baseGold + COST),
|
||||
reqNationRice(() => this.env.baseRice + COST),
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user