@vibemancer/core 1.0.7 → 1.0.9
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/LICENSE +21 -0
- package/dist/{chunk-NR326XEY.js → chunk-OLGKLCCB.js} +43 -13
- package/dist/chunk-OLGKLCCB.js.map +1 -0
- package/dist/{index-browser-iiIpqpDl.d.ts → index-browser-BTHlrB_s.d.ts} +87 -12
- package/dist/index-browser.d.ts +1 -1
- package/dist/index-browser.js +3 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/bots/sniper/01_Spellshot.ts +11 -5
- package/src/engine/manual-match.ts +3 -1
- package/src/engine/physics.ts +12 -2
- package/src/engine/simulation.ts +79 -2
- package/src/engine-version.ts +1 -1
- package/src/hooks/action-builders.ts +299 -266
- package/src/hooks/index.ts +84 -83
- package/src/hooks/threat-analysis.ts +396 -389
- package/src/hooks/types.ts +216 -200
- package/src/rules.ts +6 -1
- package/src/trace.ts +497 -490
- package/src/types.ts +9 -3
- package/dist/chunk-NR326XEY.js.map +0 -1
|
@@ -1,266 +1,299 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* VIBEMANCER - ACTION BUILDERS
|
|
3
|
-
*
|
|
4
|
-
* Fluent API for constructing bot actions with type-safe chaining.
|
|
5
|
-
*
|
|
6
|
-
* UNITS REFERENCE (100 ticks = 1 second):
|
|
7
|
-
* Position: absolute world coordinates, 0-860 on each axis (860×860 arena, of which
|
|
8
|
-
* the outer 30 units on every side are lethal lava — playfield is [30, 830])
|
|
9
|
-
* Movement: direction vector, magnitude clamped to max 1 (speed in [0, 1])
|
|
10
|
-
* Speed: units per tick (player moves at 1.5 units/tick = 150 units/sec)
|
|
11
|
-
* Duration: ticks (divide by 100 for seconds)
|
|
12
|
-
* Angles: degrees (0°=right, 90°=down, 180°=left, 270°=up)
|
|
13
|
-
* Damage: raw HP removed on hit (wizard has 60 HP)
|
|
14
|
-
* Turn rate: degrees per tick the missile can rotate
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import {WizardActions, MissileConfig, MissileActions} from '../types.js';
|
|
18
|
-
import type {FinalAction, ActionBuilder, MissileAction, MissileFunction} from './types.js';
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Create a FinalAction (no further chaining possible).
|
|
22
|
-
*/
|
|
23
|
-
function createFinalAction(action: WizardActions): FinalAction
|
|
24
|
-
{
|
|
25
|
-
return {
|
|
26
|
-
_toAction: () => action,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Create an ActionBuilder (can chain .move()).
|
|
32
|
-
*/
|
|
33
|
-
function createActionBuilder(baseAction: Omit<WizardActions, 'move'>): ActionBuilder
|
|
34
|
-
{
|
|
35
|
-
const action: WizardActions = {
|
|
36
|
-
...baseAction,
|
|
37
|
-
move: {x: 0, y: 0},
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
return {
|
|
41
|
-
_toAction: () => action,
|
|
42
|
-
move(x: number, y: number): FinalAction
|
|
43
|
-
{
|
|
44
|
-
return createFinalAction({
|
|
45
|
-
...action,
|
|
46
|
-
move: {x, y},
|
|
47
|
-
});
|
|
48
|
-
},
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* @
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
*
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
* @param x -
|
|
214
|
-
* @param y -
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
*
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
{
|
|
252
|
-
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
*
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
{
|
|
265
|
-
|
|
266
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* VIBEMANCER - ACTION BUILDERS
|
|
3
|
+
*
|
|
4
|
+
* Fluent API for constructing bot actions with type-safe chaining.
|
|
5
|
+
*
|
|
6
|
+
* UNITS REFERENCE (100 ticks = 1 second):
|
|
7
|
+
* Position: absolute world coordinates, 0-860 on each axis (860×860 arena, of which
|
|
8
|
+
* the outer 30 units on every side are lethal lava — playfield is [30, 830])
|
|
9
|
+
* Movement: direction vector, magnitude clamped to max 1 (speed in [0, 1])
|
|
10
|
+
* Speed: units per tick (player moves at 1.5 units/tick = 150 units/sec)
|
|
11
|
+
* Duration: ticks (divide by 100 for seconds)
|
|
12
|
+
* Angles: degrees (0°=right, 90°=down, 180°=left, 270°=up)
|
|
13
|
+
* Damage: raw HP removed on hit (wizard has 60 HP)
|
|
14
|
+
* Turn rate: degrees per tick the missile can rotate
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import {WizardActions, MissileConfig, MissileActions} from '../types.js';
|
|
18
|
+
import type {FinalAction, ActionBuilder, MissileAction, MissileFunction} from './types.js';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Create a FinalAction (no further chaining possible).
|
|
22
|
+
*/
|
|
23
|
+
function createFinalAction(action: WizardActions): FinalAction
|
|
24
|
+
{
|
|
25
|
+
return {
|
|
26
|
+
_toAction: () => action,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Create an ActionBuilder (can chain .move()).
|
|
32
|
+
*/
|
|
33
|
+
function createActionBuilder(baseAction: Omit<WizardActions, 'move'>): ActionBuilder
|
|
34
|
+
{
|
|
35
|
+
const action: WizardActions = {
|
|
36
|
+
...baseAction,
|
|
37
|
+
move: {x: 0, y: 0},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
_toAction: () => action,
|
|
42
|
+
move(x: number, y: number): FinalAction
|
|
43
|
+
{
|
|
44
|
+
return createFinalAction({
|
|
45
|
+
...action,
|
|
46
|
+
move: {x, y},
|
|
47
|
+
});
|
|
48
|
+
},
|
|
49
|
+
lockAim(): ActionBuilder
|
|
50
|
+
{
|
|
51
|
+
// Opting out of auto-aim for this action. The engine holds `aimDirection` for the
|
|
52
|
+
// duration of a missile cast, so the angle survives to launch — without this, the
|
|
53
|
+
// per-tick auto-aim overwrites it and the shot goes at the enemy instead.
|
|
54
|
+
//
|
|
55
|
+
// Nothing happens if the action names no direction: there is no angle to keep, and
|
|
56
|
+
// silently facing 0 degrees would be worse than doing nothing.
|
|
57
|
+
const cast = action.startCast;
|
|
58
|
+
const direction = cast && cast.spell === 'missile' ? cast.direction : undefined;
|
|
59
|
+
if (direction === undefined || !Number.isFinite(direction)) return createActionBuilder(baseAction);
|
|
60
|
+
return createActionBuilder({...baseAction, aimDirection: direction});
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ============================================================
|
|
66
|
+
// ACTION BUILDERS
|
|
67
|
+
// ============================================================
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Channel a shield that blocks incoming damage.
|
|
71
|
+
*
|
|
72
|
+
* Starts at 90% block, decays by 20% per second, minimum 30%.
|
|
73
|
+
* Takes 20 ticks (0.2s) to activate. Movement is disabled while channeling.
|
|
74
|
+
* Cancel anytime with cancel(). Cancelling costs NO GCD — you are idle the next tick.
|
|
75
|
+
*
|
|
76
|
+
* Can chain .move() — movement applies during the 20-tick cast, NOT during channel.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* return shield(); // shield and stay still
|
|
80
|
+
* return shield().move(1, 0); // move right while cast starts
|
|
81
|
+
*/
|
|
82
|
+
export function shield(): ActionBuilder
|
|
83
|
+
{
|
|
84
|
+
return createActionBuilder({
|
|
85
|
+
startCast: {spell: 'shield'},
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Cast a missile spell.
|
|
91
|
+
*
|
|
92
|
+
* Cast time scales with damage, speed, duration, and turn rate — bigger missiles
|
|
93
|
+
* take longer to cast. While casting you move at 50% speed. After firing, 100-tick
|
|
94
|
+
* (1s) GCD before next spell.
|
|
95
|
+
*
|
|
96
|
+
* Repeated similar missiles cast 20% faster (warmup bonus). Switching styles
|
|
97
|
+
* incurs a 20% penalty.
|
|
98
|
+
*
|
|
99
|
+
* Can chain .move() for simultaneous movement while casting.
|
|
100
|
+
*
|
|
101
|
+
* @param config - Missile stats:
|
|
102
|
+
* - damage: HP removed on hit (1-60 typical). Also sets hitbox: radius = 2 + 0.1×damage.
|
|
103
|
+
* - speed: units/tick (min 1.5). Player moves at 1 u/t, so 5 = 5× player speed.
|
|
104
|
+
* - duration: ticks the missile lives (min 10). Range ≈ speed × duration.
|
|
105
|
+
* - turnRate: degrees/tick of homing (0 = straight line, 3 = moderate homing, 5+ = strong).
|
|
106
|
+
* Negative = no homing + minor speed cost reduction.
|
|
107
|
+
* @param ai - Called every tick to control missile steering. Use getMissileContext()
|
|
108
|
+
* to read the missile's state (position, rotation, speed, etc.), the full game
|
|
109
|
+
* state (worldState), and a seeded PRNG (random). Return turnToward(x, y) to home
|
|
110
|
+
* toward a position, or flyStraight() to fly straight.
|
|
111
|
+
* @param direction - Launch angle in degrees (0°=right, 90°=down, 180°=left, 270°=up).
|
|
112
|
+
* Tip: use Math.atan2(dy, dx) * (180 / Math.PI) to aim at a target.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* // Straight missile aimed at enemy
|
|
116
|
+
* const angle = Math.atan2(dy, dx) * (180 / Math.PI);
|
|
117
|
+
* return missile({damage: 15, speed: 6, duration: 200, turnRate: 0}, () => flyStraight(), angle);
|
|
118
|
+
*
|
|
119
|
+
* // Homing missile that tracks enemy
|
|
120
|
+
* return missile(
|
|
121
|
+
* {damage: 10, speed: 5, duration: 300, turnRate: 3},
|
|
122
|
+
* () => {
|
|
123
|
+
* const ctx = getMissileContext();
|
|
124
|
+
* const enemy = ctx.worldState.enemies[0];
|
|
125
|
+
* return enemy ? turnToward(enemy.position.x, enemy.position.y) : flyStraight();
|
|
126
|
+
* },
|
|
127
|
+
* angle,
|
|
128
|
+
* );
|
|
129
|
+
*/
|
|
130
|
+
export function missile(config: MissileConfig, ai: MissileFunction, direction: number): ActionBuilder
|
|
131
|
+
{
|
|
132
|
+
return createActionBuilder({
|
|
133
|
+
startCast: {
|
|
134
|
+
spell: 'missile',
|
|
135
|
+
config,
|
|
136
|
+
missileAI: ai,
|
|
137
|
+
direction,
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Face a specific direction this tick, instead of auto-aiming at the enemy.
|
|
144
|
+
*
|
|
145
|
+
* Useful on its own (turning to cover an approach) and during a cast, where it keeps a
|
|
146
|
+
* locked shot pointed where you want it. Angles are degrees, 0 = right, 90 = down.
|
|
147
|
+
*
|
|
148
|
+
* A non-finite angle is ignored rather than applied, because a NaN rotation propagates into
|
|
149
|
+
* every position calculation that follows it.
|
|
150
|
+
*/
|
|
151
|
+
export function aim(degrees: number): ActionBuilder
|
|
152
|
+
{
|
|
153
|
+
return createActionBuilder(Number.isFinite(degrees) ? {aimDirection: degrees} : {});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Teleport to an absolute position on the arena.
|
|
158
|
+
*
|
|
159
|
+
* Max range: 300 units from current position (clamped by engine if further).
|
|
160
|
+
* Cast time: 10 ticks (0.1s). Cooldown scales with distance:
|
|
161
|
+
* - 100 units → 100 ticks (1s)
|
|
162
|
+
* - 300 units → 2000 ticks (20s)
|
|
163
|
+
*
|
|
164
|
+
* Cannot chain .move() — blink IS the movement.
|
|
165
|
+
*
|
|
166
|
+
* @param x - Target X position (0-800, absolute world coordinate)
|
|
167
|
+
* @param y - Target Y position (0-800, absolute world coordinate)
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* return blink(400, 400); // blink to center
|
|
171
|
+
* return blink(enemy.position.x, enemy.position.y); // blink to enemy
|
|
172
|
+
*/
|
|
173
|
+
export function blink(x: number, y: number): FinalAction
|
|
174
|
+
{
|
|
175
|
+
return createFinalAction({
|
|
176
|
+
move: {x: 0, y: 0}, // No manual movement with blink
|
|
177
|
+
startCast: {
|
|
178
|
+
spell: 'blink',
|
|
179
|
+
target: {x, y},
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Cancel current cast or channel (e.g. stop shielding to attack).
|
|
186
|
+
*
|
|
187
|
+
* Cancelling costs NO GCD. `gcdRemaining` is set only when a spell COMPLETES; the cancel
|
|
188
|
+
* handlers just return you to idle, so you can act on the very next tick.
|
|
189
|
+
*
|
|
190
|
+
* This said "triggers 100-tick (1s) GCD" and was wrong for as long as anyone can tell. It
|
|
191
|
+
* matters more than a typo: it makes every defender look 100 ticks slower than they are, so
|
|
192
|
+
* attacks that appear unpunishable on paper are not. Cancel-then-shield really costs 1 tick
|
|
193
|
+
* plus the 20-tick shield cast, not 120.
|
|
194
|
+
* Can chain .move() for simultaneous movement.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* return cancel().move(-1, 0); // cancel and dodge left
|
|
198
|
+
*/
|
|
199
|
+
export function cancel(): ActionBuilder
|
|
200
|
+
{
|
|
201
|
+
return createActionBuilder({
|
|
202
|
+
cancel: true,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Move in a direction without casting any spell.
|
|
208
|
+
*
|
|
209
|
+
* This is a **direction vector**, not a target position. Values are in the
|
|
210
|
+
* range [-1, 1] where 1 = full speed. Larger values (like raw position
|
|
211
|
+
* deltas) are clamped to full speed automatically.
|
|
212
|
+
*
|
|
213
|
+
* @param x - Horizontal direction (positive = right, negative = left)
|
|
214
|
+
* @param y - Vertical direction (positive = down, negative = up)
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* return move(1, 0); // move right at full speed
|
|
218
|
+
* return move(dx / dist, dy / dist); // normalized unit vector = full speed
|
|
219
|
+
* return move(enemy.position.x - myPos.x, enemy.position.y - myPos.y); // raw delta = clamped to full speed
|
|
220
|
+
*/
|
|
221
|
+
export function move(x: number, y: number): FinalAction
|
|
222
|
+
{
|
|
223
|
+
return createFinalAction({
|
|
224
|
+
move: {x, y},
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Do nothing — no action, no movement.
|
|
230
|
+
*/
|
|
231
|
+
export function idle(): FinalAction
|
|
232
|
+
{
|
|
233
|
+
return createFinalAction({
|
|
234
|
+
move: {x: 0, y: 0},
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// ============================================================
|
|
239
|
+
// MISSILE ACTION BUILDERS
|
|
240
|
+
// ============================================================
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Steer the missile toward a world position.
|
|
244
|
+
* The engine clamps the actual turn to the missile's turnRate.
|
|
245
|
+
*
|
|
246
|
+
* @param x - Target X position (world coordinates)
|
|
247
|
+
* @param y - Target Y position (world coordinates)
|
|
248
|
+
*/
|
|
249
|
+
export function turnToward(x: number, y: number): MissileAction
|
|
250
|
+
{
|
|
251
|
+
return {
|
|
252
|
+
_toMissileAction: () => ({turnToward: {x, y}}),
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Steer the missile toward a specific angle (degrees).
|
|
258
|
+
* The engine clamps the actual turn to the missile's turnRate.
|
|
259
|
+
*
|
|
260
|
+
* @param degrees - Target rotation in degrees (0=right, 90=down, 180=left, 270=up)
|
|
261
|
+
*/
|
|
262
|
+
export function turnToAngle(degrees: number): MissileAction
|
|
263
|
+
{
|
|
264
|
+
return {
|
|
265
|
+
_toMissileAction: () => ({turnToAngle: degrees}),
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Fly straight — no steering this tick.
|
|
271
|
+
*/
|
|
272
|
+
export function flyStraight(): MissileAction
|
|
273
|
+
{
|
|
274
|
+
return {
|
|
275
|
+
_toMissileAction: () => ({}),
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Extract MissileActions from a MissileAction.
|
|
281
|
+
* Used by the engine to get the actual missile action.
|
|
282
|
+
*/
|
|
283
|
+
export function extractMissileAction(action: MissileAction): MissileActions
|
|
284
|
+
{
|
|
285
|
+
return action._toMissileAction();
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// ============================================================
|
|
289
|
+
// WIZARD ACTION EXTRACTION
|
|
290
|
+
// ============================================================
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Extract WizardActions from a FinalAction.
|
|
294
|
+
* Used by the engine to get the actual action.
|
|
295
|
+
*/
|
|
296
|
+
export function extractAction(finalAction: FinalAction): WizardActions
|
|
297
|
+
{
|
|
298
|
+
return finalAction._toAction();
|
|
299
|
+
}
|