1use crate::stats::analysis_graph::*;
2use crate::stats::calculators::*;
3use crate::*;
4use boxcars;
5
6macro_rules! build_analysis_player_event_indicator {
7 (
8 $struct_name:ident,
9 $dependency:ident,
10 $calculator:ty,
11 $events:ident,
12 $player_matches:expr,
13 $column_name:expr $(,)?
14 ) => {
15 build_analysis_player_feature_adder!(
16 $struct_name,
17 |_self_: &$struct_name<F>| vec![$dependency()],
18 |_self_: &$struct_name<F>,
19 context: &AnalysisFeatureContext<'_>,
20 player_id: &PlayerId,
21 _processor: &dyn ProcessorView,
22 _frame: &boxcars::Frame,
23 _frame_count: usize,
24 _current_time: f32| {
25 let player_matches = $player_matches;
26 let has_event = context
27 .state::<$calculator>()?
28 .$events()
29 .iter()
30 .any(|event| player_matches(event, player_id));
31 convert_all_floats!(f32::from(has_event))
32 },
33 $column_name,
34 );
35 };
36}
37
38build_analysis_player_event_indicator!(
39 AnalysisPlayerTouches,
40 touch_dependency,
41 TouchCalculator,
42 new_events,
43 |event: &TouchClassificationEvent, player_id: &PlayerId| &event.player == player_id,
44 "analysis touch event",
45);
46
47build_analysis_player_event_indicator!(
48 AnalysisPlayerCenters,
49 center_dependency,
50 CenterCalculator,
51 new_events,
52 |event: &CenterEvent, player_id: &PlayerId| &event.player == player_id,
53 "analysis center event",
54);
55
56build_analysis_player_event_indicator!(
57 AnalysisPlayerDoubleTaps,
58 double_tap_dependency,
59 DoubleTapCalculator,
60 new_events,
61 |event: &DoubleTapEvent, player_id: &PlayerId| &event.player == player_id,
62 "analysis double tap event",
63);
64
65build_analysis_player_event_indicator!(
66 AnalysisPlayerOneTimers,
67 one_timer_dependency,
68 OneTimerCalculator,
69 new_events,
70 |event: &OneTimerEvent, player_id: &PlayerId| {
71 &event.player == player_id || &event.passer == player_id
72 },
73 "analysis one timer event",
74);
75
76build_analysis_player_event_indicator!(
77 AnalysisPlayerWallAerials,
78 wall_aerial_dependency,
79 WallAerialCalculator,
80 new_events,
81 |event: &WallAerialEvent, player_id: &PlayerId| &event.player == player_id,
82 "analysis wall aerial event",
83);
84
85build_analysis_player_event_indicator!(
86 AnalysisPlayerWallAerialShots,
87 wall_aerial_shot_dependency,
88 WallAerialShotCalculator,
89 new_events,
90 |event: &WallAerialShotEvent, player_id: &PlayerId| &event.player == player_id,
91 "analysis wall aerial shot event",
92);
93
94build_analysis_player_event_indicator!(
95 AnalysisPlayerCeilingShots,
96 ceiling_shot_dependency,
97 CeilingShotCalculator,
98 new_events,
99 |event: &CeilingShotEvent, player_id: &PlayerId| &event.player == player_id,
100 "analysis ceiling shot event",
101);
102
103build_analysis_player_event_indicator!(
104 AnalysisPlayerFlicks,
105 flick_dependency,
106 FlickCalculator,
107 new_events,
108 |event: &FlickEvent, player_id: &PlayerId| &event.player == player_id,
109 "analysis flick event",
110);
111
112build_analysis_player_event_indicator!(
113 AnalysisPlayerMustyFlicks,
114 musty_flick_dependency,
115 MustyFlickCalculator,
116 new_events,
117 |event: &MustyFlickEvent, player_id: &PlayerId| &event.player == player_id,
118 "analysis musty flick event",
119);
120
121build_analysis_player_event_indicator!(
122 AnalysisPlayerDodgeResets,
123 dodge_reset_dependency,
124 DodgeResetCalculator,
125 new_events,
126 |event: &DodgeResetEvent, player_id: &PlayerId| &event.player == player_id,
127 "analysis dodge reset event",
128);
129
130build_analysis_player_event_indicator!(
131 AnalysisPlayerFlipResetDodges,
132 dodge_reset_dependency,
133 DodgeResetCalculator,
134 new_confirmed_flip_reset_events,
135 |event: &ConfirmedFlipResetEvent, player_id: &PlayerId| &event.player == player_id,
136 "analysis flip reset dodge event",
137);
138
139build_analysis_player_event_indicator!(
140 AnalysisPlayerHalfFlips,
141 half_flip_dependency,
142 HalfFlipCalculator,
143 new_events,
144 |event: &HalfFlipEvent, player_id: &PlayerId| &event.player == player_id,
145 "analysis half flip event",
146);
147
148build_analysis_player_event_indicator!(
149 AnalysisPlayerHalfVolleys,
150 half_volley_dependency,
151 HalfVolleyCalculator,
152 new_events,
153 |event: &HalfVolleyEvent, player_id: &PlayerId| &event.player == player_id,
154 "analysis half volley event",
155);
156
157build_analysis_player_event_indicator!(
158 AnalysisPlayerWavedashes,
159 wavedash_dependency,
160 WavedashCalculator,
161 new_events,
162 |event: &WavedashEvent, player_id: &PlayerId| &event.player == player_id,
163 "analysis wavedash event",
164);
165
166build_analysis_player_event_indicator!(
167 AnalysisPlayerWhiffs,
168 whiff_dependency,
169 WhiffCalculator,
170 new_events,
171 |event: &WhiffEvent, player_id: &PlayerId| &event.player == player_id,
172 "analysis whiff event",
173);
174
175build_analysis_player_event_indicator!(
176 AnalysisPlayerSpeedFlips,
177 speed_flip_dependency,
178 SpeedFlipCalculator,
179 new_events,
180 |event: &SpeedFlipEvent, player_id: &PlayerId| &event.player == player_id,
181 "analysis speed flip event",
182);
183
184build_analysis_player_event_indicator!(
185 AnalysisPlayerFlipImpulses,
186 flip_impulse_dependency,
187 FlipImpulseCalculator,
188 new_events,
189 |event: &DodgeEvent, player_id: &PlayerId| &event.player == player_id,
190 "analysis dodge event",
191);
192
193build_analysis_player_event_indicator!(
194 AnalysisPlayerPowerslides,
195 powerslide_dependency,
196 PowerslideCalculator,
197 new_events,
198 |event: &PowerslideEvent, player_id: &PlayerId| &event.player == player_id,
199 "analysis powerslide event",
200);
201
202build_analysis_player_event_indicator!(
203 AnalysisPlayerBallCarries,
204 ball_carry_dependency,
205 BallCarryCalculator,
206 new_carry_events,
207 |event: &BallCarryEvent, player_id: &PlayerId| &event.player_id == player_id,
208 "analysis ball carry event",
209);
210
211build_analysis_player_event_indicator!(
212 AnalysisPlayerBoostPickups,
213 boost_dependency,
214 BoostCalculator,
215 new_pickup_events,
216 |event: &BoostPickupEvent, player_id: &PlayerId| &event.player_id == player_id,
217 "analysis boost pickup event",
218);
219
220build_analysis_player_event_indicator!(
221 AnalysisPlayerBoostRespawns,
222 boost_dependency,
223 BoostCalculator,
224 new_respawn_events,
225 |event: &RespawnEvent, player_id: &PlayerId| &event.player_id == player_id,
226 "analysis boost respawn event",
227);
228
229build_analysis_player_event_indicator!(
230 AnalysisPlayerBumps,
231 bump_dependency,
232 BumpCalculator,
233 new_events,
234 |event: &BumpEvent, player_id: &PlayerId| {
235 &event.initiator == player_id || &event.victim == player_id
236 },
237 "analysis bump event",
238);
239
240build_analysis_player_event_indicator!(
241 AnalysisPlayerPasses,
242 pass_dependency,
243 PassCalculator,
244 new_events,
245 |event: &PassEvent, player_id: &PlayerId| {
246 &event.passer == player_id || &event.receiver == player_id
247 },
248 "analysis pass event",
249);
250
251build_analysis_player_event_indicator!(
252 AnalysisPlayerRotationEvents,
253 rotation_dependency,
254 RotationCalculator,
255 new_role_events,
256 |event: &RotationRoleEvent, player_id: &PlayerId| &event.player == player_id,
257 "analysis rotation event",
258);
259
260build_analysis_player_event_indicator!(
261 AnalysisPlayerMovementEvents,
262 movement_dependency,
263 MovementCalculator,
264 new_events,
265 |event: &MovementEvent, player_id: &PlayerId| &event.player == player_id,
266 "analysis movement event",
267);
268
269build_analysis_player_event_indicator!(
270 AnalysisPlayerPositioningEvents,
271 positioning_dependency,
272 PositioningCalculator,
273 new_event_players,
274 |event: &PlayerId, player_id: &PlayerId| event == player_id,
275 "analysis positioning event",
276);
277
278pub(crate) fn analysis_player_event_feature_adder_from_name<F>(
279 name: &str,
280) -> Option<NDArrayPlayerFeatureAdder<F>>
281where
282 F: TryFrom<f32> + Send + Sync + 'static,
283 <F as TryFrom<f32>>::Error: std::fmt::Debug,
284{
285 let event_name = name.strip_prefix("PlayerEvent:")?;
286
287 match event_name {
288 "touch" => Some(NDArrayPlayerFeatureAdder::analysis(
289 AnalysisPlayerTouches::<F>::arc_new(),
290 )),
291 "center" => Some(NDArrayPlayerFeatureAdder::analysis(
292 AnalysisPlayerCenters::<F>::arc_new(),
293 )),
294 "double_tap" => Some(NDArrayPlayerFeatureAdder::analysis(
295 AnalysisPlayerDoubleTaps::<F>::arc_new(),
296 )),
297 "one_timer" => Some(NDArrayPlayerFeatureAdder::analysis(
298 AnalysisPlayerOneTimers::<F>::arc_new(),
299 )),
300 "wall_aerial" => Some(NDArrayPlayerFeatureAdder::analysis(
301 AnalysisPlayerWallAerials::<F>::arc_new(),
302 )),
303 "wall_aerial_shot" => Some(NDArrayPlayerFeatureAdder::analysis(
304 AnalysisPlayerWallAerialShots::<F>::arc_new(),
305 )),
306 "ceiling_shot" => Some(NDArrayPlayerFeatureAdder::analysis(
307 AnalysisPlayerCeilingShots::<F>::arc_new(),
308 )),
309 "flick" => Some(NDArrayPlayerFeatureAdder::analysis(
310 AnalysisPlayerFlicks::<F>::arc_new(),
311 )),
312 "musty_flick" => Some(NDArrayPlayerFeatureAdder::analysis(
313 AnalysisPlayerMustyFlicks::<F>::arc_new(),
314 )),
315 "dodge_reset" => Some(NDArrayPlayerFeatureAdder::analysis(
316 AnalysisPlayerDodgeResets::<F>::arc_new(),
317 )),
318 "flip_reset_dodge" => Some(NDArrayPlayerFeatureAdder::analysis(
319 AnalysisPlayerFlipResetDodges::<F>::arc_new(),
320 )),
321 "half_flip" => Some(NDArrayPlayerFeatureAdder::analysis(
322 AnalysisPlayerHalfFlips::<F>::arc_new(),
323 )),
324 "half_volley" => Some(NDArrayPlayerFeatureAdder::analysis(
325 AnalysisPlayerHalfVolleys::<F>::arc_new(),
326 )),
327 "wavedash" => Some(NDArrayPlayerFeatureAdder::analysis(
328 AnalysisPlayerWavedashes::<F>::arc_new(),
329 )),
330 "whiff" => Some(NDArrayPlayerFeatureAdder::analysis(
331 AnalysisPlayerWhiffs::<F>::arc_new(),
332 )),
333 "speed_flip" => Some(NDArrayPlayerFeatureAdder::analysis(
334 AnalysisPlayerSpeedFlips::<F>::arc_new(),
335 )),
336 "dodge" | "flip_impulse" => Some(NDArrayPlayerFeatureAdder::analysis(
337 AnalysisPlayerFlipImpulses::<F>::arc_new(),
338 )),
339 "powerslide" => Some(NDArrayPlayerFeatureAdder::analysis(
340 AnalysisPlayerPowerslides::<F>::arc_new(),
341 )),
342 "ball_carry" => Some(NDArrayPlayerFeatureAdder::analysis(
343 AnalysisPlayerBallCarries::<F>::arc_new(),
344 )),
345 "boost_pickup" => Some(NDArrayPlayerFeatureAdder::analysis(
346 AnalysisPlayerBoostPickups::<F>::arc_new(),
347 )),
348 "boost_respawn" => Some(NDArrayPlayerFeatureAdder::analysis(
349 AnalysisPlayerBoostRespawns::<F>::arc_new(),
350 )),
351 "bump" => Some(NDArrayPlayerFeatureAdder::analysis(
352 AnalysisPlayerBumps::<F>::arc_new(),
353 )),
354 "pass" => Some(NDArrayPlayerFeatureAdder::analysis(
355 AnalysisPlayerPasses::<F>::arc_new(),
356 )),
357 "rotation" => Some(NDArrayPlayerFeatureAdder::analysis(
358 AnalysisPlayerRotationEvents::<F>::arc_new(),
359 )),
360 "movement" => Some(NDArrayPlayerFeatureAdder::analysis(
361 AnalysisPlayerMovementEvents::<F>::arc_new(),
362 )),
363 "positioning" => Some(NDArrayPlayerFeatureAdder::analysis(
364 AnalysisPlayerPositioningEvents::<F>::arc_new(),
365 )),
366 _ => None,
367 }
368}