]> git.sesse.net Git - pkanalytics/commitdiff
Support filtering passes by thrower and receiver. master
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 6 Aug 2023 15:31:27 +0000 (17:31 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 6 Aug 2023 15:31:27 +0000 (17:31 +0200)
ultimate.js

index ead0047cee0f5c4e4a92c318c4cb068491e5e0a1..f556ee4752d9d3594a7ab6f73dd6846df7182168 100644 (file)
@@ -649,23 +649,23 @@ function calc_stats(json, filters) {
                                // _not_ after an interception, or a self-pass that's not a goal.
                                // (It must mean we tipped off someone.) We'll count it as a regular one
                                // for the time being, although it will make hockey assists weird.
-                               if (keep) {
+                               if (keep) {  // TODO: keep_pass()?
                                        ++p.goals;
                                        ++p.callahans;
                                }
                                handler = prev_handler = null;
                        } else if (type === 'catch' || type === 'goal') {
                                if (handler !== null) {
-                                       if (keep) {
+                                       if (keep && keep_pass(handler, e['player'], filters)) {
                                                ++players[handler].num_throws;
                                                ++p.catches;
                                        }
                                }
 
-                               if (keep) ++p.touches;
+                               if (keep && keep_pass(handler, e['player'], filters)) ++p.touches;
                                ++touches_this_possession;
                                if (type === 'goal') {
-                                       if (keep) {
+                                       if (keep && keep_pass(handler, e['player'], filters)) {
                                                if (prev_handler !== null) {
                                                        ++players[prev_handler].hockey_assists;
                                                }
@@ -682,24 +682,24 @@ function calc_stats(json, filters) {
                                        handler_got_by_interception = false;
                                }
                        } else if (type === 'throwaway') {
-                               if (keep) {
+                               if (keep && keep_pass(e['player'], null, filters)) {
                                        ++p.num_throws;
                                        ++p.throwaways;
                                }
                                handler = prev_handler = null;
                        } else if (type === 'drop') {
-                               if (keep) ++p.drops;
+                               if (keep && keep_pass(handler, e['player'], filters)) ++p.drops;
                                handler = prev_handler = null;
                        } else if (type === 'stallout') {
                                if (keep) ++p.stallouts;
                                handler = prev_handler = null;
                        } else if (type === 'was_d') {
-                               if (keep) ++p.was_ds;
+                               if (keep && keep_pass(handler, e['player'], filters)) ++p.was_ds;
                                handler = prev_handler = null;
                        } else if (type === 'defense') {
                                if (keep) ++p.defenses;
                        } else if (type === 'interception') {
-                               if (keep) {
+                               if (keep && keep_pass(null, e['player'], filters)) {
                                        ++p.catches;
                                        ++p.defenses;
                                        ++p.touches;
@@ -1555,10 +1555,12 @@ function open_filter_menu(click_to_add_div) {
        add_menu_item(filter_div, filterset, menu, 0, 'match', 'Match (any)');
        add_menu_item(filter_div, filterset, menu, 1, 'player_any', 'Player on field (any)');
        add_menu_item(filter_div, filterset, menu, 2, 'player_all', 'Player on field (all)');
-       add_menu_item(filter_div, filterset, menu, 3, 'formation_offense', 'Offense played (any)');
-       add_menu_item(filter_div, filterset, menu, 4, 'formation_defense', 'Defense played (any)');
-       add_menu_item(filter_div, filterset, menu, 5, 'starting_on', 'Starting on');
-       add_menu_item(filter_div, filterset, menu, 6, 'gender_ratio', 'Gender ratio');
+       add_menu_item(filter_div, filterset, menu, 3, 'thrower', 'Thrower (any)');
+       add_menu_item(filter_div, filterset, menu, 4, 'receiver', 'Receiver (any)');
+       add_menu_item(filter_div, filterset, menu, 5, 'formation_offense', 'Offense played (any)');
+       add_menu_item(filter_div, filterset, menu, 6, 'formation_defense', 'Defense played (any)');
+       add_menu_item(filter_div, filterset, menu, 7, 'starting_on', 'Starting on');
+       add_menu_item(filter_div, filterset, menu, 8, 'gender_ratio', 'Gender ratio');
 }
 
 function add_menu_item(filter_div, filterset, menu, menu_idx, filter_type, title) {
@@ -1630,7 +1632,7 @@ function show_submenu(filter_div, filterset, menu_idx, pill, filter_type) {
                                'id': match['match_id']
                        });
                }
-       } else if (filter_type === 'player_any' || filter_type === 'player_all') {
+       } else if (filter_type === 'player_any' || filter_type === 'player_all' || filter_type === 'thrower' || filter_type === 'receiver') {
                for (const player of global_json['players']) {
                        choices.push({
                                'title': player['name'],
@@ -1930,8 +1932,14 @@ function make_filter_pill(filter_div, filterset, filter) {
                if (common_prefix !== null) {
                        text += ')';
                }
-       } else if (filter.type === 'player_any') {
-               text = 'Player (any): ';
+       } else if (filter.type === 'player_any' || filter.type === 'thrower' || filter.type === 'receiver') {
+               if (filter.type === 'player_any') {
+                       text = 'Player (any): ';
+               } else if (filter.type === 'thrower') {
+                       text = 'Thrower (any): ';
+               } else {
+                       text = 'Receiver (any): ';
+               }
                let sorted_players = Array.from(filter.elements).sort((a, b) => player_pos(a) - player_pos(b));
                let first = true;
                for (const player_id of sorted_players) {
@@ -2081,7 +2089,7 @@ function make_filter_marker(filterset) {
                                        text += desc.substr(common_prefix.length, 3);
                                }
                        }
-               } else if (filter.type === 'player_any' || filter.type === 'player_all') {
+               } else if (filter.type === 'player_any' || filter.type === 'player_all' || filter.type === 'thrower' || filter.type === 'receiver') {
                        let sorted_players = Array.from(filter.elements).sort((a, b) => player_pos(a) - player_pos(b));
                        if (filter.elements.size >= 3 && entire_gender(filter.elements)) {
                                text += find_player(sorted_players[0]).gender;
@@ -2293,6 +2301,8 @@ function filter_passes(players, formations_used_this_point, last_pull_was_ours,
        } else if (filter.type === 'gender_ratio') {
                return filter.elements.has(find_gender_ratio_code(players));
        }
+       // NOTE: thrower and receiver uses different state information and applies
+       // to throws only, so will be checked by keep_pass() instead.
        return true;
 }
 
@@ -2305,6 +2315,25 @@ function keep_event(players, formations_used_this_point, last_pull_was_ours, fil
        return true;
 }
 
+function pass_filter_passes(thrower, receiver, filter) {
+       if (filter.type === 'thrower') {
+               return filter.elements.has(thrower);
+       } else if (filter.type === 'receiver') {
+               return filter.elements.has(receiver);
+       }
+       // The others are tested in keep_event().
+       return true;
+}
+
+function keep_pass(thrower, receiver, filters) {
+       for (const filter of filters) {
+               if (!pass_filter_passes(thrower, receiver, filter)) {
+                       return false;
+               }
+       }
+       return true;
+}
+
 // Heuristic: If we go at least ten seconds without the possession changing
 // or the operator specifying some other formation, we probably play the
 // same formation as the last point.