55export const getMapId = ( x ) =>
66 x ?. map_id || x ?. map ?. id || x ?. map || x ?. id || x ?. pk || null ;
77
8- export const getModeId = ( x ) =>
9- x ?. mode_id || x ?. mode ?. id || x ?. mode || null ;
8+ export const getModeId = ( x ) =>
9+ // prefer explicit objective_mode fields, then generic mode fields
10+ x ?. objective_mode_id ||
11+ x ?. objective_mode ||
12+ x ?. mode_id ||
13+ x ?. mode ?. id ||
14+ x ?. mode ||
15+ x ?. modeId ||
16+ null ;
1017
1118export const getModeName = ( x ) => {
1219 if ( ! x ) return "" ;
@@ -15,21 +22,22 @@ export const getModeName = (x) => {
1522} ;
1623
1724export const isSlayerMode = ( modeVal ) => {
18- if ( ! modeVal ) return false ;
19-
20- // Check for mode ID 6 (Slayer)
21- if ( modeVal === 6 || modeVal === "6" ) return true ;
22-
23- // Check string values
25+ if ( modeVal == null ) return false ;
26+ // Prefer numeric mode id if available (mode.id, mode_id, or raw value)
27+ const parsed = Number ( modeVal ?. id ?? modeVal ?. mode_id ?? modeVal ) ;
28+ if ( ! isNaN ( parsed ) && parsed === 6 ) return true ;
29+ // Fallback: only treat explicit string mentions of "slayer" as Slayer
2430 if ( typeof modeVal === "string" ) {
25- return modeVal . toLowerCase ( ) === "slayer" || modeVal . toLowerCase ( ) . includes ( "slayer" ) ;
31+ const s = modeVal . toLowerCase ( ) ;
32+ return s === "slayer" || s . includes ( "slayer" ) ;
2633 }
27-
28- // Check name property
29- const name = modeVal . name || modeVal . mode_name || modeVal . mode || "" ;
30- return name . toLowerCase ( ) === "slayer" || name . toLowerCase ( ) . includes ( "slayer" ) ;
34+ // If object has a name-like property, check it safely
35+ const name = ( typeof modeVal ?. name === "string" && modeVal . name ) ||
36+ ( typeof modeVal ?. mode_name === "string" && modeVal . mode_name ) ||
37+ "" ;
38+ return name . toLowerCase ( ) . includes ( "slayer" ) ;
3139} ;
32-
40+
3341export function processBansAndPicks ( actions ) {
3442 const bans = actions ?. filter ( a => a . action_type === "BAN" ) || [ ] ;
3543 const picks = actions ?. filter ( a => a . action_type === "PICK" ) || [ ] ;
@@ -48,15 +56,18 @@ export function processBansAndPicks(actions) {
4856
4957 console . log ( `[DEBUG] Processing ban:` , ban ) ;
5058
51- // FIXED: Prioritize 'kind' field, then fallback to mode checks
52- const isSlayerBan =
53- ban . kind === "SLAYER_MAP" ||
54- ( ban . mode_id === 6 ) ||
55- ( ban . mode === "Slayer" ) ||
56- ( ban . mode_name === "Slayer" ) ||
57- isSlayerMode ( ban . mode ) ||
58- isSlayerMode ( ban . mode_name ) ;
59-
59+ // Determine mode id using helper, then decide if this is a Slayer ban.
60+ const banModeId = Number ( getModeId ( ban ) ) ;
61+
62+ // If kind explicitly indicates objective, trust it and never treat as Slayer.
63+ const kindStr = typeof ban . kind === "string" ? ban . kind . toUpperCase ( ) : "" ;
64+ const isObjectiveKind = kindStr . includes ( "OBJECTIVE" ) ;
65+ // Only treat numeric modeId === 6 as Slayer when kind is absent/ambiguous
66+ const isSlayerBan = ban . kind === "SLAYER_MAP" || ( ! isObjectiveKind && banModeId === 6 ) ;
67+ if ( banModeId === 6 && isObjectiveKind ) {
68+ console . warn ( `[WARN] Ban has mode=6 but kind=${ ban . kind } ; treating as OBJECTIVE_COMBO (defensive)` , ban ) ;
69+ }
70+
6071 console . log ( `[DEBUG] Map ${ ban . map } (ID: ${ mapId } ) - kind: ${ ban . kind } , isSlayerBan: ${ isSlayerBan } ` ) ;
6172
6273 if ( isSlayerBan ) {
@@ -75,21 +86,22 @@ export function processBansAndPicks(actions) {
7586 for ( const pick of picks ) {
7687 const mapId = Number ( getMapId ( pick ) ) ;
7788 if ( ! mapId ) continue ;
78-
89+
7990 pickedMapIds . add ( mapId ) ;
80-
91+
8192 const modeId = Number ( getModeId ( pick ) ) ;
8293 if ( modeId ) {
8394 pickedCombinations . add ( `${ mapId } :${ modeId } ` ) ;
8495 }
85-
86- const isSlayerPick =
87- pick . kind === "SLAYER_MAP" ||
88- pick . slot_type === "SLAYER" ||
89- ( pick . mode_id === 6 ) ||
90- isSlayerMode ( pick . mode ) ||
91- isSlayerMode ( pick . mode_name ) ;
92-
96+
97+ const pickModeId = Number ( getModeId ( pick ) ) ;
98+ const pickKindStr = typeof pick . kind === "string" ? pick . kind . toUpperCase ( ) : "" ;
99+ const pickIsObjectiveKind = pickKindStr . includes ( "OBJECTIVE" ) ;
100+ const isSlayerPick = pick . kind === "SLAYER_MAP" || ( ! pickIsObjectiveKind && pickModeId === 6 ) ;
101+ if ( pickModeId === 6 && pickIsObjectiveKind ) {
102+ console . warn ( `[WARN] Pick has mode=6 but kind=${ pick . kind } ; treating as OBJECTIVE (defensive)` , pick ) ;
103+ }
104+
93105 if ( isSlayerPick ) {
94106 slayerPickedMapIds . add ( mapId ) ;
95107 console . log ( `[DEBUG] Classified as SLAYER pick: ${ pick . map } ` ) ;
0 commit comments