Skip to main content

subtr_actor/collector/ndarray/
analysis_builtins.rs

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}