From 5d71b3a28ff00daa3aaeb66ecb36096e4a1d7fbf Mon Sep 17 00:00:00 2001 From: MacChaeger Date: Fri, 20 Nov 2020 02:50:09 -0600 Subject: [PATCH] Dexsearch: Support resists move and weak move (#7713) --- server/chat-plugins/datasearch.ts | 48 ++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/server/chat-plugins/datasearch.ts b/server/chat-plugins/datasearch.ts index f9fceea1db..fed5fc6cce 100644 --- a/server/chat-plugins/datasearch.ts +++ b/server/chat-plugins/datasearch.ts @@ -133,13 +133,13 @@ export const commands: ChatCommands = { dexsearchhelp() { this.sendReplyBox( `/dexsearch [parameter], [parameter], [parameter], ...: searches for Pok\u00e9mon that fulfill the selected criteria
` + - `Search categories are: type, tier, color, moves, ability, gen, resists, recovery, zrecovery, priority, stat, weight, height, egg group.
` + + `Search categories are: type, tier, color, moves, ability, gen, resists, weak, recovery, zrecovery, priority, stat, weight, height, egg group.
` + `Valid colors are: green, red, blue, white, brown, yellow, purple, pink, gray and black.
` + `Valid tiers are: Uber/OU/UUBL/UU/RUBL/RU/NUBL/NU/PUBL/PU/ZU/NFE/LC Uber/LC/CAP/CAP NFE/CAP LC.
` + `Valid doubles tiers are: DUber/DOU/DBL/DUU/DNU.
` + `Types can be searched for by either having the type precede type or just using the type itself as a parameter; e.g., both fire type and fire show all Fire types; however, using psychic as a parameter will show all Pok\u00e9mon that learn the move Psychic and not Psychic types.
` + - `resists followed by a type will show Pok\u00e9mon that resist that typing (e.g. resists normal).
` + - `weak followed by a type will show Pok\u00e9mon that are weak to that typing (e.g. weak fire).
` + + `resists followed by a type or move will show Pok\u00e9mon that resist that typing or move (e.g. resists normal).
` + + `weak followed by a type or move will show Pok\u00e9mon that are weak to that typing or move (e.g. weak fire).
` + `asc or desc following a stat will show the Pok\u00e9mon in ascending or descending order of that stat respectively (e.g. speed asc).
` + `Inequality ranges use the characters >= for and <= for ; e.g., hp <= 95 searches all Pok\u00e9mon with HP less than or equal to 95.
` + `Parameters can be excluded through the use of !; e.g., !water type excludes all Water types.
` + @@ -758,7 +758,7 @@ function runDexsearch(target: string, cmd: string, canAll: boolean, message: str if (target.substr(0, 8) === 'resists ') { const targetResist = target.substr(8, 1).toUpperCase() + target.substr(9); - if (targetResist in Dex.data.TypeChart) { + if (targetResist in Dex.data.TypeChart || toID(targetResist) in Dex.data.Moves) { const invalid = validParameter("resists", targetResist, isNotSearch, target); if (invalid) return {error: invalid}; orGroup.resists[targetResist] = !isNotSearch; @@ -770,7 +770,7 @@ function runDexsearch(target: string, cmd: string, canAll: boolean, message: str if (target.substr(0, 5) === 'weak ') { const targetWeak = target.substr(5, 1).toUpperCase() + target.substr(6); - if (targetWeak in Dex.data.TypeChart) { + if (targetWeak in Dex.data.TypeChart || toID(targetWeak) in Dex.data.Moves) { const invalid = validParameter("weak", targetWeak, isNotSearch, target); if (invalid) return {error: invalid}; orGroup.weak[targetWeak] = !isNotSearch; @@ -943,11 +943,22 @@ function runDexsearch(target: string, cmd: string, canAll: boolean, message: str } if (matched) continue; - for (const type in alts.resists) { + for (const targetResist in alts.resists) { let effectiveness = 0; - const notImmune = mod.getImmunity(type, dex[mon]); - if (notImmune) effectiveness = mod.getEffectiveness(type, dex[mon]); - if (!alts.resists[type]) { + const move = Dex.getMove(targetResist); + const attackingType = move.type || targetResist; + const notImmune = mod.getImmunity(attackingType, dex[mon]) || !move.exists || + !move.ignoreImmunity || (move.ignoreImmunity !== true && !move.ignoreImmunity[move.type]); + if (notImmune) { + for (const defenderType of dex[mon].types) { + const baseMod = Dex.getEffectiveness(attackingType, defenderType); + const moveMod = move.onEffectiveness?.call( + {dex: Dex} as Battle, baseMod, null, defenderType, move as ActiveMove, + ); + effectiveness += typeof moveMod === 'number' ? moveMod : baseMod; + } + } + if (!alts.resists[targetResist]) { if (notImmune && effectiveness >= 0) matched = true; } else { if (!notImmune || effectiveness < 0) matched = true; @@ -955,11 +966,22 @@ function runDexsearch(target: string, cmd: string, canAll: boolean, message: str } if (matched) continue; - for (const type in alts.weak) { + for (const targetWeak in alts.weak) { let effectiveness = 0; - const notImmune = mod.getImmunity(type, dex[mon]); - if (notImmune) effectiveness = mod.getEffectiveness(type, dex[mon]); - if (alts.weak[type]) { + const move = Dex.getMove(targetWeak); + const attackingType = move.type || targetWeak; + const notImmune = mod.getImmunity(attackingType, dex[mon]) || !move.exists || + !move.ignoreImmunity || (move.ignoreImmunity !== true && !move.ignoreImmunity[move.type]); + if (notImmune) { + for (const defenderType of dex[mon].types) { + const baseMod = Dex.getEffectiveness(attackingType, defenderType); + const moveMod = move.onEffectiveness?.call( + {dex: Dex} as Battle, baseMod, null, defenderType, move as ActiveMove, + ); + effectiveness += typeof moveMod === 'number' ? moveMod : baseMod; + } + } + if (alts.weak[targetWeak]) { if (notImmune && effectiveness >= 1) matched = true; } else { if (!notImmune || effectiveness < 1) matched = true;