constraint 실패 후 실패 검사 결과 항목을 직접 반환.
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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,15 +109,15 @@ 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
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
kind: 'destCity',
|
kind: 'destCity',
|
||||||
id: resolveDestCityId(ctx) ?? 0,
|
id: resolveDestCityId(ctx) ?? 0,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
: [],
|
: [],
|
||||||
test: (ctx, view) => {
|
test: (ctx, view) => {
|
||||||
const destCity = readDestCity(ctx, view);
|
const destCity = readDestCity(ctx, view);
|
||||||
@@ -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,15 +245,15 @@ 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
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
kind: 'destCity',
|
kind: 'destCity',
|
||||||
id: resolveDestCityId(ctx) ?? 0,
|
id: resolveDestCityId(ctx) ?? 0,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
: [],
|
: [],
|
||||||
test: (ctx, view) => {
|
test: (ctx, view) => {
|
||||||
const destCityId = resolveDestCityId(ctx);
|
const destCityId = resolveDestCityId(ctx);
|
||||||
@@ -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,15 +311,15 @@ 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
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
kind: 'destCity',
|
kind: 'destCity',
|
||||||
id: resolveDestCityId(ctx) ?? 0,
|
id: resolveDestCityId(ctx) ?? 0,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
: [],
|
: [],
|
||||||
test: (ctx, view) => {
|
test: (ctx, view) => {
|
||||||
const destCity = readDestCity(ctx, view);
|
const destCity = readDestCity(ctx, view);
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ const readDiplomacyEntry = (
|
|||||||
typeof record.state === 'number'
|
typeof record.state === 'number'
|
||||||
? record.state
|
? record.state
|
||||||
: typeof record.stateCode === 'number'
|
: typeof record.stateCode === 'number'
|
||||||
? record.stateCode
|
? record.stateCode
|
||||||
: null;
|
: null;
|
||||||
const term = typeof record.term === 'number' ? record.term : null;
|
const term = typeof record.term === 'number' ? record.term : null;
|
||||||
return { state, term };
|
return { state, term };
|
||||||
}
|
}
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,15 +177,15 @@ 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
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
kind: 'destGeneral',
|
kind: 'destGeneral',
|
||||||
id: resolveDestGeneralId(ctx) ?? 0,
|
id: resolveDestGeneralId(ctx) ?? 0,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
: [],
|
: [],
|
||||||
test: (ctx, view) => {
|
test: (ctx, view) => {
|
||||||
const destGeneralId = resolveDestGeneralId(ctx);
|
const destGeneralId = resolveDestGeneralId(ctx);
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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' },
|
||||||
|
|||||||
@@ -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,15 +150,15 @@ 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
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
kind: 'destNation',
|
kind: 'destNation',
|
||||||
id: resolveDestNationId(ctx) ?? 0,
|
id: resolveDestNationId(ctx) ?? 0,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
: [],
|
: [],
|
||||||
test: (ctx, view) => {
|
test: (ctx, view) => {
|
||||||
const destNationId = resolveDestNationId(ctx);
|
const destNationId = resolveDestNationId(ctx);
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,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 =
|
||||||
|
|||||||
Reference in New Issue
Block a user