@alpaca-software/40kdc-data 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/author-input.d.ts +20 -1
- package/dist/author-input.d.ts.map +1 -1
- package/dist/author-input.js +64 -8
- package/dist/author-input.js.map +1 -1
- package/dist/author-seed.d.ts +62 -0
- package/dist/author-seed.d.ts.map +1 -0
- package/dist/author-seed.js +194 -0
- package/dist/author-seed.js.map +1 -0
- package/dist/codegen-data.js +2 -0
- package/dist/codegen-data.js.map +1 -1
- package/dist/commands/translate.d.ts.map +1 -1
- package/dist/commands/translate.js +6 -68
- package/dist/commands/translate.js.map +1 -1
- package/dist/data/bundle.generated.js +1 -1
- package/dist/data/bundle.generated.js.map +1 -1
- package/dist/data/dataset.d.ts +16 -1
- package/dist/data/dataset.d.ts.map +1 -1
- package/dist/data/dataset.js +25 -0
- package/dist/data/dataset.js.map +1 -1
- package/dist/data/index.d.ts +4 -0
- package/dist/data/index.d.ts.map +1 -1
- package/dist/data/index.js +4 -0
- package/dist/data/index.js.map +1 -1
- package/dist/data/types.d.ts +5 -1
- package/dist/data/types.d.ts.map +1 -1
- package/dist/data/types.js +2 -0
- package/dist/data/types.js.map +1 -1
- package/dist/gen-conformance.js +180 -1
- package/dist/gen-conformance.js.map +1 -1
- package/dist/generated.d.ts +309 -154
- package/dist/generated.d.ts.map +1 -1
- package/dist/generated.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/migrate-terrain.d.ts +2 -0
- package/dist/migrate-terrain.d.ts.map +1 -0
- package/dist/migrate-terrain.js +297 -0
- package/dist/migrate-terrain.js.map +1 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +42 -0
- package/dist/runner.js.map +1 -1
- package/dist/terrain/index.d.ts +11 -0
- package/dist/terrain/index.d.ts.map +1 -0
- package/dist/terrain/index.js +9 -0
- package/dist/terrain/index.js.map +1 -0
- package/dist/terrain/resolve.d.ts +122 -0
- package/dist/terrain/resolve.d.ts.map +1 -0
- package/dist/terrain/resolve.js +221 -0
- package/dist/terrain/resolve.js.map +1 -0
- package/dist/terrain/solve.d.ts +56 -0
- package/dist/terrain/solve.d.ts.map +1 -0
- package/dist/terrain/solve.js +80 -0
- package/dist/terrain/solve.js.map +1 -0
- package/dist/translate/condition.d.ts +26 -0
- package/dist/translate/condition.d.ts.map +1 -0
- package/dist/translate/condition.js +171 -0
- package/dist/translate/condition.js.map +1 -0
- package/dist/translate/index.d.ts +9 -0
- package/dist/translate/index.d.ts.map +1 -0
- package/dist/translate/index.js +9 -0
- package/dist/translate/index.js.map +1 -0
- package/dist/translate/scoring.d.ts +38 -0
- package/dist/translate/scoring.d.ts.map +1 -0
- package/dist/translate/scoring.js +80 -0
- package/dist/translate/scoring.js.map +1 -0
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +1 -0
- package/dist/validate.js.map +1 -1
- package/package.json +3 -1
- package/schemas/$defs/common.schema.json +43 -0
- package/schemas/core/secondary-card.schema.json +50 -28
- package/schemas/core/terrain-layout.schema.json +42 -56
- package/schemas/core/terrain-template.schema.json +105 -0
- package/schemas/enrichment/ability-dsl/condition.schema.json +5 -2
- package/schemas/enrichment/ability-dsl/effect.schema.json +2 -1
package/dist/generated.d.ts
CHANGED
|
@@ -85,6 +85,34 @@ export type BattleSize = "incursion" | "strike-force";
|
|
|
85
85
|
* via the `definition` "force-disposition-id".
|
|
86
86
|
*/
|
|
87
87
|
export type ForceDispositionId = "take-and-hold" | "disruption" | "purge-the-foe" | "priority-assets" | "reconnaissance";
|
|
88
|
+
/**
|
|
89
|
+
* A terrain piece's 2D footprint in local inches (y-down): an axis-aligned rectangle with its min corner at the local origin, a right triangle with the right angle at the local origin and legs along +x/+y, or an explicit polygon (>= 3 points). The placement resolver re-centers the footprint on its polygon area centroid, so the local-origin convention does not affect where the piece lands — only its shape matters.
|
|
90
|
+
*
|
|
91
|
+
* This interface was referenced by `0KdcBundledSchemas`'s JSON-Schema
|
|
92
|
+
* via the `definition` "footprint".
|
|
93
|
+
*/
|
|
94
|
+
export type Footprint = {
|
|
95
|
+
type: "rectangle";
|
|
96
|
+
width: number;
|
|
97
|
+
height: number;
|
|
98
|
+
} | {
|
|
99
|
+
type: "right-triangle";
|
|
100
|
+
width: number;
|
|
101
|
+
height: number;
|
|
102
|
+
} | {
|
|
103
|
+
type: "polygon";
|
|
104
|
+
/**
|
|
105
|
+
* @minItems 3
|
|
106
|
+
*/
|
|
107
|
+
points: [Vec2, Vec2, Vec2, ...Vec2[]];
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* An 11e terrain-area keyword. Confirmed launch set; extend as further keywords publish on dataslate.
|
|
111
|
+
*
|
|
112
|
+
* This interface was referenced by `0KdcBundledSchemas`'s JSON-Schema
|
|
113
|
+
* via the `definition` "terrain-area-keyword".
|
|
114
|
+
*/
|
|
115
|
+
export type TerrainAreaKeyword = "obscuring" | "hidden" | "plunging-fire";
|
|
88
116
|
/**
|
|
89
117
|
* A zone footprint, expressed as an axis-aligned rectangle or an explicit polygon. Vertices/extent are relative to the owning element's position.
|
|
90
118
|
*
|
|
@@ -123,68 +151,43 @@ export type ConditionNode = SimpleCondition | CompoundCondition;
|
|
|
123
151
|
*/
|
|
124
152
|
export type AbilityCondition1 = SimpleCondition | CompoundCondition;
|
|
125
153
|
/**
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
* This interface was referenced by `0KdcBundledSchemas`'s JSON-Schema
|
|
129
|
-
* via the `definition` "footprint".
|
|
154
|
+
* Effect applied when the action completes (e.g. terrain-area-tag, objective-tag, or unit-tag to mark transient state).
|
|
130
155
|
*/
|
|
131
|
-
export type
|
|
132
|
-
type: "rectangle";
|
|
133
|
-
width: number;
|
|
134
|
-
height: number;
|
|
135
|
-
} | {
|
|
136
|
-
type: "right-triangle";
|
|
137
|
-
width: number;
|
|
138
|
-
height: number;
|
|
139
|
-
} | {
|
|
140
|
-
type: "polygon";
|
|
141
|
-
/**
|
|
142
|
-
* @minItems 3
|
|
143
|
-
*/
|
|
144
|
-
points: [Vec2, Vec2, Vec2, ...Vec2[]];
|
|
145
|
-
};
|
|
146
|
-
/**
|
|
147
|
-
* An 11e terrain-area keyword. Confirmed launch set; extend as further keywords publish on dataslate.
|
|
148
|
-
*
|
|
149
|
-
* This interface was referenced by `0KdcBundledSchemas`'s JSON-Schema
|
|
150
|
-
* via the `definition` "terrain-area-keyword".
|
|
151
|
-
*/
|
|
152
|
-
export type TerrainAreaKeyword = "obscuring" | "hidden" | "plunging-fire";
|
|
153
|
-
export type AbilityEffect1 = SingleEffect | ChoiceEffect | SequenceEffect | DiceGatedEffect | ConditionalEffect | DicePoolAllocationEffect;
|
|
156
|
+
export type AbilityEffect = SingleEffect | ChoiceEffect | SequenceEffect | DiceGatedEffect | ConditionalEffect | DicePoolAllocationEffect;
|
|
154
157
|
/**
|
|
155
158
|
* This interface was referenced by `0KdcBundledSchemas`'s JSON-Schema
|
|
156
159
|
* via the `definition` "single-effect".
|
|
157
160
|
*/
|
|
158
161
|
export type SingleEffect = unknown & {
|
|
159
|
-
type: "stat-modifier" | "roll-modifier" | "re-roll" | "mortal-wounds" | "feel-no-pain" | "invulnerable-save" | "ward" | "keyword-grant" | "movement-modifier" | "deep-strike" | "fallback-and-act" | "fight-first" | "fight-last" | "shoot-on-death" | "fight-on-death" | "objective-control-modifier" | "leadership-modifier" | "damage-reduction" | "attack-restriction" | "ability-grant" | "cp-gain" | "cp-refund" | "model-destruction" | "resurrection" | "resource-gain" | "resource-spend" | "charge-roll-modifier" | "terrain-area-tag" | "bs-modifier" | "engagement-passthrough";
|
|
162
|
+
type: "stat-modifier" | "roll-modifier" | "re-roll" | "mortal-wounds" | "feel-no-pain" | "invulnerable-save" | "ward" | "keyword-grant" | "movement-modifier" | "deep-strike" | "fallback-and-act" | "fight-first" | "fight-last" | "shoot-on-death" | "fight-on-death" | "objective-control-modifier" | "leadership-modifier" | "damage-reduction" | "attack-restriction" | "ability-grant" | "cp-gain" | "cp-refund" | "model-destruction" | "resurrection" | "resource-gain" | "resource-spend" | "charge-roll-modifier" | "terrain-area-tag" | "objective-tag" | "unit-tag" | "bs-modifier" | "engagement-passthrough";
|
|
160
163
|
target: "self" | "bearer" | "unit" | "attached-unit" | "attacker" | "defender" | "friendly-within-aura" | "enemy-within-aura" | "all-friendly" | "all-enemy";
|
|
161
164
|
modifier?: {
|
|
162
165
|
[k: string]: unknown;
|
|
163
166
|
};
|
|
164
167
|
[k: string]: unknown;
|
|
165
168
|
} & {
|
|
166
|
-
type: "stat-modifier" | "roll-modifier" | "re-roll" | "mortal-wounds" | "feel-no-pain" | "invulnerable-save" | "ward" | "keyword-grant" | "movement-modifier" | "deep-strike" | "fallback-and-act" | "fight-first" | "fight-last" | "shoot-on-death" | "fight-on-death" | "objective-control-modifier" | "leadership-modifier" | "damage-reduction" | "attack-restriction" | "ability-grant" | "cp-gain" | "cp-refund" | "model-destruction" | "resurrection" | "resource-gain" | "resource-spend" | "charge-roll-modifier" | "terrain-area-tag" | "bs-modifier" | "engagement-passthrough";
|
|
169
|
+
type: "stat-modifier" | "roll-modifier" | "re-roll" | "mortal-wounds" | "feel-no-pain" | "invulnerable-save" | "ward" | "keyword-grant" | "movement-modifier" | "deep-strike" | "fallback-and-act" | "fight-first" | "fight-last" | "shoot-on-death" | "fight-on-death" | "objective-control-modifier" | "leadership-modifier" | "damage-reduction" | "attack-restriction" | "ability-grant" | "cp-gain" | "cp-refund" | "model-destruction" | "resurrection" | "resource-gain" | "resource-spend" | "charge-roll-modifier" | "terrain-area-tag" | "objective-tag" | "unit-tag" | "bs-modifier" | "engagement-passthrough";
|
|
167
170
|
target: "self" | "bearer" | "unit" | "attached-unit" | "attacker" | "defender" | "friendly-within-aura" | "enemy-within-aura" | "all-friendly" | "all-enemy";
|
|
168
171
|
modifier?: {
|
|
169
172
|
[k: string]: unknown;
|
|
170
173
|
};
|
|
171
174
|
[k: string]: unknown;
|
|
172
175
|
} & {
|
|
173
|
-
type: "stat-modifier" | "roll-modifier" | "re-roll" | "mortal-wounds" | "feel-no-pain" | "invulnerable-save" | "ward" | "keyword-grant" | "movement-modifier" | "deep-strike" | "fallback-and-act" | "fight-first" | "fight-last" | "shoot-on-death" | "fight-on-death" | "objective-control-modifier" | "leadership-modifier" | "damage-reduction" | "attack-restriction" | "ability-grant" | "cp-gain" | "cp-refund" | "model-destruction" | "resurrection" | "resource-gain" | "resource-spend" | "charge-roll-modifier" | "terrain-area-tag" | "bs-modifier" | "engagement-passthrough";
|
|
176
|
+
type: "stat-modifier" | "roll-modifier" | "re-roll" | "mortal-wounds" | "feel-no-pain" | "invulnerable-save" | "ward" | "keyword-grant" | "movement-modifier" | "deep-strike" | "fallback-and-act" | "fight-first" | "fight-last" | "shoot-on-death" | "fight-on-death" | "objective-control-modifier" | "leadership-modifier" | "damage-reduction" | "attack-restriction" | "ability-grant" | "cp-gain" | "cp-refund" | "model-destruction" | "resurrection" | "resource-gain" | "resource-spend" | "charge-roll-modifier" | "terrain-area-tag" | "objective-tag" | "unit-tag" | "bs-modifier" | "engagement-passthrough";
|
|
174
177
|
target: "self" | "bearer" | "unit" | "attached-unit" | "attacker" | "defender" | "friendly-within-aura" | "enemy-within-aura" | "all-friendly" | "all-enemy";
|
|
175
178
|
modifier?: {
|
|
176
179
|
[k: string]: unknown;
|
|
177
180
|
};
|
|
178
181
|
[k: string]: unknown;
|
|
179
182
|
} & {
|
|
180
|
-
type: "stat-modifier" | "roll-modifier" | "re-roll" | "mortal-wounds" | "feel-no-pain" | "invulnerable-save" | "ward" | "keyword-grant" | "movement-modifier" | "deep-strike" | "fallback-and-act" | "fight-first" | "fight-last" | "shoot-on-death" | "fight-on-death" | "objective-control-modifier" | "leadership-modifier" | "damage-reduction" | "attack-restriction" | "ability-grant" | "cp-gain" | "cp-refund" | "model-destruction" | "resurrection" | "resource-gain" | "resource-spend" | "charge-roll-modifier" | "terrain-area-tag" | "bs-modifier" | "engagement-passthrough";
|
|
183
|
+
type: "stat-modifier" | "roll-modifier" | "re-roll" | "mortal-wounds" | "feel-no-pain" | "invulnerable-save" | "ward" | "keyword-grant" | "movement-modifier" | "deep-strike" | "fallback-and-act" | "fight-first" | "fight-last" | "shoot-on-death" | "fight-on-death" | "objective-control-modifier" | "leadership-modifier" | "damage-reduction" | "attack-restriction" | "ability-grant" | "cp-gain" | "cp-refund" | "model-destruction" | "resurrection" | "resource-gain" | "resource-spend" | "charge-roll-modifier" | "terrain-area-tag" | "objective-tag" | "unit-tag" | "bs-modifier" | "engagement-passthrough";
|
|
181
184
|
target: "self" | "bearer" | "unit" | "attached-unit" | "attacker" | "defender" | "friendly-within-aura" | "enemy-within-aura" | "all-friendly" | "all-enemy";
|
|
182
185
|
modifier?: {
|
|
183
186
|
[k: string]: unknown;
|
|
184
187
|
};
|
|
185
188
|
[k: string]: unknown;
|
|
186
189
|
} & {
|
|
187
|
-
type: "stat-modifier" | "roll-modifier" | "re-roll" | "mortal-wounds" | "feel-no-pain" | "invulnerable-save" | "ward" | "keyword-grant" | "movement-modifier" | "deep-strike" | "fallback-and-act" | "fight-first" | "fight-last" | "shoot-on-death" | "fight-on-death" | "objective-control-modifier" | "leadership-modifier" | "damage-reduction" | "attack-restriction" | "ability-grant" | "cp-gain" | "cp-refund" | "model-destruction" | "resurrection" | "resource-gain" | "resource-spend" | "charge-roll-modifier" | "terrain-area-tag" | "bs-modifier" | "engagement-passthrough";
|
|
190
|
+
type: "stat-modifier" | "roll-modifier" | "re-roll" | "mortal-wounds" | "feel-no-pain" | "invulnerable-save" | "ward" | "keyword-grant" | "movement-modifier" | "deep-strike" | "fallback-and-act" | "fight-first" | "fight-last" | "shoot-on-death" | "fight-on-death" | "objective-control-modifier" | "leadership-modifier" | "damage-reduction" | "attack-restriction" | "ability-grant" | "cp-gain" | "cp-refund" | "model-destruction" | "resurrection" | "resource-gain" | "resource-spend" | "charge-roll-modifier" | "terrain-area-tag" | "objective-tag" | "unit-tag" | "bs-modifier" | "engagement-passthrough";
|
|
188
191
|
target: "self" | "bearer" | "unit" | "attached-unit" | "attacker" | "defender" | "friendly-within-aura" | "enemy-within-aura" | "all-friendly" | "all-enemy";
|
|
189
192
|
modifier?: {
|
|
190
193
|
[k: string]: unknown;
|
|
@@ -197,6 +200,7 @@ export type SingleEffect = unknown & {
|
|
|
197
200
|
*/
|
|
198
201
|
export type EffectNode = SingleEffect | ChoiceEffect | SequenceEffect | DiceGatedEffect | ConditionalEffect | DicePoolAllocationEffect;
|
|
199
202
|
export type AbilityCondition2 = SimpleCondition | CompoundCondition;
|
|
203
|
+
export type AbilityEffect1 = unknown | ChoiceEffect | SequenceEffect | DiceGatedEffect | ConditionalEffect | DicePoolAllocationEffect;
|
|
200
204
|
/**
|
|
201
205
|
* This interface was referenced by `0KdcBundledSchemas`'s JSON-Schema
|
|
202
206
|
* via the `definition` "condition".
|
|
@@ -519,24 +523,58 @@ export interface SecondaryCard {
|
|
|
519
523
|
condition?: ArmyCompositionPredicate1;
|
|
520
524
|
};
|
|
521
525
|
/**
|
|
522
|
-
* Optional player
|
|
526
|
+
* Optional player actions the card enables. Most cards have a single action; a few (e.g. Observe Enemy, with separate Baited-removal and Spotted actions) have two distinct actions on the same card.
|
|
527
|
+
*
|
|
528
|
+
* @minItems 1
|
|
523
529
|
*/
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
530
|
+
actions?: [
|
|
531
|
+
{
|
|
532
|
+
/**
|
|
533
|
+
* Optional kebab-case identifier used to reference this action from `action-completed` conditions in `awards[].when`.
|
|
534
|
+
*/
|
|
535
|
+
action_id?: string;
|
|
536
|
+
/**
|
|
537
|
+
* The five official game phases. Unchanged between 10th and 11th edition — 11e reorders Pile In timing within the Fight phase but adds no top-level phase.
|
|
538
|
+
*/
|
|
539
|
+
starts?: "command" | "movement" | "shooting" | "charge" | "fight";
|
|
540
|
+
player_turn?: PlayerTurn;
|
|
541
|
+
units?: AbilityCondition;
|
|
542
|
+
/**
|
|
543
|
+
* Maximum number of times the action may be performed (per turn unless `use_limit_scope` says otherwise).
|
|
544
|
+
*/
|
|
545
|
+
use_limit?: number;
|
|
546
|
+
/**
|
|
547
|
+
* Whether `use_limit` is enforced per turn or once per game (e.g. Recover the Relics / Find and Deny 'Overwhelming Force' is once per game).
|
|
548
|
+
*/
|
|
549
|
+
use_limit_scope?: "per-turn" | "per-game";
|
|
550
|
+
completes?: AbilityCondition1;
|
|
551
|
+
effect?: AbilityEffect;
|
|
552
|
+
},
|
|
553
|
+
...{
|
|
554
|
+
/**
|
|
555
|
+
* Optional kebab-case identifier used to reference this action from `action-completed` conditions in `awards[].when`.
|
|
556
|
+
*/
|
|
557
|
+
action_id?: string;
|
|
558
|
+
/**
|
|
559
|
+
* The five official game phases. Unchanged between 10th and 11th edition — 11e reorders Pile In timing within the Fight phase but adds no top-level phase.
|
|
560
|
+
*/
|
|
561
|
+
starts?: "command" | "movement" | "shooting" | "charge" | "fight";
|
|
562
|
+
player_turn?: PlayerTurn;
|
|
563
|
+
units?: AbilityCondition;
|
|
564
|
+
/**
|
|
565
|
+
* Maximum number of times the action may be performed (per turn unless `use_limit_scope` says otherwise).
|
|
566
|
+
*/
|
|
567
|
+
use_limit?: number;
|
|
568
|
+
/**
|
|
569
|
+
* Whether `use_limit` is enforced per turn or once per game (e.g. Recover the Relics / Find and Deny 'Overwhelming Force' is once per game).
|
|
570
|
+
*/
|
|
571
|
+
use_limit_scope?: "per-turn" | "per-game";
|
|
572
|
+
completes?: AbilityCondition1;
|
|
573
|
+
effect?: AbilityEffect;
|
|
574
|
+
}[]
|
|
575
|
+
];
|
|
538
576
|
/**
|
|
539
|
-
* VP-award blocks: each scores when `trigger` fires and the optional `when` condition holds. An award scores either a flat `vp` or a count-scaled `vp_per` (VP per instance of the thing named by `per`). Awards accrue independently and sum; a card's '+ ... CUMULATIVE' rows are modelled as separate awards flagged `cumulative` for faithful round-trip.
|
|
577
|
+
* VP-award blocks: each scores when `trigger` fires and the optional `when` condition holds. An award scores either a flat `vp` or a count-scaled `vp_per` (VP per instance of the thing named by `per`). Awards accrue independently and sum; a card's '+ ... CUMULATIVE' rows are modelled as separate awards flagged `cumulative` for faithful round-trip. Awards sharing the same `exclusive_group` value within a card resolve as the highest-scoring single award fires (the card's literal 'OR' rows between tier breakpoints, e.g. Record-Breaking Mission's 3-Fronts vs 4-Fronts).
|
|
540
578
|
*
|
|
541
579
|
* @minItems 1
|
|
542
580
|
*/
|
|
@@ -585,7 +623,7 @@ export interface ArmyCompositionPredicate1 {
|
|
|
585
623
|
* via the `definition` "simple-condition".
|
|
586
624
|
*/
|
|
587
625
|
export interface SimpleCondition {
|
|
588
|
-
type: "phase-is" | "timing-is" | "player-turn-is" | "unit-below-starting-strength" | "unit-below-half-strength" | "unit-has-keyword" | "unit-within-range-of" | "model-is-leader" | "target-has-keyword" | "charged-this-turn" | "advanced-this-turn" | "remained-stationary" | "is-battle-shocked" | "has-lost-wounds" | "opponent-unit-within-range" | "within-range-of-objective" | "attack-is-type" | "has-fought-this-phase" | "destroyed-by-attack-type" | "controls-objective" | "is-attached" | "terrain-area-control" | "engagement-state" | "territory-control" | "fights-first" | "disposition-matches" | "units-destroyed" | "units-destroyed-comparison" | "objective-majority";
|
|
626
|
+
type: "phase-is" | "timing-is" | "player-turn-is" | "unit-below-starting-strength" | "unit-below-half-strength" | "unit-has-keyword" | "unit-within-range-of" | "model-is-leader" | "target-has-keyword" | "charged-this-turn" | "advanced-this-turn" | "remained-stationary" | "is-battle-shocked" | "has-lost-wounds" | "opponent-unit-within-range" | "within-range-of-objective" | "attack-is-type" | "has-fought-this-phase" | "destroyed-by-attack-type" | "controls-objective" | "is-attached" | "terrain-area-control" | "engagement-state" | "territory-control" | "fights-first" | "disposition-matches" | "units-destroyed" | "units-destroyed-comparison" | "objective-majority" | "action-completed" | "objective-has-tag" | "unit-has-tag" | "terrain-has-tag" | "new-objective-controlled" | "engagement-fronts" | "destroyed-while-on-objective";
|
|
589
627
|
parameters?: {
|
|
590
628
|
[k: string]: unknown;
|
|
591
629
|
};
|
|
@@ -604,6 +642,99 @@ export interface CompoundCondition {
|
|
|
604
642
|
operands: [ConditionNode, ...ConditionNode[]];
|
|
605
643
|
[k: string]: unknown;
|
|
606
644
|
}
|
|
645
|
+
/**
|
|
646
|
+
* This interface was referenced by `0KdcBundledSchemas`'s JSON-Schema
|
|
647
|
+
* via the `definition` "choice-effect".
|
|
648
|
+
*/
|
|
649
|
+
export interface ChoiceEffect {
|
|
650
|
+
type: "choice";
|
|
651
|
+
/**
|
|
652
|
+
* @minItems 2
|
|
653
|
+
*/
|
|
654
|
+
options: [EffectNode, EffectNode, ...EffectNode[]];
|
|
655
|
+
choice_label?: string;
|
|
656
|
+
[k: string]: unknown;
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* This interface was referenced by `0KdcBundledSchemas`'s JSON-Schema
|
|
660
|
+
* via the `definition` "sequence-effect".
|
|
661
|
+
*/
|
|
662
|
+
export interface SequenceEffect {
|
|
663
|
+
type: "sequence";
|
|
664
|
+
/**
|
|
665
|
+
* @minItems 1
|
|
666
|
+
*/
|
|
667
|
+
steps: [EffectNode, ...EffectNode[]];
|
|
668
|
+
[k: string]: unknown;
|
|
669
|
+
}
|
|
670
|
+
/**
|
|
671
|
+
* This interface was referenced by `0KdcBundledSchemas`'s JSON-Schema
|
|
672
|
+
* via the `definition` "dice-gated-effect".
|
|
673
|
+
*/
|
|
674
|
+
export interface DiceGatedEffect {
|
|
675
|
+
type: "dice-gated";
|
|
676
|
+
/**
|
|
677
|
+
* Dice expression, e.g. 'D6', '2D6'
|
|
678
|
+
*/
|
|
679
|
+
dice: string;
|
|
680
|
+
/**
|
|
681
|
+
* Fixed threshold or model characteristic to compare against
|
|
682
|
+
*/
|
|
683
|
+
threshold: number | ("leadership" | "toughness" | "save");
|
|
684
|
+
comparison?: "gte" | "lte" | "gt" | "lt" | "eq";
|
|
685
|
+
on_success?: EffectNode | null;
|
|
686
|
+
on_fail?: EffectNode | null;
|
|
687
|
+
[k: string]: unknown;
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* This interface was referenced by `0KdcBundledSchemas`'s JSON-Schema
|
|
691
|
+
* via the `definition` "conditional-effect".
|
|
692
|
+
*/
|
|
693
|
+
export interface ConditionalEffect {
|
|
694
|
+
type: "conditional";
|
|
695
|
+
condition: AbilityCondition2;
|
|
696
|
+
effect: EffectNode;
|
|
697
|
+
[k: string]: unknown;
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* This interface was referenced by `0KdcBundledSchemas`'s JSON-Schema
|
|
701
|
+
* via the `definition` "dice-pool-allocation-effect".
|
|
702
|
+
*/
|
|
703
|
+
export interface DicePoolAllocationEffect {
|
|
704
|
+
type: "dice-pool-allocation";
|
|
705
|
+
pool: {
|
|
706
|
+
count: number;
|
|
707
|
+
die: string;
|
|
708
|
+
[k: string]: unknown;
|
|
709
|
+
};
|
|
710
|
+
max_activations: number;
|
|
711
|
+
/**
|
|
712
|
+
* @minItems 1
|
|
713
|
+
*/
|
|
714
|
+
options: [
|
|
715
|
+
{
|
|
716
|
+
name: string;
|
|
717
|
+
requirement: {
|
|
718
|
+
type: "pair" | "triple" | "single" | "run";
|
|
719
|
+
min_value: number;
|
|
720
|
+
[k: string]: unknown;
|
|
721
|
+
};
|
|
722
|
+
effect: EffectNode;
|
|
723
|
+
[k: string]: unknown;
|
|
724
|
+
},
|
|
725
|
+
...{
|
|
726
|
+
name: string;
|
|
727
|
+
requirement: {
|
|
728
|
+
type: "pair" | "triple" | "single" | "run";
|
|
729
|
+
min_value: number;
|
|
730
|
+
[k: string]: unknown;
|
|
731
|
+
};
|
|
732
|
+
effect: EffectNode;
|
|
733
|
+
[k: string]: unknown;
|
|
734
|
+
}[]
|
|
735
|
+
];
|
|
736
|
+
[k: string]: unknown;
|
|
737
|
+
}
|
|
607
738
|
/**
|
|
608
739
|
* A CP-costed ability usable during specific game phases.
|
|
609
740
|
*
|
|
@@ -638,29 +769,66 @@ export interface Stratagem {
|
|
|
638
769
|
game_version: GameVersionReference;
|
|
639
770
|
}
|
|
640
771
|
/**
|
|
641
|
-
* One terrain
|
|
772
|
+
* One terrain piece placed on the board. Geometry comes from a catalog `template` or an inline `footprint` (if both are present, `footprint` is authoritative and `template` is provenance).
|
|
642
773
|
*
|
|
643
774
|
* This interface was referenced by `0KdcBundledSchemas`'s JSON-Schema
|
|
644
775
|
* via the `definition` "piece".
|
|
645
776
|
*/
|
|
646
777
|
export interface Piece {
|
|
778
|
+
/**
|
|
779
|
+
* Kebab-case identifier
|
|
780
|
+
*/
|
|
781
|
+
id?: string;
|
|
647
782
|
name?: string;
|
|
648
|
-
|
|
783
|
+
/**
|
|
784
|
+
* An `area` is a gameplay terrain zone (the 11e 'terrain area'); a `feature` is physical scenery (walls, containers, pipes) placed on an area.
|
|
785
|
+
*/
|
|
786
|
+
piece_type?: "area" | "feature";
|
|
787
|
+
/**
|
|
788
|
+
* Kebab-case identifier
|
|
789
|
+
*/
|
|
790
|
+
template?: string;
|
|
791
|
+
/**
|
|
792
|
+
* Inline geometry, standing in for or overriding a template footprint. Authoritative when present.
|
|
793
|
+
*/
|
|
794
|
+
footprint?: {
|
|
795
|
+
type: "rectangle";
|
|
796
|
+
width: number;
|
|
797
|
+
height: number;
|
|
798
|
+
} | {
|
|
799
|
+
type: "right-triangle";
|
|
800
|
+
width: number;
|
|
801
|
+
height: number;
|
|
802
|
+
} | {
|
|
803
|
+
type: "polygon";
|
|
804
|
+
/**
|
|
805
|
+
* @minItems 3
|
|
806
|
+
*/
|
|
807
|
+
points: [Vec2, Vec2, Vec2, ...Vec2[]];
|
|
808
|
+
};
|
|
649
809
|
position: Vec21;
|
|
650
810
|
/**
|
|
651
|
-
* Clockwise rotation
|
|
811
|
+
* Clockwise rotation about the centroid in the y-down board frame. Absent or 0 means the template's natural orientation.
|
|
652
812
|
*/
|
|
653
813
|
rotation_degrees?: number;
|
|
654
814
|
/**
|
|
655
|
-
*
|
|
815
|
+
* Reflection applied in the centroid-local frame before rotation: `horizontal` negates local x (left-right flip), `vertical` negates local y.
|
|
656
816
|
*/
|
|
657
|
-
|
|
817
|
+
mirror?: "none" | "horizontal" | "vertical";
|
|
658
818
|
/**
|
|
659
|
-
*
|
|
819
|
+
* Kebab-case identifier
|
|
820
|
+
*/
|
|
821
|
+
parent_area_id?: string;
|
|
822
|
+
/**
|
|
823
|
+
* Ruin floor this piece occupies (0 = ground level).
|
|
824
|
+
*/
|
|
825
|
+
floor?: number;
|
|
826
|
+
/**
|
|
827
|
+
* Height of the piece in inches; overrides the template default. Gates Plunging Fire (a piece 3" or taller confers +1 BS on ground-level targets).
|
|
660
828
|
*/
|
|
661
829
|
height_inches?: number;
|
|
662
830
|
/**
|
|
663
|
-
* Terrain-area keywords this piece's area carries.
|
|
831
|
+
* Terrain-area keywords this piece's area carries; overrides the template default.
|
|
664
832
|
*/
|
|
665
833
|
terrain_area_keywords?: TerrainAreaKeyword[];
|
|
666
834
|
/**
|
|
@@ -697,7 +865,7 @@ export interface Vec22 {
|
|
|
697
865
|
y: number;
|
|
698
866
|
}
|
|
699
867
|
/**
|
|
700
|
-
* A recommended arrangement of terrain pieces on the board, independent of the deployment map (a deployment-pattern references the layouts it recommends via recommended_terrain_layout_ids).
|
|
868
|
+
* A recommended arrangement of terrain pieces on the board, independent of the deployment map (a deployment-pattern references the layouts it recommends via recommended_terrain_layout_ids). Each piece draws its geometry from a catalog `template` (a terrain-template entity) or an inline `footprint`; geometry is the source of truth. Placement is template-centroid-anchored: `position` is the piece's centroid, which is invariant under rotation and mirror, so orientation and location are decoupled. Resolved board-space vertices are derived by the shared terrain resolver (pinned by the conformance corpus), never stored here. No layout data is authored yet beyond migrated examples.
|
|
701
869
|
*
|
|
702
870
|
* This interface was referenced by `0KdcBundledSchemas`'s JSON-Schema
|
|
703
871
|
* via the `definition` "terrain-layout".
|
|
@@ -716,6 +884,89 @@ export interface TerrainLayout {
|
|
|
716
884
|
pieces?: Piece[];
|
|
717
885
|
game_version: GameVersionReference;
|
|
718
886
|
}
|
|
887
|
+
/**
|
|
888
|
+
* A feature placed on an area template, positioned in the area's centroid-local frame (y-down inches). When the area is placed, rotated, or mirrored, its composed features are carried along.
|
|
889
|
+
*
|
|
890
|
+
* This interface was referenced by `0KdcBundledSchemas`'s JSON-Schema
|
|
891
|
+
* via the `definition` "composed-feature".
|
|
892
|
+
*/
|
|
893
|
+
export interface ComposedFeature {
|
|
894
|
+
/**
|
|
895
|
+
* Kebab-case identifier
|
|
896
|
+
*/
|
|
897
|
+
id?: string;
|
|
898
|
+
/**
|
|
899
|
+
* Kebab-case identifier
|
|
900
|
+
*/
|
|
901
|
+
template: string;
|
|
902
|
+
position: Vec23;
|
|
903
|
+
/**
|
|
904
|
+
* Clockwise rotation of the feature about its own centroid, within the area-local frame.
|
|
905
|
+
*/
|
|
906
|
+
rotation_degrees?: number;
|
|
907
|
+
mirror?: "none" | "horizontal" | "vertical";
|
|
908
|
+
/**
|
|
909
|
+
* Ruin floor this feature occupies (0 = ground level).
|
|
910
|
+
*/
|
|
911
|
+
floor?: number;
|
|
912
|
+
}
|
|
913
|
+
/**
|
|
914
|
+
* A 2D point in board inches. Origin at a board corner; JSON uses y-down (downstream renderers may flip to y-up).
|
|
915
|
+
*/
|
|
916
|
+
export interface Vec23 {
|
|
917
|
+
x: number;
|
|
918
|
+
y: number;
|
|
919
|
+
}
|
|
920
|
+
/**
|
|
921
|
+
* A reusable terrain piece in the standard catalog: a gameplay area (the 11e terrain-area templates) or a scenery feature (walls, containers, pipes, floor segments). Footprints are authored in natural local inches; the terrain resolver derives each footprint's polygon area centroid and re-centers on it, so a layout piece that instances a template places its centroid via the layout's `position`. An `area` template may carry an embedded `features` list — scenery placed in the area's centroid-local frame — making the template a reusable composition (e.g. a ruin with its walls). Placing such a template places all of its features, transformed by the area's own placement.
|
|
922
|
+
*
|
|
923
|
+
* This interface was referenced by `0KdcBundledSchemas`'s JSON-Schema
|
|
924
|
+
* via the `definition` "terrain-template".
|
|
925
|
+
*/
|
|
926
|
+
export interface TerrainTemplate {
|
|
927
|
+
id: EntityId;
|
|
928
|
+
name: string;
|
|
929
|
+
/**
|
|
930
|
+
* `area` = a gameplay terrain zone; `feature` = physical scenery placed on an area.
|
|
931
|
+
*/
|
|
932
|
+
kind: "area" | "feature";
|
|
933
|
+
/**
|
|
934
|
+
* Catalog or mission pack the template originates from.
|
|
935
|
+
*/
|
|
936
|
+
source?: string;
|
|
937
|
+
footprint: Footprint;
|
|
938
|
+
/**
|
|
939
|
+
* Default height in inches for pieces instancing this template. Gates Plunging Fire (>= 3").
|
|
940
|
+
*/
|
|
941
|
+
default_height_inches?: number;
|
|
942
|
+
/**
|
|
943
|
+
* Whether the template blocks line of sight / movement by default.
|
|
944
|
+
*/
|
|
945
|
+
default_blocking?: boolean;
|
|
946
|
+
/**
|
|
947
|
+
* Whether models may be placed on the ground footprint. `false` marks an elevated-only piece (a platform reachable only on its `upper_floor`, e.g. a gantry/catwalk) or a solid obstacle with no valid placement (e.g. a generator). Meaningful for `kind: "feature"`.
|
|
948
|
+
*/
|
|
949
|
+
ground_accessible?: boolean;
|
|
950
|
+
/**
|
|
951
|
+
* An elevated platform carried by this feature (e.g. a ruin's second storey). Its footprint is authored in the SAME local frame as `footprint` and re-centered on the GROUND footprint's polygon area centroid, so the two floors stay registered when the piece is placed, rotated, or mirrored. Non-resolved metadata: the terrain resolver does not emit it; authoring/visualization tools render it as an overlay. Meaningful for `kind: "feature"`.
|
|
952
|
+
*/
|
|
953
|
+
upper_floor?: {
|
|
954
|
+
footprint: Footprint;
|
|
955
|
+
/**
|
|
956
|
+
* Ruin floor this platform occupies (1 = first floor above ground).
|
|
957
|
+
*/
|
|
958
|
+
floor?: number;
|
|
959
|
+
};
|
|
960
|
+
/**
|
|
961
|
+
* Terrain-area keywords areas of this template carry by default. Meaningful for `kind: "area"`.
|
|
962
|
+
*/
|
|
963
|
+
default_terrain_area_keywords?: TerrainAreaKeyword[];
|
|
964
|
+
/**
|
|
965
|
+
* Composed scenery features, in the area's centroid-local frame. Only meaningful for `kind: "area"`.
|
|
966
|
+
*/
|
|
967
|
+
features?: ComposedFeature[];
|
|
968
|
+
game_version: GameVersionReference;
|
|
969
|
+
}
|
|
719
970
|
/**
|
|
720
971
|
* Describes the internal model-type breakdown of a unit.
|
|
721
972
|
*
|
|
@@ -880,105 +1131,9 @@ export interface WeaponKeyword {
|
|
|
880
1131
|
"value" | "target_keyword" | "threshold",
|
|
881
1132
|
"value" | "target_keyword" | "threshold"
|
|
882
1133
|
];
|
|
883
|
-
|
|
884
|
-
* Mechanical effect of this keyword. Null when the behaviour is faction-specific flavour not yet expressible in the DSL — engines treat such references as no-op buffs and may surface them as 'cannot auto-apply'.
|
|
885
|
-
*/
|
|
886
|
-
effect: AbilityEffect1 | null;
|
|
1134
|
+
effect: unknown;
|
|
887
1135
|
game_version: GameVersionReference;
|
|
888
1136
|
}
|
|
889
|
-
/**
|
|
890
|
-
* This interface was referenced by `0KdcBundledSchemas`'s JSON-Schema
|
|
891
|
-
* via the `definition` "choice-effect".
|
|
892
|
-
*/
|
|
893
|
-
export interface ChoiceEffect {
|
|
894
|
-
type: "choice";
|
|
895
|
-
/**
|
|
896
|
-
* @minItems 2
|
|
897
|
-
*/
|
|
898
|
-
options: [EffectNode, EffectNode, ...EffectNode[]];
|
|
899
|
-
choice_label?: string;
|
|
900
|
-
[k: string]: unknown;
|
|
901
|
-
}
|
|
902
|
-
/**
|
|
903
|
-
* This interface was referenced by `0KdcBundledSchemas`'s JSON-Schema
|
|
904
|
-
* via the `definition` "sequence-effect".
|
|
905
|
-
*/
|
|
906
|
-
export interface SequenceEffect {
|
|
907
|
-
type: "sequence";
|
|
908
|
-
/**
|
|
909
|
-
* @minItems 1
|
|
910
|
-
*/
|
|
911
|
-
steps: [EffectNode, ...EffectNode[]];
|
|
912
|
-
[k: string]: unknown;
|
|
913
|
-
}
|
|
914
|
-
/**
|
|
915
|
-
* This interface was referenced by `0KdcBundledSchemas`'s JSON-Schema
|
|
916
|
-
* via the `definition` "dice-gated-effect".
|
|
917
|
-
*/
|
|
918
|
-
export interface DiceGatedEffect {
|
|
919
|
-
type: "dice-gated";
|
|
920
|
-
/**
|
|
921
|
-
* Dice expression, e.g. 'D6', '2D6'
|
|
922
|
-
*/
|
|
923
|
-
dice: string;
|
|
924
|
-
/**
|
|
925
|
-
* Fixed threshold or model characteristic to compare against
|
|
926
|
-
*/
|
|
927
|
-
threshold: number | ("leadership" | "toughness" | "save");
|
|
928
|
-
comparison?: "gte" | "lte" | "gt" | "lt" | "eq";
|
|
929
|
-
on_success?: EffectNode | null;
|
|
930
|
-
on_fail?: EffectNode | null;
|
|
931
|
-
[k: string]: unknown;
|
|
932
|
-
}
|
|
933
|
-
/**
|
|
934
|
-
* This interface was referenced by `0KdcBundledSchemas`'s JSON-Schema
|
|
935
|
-
* via the `definition` "conditional-effect".
|
|
936
|
-
*/
|
|
937
|
-
export interface ConditionalEffect {
|
|
938
|
-
type: "conditional";
|
|
939
|
-
condition: AbilityCondition2;
|
|
940
|
-
effect: EffectNode;
|
|
941
|
-
[k: string]: unknown;
|
|
942
|
-
}
|
|
943
|
-
/**
|
|
944
|
-
* This interface was referenced by `0KdcBundledSchemas`'s JSON-Schema
|
|
945
|
-
* via the `definition` "dice-pool-allocation-effect".
|
|
946
|
-
*/
|
|
947
|
-
export interface DicePoolAllocationEffect {
|
|
948
|
-
type: "dice-pool-allocation";
|
|
949
|
-
pool: {
|
|
950
|
-
count: number;
|
|
951
|
-
die: string;
|
|
952
|
-
[k: string]: unknown;
|
|
953
|
-
};
|
|
954
|
-
max_activations: number;
|
|
955
|
-
/**
|
|
956
|
-
* @minItems 1
|
|
957
|
-
*/
|
|
958
|
-
options: [
|
|
959
|
-
{
|
|
960
|
-
name: string;
|
|
961
|
-
requirement: {
|
|
962
|
-
type: "pair" | "triple" | "single" | "run";
|
|
963
|
-
min_value: number;
|
|
964
|
-
[k: string]: unknown;
|
|
965
|
-
};
|
|
966
|
-
effect: EffectNode;
|
|
967
|
-
[k: string]: unknown;
|
|
968
|
-
},
|
|
969
|
-
...{
|
|
970
|
-
name: string;
|
|
971
|
-
requirement: {
|
|
972
|
-
type: "pair" | "triple" | "single" | "run";
|
|
973
|
-
min_value: number;
|
|
974
|
-
[k: string]: unknown;
|
|
975
|
-
};
|
|
976
|
-
effect: EffectNode;
|
|
977
|
-
[k: string]: unknown;
|
|
978
|
-
}[]
|
|
979
|
-
];
|
|
980
|
-
[k: string]: unknown;
|
|
981
|
-
}
|
|
982
1137
|
/**
|
|
983
1138
|
* A weapon entry with one or more stat profiles (e.g., standard and overcharge modes).
|
|
984
1139
|
*
|