constraint 실패 후 실패 검사 결과 항목을 직접 반환.

This commit is contained in:
2026-01-10 13:16:43 +00:00
parent d5d3949705
commit 3ec7e66948
9 changed files with 82 additions and 74 deletions
@@ -340,11 +340,12 @@ const buildConstraintContext = (
mode: 'full', mode: 'full',
}); });
const createActionLog = (message: string): LogEntryDraft => ({ const createActionLog = (message: string, meta?: Record<string, unknown>): LogEntryDraft => ({
scope: LogScope.GENERAL, scope: LogScope.GENERAL,
category: LogCategory.ACTION, category: LogCategory.ACTION,
format: LogFormat.MONTH, format: LogFormat.MONTH,
text: message, text: message,
meta,
}); });
const resolveDefinition = ( const resolveDefinition = (
@@ -505,7 +506,8 @@ export const createReservedTurnHandler = async (options: {
actionArgs = definition.parseArgs({}) ?? {}; actionArgs = definition.parseArgs({}) ?? {};
actionKey = definition.key; actionKey = definition.key;
const reason = result.kind === 'deny' ? result.reason : '조건을 확인할 수 없습니다.'; const reason = result.kind === 'deny' ? result.reason : '조건을 확인할 수 없습니다.';
logs.push(createActionLog(reason)); const meta = result.kind === 'deny' ? { constraintName: result.constraintName } : undefined;
logs.push(createActionLog(reason, meta));
} }
const seedBase = buildSeedBase(context.world); const seedBase = buildSeedBase(context.world);
+15 -15
View File
@@ -14,7 +14,7 @@ import {
import type { Constraint, RequirementKey } from './types.js'; import type { Constraint, RequirementKey } from './types.js';
export const occupiedCity = (options: { allowNeutral?: boolean } = {}): Constraint => ({ export const occupiedCity = (options: { allowNeutral?: boolean } = {}): Constraint => ({
name: 'OccupiedCity', name: 'occupiedCity',
requires: (ctx) => { requires: (ctx) => {
const reqs: RequirementKey[] = [{ kind: 'general', id: ctx.actorId }]; const reqs: RequirementKey[] = [{ kind: 'general', id: ctx.actorId }];
if (ctx.cityId !== undefined) { if (ctx.cityId !== undefined) {
@@ -51,7 +51,7 @@ export const occupiedCity = (options: { allowNeutral?: boolean } = {}): Constrai
}); });
export const occupiedDestCity = (): Constraint => ({ export const occupiedDestCity = (): Constraint => ({
name: 'OccupiedDestCity', name: 'occupiedDestCity',
requires: (ctx) => { requires: (ctx) => {
const reqs: RequirementKey[] = [{ kind: 'general', id: ctx.actorId }]; const reqs: RequirementKey[] = [{ kind: 'general', id: ctx.actorId }];
const destCityId = resolveDestCityId(ctx); const destCityId = resolveDestCityId(ctx);
@@ -90,7 +90,7 @@ export const occupiedDestCity = (): Constraint => ({
}); });
export const suppliedCity = (): Constraint => ({ export const suppliedCity = (): Constraint => ({
name: 'SuppliedCity', name: 'suppliedCity',
requires: (ctx) => (ctx.cityId !== undefined ? [{ kind: 'city', id: ctx.cityId }] : []), requires: (ctx) => (ctx.cityId !== undefined ? [{ kind: 'city', id: ctx.cityId }] : []),
test: (ctx, view) => { test: (ctx, view) => {
const city = readCity(view, ctx.cityId); const city = readCity(view, ctx.cityId);
@@ -109,7 +109,7 @@ export const suppliedCity = (): Constraint => ({
}); });
export const suppliedDestCity = (): Constraint => ({ export const suppliedDestCity = (): Constraint => ({
name: 'SuppliedDestCity', name: 'suppliedDestCity',
requires: (ctx) => requires: (ctx) =>
resolveDestCityId(ctx) !== undefined resolveDestCityId(ctx) !== undefined
? [ ? [
@@ -140,7 +140,7 @@ export const suppliedDestCity = (): Constraint => ({
}); });
export const remainCityCapacity = (key: keyof City, label: string): Constraint => ({ export const remainCityCapacity = (key: keyof City, label: string): Constraint => ({
name: 'RemainCityCapacity', name: 'remainCityCapacity',
requires: (ctx) => (ctx.cityId !== undefined ? [{ kind: 'city', id: ctx.cityId }] : []), requires: (ctx) => (ctx.cityId !== undefined ? [{ kind: 'city', id: ctx.cityId }] : []),
test: (ctx, view) => { test: (ctx, view) => {
const city = readCity(view, ctx.cityId); const city = readCity(view, ctx.cityId);
@@ -165,7 +165,7 @@ export const remainCityCapacity = (key: keyof City, label: string): Constraint =
}); });
export const remainCityCapacityByMax = (key: keyof City, maxKey: keyof City, label: string): Constraint => ({ export const remainCityCapacityByMax = (key: keyof City, maxKey: keyof City, label: string): Constraint => ({
name: 'RemainCityCapacityByMax', name: 'remainCityCapacityByMax',
requires: (ctx) => (ctx.cityId !== undefined ? [{ kind: 'city', id: ctx.cityId }] : []), requires: (ctx) => (ctx.cityId !== undefined ? [{ kind: 'city', id: ctx.cityId }] : []),
test: (ctx, view) => { test: (ctx, view) => {
const city = readCity(view, ctx.cityId); const city = readCity(view, ctx.cityId);
@@ -189,7 +189,7 @@ export const remainCityCapacityByMax = (key: keyof City, maxKey: keyof City, lab
}); });
export const reqCityCapacity = (key: keyof City, label: string, required: number | string): Constraint => ({ export const reqCityCapacity = (key: keyof City, label: string, required: number | string): Constraint => ({
name: 'ReqCityCapacity', name: 'reqCityCapacity',
requires: (ctx) => (ctx.cityId !== undefined ? [{ kind: 'city', id: ctx.cityId }] : []), requires: (ctx) => (ctx.cityId !== undefined ? [{ kind: 'city', id: ctx.cityId }] : []),
test: (ctx, view) => { test: (ctx, view) => {
const city = readCity(view, ctx.cityId); const city = readCity(view, ctx.cityId);
@@ -222,7 +222,7 @@ export const reqCityCapacity = (key: keyof City, label: string, required: number
}); });
export const reqCityTrust = (minTrust: number): Constraint => ({ export const reqCityTrust = (minTrust: number): Constraint => ({
name: 'ReqCityTrust', name: 'reqCityTrust',
requires: (ctx) => (ctx.cityId !== undefined ? [{ kind: 'city', id: ctx.cityId }] : []), requires: (ctx) => (ctx.cityId !== undefined ? [{ kind: 'city', id: ctx.cityId }] : []),
test: (ctx, view) => { test: (ctx, view) => {
const city = readCity(view, ctx.cityId); const city = readCity(view, ctx.cityId);
@@ -245,7 +245,7 @@ export const reqCityTrust = (minTrust: number): Constraint => ({
}); });
export const existsDestCity = (): Constraint => ({ export const existsDestCity = (): Constraint => ({
name: 'ExistsDestCity', name: 'existsDestCity',
requires: (ctx) => requires: (ctx) =>
resolveDestCityId(ctx) !== undefined resolveDestCityId(ctx) !== undefined
? [ ? [
@@ -273,7 +273,7 @@ export const existsDestCity = (): Constraint => ({
}); });
export const notOccupiedDestCity = (): Constraint => ({ export const notOccupiedDestCity = (): Constraint => ({
name: 'NotOccupiedDestCity', name: 'notOccupiedDestCity',
requires: (ctx) => { requires: (ctx) => {
const reqs: RequirementKey[] = [{ kind: 'general', id: ctx.actorId }]; const reqs: RequirementKey[] = [{ kind: 'general', id: ctx.actorId }];
const destCityId = resolveDestCityId(ctx); const destCityId = resolveDestCityId(ctx);
@@ -311,7 +311,7 @@ export const notOccupiedDestCity = (): Constraint => ({
}); });
export const notNeutralDestCity = (): Constraint => ({ export const notNeutralDestCity = (): Constraint => ({
name: 'NotNeutralDestCity', name: 'notNeutralDestCity',
requires: (ctx) => requires: (ctx) =>
resolveDestCityId(ctx) !== undefined resolveDestCityId(ctx) !== undefined
? [ ? [
@@ -342,7 +342,7 @@ export const notNeutralDestCity = (): Constraint => ({
}); });
export const notSameDestCity = (): Constraint => ({ export const notSameDestCity = (): Constraint => ({
name: 'NotSameDestCity', name: 'notSameDestCity',
requires: (ctx) => { requires: (ctx) => {
const reqs: RequirementKey[] = [{ kind: 'general', id: ctx.actorId }]; const reqs: RequirementKey[] = [{ kind: 'general', id: ctx.actorId }];
const destCityId = resolveDestCityId(ctx); const destCityId = resolveDestCityId(ctx);
@@ -369,7 +369,7 @@ export const notSameDestCity = (): Constraint => ({
}); });
export const hasRouteWithEnemy = (): Constraint => ({ export const hasRouteWithEnemy = (): Constraint => ({
name: 'HasRouteWithEnemy', name: 'hasRouteWithEnemy',
requires: (ctx) => { requires: (ctx) => {
const reqs: RequirementKey[] = [{ kind: 'general', id: ctx.actorId }]; const reqs: RequirementKey[] = [{ kind: 'general', id: ctx.actorId }];
const destCityId = resolveDestCityId(ctx); const destCityId = resolveDestCityId(ctx);
@@ -435,7 +435,7 @@ export const hasRouteWithEnemy = (): Constraint => ({
}); });
export const beNeutralCity = (): Constraint => ({ export const beNeutralCity = (): Constraint => ({
name: 'BeNeutralCity', name: 'beNeutralCity',
requires: (ctx) => (ctx.cityId !== undefined ? [{ kind: 'city', id: ctx.cityId }] : []), requires: (ctx) => (ctx.cityId !== undefined ? [{ kind: 'city', id: ctx.cityId }] : []),
test: (ctx, view) => { test: (ctx, view) => {
const city = readCity(view, ctx.cityId); const city = readCity(view, ctx.cityId);
@@ -463,7 +463,7 @@ export const beNeutralCity = (): Constraint => ({
}); });
export const reqCityLevel = (levels: number[]): Constraint => ({ export const reqCityLevel = (levels: number[]): Constraint => ({
name: 'ReqCityLevel', name: 'reqCityLevel',
requires: (ctx) => (ctx.cityId !== undefined ? [{ kind: 'city', id: ctx.cityId }] : []), requires: (ctx) => (ctx.cityId !== undefined ? [{ kind: 'city', id: ctx.cityId }] : []),
test: (ctx, view) => { test: (ctx, view) => {
const city = readCity(view, ctx.cityId); const city = readCity(view, ctx.cityId);
+4 -4
View File
@@ -41,7 +41,7 @@ const readDiplomacyEntry = (
}; };
export const disallowDiplomacyBetweenStatus = (disallowList: Record<number, string>): Constraint => ({ export const disallowDiplomacyBetweenStatus = (disallowList: Record<number, string>): Constraint => ({
name: 'DisallowDiplomacyBetweenStatus', name: 'disallowDiplomacyBetweenStatus',
requires: (ctx) => { requires: (ctx) => {
const reqs: RequirementKey[] = []; const reqs: RequirementKey[] = [];
if (ctx.nationId !== undefined) { if (ctx.nationId !== undefined) {
@@ -93,7 +93,7 @@ export const disallowDiplomacyBetweenStatus = (disallowList: Record<number, stri
}); });
export const allowDiplomacyBetweenStatus = (allowList: number[], reason: string): Constraint => ({ export const allowDiplomacyBetweenStatus = (allowList: number[], reason: string): Constraint => ({
name: 'AllowDiplomacyBetweenStatus', name: 'allowDiplomacyBetweenStatus',
requires: (ctx) => { requires: (ctx) => {
const reqs: RequirementKey[] = []; const reqs: RequirementKey[] = [];
if (ctx.nationId !== undefined) { if (ctx.nationId !== undefined) {
@@ -144,7 +144,7 @@ export const allowDiplomacyBetweenStatus = (allowList: number[], reason: string)
}); });
export const allowDiplomacyWithTerm = (requiredState: number, minTerm: number, reason: string): Constraint => ({ export const allowDiplomacyWithTerm = (requiredState: number, minTerm: number, reason: string): Constraint => ({
name: 'AllowDiplomacyWithTerm', name: 'allowDiplomacyWithTerm',
requires: (ctx) => { requires: (ctx) => {
const reqs: RequirementKey[] = []; const reqs: RequirementKey[] = [];
if (ctx.nationId !== undefined) { if (ctx.nationId !== undefined) {
@@ -195,7 +195,7 @@ export const allowDiplomacyWithTerm = (requiredState: number, minTerm: number, r
}); });
export const allowDiplomacyStatus = (allowList: number[], reason: string): Constraint => ({ export const allowDiplomacyStatus = (allowList: number[], reason: string): Constraint => ({
name: 'AllowDiplomacyStatus', name: 'allowDiplomacyStatus',
requires: (ctx) => { requires: (ctx) => {
const reqs: RequirementKey[] = [{ kind: 'general', id: ctx.actorId }]; const reqs: RequirementKey[] = [{ kind: 'general', id: ctx.actorId }];
if (ctx.nationId !== undefined) { if (ctx.nationId !== undefined) {
@@ -11,6 +11,12 @@ export const evaluateConstraints = (
return { kind: 'unknown', missing }; return { kind: 'unknown', missing };
} }
const result = constraint.test(ctx, view); const result = constraint.test(ctx, view);
if (result.kind === 'deny') {
return {
...result,
constraintName: result.constraintName ?? constraint.name,
};
}
if (result.kind !== 'allow') { if (result.kind !== 'allow') {
return result; return result;
} }
+11 -11
View File
@@ -3,7 +3,7 @@ import { allow, readDestGeneral, resolveDestGeneralId, resolveDestNationId, unkn
import type { Constraint, ConstraintContext, RequirementKey, StateView } from './types.js'; import type { Constraint, ConstraintContext, RequirementKey, StateView } from './types.js';
export const notBeNeutral = (): Constraint => ({ export const notBeNeutral = (): Constraint => ({
name: 'NotBeNeutral', name: 'notBeNeutral',
requires: (ctx) => [{ kind: 'general', id: ctx.actorId }], requires: (ctx) => [{ kind: 'general', id: ctx.actorId }],
test: (ctx, view) => { test: (ctx, view) => {
const req: RequirementKey = { kind: 'general', id: ctx.actorId }; const req: RequirementKey = { kind: 'general', id: ctx.actorId };
@@ -22,7 +22,7 @@ export const notBeNeutral = (): Constraint => ({
}); });
export const beNeutral = (): Constraint => ({ export const beNeutral = (): Constraint => ({
name: 'BeNeutral', name: 'beNeutral',
requires: (ctx) => [{ kind: 'general', id: ctx.actorId }], requires: (ctx) => [{ kind: 'general', id: ctx.actorId }],
test: (ctx, view) => { test: (ctx, view) => {
const req: RequirementKey = { kind: 'general', id: ctx.actorId }; const req: RequirementKey = { kind: 'general', id: ctx.actorId };
@@ -41,7 +41,7 @@ export const beNeutral = (): Constraint => ({
}); });
export const beChief = (): Constraint => ({ export const beChief = (): Constraint => ({
name: 'BeChief', name: 'beChief',
requires: (ctx) => [{ kind: 'general', id: ctx.actorId }], requires: (ctx) => [{ kind: 'general', id: ctx.actorId }],
test: (ctx, view) => { test: (ctx, view) => {
const req: RequirementKey = { kind: 'general', id: ctx.actorId }; const req: RequirementKey = { kind: 'general', id: ctx.actorId };
@@ -60,7 +60,7 @@ export const beChief = (): Constraint => ({
}); });
export const beMonarch = (): Constraint => ({ export const beMonarch = (): Constraint => ({
name: 'BeMonarch', name: 'beMonarch',
requires: (ctx) => [{ kind: 'general', id: ctx.actorId }], requires: (ctx) => [{ kind: 'general', id: ctx.actorId }],
test: (ctx, view) => { test: (ctx, view) => {
const req: RequirementKey = { kind: 'general', id: ctx.actorId }; const req: RequirementKey = { kind: 'general', id: ctx.actorId };
@@ -82,7 +82,7 @@ export const reqGeneralGold = (
getRequiredGold: (ctx: ConstraintContext, view: StateView) => number, getRequiredGold: (ctx: ConstraintContext, view: StateView) => number,
requirements: RequirementKey[] = [] requirements: RequirementKey[] = []
): Constraint => ({ ): Constraint => ({
name: 'ReqGeneralGold', name: 'reqGeneralGold',
requires: (ctx) => [{ kind: 'general', id: ctx.actorId }, ...requirements], requires: (ctx) => [{ kind: 'general', id: ctx.actorId }, ...requirements],
test: (ctx, view) => { test: (ctx, view) => {
const generalReq: RequirementKey = { kind: 'general', id: ctx.actorId }; const generalReq: RequirementKey = { kind: 'general', id: ctx.actorId };
@@ -106,7 +106,7 @@ export const reqGeneralRice = (
getRequiredRice: (ctx: ConstraintContext, view: StateView) => number, getRequiredRice: (ctx: ConstraintContext, view: StateView) => number,
requirements: RequirementKey[] = [] requirements: RequirementKey[] = []
): Constraint => ({ ): Constraint => ({
name: 'ReqGeneralRice', name: 'reqGeneralRice',
requires: (ctx) => [{ kind: 'general', id: ctx.actorId }, ...requirements], requires: (ctx) => [{ kind: 'general', id: ctx.actorId }, ...requirements],
test: (ctx, view) => { test: (ctx, view) => {
const generalReq: RequirementKey = { kind: 'general', id: ctx.actorId }; const generalReq: RequirementKey = { kind: 'general', id: ctx.actorId };
@@ -127,7 +127,7 @@ export const reqGeneralRice = (
}); });
export const reqGeneralCrew = (): Constraint => ({ export const reqGeneralCrew = (): Constraint => ({
name: 'ReqGeneralCrew', name: 'reqGeneralCrew',
requires: (ctx) => [{ kind: 'general', id: ctx.actorId }], requires: (ctx) => [{ kind: 'general', id: ctx.actorId }],
test: (ctx, view) => { test: (ctx, view) => {
const generalReq: RequirementKey = { kind: 'general', id: ctx.actorId }; const generalReq: RequirementKey = { kind: 'general', id: ctx.actorId };
@@ -149,7 +149,7 @@ export const reqGeneralCrewMargin = (
getCrewTypeId: (ctx: ConstraintContext, view: StateView) => number | null, getCrewTypeId: (ctx: ConstraintContext, view: StateView) => number | null,
requirements: RequirementKey[] = [] requirements: RequirementKey[] = []
): Constraint => ({ ): Constraint => ({
name: 'ReqGeneralCrewMargin', name: 'reqGeneralCrewMargin',
requires: (ctx) => [{ kind: 'general', id: ctx.actorId }, ...requirements], requires: (ctx) => [{ kind: 'general', id: ctx.actorId }, ...requirements],
test: (ctx, view) => { test: (ctx, view) => {
const generalReq: RequirementKey = { kind: 'general', id: ctx.actorId }; const generalReq: RequirementKey = { kind: 'general', id: ctx.actorId };
@@ -177,7 +177,7 @@ export const reqGeneralCrewMargin = (
}); });
export const existsDestGeneral = (): Constraint => ({ export const existsDestGeneral = (): Constraint => ({
name: 'ExistsDestGeneral', name: 'existsDestGeneral',
requires: (ctx) => requires: (ctx) =>
resolveDestGeneralId(ctx) !== undefined resolveDestGeneralId(ctx) !== undefined
? [ ? [
@@ -205,7 +205,7 @@ export const existsDestGeneral = (): Constraint => ({
}); });
export const destGeneralInDestNation = (): Constraint => ({ export const destGeneralInDestNation = (): Constraint => ({
name: 'DestGeneralInDestNation', name: 'destGeneralInDestNation',
requires: (ctx) => { requires: (ctx) => {
const reqs: RequirementKey[] = []; const reqs: RequirementKey[] = [];
const destGeneralId = resolveDestGeneralId(ctx); const destGeneralId = resolveDestGeneralId(ctx);
@@ -246,7 +246,7 @@ export const destGeneralInDestNation = (): Constraint => ({
}); });
export const friendlyDestGeneral = (): Constraint => ({ export const friendlyDestGeneral = (): Constraint => ({
name: 'FriendlyDestGeneral', name: 'friendlyDestGeneral',
requires: (ctx) => { requires: (ctx) => {
const reqs: RequirementKey[] = [{ kind: 'general', id: ctx.actorId }]; const reqs: RequirementKey[] = [{ kind: 'general', id: ctx.actorId }];
const destGeneralId = resolveDestGeneralId(ctx); const destGeneralId = resolveDestGeneralId(ctx);
+3 -3
View File
@@ -2,13 +2,13 @@ import { allow } from './helpers.js';
import type { Constraint } from './types.js'; import type { Constraint } from './types.js';
export const alwaysFail = (reason: string): Constraint => ({ export const alwaysFail = (reason: string): Constraint => ({
name: 'AlwaysFail', name: 'alwaysFail',
requires: () => [], requires: () => [],
test: () => ({ kind: 'deny', reason }), test: () => ({ kind: 'deny', reason }),
}); });
export const notOpeningPart = (relYear: number, openingPartYear: number): Constraint => ({ export const notOpeningPart = (relYear: number, openingPartYear: number): Constraint => ({
name: 'NotOpeningPart', name: 'notOpeningPart',
requires: () => [], requires: () => [],
test: (_ctx) => { test: (_ctx) => {
if (relYear >= openingPartYear) { if (relYear >= openingPartYear) {
@@ -19,7 +19,7 @@ export const notOpeningPart = (relYear: number, openingPartYear: number): Constr
}); });
export const beOpeningPart = (): Constraint => ({ export const beOpeningPart = (): Constraint => ({
name: 'BeOpeningPart', name: 'beOpeningPart',
requires: () => [ requires: () => [
{ kind: 'env', key: 'year' }, { kind: 'env', key: 'year' },
{ kind: 'env', key: 'openingPartYear' }, { kind: 'env', key: 'openingPartYear' },
+9 -9
View File
@@ -3,7 +3,7 @@ import { allow, readGeneral, readMetaNumber, readNation, resolveDestNationId, un
import type { Constraint, ConstraintContext, RequirementKey, StateView } from './types.js'; import type { Constraint, ConstraintContext, RequirementKey, StateView } from './types.js';
export const notWanderingNation = (): Constraint => ({ export const notWanderingNation = (): Constraint => ({
name: 'NotWanderingNation', name: 'notWanderingNation',
requires: (ctx) => (ctx.nationId !== undefined ? [{ kind: 'nation', id: ctx.nationId }] : []), requires: (ctx) => (ctx.nationId !== undefined ? [{ kind: 'nation', id: ctx.nationId }] : []),
test: (ctx, view) => { test: (ctx, view) => {
const nation = readNation(view, ctx.nationId); const nation = readNation(view, ctx.nationId);
@@ -22,7 +22,7 @@ export const notWanderingNation = (): Constraint => ({
}); });
export const beWanderingNation = (): Constraint => ({ export const beWanderingNation = (): Constraint => ({
name: 'BeWanderingNation', name: 'beWanderingNation',
requires: (ctx) => (ctx.nationId !== undefined ? [{ kind: 'nation', id: ctx.nationId }] : []), requires: (ctx) => (ctx.nationId !== undefined ? [{ kind: 'nation', id: ctx.nationId }] : []),
test: (ctx, view) => { test: (ctx, view) => {
const nation = readNation(view, ctx.nationId); const nation = readNation(view, ctx.nationId);
@@ -41,7 +41,7 @@ export const beWanderingNation = (): Constraint => ({
}); });
export const availableStrategicCommand = (allowTurnCnt = 0): Constraint => ({ export const availableStrategicCommand = (allowTurnCnt = 0): Constraint => ({
name: 'AvailableStrategicCommand', name: 'availableStrategicCommand',
requires: (ctx) => { requires: (ctx) => {
const reqs: RequirementKey[] = [{ kind: 'general', id: ctx.actorId }]; const reqs: RequirementKey[] = [{ kind: 'general', id: ctx.actorId }];
if (ctx.nationId !== undefined) { if (ctx.nationId !== undefined) {
@@ -85,7 +85,7 @@ export const reqNationGold = (
getRequiredGold: (ctx: ConstraintContext, view: StateView) => number, getRequiredGold: (ctx: ConstraintContext, view: StateView) => number,
requirements: RequirementKey[] = [] requirements: RequirementKey[] = []
): Constraint => ({ ): Constraint => ({
name: 'ReqNationGold', name: 'reqNationGold',
requires: (ctx) => { requires: (ctx) => {
const reqs: RequirementKey[] = [...requirements]; const reqs: RequirementKey[] = [...requirements];
if (ctx.nationId !== undefined) { if (ctx.nationId !== undefined) {
@@ -119,7 +119,7 @@ export const reqNationRice = (
getRequiredRice: (ctx: ConstraintContext, view: StateView) => number, getRequiredRice: (ctx: ConstraintContext, view: StateView) => number,
requirements: RequirementKey[] = [] requirements: RequirementKey[] = []
): Constraint => ({ ): Constraint => ({
name: 'ReqNationRice', name: 'reqNationRice',
requires: (ctx) => { requires: (ctx) => {
const reqs: RequirementKey[] = [...requirements]; const reqs: RequirementKey[] = [...requirements];
if (ctx.nationId !== undefined) { if (ctx.nationId !== undefined) {
@@ -150,7 +150,7 @@ export const reqNationRice = (
}); });
export const existsDestNation = (): Constraint => ({ export const existsDestNation = (): Constraint => ({
name: 'ExistsDestNation', name: 'existsDestNation',
requires: (ctx) => requires: (ctx) =>
resolveDestNationId(ctx) !== undefined resolveDestNationId(ctx) !== undefined
? [ ? [
@@ -178,7 +178,7 @@ export const existsDestNation = (): Constraint => ({
}); });
export const differentDestNation = (): Constraint => ({ export const differentDestNation = (): Constraint => ({
name: 'DifferentDestNation', name: 'differentDestNation',
requires: (ctx) => { requires: (ctx) => {
const reqs: RequirementKey[] = []; const reqs: RequirementKey[] = [];
if (ctx.nationId !== undefined) { if (ctx.nationId !== undefined) {
@@ -217,7 +217,7 @@ export const differentDestNation = (): Constraint => ({
}); });
export const reqNationGeneralCount = (min: number): Constraint => ({ export const reqNationGeneralCount = (min: number): Constraint => ({
name: 'ReqNationGeneralCount', name: 'reqNationGeneralCount',
requires: (ctx) => { requires: (ctx) => {
const reqs: RequirementKey[] = [{ kind: 'generalList' }]; const reqs: RequirementKey[] = [{ kind: 'generalList' }];
if (ctx.nationId !== undefined) { if (ctx.nationId !== undefined) {
@@ -259,7 +259,7 @@ export const reqNationGeneralCount = (min: number): Constraint => ({
}); });
export const checkNationNameDuplicate = (name: string): Constraint => ({ export const checkNationNameDuplicate = (name: string): Constraint => ({
name: 'CheckNationNameDuplicate', name: 'checkNationNameDuplicate',
requires: () => [{ kind: 'nationList' }], requires: () => [{ kind: 'nationList' }],
test: (ctx, view) => { test: (ctx, view) => {
const nations = view.get({ kind: 'nationList' }) as Nation[] | null; const nations = view.get({ kind: 'nationList' }) as Nation[] | null;
+2 -2
View File
@@ -3,7 +3,7 @@ import { allow, unknownOrDeny } from './helpers.js';
import type { Constraint, RequirementKey } from './types.js'; import type { Constraint, RequirementKey } from './types.js';
export const mustBeTroopLeader = (): Constraint => ({ export const mustBeTroopLeader = (): Constraint => ({
name: 'MustBeTroopLeader', name: 'mustBeTroopLeader',
requires: (ctx) => [{ kind: 'general', id: ctx.actorId }], requires: (ctx) => [{ kind: 'general', id: ctx.actorId }],
test: (ctx, view) => { test: (ctx, view) => {
const generalReq: RequirementKey = { kind: 'general', id: ctx.actorId }; const generalReq: RequirementKey = { kind: 'general', id: ctx.actorId };
@@ -22,7 +22,7 @@ export const mustBeTroopLeader = (): Constraint => ({
}); });
export const reqTroopMembers = (): Constraint => ({ export const reqTroopMembers = (): Constraint => ({
name: 'ReqTroopMembers', name: 'reqTroopMembers',
requires: (ctx) => [{ kind: 'general', id: ctx.actorId }, { kind: 'generalList' }], requires: (ctx) => [{ kind: 'general', id: ctx.actorId }, { kind: 'generalList' }],
test: (ctx, view) => { test: (ctx, view) => {
const generalReq: RequirementKey = { kind: 'general', id: ctx.actorId }; const generalReq: RequirementKey = { kind: 'general', id: ctx.actorId };
+1 -1
View File
@@ -1,6 +1,6 @@
export type ConstraintResult = export type ConstraintResult =
| { kind: 'allow' } | { kind: 'allow' }
| { kind: 'deny'; reason: string; code?: string } | { kind: 'deny'; reason: string; code?: string; constraintName?: string }
| { kind: 'unknown'; missing: RequirementKey[] }; | { kind: 'unknown'; missing: RequirementKey[] };
export type RequirementKey = export type RequirementKey =