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_2021,
13 $column_name:expr_2021 $(,)?
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 AnalysisPlayerDodgeResets,
114 dodge_reset_dependency,
115 DodgeResetCalculator,
116 new_events,
117 |event: &DodgeResetEvent, player_id: &PlayerId| &event.player == player_id,
118 "analysis dodge reset event",
119);
120
121build_analysis_player_event_indicator!(
122 AnalysisPlayerFlipResetDodges,
123 dodge_reset_dependency,
124 DodgeResetCalculator,
125 new_confirmed_flip_reset_events,
126 |event: &FlipResetEvent, player_id: &PlayerId| &event.player == player_id,
127 "analysis flip reset dodge event",
128);
129
130build_analysis_player_event_indicator!(
131 AnalysisPlayerHalfFlips,
132 half_flip_dependency,
133 HalfFlipCalculator,
134 new_events,
135 |event: &HalfFlipEvent, player_id: &PlayerId| &event.player == player_id,
136 "analysis half flip event",
137);
138
139build_analysis_player_event_indicator!(
140 AnalysisPlayerHalfVolleys,
141 half_volley_dependency,
142 HalfVolleyCalculator,
143 new_events,
144 |event: &HalfVolleyEvent, player_id: &PlayerId| &event.player == player_id,
145 "analysis half volley event",
146);
147
148build_analysis_player_event_indicator!(
149 AnalysisPlayerWavedashes,
150 wavedash_dependency,
151 WavedashCalculator,
152 new_events,
153 |event: &WavedashEvent, player_id: &PlayerId| &event.player == player_id,
154 "analysis wavedash event",
155);
156
157build_analysis_player_event_indicator!(
158 AnalysisPlayerWhiffs,
159 whiff_dependency,
160 WhiffCalculator,
161 new_events,
162 |event: &WhiffEvent, player_id: &PlayerId| &event.player == player_id,
163 "analysis whiff event",
164);
165
166build_analysis_player_event_indicator!(
167 AnalysisPlayerSpeedFlips,
168 speed_flip_dependency,
169 SpeedFlipCalculator,
170 new_events,
171 |event: &SpeedFlipEvent, player_id: &PlayerId| &event.player == player_id,
172 "analysis speed flip event",
173);
174
175build_analysis_player_event_indicator!(
176 AnalysisPlayerFlipImpulses,
177 flip_impulse_dependency,
178 FlipImpulseCalculator,
179 new_events,
180 |event: &DodgeEvent, player_id: &PlayerId| &event.player == player_id,
181 "analysis dodge event",
182);
183
184build_analysis_player_event_indicator!(
185 AnalysisPlayerPowerslides,
186 powerslide_dependency,
187 PowerslideCalculator,
188 new_events,
189 |event: &PowerslideEvent, player_id: &PlayerId| &event.player == player_id,
190 "analysis powerslide event",
191);
192
193build_analysis_player_event_indicator!(
194 AnalysisPlayerBallCarries,
195 ball_carry_dependency,
196 BallCarryCalculator,
197 new_carry_events,
198 |event: &BallCarryEvent, player_id: &PlayerId| &event.player_id == player_id,
199 "analysis ball carry event",
200);
201
202build_analysis_player_event_indicator!(
203 AnalysisPlayerBoostPickups,
204 boost_dependency,
205 BoostCalculator,
206 new_pickup_events,
207 |event: &BoostPickupEvent, player_id: &PlayerId| &event.player_id == player_id,
208 "analysis boost pickup event",
209);
210
211build_analysis_player_event_indicator!(
212 AnalysisPlayerBoostRespawns,
213 boost_dependency,
214 BoostCalculator,
215 new_respawn_events,
216 |event: &RespawnEvent, player_id: &PlayerId| &event.player_id == player_id,
217 "analysis boost respawn event",
218);
219
220build_analysis_player_event_indicator!(
221 AnalysisPlayerBumps,
222 bump_dependency,
223 BumpCalculator,
224 new_events,
225 |event: &BumpEvent, player_id: &PlayerId| {
226 &event.initiator == player_id || &event.victim == player_id
227 },
228 "analysis bump event",
229);
230
231build_analysis_player_event_indicator!(
232 AnalysisPlayerPasses,
233 pass_dependency,
234 PassCalculator,
235 new_events,
236 |event: &PassEvent, player_id: &PlayerId| {
237 &event.passer == player_id || &event.receiver == player_id
238 },
239 "analysis pass event",
240);
241
242build_analysis_player_event_indicator!(
243 AnalysisPlayerRotationEvents,
244 rotation_dependency,
245 RotationCalculator,
246 new_role_events,
247 |event: &RotationRoleEvent, player_id: &PlayerId| &event.player == player_id,
248 "analysis rotation event",
249);
250
251build_analysis_player_event_indicator!(
252 AnalysisPlayerMovementEvents,
253 movement_dependency,
254 MovementCalculator,
255 new_events,
256 |event: &MovementEvent, player_id: &PlayerId| &event.player == player_id,
257 "analysis movement event",
258);
259
260build_analysis_player_event_indicator!(
261 AnalysisPlayerPositioningEvents,
262 positioning_dependency,
263 PositioningCalculator,
264 new_event_players,
265 |event: &PlayerId, player_id: &PlayerId| event == player_id,
266 "analysis positioning event",
267);
268
269pub(crate) fn analysis_player_event_feature_adder_from_name<F>(
270 name: &str,
271) -> Option<NDArrayPlayerFeatureAdder<F>>
272where
273 F: TryFrom<f32> + Send + Sync + 'static,
274 <F as TryFrom<f32>>::Error: std::fmt::Debug,
275{
276 let event_name = name.strip_prefix("PlayerEvent:")?;
277
278 match event_name {
279 "touch" => Some(NDArrayPlayerFeatureAdder::analysis(
280 AnalysisPlayerTouches::<F>::arc_new(),
281 )),
282 "center" => Some(NDArrayPlayerFeatureAdder::analysis(
283 AnalysisPlayerCenters::<F>::arc_new(),
284 )),
285 "double_tap" => Some(NDArrayPlayerFeatureAdder::analysis(
286 AnalysisPlayerDoubleTaps::<F>::arc_new(),
287 )),
288 "one_timer" => Some(NDArrayPlayerFeatureAdder::analysis(
289 AnalysisPlayerOneTimers::<F>::arc_new(),
290 )),
291 "wall_aerial" => Some(NDArrayPlayerFeatureAdder::analysis(
292 AnalysisPlayerWallAerials::<F>::arc_new(),
293 )),
294 "wall_aerial_shot" => Some(NDArrayPlayerFeatureAdder::analysis(
295 AnalysisPlayerWallAerialShots::<F>::arc_new(),
296 )),
297 "ceiling_shot" => Some(NDArrayPlayerFeatureAdder::analysis(
298 AnalysisPlayerCeilingShots::<F>::arc_new(),
299 )),
300 "flick" => Some(NDArrayPlayerFeatureAdder::analysis(
301 AnalysisPlayerFlicks::<F>::arc_new(),
302 )),
303 "dodge_reset" => Some(NDArrayPlayerFeatureAdder::analysis(
304 AnalysisPlayerDodgeResets::<F>::arc_new(),
305 )),
306 "flip_reset_dodge" => Some(NDArrayPlayerFeatureAdder::analysis(
307 AnalysisPlayerFlipResetDodges::<F>::arc_new(),
308 )),
309 "half_flip" => Some(NDArrayPlayerFeatureAdder::analysis(
310 AnalysisPlayerHalfFlips::<F>::arc_new(),
311 )),
312 "half_volley" => Some(NDArrayPlayerFeatureAdder::analysis(
313 AnalysisPlayerHalfVolleys::<F>::arc_new(),
314 )),
315 "wavedash" => Some(NDArrayPlayerFeatureAdder::analysis(
316 AnalysisPlayerWavedashes::<F>::arc_new(),
317 )),
318 "whiff" => Some(NDArrayPlayerFeatureAdder::analysis(
319 AnalysisPlayerWhiffs::<F>::arc_new(),
320 )),
321 "speed_flip" => Some(NDArrayPlayerFeatureAdder::analysis(
322 AnalysisPlayerSpeedFlips::<F>::arc_new(),
323 )),
324 "dodge" | "flip_impulse" => Some(NDArrayPlayerFeatureAdder::analysis(
325 AnalysisPlayerFlipImpulses::<F>::arc_new(),
326 )),
327 "powerslide" => Some(NDArrayPlayerFeatureAdder::analysis(
328 AnalysisPlayerPowerslides::<F>::arc_new(),
329 )),
330 "ball_carry" => Some(NDArrayPlayerFeatureAdder::analysis(
331 AnalysisPlayerBallCarries::<F>::arc_new(),
332 )),
333 "boost_pickup" => Some(NDArrayPlayerFeatureAdder::analysis(
334 AnalysisPlayerBoostPickups::<F>::arc_new(),
335 )),
336 "boost_respawn" => Some(NDArrayPlayerFeatureAdder::analysis(
337 AnalysisPlayerBoostRespawns::<F>::arc_new(),
338 )),
339 "bump" => Some(NDArrayPlayerFeatureAdder::analysis(
340 AnalysisPlayerBumps::<F>::arc_new(),
341 )),
342 "pass" => Some(NDArrayPlayerFeatureAdder::analysis(
343 AnalysisPlayerPasses::<F>::arc_new(),
344 )),
345 "rotation" => Some(NDArrayPlayerFeatureAdder::analysis(
346 AnalysisPlayerRotationEvents::<F>::arc_new(),
347 )),
348 "movement" => Some(NDArrayPlayerFeatureAdder::analysis(
349 AnalysisPlayerMovementEvents::<F>::arc_new(),
350 )),
351 "positioning" => Some(NDArrayPlayerFeatureAdder::analysis(
352 AnalysisPlayerPositioningEvents::<F>::arc_new(),
353 )),
354 _ => None,
355 }
356}