@drmxrcy/tcg-lorcana-types 0.0.0-202602060544
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/package.json +46 -0
- package/src/abilities/ability-types.ts +766 -0
- package/src/abilities/condition-types.ts +1202 -0
- package/src/abilities/cost-types.ts +344 -0
- package/src/abilities/effect-types/amount-types.ts +115 -0
- package/src/abilities/effect-types/basic-effects.ts +200 -0
- package/src/abilities/effect-types/combined-types.ts +564 -0
- package/src/abilities/effect-types/control-flow.ts +317 -0
- package/src/abilities/effect-types/index.ts +136 -0
- package/src/abilities/effect-types/modifier-effects.ts +248 -0
- package/src/abilities/effect-types/movement-effects.ts +216 -0
- package/src/abilities/effect-types/scry-effects.ts +269 -0
- package/src/abilities/helpers/Abilities.ts +172 -0
- package/src/abilities/helpers/Conditions.ts +266 -0
- package/src/abilities/helpers/Costs.ts +83 -0
- package/src/abilities/helpers/Effects.ts +182 -0
- package/src/abilities/helpers/Targets.ts +193 -0
- package/src/abilities/helpers/Triggers.ts +167 -0
- package/src/abilities/helpers/index.ts +42 -0
- package/src/abilities/index.ts +401 -0
- package/src/abilities/target-types.ts +791 -0
- package/src/abilities/trigger-types.ts +530 -0
- package/src/cards/card-types.ts +502 -0
- package/src/cards/classifications.ts +86 -0
- package/src/cards/deck-validation.ts +71 -0
- package/src/cards/index.ts +77 -0
- package/src/cards/ink-types.ts +55 -0
- package/src/game/index.ts +14 -0
- package/src/game/state-types.ts +258 -0
- package/src/index.ts +16 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Condition Helpers for Lorcana Abilities
|
|
3
|
+
*
|
|
4
|
+
* Provides a fluent API for building condition definitions.
|
|
5
|
+
* These helpers make it easy to construct common condition patterns.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const condition = Conditions.HasAnotherCharacter();
|
|
10
|
+
* const condition = Conditions.HasCharacterNamed("Elsa");
|
|
11
|
+
* const condition = Conditions.WhileDamaged();
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { Condition } from "../condition-types";
|
|
16
|
+
|
|
17
|
+
export const Conditions = {
|
|
18
|
+
/**
|
|
19
|
+
* "If you have another character in play"
|
|
20
|
+
*/
|
|
21
|
+
HasAnotherCharacter: (): Condition => ({
|
|
22
|
+
type: "has-another-character",
|
|
23
|
+
}),
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* "If you have a character named X"
|
|
27
|
+
*/
|
|
28
|
+
HasCharacterNamed: (name: string): Condition => ({
|
|
29
|
+
type: "has-named-character",
|
|
30
|
+
name,
|
|
31
|
+
controller: "you",
|
|
32
|
+
}),
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* "If you have a character with classification X"
|
|
36
|
+
*/
|
|
37
|
+
HasCharacterWithClassification: (classification: string): Condition => ({
|
|
38
|
+
type: "has-character-with-classification",
|
|
39
|
+
classification,
|
|
40
|
+
controller: "you",
|
|
41
|
+
}),
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* "If you have a character with keyword X"
|
|
45
|
+
*/
|
|
46
|
+
HasCharacterWithKeyword: (keyword: string): Condition => ({
|
|
47
|
+
type: "has-character-with-keyword",
|
|
48
|
+
keyword,
|
|
49
|
+
controller: "you",
|
|
50
|
+
}),
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* "While this character has damage"
|
|
54
|
+
*/
|
|
55
|
+
WhileDamaged: (): Condition => ({
|
|
56
|
+
type: "has-any-damage",
|
|
57
|
+
}),
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* "While this character has no damage"
|
|
61
|
+
*/
|
|
62
|
+
WhileNoDamage: (): Condition => ({
|
|
63
|
+
type: "has-no-damage",
|
|
64
|
+
}),
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* "While this character is exerted"
|
|
68
|
+
*/
|
|
69
|
+
WhileExerted: (): Condition => ({
|
|
70
|
+
type: "is-exerted",
|
|
71
|
+
}),
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* "While this character is ready"
|
|
75
|
+
*/
|
|
76
|
+
WhileReady: (): Condition => ({
|
|
77
|
+
type: "is-ready",
|
|
78
|
+
}),
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* "While in a challenge"
|
|
82
|
+
*/
|
|
83
|
+
InChallenge: (): Condition => ({
|
|
84
|
+
type: "in-challenge",
|
|
85
|
+
}),
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* "If you have X or more cards in hand"
|
|
89
|
+
*/
|
|
90
|
+
HandSizeAtLeast: (amount: number): Condition => ({
|
|
91
|
+
type: "resource-count",
|
|
92
|
+
what: "cards-in-hand",
|
|
93
|
+
controller: "you",
|
|
94
|
+
comparison: "greater-or-equal",
|
|
95
|
+
value: amount,
|
|
96
|
+
}),
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* "If you have X or fewer cards in hand"
|
|
100
|
+
*/
|
|
101
|
+
HandSizeAtMost: (amount: number): Condition => ({
|
|
102
|
+
type: "resource-count",
|
|
103
|
+
what: "cards-in-hand",
|
|
104
|
+
controller: "you",
|
|
105
|
+
comparison: "less-or-equal",
|
|
106
|
+
value: amount,
|
|
107
|
+
}),
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* "If you have no cards in hand"
|
|
111
|
+
*/
|
|
112
|
+
HandIsEmpty: (): Condition => ({
|
|
113
|
+
type: "resource-count",
|
|
114
|
+
what: "cards-in-hand",
|
|
115
|
+
controller: "you",
|
|
116
|
+
comparison: "equal",
|
|
117
|
+
value: 0,
|
|
118
|
+
}),
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* "If you have X or more lore"
|
|
122
|
+
*/
|
|
123
|
+
LoreAtLeast: (amount: number): Condition => ({
|
|
124
|
+
type: "lore-comparison",
|
|
125
|
+
comparison: "greater-or-equal",
|
|
126
|
+
value: amount,
|
|
127
|
+
}),
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* "If you have X or fewer lore"
|
|
131
|
+
*/
|
|
132
|
+
LoreAtMost: (amount: number): Condition => ({
|
|
133
|
+
type: "lore-comparison",
|
|
134
|
+
comparison: "less-or-equal",
|
|
135
|
+
value: amount,
|
|
136
|
+
}),
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* "If you have a card under this character"
|
|
140
|
+
*/
|
|
141
|
+
HasCardUnder: (): Condition => ({
|
|
142
|
+
type: "has-card-under",
|
|
143
|
+
}),
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* "If this is the first time this turn"
|
|
147
|
+
*/
|
|
148
|
+
FirstTimeThisTurn: (): Condition => ({
|
|
149
|
+
type: "first-this-turn",
|
|
150
|
+
event: "action",
|
|
151
|
+
}),
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* "If you used Shift this turn"
|
|
155
|
+
*/
|
|
156
|
+
UsedShiftThisTurn: (): Condition => ({
|
|
157
|
+
type: "used-shift",
|
|
158
|
+
}),
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* "If you have a character in play"
|
|
162
|
+
*/
|
|
163
|
+
HaveCharacterInPlay: (): Condition => ({
|
|
164
|
+
type: "has-named-character",
|
|
165
|
+
controller: "you",
|
|
166
|
+
}),
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* "If you have an item in play"
|
|
170
|
+
*/
|
|
171
|
+
HaveItemInPlay: (): Condition => ({
|
|
172
|
+
type: "has-named-item",
|
|
173
|
+
name: "",
|
|
174
|
+
controller: "you",
|
|
175
|
+
}),
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* "If you have a location in play"
|
|
179
|
+
*/
|
|
180
|
+
HaveLocationInPlay: (): Condition => ({
|
|
181
|
+
type: "has-named-location",
|
|
182
|
+
name: "",
|
|
183
|
+
controller: "you",
|
|
184
|
+
}),
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* "If you have a card with classification X in play"
|
|
188
|
+
*/
|
|
189
|
+
HaveClassificationInPlay: (classification: string): Condition => ({
|
|
190
|
+
type: "has-character-with-classification",
|
|
191
|
+
classification,
|
|
192
|
+
controller: "you",
|
|
193
|
+
}),
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* "If you have a card with keyword X in play"
|
|
197
|
+
*/
|
|
198
|
+
HaveKeywordInPlay: (keyword: string): Condition => ({
|
|
199
|
+
type: "has-character-with-keyword",
|
|
200
|
+
keyword,
|
|
201
|
+
controller: "you",
|
|
202
|
+
}),
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* "If you have a card named X in play"
|
|
206
|
+
*/
|
|
207
|
+
HaveNamedInPlay: (name: string): Condition => ({
|
|
208
|
+
type: "has-named-character",
|
|
209
|
+
name,
|
|
210
|
+
controller: "you",
|
|
211
|
+
}),
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* "If you have X or more characters in play"
|
|
215
|
+
*/
|
|
216
|
+
CharacterCountAtLeast: (amount: number): Condition => ({
|
|
217
|
+
type: "has-character-count",
|
|
218
|
+
controller: "you",
|
|
219
|
+
comparison: "greater-or-equal",
|
|
220
|
+
count: amount,
|
|
221
|
+
}),
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* "If you have X or fewer characters in play"
|
|
225
|
+
*/
|
|
226
|
+
CharacterCountAtMost: (amount: number): Condition => ({
|
|
227
|
+
type: "has-character-count",
|
|
228
|
+
controller: "you",
|
|
229
|
+
comparison: "less-or-equal",
|
|
230
|
+
count: amount,
|
|
231
|
+
}),
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* "If you have exactly X characters in play"
|
|
235
|
+
*/
|
|
236
|
+
CharacterCountExactly: (amount: number): Condition => ({
|
|
237
|
+
type: "has-character-count",
|
|
238
|
+
controller: "you",
|
|
239
|
+
comparison: "equal",
|
|
240
|
+
count: amount,
|
|
241
|
+
}),
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Logical AND - all conditions must be true
|
|
245
|
+
*/
|
|
246
|
+
And: (...conditions: Condition[]): Condition => ({
|
|
247
|
+
type: "and",
|
|
248
|
+
conditions,
|
|
249
|
+
}),
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Logical OR - any condition must be true
|
|
253
|
+
*/
|
|
254
|
+
Or: (...conditions: Condition[]): Condition => ({
|
|
255
|
+
type: "or",
|
|
256
|
+
conditions,
|
|
257
|
+
}),
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Logical NOT - negate a condition
|
|
261
|
+
*/
|
|
262
|
+
Not: (condition: Condition): Condition => ({
|
|
263
|
+
type: "not",
|
|
264
|
+
condition,
|
|
265
|
+
}),
|
|
266
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cost Helpers for Lorcana Abilities
|
|
3
|
+
*
|
|
4
|
+
* Provides a fluent API for building cost definitions.
|
|
5
|
+
* These helpers make it easy to construct common cost patterns.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const cost = Costs.Ink(2);
|
|
10
|
+
* const cost = Costs.Exert();
|
|
11
|
+
* const cost = Costs.Combined(Costs.Ink(1), Costs.Exert());
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { AbilityCost } from "../cost-types";
|
|
16
|
+
|
|
17
|
+
export const Costs = {
|
|
18
|
+
/**
|
|
19
|
+
* "X ink cost"
|
|
20
|
+
*/
|
|
21
|
+
Ink: (amount: number): AbilityCost => ({ ink: amount }),
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* "Exert this character"
|
|
25
|
+
*/
|
|
26
|
+
Exert: (): AbilityCost => ({ exert: true }),
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* "Banish this character"
|
|
30
|
+
*/
|
|
31
|
+
BanishSelf: (): AbilityCost => ({ banishSelf: true }),
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* "Discard a card"
|
|
35
|
+
*/
|
|
36
|
+
Discard: (amount = 1): AbilityCost => ({
|
|
37
|
+
discardCards: amount,
|
|
38
|
+
}),
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* "Return this card to hand"
|
|
42
|
+
*/
|
|
43
|
+
ReturnToHand: (): AbilityCost => ({ returnSelfToHand: true }),
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* "Damage this character X"
|
|
47
|
+
*/
|
|
48
|
+
DamageSelf: (amount: number): AbilityCost => ({
|
|
49
|
+
damageSelf: amount,
|
|
50
|
+
}),
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* "X ink and exert"
|
|
54
|
+
*/
|
|
55
|
+
InkAndExert: (amount: number): AbilityCost => ({
|
|
56
|
+
ink: amount,
|
|
57
|
+
exert: true,
|
|
58
|
+
}),
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* "X ink and banish"
|
|
62
|
+
*/
|
|
63
|
+
InkAndBanish: (amount: number): AbilityCost => ({
|
|
64
|
+
ink: amount,
|
|
65
|
+
banishSelf: true,
|
|
66
|
+
}),
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* "X ink and discard"
|
|
70
|
+
*/
|
|
71
|
+
InkAndDiscard: (amount: number, discardAmount = 1): AbilityCost => ({
|
|
72
|
+
ink: amount,
|
|
73
|
+
discardCards: discardAmount,
|
|
74
|
+
}),
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* "Exert and banish"
|
|
78
|
+
*/
|
|
79
|
+
ExertAndBanish: (): AbilityCost => ({
|
|
80
|
+
exert: true,
|
|
81
|
+
banishSelf: true,
|
|
82
|
+
}),
|
|
83
|
+
};
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Effect Helpers for Lorcana Abilities
|
|
3
|
+
*
|
|
4
|
+
* Provides a fluent API for building effect definitions.
|
|
5
|
+
* These helpers make it easy to construct common effect patterns.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const effect = Effects.Draw({ amount: 2 });
|
|
10
|
+
* const effect = Effects.Banish({ target: Targets.ChallengedCharacter(), optional: true });
|
|
11
|
+
* const effect = Effects.RemoveDamage({ amount: 2, target: Targets.Self() });
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { Effect, OptionalEffect } from "../effect-types";
|
|
16
|
+
import type {
|
|
17
|
+
CardTarget,
|
|
18
|
+
CharacterTarget,
|
|
19
|
+
PlayerTarget,
|
|
20
|
+
} from "../target-types";
|
|
21
|
+
|
|
22
|
+
export const Effects = {
|
|
23
|
+
/**
|
|
24
|
+
* "Draw X cards"
|
|
25
|
+
*/
|
|
26
|
+
Draw: (params: { amount: number }): Effect => ({
|
|
27
|
+
type: "draw",
|
|
28
|
+
amount: params.amount,
|
|
29
|
+
}),
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* "Banish chosen character" or "You may banish chosen character"
|
|
33
|
+
*/
|
|
34
|
+
Banish: (params: { target: CharacterTarget; optional?: boolean }): Effect => {
|
|
35
|
+
const banishEffect: Effect = {
|
|
36
|
+
type: "banish",
|
|
37
|
+
target: params.target,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
return params.optional
|
|
41
|
+
? { type: "optional", effect: banishEffect }
|
|
42
|
+
: banishEffect;
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* "Remove up to X damage from target"
|
|
47
|
+
*/
|
|
48
|
+
RemoveDamage: (params: {
|
|
49
|
+
amount: number;
|
|
50
|
+
target: CharacterTarget;
|
|
51
|
+
upTo?: boolean;
|
|
52
|
+
}): Effect => ({
|
|
53
|
+
type: "remove-damage",
|
|
54
|
+
amount: params.amount,
|
|
55
|
+
target: params.target,
|
|
56
|
+
upTo: params.upTo,
|
|
57
|
+
}),
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* "Target gains keyword"
|
|
61
|
+
*/
|
|
62
|
+
GainKeyword: (params: {
|
|
63
|
+
keyword: string;
|
|
64
|
+
target?: CharacterTarget;
|
|
65
|
+
}): Effect => ({
|
|
66
|
+
type: "gain-keyword",
|
|
67
|
+
keyword: params.keyword,
|
|
68
|
+
target: params.target ?? "SELF",
|
|
69
|
+
}),
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* "Sequence of effects"
|
|
73
|
+
*/
|
|
74
|
+
Sequence: (effects: Effect[]): Effect => ({
|
|
75
|
+
type: "sequence",
|
|
76
|
+
effects,
|
|
77
|
+
}),
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* "You may [effect]"
|
|
81
|
+
*/
|
|
82
|
+
Optional: (effect: Effect): OptionalEffect => ({
|
|
83
|
+
type: "optional",
|
|
84
|
+
effect,
|
|
85
|
+
}),
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* "Deal X damage to target"
|
|
89
|
+
*/
|
|
90
|
+
DealDamage: (params: {
|
|
91
|
+
amount: number;
|
|
92
|
+
target: CharacterTarget;
|
|
93
|
+
}): Effect => ({
|
|
94
|
+
type: "deal-damage",
|
|
95
|
+
amount: params.amount,
|
|
96
|
+
target: params.target,
|
|
97
|
+
}),
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* "Gain X lore"
|
|
101
|
+
*/
|
|
102
|
+
GainLore: (params: { amount: number }): Effect => ({
|
|
103
|
+
type: "gain-lore",
|
|
104
|
+
amount: params.amount,
|
|
105
|
+
}),
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* "Lose X lore"
|
|
109
|
+
*/
|
|
110
|
+
LoseLore: (params: { amount: number }): Effect => ({
|
|
111
|
+
type: "lose-lore",
|
|
112
|
+
amount: params.amount,
|
|
113
|
+
}),
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* "Exert target"
|
|
117
|
+
*/
|
|
118
|
+
Exert: (params?: { target?: CharacterTarget }): Effect => ({
|
|
119
|
+
type: "exert",
|
|
120
|
+
target: params?.target ?? "SELF",
|
|
121
|
+
}),
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* "Ready target"
|
|
125
|
+
*/
|
|
126
|
+
Ready: (params?: { target?: CharacterTarget }): Effect => ({
|
|
127
|
+
type: "ready",
|
|
128
|
+
target: params?.target ?? "SELF",
|
|
129
|
+
}),
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* "Return target to hand"
|
|
133
|
+
*/
|
|
134
|
+
ReturnToHand: (params: { target: CharacterTarget }): Effect => ({
|
|
135
|
+
type: "return-to-hand",
|
|
136
|
+
target: params.target,
|
|
137
|
+
}),
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* "Discard target"
|
|
141
|
+
*/
|
|
142
|
+
Discard: (params?: { target?: CharacterTarget }): Effect => ({
|
|
143
|
+
type: "discard",
|
|
144
|
+
}),
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* "Put target into inkwell"
|
|
148
|
+
*/
|
|
149
|
+
PutIntoInkwell: (params?: { target?: CharacterTarget }): Effect => ({
|
|
150
|
+
type: "put-into-inkwell",
|
|
151
|
+
}),
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* "Search deck for card and put into hand"
|
|
155
|
+
*/
|
|
156
|
+
SearchDeck: (): Effect => ({
|
|
157
|
+
type: "search-deck",
|
|
158
|
+
}),
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* "Shuffle target into deck"
|
|
162
|
+
*/
|
|
163
|
+
ShuffleIntoDeck: (params: { target: CharacterTarget }): Effect => ({
|
|
164
|
+
type: "shuffle-into-deck",
|
|
165
|
+
target: params.target,
|
|
166
|
+
}),
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* "Put target on top of deck"
|
|
170
|
+
*/
|
|
171
|
+
PutOnTop: (params: { target: CharacterTarget }): Effect => ({
|
|
172
|
+
type: "put-on-top",
|
|
173
|
+
}),
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* "Put target on bottom of deck"
|
|
177
|
+
*/
|
|
178
|
+
PutOnBottom: (params: { target: CharacterTarget }): Effect => ({
|
|
179
|
+
type: "put-on-bottom",
|
|
180
|
+
target: params.target,
|
|
181
|
+
}),
|
|
182
|
+
};
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Target Helpers for Lorcana Abilities
|
|
3
|
+
*
|
|
4
|
+
* Provides a fluent API for building target definitions.
|
|
5
|
+
* These helpers make it easy to construct common target patterns.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const target = Targets.Self();
|
|
10
|
+
* const target = Targets.ChallengedCharacter();
|
|
11
|
+
* const target = Targets.YourCharacters();
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type {
|
|
16
|
+
CardTarget,
|
|
17
|
+
CharacterTarget,
|
|
18
|
+
PlayerTarget,
|
|
19
|
+
} from "../target-types";
|
|
20
|
+
|
|
21
|
+
export const Targets = {
|
|
22
|
+
// ========================================================================
|
|
23
|
+
// Self/Controller Targets
|
|
24
|
+
// ========================================================================
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* "This character" or "this card"
|
|
28
|
+
*/
|
|
29
|
+
Self: (): CardTarget => "SELF",
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* "You" (for player-targeted effects)
|
|
33
|
+
*/
|
|
34
|
+
Controller: (): PlayerTarget => "CONTROLLER",
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* "Your opponent"
|
|
38
|
+
*/
|
|
39
|
+
Opponent: (): PlayerTarget => "OPPONENT",
|
|
40
|
+
|
|
41
|
+
// ========================================================================
|
|
42
|
+
// Character Targets
|
|
43
|
+
// ========================================================================
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* "Chosen character"
|
|
47
|
+
*/
|
|
48
|
+
ChosenCharacter: (): CharacterTarget => "CHOSEN_CHARACTER",
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* "Challenged character"
|
|
52
|
+
*/
|
|
53
|
+
ChallengedCharacter: (): CharacterTarget => "CHALLENGED_CHARACTER",
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* "Challenging character"
|
|
57
|
+
*/
|
|
58
|
+
ChallengingCharacter: (): CharacterTarget => "CHALLENGING_CHARACTER",
|
|
59
|
+
|
|
60
|
+
// ========================================================================
|
|
61
|
+
// Your Characters
|
|
62
|
+
// ========================================================================
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* "Your characters"
|
|
66
|
+
*/
|
|
67
|
+
YourCharacters: (): CharacterTarget => "YOUR_CHARACTERS",
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* "Your other characters"
|
|
71
|
+
*/
|
|
72
|
+
YourOtherCharacters: (): CharacterTarget => "YOUR_OTHER_CHARACTERS",
|
|
73
|
+
|
|
74
|
+
// ========================================================================
|
|
75
|
+
// Opponent Characters
|
|
76
|
+
// ========================================================================
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* "Opponent's characters"
|
|
80
|
+
*/
|
|
81
|
+
OpponentCharacters: (): CharacterTarget => "ALL_OPPOSING_CHARACTERS",
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* "Opposing characters"
|
|
85
|
+
*/
|
|
86
|
+
OpposingCharacters: (): CharacterTarget => "OPPOSING_CHARACTERS",
|
|
87
|
+
|
|
88
|
+
// ========================================================================
|
|
89
|
+
// Classification-based Targets
|
|
90
|
+
// ========================================================================
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* "Your Musketeer characters"
|
|
94
|
+
*/
|
|
95
|
+
YourMusketeers: (): CharacterTarget => "YOUR_MUSKETEER_CHARACTERS",
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* "Your Villain characters"
|
|
99
|
+
*/
|
|
100
|
+
YourVillains: (): CharacterTarget => "YOUR_VILLAIN_CHARACTERS",
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* "Your Broom characters"
|
|
104
|
+
*/
|
|
105
|
+
YourBrooms: (): CharacterTarget => "YOUR_BROOM_CHARACTERS",
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* "Your other Steel characters"
|
|
109
|
+
*/
|
|
110
|
+
YourOtherSteelCharacters: (): CharacterTarget =>
|
|
111
|
+
"YOUR_OTHER_STEEL_CHARACTERS",
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* "Your other Amethyst characters"
|
|
115
|
+
*/
|
|
116
|
+
YourOtherAmethystCharacters: (): CharacterTarget =>
|
|
117
|
+
"YOUR_OTHER_AMETHYST_CHARACTERS",
|
|
118
|
+
|
|
119
|
+
// ========================================================================
|
|
120
|
+
// Zone-based Targets
|
|
121
|
+
// ========================================================================
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* "Character from discard"
|
|
125
|
+
*/
|
|
126
|
+
CharacterFromDiscard: (): CharacterTarget => "CHOSEN_CHARACTER_IN_DISCARD",
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* "Characters at this location"
|
|
130
|
+
*/
|
|
131
|
+
CharactersHere: (): CharacterTarget => "CHARACTERS_HERE",
|
|
132
|
+
|
|
133
|
+
// ========================================================================
|
|
134
|
+
// All/Each Targets
|
|
135
|
+
// ========================================================================
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* "All characters"
|
|
139
|
+
*/
|
|
140
|
+
AllCharacters: (): CharacterTarget => "ALL_CHARACTERS",
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* "All your characters"
|
|
144
|
+
*/
|
|
145
|
+
AllYourCharacters: (): CharacterTarget => "YOUR_CHARACTERS",
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* "All opponent characters"
|
|
149
|
+
*/
|
|
150
|
+
AllOpponentCharacters: (): CharacterTarget => "ALL_OPPOSING_CHARACTERS",
|
|
151
|
+
|
|
152
|
+
// ========================================================================
|
|
153
|
+
// Item Targets
|
|
154
|
+
// ========================================================================
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* "Your items"
|
|
158
|
+
*/
|
|
159
|
+
YourItems: (): CardTarget => "YOUR_ITEMS",
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* "Chosen item"
|
|
163
|
+
*/
|
|
164
|
+
ChosenItem: (): CardTarget => "CHOSEN_ITEM",
|
|
165
|
+
|
|
166
|
+
// ========================================================================
|
|
167
|
+
// Location Targets
|
|
168
|
+
// ========================================================================
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* "Your locations"
|
|
172
|
+
*/
|
|
173
|
+
YourLocations: (): CardTarget => "YOUR_LOCATIONS",
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* "Chosen location"
|
|
177
|
+
*/
|
|
178
|
+
ChosenLocation: (): CardTarget => "CHOSEN_LOCATION",
|
|
179
|
+
|
|
180
|
+
// ========================================================================
|
|
181
|
+
// Generic Targets
|
|
182
|
+
// ========================================================================
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* "Any character"
|
|
186
|
+
*/
|
|
187
|
+
AnyCharacter: (): CharacterTarget => "ALL_CHARACTERS",
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* "All characters"
|
|
191
|
+
*/
|
|
192
|
+
AllCharactersTarget: (): CharacterTarget => "ALL_CHARACTERS",
|
|
193
|
+
};
|