@vibemancer/core 1.0.8 → 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/dist/{chunk-MUU3ELH5.js → chunk-OLGKLCCB.js} +36 -11
- package/dist/chunk-OLGKLCCB.js.map +1 -0
- package/dist/{index-browser-ClmR9SkR.d.ts → index-browser-BTHlrB_s.d.ts} +86 -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/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/types.ts +216 -200
- package/src/trace.ts +497 -490
- package/src/types.ts +9 -3
- package/dist/chunk-MUU3ELH5.js.map +0 -1
package/src/hooks/index.ts
CHANGED
|
@@ -1,83 +1,84 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* VIBEMANCER - HOOKS API
|
|
3
|
-
*
|
|
4
|
-
* Main export file for the hooks-based bot API.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
// Types
|
|
8
|
-
export type {
|
|
9
|
-
EnemyState,
|
|
10
|
-
AnalyzedThreat,
|
|
11
|
-
FinalAction,
|
|
12
|
-
ActionBuilder,
|
|
13
|
-
WizardFunction,
|
|
14
|
-
WizardContext,
|
|
15
|
-
MissileConfig,
|
|
16
|
-
MissileContext,
|
|
17
|
-
MissileAction,
|
|
18
|
-
MissileFunction,
|
|
19
|
-
} from './types.js';
|
|
20
|
-
|
|
21
|
-
// State hooks
|
|
22
|
-
export {
|
|
23
|
-
useRandom,
|
|
24
|
-
useHealth,
|
|
25
|
-
usePosition,
|
|
26
|
-
useVelocity,
|
|
27
|
-
useStatus,
|
|
28
|
-
useTicksUntilReady,
|
|
29
|
-
useShieldStrength,
|
|
30
|
-
useBlinkCooldown,
|
|
31
|
-
useCastingSpell,
|
|
32
|
-
useCastProgress,
|
|
33
|
-
useEnemy,
|
|
34
|
-
useProjectiles,
|
|
35
|
-
useMyProjectiles,
|
|
36
|
-
useLastMissileConfig,
|
|
37
|
-
useDamageDealt,
|
|
38
|
-
useDamageTaken,
|
|
39
|
-
useLastHitTick,
|
|
40
|
-
useArenaSize,
|
|
41
|
-
useTick,
|
|
42
|
-
useThreats,
|
|
43
|
-
useClosestThreat,
|
|
44
|
-
useMyThreatsToEnemy,
|
|
45
|
-
} from './state-hooks.js';
|
|
46
|
-
|
|
47
|
-
// Threat analysis (for advanced users who want direct access)
|
|
48
|
-
export {analyzeThreats} from './threat-analysis.js';
|
|
49
|
-
|
|
50
|
-
// Action builders
|
|
51
|
-
export {
|
|
52
|
-
shield,
|
|
53
|
-
missile,
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
export
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
export
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
export
|
|
1
|
+
/**
|
|
2
|
+
* VIBEMANCER - HOOKS API
|
|
3
|
+
*
|
|
4
|
+
* Main export file for the hooks-based bot API.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Types
|
|
8
|
+
export type {
|
|
9
|
+
EnemyState,
|
|
10
|
+
AnalyzedThreat,
|
|
11
|
+
FinalAction,
|
|
12
|
+
ActionBuilder,
|
|
13
|
+
WizardFunction,
|
|
14
|
+
WizardContext,
|
|
15
|
+
MissileConfig,
|
|
16
|
+
MissileContext,
|
|
17
|
+
MissileAction,
|
|
18
|
+
MissileFunction,
|
|
19
|
+
} from './types.js';
|
|
20
|
+
|
|
21
|
+
// State hooks
|
|
22
|
+
export {
|
|
23
|
+
useRandom,
|
|
24
|
+
useHealth,
|
|
25
|
+
usePosition,
|
|
26
|
+
useVelocity,
|
|
27
|
+
useStatus,
|
|
28
|
+
useTicksUntilReady,
|
|
29
|
+
useShieldStrength,
|
|
30
|
+
useBlinkCooldown,
|
|
31
|
+
useCastingSpell,
|
|
32
|
+
useCastProgress,
|
|
33
|
+
useEnemy,
|
|
34
|
+
useProjectiles,
|
|
35
|
+
useMyProjectiles,
|
|
36
|
+
useLastMissileConfig,
|
|
37
|
+
useDamageDealt,
|
|
38
|
+
useDamageTaken,
|
|
39
|
+
useLastHitTick,
|
|
40
|
+
useArenaSize,
|
|
41
|
+
useTick,
|
|
42
|
+
useThreats,
|
|
43
|
+
useClosestThreat,
|
|
44
|
+
useMyThreatsToEnemy,
|
|
45
|
+
} from './state-hooks.js';
|
|
46
|
+
|
|
47
|
+
// Threat analysis (for advanced users who want direct access)
|
|
48
|
+
export {analyzeThreats} from './threat-analysis.js';
|
|
49
|
+
|
|
50
|
+
// Action builders
|
|
51
|
+
export {
|
|
52
|
+
shield,
|
|
53
|
+
missile,
|
|
54
|
+
aim,
|
|
55
|
+
blink,
|
|
56
|
+
cancel,
|
|
57
|
+
move,
|
|
58
|
+
idle,
|
|
59
|
+
extractAction,
|
|
60
|
+
turnToward,
|
|
61
|
+
turnToAngle,
|
|
62
|
+
flyStraight,
|
|
63
|
+
extractMissileAction,
|
|
64
|
+
} from './action-builders.js';
|
|
65
|
+
|
|
66
|
+
// Re-export persistence hooks from runtime
|
|
67
|
+
export {
|
|
68
|
+
useState,
|
|
69
|
+
useEffect,
|
|
70
|
+
useMemo,
|
|
71
|
+
useRef,
|
|
72
|
+
runWizardWithContext,
|
|
73
|
+
withWizardContext,
|
|
74
|
+
withMissileContext,
|
|
75
|
+
getWizardContext,
|
|
76
|
+
getMissileContext,
|
|
77
|
+
} from '../engine/hooks-runtime.js';
|
|
78
|
+
|
|
79
|
+
// Re-export RefObject type
|
|
80
|
+
export type {RefObject} from '../engine/hooks-runtime.js';
|
|
81
|
+
|
|
82
|
+
// Parameter tuning hook
|
|
83
|
+
export {useParam} from '../engine/params-runtime.js';
|
|
84
|
+
export type {ParamDeclaration} from '../engine/params-runtime.js';
|
package/src/hooks/types.ts
CHANGED
|
@@ -1,200 +1,216 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* VIBEMANCER - HOOKS API TYPES
|
|
3
|
-
*
|
|
4
|
-
* Types for the hooks-based bot API.
|
|
5
|
-
*
|
|
6
|
-
* UNITS REFERENCE (100 ticks = 1 second):
|
|
7
|
-
* Position: absolute world coordinates, 0-860 on each axis. The arena is 860x860,
|
|
8
|
-
* but only [30, 830] is safe — the outer 30 units are lethal lava.
|
|
9
|
-
* Velocity: units per tick on each axis (player max speed = 1 u/t)
|
|
10
|
-
* Health: hit points (max 60)
|
|
11
|
-
* Ticks: game ticks (10ms each, 100/sec). Divide by 100 for seconds.
|
|
12
|
-
* Angles: degrees (0°=right, 90°=down, 180°=left, 270°=up)
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import {Position, Velocity, ProjectileState, MissileConfig, WizardActions, GameState, MissileActions} from '../types.js';
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Enemy wizard state as seen by your bot.
|
|
19
|
-
*
|
|
20
|
-
* Note: you cannot see the enemy's missile configs, cooldown timers, or
|
|
21
|
-
* damage history — only what's visible on the battlefield.
|
|
22
|
-
*/
|
|
23
|
-
export interface EnemyState
|
|
24
|
-
{
|
|
25
|
-
/** Enemy position in world coordinates (0-800). */
|
|
26
|
-
position: Position;
|
|
27
|
-
/** Enemy velocity in units/tick. */
|
|
28
|
-
velocity: Velocity;
|
|
29
|
-
/** Enemy current HP (0-60). */
|
|
30
|
-
health: number;
|
|
31
|
-
/** Enemy status: 'idle', 'casting', 'channeling' (shield), or 'gcd_locked'. */
|
|
32
|
-
status: 'idle' | 'casting' | 'channeling' | 'gcd_locked';
|
|
33
|
-
/** Which spell enemy is casting, or null. */
|
|
34
|
-
castingSpell: 'missile' | 'shield' | 'blink' | null;
|
|
35
|
-
/** Cast progress in ticks (0 if not casting). */
|
|
36
|
-
castProgress: number;
|
|
37
|
-
/** Total cast duration in ticks (0 if not casting). */
|
|
38
|
-
castDuration: number;
|
|
39
|
-
/** Remaining GCD ticks (0 if not in GCD). */
|
|
40
|
-
gcdRemaining: number;
|
|
41
|
-
/** Duration the enemy has been channeling in ticks (0 if not channeling). */
|
|
42
|
-
channelDuration: number;
|
|
43
|
-
/** Enemy shield block multiplier (0 if not shielding, 0.3-0.9 if shielding). */
|
|
44
|
-
shieldStrength: number;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Pre-computed analysis of an incoming enemy projectile.
|
|
49
|
-
*
|
|
50
|
-
* All timing values are in ticks (100 ticks = 1 second).
|
|
51
|
-
* Dodge directions are relative to missile heading, not world axes.
|
|
52
|
-
*/
|
|
53
|
-
export interface AnalyzedThreat
|
|
54
|
-
{
|
|
55
|
-
/** Unique projectile ID. */
|
|
56
|
-
id: string;
|
|
57
|
-
/** Raw projectile state (position, rotation in degrees, speed in u/t, turnRate, remainingTicks). */
|
|
58
|
-
projectile: ProjectileState;
|
|
59
|
-
|
|
60
|
-
/** Ticks until missile hits your current position. Infinity if predicted to miss. */
|
|
61
|
-
ticksToImpact: number;
|
|
62
|
-
/** Whether the missile will hit if you stand still. */
|
|
63
|
-
willHit: boolean;
|
|
64
|
-
|
|
65
|
-
/** Whether strafing left (perpendicular to missile heading) avoids it. */
|
|
66
|
-
canDodgeLeft: boolean;
|
|
67
|
-
/** Whether strafing right (perpendicular to missile heading) avoids it. */
|
|
68
|
-
canDodgeRight: boolean;
|
|
69
|
-
/** Whether moving directly away from the missile avoids it. */
|
|
70
|
-
canOutrun: boolean;
|
|
71
|
-
/** Optimal dodge direction as a unit vector {x, y}, or null if undodgeable. */
|
|
72
|
-
bestDodgeDirection: Position | null;
|
|
73
|
-
|
|
74
|
-
/** Whether you can channel shield before the missile arrives. */
|
|
75
|
-
canBlockInTime: boolean;
|
|
76
|
-
/** Ticks from now when you should START channeling shield to block in time. */
|
|
77
|
-
ticksToStartShield: number;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Final action that can be returned from a bot.
|
|
82
|
-
* Cannot be further chained.
|
|
83
|
-
*/
|
|
84
|
-
export interface FinalAction
|
|
85
|
-
{
|
|
86
|
-
/** Internal: extract the WizardActions */
|
|
87
|
-
readonly _toAction: () => WizardActions;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Action builder that allows chaining .move() for simultaneous movement.
|
|
92
|
-
* Returned by shield(), missile(), and cancel().
|
|
93
|
-
*/
|
|
94
|
-
export interface ActionBuilder extends FinalAction
|
|
95
|
-
{
|
|
96
|
-
/**
|
|
97
|
-
* Add movement to this action (e.g., move while casting).
|
|
98
|
-
* Direction vector, not absolute position. Auto-normalized.
|
|
99
|
-
* Positive X = right, positive Y = down.
|
|
100
|
-
*/
|
|
101
|
-
move(x: number, y: number): FinalAction;
|
|
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
|
-
export
|
|
1
|
+
/**
|
|
2
|
+
* VIBEMANCER - HOOKS API TYPES
|
|
3
|
+
*
|
|
4
|
+
* Types for the hooks-based bot API.
|
|
5
|
+
*
|
|
6
|
+
* UNITS REFERENCE (100 ticks = 1 second):
|
|
7
|
+
* Position: absolute world coordinates, 0-860 on each axis. The arena is 860x860,
|
|
8
|
+
* but only [30, 830] is safe — the outer 30 units are lethal lava.
|
|
9
|
+
* Velocity: units per tick on each axis (player max speed = 1 u/t)
|
|
10
|
+
* Health: hit points (max 60)
|
|
11
|
+
* Ticks: game ticks (10ms each, 100/sec). Divide by 100 for seconds.
|
|
12
|
+
* Angles: degrees (0°=right, 90°=down, 180°=left, 270°=up)
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import {Position, Velocity, ProjectileState, MissileConfig, WizardActions, GameState, MissileActions} from '../types.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Enemy wizard state as seen by your bot.
|
|
19
|
+
*
|
|
20
|
+
* Note: you cannot see the enemy's missile configs, cooldown timers, or
|
|
21
|
+
* damage history — only what's visible on the battlefield.
|
|
22
|
+
*/
|
|
23
|
+
export interface EnemyState
|
|
24
|
+
{
|
|
25
|
+
/** Enemy position in world coordinates (0-800). */
|
|
26
|
+
position: Position;
|
|
27
|
+
/** Enemy velocity in units/tick. */
|
|
28
|
+
velocity: Velocity;
|
|
29
|
+
/** Enemy current HP (0-60). */
|
|
30
|
+
health: number;
|
|
31
|
+
/** Enemy status: 'idle', 'casting', 'channeling' (shield), or 'gcd_locked'. */
|
|
32
|
+
status: 'idle' | 'casting' | 'channeling' | 'gcd_locked';
|
|
33
|
+
/** Which spell enemy is casting, or null. */
|
|
34
|
+
castingSpell: 'missile' | 'shield' | 'blink' | null;
|
|
35
|
+
/** Cast progress in ticks (0 if not casting). */
|
|
36
|
+
castProgress: number;
|
|
37
|
+
/** Total cast duration in ticks (0 if not casting). */
|
|
38
|
+
castDuration: number;
|
|
39
|
+
/** Remaining GCD ticks (0 if not in GCD). */
|
|
40
|
+
gcdRemaining: number;
|
|
41
|
+
/** Duration the enemy has been channeling in ticks (0 if not channeling). */
|
|
42
|
+
channelDuration: number;
|
|
43
|
+
/** Enemy shield block multiplier (0 if not shielding, 0.3-0.9 if shielding). */
|
|
44
|
+
shieldStrength: number;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Pre-computed analysis of an incoming enemy projectile.
|
|
49
|
+
*
|
|
50
|
+
* All timing values are in ticks (100 ticks = 1 second).
|
|
51
|
+
* Dodge directions are relative to missile heading, not world axes.
|
|
52
|
+
*/
|
|
53
|
+
export interface AnalyzedThreat
|
|
54
|
+
{
|
|
55
|
+
/** Unique projectile ID. */
|
|
56
|
+
id: string;
|
|
57
|
+
/** Raw projectile state (position, rotation in degrees, speed in u/t, turnRate, remainingTicks). */
|
|
58
|
+
projectile: ProjectileState;
|
|
59
|
+
|
|
60
|
+
/** Ticks until missile hits your current position. Infinity if predicted to miss. */
|
|
61
|
+
ticksToImpact: number;
|
|
62
|
+
/** Whether the missile will hit if you stand still. */
|
|
63
|
+
willHit: boolean;
|
|
64
|
+
|
|
65
|
+
/** Whether strafing left (perpendicular to missile heading) avoids it. */
|
|
66
|
+
canDodgeLeft: boolean;
|
|
67
|
+
/** Whether strafing right (perpendicular to missile heading) avoids it. */
|
|
68
|
+
canDodgeRight: boolean;
|
|
69
|
+
/** Whether moving directly away from the missile avoids it. */
|
|
70
|
+
canOutrun: boolean;
|
|
71
|
+
/** Optimal dodge direction as a unit vector {x, y}, or null if undodgeable. */
|
|
72
|
+
bestDodgeDirection: Position | null;
|
|
73
|
+
|
|
74
|
+
/** Whether you can channel shield before the missile arrives. */
|
|
75
|
+
canBlockInTime: boolean;
|
|
76
|
+
/** Ticks from now when you should START channeling shield to block in time. */
|
|
77
|
+
ticksToStartShield: number;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Final action that can be returned from a bot.
|
|
82
|
+
* Cannot be further chained.
|
|
83
|
+
*/
|
|
84
|
+
export interface FinalAction
|
|
85
|
+
{
|
|
86
|
+
/** Internal: extract the WizardActions */
|
|
87
|
+
readonly _toAction: () => WizardActions;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Action builder that allows chaining .move() for simultaneous movement.
|
|
92
|
+
* Returned by shield(), missile(), and cancel().
|
|
93
|
+
*/
|
|
94
|
+
export interface ActionBuilder extends FinalAction
|
|
95
|
+
{
|
|
96
|
+
/**
|
|
97
|
+
* Add movement to this action (e.g., move while casting).
|
|
98
|
+
* Direction vector, not absolute position. Auto-normalized.
|
|
99
|
+
* Positive X = right, positive Y = down.
|
|
100
|
+
*/
|
|
101
|
+
move(x: number, y: number): FinalAction;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Fire at the angle you asked for, instead of auto-aiming at the enemy.
|
|
105
|
+
*
|
|
106
|
+
* By default a wizard re-aims at the enemy's CURRENT position every tick, and a missile
|
|
107
|
+
* launches with the rotation it has when the cast finishes — so the `direction` you pass
|
|
108
|
+
* to `missile()` is overwritten before the shot leaves. That makes the enemy impossible
|
|
109
|
+
* to LEAD: you always fire where they are, never where they will be.
|
|
110
|
+
*
|
|
111
|
+
* `lockAim()` holds your angle for the whole cast, which is what makes `getLeadPosition`
|
|
112
|
+
* and `interceptAngle` worth using. It is opt-in precisely because auto-aim is the right
|
|
113
|
+
* default for most bots: lock your aim and a target that moves during the cast is missed.
|
|
114
|
+
*
|
|
115
|
+
* Chainable — `missile(cfg, ai, angle).lockAim().move(0, 1)` aims, fires and kites.
|
|
116
|
+
*/
|
|
117
|
+
lockAim(): ActionBuilder;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Wizard function type for the hooks API.
|
|
122
|
+
* Called every tick. Read state with hooks, return an action.
|
|
123
|
+
*/
|
|
124
|
+
export type WizardFunction = () => FinalAction;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Internal context for game state hooks.
|
|
128
|
+
*/
|
|
129
|
+
export interface WizardContext
|
|
130
|
+
{
|
|
131
|
+
entityId: string;
|
|
132
|
+
tick: number;
|
|
133
|
+
position: Position;
|
|
134
|
+
velocity: Velocity;
|
|
135
|
+
health: number;
|
|
136
|
+
maxHealth: number;
|
|
137
|
+
state: 'idle' | 'casting' | 'channeling' | 'gcd_locked';
|
|
138
|
+
castingSpell?: 'missile' | 'shield' | 'blink';
|
|
139
|
+
castProgress?: number;
|
|
140
|
+
castDuration?: number;
|
|
141
|
+
channelingSpell?: 'shield';
|
|
142
|
+
channelDuration?: number;
|
|
143
|
+
gcdRemaining?: number;
|
|
144
|
+
blinkCooldown: number;
|
|
145
|
+
lastMissileConfig?: MissileConfig;
|
|
146
|
+
enemies: Array<{
|
|
147
|
+
id: string;
|
|
148
|
+
position: Position;
|
|
149
|
+
velocity: Velocity;
|
|
150
|
+
health: number;
|
|
151
|
+
state: 'idle' | 'casting' | 'channeling' | 'gcd_locked';
|
|
152
|
+
castingSpell?: 'missile' | 'shield' | 'blink';
|
|
153
|
+
castProgress?: number;
|
|
154
|
+
castDuration?: number;
|
|
155
|
+
gcdRemaining?: number;
|
|
156
|
+
channelingSpell?: 'shield';
|
|
157
|
+
channelDuration?: number;
|
|
158
|
+
}>;
|
|
159
|
+
projectiles: ProjectileState[];
|
|
160
|
+
myProjectiles: ProjectileState[];
|
|
161
|
+
arenaWidth: number;
|
|
162
|
+
arenaHeight: number;
|
|
163
|
+
damageDealt: number;
|
|
164
|
+
damageTaken: number;
|
|
165
|
+
lastHitTick: number;
|
|
166
|
+
random: () => number;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Context available to missile AI functions via getMissileContext().
|
|
171
|
+
* Provides missile state, the full game state from the owner's perspective,
|
|
172
|
+
* and a seeded PRNG.
|
|
173
|
+
*/
|
|
174
|
+
export interface MissileContext
|
|
175
|
+
{
|
|
176
|
+
/** Missile position in world coordinates. */
|
|
177
|
+
position: Position;
|
|
178
|
+
/** Missile heading in degrees (0=right, 90=down). */
|
|
179
|
+
rotation: number;
|
|
180
|
+
/** Missile speed in units/tick. */
|
|
181
|
+
speed: number;
|
|
182
|
+
/** Missile turn rate in degrees/tick. */
|
|
183
|
+
turnRate: number;
|
|
184
|
+
/** Missile damage on hit. */
|
|
185
|
+
damage: number;
|
|
186
|
+
/** Ticks remaining before the missile expires. */
|
|
187
|
+
remainingTicks: number;
|
|
188
|
+
/** ID of the wizard who owns this missile. */
|
|
189
|
+
ownerId: string;
|
|
190
|
+
/** Full game state from the missile owner's perspective. */
|
|
191
|
+
worldState: GameState;
|
|
192
|
+
/** Seeded PRNG [0, 1). Deterministic per missile per tick. */
|
|
193
|
+
random: () => number;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Action returned by a missile AI function.
|
|
198
|
+
* Call turnToward(x, y) to steer, or flyStraight() to coast.
|
|
199
|
+
*/
|
|
200
|
+
export interface MissileAction
|
|
201
|
+
{
|
|
202
|
+
/** Internal: extract the MissileActions */
|
|
203
|
+
readonly _toMissileAction: () => MissileActions;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Missile AI function type for the hooks API.
|
|
208
|
+
* Called every tick for each in-flight missile.
|
|
209
|
+
* Read state with getMissileContext(), return a MissileAction.
|
|
210
|
+
*/
|
|
211
|
+
export type MissileFunction = () => MissileAction;
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Missile configuration for action builders.
|
|
215
|
+
*/
|
|
216
|
+
export type {MissileConfig};
|