From 2d3614f3252dcad1d00e39c5802b48c880b12d65 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Sat, 5 Oct 2019 05:56:05 +1000 Subject: [PATCH] Refactor battle.dex out of battle In most other similar systems, like TeamValidator, we use `thing.dex` instead of having it extend `ModdedDex`. Battle has always extended `ModdedDex`, though. This changes Battle to match the others. This should fix an issue with `Battle.data` not being cached. This also frees up Battle to extend ObjectReadWriteStream in a future update. --- config/formats.js | 64 ++++++------- data/abilities.js | 36 +++---- data/items.js | 10 +- data/mods/gen1/moves.js | 8 +- data/mods/gen1/random-teams.js | 26 ++--- data/mods/gen1/scripts.js | 34 +++---- data/mods/gen1/statuses.js | 8 +- data/mods/gen2/moves.js | 16 ++-- data/mods/gen2/random-teams.js | 16 ++-- data/mods/gen2/scripts.js | 26 ++--- data/mods/gen2/statuses.js | 10 +- data/mods/gen3/abilities.js | 2 +- data/mods/gen3/moves.js | 14 +-- data/mods/gen3/random-teams.js | 24 ++--- data/mods/gen3/scripts.js | 16 ++-- data/mods/gen4/abilities.js | 4 +- data/mods/gen4/items.js | 2 +- data/mods/gen4/moves.js | 20 ++-- data/mods/gen4/random-teams.js | 16 ++-- data/mods/gen4/rulesets.js | 4 +- data/mods/gen4/scripts.js | 4 +- data/mods/gen5/abilities.js | 4 +- data/mods/gen5/moves.js | 8 +- data/mods/gen5/random-teams.js | 30 +++--- data/mods/gen6/abilities.js | 2 +- data/mods/gen6/items.js | 2 +- data/mods/gen6/moves.js | 2 +- data/mods/gen6/random-teams.js | 40 ++++---- data/mods/gennext/abilities.js | 8 +- data/mods/gennext/items.js | 2 +- data/mods/gennext/moves.js | 8 +- data/mods/gennext/statuses.js | 6 +- data/mods/letsgo/moves.js | 2 +- data/mods/letsgo/random-teams.js | 12 +-- data/mods/letsgo/scripts.js | 4 +- data/mods/mixandmega/items.js | 2 +- data/mods/mixandmega/scripts.js | 16 ++-- data/mods/pic/moves.js | 4 +- data/mods/pic/scripts.js | 6 +- data/mods/ssb/abilities.js | 34 +++---- data/mods/ssb/moves.js | 86 ++++++++--------- data/mods/ssb/random-teams.js | 6 +- data/mods/ssb/scripts.js | 28 +++--- data/mods/ssb/statuses.js | 12 +-- data/mods/stadium/moves.js | 2 +- data/mods/stadium/scripts.js | 26 ++--- data/mods/stadium/statuses.js | 12 +-- data/mods/vgc17/rulesets.js | 4 +- data/moves.js | 86 ++++++++--------- data/random-teams.js | 143 ++++++++++++++-------------- data/rulesets.js | 56 +++++------ data/scripts.js | 50 +++++----- data/statuses.js | 6 +- sim/battle.ts | 120 +++++++++++------------ sim/dex.ts | 2 +- sim/field.ts | 14 +-- sim/globals.ts | 8 +- sim/pokemon.ts | 78 +++++++-------- sim/side.ts | 22 ++--- sim/state.ts | 20 ++-- sim/team-validator.ts | 14 +-- test/sim/abilities/battlearmor.js | 4 +- test/sim/abilities/comatose.js | 6 +- test/sim/abilities/desolateland.js | 2 +- test/sim/abilities/disguise.js | 2 +- test/sim/abilities/intimidate.js | 6 +- test/sim/abilities/parentalbond.js | 4 +- test/sim/abilities/primordialsea.js | 2 +- test/sim/abilities/shellarmor.js | 4 +- test/sim/abilities/shielddust.js | 2 +- test/sim/abilities/thickfat.js | 4 +- test/sim/events.js | 10 +- test/sim/items/lansatberry.js | 2 +- test/sim/misc/fusion-combo.js | 6 +- test/sim/misc/statuses.js | 4 +- test/sim/misc/statusmoves.js | 2 +- test/sim/misc/weight.js | 16 ++-- test/sim/moves/counter.js | 4 +- test/sim/moves/followme.js | 2 +- test/sim/moves/rollout.js | 14 +-- test/sim/moves/skydrop.js | 2 +- test/sim/moves/stompingtantrum.js | 10 +- test/sim/moves/transform.js | 2 +- test/sim/moves/trickroom.js | 2 +- test/sim/moves/trumpcard.js | 6 +- 85 files changed, 734 insertions(+), 731 deletions(-) diff --git a/config/formats.js b/config/formats.js index aac3b562ea..d7949765e5 100644 --- a/config/formats.js +++ b/config/formats.js @@ -239,7 +239,7 @@ let Formats = [ 'Drought', 'Aurora Veil', ], onValidateSet(set) { - let template = this.getTemplate(set.species || set.name); + let template = this.dex.getTemplate(set.species || set.name); if (!template.nfe) { return [set.species + " cannot evolve."]; } @@ -313,9 +313,9 @@ let Formats = [ 'Spiritomb', 'Stantler', 'Starmie', 'Steelix', 'Stunfisk', 'Sudowoodo', 'Sunflora', 'Tauros', 'Throh', 'Togedemaru', 'Torkoal', 'Trevenant', 'Tropius', 'Turtonator', 'Vaporeon', 'Volbeat', 'Whimsicott', 'Wishiwashi', 'Wobbuffet', 'Zangoose', ]; - let template = this.getTemplate(set.species || set.name); - let futureGenEvo = template.evos && this.getTemplate(template.evos[0]).gen > this.gen; - if ((template.prevo && this.getTemplate(template.prevo).gen <= this.gen || (!template.nfe || futureGenEvo)) && !allowedNonLittleCupMons.includes(template.baseSpecies) && template.speciesid !== 'sandslashalola') { + let template = this.dex.getTemplate(set.species || set.name); + let futureGenEvo = template.evos && this.dex.getTemplate(template.evos[0]).gen > this.gen; + if ((template.prevo && this.dex.getTemplate(template.prevo).gen <= this.gen || (!template.nfe || futureGenEvo)) && !allowedNonLittleCupMons.includes(template.baseSpecies) && template.speciesid !== 'sandslashalola') { return [set.species + " isn't obtainable at Level 1."]; } }, @@ -414,12 +414,12 @@ let Formats = [ let n = 0; let problems = []; for (const set of team) { - const baseSpecies = this.getTemplate(set.species).baseSpecies; + const baseSpecies = this.dex.getTemplate(set.species).baseSpecies; if (legends.includes(baseSpecies)) { n++; if (n === 3) problems.push(`You can only use up to two legendary Pok\u00E9mon.`); } - const item = this.getItem(set.item); + const item = this.dex.getItem(set.item); if (item.zMove || item.megaStone || ['redorb', 'blueorb'].includes(item.id)) problems.push(`${set.name || set.species}'s item ${item.name} is banned.`); } return problems; @@ -444,12 +444,12 @@ let Formats = [ let n = 0; let problems = []; for (const set of team) { - const baseSpecies = this.getTemplate(set.species).baseSpecies; + const baseSpecies = this.dex.getTemplate(set.species).baseSpecies; if (legends.includes(baseSpecies)) { n++; if (n === 3) problems.push(`You can only use up to two legendary Pok\u00E9mon.`); } - const item = this.getItem(set.item); + const item = this.dex.getItem(set.item); if (item.megaStone || ['redorb', 'blueorb', 'ultranecroziumz'].includes(item.id)) problems.push(`${set.name || set.species}'s item ${item.name} is banned.`); } return problems; @@ -476,7 +476,7 @@ let Formats = [ const legends = ['Mewtwo', 'Lugia', 'Ho-Oh', 'Kyogre', 'Groudon', 'Rayquaza', 'Dialga', 'Palkia', 'Giratina', 'Reshiram', 'Zekrom', 'Kyurem', 'Xerneas', 'Yveltal', 'Zygarde', 'Cosmog', 'Cosmoem', 'Solgaleo', 'Lunala', 'Necrozma']; let n = 0; for (const set of team) { - const baseSpecies = this.getTemplate(set.species).baseSpecies; + const baseSpecies = this.dex.getTemplate(set.species).baseSpecies; if (legends.includes(baseSpecies)) n++; if (n > 2) return [`You can only use up to two legendary Pok\u00E9mon.`]; } @@ -590,7 +590,7 @@ let Formats = [ 'Sitrus Berry', 'Wiki Berry', 'Harvest + Rowap Berry', 'Harvest + Jaboca Berry', 'Shedinja + Sturdy', ], onValidateSet(set) { - let template = this.getTemplate(set.species); + let template = this.dex.getTemplate(set.species); if (template.types.includes('Steel')) return [`${template.species} is a Steel-type, which is banned from Metronome Battle.`]; let bst = 0; for (let stat in template.baseStats) { @@ -598,17 +598,17 @@ let Formats = [ bst += template.baseStats[stat]; } if (bst > 625) return [`${template.species} is banned.`, `(Pok\u00e9mon with a BST higher than 625 are banned)`]; - let item = this.getItem(set.item); + let item = this.dex.getItem(set.item); if (set.item && item.megaStone) { let bstMega = 0; - let megaTemplate = this.getTemplate(item.megaStone); + let megaTemplate = this.dex.getTemplate(item.megaStone); for (let stat in megaTemplate.baseStats) { // @ts-ignore bstMega += megaTemplate.baseStats[stat]; } if (template.baseSpecies === item.megaEvolves && bstMega > 625) return [`${set.name || set.species}'s item ${item.name} is banned.`, `(Pok\u00e9mon with a BST higher than 625 are banned)`]; } - if (set.moves.length !== 1 || this.getMove(set.moves[0]).id !== 'metronome') return [`${set.name || set.species} has illegal moves.`, `(Pok\u00e9mon can only have one Metronome in their moveset)`]; + if (set.moves.length !== 1 || this.dex.getMove(set.moves[0]).id !== 'metronome') return [`${set.name || set.species} has illegal moves.`, `(Pok\u00e9mon can only have one Metronome in their moveset)`]; }, }, { @@ -743,7 +743,7 @@ let Formats = [ let [familyId] = evoFamilies; if (!(familyId in requiredFamilies)) requiredFamilies[familyId] = 1; requiredFamilies[familyId]++; - if (requiredFamilies[familyId] > 2) return [`You are limited to up to two inheritances from each evolution family by the Donor Clause.`, `(You inherit more than twice from ${this.getTemplate(familyId).species}).`]; + if (requiredFamilies[familyId] > 2) return [`You are limited to up to two inheritances from each evolution family by the Donor Clause.`, `(You inherit more than twice from ${this.dex.getTemplate(familyId).species}).`]; } }, onBegin() { @@ -762,7 +762,7 @@ let Formats = [ // @ts-ignore if (!pokemon.donor) return; // @ts-ignore - let donorTemplate = this.getTemplate(pokemon.donor); + let donorTemplate = this.dex.getTemplate(pokemon.donor); if (!donorTemplate.exists) return; // Place volatiles on the Pokémon to show the donor details. this.add('-start', pokemon, donorTemplate.species, '[silent]'); @@ -829,16 +829,16 @@ let Formats = [ /**@type {{[k: string]: true}} */ let itemTable = {}; for (const set of team) { - let item = this.getItem(set.item); + let item = this.dex.getItem(set.item); if (!item) continue; - if (itemTable[item.id] && item.megaStone) return ["You are limited to one of each Mega Stone.", "(You have more than one " + this.getItem(item).name + ")"]; - if (itemTable[item.id] && ['blueorb', 'redorb'].includes(item.id)) return ["You are limited to one of each Primal Orb.", "(You have more than one " + this.getItem(item).name + ")"]; + if (itemTable[item.id] && item.megaStone) return ["You are limited to one of each Mega Stone.", "(You have more than one " + this.dex.getItem(item).name + ")"]; + if (itemTable[item.id] && ['blueorb', 'redorb'].includes(item.id)) return ["You are limited to one of each Primal Orb.", "(You have more than one " + this.dex.getItem(item).name + ")"]; itemTable[item.id] = true; } }, onValidateSet(set, format) { - let template = this.getTemplate(set.species || set.name); - let item = this.getItem(set.item); + let template = this.dex.getTemplate(set.species || set.name); + let item = this.dex.getItem(set.item); if (!item.megaEvolves && !['blueorb', 'redorb', 'ultranecroziumz'].includes(item.id)) return; if (template.baseSpecies === item.megaEvolves || (template.baseSpecies === 'Groudon' && item.id === 'redorb') || (template.baseSpecies === 'Kyogre' && item.id === 'blueorb') || (template.species.substr(0, 9) === 'Necrozma-' && item.id === 'ultranecroziumz')) return; let uberStones = format.restrictedStones || []; @@ -852,11 +852,11 @@ let Formats = [ }, onSwitchIn(pokemon) { // @ts-ignore - let oMegaTemplate = this.getTemplate(pokemon.template.originalMega); + let oMegaTemplate = this.dex.getTemplate(pokemon.template.originalMega); if (oMegaTemplate.exists && pokemon.m.originalSpecies !== oMegaTemplate.baseSpecies) { // Place volatiles on the Pokémon to show its mega-evolved condition and details this.add('-start', pokemon, oMegaTemplate.requiredItem || oMegaTemplate.requiredMove, '[silent]'); - let oTemplate = this.getTemplate(pokemon.m.originalSpecies); + let oTemplate = this.dex.getTemplate(pokemon.m.originalSpecies); if (oTemplate.types.length !== pokemon.template.types.length || oTemplate.types[1] !== pokemon.template.types[1]) { this.add('-start', pokemon, 'typechange', pokemon.template.types.join('/'), '[silent]'); } @@ -864,7 +864,7 @@ let Formats = [ }, onSwitchOut(pokemon) { // @ts-ignore - let oMegaTemplate = this.getTemplate(pokemon.template.originalMega); + let oMegaTemplate = this.dex.getTemplate(pokemon.template.originalMega); if (oMegaTemplate.exists && pokemon.m.originalSpecies !== oMegaTemplate.baseSpecies) { this.add('-end', pokemon, oMegaTemplate.requiredItem || oMegaTemplate.requiredMove, '[silent]'); } @@ -889,7 +889,7 @@ let Formats = [ onValidateSet(set, format) { let restrictedAbilities = format.restrictedAbilities || []; if (restrictedAbilities.includes(set.ability)) { - let template = this.getTemplate(set.species || set.name); + let template = this.dex.getTemplate(set.species || set.name); let legalAbility = false; for (let i in template.abilities) { // @ts-ignore @@ -912,7 +912,7 @@ let Formats = [ onModifyTemplate(template, target, source, effect) { if (!target) return; // Chat command if (effect && ['imposter', 'transform'].includes(effect.id)) return; - let types = [...new Set(target.baseMoveSlots.slice(0, 2).map(move => this.getMove(move.id).type))]; + let types = [...new Set(target.baseMoveSlots.slice(0, 2).map(move => this.dex.getMove(move.id).type))]; return Object.assign({}, template, {types: types}); }, onSwitchIn(pokemon) { @@ -964,20 +964,20 @@ let Formats = [ if (target && target.set.ability === 'Drizzle') return; let tier = template.tier; if (target && target.set.item) { - let item = this.getItem(target.set.item); + let item = this.dex.getItem(target.set.item); if (item.name === 'Kommonium Z' || item.name === 'Mewnium Z') return; - if (item.megaEvolves === template.species) tier = this.getTemplate(item.megaStone).tier; + if (item.megaEvolves === template.species) tier = this.dex.getTemplate(item.megaStone).tier; } if (target && target.set.moves.includes('auroraveil')) tier = 'UU'; if (target && target.set.ability === 'Drought') tier = 'RU'; if (tier[0] === '(') tier = tier.slice(1, -1); if (!(tier in boosts)) return; - let pokemon = this.deepClone(template); + let pokemon = this.dex.deepClone(template); let boost = boosts[tier]; for (let statName in pokemon.baseStats) { if (statName === 'hp') continue; - pokemon.baseStats[statName] = this.clampIntRange(pokemon.baseStats[statName] + boost, 1, 255); + pokemon.baseStats[statName] = this.dex.clampIntRange(pokemon.baseStats[statName] + boost, 1, 255); } return pokemon; }, @@ -1191,7 +1191,7 @@ let Formats = [ onSwitchInPriority: 100, onSwitchIn(pokemon) { let name = toID(pokemon.illusion ? pokemon.illusion.name : pokemon.name); - if (this.getTemplate(name).exists || name === 'rage') { + if (this.dex.getTemplate(name).exists || name === 'rage') { // Certain pokemon have volatiles named after their speciesid // To prevent overwriting those, and to prevent accidentaly leaking // that a pokemon is on a team through the onStart even triggering @@ -1200,7 +1200,7 @@ let Formats = [ name = /** @type {ID} */(name + 'user'); } // Add the mon's status effect to it as a volatile. - let status = this.getEffect(name); + let status = this.dex.getEffect(name); if (status && status.exists) { pokemon.addVolatile(name, pokemon); } @@ -1632,7 +1632,7 @@ let Formats = [ const legends = ['Mewtwo', 'Lugia', 'Ho-Oh', 'Kyogre', 'Groudon', 'Rayquaza', 'Dialga', 'Palkia', 'Giratina', 'Reshiram', 'Zekrom', 'Kyurem', 'Xerneas', 'Yveltal', 'Zygarde']; let n = 0; for (const set of team) { - let baseSpecies = this.getTemplate(set.species).baseSpecies; + let baseSpecies = this.dex.getTemplate(set.species).baseSpecies; if (legends.includes(baseSpecies)) n++; if (n > 2) return ["You can only use up to two legendary Pok\u00E9mon."]; } diff --git a/data/abilities.js b/data/abilities.js index d49a6c6100..92938ff25f 100644 --- a/data/abilities.js +++ b/data/abilities.js @@ -144,9 +144,9 @@ let BattleAbilities = { for (const target of pokemon.side.foe.active) { if (!target || target.fainted) continue; for (const moveSlot of target.moveSlots) { - const move = this.getMove(moveSlot.move); + const move = this.dex.getMove(moveSlot.move); const moveType = move.id === 'hiddenpower' ? target.hpType : move.type; - if (move.category !== 'Status' && (this.getImmunity(moveType, pokemon) && this.getEffectiveness(moveType, pokemon) > 0 || move.ohko)) { + if (move.category !== 'Status' && (this.dex.getImmunity(moveType, pokemon) && this.dex.getEffectiveness(moveType, pokemon) > 0 || move.ohko)) { this.add('-ability', pokemon, 'Anticipation'); return; } @@ -1111,7 +1111,7 @@ let BattleAbilities = { for (const target of pokemon.side.foe.active) { if (target.fainted) continue; for (const moveSlot of target.moveSlots) { - let move = this.getMove(moveSlot.move); + let move = this.dex.getMove(moveSlot.move); let bp = move.basePower; if (move.ohko) bp = 150; if (move.id === 'counter' || move.id === 'metalburst' || move.id === 'mirrorcoat') bp = 120; @@ -1290,7 +1290,7 @@ let BattleAbilities = { onResidualSubOrder: 1, onResidual(pokemon) { if (this.field.isWeather(['sunnyday', 'desolateland']) || this.randomChance(1, 2)) { - if (pokemon.hp && !pokemon.item && this.getItem(pokemon.lastItem).isBerry) { + if (pokemon.hp && !pokemon.item && this.dex.getItem(pokemon.lastItem).isBerry) { pokemon.setItem(pokemon.lastItem); pokemon.lastItem = ''; this.add('-item', pokemon, pokemon.getItem(), '[from] ability: Harvest'); @@ -1460,7 +1460,7 @@ let BattleAbilities = { }, onAfterDamage(damage, target, source, effect) { if (target.illusion && effect && effect.effectType === 'Move' && effect.id !== 'confused') { - this.singleEvent('End', this.getAbility('Illusion'), target.abilityData, target, source, effect); + this.singleEvent('End', this.dex.getAbility('Illusion'), target.abilityData, target, source, effect); } }, onEnd(pokemon) { @@ -1507,7 +1507,7 @@ let BattleAbilities = { if (this.activeMove && this.activeMove.id === 'skillswap') return; let target = pokemon.side.foe.active[pokemon.side.foe.active.length - 1 - pokemon.position]; if (target) { - pokemon.transformInto(target, this.getAbility('imposter')); + pokemon.transformInto(target, this.dex.getAbility('imposter')); } }, id: "imposter", @@ -1793,7 +1793,7 @@ let BattleAbilities = { if (target === source || move.hasBounced || !move.flags['reflectable']) { return; } - let newMove = this.getActiveMove(move.id); + let newMove = this.dex.getActiveMove(move.id); newMove.hasBounced = true; newMove.pranksterBoosted = false; this.useMove(newMove, target, source); @@ -1803,7 +1803,7 @@ let BattleAbilities = { if (target.side === source.side || move.hasBounced || !move.flags['reflectable']) { return; } - let newMove = this.getActiveMove(move.id); + let newMove = this.dex.getActiveMove(move.id); newMove.hasBounced = true; newMove.pranksterBoosted = false; this.useMove(newMove, this.effectData.target, source); @@ -2061,7 +2061,7 @@ let BattleAbilities = { if (source && source !== target && move && move.flags['contact'] && source.ability !== 'mummy') { let oldAbility = source.setAbility('mummy', target); if (oldAbility) { - this.add('-activate', target, 'ability: Mummy', this.getAbility(oldAbility).name, '[of] ' + source); + this.add('-activate', target, 'ability: Mummy', this.dex.getAbility(oldAbility).name, '[of] ' + source); } } }, @@ -2094,7 +2094,7 @@ let BattleAbilities = { // this.add('-message', "" + curPoke + " skipped: Natural Cure already known"); continue; } - let template = this.getTemplate(curPoke.species); + let template = this.dex.getTemplate(curPoke.species); // pokemon can't get Natural Cure if (Object.values(template.abilities).indexOf('Natural Cure') < 0) { // this.add('-message', "" + curPoke + " skipped: no Natural Cure"); @@ -2235,7 +2235,7 @@ let BattleAbilities = { }, onTryHitPriority: 1, onTryHit(target, source, move) { - if (move.flags['powder'] && target !== source && this.getImmunity('powder', target)) { + if (move.flags['powder'] && target !== source && this.dex.getImmunity('powder', target)) { this.add('-immune', target, '[from] ability: Overcoat'); return null; } @@ -2354,7 +2354,7 @@ let BattleAbilities = { let randomTarget = this.sample(pickupTargets); let item = randomTarget.lastItem; randomTarget.lastItem = ''; - this.add('-item', pokemon, this.getItem(item), '[from] ability: Pickup'); + this.add('-item', pokemon, this.dex.getItem(item), '[from] ability: Pickup'); pokemon.setItem(item); }, id: "pickup", @@ -2440,7 +2440,7 @@ let BattleAbilities = { move.secondaries.push({ chance: 30, status: 'psn', - ability: this.getAbility('poisontouch'), + ability: this.dex.getAbility('poisontouch'), }); }, id: "poisontouch", @@ -2472,7 +2472,7 @@ let BattleAbilities = { shortDesc: "This Pokemon copies the Ability of an ally that faints.", onAllyFaint(target) { if (!this.effectData.target.hp) return; - let ability = this.getAbility(target.ability); + let ability = this.dex.getAbility(target.ability); let bannedAbilities = ['battlebond', 'comatose', 'disguise', 'flowergift', 'forecast', 'illusion', 'imposter', 'multitype', 'powerconstruct', 'powerofalchemy', 'receiver', 'rkssystem', 'schooling', 'shieldsdown', 'stancechange', 'trace', 'wonderguard', 'zenmode']; if (bannedAbilities.includes(target.ability)) return; this.add('-ability', this.effectData.target, ability, '[from] ability: Power of Alchemy', '[of] ' + target); @@ -2647,7 +2647,7 @@ let BattleAbilities = { shortDesc: "This Pokemon copies the Ability of an ally that faints.", onAllyFaint(target) { if (!this.effectData.target.hp) return; - let ability = this.getAbility(target.ability); + let ability = this.dex.getAbility(target.ability); let bannedAbilities = ['battlebond', 'comatose', 'disguise', 'flowergift', 'forecast', 'illusion', 'imposter', 'multitype', 'powerconstruct', 'powerofalchemy', 'receiver', 'rkssystem', 'schooling', 'shieldsdown', 'stancechange', 'trace', 'wonderguard', 'zenmode']; if (bannedAbilities.includes(target.ability)) return; this.add('-ability', this.effectData.target, ability, '[from] ability: Receiver', '[of] ' + target); @@ -3735,7 +3735,7 @@ let BattleAbilities = { let rand = 0; if (possibleTargets.length > 1) rand = this.random(possibleTargets.length); let target = possibleTargets[rand]; - let ability = this.getAbility(target.ability); + let ability = this.dex.getAbility(target.ability); let bannedAbilities = ['noability', 'battlebond', 'comatose', 'disguise', 'flowergift', 'forecast', 'illusion', 'imposter', 'multitype', 'powerconstruct', 'powerofalchemy', 'receiver', 'rkssystem', 'schooling', 'shieldsdown', 'stancechange', 'trace', 'zenmode']; if (bannedAbilities.includes(target.ability)) { possibleTargets.splice(rand, 1); @@ -4152,7 +4152,7 @@ let BattleAbilities = { if (target === source || move.hasBounced || !move.flags['reflectable']) { return; } - let newMove = this.getActiveMove(move.id); + let newMove = this.dex.getActiveMove(move.id); newMove.hasBounced = true; this.useMove(newMove, target, source); return null; @@ -4163,7 +4163,7 @@ let BattleAbilities = { if (target.side === source.side || move.hasBounced || !move.flags['reflectable']) { return; } - let newMove = this.getActiveMove(move.id); + let newMove = this.dex.getActiveMove(move.id); newMove.hasBounced = true; this.useMove(newMove, this.effectData.target, source); return null; diff --git a/data/items.js b/data/items.js index 04960ed88f..241609c4df 100644 --- a/data/items.js +++ b/data/items.js @@ -153,7 +153,7 @@ let BattleItems = { this.add('-enditem', target, 'Air Balloon'); target.item = ''; target.itemData = {id: '', target}; - this.runEvent('AfterUseItem', target, null, null, this.getItem('airballoon')); + this.runEvent('AfterUseItem', target, null, null, this.dex.getItem('airballoon')); } }, onAfterSubDamage(damage, target, source, effect) { @@ -162,7 +162,7 @@ let BattleItems = { this.add('-enditem', target, 'Air Balloon'); target.item = ''; target.itemData = {id: '', target}; - this.runEvent('AfterUseItem', target, null, null, this.getItem('airballoon')); + this.runEvent('AfterUseItem', target, null, null, this.dex.getItem('airballoon')); } }, num: 541, @@ -291,7 +291,7 @@ let BattleItems = { }, onDisableMove(pokemon) { for (const moveSlot of pokemon.moveSlots) { - if (this.getMove(moveSlot.move).category === 'Status') { + if (this.dex.getMove(moveSlot.move).category === 'Status') { pokemon.disableMove(moveSlot.id); } } @@ -3001,7 +3001,7 @@ let BattleItems = { }, onAfterMoveSecondarySelf(source, target, move) { if (source && source !== target && move && move.category !== 'Status') { - this.damage(source.maxhp / 10, source, source, this.getItem('lifeorb')); + this.damage(source.maxhp / 10, source, source, this.dex.getItem('lifeorb')); } }, num: 270, @@ -4952,7 +4952,7 @@ let BattleItems = { if (type === 'sandstorm' || type === 'hail' || type === 'powder') return false; }, onTryHit(pokemon, source, move) { - if (move.flags['powder'] && pokemon !== source && this.getImmunity('powder', pokemon)) { + if (move.flags['powder'] && pokemon !== source && this.dex.getImmunity('powder', pokemon)) { this.add('-activate', pokemon, 'item: Safety Goggles', move.name); return null; } diff --git a/data/mods/gen1/moves.js b/data/mods/gen1/moves.js index e1d70b904c..8cd92d1573 100644 --- a/data/mods/gen1/moves.js +++ b/data/mods/gen1/moves.js @@ -253,7 +253,7 @@ let BattleMovedex = { // It will fail if the last move selected by the opponent has base power 0 or is not Normal or Fighting Type. // If both are true, counter will deal twice the last damage dealt in battle, no matter what was the move. // That means that, if opponent switches, counter will use last counter damage * 2. - let lastUsedMove = target.side.lastMove && this.getMove(target.side.lastMove.id); + let lastUsedMove = target.side.lastMove && this.dex.getMove(target.side.lastMove.id); if (lastUsedMove && lastUsedMove.basePower > 0 && ['Normal', 'Fighting'].includes(lastUsedMove.type) && this.lastDamage > 0 && !this.willMove(target)) { return 2 * this.lastDamage; } @@ -306,7 +306,7 @@ let BattleMovedex = { this.effectData.duration++; } let moves = pokemon.moves; - let move = this.getMove(this.sample(moves)); + let move = this.dex.getMove(this.sample(moves)); this.add('-start', pokemon, 'Disable', move.name); this.effectData.move = move.id; return; @@ -558,7 +558,7 @@ let BattleMovedex = { residualdmg.counter++; toxicCounter = residualdmg.counter; } - let toLeech = this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1) * toxicCounter; + let toLeech = this.dex.clampIntRange(Math.floor(pokemon.maxhp / 16), 1) * toxicCounter; let damage = this.damage(toLeech, pokemon, leecher); if (residualdmg) this.hint("In Gen 1, Leech Seed's damage is affected by Toxic's counter.", true); if (!damage || toLeech > damage) { @@ -613,7 +613,7 @@ let BattleMovedex = { let moves = target.moves; let moveid = this.sample(moves); if (!moveid) return false; - let move = this.getMove(moveid); + let move = this.dex.getMove(moveid); source.moveSlots[moveslot] = { move: move.name, id: move.id, diff --git a/data/mods/gen1/random-teams.js b/data/mods/gen1/random-teams.js index b334cc658b..273fc8b494 100644 --- a/data/mods/gen1/random-teams.js +++ b/data/mods/gen1/random-teams.js @@ -22,9 +22,9 @@ class RandomGen1Teams extends RandomGen2Teams { } let formeCounter = 0; - for (let id in this.data.Pokedex) { - if (!(this.data.Pokedex[id].num in hasDexNumber)) continue; - let template = this.getTemplate(id); + for (let id in this.dex.data.Pokedex) { + if (!(this.dex.data.Pokedex[id].num in hasDexNumber)) continue; + let template = this.dex.getTemplate(id); if (!template.learnset || template.forme) continue; formes[hasDexNumber[template.num]].push(template.species); if (++formeCounter >= 6) { @@ -36,7 +36,7 @@ class RandomGen1Teams extends RandomGen2Teams { for (let i = 0; i < 6; i++) { // Choose forme. let poke = this.sample(formes[i]); - let template = this.getTemplate(poke); + let template = this.dex.getTemplate(poke); // Level balance: calculate directly from stats rather than using some silly lookup table. let mbstmin = 1307; @@ -90,7 +90,7 @@ class RandomGen1Teams extends RandomGen2Teams { let pool = []; if (template.learnset) { for (let move in template.learnset) { - if (this.getMove(move).gen !== 1) continue; + if (this.dex.getMove(move).gen !== 1) continue; if (template.learnset[move].some(learned => learned[0] === '1')) { pool.push(move); } @@ -132,8 +132,8 @@ class RandomGen1Teams extends RandomGen2Teams { let uuTiers = ['NFE', 'UU', 'UUBL', 'NU']; let pokemonPool = []; - for (let id in this.data.FormatsData) { - let template = this.getTemplate(id); + for (let id in this.dex.data.FormatsData) { + let template = this.dex.getTemplate(id); if (!template.isNonstandard && template.randomBattleMoves) { pokemonPool.push(id); } @@ -149,7 +149,7 @@ class RandomGen1Teams extends RandomGen2Teams { let hasShitmon = false; while (pokemonPool.length && pokemonLeft < 6) { - let template = this.getTemplate(this.sampleNoReplace(pokemonPool)); + let template = this.dex.getTemplate(this.sampleNoReplace(pokemonPool)); if (!template.exists) continue; // Bias the tiers so you get less shitmons and only one of the two Ubers. @@ -189,7 +189,7 @@ class RandomGen1Teams extends RandomGen2Teams { // Spammable attacks are: Thunderbolt, Psychic, Surf, Blizzard, Earthquake. let pokemonWeaknesses = []; for (let type in weaknessCount) { - let increaseCount = this.getImmunity(type, template) && this.getEffectiveness(type, template) > 0; + let increaseCount = this.dex.getImmunity(type, template) && this.dex.getEffectiveness(type, template) > 0; if (!increaseCount) continue; if (weaknessCount[type] >= 2) { skip = true; @@ -241,8 +241,8 @@ class RandomGen1Teams extends RandomGen2Teams { * @return {RandomTeamsTypes.RandomSet} */ randomSet(template) { - template = this.getTemplate(template); - if (!template.exists) template = this.getTemplate('pikachu'); // Because Gen 1. + template = this.dex.getTemplate(template); + if (!template.exists) template = this.dex.getTemplate('pikachu'); // Because Gen 1. let movePool = template.randomBattleMoves ? template.randomBattleMoves.slice() : []; /**@type {string[]} */ @@ -292,7 +292,7 @@ class RandomGen1Teams extends RandomGen2Teams { hasMove = {}; counter = {Physical: 0, Special: 0, Status: 0, physicalsetup: 0, specialsetup: 0}; for (const setMoveid of moves) { - let move = this.getMove(setMoveid); + let move = this.dex.getMove(setMoveid); let moveid = move.id; hasMove[moveid] = true; if (!move.damage && !move.damageCallback) { @@ -314,7 +314,7 @@ class RandomGen1Teams extends RandomGen2Teams { for (const [i, moveid] of moves.entries()) { if (moveid === template.essentialMove) continue; - let move = this.getMove(moveid); + let move = this.dex.getMove(moveid); let rejected = false; if (!template.essentialMove || moveid !== template.essentialMove) { switch (moveid) { diff --git a/data/mods/gen1/scripts.js b/data/mods/gen1/scripts.js index abee702c87..90cc9ba86c 100644 --- a/data/mods/gen1/scripts.js +++ b/data/mods/gen1/scripts.js @@ -11,7 +11,7 @@ let BattleScripts = { inherit: 'gen2', gen: 1, debug(activity) { - if (this.getFormat().debug) { + if (this.format.debug) { this.add('debug', activity); } }, @@ -39,7 +39,7 @@ let BattleScripts = { modifyStat(statName, modifier) { if (!(statName in this.storedStats)) throw new Error("Invalid `statName` passed to `modifyStat`"); // @ts-ignore - this.modifiedStats[statName] = this.battle.clampIntRange(Math.floor(this.modifiedStats[statName] * modifier), 1, 999); + this.modifiedStats[statName] = this.battle.dex.clampIntRange(Math.floor(this.modifiedStats[statName] * modifier), 1, 999); }, // In generation 1, boosting function increases the stored modified stat and checks for opponent's status. boostBy(boost) { @@ -91,7 +91,7 @@ let BattleScripts = { // It also deals with how PP reduction works on gen 1. runMove(moveOrMoveName, pokemon, targetLoc, sourceEffect) { let target = this.getTarget(pokemon, moveOrMoveName, targetLoc); - let move = this.getActiveMove(moveOrMoveName); + let move = this.dex.getActiveMove(moveOrMoveName); if (target && target.subFainted) target.subFainted = null; this.setActiveMove(move, pokemon, target); @@ -174,8 +174,8 @@ let BattleScripts = { // @ts-ignore useMove(moveOrMoveName, pokemon, target, sourceEffect) { if (!sourceEffect && this.effect.id) sourceEffect = this.effect; - let baseMove = this.getMove(moveOrMoveName); - let move = this.getActiveMove(baseMove); + let baseMove = this.dex.getMove(moveOrMoveName); + let move = this.dex.getActiveMove(baseMove); if (target === undefined) target = this.resolveTarget(pokemon, move); if (move.target === 'self') { target = pokemon; @@ -205,7 +205,7 @@ let BattleScripts = { return false; } - if (sourceEffect) attrs += '|[from]' + this.getEffect(sourceEffect); + if (sourceEffect) attrs += '|[from]' + this.dex.getEffect(sourceEffect); this.addMove('move', pokemon, move.name, target + attrs); if (!this.singleEvent('Try', move, null, pokemon, target, move)) { @@ -628,7 +628,7 @@ let BattleScripts = { if (!source) source = this.event.source; if (!effect) effect = this.effect; } - if (typeof effect === 'string') effect = this.getEffect(effect); + if (typeof effect === 'string') effect = this.dex.getEffect(effect); if (!target || !target.hp) return 0; let success = null; boost = this.runEvent('Boost', target, source, effect, Object.assign({}, boost)); @@ -680,7 +680,7 @@ let BattleScripts = { getDamage(pokemon, target, move, suppressMessages) { // First of all, we get the move. if (typeof move === 'string') { - move = this.getActiveMove(move); + move = this.dex.getActiveMove(move); } else if (typeof move === 'number') { // @ts-ignore move = /** @type {ActiveMove} */ ({ @@ -745,7 +745,7 @@ let BattleScripts = { if (!basePower) { return basePower === 0 ? undefined : basePower; } - basePower = this.clampIntRange(basePower, 1); + basePower = this.dex.clampIntRange(basePower, 1); // Checking for the move's Critical Hit possibility. We check if it's a 100% crit move, otherwise we calculate the chance. let isCrit = move.willCrit || false; @@ -760,7 +760,7 @@ let BattleScripts = { critChance = Math.floor(critChance / 2); } else { // Normally, without focus energy, crit chance is multiplied by 2 and capped at 255 here. - critChance = this.clampIntRange(critChance * 2, 1, 255); + critChance = this.dex.clampIntRange(critChance * 2, 1, 255); } // Now we check for the move's critical hit ratio. @@ -769,7 +769,7 @@ let BattleScripts = { critChance = Math.floor(critChance / 2); } else if (move.critRatio === 2) { // High crit ratio, we multiply the result so far by 4 and cap it at 255. - critChance = this.clampIntRange(critChance * 4, 1, 255); + critChance = this.dex.clampIntRange(critChance * 4, 1, 255); } // Last, we check deppending on ratio if the move critical hits or not. @@ -789,7 +789,7 @@ let BattleScripts = { } } if (!basePower) return 0; - basePower = this.clampIntRange(basePower, 1); + basePower = this.dex.clampIntRange(basePower, 1); // We now check attacker's and defender's stats. let level = pokemon.level; @@ -807,7 +807,7 @@ let BattleScripts = { if ((defType === 'def' && defender.volatiles['reflect']) || (defType === 'spd' && defender.volatiles['lightscreen'])) { this.debug('Screen doubling (Sp)Def'); defense *= 2; - defense = this.clampIntRange(defense, 1, 1998); + defense = this.dex.clampIntRange(defense, 1, 1998); } // In the event of a critical hit, the offense and defense changes are ignored. @@ -832,14 +832,14 @@ let BattleScripts = { // When either attack or defense are higher than 256, they are both divided by 4 and moded by 256. // This is what cuases the roll over bugs. if (attack >= 256 || defense >= 256) { - attack = this.clampIntRange(Math.floor(attack / 4) % 256, 1); + attack = this.dex.clampIntRange(Math.floor(attack / 4) % 256, 1); // Defense isn't checked on the cartridge, but we don't want those / 0 bugs on the sim. - defense = this.clampIntRange(Math.floor(defense / 4) % 256, 1); + defense = this.dex.clampIntRange(Math.floor(defense / 4) % 256, 1); } // Self destruct moves halve defense at this point. if (move.selfdestruct && defType === 'def') { - defense = this.clampIntRange(Math.floor(defense / 2), 1); + defense = this.dex.clampIntRange(Math.floor(defense / 2), 1); } // Let's go with the calculation now that we have what we need. @@ -850,7 +850,7 @@ let BattleScripts = { damage *= basePower; damage *= attack; damage = Math.floor(damage / defense); - damage = this.clampIntRange(Math.floor(damage / 50), 1, 997); + damage = this.dex.clampIntRange(Math.floor(damage / 50), 1, 997); damage += 2; // STAB damage bonus, the "???" type never gets STAB diff --git a/data/mods/gen1/statuses.js b/data/mods/gen1/statuses.js index bd55552a1d..2f7bf0b8f8 100644 --- a/data/mods/gen1/statuses.js +++ b/data/mods/gen1/statuses.js @@ -24,7 +24,7 @@ let BattleStatuses = { onAfterMoveSelfPriority: 2, onAfterMoveSelf(pokemon) { let toxicCounter = pokemon.volatiles['residualdmg'] ? pokemon.volatiles['residualdmg'].counter : 1; - this.damage(this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1) * toxicCounter, pokemon); + this.damage(this.dex.clampIntRange(Math.floor(pokemon.maxhp / 16), 1) * toxicCounter, pokemon); if (pokemon.volatiles['residualdmg']) { this.hint("In Gen 1, Toxic's counter is retained after Rest and applies to PSN/BRN.", true); } @@ -33,7 +33,7 @@ let BattleStatuses = { pokemon.addVolatile('brnattackdrop'); }, onAfterSwitchInSelf(pokemon) { - this.damage(this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1)); + this.damage(this.dex.clampIntRange(Math.floor(pokemon.maxhp / 16), 1)); }, }, par: { @@ -122,13 +122,13 @@ let BattleStatuses = { onAfterMoveSelfPriority: 2, onAfterMoveSelf(pokemon) { let toxicCounter = pokemon.volatiles['residualdmg'] ? pokemon.volatiles['residualdmg'].counter : 1; - this.damage(this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1) * toxicCounter, pokemon); + this.damage(this.dex.clampIntRange(Math.floor(pokemon.maxhp / 16), 1) * toxicCounter, pokemon); if (pokemon.volatiles['residualdmg']) { this.hint("In Gen 1, Toxic's counter is retained after Rest and applies to PSN/BRN.", true); } }, onAfterSwitchInSelf(pokemon) { - this.damage(this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1)); + this.damage(this.dex.clampIntRange(Math.floor(pokemon.maxhp / 16), 1)); }, }, tox: { diff --git a/data/mods/gen2/moves.js b/data/mods/gen2/moves.js index 4f9d41c7e9..bf86db27e4 100644 --- a/data/mods/gen2/moves.js +++ b/data/mods/gen2/moves.js @@ -39,7 +39,7 @@ let BattleMovedex = { return false; } if (target.hp <= target.maxhp / 2) { - this.boost({atk: 2}, null, null, this.getEffect('bellydrum2')); + this.boost({atk: 2}, null, null, this.dex.getEffect('bellydrum2')); return false; } this.directDamage(target.maxhp / 2); @@ -97,7 +97,7 @@ let BattleMovedex = { return false; } if (!target.isActive) { - const possibleTarget = this.resolveTarget(pokemon, this.getMove('pound')); + const possibleTarget = this.resolveTarget(pokemon, this.dex.getMove('pound')); if (!possibleTarget) { this.add('-miss', pokemon); return false; @@ -148,7 +148,7 @@ let BattleMovedex = { desc: "Deals damage to the opposing Pokemon equal to twice the HP lost by the user from a physical attack this turn. This move considers Hidden Power as Normal type, and only the last hit of a multi-hit attack is counted. Fails if the user moves first, if the user was not hit by a physical attack this turn, or if the user did not lose HP from the attack. If the opposing Pokemon used Fissure or Horn Drill and missed, this move deals 65535 damage.", damageCallback(pokemon, target) { let lastAttackedBy = pokemon.getLastAttackedBy(); - if (lastAttackedBy && lastAttackedBy.move && lastAttackedBy.thisTurn && (this.getCategory(lastAttackedBy.move) === 'Physical' || this.getMove(lastAttackedBy.move).id === 'hiddenpower') && (!target.lastMove || target.lastMove.id !== 'sleeptalk')) { + if (lastAttackedBy && lastAttackedBy.move && lastAttackedBy.thisTurn && (this.getCategory(lastAttackedBy.move) === 'Physical' || this.dex.getMove(lastAttackedBy.move).id === 'hiddenpower') && (!target.lastMove || target.lastMove.id !== 'sleeptalk')) { return 2 * lastAttackedBy.damage; } return false; @@ -387,7 +387,7 @@ let BattleMovedex = { if (target.runImmunity('Fighting')) { let damage = this.getDamage(source, target, move, true); if (typeof damage !== 'number') throw new Error("Couldn't get High Jump Kick recoil"); - this.damage(this.clampIntRange(damage / 8, 1), source, source, move); + this.damage(this.dex.clampIntRange(damage / 8, 1), source, source, move); } }, }, @@ -407,7 +407,7 @@ let BattleMovedex = { if (target.runImmunity('Fighting')) { let damage = this.getDamage(source, target, move, true); if (typeof damage !== 'number') throw new Error("Couldn't get Jump Kick recoil"); - this.damage(this.clampIntRange(damage / 8, 1), source, source, move); + this.damage(this.dex.clampIntRange(damage / 8, 1), source, source, move); } }, }, @@ -429,7 +429,7 @@ let BattleMovedex = { if (!leecher || leecher.fainted || leecher.hp <= 0) { return; } - let toLeech = this.clampIntRange(pokemon.maxhp / 8, 1); + let toLeech = this.dex.clampIntRange(pokemon.maxhp / 8, 1); let damage = this.damage(toLeech, pokemon, leecher); if (damage) { this.heal(damage, leecher, pokemon); @@ -501,7 +501,7 @@ let BattleMovedex = { desc: "Deals damage to the opposing Pokemon equal to twice the HP lost by the user from a special attack this turn. This move considers Hidden Power as Normal type, and only the last hit of a multi-hit attack is counted. Fails if the user moves first, if the user was not hit by a special attack this turn, or if the user did not lose HP from the attack.", damageCallback(pokemon, target) { let lastAttackedBy = pokemon.getLastAttackedBy(); - if (lastAttackedBy && lastAttackedBy.move && lastAttackedBy.thisTurn && this.getCategory(lastAttackedBy.move) === 'Special' && this.getMove(lastAttackedBy.move).id !== 'hiddenpower' && (!target.lastMove || target.lastMove.id !== 'sleeptalk')) { + if (lastAttackedBy && lastAttackedBy.move && lastAttackedBy.thisTurn && this.getCategory(lastAttackedBy.move) === 'Special' && this.dex.getMove(lastAttackedBy.move).id !== 'hiddenpower' && (!target.lastMove || target.lastMove.id !== 'sleeptalk')) { return 2 * lastAttackedBy.damage; } return false; @@ -769,7 +769,7 @@ let BattleMovedex = { let moves = []; for (const moveSlot of pokemon.moveSlots) { let move = moveSlot.id; - if (move && !NoSleepTalk.includes(move) && !this.getMove(move).flags['charge']) { + if (move && !NoSleepTalk.includes(move) && !this.dex.getMove(move).flags['charge']) { moves.push(move); } } diff --git a/data/mods/gen2/random-teams.js b/data/mods/gen2/random-teams.js index 38458c3e28..5d0565ba34 100644 --- a/data/mods/gen2/random-teams.js +++ b/data/mods/gen2/random-teams.js @@ -9,9 +9,9 @@ class RandomGen2Teams extends RandomGen3Teams { let pokemon = []; let pokemonPool = []; - for (let id in this.data.FormatsData) { - let template = this.getTemplate(id); - if (!template.isNonstandard && this.data.FormatsData[id].randomSet1) { + for (let id in this.dex.data.FormatsData) { + let template = this.dex.getTemplate(id); + if (!template.isNonstandard && this.dex.data.FormatsData[id].randomSet1) { pokemonPool.push(id); } } @@ -38,7 +38,7 @@ class RandomGen2Teams extends RandomGen3Teams { }; while (pokemonPool.length && pokemonLeft > 0) { - let template = this.getTemplate(this.sampleNoReplace(pokemonPool)); + let template = this.dex.getTemplate(this.sampleNoReplace(pokemonPool)); if (!template.exists) continue; let skip = false; @@ -69,7 +69,7 @@ class RandomGen2Teams extends RandomGen3Teams { // but ensure no more than 3 pokemon weak to the same regardless. let weaknesses = []; for (let type in weaknessCount) { - let weak = this.getImmunity(type, template) && this.getEffectiveness(type, template) > 0; + let weak = this.dex.getImmunity(type, template) && this.dex.getEffectiveness(type, template) > 0; if (!weak) continue; if (weaknessCount[type] > 2 || weaknessCount[type] - resistanceCount[type] > 1) { skip = true; @@ -78,7 +78,7 @@ class RandomGen2Teams extends RandomGen3Teams { } let resistances = []; for (let type in resistanceCount) { - let resist = !this.getImmunity(type, template) || this.getEffectiveness(type, template) < 0; + let resist = !this.dex.getImmunity(type, template) || this.dex.getEffectiveness(type, template) < 0; if (resist) resistances.push(type); } @@ -146,8 +146,8 @@ class RandomGen2Teams extends RandomGen3Teams { */ randomSet(template, restrictMoves, slot) { if (slot === undefined) slot = 1; - template = this.getTemplate(template); - if (!template.exists) template = this.getTemplate('unown'); + template = this.dex.getTemplate(template); + if (!template.exists) template = this.dex.getTemplate('unown'); let randomSetNumber = 0; /**@type {RandomTeamsTypes.RandomSet} */ diff --git a/data/mods/gen2/scripts.js b/data/mods/gen2/scripts.js index ec1d9975b6..293031b4e1 100644 --- a/data/mods/gen2/scripts.js +++ b/data/mods/gen2/scripts.js @@ -45,7 +45,7 @@ let BattleScripts = { } // Gen 2 caps stats at 999 and min is 1. - stat = this.battle.clampIntRange(stat, 1, 999); + stat = this.battle.dex.clampIntRange(stat, 1, 999); if (fastReturn) return stat; // Screens @@ -96,12 +96,12 @@ let BattleScripts = { }, // Battle scripts. runMove(moveOrMoveName, pokemon, targetLoc, sourceEffect) { - let move = this.getActiveMove(moveOrMoveName); + let move = this.dex.getActiveMove(moveOrMoveName); let target = this.getTarget(pokemon, move, targetLoc); if (!sourceEffect && move.id !== 'struggle') { let changedMove = this.runEvent('OverrideAction', pokemon, target, move); if (changedMove && changedMove !== true) { - move = this.getActiveMove(changedMove); + move = this.dex.getActiveMove(changedMove); target = this.resolveTarget(pokemon, move); } } @@ -255,7 +255,7 @@ let BattleScripts = { /**@type {number | undefined | false} */ let moveDamage; - let isSleepUsable = move.sleepUsable || this.getMove(move.sourceEffect).sleepUsable; + let isSleepUsable = move.sleepUsable || this.dex.getMove(move.sourceEffect).sleepUsable; let i; for (i = 0; i < hits && target.hp && pokemon.hp; i++) { if (pokemon.status === 'slp' && !isSleepUsable) break; @@ -294,7 +294,7 @@ let BattleScripts = { moveHit(target, pokemon, move, moveData, isSecondary, isSelf) { /** @type {number | false | null | undefined} */ let damage = undefined; - move = this.getActiveMove(move); + move = this.dex.getActiveMove(move); if (!moveData) moveData = move; /**@type {?boolean | number} */ @@ -475,7 +475,7 @@ let BattleScripts = { getDamage(pokemon, target, move, suppressMessages) { // First of all, we get the move. if (typeof move === 'string') { - move = this.getActiveMove(move); + move = this.dex.getActiveMove(move); } else if (typeof move === 'number') { move = /** @type {ActiveMove} */ ({ basePower: move, @@ -532,11 +532,11 @@ let BattleScripts = { if (basePower === 0) return; // Returning undefined means not dealing damage return basePower; } - basePower = this.clampIntRange(basePower, 1); + basePower = this.dex.clampIntRange(basePower, 1); // Checking for the move's Critical Hit ratio let critRatio = this.runEvent('ModifyCritRatio', pokemon, target, move, move.critRatio || 0); - critRatio = this.clampIntRange(critRatio, 0, 5); + critRatio = this.dex.clampIntRange(critRatio, 0, 5); let critMult = [0, 16, 8, 4, 3, 2]; let isCrit = move.willCrit || false; if (typeof move.willCrit === 'undefined') { @@ -565,7 +565,7 @@ let BattleScripts = { } } if (!basePower) return 0; - basePower = this.clampIntRange(basePower, 1); + basePower = this.dex.clampIntRange(basePower, 1); // We now check for attacker and defender let level = pokemon.level; @@ -644,13 +644,13 @@ let BattleScripts = { if (attack >= 1024 || defense >= 1024) { this.hint("In Gen 2, a stat will roll over to a small number if it is larger than 1024."); } - attack = this.clampIntRange(Math.floor(attack / 4) % 256, 1); - defense = this.clampIntRange(Math.floor(defense / 4) % 256, 1); + attack = this.dex.clampIntRange(Math.floor(attack / 4) % 256, 1); + defense = this.dex.clampIntRange(Math.floor(defense / 4) % 256, 1); } // Self destruct moves halve defense at this point. if (move.selfdestruct && defType === 'def') { - defense = this.clampIntRange(Math.floor(defense / 2), 1); + defense = this.dex.clampIntRange(Math.floor(defense / 2), 1); } // Let's go with the calculation now that we have what we need. @@ -661,7 +661,7 @@ let BattleScripts = { damage *= basePower; damage *= attack; damage = Math.floor(damage / defense); - damage = this.clampIntRange(Math.floor(damage / 50), 1, 997); + damage = this.dex.clampIntRange(Math.floor(damage / 50), 1, 997); damage += 2; // Weather modifiers diff --git a/data/mods/gen2/statuses.js b/data/mods/gen2/statuses.js index 8897004447..3a49759c51 100644 --- a/data/mods/gen2/statuses.js +++ b/data/mods/gen2/statuses.js @@ -111,7 +111,7 @@ let BattleStatuses = { }, onAfterMoveSelfPriority: 3, onAfterMoveSelf(pokemon) { - this.damage(this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1) * pokemon.volatiles['residualdmg'].counter, pokemon, pokemon); + this.damage(this.dex.clampIntRange(Math.floor(pokemon.maxhp / 16), 1) * pokemon.volatiles['residualdmg'].counter, pokemon, pokemon); }, onSwitchIn(pokemon) { // Regular poison status and damage after a switchout -> switchin. @@ -119,7 +119,7 @@ let BattleStatuses = { this.add('-status', pokemon, 'psn', '[silent]'); }, onAfterSwitchInSelf(pokemon) { - this.damage(this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1)); + this.damage(this.dex.clampIntRange(Math.floor(pokemon.maxhp / 16), 1)); }, }, confusion: { @@ -198,7 +198,7 @@ let BattleStatuses = { delete pokemon.volatiles['lockedmove']; }, onBeforeTurn(pokemon) { - let move = this.getMove(this.effectData.move); + let move = this.dex.getMove(this.effectData.move); if (move.id) { this.debug('Forcing into ' + move.id); this.changeAction(pokemon, {move: move.id}); @@ -252,10 +252,10 @@ let BattleStatuses = { */ function residualdmg(battle, pokemon) { if (pokemon.volatiles['residualdmg']) { - battle.damage(battle.clampIntRange(Math.floor(pokemon.maxhp / 16) * pokemon.volatiles['residualdmg'].counter, 1), pokemon); + battle.damage(battle.dex.clampIntRange(Math.floor(pokemon.maxhp / 16) * pokemon.volatiles['residualdmg'].counter, 1), pokemon); battle.hint("In Gen 2, Toxic's counter is retained through Baton Pass/Heal Bell and applies to PSN/BRN.", true); } else { - battle.damage(battle.clampIntRange(Math.floor(pokemon.maxhp / 8), 1), pokemon); + battle.damage(battle.dex.clampIntRange(Math.floor(pokemon.maxhp / 8), 1), pokemon); } } diff --git a/data/mods/gen3/abilities.js b/data/mods/gen3/abilities.js index 0e2e6bb810..fec4158ebc 100644 --- a/data/mods/gen3/abilities.js +++ b/data/mods/gen3/abilities.js @@ -178,7 +178,7 @@ let BattleAbilities = { if (!pokemon.isStarted) return; let target = pokemon.side.foe.randomActive(); if (!target || target.fainted) return; - let ability = this.getAbility(target.ability); + let ability = this.dex.getAbility(target.ability); let bannedAbilities = ['forecast', 'multitype', 'trace']; if (bannedAbilities.includes(target.ability)) { return; diff --git a/data/mods/gen3/moves.js b/data/mods/gen3/moves.js index ad50644e8f..d0f7587c8f 100644 --- a/data/mods/gen3/moves.js +++ b/data/mods/gen3/moves.js @@ -81,7 +81,7 @@ let BattleMovedex = { return false; } if (!target.isActive) { - const possibleTarget = this.resolveTarget(pokemon, this.getMove('pound')); + const possibleTarget = this.resolveTarget(pokemon, this.dex.getMove('pound')); if (!possibleTarget) { this.add('-miss', pokemon); return false; @@ -167,7 +167,7 @@ let BattleMovedex = { desc: "The user's type changes to match the original type of one of its known moves besides Curse, at random, but not either of its current types. Fails if the user cannot change its type, or if this move would only be able to select one of the user's current types.", onHit(target) { let possibleTypes = target.moveSlots.map(moveSlot => { - let move = this.getMove(moveSlot.id); + let move = this.dex.getMove(moveSlot.id); if (move.id !== 'curse' && !target.hasType(move.type)) { return move.type; } @@ -191,7 +191,7 @@ let BattleMovedex = { desc: "Deals damage to the last opposing Pokemon to hit the user with a physical attack this turn equal to twice the HP lost by the user from that attack. If that opposing Pokemon's position is no longer in use and there is another opposing Pokemon on the field, the damage is done to it instead. This move considers Hidden Power as Normal type, and only the last hit of a multi-hit attack is counted. Fails if the user was not hit by an opposing Pokemon's physical attack this turn, or if the user did not lose HP from the attack.", damageCallback(pokemon) { let lastAttackedBy = pokemon.getLastAttackedBy(); - if (lastAttackedBy && lastAttackedBy.move && lastAttackedBy.thisTurn && (this.getCategory(lastAttackedBy.move) === 'Physical' || this.getMove(lastAttackedBy.move).id === 'hiddenpower')) { + if (lastAttackedBy && lastAttackedBy.move && lastAttackedBy.thisTurn && (this.getCategory(lastAttackedBy.move) === 'Physical' || this.dex.getMove(lastAttackedBy.move).id === 'hiddenpower')) { // @ts-ignore return 2 * lastAttackedBy.damage; } @@ -489,7 +489,7 @@ let BattleMovedex = { if (target.runImmunity('Fighting')) { let damage = this.getDamage(source, target, move, true); if (typeof damage !== 'number') throw new Error("HJK recoil failed"); - this.damage(this.clampIntRange(damage / 2, 1, Math.floor(target.maxhp / 2)), source, source, move); + this.damage(this.dex.clampIntRange(damage / 2, 1, Math.floor(target.maxhp / 2)), source, source, move); } }, }, @@ -515,7 +515,7 @@ let BattleMovedex = { if (target.runImmunity('Fighting')) { let damage = this.getDamage(source, target, move, true); if (typeof damage !== 'number') throw new Error("Jump Kick didn't recoil"); - this.damage(this.clampIntRange(damage / 2, 1, Math.floor(target.maxhp / 2)), source, source, move); + this.damage(this.dex.clampIntRange(damage / 2, 1, Math.floor(target.maxhp / 2)), source, source, move); } }, }, @@ -748,7 +748,7 @@ let BattleMovedex = { let move = moveSlot.id; let pp = moveSlot.pp; let NoSleepTalk = ['assist', 'bide', 'focuspunch', 'metronome', 'mirrormove', 'sleeptalk', 'uproar']; - if (move && !(NoSleepTalk.includes(move) || this.getMove(move).flags['charge'])) { + if (move && !(NoSleepTalk.includes(move) || this.dex.getMove(move).flags['charge'])) { moves.push({move: move, pp: pp}); } } @@ -868,7 +868,7 @@ let BattleMovedex = { }, onDisableMove(pokemon) { for (const moveSlot of pokemon.moveSlots) { - if (this.getMove(moveSlot.move).category === 'Status') { + if (this.dex.getMove(moveSlot.move).category === 'Status') { pokemon.disableMove(moveSlot.id); } } diff --git a/data/mods/gen3/random-teams.js b/data/mods/gen3/random-teams.js index a6326a9fa6..5ab9d865f7 100644 --- a/data/mods/gen3/random-teams.js +++ b/data/mods/gen3/random-teams.js @@ -9,11 +9,11 @@ class RandomGen3Teams extends RandomGen4Teams { * @return {RandomTeamsTypes.RandomSet} */ randomSet(template, teamDetails = {}) { - let baseTemplate = (template = this.getTemplate(template)); + let baseTemplate = (template = this.dex.getTemplate(template)); let species = template.species; if (!template.exists || (!template.randomBattleMoves && !template.learnset)) { - template = this.getTemplate('unown'); + template = this.dex.getTemplate('unown'); let err = new Error('Template incompatible with random battles: ' + species); Monitor.crashlog(err, 'The gen 3 randbat set generator'); @@ -115,7 +115,7 @@ class RandomGen3Teams extends RandomGen4Teams { // Iterate through the moves again, this time to cull them: for (const [i, setMoveid] of moves.entries()) { - let move = this.getMove(setMoveid); + let move = this.dex.getMove(setMoveid); let moveid = move.id; let rejected = false; let isSetup = false; @@ -365,7 +365,7 @@ class RandomGen3Teams extends RandomGen4Teams { if (reqMove) { // reject a move for (let [i, move] of moves.entries()) { - if (move === 'weatherball' || this.getMove(move).type in hasType) continue; + if (move === 'weatherball' || this.dex.getMove(move).type in hasType) continue; moves[i] = reqMove; let reqMoveIndex = movePool.indexOf(reqMove); if (reqMoveIndex !== -1) this.fastPop(movePool, reqMoveIndex); @@ -437,10 +437,10 @@ class RandomGen3Teams extends RandomGen4Teams { ivs = {hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31}; } - let abilities = Object.values(baseTemplate.abilities).filter(a => this.getAbility(a).gen === 3); - abilities.sort((a, b) => this.getAbility(b).rating - this.getAbility(a).rating); - let ability0 = this.getAbility(abilities[0]); - let ability1 = this.getAbility(abilities[1]); + let abilities = Object.values(baseTemplate.abilities).filter(a => this.dex.getAbility(a).gen === 3); + abilities.sort((a, b) => this.dex.getAbility(b).rating - this.dex.getAbility(a).rating); + let ability0 = this.dex.getAbility(abilities[0]); + let ability1 = this.dex.getAbility(abilities[1]); if (abilities[1]) { if (ability0.rating <= ability1.rating && this.randomChance(1, 2)) { [ability0, ability1] = [ability1, ability0]; @@ -610,13 +610,13 @@ class RandomGen3Teams extends RandomGen4Teams { let allowedNFE = ['Scyther', 'Vigoroth']; let pokemonPool = []; - for (let id in this.data.FormatsData) { - let template = this.getTemplate(id); + for (let id in this.dex.data.FormatsData) { + let template = this.dex.getTemplate(id); if (template.isNonstandard || !template.randomBattleMoves) continue; if (template.evos && !allowedNFE.includes(template.species)) { let invalid = false; for (const evo of template.evos) { - if (this.getTemplate(evo).gen <= 3) { + if (this.dex.getTemplate(evo).gen <= 3) { invalid = true; break; } @@ -638,7 +638,7 @@ class RandomGen3Teams extends RandomGen4Teams { let teamDetails = {}; while (pokemonPool.length && pokemon.length < 6) { - let template = this.getTemplate(this.sampleNoReplace(pokemonPool)); + let template = this.dex.getTemplate(this.sampleNoReplace(pokemonPool)); if (!template.exists) continue; // Limit to one of each species (Species Clause) diff --git a/data/mods/gen3/scripts.js b/data/mods/gen3/scripts.js index 2e7d4d2bc0..f85e504111 100644 --- a/data/mods/gen3/scripts.js +++ b/data/mods/gen3/scripts.js @@ -23,7 +23,7 @@ let BattleScripts = { if (!sourceEffect && this.effect.id) sourceEffect = this.effect; if (sourceEffect && sourceEffect.id === 'instruct') sourceEffect = null; - let move = this.getActiveMove(moveOrMoveName); + let move = this.dex.getActiveMove(moveOrMoveName); if (this.activeMove) { move.priority = this.activeMove.priority; @@ -61,7 +61,7 @@ let BattleScripts = { let movename = move.name; if (move.id === 'hiddenpower') movename = 'Hidden Power'; - if (sourceEffect) attrs += `|[from]${this.getEffect(sourceEffect)}`; + if (sourceEffect) attrs += `|[from]${this.dex.getEffect(sourceEffect)}`; this.addMove('move', pokemon, movename, target + attrs); if (!target) { @@ -221,7 +221,7 @@ let BattleScripts = { if (accuracy !== true) { if (!move.ignoreAccuracy) { boosts = this.runEvent('ModifyBoost', pokemon, null, null, Object.assign({}, pokemon.boosts)); - boost = this.clampIntRange(boosts['accuracy'], -6, 6); + boost = this.dex.clampIntRange(boosts['accuracy'], -6, 6); if (boost > 0) { accuracy *= boostTable[boost]; } else { @@ -230,7 +230,7 @@ let BattleScripts = { } if (!move.ignoreEvasion) { boosts = this.runEvent('ModifyBoost', target, null, null, Object.assign({}, target.boosts)); - boost = this.clampIntRange(boosts['evasion'], -6, 6); + boost = this.dex.clampIntRange(boosts['evasion'], -6, 6); if (boost > 0) { accuracy /= boostTable[boost]; } else if (boost < 0) { @@ -301,7 +301,7 @@ let BattleScripts = { /** @type {number | undefined | false} */ let moveDamage; // There is no need to recursively check the ´sleepUsable´ flag as Sleep Talk can only be used while asleep. - let isSleepUsable = move.sleepUsable || this.getMove(move.sourceEffect).sleepUsable; + let isSleepUsable = move.sleepUsable || this.dex.getMove(move.sourceEffect).sleepUsable; let i; for (i = 0; i < hits && target.hp && pokemon.hp; i++) { if (pokemon.status === 'slp' && !isSleepUsable) break; @@ -312,7 +312,7 @@ let BattleScripts = { if (accuracy !== true) { if (!move.ignoreAccuracy) { boosts = this.runEvent('ModifyBoost', pokemon, null, null, Object.assign({}, pokemon.boosts)); - boost = this.clampIntRange(boosts['accuracy'], -6, 6); + boost = this.dex.clampIntRange(boosts['accuracy'], -6, 6); if (boost > 0) { accuracy *= boostTable[boost]; } else { @@ -321,7 +321,7 @@ let BattleScripts = { } if (!move.ignoreEvasion) { boosts = this.runEvent('ModifyBoost', target, null, null, Object.assign({}, target.boosts)); - boost = this.clampIntRange(boosts['evasion'], -6, 6); + boost = this.dex.clampIntRange(boosts['evasion'], -6, 6); if (boost > 0) { accuracy /= boostTable[boost]; } else if (boost < 0) { @@ -375,7 +375,7 @@ let BattleScripts = { calcRecoilDamage(damageDealt, move) { // @ts-ignore - return this.clampIntRange(Math.floor(damageDealt * move.recoil[0] / move.recoil[1]), 1); + return this.dex.clampIntRange(Math.floor(damageDealt * move.recoil[0] / move.recoil[1]), 1); }, }; diff --git a/data/mods/gen4/abilities.js b/data/mods/gen4/abilities.js index 34f35042e1..20282d26d1 100644 --- a/data/mods/gen4/abilities.js +++ b/data/mods/gen4/abilities.js @@ -111,7 +111,7 @@ let BattleAbilities = { for (const target of pokemon.side.foe.active) { if (target.fainted) continue; for (const moveSlot of target.moveSlots) { - let move = this.getMove(moveSlot.move); + let move = this.dex.getMove(moveSlot.move); let bp = move.basePower; if (move.ohko) bp = 160; if (move.id === 'counter' || move.id === 'metalburst' || move.id === 'mirrorcoat') bp = 120; @@ -420,7 +420,7 @@ let BattleAbilities = { if (!pokemon.isStarted) return; let target = pokemon.side.foe.randomActive(); if (!target || target.fainted) return; - let ability = this.getAbility(target.ability); + let ability = this.dex.getAbility(target.ability); let bannedAbilities = ['forecast', 'multitype', 'trace']; if (bannedAbilities.includes(target.ability)) { return; diff --git a/data/mods/gen4/items.js b/data/mods/gen4/items.js index 1caeb8f62a..fead6f05b9 100644 --- a/data/mods/gen4/items.js +++ b/data/mods/gen4/items.js @@ -166,7 +166,7 @@ let BattleItems = { duration: 1, onAfterMoveSecondarySelf(source, target, move) { if (move && move.effectType === 'Move' && source && source.volatiles['lifeorb']) { - this.damage(source.maxhp / 10, source, source, this.getItem('lifeorb')); + this.damage(source.maxhp / 10, source, source, this.dex.getItem('lifeorb')); source.removeVolatile('lifeorb'); } }, diff --git a/data/mods/gen4/moves.js b/data/mods/gen4/moves.js index a300f763df..b33414084a 100644 --- a/data/mods/gen4/moves.js +++ b/data/mods/gen4/moves.js @@ -152,7 +152,7 @@ let BattleMovedex = { return false; } if (!target.isActive) { - const possibleTarget = this.resolveTarget(pokemon, this.getMove('pound')); + const possibleTarget = this.resolveTarget(pokemon, this.dex.getMove('pound')); if (!possibleTarget) { this.add('-miss', pokemon); return false; @@ -264,7 +264,7 @@ let BattleMovedex = { flags: {}, onHit(target) { let possibleTypes = target.moveSlots.map(moveSlot => { - let move = this.getMove(moveSlot.id); + let move = this.dex.getMove(moveSlot.id); if (move.id !== 'conversion' && move.id !== 'curse' && !target.hasType(move.type)) { return move.type; } @@ -782,7 +782,7 @@ let BattleMovedex = { }, onDisableMove(pokemon) { for (const moveSlot of pokemon.moveSlots) { - if (this.getMove(moveSlot.id).flags['heal']) { + if (this.dex.getMove(moveSlot.id).flags['heal']) { pokemon.disableMove(moveSlot.id); } } @@ -842,7 +842,7 @@ let BattleMovedex = { move.causedCrashDamage = true; let damage = this.getDamage(source, target, move, true); if (!damage) damage = target.maxhp; - this.damage(this.clampIntRange(damage / 2, 1, Math.floor(target.maxhp / 2)), source, source, move); + this.damage(this.dex.clampIntRange(damage / 2, 1, Math.floor(target.maxhp / 2)), source, source, move); }, }, iciclespear: { @@ -878,7 +878,7 @@ let BattleMovedex = { move.causedCrashDamage = true; let damage = this.getDamage(source, target, move, true); if (!damage) damage = target.maxhp; - this.damage(this.clampIntRange(damage / 2, 1, Math.floor(target.maxhp / 2)), source, source, move); + this.damage(this.dex.clampIntRange(damage / 2, 1, Math.floor(target.maxhp / 2)), source, source, move); }, }, knockoff: { @@ -980,7 +980,7 @@ let BattleMovedex = { return; } target.removeVolatile('magiccoat'); - let newMove = this.getActiveMove(move.id); + let newMove = this.dex.getActiveMove(move.id); newMove.hasBounced = true; this.useMove(newMove, target, source); return null; @@ -1061,7 +1061,7 @@ let BattleMovedex = { if (source.transformed || !target.lastMove || disallowedMoves.includes(target.lastMove.id) || source.moves.indexOf(target.lastMove.id) !== -1 || target.volatiles['substitute']) return false; let mimicIndex = source.moves.indexOf('mimic'); if (mimicIndex < 0) return false; - let move = this.getMove(target.lastMove.id); + let move = this.dex.getMove(target.lastMove.id); source.moveSlots[mimicIndex] = { move: move.name, id: move.id, @@ -1254,7 +1254,7 @@ let BattleMovedex = { let sideConditions = ['spikes', 'toxicspikes', 'stealthrock', 'stickyweb']; for (const condition of sideConditions) { if (pokemon.side.removeSideCondition(condition)) { - this.add('-sideend', pokemon.side, this.getEffect(condition).name, '[from] move: Rapid Spin', '[of] ' + pokemon); + this.add('-sideend', pokemon.side, this.dex.getEffect(condition).name, '[from] move: Rapid Spin', '[of] ' + pokemon); } } if (pokemon.volatiles['partiallytrapped']) { @@ -1382,7 +1382,7 @@ let BattleMovedex = { if (source.transformed || !target.lastMove || disallowedMoves.includes(target.lastMove.id) || source.moves.includes(target.lastMove.id) || target.volatiles['substitute']) return false; let sketchIndex = source.moves.indexOf('sketch'); if (sketchIndex < 0) return false; - let move = this.getMove(target.lastMove.id); + let move = this.dex.getMove(target.lastMove.id); let sketchedMove = { move: move.name, id: move.id, @@ -1632,7 +1632,7 @@ let BattleMovedex = { }, onDisableMove(pokemon) { for (const moveSlot of pokemon.moveSlots) { - if (this.getMove(moveSlot.id).category === 'Status') { + if (this.dex.getMove(moveSlot.id).category === 'Status') { pokemon.disableMove(moveSlot.id); } } diff --git a/data/mods/gen4/random-teams.js b/data/mods/gen4/random-teams.js index ed6f3c3cae..1cc8cd7a06 100644 --- a/data/mods/gen4/random-teams.js +++ b/data/mods/gen4/random-teams.js @@ -10,11 +10,11 @@ class RandomGen4Teams extends RandomGen5Teams { * @return {RandomTeamsTypes.RandomSet} */ randomSet(template, teamDetails = {}, isLead = false) { - let baseTemplate = (template = this.getTemplate(template)); + let baseTemplate = (template = this.dex.getTemplate(template)); let species = template.species; if (!template.exists || (!template.randomBattleMoves && !template.learnset)) { - template = this.getTemplate('unown'); + template = this.dex.getTemplate('unown'); let err = new Error('Template incompatible with random battles: ' + species); Monitor.crashlog(err, 'The gen 4 randbat set generator'); @@ -110,7 +110,7 @@ class RandomGen4Teams extends RandomGen5Teams { // Iterate through the moves again, this time to cull them: for (const [i, setMoveid] of moves.entries()) { - let move = this.getMove(setMoveid); + let move = this.dex.getMove(setMoveid); let moveid = move.id; let rejected = false; let isSetup = false; @@ -485,9 +485,9 @@ class RandomGen4Teams extends RandomGen5Teams { } let abilities = Object.values(baseTemplate.abilities); - abilities.sort((a, b) => this.getAbility(b).rating - this.getAbility(a).rating); - let ability0 = this.getAbility(abilities[0]); - let ability1 = this.getAbility(abilities[1]); + abilities.sort((a, b) => this.dex.getAbility(b).rating - this.dex.getAbility(a).rating); + let ability0 = this.dex.getAbility(abilities[0]); + let ability1 = this.dex.getAbility(abilities[1]); if (abilities[1]) { if (ability0.rating <= ability1.rating && this.randomChance(1, 2)) { [ability0, ability1] = [ability1, ability0]; @@ -638,7 +638,7 @@ class RandomGen4Teams extends RandomGen5Teams { // This is the "REALLY can't think of a good item" cutoff } else if (hasType['Poison']) { item = 'Black Sludge'; - } else if (this.getEffectiveness('Rock', template) >= 1 || hasMove['roar']) { + } else if (this.dex.getEffectiveness('Rock', template) >= 1 || hasMove['roar']) { item = 'Leftovers'; } else if (counter.Status <= 1 && !hasMove['metalburst'] && !hasMove['rapidspin'] && !hasMove['superfang']) { item = 'Life Orb'; @@ -686,7 +686,7 @@ class RandomGen4Teams extends RandomGen5Teams { if (hp % 4 === 0) evs.hp -= 4; } else { // Maximize number of Stealth Rock switch-ins - let srWeakness = this.getEffectiveness('Rock', template); + let srWeakness = this.dex.getEffectiveness('Rock', template); if (srWeakness > 0 && hp % (4 / srWeakness) === 0) evs.hp -= 4; } diff --git a/data/mods/gen4/rulesets.js b/data/mods/gen4/rulesets.js index 6facb00d96..400a6e97f9 100644 --- a/data/mods/gen4/rulesets.js +++ b/data/mods/gen4/rulesets.js @@ -5,8 +5,8 @@ let BattleFormats = { validatestats: { inherit: true, onValidateSet(set) { - let template = this.getTemplate(set.species); - let item = this.getItem(set.item); + let template = this.dex.getTemplate(set.species); + let item = this.dex.getItem(set.item); if (item && item.id === 'griseousorb' && template.num !== 487) { return ['Griseous Orb can only be held by Giratina in Generation 4.']; } diff --git a/data/mods/gen4/scripts.js b/data/mods/gen4/scripts.js index 1de90ca7d3..15e1cdc17a 100644 --- a/data/mods/gen4/scripts.js +++ b/data/mods/gen4/scripts.js @@ -62,7 +62,7 @@ let BattleScripts = { } // types let typeMod = target.runEffectiveness(move); - typeMod = this.clampIntRange(typeMod, -6, 6); + typeMod = this.dex.clampIntRange(typeMod, -6, 6); target.getMoveHitData(move).typeMod = typeMod; if (typeMod > 0) { if (!suppressMessages) this.add('-supereffective', target); @@ -104,7 +104,7 @@ let BattleScripts = { calcRecoilDamage(damageDealt, move) { // @ts-ignore - return this.clampIntRange(Math.floor(damageDealt * move.recoil[0] / move.recoil[1]), 1); + return this.dex.clampIntRange(Math.floor(damageDealt * move.recoil[0] / move.recoil[1]), 1); }, }; diff --git a/data/mods/gen5/abilities.js b/data/mods/gen5/abilities.js index 197fecd771..d2cdb10438 100644 --- a/data/mods/gen5/abilities.js +++ b/data/mods/gen5/abilities.js @@ -9,8 +9,8 @@ let BattleAbilities = { for (const target of pokemon.side.foe.active) { if (!target || target.fainted) continue; for (const moveSlot of target.moveSlots) { - const move = this.getMove(moveSlot.move); - if (move.category !== 'Status' && (this.getImmunity(move.type, pokemon) && this.getEffectiveness(move.type, pokemon) > 0 || move.ohko)) { + const move = this.dex.getMove(moveSlot.move); + if (move.category !== 'Status' && (this.dex.getImmunity(move.type, pokemon) && this.dex.getEffectiveness(move.type, pokemon) > 0 || move.ohko)) { this.add('-ability', pokemon, 'Anticipation'); return; } diff --git a/data/mods/gen5/moves.js b/data/mods/gen5/moves.js index 65d49e78a2..c69e44b8e4 100644 --- a/data/mods/gen5/moves.js +++ b/data/mods/gen5/moves.js @@ -181,7 +181,7 @@ let BattleMovedex = { shortDesc: "Changes user's type to match a known move.", onHit(target) { let possibleTypes = target.moveSlots.map(moveSlot => { - let move = this.getMove(moveSlot.id); + let move = this.dex.getMove(moveSlot.id); if (move.id !== 'conversion' && !target.hasType(move.type)) { return move.type; } @@ -230,7 +230,7 @@ let BattleMovedex = { let sideConditions = ['reflect', 'lightscreen', 'safeguard', 'mist', 'spikes', 'toxicspikes', 'stealthrock']; for (const condition of sideConditions) { if (pokemon.side.removeSideCondition(condition)) { - this.add('-sideend', pokemon.side, this.getEffect(condition).name, '[from] move: Defog', '[of] ' + pokemon); + this.add('-sideend', pokemon.side, this.dex.getEffect(condition).name, '[from] move: Defog', '[of] ' + pokemon); } } }, @@ -834,7 +834,7 @@ let BattleMovedex = { onTryHit(target, source, effect) { // Quick Guard only blocks moves with a natural positive priority // (e.g. it doesn't block 0 priority moves boosted by Prankster) - if (effect && (effect.id === 'feint' || this.getMove(effect.id).priority <= 0)) { + if (effect && (effect.id === 'feint' || this.dex.getMove(effect.id).priority <= 0)) { return; } this.add('-activate', target, 'Quick Guard'); @@ -970,7 +970,7 @@ let BattleMovedex = { if (targetAbility === sourceAbility) { return false; } - this.add('-activate', source, 'move: Skill Swap', this.getAbility(targetAbility), this.getAbility(sourceAbility), '[of] ' + target); + this.add('-activate', source, 'move: Skill Swap', this.dex.getAbility(targetAbility), this.dex.getAbility(sourceAbility), '[of] ' + target); source.setAbility(targetAbility); target.setAbility(sourceAbility); }, diff --git a/data/mods/gen5/random-teams.js b/data/mods/gen5/random-teams.js index 2bc00b2485..8120ef1266 100644 --- a/data/mods/gen5/random-teams.js +++ b/data/mods/gen5/random-teams.js @@ -10,12 +10,12 @@ class RandomGen5Teams extends RandomGen6Teams { * @return {RandomTeamsTypes.RandomSet} */ randomSet(template, teamDetails = {}, isLead = false) { - let baseTemplate = (template = this.getTemplate(template)); + let baseTemplate = (template = this.dex.getTemplate(template)); let species = template.species; if (!template.exists || (!template.randomBattleMoves && !template.learnset)) { // GET IT? UNOWN? BECAUSE WE CAN'T TELL WHAT THE POKEMON IS - template = this.getTemplate('unown'); + template = this.dex.getTemplate('unown'); let err = new Error('Template incompatible with random battles: ' + species); Monitor.crashlog(err, 'The gen 5 randbat set generator'); @@ -106,7 +106,7 @@ class RandomGen5Teams extends RandomGen6Teams { // Iterate through the moves again, this time to cull them: for (const [i, setMoveid] of moves.entries()) { - let move = this.getMove(setMoveid); + let move = this.dex.getMove(setMoveid); let moveid = move.id; let rejected = false; let isSetup = false; @@ -385,7 +385,7 @@ class RandomGen5Teams extends RandomGen6Teams { // Handle Hidden Power IVs if (moveid === 'hiddenpower') { - let HPivs = this.getType(move.type).HPivs; + let HPivs = this.dex.getType(move.type).HPivs; for (let iv in HPivs) { // @ts-ignore ivs[iv] = HPivs[iv]; @@ -400,10 +400,10 @@ class RandomGen5Teams extends RandomGen6Teams { } let abilities = Object.values(baseTemplate.abilities); - abilities.sort((a, b) => this.getAbility(b).rating - this.getAbility(a).rating); - let ability0 = this.getAbility(abilities[0]); - let ability1 = this.getAbility(abilities[1]); - let ability2 = this.getAbility(abilities[2]); + abilities.sort((a, b) => this.dex.getAbility(b).rating - this.dex.getAbility(a).rating); + let ability0 = this.dex.getAbility(abilities[0]); + let ability1 = this.dex.getAbility(abilities[1]); + let ability2 = this.dex.getAbility(abilities[2]); if (abilities[1]) { if (abilities[2] && ability1.rating <= ability2.rating && this.randomChance(1, 2)) { [ability1, ability2] = [ability2, ability1]; @@ -556,7 +556,7 @@ class RandomGen5Teams extends RandomGen6Teams { // Give Unburden mons a random Gem of the type of one of their damaging moves let eligibleTypes = []; for (const setMoveid of moves) { - let move = this.getMove(setMoveid); + let move = this.dex.getMove(setMoveid); if (!move.basePower && !move.basePowerCallback) continue; eligibleTypes.push(move.type); } @@ -571,12 +571,12 @@ class RandomGen5Teams extends RandomGen6Teams { item = 'Life Orb'; } else if ((hasMove['eruption'] || hasMove['waterspout']) && !counter['Status']) { item = 'Choice Scarf'; - } else if (this.getEffectiveness('Ground', template) >= 2 && ability !== 'Levitate' && !hasMove['magnetrise']) { + } else if (this.dex.getEffectiveness('Ground', template) >= 2 && ability !== 'Levitate' && !hasMove['magnetrise']) { item = 'Air Balloon'; } else if (hasMove['substitute'] && hasMove['reversal']) { let eligibleTypes = []; for (const setMoveid of moves) { - let move = this.getMove(setMoveid); + let move = this.dex.getMove(setMoveid); if (!move.basePower && !move.basePowerCallback) continue; eligibleTypes.push(move.type); } @@ -601,7 +601,7 @@ class RandomGen5Teams extends RandomGen6Teams { // This is the "REALLY can't think of a good item" cutoff } else if (hasType['Poison']) { item = 'Black Sludge'; - } else if (this.getEffectiveness('Rock', template) >= 1 || hasMove['dragontail']) { + } else if (this.dex.getEffectiveness('Rock', template) >= 1 || hasMove['dragontail']) { item = 'Leftovers'; } else if (counter.Status <= 1 && ability !== 'Sturdy' && !hasMove['rapidspin']) { item = 'Life Orb'; @@ -662,8 +662,8 @@ class RandomGen5Teams extends RandomGen6Teams { const allowedNFE = ['Porygon2', 'Scyther']; let pokemonPool = []; - for (let id in this.data.FormatsData) { - let template = this.getTemplate(id); + for (let id in this.dex.data.FormatsData) { + let template = this.dex.getTemplate(id); if ((!template.nfe || allowedNFE.includes(template.species)) && !template.isNonstandard && template.randomBattleMoves) { pokemonPool.push(id); } @@ -681,7 +681,7 @@ class RandomGen5Teams extends RandomGen6Teams { let teamDetails = {}; while (pokemonPool.length && pokemon.length < 6) { - let template = this.getTemplate(this.sampleNoReplace(pokemonPool)); + let template = this.dex.getTemplate(this.sampleNoReplace(pokemonPool)); if (!template.exists) continue; // Limit to one of each species (Species Clause) diff --git a/data/mods/gen6/abilities.js b/data/mods/gen6/abilities.js index a3fb2e62e4..c5d7a4b2e2 100644 --- a/data/mods/gen6/abilities.js +++ b/data/mods/gen6/abilities.js @@ -75,7 +75,7 @@ let BattleAbilities = { shortDesc: "This Pokemon's moves are changed to be Normal type.", onModifyMovePriority: 1, onModifyMove(move) { - if (move.id !== 'struggle' && this.getMove(move.id).type !== 'Normal') { + if (move.id !== 'struggle' && this.dex.getMove(move.id).type !== 'Normal') { move.type = 'Normal'; } }, diff --git a/data/mods/gen6/items.js b/data/mods/gen6/items.js index 391e7175ca..10e90e6998 100644 --- a/data/mods/gen6/items.js +++ b/data/mods/gen6/items.js @@ -77,7 +77,7 @@ let BattleItems = { inherit: true, onAfterMoveSecondarySelf(source, target, move) { if (source && source !== target && move && move.category !== 'Status' && !move.ohko) { - this.damage(source.maxhp / 10, source, source, this.getItem('lifeorb')); + this.damage(source.maxhp / 10, source, source, this.dex.getItem('lifeorb')); } }, }, diff --git a/data/mods/gen6/moves.js b/data/mods/gen6/moves.js index 9391f3c8b7..fcf0e660fa 100644 --- a/data/mods/gen6/moves.js +++ b/data/mods/gen6/moves.js @@ -312,7 +312,7 @@ let BattleMovedex = { onTryMove(pokemon, target, move) { if (move.type === 'Fire') { this.add('-activate', pokemon, 'move: Powder'); - this.damage(this.clampIntRange(Math.round(pokemon.maxhp / 4), 1)); + this.damage(this.dex.clampIntRange(Math.round(pokemon.maxhp / 4), 1)); return false; } }, diff --git a/data/mods/gen6/random-teams.js b/data/mods/gen6/random-teams.js index 57500934e1..8070576a1e 100644 --- a/data/mods/gen6/random-teams.js +++ b/data/mods/gen6/random-teams.js @@ -21,12 +21,12 @@ class RandomGen6Teams extends RandomTeams { * @return {RandomTeamsTypes.RandomSet} */ randomSet(template, teamDetails = {}, isLead = false) { - let baseTemplate = (template = this.getTemplate(template)); + let baseTemplate = (template = this.dex.getTemplate(template)); let species = template.species; if (!template.exists || (!template.randomBattleMoves && !template.learnset)) { // GET IT? UNOWN? BECAUSE WE CAN'T TELL WHAT THE POKEMON IS - template = this.getTemplate('unown'); + template = this.dex.getTemplate('unown'); let err = new Error('Template incompatible with random battles: ' + species); Monitor.crashlog(err, 'The gen 6 randbat set generator'); @@ -38,7 +38,7 @@ class RandomGen6Teams extends RandomTeams { } let battleForme = this.checkBattleForme(template); if (battleForme && battleForme.randomBattleMoves && template.otherFormes && (battleForme.isMega ? !teamDetails.megaStone : this.random(2))) { - template = this.getTemplate(template.otherFormes.length >= 2 ? this.sample(template.otherFormes) : template.otherFormes[0]); + template = this.dex.getTemplate(template.otherFormes.length >= 2 ? this.sample(template.otherFormes) : template.otherFormes[0]); } let movePool = (template.randomBattleMoves ? template.randomBattleMoves.slice() : template.learnset ? Object.keys(template.learnset) : []); @@ -128,7 +128,7 @@ class RandomGen6Teams extends RandomTeams { // Iterate through the moves again, this time to cull them: for (const [i, setMoveid] of moves.entries()) { - let move = this.getMove(setMoveid); + let move = this.dex.getMove(setMoveid); let moveid = move.id; let rejected = false; let isSetup = false; @@ -568,7 +568,7 @@ class RandomGen6Teams extends RandomTeams { // Handle Hidden Power IVs if (moveid === 'hiddenpower') { - let HPivs = this.getType(move.type).HPivs; + let HPivs = this.dex.getType(move.type).HPivs; for (let iv in HPivs) { // @ts-ignore ivs[iv] = HPivs[iv]; @@ -591,10 +591,10 @@ class RandomGen6Teams extends RandomTeams { } let abilities = Object.values(baseTemplate.abilities); - abilities.sort((a, b) => this.getAbility(b).rating - this.getAbility(a).rating); - let ability0 = this.getAbility(abilities[0]); - let ability1 = this.getAbility(abilities[1]); - let ability2 = this.getAbility(abilities[2]); + abilities.sort((a, b) => this.dex.getAbility(b).rating - this.dex.getAbility(a).rating); + let ability0 = this.dex.getAbility(abilities[0]); + let ability1 = this.dex.getAbility(abilities[1]); + let ability2 = this.dex.getAbility(abilities[2]); if (abilities[1]) { if (abilities[2] && ability1.rating <= ability2.rating && this.randomChance(1, 2)) { [ability1, ability2] = [ability2, ability1]; @@ -787,7 +787,7 @@ class RandomGen6Teams extends RandomTeams { } else { item = 'Red Card'; for (let m in moves) { - let move = this.getMove(moves[m]); + let move = this.dex.getMove(moves[m]); if (hasType[move.type] && move.basePower >= 90) { item = move.type + ' Gem'; break; @@ -822,7 +822,7 @@ class RandomGen6Teams extends RandomTeams { item = 'Lum Berry'; } else if (hasMove['substitute']) { item = counter.damagingMoves.length > 2 && !!counter['drain'] ? 'Life Orb' : 'Leftovers'; - } else if (this.getEffectiveness('Ground', template) >= 2 && ability !== 'Levitate' && !hasMove['magnetrise']) { + } else if (this.dex.getEffectiveness('Ground', template) >= 2 && ability !== 'Levitate' && !hasMove['magnetrise']) { item = 'Air Balloon'; } else if ((ability === 'Iron Barbs' || ability === 'Rough Skin') && this.randomChance(1, 2)) { item = 'Rocky Helmet'; @@ -884,7 +884,7 @@ class RandomGen6Teams extends RandomTeams { if (customScale[species]) level = customScale[species]; // Prepare optimal HP - let srWeakness = this.getEffectiveness('Rock', template); + let srWeakness = this.dex.getEffectiveness('Rock', template); while (evs.hp > 1) { let hp = Math.floor(Math.floor(2 * template.baseStats.hp + ivs.hp + Math.floor(evs.hp / 4) + 100) * level / 100 + 10); if (hasMove['substitute'] && hasMove['reversal']) { @@ -962,11 +962,11 @@ class RandomGen6Teams extends RandomTeams { let effectivePool = []; let priorityPool = []; for (const curSet of setList) { - let itemData = this.getItem(curSet.item); + let itemData = this.dex.getItem(curSet.item); if (teamData.megaCount > 0 && itemData.megaStone) continue; // reject 2+ mega stones if (itemsMax[itemData.id] && teamData.has[itemData.id] >= itemsMax[itemData.id]) continue; - let abilityData = this.getAbility(curSet.ability); + let abilityData = this.dex.getAbility(curSet.ability); if (weatherAbilitiesRequire[abilityData.id] && teamData.weather !== weatherAbilitiesRequire[abilityData.id]) continue; if (teamData.weather && weatherAbilities.includes(abilityData.id)) continue; // reject 2+ weather setters @@ -1055,7 +1055,7 @@ class RandomGen6Teams extends RandomTeams { }; while (pokemonPool.length && pokemon.length < 6) { - let template = this.getTemplate(this.sampleNoReplace(pokemonPool)); + let template = this.dex.getTemplate(this.sampleNoReplace(pokemonPool)); if (!template.exists) continue; let speciesFlags = this.randomFactorySets[chosenTier][template.speciesid].flags; @@ -1103,7 +1103,7 @@ class RandomGen6Teams extends RandomTeams { teamData.baseFormes[template.baseSpecies] = 1; - let itemData = this.getItem(set.item); + let itemData = this.dex.getItem(set.item); if (itemData.megaStone) teamData.megaCount++; if (itemData.id in teamData.has) { teamData.has[itemData.id]++; @@ -1111,7 +1111,7 @@ class RandomGen6Teams extends RandomTeams { teamData.has[itemData.id] = 1; } - let abilityData = this.getAbility(set.ability); + let abilityData = this.dex.getAbility(set.ability); if (abilityData.id in weatherAbilitiesSet) { teamData.weather = weatherAbilitiesSet[abilityData.id]; } @@ -1128,16 +1128,16 @@ class RandomGen6Teams extends RandomTeams { } } - for (let typeName in this.data.TypeChart) { + for (let typeName in this.dex.data.TypeChart) { // Cover any major weakness (3+) with at least one resistance if (teamData.resistances[typeName] >= 1) continue; - if (resistanceAbilities[abilityData.id] && resistanceAbilities[abilityData.id].includes(typeName) || !this.getImmunity(typeName, types)) { + if (resistanceAbilities[abilityData.id] && resistanceAbilities[abilityData.id].includes(typeName) || !this.dex.getImmunity(typeName, types)) { // Heuristic: assume that Pokemon with these abilities don't have (too) negative typing. teamData.resistances[typeName] = (teamData.resistances[typeName] || 0) + 1; if (teamData.resistances[typeName] >= 1) teamData.weaknesses[typeName] = 0; continue; } - let typeMod = this.getEffectiveness(typeName, types); + let typeMod = this.dex.getEffectiveness(typeName, types); if (typeMod < 0) { teamData.resistances[typeName] = (teamData.resistances[typeName] || 0) + 1; if (teamData.resistances[typeName] >= 1) teamData.weaknesses[typeName] = 0; diff --git a/data/mods/gennext/abilities.js b/data/mods/gennext/abilities.js index 911cf287db..e4babe9c2e 100644 --- a/data/mods/gennext/abilities.js +++ b/data/mods/gennext/abilities.js @@ -45,7 +45,7 @@ let BattleAbilities = { let weather = move.weather; move.weather = ''; move.onHit = function (target, source) { - this.field.setWeather(weather, source, this.getAbility('forecast')); + this.field.setWeather(weather, source, this.dex.getAbility('forecast')); this.field.weatherData.duration = 0; }; move.target = 'self'; @@ -176,7 +176,7 @@ let BattleAbilities = { let weather = move.weather; move.weather = ''; move.onHit = function (target, source) { - this.field.setWeather(weather, source, this.getAbility('flowergift')); + this.field.setWeather(weather, source, this.dex.getAbility('flowergift')); this.field.weatherData.duration = 0; }; move.target = 'self'; @@ -199,7 +199,7 @@ let BattleAbilities = { onSwitchInPriority: 1, onSwitchIn(target) { if (!target.fainted) { - this.boost({spd: 1}, target, target, this.getAbility('flowergift')); + this.boost({spd: 1}, target, target, this.dex.getAbility('flowergift')); } target.side.removeSideCondition('flowergift'); }, @@ -508,7 +508,7 @@ let BattleAbilities = { onResidualOrder: 26, onResidualSubOrder: 1, onResidual(pokemon) { - if (!pokemon.m.gluttonyFlag && !pokemon.item && this.getItem(pokemon.lastItem).isBerry) { + if (!pokemon.m.gluttonyFlag && !pokemon.item && this.dex.getItem(pokemon.lastItem).isBerry) { pokemon.m.gluttonyFlag = true; pokemon.setItem(pokemon.lastItem); pokemon.lastItem = ''; diff --git a/data/mods/gennext/items.js b/data/mods/gennext/items.js index 127c96fec6..82a0b6a4c5 100644 --- a/data/mods/gennext/items.js +++ b/data/mods/gennext/items.js @@ -173,7 +173,7 @@ let BattleItems = { }, // onResidual(pokemon) { // if (pokemon.template.species === 'Shuckle') { - // this.heal(this.clampIntRange(pokemon.maxhp / 16, 1)); + // this.heal(this.dex.clampIntRange(pokemon.maxhp / 16, 1)); // } // }, desc: "Raises Farfetch'd's critical hit rate two stages.", diff --git a/data/mods/gennext/moves.js b/data/mods/gennext/moves.js index 6ebb278308..48ba3b61a9 100644 --- a/data/mods/gennext/moves.js +++ b/data/mods/gennext/moves.js @@ -175,7 +175,7 @@ let BattleMovedex = { this.add('-activate', target, 'Substitute', '[damage]'); } if (move.recoil) { - this.damage(this.clampIntRange(Math.round(damage * move.recoil[0] / move.recoil[1]), 1), source, target, 'recoil'); + this.damage(this.dex.clampIntRange(Math.round(damage * move.recoil[0] / move.recoil[1]), 1), source, target, 'recoil'); } if (move.drain) { this.heal(Math.ceil(damage * move.drain[0] / move.drain[1]), source, target, 'drain'); @@ -1318,7 +1318,7 @@ let BattleMovedex = { let sideConditions = ['spikes', 'toxicspikes', 'stealthrock']; for (let condition in sideConditions) { if (user.side.removeSideCondition(condition)) { - this.add('-sideend', user.side, this.getEffect(condition).name, '[from] move: Rapid Spin', '[of] ' + user); + this.add('-sideend', user.side, this.dex.getEffect(condition).name, '[from] move: Rapid Spin', '[of] ' + user); doubled = true; } } @@ -2022,9 +2022,9 @@ let BattleMovedex = { accuracy: 100, onModifyMove(move, user) { if (user.illusion) { - let illusionMoves = user.illusion.moves.filter(move => this.getMove(move).category !== 'Status'); + let illusionMoves = user.illusion.moves.filter(move => this.dex.getMove(move).category !== 'Status'); if (!illusionMoves.length) return; - move.name = this.getMove(this.sample(illusionMoves)).name; + move.name = this.dex.getMove(this.sample(illusionMoves)).name; } }, desc: "Has a 40% chance to lower the target's accuracy by 1 stage. If Illusion is active, displays as a random non-Status move in the copied Pokémon's moveset.", diff --git a/data/mods/gennext/statuses.js b/data/mods/gennext/statuses.js index bdb8f64a14..23a6f549ab 100644 --- a/data/mods/gennext/statuses.js +++ b/data/mods/gennext/statuses.js @@ -356,7 +356,7 @@ let BattleStatuses = { let weather = move.weather; move.weather = ''; move.onHit = function (target, source) { - this.field.setWeather(weather, source, this.getAbility('snowwarning')); + this.field.setWeather(weather, source, this.dex.getAbility('snowwarning')); this.field.weatherData.duration = 0; }; move.target = 'self'; @@ -381,7 +381,7 @@ let BattleStatuses = { let weather = move.weather; move.weather = ''; move.onHit = function (target, source) { - this.field.setWeather(weather, source, this.getAbility('sandstream')); + this.field.setWeather(weather, source, this.dex.getAbility('sandstream')); this.field.weatherData.duration = 0; }; move.target = 'self'; @@ -397,7 +397,7 @@ let BattleStatuses = { let weather = move.weather; move.weather = ''; move.onHit = function (target, source) { - this.field.setWeather(weather, source, this.getAbility('drizzle')); + this.field.setWeather(weather, source, this.dex.getAbility('drizzle')); this.field.weatherData.duration = 0; }; move.target = 'self'; diff --git a/data/mods/letsgo/moves.js b/data/mods/letsgo/moves.js index f7a1b0b5f7..0a1fb2c345 100644 --- a/data/mods/letsgo/moves.js +++ b/data/mods/letsgo/moves.js @@ -52,7 +52,7 @@ let BattleMovedex = { onHit(target, source, effect) { let moves = []; for (let i in exports.BattleMovedex) { - let move = this.getMove(i); + let move = this.dex.getMove(i); if (i !== move.id) continue; if (move.gen !== 1) continue; // @ts-ignore diff --git a/data/mods/letsgo/random-teams.js b/data/mods/letsgo/random-teams.js index 3980cdc884..496e3aa414 100644 --- a/data/mods/letsgo/random-teams.js +++ b/data/mods/letsgo/random-teams.js @@ -9,11 +9,11 @@ class RandomLetsGoTeams extends RandomTeams { * @return {RandomTeamsTypes.RandomSet} */ randomSet(template, teamDetails = {}) { - template = this.getTemplate(template); + template = this.dex.getTemplate(template); let species = template.species; if (!template.exists || (!template.randomBattleMoves && !template.learnset)) { - template = this.getTemplate('bulbasaur'); + template = this.dex.getTemplate('bulbasaur'); let err = new Error('Template incompatible with random battles: ' + species); Monitor.crashlog(err, 'The Let\'s Go randbat set generator'); @@ -56,7 +56,7 @@ class RandomLetsGoTeams extends RandomTeams { // Iterate through the moves again, this time to cull them: for (const [i, setMoveid] of moves.entries()) { - let move = this.getMove(setMoveid); + let move = this.dex.getMove(setMoveid); let moveid = move.id; let rejected = false; let isSetup = false; @@ -220,8 +220,8 @@ class RandomLetsGoTeams extends RandomTeams { let pokemon = []; let pokemonPool = []; - for (let id in this.data.FormatsData) { - let template = this.getTemplate(id); + for (let id in this.dex.data.FormatsData) { + let template = this.dex.getTemplate(id); if (template.num < 1 || (template.num > 151 && ![808, 809].includes(template.num)) || template.nfe || !template.randomBattleMoves || !template.randomBattleMoves.length) continue; pokemonPool.push(id); } @@ -236,7 +236,7 @@ class RandomLetsGoTeams extends RandomTeams { let teamDetails = {}; while (pokemonPool.length && pokemon.length < 6) { - let template = this.getTemplate(this.sampleNoReplace(pokemonPool)); + let template = this.dex.getTemplate(this.sampleNoReplace(pokemonPool)); if (!template.exists) continue; // Limit to one of each species (Species Clause) diff --git a/data/mods/letsgo/scripts.js b/data/mods/letsgo/scripts.js index 4af710c468..86d8953b96 100644 --- a/data/mods/letsgo/scripts.js +++ b/data/mods/letsgo/scripts.js @@ -27,7 +27,7 @@ let BattleScripts = { let stat = baseStats['hp']; modStats['hp'] = Math.floor(Math.floor(2 * stat + set.ivs['hp'] + 100) * set.level / 100 + 10); } - return this.natureModify(modStats, set); + return this.dex.natureModify(modStats, set); }, /** @@ -36,7 +36,7 @@ let BattleScripts = { * @return {StatsTable} */ natureModify(stats, set) { - let nature = this.getNature(set.nature); + let nature = this.dex.getNature(set.nature); // @ts-ignore if (nature.plus) stats[nature.plus] = Math.floor(stats[nature.plus] * 1.1); // @ts-ignore diff --git a/data/mods/mixandmega/items.js b/data/mods/mixandmega/items.js index 0b732d6214..a1b7c3ebda 100644 --- a/data/mods/mixandmega/items.js +++ b/data/mods/mixandmega/items.js @@ -43,7 +43,7 @@ let BattleItems = { pokemon.baseTemplate = template; this.add('-start', pokemon, 'Red Orb', '[silent]'); let apparentSpecies = pokemon.illusion ? pokemon.illusion.template.species : pokemon.m.originalSpecies; - let oTemplate = this.getTemplate(apparentSpecies); + let oTemplate = this.dex.getTemplate(apparentSpecies); if (pokemon.illusion) { let types = oTemplate.types; if (types.length > 1 || types[types.length - 1] !== 'Fire') { diff --git a/data/mods/mixandmega/scripts.js b/data/mods/mixandmega/scripts.js index 1a4a20c8e0..9bd704f410 100644 --- a/data/mods/mixandmega/scripts.js +++ b/data/mods/mixandmega/scripts.js @@ -39,12 +39,12 @@ let BattleScripts = { // Do we have a proper sprite for it? // @ts-ignore assert non-null pokemon.canMegaEvo - if (isUltraBurst || this.getTemplate(pokemon.canMegaEvo).baseSpecies === pokemon.m.originalSpecies) { + if (isUltraBurst || this.dex.getTemplate(pokemon.canMegaEvo).baseSpecies === pokemon.m.originalSpecies) { pokemon.formeChange(template, pokemon.getItem(), true); } else { - let oTemplate = this.getTemplate(pokemon.m.originalSpecies); + let oTemplate = this.dex.getTemplate(pokemon.m.originalSpecies); // @ts-ignore - let oMegaTemplate = this.getTemplate(template.originalMega); + let oMegaTemplate = this.dex.getTemplate(template.originalMega); pokemon.formeChange(template, pokemon.getItem(), true); this.add('-start', pokemon, oMegaTemplate.requiredItem || oMegaTemplate.requiredMove, '[silent]'); if (oTemplate.types.length !== pokemon.template.types.length || oTemplate.types[1] !== pokemon.template.types[1]) { @@ -57,8 +57,8 @@ let BattleScripts = { return true; }, getMixedTemplate(originalSpecies, megaSpecies) { - let originalTemplate = this.getTemplate(originalSpecies); - let megaTemplate = this.getTemplate(megaSpecies); + let originalTemplate = this.dex.getTemplate(originalSpecies); + let megaTemplate = this.dex.getTemplate(megaSpecies); if (originalTemplate.baseSpecies === megaTemplate.baseSpecies) return megaTemplate; // @ts-ignore let deltas = this.getMegaDeltas(megaTemplate); @@ -67,7 +67,7 @@ let BattleScripts = { return template; }, getMegaDeltas(megaTemplate) { - let baseTemplate = this.getTemplate(megaTemplate.baseSpecies); + let baseTemplate = this.dex.getTemplate(megaTemplate.baseSpecies); /**@type {{ability: string, baseStats: {[k: string]: number}, weighthg: number, originalMega: string, requiredItem: string | undefined, type?: string, isMega?: boolean, isPrimal?: boolean}} */ let deltas = { ability: megaTemplate.abilities['0'], @@ -93,7 +93,7 @@ let BattleScripts = { }, doGetMixedTemplate(templateOrTemplateName, deltas) { if (!deltas) throw new TypeError("Must specify deltas!"); - let template = this.deepClone(this.getTemplate(templateOrTemplateName)); + let template = this.dex.deepClone(this.dex.getTemplate(templateOrTemplateName)); template.abilities = {'0': deltas.ability}; if (template.types[0] === deltas.type) { template.types = [deltas.type]; @@ -102,7 +102,7 @@ let BattleScripts = { } let baseStats = template.baseStats; for (let statName in baseStats) { - baseStats[statName] = this.clampIntRange(baseStats[statName] + deltas.baseStats[statName], 1, 255); + baseStats[statName] = this.dex.clampIntRange(baseStats[statName] + deltas.baseStats[statName], 1, 255); } template.weighthg = Math.max(1, template.weighthg + deltas.weighthg); template.originalMega = deltas.originalMega; diff --git a/data/mods/pic/moves.js b/data/mods/pic/moves.js index d6c728e8d1..3f4c44e6dc 100644 --- a/data/mods/pic/moves.js +++ b/data/mods/pic/moves.js @@ -5,8 +5,8 @@ exports.BattleMovedex = { "skillswap": { inherit: true, onHit(target, source, move) { - let targetAbility = this.getAbility(target.ability); - let sourceAbility = this.getAbility(source.ability); + let targetAbility = this.dex.getAbility(target.ability); + let sourceAbility = this.dex.getAbility(source.ability); if (target.side === source.side) { this.add('-activate', source, 'move: Skill Swap', '', '', '[of] ' + target); } else { diff --git a/data/mods/pic/scripts.js b/data/mods/pic/scripts.js index 8f8977d04e..d0301e484e 100644 --- a/data/mods/pic/scripts.js +++ b/data/mods/pic/scripts.js @@ -7,19 +7,19 @@ exports.BattleScripts = { return name; } let id = toID(name); - if (id.startsWith('ability') && !['abilitypowerofalchemy', 'abilityreceiver', 'abilitytrace'].includes(id)) return Object.assign(Object.create(this.getAbility(id.slice(7))), {id}); + if (id.startsWith('ability') && !['abilitypowerofalchemy', 'abilityreceiver', 'abilitytrace'].includes(id)) return Object.assign(Object.create(this.dex.getAbility(id.slice(7))), {id}); return Object.getPrototypeOf(this).getEffect.call(this, name); }, pokemon: { setAbility(ability, source, isFromFormechange) { if (!this.hp) return false; - ability = this.battle.getAbility(ability); + ability = this.battle.dex.getAbility(ability); let oldAbility = this.ability; if (!isFromFormechange) { if (['illusion', 'battlebond', 'comatose', 'disguise', 'multitype', 'powerconstruct', 'rkssystem', 'schooling', 'shieldsdown', 'stancechange'].includes(ability.id)) return false; if (['battlebond', 'comatose', 'disguise', 'multitype', 'powerconstruct', 'rkssystem', 'schooling', 'shieldsdown', 'stancechange'].includes(oldAbility)) return false; } - this.battle.singleEvent('End', this.battle.getAbility(oldAbility), this.abilityData, this, source); + this.battle.singleEvent('End', this.battle.dex.getAbility(oldAbility), this.abilityData, this, source); let ally = this.side.active.find(ally => ally && ally !== this && !ally.fainted); if (ally && ally.m.innate) { ally.removeVolatile(ally.m.innate); diff --git a/data/mods/ssb/abilities.js b/data/mods/ssb/abilities.js index c0dff65dac..147dc2dfde 100644 --- a/data/mods/ssb/abilities.js +++ b/data/mods/ssb/abilities.js @@ -55,20 +55,20 @@ let BattleAbilities = { if (target === source || move.hasBounced || !move.flags['reflectable']) { return; } - let newMove = this.getActiveMove(move.id); + let newMove = this.dex.getActiveMove(move.id); newMove.hasBounced = true; newMove.pranksterBoosted = false; - this.useMove(newMove, target, source, this.getAbility('magicbounce')); + this.useMove(newMove, target, source, this.dex.getAbility('magicbounce')); return null; }, onAllyTryHitSide(target, source, move) { if (target.side === source.side || move.hasBounced || !move.flags['reflectable']) { return; } - let newMove = this.getActiveMove(move.id); + let newMove = this.dex.getActiveMove(move.id); newMove.hasBounced = true; newMove.pranksterBoosted = false; - this.useMove(newMove, this.effectData.target, source, this.getAbility('magicbounce')); + this.useMove(newMove, this.effectData.target, source, this.dex.getAbility('magicbounce')); return null; }, onDamagePriority: -100, @@ -188,7 +188,7 @@ let BattleAbilities = { if (target === source || move.hasBounced || !move.flags['reflectable']) { return; } - let newMove = this.getActiveMove(move.id); + let newMove = this.dex.getActiveMove(move.id); newMove.hasBounced = true; newMove.pranksterBoosted = false; this.useMove(newMove, target, source); @@ -198,7 +198,7 @@ let BattleAbilities = { if (target.side === source.side || move.hasBounced || !move.flags['reflectable']) { return; } - let newMove = this.getActiveMove(move.id); + let newMove = this.dex.getActiveMove(move.id); newMove.hasBounced = true; newMove.pranksterBoosted = false; this.useMove(newMove, this.effectData.target, source); @@ -231,7 +231,7 @@ let BattleAbilities = { name: "Logia", isNonstandard: "Custom", onTryHit(target, source, move) { - let plateType = this.getItem(target.item).onPlate; + let plateType = this.dex.getItem(target.item).onPlate; if (target !== source && (move.type === 'Normal' || plateType === move.type)) { this.add('-immune', target, '[from] ability: Logia'); return null; @@ -250,7 +250,7 @@ let BattleAbilities = { if (formes.includes(toID(source.template.species))) { formes.splice(formes.indexOf(toID(source.template.species)), 1); this.add('-activate', source, 'ability: Arabesque'); - source.formeChange(formes[this.random(formes.length)], this.getAbility('arabesque'), true); + source.formeChange(formes[this.random(formes.length)], this.dex.getAbility('arabesque'), true); } }, }, @@ -271,7 +271,7 @@ let BattleAbilities = { onEffectiveness(typeMod, target, type, move) { if (!target) return; if (target.template.baseSpecies !== 'Shaymin' || target.transformed) return; - return this.getEffectiveness(move.type, 'Grass'); + return this.dex.getEffectiveness(move.type, 'Grass'); }, onAfterDamage(damage, target, source, effect) { if (source === target) return; @@ -433,8 +433,8 @@ let BattleAbilities = { }, onAfterDamage(damage, target, source, effect) { // Illusion that only breaks when hit with a move that is super effective VS dark - if (target.illusion && effect && effect.effectType === 'Move' && effect.id !== 'confused' && this.getEffectiveness(effect.type, target.getTypes()) > 0) { - this.singleEvent('End', this.getAbility('Illusion'), target.abilityData, target, source, effect); + if (target.illusion && effect && effect.effectType === 'Move' && effect.id !== 'confused' && this.dex.getEffectiveness(effect.type, target.getTypes()) > 0) { + this.singleEvent('End', this.dex.getAbility('Illusion'), target.abilityData, target, source, effect); } }, onEnd(pokemon) { @@ -446,12 +446,12 @@ let BattleAbilities = { this.add('replace', pokemon, details); this.add('-end', pokemon, 'Illusion'); // Handle hippopotas - if (this.getTemplate(disguisedAs).exists) disguisedAs += 'user'; + if (this.dex.getTemplate(disguisedAs).exists) disguisedAs += 'user'; if (pokemon.volatiles[disguisedAs]) { pokemon.removeVolatile(disguisedAs); } if (!pokemon.volatiles[toID(pokemon.name)]) { - let status = this.getEffect(toID(pokemon.name)); + let status = this.dex.getEffect(toID(pokemon.name)); if (status && status.exists) { pokemon.addVolatile(toID(pokemon.name), pokemon); } @@ -725,7 +725,7 @@ let BattleAbilities = { pokemon.moveSlots = []; for (let i = 0; i < set.length; i++) { let newMove = set[i]; - let moveTemplate = this.getMove(newMove); + let moveTemplate = this.dex.getMove(newMove); pokemon.moveSlots.push({ move: moveTemplate.name, id: moveTemplate.id, @@ -1185,7 +1185,7 @@ let BattleAbilities = { name: "Snow Storm", isNonstandard: "Custom", onStart() { - let snowStorm = this.getEffect('hail'); + let snowStorm = this.dex.getEffect('hail'); this.field.setWeather(snowStorm); }, }, @@ -1201,12 +1201,12 @@ let BattleAbilities = { this.add('replace', pokemon, details); this.add('-end', pokemon, 'Illusion'); // Handle hippopotas - if (this.getTemplate(disguisedAs).exists) disguisedAs += 'user'; + if (this.dex.getTemplate(disguisedAs).exists) disguisedAs += 'user'; if (pokemon.volatiles[disguisedAs]) { pokemon.removeVolatile(disguisedAs); } if (!pokemon.volatiles[toID(pokemon.name)]) { - let status = this.getEffect(toID(pokemon.name)); + let status = this.dex.getEffect(toID(pokemon.name)); if (status && status.exists) { pokemon.addVolatile(toID(pokemon.name), pokemon); } diff --git a/data/mods/ssb/moves.js b/data/mods/ssb/moves.js index 6ccf640b46..d646d012e4 100644 --- a/data/mods/ssb/moves.js +++ b/data/mods/ssb/moves.js @@ -59,7 +59,7 @@ let BattleMovedex = { this.add('-anim', source, 'Boomburst', source); }, onHit(target, source, move) { - this.boost({atk: 2}, source, source, this.getActiveMove('Noble Howl')); + this.boost({atk: 2}, source, source, this.dex.getActiveMove('Noble Howl')); if (!(['', 'slp', 'frz'].includes(source.status))) { source.cureStatus(); } @@ -68,12 +68,12 @@ let BattleMovedex = { for (const targetCondition of removeTarget) { if (target.side.removeSideCondition(targetCondition)) { if (!removeAll.includes(targetCondition)) continue; - this.add('-sideend', target.side, this.getEffect(targetCondition).name, '[from] move: Noble Howl', '[of] ' + target); + this.add('-sideend', target.side, this.dex.getEffect(targetCondition).name, '[from] move: Noble Howl', '[of] ' + target); } } for (const sideCondition of removeAll) { if (source.side.removeSideCondition(sideCondition)) { - this.add('-sideend', source.side, this.getEffect(sideCondition).name, '[from] move: Noble Howl', '[of] ' + source); + this.add('-sideend', source.side, this.dex.getEffect(sideCondition).name, '[from] move: Noble Howl', '[of] ' + source); } } }, @@ -201,7 +201,7 @@ let BattleMovedex = { onAfterMoveSecondarySelf(pokemon) { pokemon.clearBoosts(); this.add('-clearboost', pokemon); - this.boost({atk: -1, def: -1, spe: -1}, pokemon, pokemon, this.getActiveMove('Cataclysm')); + this.boost({atk: -1, def: -1, spe: -1}, pokemon, pokemon, this.dex.getActiveMove('Cataclysm')); }, secondary: null, target: "normal", @@ -232,10 +232,10 @@ let BattleMovedex = { let silentRemove = ['reflect', 'lightscreen', 'auroraveil', 'safeguard', 'mist']; for (const sideCondition of removeAll) { if (target.side.removeSideCondition(sideCondition)) { - if (!(silentRemove.includes(sideCondition))) this.add('-sideend', target.side, this.getEffect(sideCondition).name, '[from] move: Quick Reload', '[of] ' + source); + if (!(silentRemove.includes(sideCondition))) this.add('-sideend', target.side, this.dex.getEffect(sideCondition).name, '[from] move: Quick Reload', '[of] ' + source); } if (source.side.removeSideCondition(sideCondition)) { - if (!(silentRemove.includes(sideCondition))) this.add('-sideend', source.side, this.getEffect(sideCondition).name, '[from] move: Quick Reload', '[of] ' + source); + if (!(silentRemove.includes(sideCondition))) this.add('-sideend', source.side, this.dex.getEffect(sideCondition).name, '[from] move: Quick Reload', '[of] ' + source); } } }, @@ -526,7 +526,7 @@ let BattleMovedex = { this.add('replace', target, pokemon.getDetails, target.hp / target.maxhp); // name change target.setAbility(set.ability); - const format = this.getFormat(); + const format = this.format; if (format && format.onSwitchIn) format.onSwitchIn.call(this, target); this.add('-message', `${oldName} was sent to the Distortion World and replaced with somebody else!`); for (let stat of Object.keys(target.boosts)) { @@ -1009,10 +1009,10 @@ let BattleMovedex = { let silentRemove = ['reflect', 'lightscreen', 'auroraveil', 'safeguard', 'mist']; for (const sideCondition of removeAll) { if (target.side.removeSideCondition(sideCondition)) { - if (!(silentRemove.includes(sideCondition))) this.add('-sideend', target.side, this.getEffect(sideCondition).name, '[from] move: Blustery Winds', '[of] ' + source); + if (!(silentRemove.includes(sideCondition))) this.add('-sideend', target.side, this.dex.getEffect(sideCondition).name, '[from] move: Blustery Winds', '[of] ' + source); } if (source.side.removeSideCondition(sideCondition)) { - if (!(silentRemove.includes(sideCondition))) this.add('-sideend', source.side, this.getEffect(sideCondition).name, '[from] move: Blustery Winds', '[of] ' + source); + if (!(silentRemove.includes(sideCondition))) this.add('-sideend', source.side, this.dex.getEffect(sideCondition).name, '[from] move: Blustery Winds', '[of] ' + source); } } this.field.clearWeather(); @@ -1131,13 +1131,13 @@ let BattleMovedex = { for (const targetCondition of removeTarget) { if (target.side.removeSideCondition(targetCondition)) { if (!removeAll.includes(targetCondition)) continue; - this.add('-sideend', target.side, this.getEffect(targetCondition).name, '[from] move: Defog', '[of] ' + source); + this.add('-sideend', target.side, this.dex.getEffect(targetCondition).name, '[from] move: Defog', '[of] ' + source); success = true; } } for (const sideCondition of removeAll) { if (source.side.removeSideCondition(sideCondition)) { - this.add('-sideend', source.side, this.getEffect(sideCondition).name, '[from] move: Defog', '[of] ' + source); + this.add('-sideend', source.side, this.dex.getEffect(sideCondition).name, '[from] move: Defog', '[of] ' + source); success = true; } } @@ -1310,9 +1310,9 @@ let BattleMovedex = { this.add('-anim', target, 'Nasty Plot', target); }, onHit(target, source, move) { - this.heal(source.maxhp / 4, source, source, this.getActiveMove('Super Ego Inflation')); - this.boost({atk: 2, spa: 2}, target, source, this.getActiveMove('Super Ego Inflation')); - target.addVolatile('taunt', source, this.getActiveMove('Super Ego Inflation')); + this.heal(source.maxhp / 4, source, source, this.dex.getActiveMove('Super Ego Inflation')); + this.boost({atk: 2, spa: 2}, target, source, this.dex.getActiveMove('Super Ego Inflation')); + target.addVolatile('taunt', source, this.dex.getActiveMove('Super Ego Inflation')); }, secondary: null, target: "normal", @@ -1398,7 +1398,7 @@ let BattleMovedex = { }, onHit(pokemon, move) { if (this.field.pseudoWeather.gravity) return false; - this.boost({atk: 2}, pokemon, pokemon, this.getActiveMove('EarthsBlessing')); + this.boost({atk: 2}, pokemon, pokemon, this.dex.getActiveMove('EarthsBlessing')); this.field.addPseudoWeather('gravity'); if (['', 'slp', 'frz'].includes(pokemon.status)) return; pokemon.cureStatus(); @@ -1470,12 +1470,12 @@ let BattleMovedex = { victini: ['V-create', 'Blue Flare'], }; let forme = Object.keys(formes)[this.random(5)]; - source.formeChange(forme, this.getAbility('psychicsurge'), true); + source.formeChange(forme, this.dex.getAbility('psychicsurge'), true); this.boost({atk: 1, spa: 1}, source, source, move); this.useMove(formes[forme][0], source, target); this.useMove(formes[forme][1], source, target); this.boost({atk: -1, spa: -1}, source, source, move); - source.formeChange(baseForme, this.getAbility('psychicsurge'), true); + source.formeChange(baseForme, this.dex.getAbility('psychicsurge'), true); }, secondary: null, target: "normal", @@ -1956,7 +1956,7 @@ let BattleMovedex = { // Pick a random hazard, and set it let hazard1 = this.sample(hazardTypes); // Theoretically, this should always work - this.add('-anim', source, this.getMove(hazard1).name, target); + this.add('-anim', source, this.dex.getMove(hazard1).name, target); target.addSideCondition(hazard1, source, this.effect); // If that was the last possible layer of that hazard, remove it from our list of possible hazards if (hazards[hazard1] === 1) { @@ -1966,7 +1966,7 @@ let BattleMovedex = { } // Set the last hazard and animate the switch let hazard2 = this.sample(hazardTypes); - this.add('-anim', source, this.getMove(hazard2).name, target); + this.add('-anim', source, this.dex.getMove(hazard2).name, target); target.addSideCondition(hazard2, source, this.effect); this.add('-anim', source, "Baton Pass", target); }, @@ -2041,23 +2041,23 @@ let BattleMovedex = { this.add('message', `${pokemon.name} was corrupted by a bug in the Scripted Terrain!`); // generate a movepool let moves = []; - let pool = this.shuffle(Object.keys(this.data.Movedex)); - let metronome = this.getMove('metronome'); + let pool = this.dex.shuffle(Object.keys(this.dex.data.Movedex)); + let metronome = this.dex.getMove('metronome'); for (let i of pool) { - let move = this.getMove(i); + let move = this.dex.getMove(i); if (i !== move.id) continue; if (move.isZ || move.isNonstandard) continue; if (metronome.noMetronome && metronome.noMetronome.includes(move.id)) continue; - if (this.getMove(i).gen > this.gen) continue; + if (this.dex.getMove(i).gen > this.gen) continue; moves.push(move); if (moves.length >= 3) break; } moves.push('glitchout'); - if (toID(pokemon.ability).includes('illusion') && pokemon.illusion) this.singleEvent('End', this.getAbility('Illusion'), pokemon.abilityData, pokemon, pokemon); + if (toID(pokemon.ability).includes('illusion') && pokemon.illusion) this.singleEvent('End', this.dex.getAbility('Illusion'), pokemon.abilityData, pokemon, pokemon); pokemon.formeChange('missingno'); pokemon.moveSlots = []; for (let moveid of moves) { - let move = this.getMove(moveid); + let move = this.dex.getMove(moveid); if (!move.id) continue; pokemon.moveSlots.push({ move: move.name, @@ -2105,12 +2105,12 @@ let BattleMovedex = { }, onHit(target, source, effect) { let moves = []; - for (let i in this.data.Movedex) { - let move = this.data.Movedex[i]; + for (let i in this.dex.data.Movedex) { + let move = this.dex.data.Movedex[i]; if (i !== move.id) continue; if (move.isZ || move.isNonstandard) continue; if (effect.noMetronome && effect.noMetronome.includes(move.id)) continue; - if (this.getMove(i).gen > this.gen) continue; + if (this.dex.getMove(i).gen > this.gen) continue; moves.push(move); } let randomMove = ''; @@ -2810,7 +2810,7 @@ let BattleMovedex = { }, onPrepareHit(target, source) { this.add('-anim', source, "Recover", source); - this.heal(source.maxhp, source, source, this.getActiveMove('Blaze of Glory')); + this.heal(source.maxhp, source, source, this.dex.getActiveMove('Blaze of Glory')); this.add('-anim', source, "Final Gambit", target); }, selfdestruct: "ifHit", @@ -2925,9 +2925,9 @@ let BattleMovedex = { } } let weaknesses = []; - for (let type in this.data.TypeChart) { - let typeMod = this.getEffectiveness(type, targetTypes); - if (typeMod > 0 && this.getImmunity(type, target)) weaknesses.push(type); + for (let type in this.dex.data.TypeChart) { + let typeMod = this.dex.getEffectiveness(type, targetTypes); + if (typeMod > 0 && this.dex.getImmunity(type, target)) weaknesses.push(type); } if (!weaknesses.length) { return false; @@ -2935,9 +2935,9 @@ let BattleMovedex = { let randomType = this.sample(weaknesses); source.setItem(randomType + 'memory'); this.add('-item', source, source.getItem(), '[from] move: Type Analysis'); - let template = this.getTemplate('Silvally-' + randomType); - source.formeChange(template, this.getAbility('rkssystem'), true); - let move = this.getActiveMove('multiattack'); + let template = this.dex.getTemplate('Silvally-' + randomType); + source.formeChange(template, this.dex.getAbility('rkssystem'), true); + let move = this.dex.getActiveMove('multiattack'); move.basePower = 80; this.useMove(move, source, target); }, @@ -2967,7 +2967,7 @@ let BattleMovedex = { this.add('-anim', source, "Miracle Eye", target); }, onHit(target, source) { - this.boost({atk: -2, spa: -2}, source, source, this.getActiveMove('/scavenges u')); + this.boost({atk: -2, spa: -2}, source, source, this.dex.getActiveMove('/scavenges u')); let targetBoosts = {}; let sourceBoosts = {}; @@ -3125,10 +3125,10 @@ let BattleMovedex = { let removeAll = ['reflect', 'lightscreen', 'auroraveil', 'safeguard', 'mist', 'spikes', 'toxicspikes', 'stealthrock', 'stickyweb']; for (const sideCondition of removeAll) { if (source.side.foe.removeSideCondition(sideCondition)) { - this.add('-sideend', source.side.foe, this.getEffect(sideCondition).name, '[from] move: Prismatic Terrain', '[of] ' + source); + this.add('-sideend', source.side.foe, this.dex.getEffect(sideCondition).name, '[from] move: Prismatic Terrain', '[of] ' + source); } if (source.side.removeSideCondition(sideCondition)) { - this.add('-sideend', source.side, this.getEffect(sideCondition).name, '[from] move: Prismatic Terrain', '[of] ' + source); + this.add('-sideend', source.side, this.dex.getEffect(sideCondition).name, '[from] move: Prismatic Terrain', '[of] ' + source); } } }, @@ -3174,7 +3174,7 @@ let BattleMovedex = { effect: { duration: 1, onSwitchIn(pokemon) { - this.boost({spe: -1}, pokemon, pokemon.side.foe.active[0], this.getActiveMove('pyramidingsong')); + this.boost({spe: -1}, pokemon, pokemon.side.foe.active[0], this.dex.getActiveMove('pyramidingsong')); }, }, forceSwitch: true, @@ -4049,7 +4049,7 @@ let BattleMovedex = { this.attrLastMove('[still]'); }, onPrepareHit(target, source, move) { - let zmove = this.getMove(this.zMoveTable[move.type]); + let zmove = this.dex.getMove(this.zMoveTable[move.type]); this.add('-anim', source, zmove.name, target); this.add('-anim', source, "Transform", source); }, @@ -4076,7 +4076,7 @@ let BattleMovedex = { // Tranform into it pokemon.formeChange(set.species); for (let newMove of set.moves) { - let moveTemplate = this.getMove(newMove); + let moveTemplate = this.dex.getMove(newMove); if (pokemon.moves.includes(moveTemplate.id)) continue; pokemon.moveSlots.push({ move: moveTemplate.name, @@ -4423,7 +4423,7 @@ let BattleMovedex = { for (let i in sideConditions) { let layers = source.side.sideConditions[i] ? (source.side.sideConditions[i].layers || 1) : 1; if (source.side.removeSideCondition(i)) { - this.add('-sideend', source.side, this.getEffect(i).name, '[from] move: Smoke Bomb', '[of] ' + source); + this.add('-sideend', source.side, this.dex.getEffect(i).name, '[from] move: Smoke Bomb', '[of] ' + source); for (layers; layers > 0; layers--) target.side.addSideCondition(i, source); } } @@ -4861,7 +4861,7 @@ let BattleMovedex = { 'assist', 'beakblast', 'belch', 'bide', 'celebrate', 'chatter', 'copycat', 'focuspunch', 'mefirst', 'metronome', 'mimic', 'mirrormove', 'naturepower', 'shelltrap', 'sketch', 'sleeptalk', 'uproar', 'teabreak', 'glitzerpopping', // Modded banlist ]; - if (move && !(noSleepTalk.includes(move) || this.getMove(move).flags['charge'] || (this.getMove(move).isZ && this.getMove(move).basePower !== 1))) { + if (move && !(noSleepTalk.includes(move) || this.dex.getMove(move).flags['charge'] || (this.dex.getMove(move).isZ && this.dex.getMove(move).basePower !== 1))) { moves.push(move); } } diff --git a/data/mods/ssb/random-teams.js b/data/mods/ssb/random-teams.js index 83c94f89ca..d88d8668e8 100644 --- a/data/mods/ssb/random-teams.js +++ b/data/mods/ssb/random-teams.js @@ -789,7 +789,7 @@ class RandomStaffBrosTeams extends RandomTeams { if (!this.allXfix) { // Enforce typing limits - let types = this.getTemplate(ssbSet.species).types; + let types = this.dex.getTemplate(ssbSet.species).types; let rejected = false; for (let type of types) { if (typePool[type] === undefined) typePool[type] = 0; @@ -842,8 +842,8 @@ class RandomStaffBrosTeams extends RandomTeams { set.moves.push(move); } set.moves.push(ssbSet.signatureMove); - if (name === 'Arsenal' && this.getItem(set.item).onPlate) { - set.species = 'Arceus-' + this.getItem(set.item).onPlate; + if (name === 'Arsenal' && this.dex.getItem(set.item).onPlate) { + set.species = 'Arceus-' + this.dex.getItem(set.item).onPlate; } if (name === 'Gallant Spear' && set.item === 'Choice Band') set.moves[set.moves.indexOf('Recover')] = 'Aqua Tail'; if (name === 'The Immortal' && set.item === 'Choice Scarf') set.moves[3] = 'Superpower'; diff --git a/data/mods/ssb/scripts.js b/data/mods/ssb/scripts.js index a1e8a8f189..2b1c350e01 100644 --- a/data/mods/ssb/scripts.js +++ b/data/mods/ssb/scripts.js @@ -4,12 +4,12 @@ let BattleScripts = { runMove(moveOrMoveName, pokemon, targetLoc, sourceEffect, zMove, externalMove) { let target = this.getTarget(pokemon, zMove || moveOrMoveName, targetLoc); - let baseMove = this.getActiveMove(moveOrMoveName); + let baseMove = this.dex.getActiveMove(moveOrMoveName); const pranksterBoosted = baseMove.pranksterBoosted; if (!sourceEffect && baseMove.id !== 'struggle' && !zMove) { let changedMove = this.runEvent('OverrideAction', pokemon, target, baseMove); if (changedMove && changedMove !== true) { - baseMove = this.getActiveMove(changedMove); + baseMove = this.dex.getActiveMove(changedMove); if (pranksterBoosted) baseMove.pranksterBoosted = pranksterBoosted; target = this.resolveTarget(pokemon, baseMove); } @@ -60,7 +60,7 @@ let BattleScripts = { return; } } else { - sourceEffect = this.getEffect('lockedmove'); + sourceEffect = this.dex.getEffect('lockedmove'); } pokemon.moveUsed(move, targetLoc); } @@ -71,7 +71,7 @@ let BattleScripts = { if (zMove) { if (pokemon.illusion) { - this.singleEvent('End', this.getAbility('Illusion'), pokemon.abilityData, pokemon); + this.singleEvent('End', this.dex.getAbility('Illusion'), pokemon.abilityData, pokemon); } this.add('-zpower', pokemon); pokemon.m.zMoveUsed = true; @@ -100,7 +100,7 @@ let BattleScripts = { for (const dancer of dancers) { if (this.faintMessages()) break; this.add('-activate', dancer, 'ability: Dancer'); - this.runMove(move.id, dancer, 0, this.getAbility('dancer'), undefined, true); + this.runMove(move.id, dancer, 0, this.dex.getAbility('dancer'), undefined, true); // Using a Dancer move is enough to spoil Fake Out etc. dancer.activeTurns++; } @@ -109,7 +109,7 @@ let BattleScripts = { }, // Modded to allow arrays as Mega Stone options canMegaEvo(pokemon) { - let altForme = pokemon.baseTemplate.otherFormes && this.getTemplate(pokemon.baseTemplate.otherFormes[0]); + let altForme = pokemon.baseTemplate.otherFormes && this.dex.getTemplate(pokemon.baseTemplate.otherFormes[0]); let item = pokemon.getItem(); if (altForme && altForme.isMega && altForme.requiredMove && pokemon.baseMoves.includes(toID(altForme.requiredMove)) && !item.zMove) return altForme.species; if (item.megaEvolves !== pokemon.baseTemplate.species || (Array.isArray(item.megaStone) && item.megaStone.includes(pokemon.species)) || (typeof item.megaStone === 'string' && item.megaStone === pokemon.species)) { @@ -178,7 +178,7 @@ let BattleScripts = { let item = pokemon.getItem(); if (item.zMoveFrom && Array.isArray(item.zMoveFrom) ? item.zMoveFrom.includes(move.name) : item.zMoveFrom === move.name) { // @ts-ignore - zMove = this.getActiveMove(item.zMove); + zMove = this.dex.getActiveMove(item.zMove); // @ts-ignore Hack for Snaquaza's Z move zMove.baseMove = move; zMove.isZPowered = true; @@ -187,12 +187,12 @@ let BattleScripts = { } if (move.category === 'Status') { - zMove = this.getActiveMove(move); + zMove = this.dex.getActiveMove(move); zMove.isZ = true; zMove.isZPowered = true; return zMove; } - zMove = this.getActiveMove(this.zMoveTable[move.type]); + zMove = this.dex.getActiveMove(this.zMoveTable[move.type]); // @ts-ignore zMove.basePower = move.zMovePower; zMove.category = move.category; @@ -213,10 +213,10 @@ let BattleScripts = { zMoves.push(null); continue; } - let move = this.getMove(moveSlot.move); + let move = this.dex.getMove(moveSlot.move); let zMoveName = this.getZMove(move, pokemon, true) || ''; if (zMoveName) { - let zMove = this.getMove(zMoveName); + let zMove = this.dex.getMove(zMoveName); if (!zMove.isZ && zMove.category === 'Status') zMoveName = "Z-" + zMoveName; zMoves.push({move: zMoveName, target: zMove.target}); } else { @@ -227,7 +227,7 @@ let BattleScripts = { if (atLeastOne) return zMoves; }, runZPower(move, pokemon) { - const zPower = this.getEffect('zpower'); + const zPower = this.dex.getEffect('zpower'); if (move.category !== 'Status') { this.attrLastMove('[zeffect]'); } else if (move.zMoveBoost) { @@ -312,7 +312,7 @@ let BattleScripts = { } // types let typeMod = target.runEffectiveness(move); - typeMod = this.clampIntRange(typeMod, -6, 6); + typeMod = this.dex.clampIntRange(typeMod, -6, 6); target.getMoveHitData(move).typeMod = typeMod; if (typeMod > 0) { if (!suppressMessages) this.add('-supereffective', target); @@ -382,7 +382,7 @@ let BattleScripts = { }, setStatus(status, source = null, sourceEffect = null, ignoreImmunities = false) { if (!this.hp) return false; - status = this.battle.getEffect(status); + status = this.battle.dex.getEffect(status); if (this.battle.event) { if (!source) source = this.battle.event.source; if (!sourceEffect) sourceEffect = this.battle.effect; diff --git a/data/mods/ssb/statuses.js b/data/mods/ssb/statuses.js index 7c6e45907e..4b9a2990cf 100644 --- a/data/mods/ssb/statuses.js +++ b/data/mods/ssb/statuses.js @@ -897,9 +897,9 @@ let BattleStatuses = { for (const target of pokemon.side.foe.active) { if (!target || target.fainted) continue; for (const moveSlot of target.moveSlots) { - const move = this.getMove(moveSlot.move); + const move = this.dex.getMove(moveSlot.move); const moveType = move.id === 'hiddenpower' ? target.hpType : move.type; - if (move.category !== 'Status' && (this.getImmunity(moveType, pokemon) && this.getEffectiveness(moveType, pokemon) > 0 || move.ohko)) { + if (move.category !== 'Status' && (this.dex.getImmunity(moveType, pokemon) && this.dex.getEffectiveness(moveType, pokemon) > 0 || move.ohko)) { this.add('-ability', pokemon, 'Anticipation'); return; } @@ -1472,10 +1472,10 @@ let BattleStatuses = { let silentRemove = ['reflect', 'lightscreen', 'auroraveil', 'safeguard', 'mist']; for (const sideCondition of removeAll) { if (target.side.removeSideCondition(sideCondition)) { - if (!(silentRemove.includes(sideCondition))) this.add('-sideend', target.side, this.getEffect(sideCondition).name, '[from] move: No Fun Zone', '[of] ' + source); + if (!(silentRemove.includes(sideCondition))) this.add('-sideend', target.side, this.dex.getEffect(sideCondition).name, '[from] move: No Fun Zone', '[of] ' + source); } if (source.side.removeSideCondition(sideCondition)) { - if (!(silentRemove.includes(sideCondition))) this.add('-sideend', source.side, this.getEffect(sideCondition).name, '[from] move: No Fun Zone', '[of] ' + source); + if (!(silentRemove.includes(sideCondition))) this.add('-sideend', source.side, this.dex.getEffect(sideCondition).name, '[from] move: No Fun Zone', '[of] ' + source); } } this.add('-clearallboost'); @@ -2052,7 +2052,7 @@ let BattleStatuses = { this.add('-sidestart', side, 'move: Stealth Rock'); }, onSwitchIn(pokemon) { - let typeMod = this.clampIntRange(pokemon.runEffectiveness(this.getActiveMove('stealthrock')), -6, 6); + let typeMod = this.dex.clampIntRange(pokemon.runEffectiveness(this.dex.getActiveMove('stealthrock')), -6, 6); this.damage(pokemon.maxhp * Math.pow(2, typeMod) / 8); }, }, @@ -2067,7 +2067,7 @@ let BattleStatuses = { onSwitchIn(pokemon) { if (!pokemon.isGrounded()) return; this.add('-activate', pokemon, 'move: Sticky Web'); - this.boost({spe: -1}, pokemon, pokemon.side.foe.active[0], this.getActiveMove('stickyweb')); + this.boost({spe: -1}, pokemon, pokemon.side.foe.active[0], this.dex.getActiveMove('stickyweb')); }, }, toxicspikes: { diff --git a/data/mods/stadium/moves.js b/data/mods/stadium/moves.js index 5c51cf903f..7ae941288a 100644 --- a/data/mods/stadium/moves.js +++ b/data/mods/stadium/moves.js @@ -46,7 +46,7 @@ let BattleMovedex = { this.debug('Nothing to leech into'); return; } - let toLeech = this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1); + let toLeech = this.dex.clampIntRange(Math.floor(pokemon.maxhp / 16), 1); let damage = this.damage(toLeech, pokemon, leecher); if (damage) this.heal(damage, leecher, pokemon); }, diff --git a/data/mods/stadium/scripts.js b/data/mods/stadium/scripts.js index 67fae8b631..4be595c102 100644 --- a/data/mods/stadium/scripts.js +++ b/data/mods/stadium/scripts.js @@ -15,7 +15,7 @@ let BattleScripts = { modifyStat(statName, modifier) { if (!(statName in this.storedStats)) throw new Error("Invalid `statName` passed to `modifyStat`"); // @ts-ignore - this.modifiedStats[statName] = this.battle.clampIntRange(Math.floor(this.modifiedStats[statName] * modifier), 1); + this.modifiedStats[statName] = this.battle.dex.clampIntRange(Math.floor(this.modifiedStats[statName] * modifier), 1); }, // This is run on Stadium after boosts and status changes. recalculateStats() { @@ -79,7 +79,7 @@ let BattleScripts = { }, // Battle scripts. runMove(moveOrMoveName, pokemon, targetLoc, sourceEffect) { - let move = this.getActiveMove(moveOrMoveName); + let move = this.dex.getActiveMove(moveOrMoveName); let target = this.getTarget(pokemon, move, targetLoc); if (target && target.subFainted) target.subFainted = null; @@ -264,7 +264,7 @@ let BattleScripts = { moveHit(target, pokemon, moveOrMoveName, moveData, isSecondary, isSelf) { /** @type {number | null | false | undefined} */ let damage = 0; - let move = this.getActiveMove(moveOrMoveName); + let move = this.dex.getActiveMove(moveOrMoveName); if (!isSecondary && !isSelf) this.setActiveMove(move, pokemon, target); /** @type {number | boolean} */ @@ -424,7 +424,7 @@ let BattleScripts = { getDamage(pokemon, target, move, suppressMessages) { // First of all, we get the move. if (typeof move === 'string') { - move = this.getActiveMove(move); + move = this.dex.getActiveMove(move); } else if (typeof move === 'number') { move = /** @type {ActiveMove} */ ({ basePower: move, @@ -488,7 +488,7 @@ let BattleScripts = { if (!basePower) { return basePower === 0 ? undefined : basePower; } - basePower = this.clampIntRange(basePower, 1); + basePower = this.dex.clampIntRange(basePower, 1); // Checking for the move's Critical Hit possibility. We check if it's a 100% crit move, otherwise we calculate the chance. let isCrit = move.willCrit || false; @@ -521,7 +521,7 @@ let BattleScripts = { } // Now we make sure it's a number between 1 and 255. - critChance = this.clampIntRange(critChance, 1, 255); + critChance = this.dex.clampIntRange(critChance, 1, 255); // Last, we check deppending on ratio if the move critical hits or not. // We compare our critical hit chance against a random number between 0 and 255. @@ -543,7 +543,7 @@ let BattleScripts = { } } if (!basePower) return 0; - basePower = this.clampIntRange(basePower, 1); + basePower = this.dex.clampIntRange(basePower, 1); // We now check attacker's and defender's stats. let level = pokemon.level; @@ -561,7 +561,7 @@ let BattleScripts = { if ((defType === 'def' && defender.volatiles['reflect']) || (defType === 'spd' && defender.volatiles['lightscreen'])) { this.debug('Screen doubling (Sp)Def'); defense *= 2; - defense = this.clampIntRange(defense, 1, 1998); + defense = this.dex.clampIntRange(defense, 1, 1998); } // In the event of a critical hit, the offense and defense changes are ignored. @@ -585,14 +585,14 @@ let BattleScripts = { // When either attack or defense are higher than 256, they are both divided by 4 and moded by 256. // This is what cuases the roll over bugs. if (attack >= 256 || defense >= 256) { - attack = this.clampIntRange(Math.floor(attack / 4) % 256, 1); + attack = this.dex.clampIntRange(Math.floor(attack / 4) % 256, 1); // Defense isn't checked on the cartridge, but we don't want those / 0 bugs on the sim. - defense = this.clampIntRange(Math.floor(defense / 4) % 256, 1); + defense = this.dex.clampIntRange(Math.floor(defense / 4) % 256, 1); } // Self destruct moves halve defense at this point. if (move.selfdestruct && defType === 'def') { - defense = this.clampIntRange(Math.floor(defense / 2), 1); + defense = this.dex.clampIntRange(Math.floor(defense / 2), 1); } // Let's go with the calculation now that we have what we need. @@ -603,7 +603,7 @@ let BattleScripts = { damage *= basePower; damage *= attack; damage = Math.floor(damage / defense); - damage = this.clampIntRange(Math.floor(damage / 50), 1, 997); + damage = this.dex.clampIntRange(Math.floor(damage / 50), 1, 997); damage += 2; // STAB damage bonus, the "???" type never gets STAB @@ -613,7 +613,7 @@ let BattleScripts = { // Type effectiveness. // The order here is not correct, must change to check the move versus each type. - let totalTypeMod = this.getEffectiveness(type, target); + let totalTypeMod = this.dex.getEffectiveness(type, target); // Super effective attack if (totalTypeMod > 0) { if (!suppressMessages) this.add('-supereffective', target); diff --git a/data/mods/stadium/statuses.js b/data/mods/stadium/statuses.js index 6c3ecaaddf..08c0616979 100644 --- a/data/mods/stadium/statuses.js +++ b/data/mods/stadium/statuses.js @@ -12,10 +12,10 @@ let BattleStatuses = { }, onAfterMoveSelfPriority: 2, onAfterMoveSelf(pokemon) { - this.damage(this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1)); + this.damage(this.dex.clampIntRange(Math.floor(pokemon.maxhp / 16), 1)); }, onAfterSwitchInSelf(pokemon) { - this.damage(this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1)); + this.damage(this.dex.clampIntRange(Math.floor(pokemon.maxhp / 16), 1)); }, }, par: { @@ -98,10 +98,10 @@ let BattleStatuses = { }, onAfterMoveSelfPriority: 2, onAfterMoveSelf(pokemon) { - this.damage(this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1)); + this.damage(this.dex.clampIntRange(Math.floor(pokemon.maxhp / 16), 1)); }, onAfterSwitchInSelf(pokemon) { - this.damage(this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1)); + this.damage(this.dex.clampIntRange(Math.floor(pokemon.maxhp / 16), 1)); }, }, tox: { @@ -114,14 +114,14 @@ let BattleStatuses = { }, onAfterMoveSelfPriority: 2, onAfterMoveSelf(pokemon) { - this.damage(this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1)); + this.damage(this.dex.clampIntRange(Math.floor(pokemon.maxhp / 16), 1)); }, onAfterSwitchInSelf(pokemon) { // Regular poison status and damage after a switchout -> switchin. pokemon.setStatus('psn'); pokemon.addVolatile('residualdmg'); pokemon.volatiles['residualdmg'].counter = 1; - this.damage(this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1)); + this.damage(this.dex.clampIntRange(Math.floor(pokemon.maxhp / 16), 1)); }, }, partiallytrapped: { diff --git a/data/mods/vgc17/rulesets.js b/data/mods/vgc17/rulesets.js index c3e2668b01..1f2f3c692b 100644 --- a/data/mods/vgc17/rulesets.js +++ b/data/mods/vgc17/rulesets.js @@ -10,8 +10,8 @@ let BattleFormats = { let alolaDex = [ "Rowlet", "Dartrix", "Decidueye", "Litten", "Torracat", "Incineroar", "Popplio", "Brionne", "Primarina", "Pikipek", "Trumbeak", "Toucannon", "Yungoos", "Gumshoos", "Rattata-Alola", "Raticate-Alola", "Caterpie", "Metapod", "Butterfree", "Ledyba", "Ledian", "Spinarak", "Ariados", "Pichu", "Pikachu", "Raichu-Alola", "Grubbin", "Charjabug", "Vikavolt", "Bonsly", "Sudowoodo", "Happiny", "Chansey", "Blissey", "Munchlax", "Snorlax", "Slowpoke", "Slowbro", "Slowking", "Wingull", "Pelipper", "Abra", "Kadabra", "Alakazam", "Meowth-Alola", "Persian-Alola", "Magnemite", "Magneton", "Magnezone", "Grimer-Alola", "Muk-Alola", "Growlithe", "Arcanine", "Drowzee", "Hypno", "Makuhita", "Hariyama", "Smeargle", "Crabrawler", "Crabominable", "Gastly", "Haunter", "Gengar", "Drifloon", "Drifblim", "Misdreavus", "Mismagius", "Zubat", "Golbat", "Crobat", "Diglett-Alola", "Dugtrio-Alola", "Spearow", "Fearow", "Rufflet", "Braviary", "Vullaby", "Mandibuzz", "Mankey", "Primeape", "Delibird", "Oricorio", "Cutiefly", "Ribombee", "Petilil", "Lilligant", "Cottonee", "Whimsicott", "Psyduck", "Golduck", "Magikarp", "Gyarados", "Barboach", "Whiscash", "Machop", "Machoke", "Machamp", "Roggenrola", "Boldore", "Gigalith", "Carbink", "Sableye", "Rockruff", "Lycanroc", "Spinda", "Tentacool", "Tentacruel", "Finneon", "Lumineon", "Wishiwashi", "Luvdisc", "Corsola", "Mareanie", "Toxapex", "Shellder", "Cloyster", "Bagon", "Shelgon", "Salamence", "Lillipup", "Herdier", "Stoutland", "Eevee", "Vaporeon", "Jolteon", "Flareon", "Espeon", "Umbreon", "Leafeon", "Glaceon", "Sylveon", "Mudbray", "Mudsdale", "Igglybuff", "Jigglypuff", "Wigglytuff", "Tauros", "Miltank", "Surskit", "Masquerain", "Dewpider", "Araquanid", "Fomantis", "Lurantis", "Morelull", "Shiinotic", "Paras", "Parasect", "Poliwag", "Poliwhirl", "Poliwrath", "Politoed", "Goldeen", "Seaking", "Feebas", "Milotic", "Alomomola", "Fletchling", "Fletchinder", "Talonflame", "Salandit", "Salazzle", "Cubone", "Marowak-Alola", "Kangaskhan", "Magby", "Magmar", "Magmortar", "Stufful", "Bewear", "Bounsweet", "Steenee", "Tsareena", "Comfey", "Pinsir", "Oranguru", "Passimian", "Goomy", "Sliggoo", "Goodra", "Castform", "Wimpod", "Golisopod", "Staryu", "Starmie", "Sandygast", "Palossand", "Cranidos", "Rampardos", "Shieldon", "Bastiodon", "Archen", "Archeops", "Tirtouga", "Carracosta", "Phantump", "Trevenant", "Nosepass", "Probopass", "Pyukumuku", "Chinchou", "Lanturn", "Type: Null", "Silvally", "Zygarde", "Trubbish", "Garbodor", "Skarmory", "Ditto", "Cleffa", "Clefairy", "Clefable", "Minior", "Beldum", "Metang", "Metagross", "Porygon", "Porygon2", "Porygon-Z", "Pancham", "Pangoro", "Komala", "Torkoal", "Turtonator", "Togedemaru", "Elekid", "Electabuzz", "Electivire", "Geodude-Alola", "Graveler-Alola", "Golem-Alola", "Sandile", "Krokorok", "Krookodile", "Trapinch", "Vibrava", "Flygon", "Gible", "Gabite", "Garchomp", "Klefki", "Mimikyu", "Bruxish", "Drampa", "Absol", "Snorunt", "Glalie", "Froslass", "Sneasel", "Weavile", "Sandshrew-Alola", "Sandslash-Alola", "Vulpix-Alola", "Ninetales-Alola", "Vanillite", "Vanillish", "Vanilluxe", "Snubbull", "Granbull", "Shellos", "Gastrodon", "Relicanth", "Dhelmise", "Carvanha", "Sharpedo", "Wailmer", "Wailord", "Lapras", "Exeggcute", "Exeggutor-Alola", "Jangmo-o", "Hakamo-o", "Kommo-o", "Emolga", "Scyther", "Scizor", "Murkrow", "Honchkrow", "Riolu", "Lucario", "Dratini", "Dragonair", "Dragonite", "Aerodactyl", "Tapu Koko", "Tapu Lele", "Tapu Bulu", "Tapu Fini", "Cosmog", "Cosmoem", "Solgaleo", "Lunala", "Nihilego", "Buzzwole", "Pheromosa", "Xurkitree", "Celesteela", "Kartana", "Guzzlord", "Necrozma", "Magearna", "Marshadow", ]; - let template = this.getTemplate(set.species || set.name); - if (!alolaDex.includes(template.baseSpecies) && !alolaDex.includes(template.species) && !this.getRuleTable(format).has('+' + template.speciesid)) { + let template = this.dex.getTemplate(set.species || set.name); + if (!alolaDex.includes(template.baseSpecies) && !alolaDex.includes(template.species) && !this.ruleTable.has('+' + template.speciesid)) { return [template.baseSpecies + " is not in the Alola Pokédex."]; } }, diff --git a/data/moves.js b/data/moves.js index 81ada91c8b..4ee6c4ef4f 100644 --- a/data/moves.js +++ b/data/moves.js @@ -640,7 +640,7 @@ let BattleMovedex = { let noAssist = [ 'assist', 'banefulbunker', 'beakblast', 'belch', 'bestow', 'bounce', 'celebrate', 'chatter', 'circlethrow', 'copycat', 'counter', 'covet', 'destinybond', 'detect', 'dig', 'dive', 'dragontail', 'endure', 'feint', 'fly', 'focuspunch', 'followme', 'helpinghand', 'holdhands', 'kingsshield', 'matblock', 'mefirst', 'metronome', 'mimic', 'mirrorcoat', 'mirrormove', 'naturepower', 'phantomforce', 'protect', 'ragepowder', 'roar', 'shadowforce', 'shelltrap', 'sketch', 'skydrop', 'sleeptalk', 'snatch', 'spikyshield', 'spotlight', 'struggle', 'switcheroo', 'thief', 'transform', 'trick', 'whirlwind', ]; - if (!noAssist.includes(move) && !this.getMove(move).isZ) { + if (!noAssist.includes(move) && !this.dex.getMove(move).isZ) { moves.push(move); } } @@ -1275,7 +1275,7 @@ let BattleMovedex = { return false; } if (!target.isActive) { - const possibleTarget = this.resolveTarget(pokemon, this.getMove('pound')); + const possibleTarget = this.resolveTarget(pokemon, this.dex.getMove('pound')); if (!possibleTarget) { this.add('-miss', pokemon); return false; @@ -2580,7 +2580,7 @@ let BattleMovedex = { priority: 0, flags: {snatch: 1}, onHit(target) { - let type = this.getMove(target.moveSlots[0].id).type; + let type = this.dex.getMove(target.moveSlots[0].id).type; if (target.hasType(type) || !target.setType(type)) return false; this.add('-start', target, 'typechange', type); }, @@ -2608,9 +2608,9 @@ let BattleMovedex = { } let possibleTypes = []; let attackType = target.lastMove.type; - for (let type in this.data.TypeChart) { + for (let type in this.dex.data.TypeChart) { if (source.hasType(type)) continue; - let typeCheck = this.data.TypeChart[type].damageTaken[attackType]; + let typeCheck = this.dex.data.TypeChart[type].damageTaken[attackType]; if (typeCheck === 2 || typeCheck === 3) { possibleTypes.push(type); } @@ -3233,13 +3233,13 @@ let BattleMovedex = { for (const targetCondition of removeTarget) { if (target.side.removeSideCondition(targetCondition)) { if (!removeAll.includes(targetCondition)) continue; - this.add('-sideend', target.side, this.getEffect(targetCondition).name, '[from] move: Defog', '[of] ' + source); + this.add('-sideend', target.side, this.dex.getEffect(targetCondition).name, '[from] move: Defog', '[of] ' + source); success = true; } } for (const sideCondition of removeAll) { if (source.side.removeSideCondition(sideCondition)) { - this.add('-sideend', source.side, this.getEffect(sideCondition).name, '[from] move: Defog', '[of] ' + source); + this.add('-sideend', source.side, this.dex.getEffect(sideCondition).name, '[from] move: Defog', '[of] ' + source); success = true; } } @@ -4619,7 +4619,7 @@ let BattleMovedex = { onHit(target, source) { let oldAbility = target.setAbility(source.ability); if (oldAbility) { - this.add('-ability', target, this.getAbility(target.ability).name, '[from] move: Entrainment'); + this.add('-ability', target, this.dex.getAbility(target.ability).name, '[from] move: Entrainment'); return; } return false; @@ -5295,7 +5295,7 @@ let BattleMovedex = { } for (const ally of target.side.active) { if (ally && this.isAdjacent(target, ally)) { - this.damage(ally.maxhp / 16, ally, source, this.getEffect('Flame Burst')); + this.damage(ally.maxhp / 16, ally, source, this.dex.getEffect('Flame Burst')); } } }, @@ -5305,7 +5305,7 @@ let BattleMovedex = { } for (const ally of target.side.active) { if (ally && this.isAdjacent(target, ally)) { - this.damage(ally.maxhp / 16, ally, source, this.getEffect('Flame Burst')); + this.damage(ally.maxhp / 16, ally, source, this.dex.getEffect('Flame Burst')); } } }, @@ -5690,7 +5690,7 @@ let BattleMovedex = { pp: 10, flags: {contact: 1, protect: 1, mirror: 1, gravity: 1, distance: 1, nonsky: 1}, onEffectiveness(typeMod, target, type, move) { - return typeMod + this.getEffectiveness('Flying', type); + return typeMod + this.dex.getEffectiveness('Flying', type); }, priority: 0, secondary: null, @@ -6106,7 +6106,7 @@ let BattleMovedex = { if (!pokemon.volatiles.furycutter || move.hit === 1) { pokemon.addVolatile('furycutter'); } - return this.clampIntRange(move.basePower * pokemon.volatiles.furycutter.multiplier, 1, 160); + return this.dex.clampIntRange(move.basePower * pokemon.volatiles.furycutter.multiplier, 1, 160); }, category: "Physical", desc: "Power doubles with each successful hit, up to a maximum of 160 power. The power is reset if this move misses or another move is used.", @@ -6269,7 +6269,7 @@ let BattleMovedex = { // Ability suppression implemented in Pokemon.ignoringAbility() within sim/pokemon.js onStart(pokemon) { this.add('-endability', pokemon); - this.singleEvent('End', this.getAbility(pokemon.ability), pokemon.abilityData, pokemon, pokemon, 'gastroacid'); + this.singleEvent('End', this.dex.getAbility(pokemon.ability), pokemon.abilityData, pokemon, pokemon, 'gastroacid'); }, }, secondary: null, @@ -6764,7 +6764,7 @@ let BattleMovedex = { }, onDisableMove(pokemon) { for (const moveSlot of pokemon.moveSlots) { - if (this.getMove(moveSlot.id).flags['gravity']) { + if (this.dex.getMove(moveSlot.id).flags['gravity']) { pokemon.disableMove(moveSlot.id); } } @@ -6857,7 +6857,7 @@ let BattleMovedex = { for (const moveSlot of source.moveSlots) { if (moveSlot.id === source.lastMove.id) { moveSlot.pp = 0; - this.add('-activate', source, 'move: Grudge', this.getMove(source.lastMove.id).name); + this.add('-activate', source, 'move: Grudge', this.dex.getMove(source.lastMove.id).name); } } } @@ -6881,9 +6881,9 @@ let BattleMovedex = { damageCallback(pokemon, target) { if (target.volatiles['banefulbunker'] || target.volatiles['kingsshield'] || target.side.getSideCondition('matblock') || target.volatiles['protect'] || target.volatiles['spikyshield']) { this.add('-zbroken', target); - return this.clampIntRange(Math.ceil(Math.floor(target.hp * 3 / 4) / 4 - 0.5), 1); + return this.dex.clampIntRange(Math.ceil(Math.floor(target.hp * 3 / 4) / 4 - 0.5), 1); } - return this.clampIntRange(Math.floor(target.hp * 3 / 4), 1); + return this.dex.clampIntRange(Math.floor(target.hp * 3 / 4), 1); }, category: "Special", desc: "Deals damage to the target equal to 3/4 of its current HP, rounded down, but not less than 1 HP.", @@ -7269,7 +7269,7 @@ let BattleMovedex = { }, onDisableMove(pokemon) { for (const moveSlot of pokemon.moveSlots) { - if (this.getMove(moveSlot.id).flags['heal']) { + if (this.dex.getMove(moveSlot.id).flags['heal']) { pokemon.disableMove(moveSlot.id); } } @@ -7923,7 +7923,7 @@ let BattleMovedex = { flags: {contact: 1, protect: 1, mirror: 1, gravity: 1}, hasCustomRecoil: true, onMoveFail(target, source, move) { - this.damage(source.maxhp / 2, source, source, this.getEffect('High Jump Kick')); + this.damage(source.maxhp / 2, source, source, this.dex.getEffect('High Jump Kick')); }, secondary: null, target: "normal", @@ -8879,7 +8879,7 @@ let BattleMovedex = { flags: {contact: 1, protect: 1, mirror: 1, gravity: 1}, hasCustomRecoil: true, onMoveFail(target, source, move) { - this.damage(source.maxhp / 2, source, source, this.getEffect('Jump Kick')); + this.damage(source.maxhp / 2, source, source, this.dex.getEffect('Jump Kick')); }, secondary: null, target: "normal", @@ -8968,13 +8968,13 @@ let BattleMovedex = { } } if (move.flags['contact']) { - this.boost({atk: -2}, source, target, this.getActiveMove("King's Shield")); + this.boost({atk: -2}, source, target, this.dex.getActiveMove("King's Shield")); } return this.NOT_FAIL; }, onHit(target, source, move) { if (move.isZPowered && move.flags['contact']) { - this.boost({atk: -2}, source, target, this.getActiveMove("King's Shield")); + this.boost({atk: -2}, source, target, this.dex.getActiveMove("King's Shield")); } }, }, @@ -9758,7 +9758,7 @@ let BattleMovedex = { if (target === source || move.hasBounced || !move.flags['reflectable']) { return; } - let newMove = this.getActiveMove(move.id); + let newMove = this.dex.getActiveMove(move.id); newMove.hasBounced = true; newMove.pranksterBoosted = this.effectData.pranksterBoosted; this.useMove(newMove, target, source); @@ -9768,7 +9768,7 @@ let BattleMovedex = { if (target.side === source.side || move.hasBounced || !move.flags['reflectable']) { return; } - let newMove = this.getActiveMove(move.id); + let newMove = this.dex.getActiveMove(move.id); newMove.hasBounced = true; newMove.pranksterBoosted = false; this.useMove(newMove, this.effectData.target, source); @@ -10139,7 +10139,7 @@ let BattleMovedex = { let noMeFirst = [ 'beakblast', 'chatter', 'counter', 'covet', 'focuspunch', 'mefirst', 'metalburst', 'mirrorcoat', 'shelltrap', 'struggle', 'thief', ]; - let move = this.getActiveMove(action.move.id); + let move = this.dex.getActiveMove(action.move.id); if (!action.zmove && !move.isZ && move.category !== 'Status' && !noMeFirst.includes(move.id)) { pokemon.addVolatile('mefirst'); this.useMove(move, pokemon, target); @@ -10416,7 +10416,7 @@ let BattleMovedex = { if (move.isZ || move.isNonstandard) continue; // @ts-ignore if (effect.noMetronome.includes(move.id)) continue; - if (this.getMove(i).gen > this.gen) continue; + if (this.dex.getMove(i).gen > this.gen) continue; moves.push(move); } let randomMove = ''; @@ -10471,7 +10471,7 @@ let BattleMovedex = { if (source.transformed || !target.lastMove || disallowedMoves.includes(target.lastMove.id) || source.moves.indexOf(target.lastMove.id) >= 0 || target.lastMove.isZ) return false; let mimicIndex = source.moves.indexOf('mimic'); if (mimicIndex < 0) return false; - let move = this.getMove(target.lastMove.id); + let move = this.dex.getMove(target.lastMove.id); source.moveSlots[mimicIndex] = { move: move.name, id: move.id, @@ -10506,7 +10506,7 @@ let BattleMovedex = { mindBlownRecoil: true, onAfterMove(pokemon, target, move) { if (move.mindBlownRecoil && !move.multihit) { - this.damage(Math.round(pokemon.maxhp / 2), pokemon, pokemon, this.getEffect('Mind Blown'), true); + this.damage(Math.round(pokemon.maxhp / 2), pokemon, pokemon, this.dex.getEffect('Mind Blown'), true); } }, secondary: null, @@ -11200,7 +11200,7 @@ let BattleMovedex = { accuracy: 90, basePower: 0, damageCallback(pokemon, target) { - return this.clampIntRange(Math.floor(target.hp / 2), 1); + return this.dex.clampIntRange(Math.floor(target.hp / 2), 1); }, category: "Special", desc: "Deals damage to the target equal to half of its current HP, rounded down, but not less than 1 HP.", @@ -12217,7 +12217,7 @@ let BattleMovedex = { onTryMove(pokemon, target, move) { if (move.type === 'Fire') { this.add('-activate', pokemon, 'move: Powder'); - this.damage(this.clampIntRange(Math.round(pokemon.maxhp / 4), 1)); + this.damage(this.dex.clampIntRange(Math.round(pokemon.maxhp / 4), 1)); return false; } }, @@ -13218,7 +13218,7 @@ let BattleMovedex = { let sideConditions = ['spikes', 'toxicspikes', 'stealthrock', 'stickyweb']; for (const condition of sideConditions) { if (pokemon.hp && pokemon.side.removeSideCondition(condition)) { - this.add('-sideend', pokemon.side, this.getEffect(condition).name, '[from] move: Rapid Spin', '[of] ' + pokemon); + this.add('-sideend', pokemon.side, this.dex.getEffect(condition).name, '[from] move: Rapid Spin', '[of] ' + pokemon); } } if (pokemon.hp && pokemon.volatiles['partiallytrapped']) { @@ -13341,7 +13341,7 @@ let BattleMovedex = { if (pokemon.item || !pokemon.lastItem) return false; let item = pokemon.lastItem; pokemon.lastItem = ''; - this.add('-item', pokemon, this.getItem(item), '[from] move: Recycle'); + this.add('-item', pokemon, this.dex.getItem(item), '[from] move: Recycle'); pokemon.setItem(item); }, secondary: null, @@ -13880,7 +13880,7 @@ let BattleMovedex = { onHit(target, source) { let oldAbility = source.setAbility(target.ability); if (oldAbility) { - this.add('-ability', source, this.getAbility(source.ability).name, '[from] move: Role Play', '[of] ' + target); + this.add('-ability', source, this.dex.getAbility(source.ability).name, '[from] move: Role Play', '[of] ' + target); return; } return false; @@ -15066,7 +15066,7 @@ let BattleMovedex = { if (source.transformed || !target.lastMove || disallowedMoves.includes(target.lastMove.id) || source.moves.indexOf(target.lastMove.id) >= 0 || target.lastMove.isZ) return false; let sketchIndex = source.moves.indexOf('sketch'); if (sketchIndex < 0) return false; - let move = this.getMove(target.lastMove); + let move = this.dex.getMove(target.lastMove); let sketchedMove = { move: move.name, id: move.id, @@ -15105,8 +15105,8 @@ let BattleMovedex = { } }, onHit(target, source, move) { - let targetAbility = this.getAbility(target.ability); - let sourceAbility = this.getAbility(source.ability); + let targetAbility = this.dex.getAbility(target.ability); + let sourceAbility = this.dex.getAbility(source.ability); if (target.side === source.side) { this.add('-activate', source, 'move: Skill Swap', '', '', '[of] ' + target); } else { @@ -15424,7 +15424,7 @@ let BattleMovedex = { const noSleepTalk = [ 'assist', 'beakblast', 'belch', 'bide', 'celebrate', 'chatter', 'copycat', 'focuspunch', 'mefirst', 'metronome', 'mimic', 'mirrormove', 'naturepower', 'shelltrap', 'sketch', 'sleeptalk', 'uproar', ]; - if (move && !(noSleepTalk.includes(move) || this.getMove(move).flags['charge'] || (this.getMove(move).isZ && this.getMove(move).basePower !== 1))) { + if (move && !(noSleepTalk.includes(move) || this.dex.getMove(move).flags['charge'] || (this.dex.getMove(move).isZ && this.dex.getMove(move).basePower !== 1))) { moves.push(move); } } @@ -16231,7 +16231,7 @@ let BattleMovedex = { if (target.lastMove && !target.lastMove.isZ) { let ppDeducted = target.deductPP(target.lastMove.id, 4); if (ppDeducted) { - this.add("-activate", target, 'move: Spite', this.getMove(target.lastMove.id).name, ppDeducted); + this.add("-activate", target, 'move: Spite', this.dex.getMove(target.lastMove.id).name, ppDeducted); return; } } @@ -16381,7 +16381,7 @@ let BattleMovedex = { this.add('-sidestart', side, 'move: Stealth Rock'); }, onSwitchIn(pokemon) { - let typeMod = this.clampIntRange(pokemon.runEffectiveness(this.getActiveMove('stealthrock')), -6, 6); + let typeMod = this.dex.clampIntRange(pokemon.runEffectiveness(this.dex.getActiveMove('stealthrock')), -6, 6); this.damage(pokemon.maxhp * Math.pow(2, typeMod) / 8); }, }, @@ -16481,7 +16481,7 @@ let BattleMovedex = { onSwitchIn(pokemon) { if (!pokemon.isGrounded()) return; this.add('-activate', pokemon, 'move: Sticky Web'); - this.boost({spe: -1}, pokemon, pokemon.side.foe.active[0], this.getActiveMove('stickyweb')); + this.boost({spe: -1}, pokemon, pokemon.side.foe.active[0], this.dex.getActiveMove('stickyweb')); }, }, secondary: null, @@ -16989,7 +16989,7 @@ let BattleMovedex = { accuracy: 90, basePower: 0, damageCallback(pokemon, target) { - return this.clampIntRange(Math.floor(target.hp / 2), 1); + return this.dex.clampIntRange(Math.floor(target.hp / 2), 1); }, category: "Physical", desc: "Deals damage to the target equal to half of its current HP, rounded down, but not less than 1 HP.", @@ -17486,7 +17486,7 @@ let BattleMovedex = { }, onDisableMove(pokemon) { for (const moveSlot of pokemon.moveSlots) { - if (this.getMove(moveSlot.id).category === 'Status') { + if (this.dex.getMove(moveSlot.id).category === 'Status') { pokemon.disableMove(moveSlot.id); } } @@ -17780,7 +17780,7 @@ let BattleMovedex = { }, onDisableMove(pokemon) { for (const moveSlot of pokemon.moveSlots) { - if (this.getMove(moveSlot.id).flags['sound']) { + if (this.dex.getMove(moveSlot.id).flags['sound']) { pokemon.disableMove(moveSlot.id); } } diff --git a/data/random-teams.js b/data/random-teams.js index bbb51e3833..92b1090e9d 100644 --- a/data/random-teams.js +++ b/data/random-teams.js @@ -27,14 +27,15 @@ const randomFactorySets = require('./factory-sets.json'); * @property {number} [eeveeLimCount] */ -class RandomTeams extends Dex.ModdedDex { +class RandomTeams { /** * @param {Format | string} format * @param {?PRNG | [number, number, number, number]} [prng] */ constructor(format, prng) { format = Dex.getFormat(format); - super(format.mod); + this.dex = Dex.forFormat(format); + this.gen = this.dex.gen; this.randomBSSFactorySets = randomBSSFactorySets; this.randomFactorySets = randomFactorySets; @@ -125,7 +126,7 @@ class RandomTeams extends Dex.ModdedDex { // No randomization, no choice. We are just checking its existence. // Returns a Pokémon template for further details. if (!template.otherFormes) return null; - let firstForme = this.getTemplate(template.otherFormes[0]); + let firstForme = this.dex.getTemplate(template.otherFormes[0]); if (firstForme.isMega || firstForme.isPrimal) return firstForme; return null; } @@ -149,7 +150,7 @@ class RandomTeams extends Dex.ModdedDex { // } // hasMegaEvo(template) { // if (!template.otherFormes) return false; - // let firstForme = this.getTemplate(template.otherFormes[0]); + // let firstForme = this.dex.getTemplate(template.otherFormes[0]); // return !!firstForme.isMega; // } /** @@ -158,8 +159,8 @@ class RandomTeams extends Dex.ModdedDex { randomCCTeam() { let team = []; - let natures = Object.keys(this.data.Natures); - let items = Object.keys(this.data.Items); + let natures = Object.keys(this.dex.data.Natures); + let items = Object.keys(this.dex.data.Items); let random6 = this.random6Pokemon(); @@ -172,7 +173,7 @@ class RandomTeams extends Dex.ModdedDex { if (this.gen >= 2) { do { item = this.sample(items); - } while (this.getItem(item).gen > this.gen || this.data.Items[item].isNonstandard); + } while (this.dex.getItem(item).gen > this.gen || this.dex.data.Items[item].isNonstandard); } // Make sure forme is legal @@ -182,16 +183,16 @@ class RandomTeams extends Dex.ModdedDex { } // Make sure that a base forme does not hold any forme-modifier items. - let itemData = this.getItem(item); - if (itemData.forcedForme && species === this.getTemplate(itemData.forcedForme).baseSpecies) { + let itemData = this.dex.getItem(item); + if (itemData.forcedForme && species === this.dex.getTemplate(itemData.forcedForme).baseSpecies) { do { item = this.sample(items); - itemData = this.getItem(item); - } while (itemData.gen > this.gen || itemData.isNonstandard || itemData.forcedForme && species === this.getTemplate(itemData.forcedForme).baseSpecies); + itemData = this.dex.getItem(item); + } while (itemData.gen > this.gen || itemData.isNonstandard || itemData.forcedForme && species === this.dex.getTemplate(itemData.forcedForme).baseSpecies); } // Random legal ability - let abilities = Object.values(template.abilities).filter(a => this.getAbility(a).gen <= this.gen); + let abilities = Object.values(template.abilities).filter(a => this.dex.getAbility(a).gen <= this.gen); /**@type {string} */ // @ts-ignore let ability = this.gen <= 2 ? 'None' : this.sample(abilities); @@ -200,16 +201,16 @@ class RandomTeams extends Dex.ModdedDex { let moves; let pool = ['struggle']; if (species === 'Smeargle') { - pool = Object.keys(this.data.Movedex).filter(moveid => !(['chatter', 'struggle', 'paleowave', 'shadowstrike', 'magikarpsrevenge'].includes(moveid) || this.data.Movedex[moveid].isZ || this.data.Movedex[moveid].id === 'hiddenpower' && moveid !== 'hiddenpower')); + pool = Object.keys(this.dex.data.Movedex).filter(moveid => !(['chatter', 'struggle', 'paleowave', 'shadowstrike', 'magikarpsrevenge'].includes(moveid) || this.dex.data.Movedex[moveid].isZ || this.dex.data.Movedex[moveid].id === 'hiddenpower' && moveid !== 'hiddenpower')); } else if (template.learnset) { // @ts-ignore pool = Object.keys(template.learnset).filter(moveid => template.learnset[moveid].find(learned => learned.startsWith(this.gen))); if (template.species.substr(0, 6) === 'Rotom-') { - const learnset = this.getTemplate(template.baseSpecies).learnset; + const learnset = this.dex.getTemplate(template.baseSpecies).learnset; if (learnset) pool = [...new Set(pool.concat(Object.keys(learnset)))]; } } else { - const learnset = this.getTemplate(template.baseSpecies).learnset; + const learnset = this.dex.getTemplate(template.baseSpecies).learnset; // @ts-ignore if (learnset) pool = Object.keys(learnset).filter(moveid => learnset[moveid].find(learned => learned.startsWith(this.gen))); } @@ -309,9 +310,9 @@ class RandomTeams extends Dex.ModdedDex { /**@type {string[][]} */ let formes = [[], [], [], [], [], []]; - for (let id in this.data.Pokedex) { - if (!(this.data.Pokedex[id].num in hasDexNumber)) continue; - let template = this.getTemplate(id); + for (let id in this.dex.data.Pokedex) { + if (!(this.dex.data.Pokedex[id].num in hasDexNumber)) continue; + let template = this.dex.getTemplate(id); if (template.gen <= this.gen && template.species !== 'Pichu-Spiky-eared' && template.species.substr(0, 8) !== 'Pikachu-') { formes[hasDexNumber[template.num]].push(template.species); } @@ -330,23 +331,23 @@ class RandomTeams extends Dex.ModdedDex { randomHCTeam() { let team = []; - let itemPool = Object.keys(this.data.Items); - let abilityPool = Object.keys(this.data.Abilities); - let movePool = Object.keys(this.data.Movedex); - let naturePool = Object.keys(this.data.Natures); + let itemPool = Object.keys(this.dex.data.Items); + let abilityPool = Object.keys(this.dex.data.Abilities); + let movePool = Object.keys(this.dex.data.Movedex); + let naturePool = Object.keys(this.dex.data.Natures); let random6 = this.random6Pokemon(); for (let i = 0; i < 6; i++) { // Choose forme - let template = this.getTemplate(random6[i]); + let template = this.dex.getTemplate(random6[i]); // Random unique item let item = ''; if (this.gen >= 2) { do { item = this.sampleNoReplace(itemPool); - } while (this.getItem(item).gen > this.gen || this.data.Items[item].isNonstandard); + } while (this.dex.getItem(item).gen > this.gen || this.dex.data.Items[item].isNonstandard); } // Random unique ability @@ -354,14 +355,14 @@ class RandomTeams extends Dex.ModdedDex { if (this.gen >= 3) { do { ability = this.sampleNoReplace(abilityPool); - } while (this.getAbility(ability).gen > this.gen || this.data.Abilities[ability].isNonstandard); + } while (this.dex.getAbility(ability).gen > this.gen || this.dex.data.Abilities[ability].isNonstandard); } // Random unique moves let m = []; do { let moveid = this.sampleNoReplace(movePool); - if (this.getMove(moveid).gen <= this.gen && !this.data.Movedex[moveid].isNonstandard && (moveid === 'hiddenpower' || moveid.substr(0, 11) !== 'hiddenpower')) { + if (this.dex.getMove(moveid).gen <= this.gen && !this.dex.data.Movedex[moveid].isNonstandard && (moveid === 'hiddenpower' || moveid.substr(0, 11) !== 'hiddenpower')) { m.push(moveid); } } while (m.length < 4); @@ -499,7 +500,7 @@ class RandomTeams extends Dex.ModdedDex { // Iterate through all moves we've chosen so far and keep track of what they do: for (const [k, moveId] of moves.entries()) { - let move = this.getMove(moveId); + let move = this.dex.getMove(moveId); let moveid = move.id; let movetype = move.type; if (['judgment', 'multiattack', 'revelationdance'].includes(moveid)) movetype = Object.keys(hasType)[0]; @@ -571,7 +572,7 @@ class RandomTeams extends Dex.ModdedDex { // Keep track of the available moves for (const moveid of movePool) { - let move = this.getMove(moveid); + let move = this.dex.getMove(moveid); if (move.damageCallback) continue; if (move.category === 'Physical') counter['physicalpool']++; if (move.category === 'Special') counter['specialpool']++; @@ -611,13 +612,13 @@ class RandomTeams extends Dex.ModdedDex { * @return {RandomTeamsTypes.RandomSet} */ randomSet(template, teamDetails = {}, isLead = false, isDoubles = false) { - template = this.getTemplate(template); + template = this.dex.getTemplate(template); let baseTemplate = template; let species = template.species; if (!template.exists || ((!isDoubles || !template.randomDoubleBattleMoves) && !template.randomBattleMoves && !template.learnset)) { // GET IT? UNOWN? BECAUSE WE CAN'T TELL WHAT THE POKEMON IS - template = this.getTemplate('unown'); + template = this.dex.getTemplate('unown'); let err = new Error('Template incompatible with random battles: ' + species); Monitor.crashlog(err, 'The randbat set generator'); @@ -629,7 +630,7 @@ class RandomTeams extends Dex.ModdedDex { } let battleForme = this.checkBattleForme(template); if (battleForme && battleForme.randomBattleMoves && template.otherFormes && (battleForme.isMega ? !teamDetails.megaStone : this.random(2))) { - template = this.getTemplate(template.otherFormes.length >= 2 ? this.sample(template.otherFormes) : template.otherFormes[0]); + template = this.dex.getTemplate(template.otherFormes.length >= 2 ? this.sample(template.otherFormes) : template.otherFormes[0]); } const randMoves = !isDoubles ? template.randomBattleMoves : template.randomDoubleBattleMoves || template.randomBattleMoves; @@ -720,7 +721,7 @@ class RandomTeams extends Dex.ModdedDex { // Iterate through the moves again, this time to cull them: for (const [k, moveId] of moves.entries()) { - let move = this.getMove(moveId); + let move = this.dex.getMove(moveId); let moveid = move.id; let rejected = false; let isSetup = false; @@ -1214,10 +1215,10 @@ class RandomTeams extends Dex.ModdedDex { /**@type {[string, string | undefined, string | undefined]} */ // @ts-ignore let abilities = Object.values(baseTemplate.abilities); - abilities.sort((a, b) => this.getAbility(b).rating - this.getAbility(a).rating); - let ability0 = this.getAbility(abilities[0]); - let ability1 = this.getAbility(abilities[1]); - let ability2 = this.getAbility(abilities[2]); + abilities.sort((a, b) => this.dex.getAbility(b).rating - this.dex.getAbility(a).rating); + let ability0 = this.dex.getAbility(abilities[0]); + let ability1 = this.dex.getAbility(abilities[1]); + let ability2 = this.dex.getAbility(abilities[2]); if (abilities[1]) { if (abilities[2] && ability1.rating <= ability2.rating && this.randomChance(1, 2)) { [ability1, ability2] = [ability2, ability1]; @@ -1399,7 +1400,7 @@ class RandomTeams extends Dex.ModdedDex { item = 'Ultranecrozium Z'; if (!hasMove['photongeyser']) { for (const moveid of moves) { - let move = this.getMove(moveid); + let move = this.dex.getMove(moveid); if (move.category === 'Status' || hasType[move.type]) continue; moves[moves.indexOf(moveid)] = 'photongeyser'; break; @@ -1528,17 +1529,17 @@ class RandomTeams extends Dex.ModdedDex { item = 'Lum Berry'; } else if (isDoubles && counter.damagingMoves.length >= 4 && template.baseStats.spe >= 60 && !hasMove['fakeout'] && !hasMove['flamecharge'] && !hasMove['suckerpunch'] && ability !== 'Multiscale' && ability !== 'Sturdy') { item = 'Life Orb'; - } else if (isDoubles && this.getEffectiveness('Ice', template) >= 2) { + } else if (isDoubles && this.dex.getEffectiveness('Ice', template) >= 2) { item = 'Yache Berry'; - } else if (isDoubles && this.getEffectiveness('Rock', template) >= 2) { + } else if (isDoubles && this.dex.getEffectiveness('Rock', template) >= 2) { item = 'Charti Berry'; - } else if (isDoubles && this.getEffectiveness('Fire', template) >= 2) { + } else if (isDoubles && this.dex.getEffectiveness('Fire', template) >= 2) { item = 'Occa Berry'; - } else if (isDoubles && this.getImmunity('Fighting', template) && this.getEffectiveness('Fighting', template) >= 2) { + } else if (isDoubles && this.dex.getImmunity('Fighting', template) && this.dex.getEffectiveness('Fighting', template) >= 2) { item = 'Chople Berry'; } else if (hasMove['substitute']) { item = counter.damagingMoves.length > 2 && !!counter['drain'] ? 'Life Orb' : 'Leftovers'; - } else if (this.getEffectiveness('Ground', template) >= 2 && ability !== 'Levitate' && !hasMove['magnetrise']) { + } else if (this.dex.getEffectiveness('Ground', template) >= 2 && ability !== 'Levitate' && !hasMove['magnetrise']) { item = 'Air Balloon'; } else if ((ability === 'Iron Barbs' || ability === 'Rough Skin') && this.randomChance(1, 2)) { item = 'Rocky Helmet'; @@ -1609,7 +1610,7 @@ class RandomTeams extends Dex.ModdedDex { // Every 10.34 BST adds a level from 70 up to 99. Results are floored. Uses the Mega's stats if holding a Mega Stone let baseStats = template.baseStats; // If Wishiwashi, use the school-forme's much higher stats - if (template.baseSpecies === 'Wishiwashi') baseStats = this.getTemplate('wishiwashischool').baseStats; + if (template.baseSpecies === 'Wishiwashi') baseStats = this.dex.getTemplate('wishiwashischool').baseStats; let bst = baseStats.hp + baseStats.atk + baseStats.def + baseStats.spa + baseStats.spd + baseStats.spe; // Adjust levels of mons based on abilities (Pure Power, Sheer Force, etc.) and also Eviolite @@ -1633,7 +1634,7 @@ class RandomTeams extends Dex.ModdedDex { } else if (item === 'Light Ball') { bst += baseStats.atk + baseStats.spa; } - level = 70 + Math.floor(((600 - this.clampIntRange(bst, 300, 600)) / 10.34)); + level = 70 + Math.floor(((600 - this.dex.clampIntRange(bst, 300, 600)) / 10.34)); } if (template.species === 'Stunfisk') { @@ -1644,7 +1645,7 @@ class RandomTeams extends Dex.ModdedDex { } // Prepare optimal HP - let srWeakness = this.getEffectiveness('Rock', template); + let srWeakness = this.dex.getEffectiveness('Rock', template); while (evs.hp > 1) { let hp = Math.floor(Math.floor(2 * template.baseStats.hp + ivs.hp + Math.floor(evs.hp / 4) + 100) * level / 100 + 10); if (hasMove['substitute'] && hasMove['reversal']) { @@ -1703,12 +1704,12 @@ class RandomTeams extends Dex.ModdedDex { const allowedNFE = ['Chansey', 'Doublade', 'Gligar', 'Pikachu', 'Porygon2', 'Scyther', 'Type: Null']; const exclude = pokemon.map(p => toID(p.species)); const pokemonPool = []; - for (let id in this.data.FormatsData) { - let template = this.getTemplate(id); + for (let id in this.dex.data.FormatsData) { + let template = this.dex.getTemplate(id); if (exclude.includes(template.id)) continue; if (isMonotype) { let types = template.types; - if (template.battleOnly) types = this.getTemplate(template.baseSpecies).types; + if (template.battleOnly) types = this.dex.getTemplate(template.baseSpecies).types; if (types.indexOf(type) < 0) continue; } if (template.gen <= this.gen && (!template.nfe || allowedNFE.includes(template.species)) && !template.isMega && !template.isPrimal && !template.isNonstandard && template.randomBattleMoves) { @@ -1724,13 +1725,13 @@ class RandomTeams extends Dex.ModdedDex { // For Monotype let isMonotype = this.format.id === 'gen7monotyperandombattle'; - let typePool = Object.keys(this.data.TypeChart); + let typePool = Object.keys(this.dex.data.TypeChart); let type = this.sample(typePool); // PotD stuff let potd; - if (global.Config && Config.potd && this.getRuleTable(this.getFormat()).has('potd')) { - potd = this.getTemplate(Config.potd); + if (global.Config && Config.potd && this.dex.getRuleTable(this.format).has('potd')) { + potd = this.dex.getTemplate(Config.potd); } /**@type {{[k: string]: number}} */ @@ -1750,7 +1751,7 @@ class RandomTeams extends Dex.ModdedDex { if (pokemon.length >= 6) break; const pokemonPool = this.getPokemonPool(type, pokemon, isMonotype); while (pokemonPool.length && pokemon.length < 6) { - let template = this.getTemplate(this.sampleNoReplace(pokemonPool)); + let template = this.dex.getTemplate(this.sampleNoReplace(pokemonPool)); if (!template.exists) continue; // Limit to one of each species (Species Clause) @@ -1820,7 +1821,7 @@ class RandomTeams extends Dex.ModdedDex { } } - let item = this.getItem(set.item); + let item = this.dex.getItem(set.item); // Limit 1 Z-Move per team if (item.zMove && teamDetails['zMove']) continue; @@ -1904,12 +1905,12 @@ class RandomTeams extends Dex.ModdedDex { let effectivePool = []; let priorityPool = []; for (const curSet of setList) { - let item = this.getItem(curSet.item); + let item = this.dex.getItem(curSet.item); if (teamData.megaCount > 0 && item.megaStone) continue; // reject 2+ mega stones if (teamData.zCount && teamData.zCount > 0 && item.zMove) continue; // reject 2+ Z stones if (itemsMax[item.id] && teamData.has[item.id] >= itemsMax[item.id]) continue; - let ability = this.getAbility(curSet.ability); + let ability = this.dex.getAbility(curSet.ability); // @ts-ignore if (weatherAbilitiesRequire[ability.id] && teamData.weather !== weatherAbilitiesRequire[ability.id]) continue; if (teamData.weather && weatherAbilities.includes(ability.id)) continue; // reject 2+ weather setters @@ -1996,7 +1997,7 @@ class RandomTeams extends Dex.ModdedDex { let pokemon = []; let pokemonPool = Object.keys(this.randomFactorySets[chosenTier]); - let typePool = Object.keys(this.data.TypeChart); + let typePool = Object.keys(this.dex.data.TypeChart); const type = this.sample(typePool); /**@type {TeamData} */ @@ -2017,7 +2018,7 @@ class RandomTeams extends Dex.ModdedDex { }; while (pokemonPool.length && pokemon.length < 6) { - let template = this.getTemplate(this.sampleNoReplace(pokemonPool)); + let template = this.dex.getTemplate(this.sampleNoReplace(pokemonPool)); if (!template.exists) continue; // Lessen the need of deleting sets of Pokemon after tier shifts @@ -2034,7 +2035,7 @@ class RandomTeams extends Dex.ModdedDex { let set = this.randomFactorySet(template, pokemon.length, teamData, chosenTier); if (!set) continue; - let itemData = this.getItem(set.item); + let itemData = this.dex.getItem(set.item); // Actually limit the number of Megas to one if (teamData.megaCount >= 1 && itemData.megaStone) continue; @@ -2048,7 +2049,7 @@ class RandomTeams extends Dex.ModdedDex { if (chosenTier === 'Mono') { // Prevents Mega Evolutions from breaking the type limits if (itemData.megaStone) { - let megaTemplate = this.getTemplate(itemData.megaStone); + let megaTemplate = this.dex.getTemplate(itemData.megaStone); if (types.length > megaTemplate.types.length) types = [template.types[0]]; // Only check the second type because a Mega Evolution should always share the first type with its base forme. if (megaTemplate.types[1] && types[1] && megaTemplate.types[1] !== types[1]) { @@ -2099,7 +2100,7 @@ class RandomTeams extends Dex.ModdedDex { teamData.has[itemData.id] = 1; } - let abilityData = this.getAbility(set.ability); + let abilityData = this.dex.getAbility(set.ability); if (abilityData.id in weatherAbilitiesSet) { teamData.weather = weatherAbilitiesSet[abilityData.id]; } @@ -2116,16 +2117,16 @@ class RandomTeams extends Dex.ModdedDex { } } - for (let typeName in this.data.TypeChart) { + for (let typeName in this.dex.data.TypeChart) { // Cover any major weakness (3+) with at least one resistance if (teamData.resistances[typeName] >= 1) continue; - if (resistanceAbilities[abilityData.id] && resistanceAbilities[abilityData.id].includes(typeName) || !this.getImmunity(typeName, types)) { + if (resistanceAbilities[abilityData.id] && resistanceAbilities[abilityData.id].includes(typeName) || !this.dex.getImmunity(typeName, types)) { // Heuristic: assume that Pokémon with these abilities don't have (too) negative typing. teamData.resistances[typeName] = (teamData.resistances[typeName] || 0) + 1; if (teamData.resistances[typeName] >= 1) teamData.weaknesses[typeName] = 0; continue; } - let typeMod = this.getEffectiveness(typeName, types); + let typeMod = this.dex.getEffectiveness(typeName, types); if (typeMod < 0) { teamData.resistances[typeName] = (teamData.resistances[typeName] || 0) + 1; if (teamData.resistances[typeName] >= 1) teamData.weaknesses[typeName] = 0; @@ -2177,12 +2178,12 @@ class RandomTeams extends Dex.ModdedDex { let effectivePool = []; let priorityPool = []; for (const curSet of setList) { - let item = this.getItem(curSet.item); + let item = this.dex.getItem(curSet.item); if (teamData.megaCount > 1 && item.megaStone) continue; // reject 3+ mega stones if (teamData.zCount && teamData.zCount > 1 && item.zMove) continue; // reject 3+ Z stones if (teamData.has[item.id]) continue; // Item clause - let ability = this.getAbility(curSet.ability); + let ability = this.dex.getAbility(curSet.ability); if (weatherAbilitiesRequire[ability.id] && teamData.weather !== weatherAbilitiesRequire[ability.id]) continue; if (teamData.weather && weatherAbilities.includes(ability.id)) continue; // reject 2+ weather setters @@ -2268,7 +2269,7 @@ class RandomTeams extends Dex.ModdedDex { }; while (pokemonPool.length && pokemon.length < 6) { - let template = this.getTemplate(this.sampleNoReplace(pokemonPool)); + let template = this.dex.getTemplate(this.sampleNoReplace(pokemonPool)); if (!template.exists) continue; let speciesFlags = this.randomBSSFactorySets[template.speciesid].flags; @@ -2321,12 +2322,12 @@ class RandomTeams extends Dex.ModdedDex { teamData.baseFormes[template.baseSpecies] = 1; // Limit Mega and Z-move - let itemData = this.getItem(set.item); + let itemData = this.dex.getItem(set.item); if (itemData.megaStone) teamData.megaCount++; if (itemData.zMove) teamData.zCount++; teamData.has[itemData.id] = 1; - let abilityData = this.getAbility(set.ability); + let abilityData = this.dex.getAbility(set.ability); if (abilityData.id in weatherAbilitiesSet) { teamData.weather = weatherAbilitiesSet[abilityData.id]; } @@ -2343,16 +2344,16 @@ class RandomTeams extends Dex.ModdedDex { } } - for (let typeName in this.data.TypeChart) { + for (let typeName in this.dex.data.TypeChart) { // Cover any major weakness (3+) with at least one resistance if (teamData.resistances[typeName] >= 1) continue; - if (resistanceAbilities[abilityData.id] && resistanceAbilities[abilityData.id].includes(typeName) || !this.getImmunity(typeName, types)) { + if (resistanceAbilities[abilityData.id] && resistanceAbilities[abilityData.id].includes(typeName) || !this.dex.getImmunity(typeName, types)) { // Heuristic: assume that Pokémon with these abilities don't have (too) negative typing. teamData.resistances[typeName] = (teamData.resistances[typeName] || 0) + 1; if (teamData.resistances[typeName] >= 1) teamData.weaknesses[typeName] = 0; continue; } - let typeMod = this.getEffectiveness(typeName, types); + let typeMod = this.dex.getEffectiveness(typeName, types); if (typeMod < 0) { teamData.resistances[typeName] = (teamData.resistances[typeName] || 0) + 1; if (teamData.resistances[typeName] >= 1) teamData.weaknesses[typeName] = 0; diff --git a/data/rulesets.js b/data/rulesets.js index fe30dc794b..fb1d4de0e3 100644 --- a/data/rulesets.js +++ b/data/rulesets.js @@ -136,7 +136,7 @@ let BattleFormats = { desc: "Validate all obtainability things that aren't moves/abilities (Hidden Power type, gender, stats, etc).", // Mostly hardcoded in team-validator.ts onChangeSet(set) { - let template = this.getTemplate(set.species); + let template = this.dex.getTemplate(set.species); if (template.gender) { if (set.gender !== template.gender) { @@ -154,7 +154,7 @@ let BattleFormats = { /**@type {{[k: string]: true}} */ let hasMove = {}; for (const moveId of set.moves) { - let move = this.getMove(moveId); + let move = this.dex.getMove(moveId); let moveid = move.id; if (hasMove[moveid]) continue; hasMove[moveid] = true; @@ -172,8 +172,8 @@ let BattleFormats = { let hoennDex = [ "Abra", "Absol", "Aggron", "Alakazam", "Altaria", "Anorith", "Armaldo", "Aron", "Azumarill", "Azurill", "Bagon", "Baltoy", "Banette", "Barboach", "Beautifly", "Beldum", "Bellossom", "Blaziken", "Breloom", "Budew", "Cacnea", "Cacturne", "Camerupt", "Carvanha", "Cascoon", "Castform", "Chimecho", "Chinchou", "Chingling", "Clamperl", "Claydol", "Combusken", "Corphish", "Corsola", "Cradily", "Crawdaunt", "Crobat", "Delcatty", "Dodrio", "Doduo", "Donphan", "Dusclops", "Dusknoir", "Duskull", "Dustox", "Electrike", "Electrode", "Exploud", "Feebas", "Flygon", "Froslass", "Gallade", "Gardevoir", "Geodude", "Girafarig", "Glalie", "Gloom", "Golbat", "Goldeen", "Golduck", "Golem", "Gorebyss", "Graveler", "Grimer", "Grovyle", "Grumpig", "Gulpin", "Gyarados", "Hariyama", "Heracross", "Horsea", "Huntail", "Igglybuff", "Illumise", "Jigglypuff", "Kadabra", "Kecleon", "Kingdra", "Kirlia", "Koffing", "Lairon", "Lanturn", "Latias", "Latios", "Lileep", "Linoone", "Lombre", "Lotad", "Loudred", "Ludicolo", "Lunatone", "Luvdisc", "Machamp", "Machoke", "Machop", "Magcargo", "Magikarp", "Magnemite", "Magneton", "Magnezone", "Makuhita", "Manectric", "Marill", "Marshtomp", "Masquerain", "Mawile", "Medicham", "Meditite", "Metagross", "Metang", "Mightyena", "Milotic", "Minun", "Mudkip", "Muk", "Natu", "Nincada", "Ninetales", "Ninjask", "Nosepass", "Numel", "Nuzleaf", "Oddish", "Pelipper", "Phanpy", "Pichu", "Pikachu", "Pinsir", "Plusle", "Poochyena", "Probopass", "Psyduck", "Raichu", "Ralts", "Regice", "Regirock", "Registeel", "Relicanth", "Rhydon", "Rhyhorn", "Rhyperior", "Roselia", "Roserade", "Sableye", "Salamence", "Sandshrew", "Sandslash", "Sceptile", "Seadra", "Seaking", "Sealeo", "Seedot", "Seviper", "Sharpedo", "Shedinja", "Shelgon", "Shiftry", "Shroomish", "Shuppet", "Silcoon", "Skarmory", "Skitty", "Slaking", "Slakoth", "Slugma", "Snorunt", "Solrock", "Spheal", "Spinda", "Spoink", "Starmie", "Staryu", "Surskit", "Swablu", "Swalot", "Swampert", "Swellow", "Taillow", "Tentacool", "Tentacruel", "Torchic", "Torkoal", "Trapinch", "Treecko", "Tropius", "Vibrava", "Vigoroth", "Vileplume", "Volbeat", "Voltorb", "Vulpix", "Wailmer", "Wailord", "Walrein", "Weezing", "Whiscash", "Whismur", "Wigglytuff", "Wingull", "Wobbuffet", "Wurmple", "Wynaut", "Xatu", "Zangoose", "Zigzagoon", "Zubat", ]; - let template = this.getTemplate(set.species || set.name); - if (!hoennDex.includes(template.baseSpecies) && !this.getRuleTable(format).has('+' + template.speciesid)) { + let template = this.dex.getTemplate(set.species || set.name); + if (!hoennDex.includes(template.baseSpecies) && !this.ruleTable.has('+' + template.speciesid)) { return [template.baseSpecies + " is not in the Hoenn Pokédex."]; } }, @@ -186,8 +186,8 @@ let BattleFormats = { let sinnohDex = [ "Turtwig", "Grotle", "Torterra", "Chimchar", "Monferno", "Infernape", "Piplup", "Prinplup", "Empoleon", "Starly", "Staravia", "Staraptor", "Bidoof", "Bibarel", "Kricketot", "Kricketune", "Shinx", "Luxio", "Luxray", "Abra", "Kadabra", "Alakazam", "Magikarp", "Gyarados", "Budew", "Roselia", "Roserade", "Zubat", "Golbat", "Crobat", "Geodude", "Graveler", "Golem", "Onix", "Steelix", "Cranidos", "Rampardos", "Shieldon", "Bastiodon", "Machop", "Machoke", "Machamp", "Psyduck", "Golduck", "Burmy", "Wormadam", "Mothim", "Wurmple", "Silcoon", "Beautifly", "Cascoon", "Dustox", "Combee", "Vespiquen", "Pachirisu", "Buizel", "Floatzel", "Cherubi", "Cherrim", "Shellos", "Gastrodon", "Heracross", "Aipom", "Ambipom", "Drifloon", "Drifblim", "Buneary", "Lopunny", "Gastly", "Haunter", "Gengar", "Misdreavus", "Mismagius", "Murkrow", "Honchkrow", "Glameow", "Purugly", "Goldeen", "Seaking", "Barboach", "Whiscash", "Chingling", "Chimecho", "Stunky", "Skuntank", "Meditite", "Medicham", "Bronzor", "Bronzong", "Ponyta", "Rapidash", "Bonsly", "Sudowoodo", "Mime Jr.", "Mr. Mime", "Happiny", "Chansey", "Blissey", "Cleffa", "Clefairy", "Clefable", "Chatot", "Pichu", "Pikachu", "Raichu", "Hoothoot", "Noctowl", "Spiritomb", "Gible", "Gabite", "Garchomp", "Munchlax", "Snorlax", "Unown", "Riolu", "Lucario", "Wooper", "Quagsire", "Wingull", "Pelipper", "Girafarig", "Hippopotas", "Hippowdon", "Azurill", "Marill", "Azumarill", "Skorupi", "Drapion", "Croagunk", "Toxicroak", "Carnivine", "Remoraid", "Octillery", "Finneon", "Lumineon", "Tentacool", "Tentacruel", "Feebas", "Milotic", "Mantyke", "Mantine", "Snover", "Abomasnow", "Sneasel", "Weavile", "Uxie", "Mesprit", "Azelf", "Dialga", "Palkia", "Manaphy", "Rotom", "Gligar", "Gliscor", "Nosepass", "Probopass", "Ralts", "Kirlia", "Gardevoir", "Gallade", "Lickitung", "Lickilicky", "Eevee", "Vaporeon", "Jolteon", "Flareon", "Espeon", "Umbreon", "Leafeon", "Glaceon", "Swablu", "Altaria", "Togepi", "Togetic", "Togekiss", "Houndour", "Houndoom", "Magnemite", "Magneton", "Magnezone", "Tangela", "Tangrowth", "Yanma", "Yanmega", "Tropius", "Rhyhorn", "Rhydon", "Rhyperior", "Duskull", "Dusclops", "Dusknoir", "Porygon", "Porygon2", "Porygon-Z", "Scyther", "Scizor", "Elekid", "Electabuzz", "Electivire", "Magby", "Magmar", "Magmortar", "Swinub", "Piloswine", "Mamoswine", "Snorunt", "Glalie", "Froslass", "Absol", "Giratina", ]; - let template = this.getTemplate(set.species || set.name); - if ((!sinnohDex.includes(template.baseSpecies) || template.gen > 4) && !this.getRuleTable(format).has('+' + template.speciesid)) { + let template = this.dex.getTemplate(set.species || set.name); + if ((!sinnohDex.includes(template.baseSpecies) || template.gen > 4) && !this.ruleTable.has('+' + template.speciesid)) { return [`${template.species} is not in the Sinnoh Pokédex.`]; } }, @@ -202,8 +202,8 @@ let BattleFormats = { "Drifloon", "Drifblim", "Mienfoo", "Mienshao", "Zangoose", "Seviper", "Spoink", "Grumpig", "Absol", "Inkay", "Malamar", "Lunatone", "Solrock", "Bagon", "Shelgon", "Salamence", "Wingull", "Pelipper", "Taillow", "Swellow", "Binacle", "Barbaracle", "Dwebble", "Crustle", "Tentacool", "Tentacruel", "Wailmer", "Wailord", "Luvdisc", "Skrelp", "Dragalge", "Clauncher", "Clawitzer", "Staryu", "Starmie", "Shellder", "Cloyster", "Qwilfish", "Horsea", "Seadra", "Kingdra", "Relicanth", "Sandile", "Krokorok", "Krookodile", "Helioptile", "Heliolisk", "Hippopotas", "Hippowdon", "Rhyhorn", "Rhydon", "Rhyperior", "Onix", "Steelix", "Woobat", "Swoobat", "Machop", "Machoke", "Machamp", "Cubone", "Marowak", "Kangaskhan", "Mawile", "Tyrunt", "Tyrantrum", "Amaura", "Aurorus", "Aerodactyl", "Ferroseed", "Ferrothorn", "Snubbull", "Granbull", "Electrike", "Manectric", "Houndour", "Houndoom", "Eevee", "Vaporeon", "Jolteon", "Flareon", "Espeon", "Umbreon", "Leafeon", "Glaceon", "Sylveon", "Emolga", "Yanma", "Yanmega", "Hawlucha", "Sigilyph", "Golett", "Golurk", "Nosepass", "Probopass", "Makuhita", "Hariyama", "Throh", "Sawk", "Starly", "Staravia", "Staraptor", "Stunky", "Skuntank", "Nidoran-F", "Nidorina", "Nidoqueen", "Nidoran-M", "Nidorino", "Nidoking", "Dedenne", "Chingling", "Chimecho", "Mime Jr.", "Mr. Mime", "Solosis", "Duosion", "Reuniclus", "Wynaut", "Wobbuffet", "Roggenrola", "Boldore", "Gigalith", "Sableye", "Carbink", "Tauros", "Miltank", "Mareep", "Flaaffy", "Ampharos", "Pinsir", "Heracross", "Pachirisu", "Slowpoke", "Slowbro", "Slowking", "Exeggcute", "Exeggutor", "Chatot", "Mantyke", "Mantine", "Clamperl", "Huntail", "Gorebyss", "Remoraid", "Octillery", "Corsola", "Chinchou", "Lanturn", "Alomomola", "Lapras", "Articuno", "Zapdos", "Moltres", "Diglett", "Dugtrio", "Trapinch", "Vibrava", "Flygon", "Gible", "Gabite", "Garchomp", "Geodude", "Graveler", "Golem", "Slugma", "Magcargo", "Shuckle", "Skorupi", "Drapion", "Wooper", "Quagsire", "Goomy", "Sliggoo", "Goodra", "Karrablast", "Escavalier", "Shelmet", "Accelgor", "Bellsprout", "Weepinbell", "Victreebel", "Carnivine", "Gastly", "Haunter", "Gengar", "Poliwag", "Poliwhirl", "Poliwrath", "Politoed", "Ekans", "Arbok", "Stunfisk", "Barboach", "Whiscash", "Purrloin", "Liepard", "Poochyena", "Mightyena", "Patrat", "Watchog", "Pawniard", "Bisharp", "Klefki", "Murkrow", "Honchkrow", "Foongus", "Amoonguss", "Lotad", "Lombre", "Ludicolo", "Buizel", "Floatzel", "Basculin", "Phantump", "Trevenant", "Pumpkaboo", "Gourgeist", "Litwick", "Lampent", "Chandelure", "Rotom", "Magnemite", "Magneton", "Magnezone", "Voltorb", "Electrode", "Trubbish", "Garbodor", "Swinub", "Piloswine", "Mamoswine", "Bergmite", "Avalugg", "Cubchoo", "Beartic", "Smoochum", "Jynx", "Vanillite", "Vanillish", "Vanilluxe", "Snover", "Abomasnow", "Delibird", "Sneasel", "Weavile", "Timburr", "Gurdurr", "Conkeldurr", "Torkoal", "Sandshrew", "Sandslash", "Aron", "Lairon", "Aggron", "Larvitar", "Pupitar", "Tyranitar", "Heatmor", "Durant", "Spinarak", "Ariados", "Spearow", "Fearow", "Cryogonal", "Skarmory", "Noibat", "Noivern", "Gligar", "Gliscor", "Hoothoot", "Noctowl", "Igglybuff", "Jigglypuff", "Wigglytuff", "Shuppet", "Banette", "Zorua", "Zoroark", "Gothita", "Gothorita", "Gothitelle", "Bonsly", "Sudowoodo", "Spinda", "Teddiursa", "Ursaring", "Lickitung", "Lickilicky", "Scyther", "Scizor", "Ditto", "Swablu", "Altaria", "Druddigon", "Deino", "Zweilous", "Hydreigon", "Dratini", "Dragonair", "Dragonite", "Xerneas", "Yveltal", "Zygarde", "Mewtwo", ]; - let template = this.getTemplate(set.species || set.name); - if ((!kalosDex.includes(template.baseSpecies) || template.gen > 6) && !this.getRuleTable(format).has('+' + template.speciesid)) { + let template = this.dex.getTemplate(set.species || set.name); + if ((!kalosDex.includes(template.baseSpecies) || template.gen > 6) && !this.ruleTable.has('+' + template.speciesid)) { return [`${template.species} is not in the Kalos Pokédex.`]; } }, @@ -216,8 +216,8 @@ let BattleFormats = { let alolaDex = [ "Rowlet", "Dartrix", "Decidueye", "Litten", "Torracat", "Incineroar", "Popplio", "Brionne", "Primarina", "Pikipek", "Trumbeak", "Toucannon", "Yungoos", "Gumshoos", "Rattata-Alola", "Raticate-Alola", "Caterpie", "Metapod", "Butterfree", "Ledyba", "Ledian", "Spinarak", "Ariados", "Buneary", "Lopunny", "Inkay", "Malamar", "Zorua", "Zoroark", "Furfrou", "Pichu", "Pikachu", "Raichu-Alola", "Grubbin", "Charjabug", "Vikavolt", "Bonsly", "Sudowoodo", "Happiny", "Chansey", "Blissey", "Munchlax", "Snorlax", "Slowpoke", "Slowbro", "Slowking", "Wingull", "Pelipper", "Abra", "Kadabra", "Alakazam", "Meowth-Alola", "Persian-Alola", "Magnemite", "Magneton", "Magnezone", "Grimer-Alola", "Muk-Alola", "Mime Jr.", "Mr. Mime", "Ekans", "Arbok", "Dunsparce", "Growlithe", "Arcanine", "Drowzee", "Hypno", "Makuhita", "Hariyama", "Smeargle", "Crabrawler", "Crabominable", "Gastly", "Haunter", "Gengar", "Drifloon", "Drifblim", "Murkrow", "Honchkrow", "Zubat", "Golbat", "Crobat", "Noibat", "Noivern", "Diglett-Alola", "Dugtrio-Alola", "Spearow", "Fearow", "Rufflet", "Braviary", "Vullaby", "Mandibuzz", "Mankey", "Primeape", "Delibird", "Hawlucha", "Oricorio", "Cutiefly", "Ribombee", "Flabe\u0301be\u0301", "Floette", "Florges", "Petilil", "Lilligant", "Cottonee", "Whimsicott", "Psyduck", "Golduck", "Smoochum", "Jynx", "Magikarp", "Gyarados", "Barboach", "Whiscash", "Seal", "Dewgong", "Machop", "Machoke", "Machamp", "Roggenrola", "Boldore", "Gigalith", "Carbink", "Sableye", "Mawile", "Rockruff", "Lycanroc", "Spinda", "Tentacool", "Tentacruel", "Finneon", "Lumineon", "Wishiwashi", "Luvdisc", "Corsola", "Mareanie", "Toxapex", "Shellder", "Cloyster", "Clamperl", "Huntail", "Gorebyss", "Remoraid", "Octillery", "Mantyke", "Mantine", "Bagon", "Shelgon", "Salamence", "Lillipup", "Herdier", "Stoutland", "Eevee", "Vaporeon", "Jolteon", "Flareon", "Espeon", "Umbreon", "Leafeon", "Glaceon", "Sylveon", "Mareep", "Flaaffy", "Ampharos", "Mudbray", "Mudsdale", "Igglybuff", "Jigglypuff", "Wigglytuff", "Tauros", "Miltank", "Surskit", "Masquerain", "Dewpider", "Araquanid", "Fomantis", "Lurantis", "Morelull", "Shiinotic", "Paras", "Parasect", "Poliwag", "Poliwhirl", "Poliwrath", "Politoed", "Goldeen", "Seaking", "Basculin", "Feebas", "Milotic", "Alomomola", "Fletchling", "Fletchinder", "Talonflame", "Salandit", "Salazzle", "Cubone", "Marowak-Alola", "Kangaskhan", "Magby", "Magmar", "Magmortar", "Larvesta", "Volcarona", "Stufful", "Bewear", "Bounsweet", "Steenee", "Tsareena", "Comfey", "Pinsir", "Hoothoot", "Noctowl", "Kecleon", "Oranguru", "Passimian", "Goomy", "Sliggoo", "Goodra", "Castform", "Wimpod", "Golisopod", "Staryu", "Starmie", "Sandygast", "Palossand", "Omanyte", "Omastar", "Kabuto", "Kabutops", "Lileep", "Cradily", "Anorith", "Armaldo", "Cranidos", "Rampardos", "Shieldon", "Bastiodon", "Tirtouga", "Carracosta", "Archen", "Archeops", "Tyrunt", "Tyrantrum", "Amaura", "Aurorus", "Pupitar", "Larvitar", "Tyranitar", "Phantump", "Trevenant", "Natu", "Xatu", "Nosepass", "Probopass", "Pyukumuku", "Chinchou", "Lanturn", "Type: Null", "Silvally", "Poipole", "Naganadel", "Zygarde", "Trubbish", "Garbodor", "Minccino", "Cinccino", "Pineco", "Forretress", "Skarmory", "Ditto", "Cleffa", "Clefairy", "Clefable", "Elgyem", "Beheeyem", "Minior", "Beldum", "Metang", "Metagross", "Porygon", "Porygon2", "Porygon-Z", "Pancham", "Pangoro", "Komala", "Torkoal", "Turtonator", "Houndour", "Houndoom", "Dedenne", "Togedemaru", "Electrike", "Manectric", "Elekid", "Electabuzz", "Electivire", "Geodude-Alola", "Graveler-Alola", "Golem-Alola", "Sandile", "Krokorok", "Krookodile", "Trapinch", "Vibrava", "Flygon", "Gible", "Gabite", "Garchomp", "Baltoy", "Claydol", "Golett", "Golurk", "Klefki", "Mimikyu", "Shuppet", "Banette", "Frillish", "Jellicent", "Bruxish", "Drampa", "Absol", "Snorunt", "Glalie", "Froslass", "Sneasel", "Weavile", "Sandshrew-Alola", "Sandslash-Alola", "Vulpix-Alola", "Ninetales-Alola", "Vanillite", "Vanillish", "Vanilluxe", "Scraggy", "Scrafty", "Pawniard", "Bisharp", "Snubbull", "Granbull", "Shellos", "Gastrodon", "Relicanth", "Dhelmise", "Carvanha", "Sharpedo", "Skrelp", "Dragalge", "Clauncher", "Clawitzer", "Wailmer", "Wailord", "Lapras", "Tropius", "Exeggcute", "Exeggutor-Alola", "Corphish", "Crawdaunt", "Mienfoo", "Mienshao", "Jangmo-o", "Hakamo-o", "Kommo-o", "Emolga", "Scyther", "Scizor", "Heracross", "Aipom", "Ampibom", "Litleo", "Pyroar", "Misdreavus", "Mismagius", "Druddigon", "Lickitung", "Lickilicky", "Riolu", "Lucario", "Dratini", "Dragonair", "Dragonite", "Aerodactyl", "Tapu Koko", "Tapu Lele", "Tapu Bulu", "Tapu Fini", "Cosmog", "Cosmoem", "Solgaleo", "Lunala", "Nihilego", "Stakataka", "Blacephalon", "Buzzwole", "Pheromosa", "Xurkitree", "Celesteela", "Kartana", "Guzzlord", "Necrozma", "Magearna", "Marshadow", "Zeraora", ]; - let template = this.getTemplate(set.species || set.name); - if (!alolaDex.includes(template.baseSpecies) && !alolaDex.includes(template.species) && !this.getRuleTable(format).has('+' + template.speciesid)) { + let template = this.dex.getTemplate(set.species || set.name); + if (!alolaDex.includes(template.baseSpecies) && !alolaDex.includes(template.species) && !this.ruleTable.has('+' + template.speciesid)) { return [`${template.baseSpecies} is not in the Alola Pokédex.`]; } }, @@ -227,7 +227,7 @@ let BattleFormats = { name: 'PotD', onBegin() { if (global.Config && global.Config.potd) { - this.add('rule', "Pokemon of the Day: " + this.getTemplate(Config.potd).name); + this.add('rule', "Pokemon of the Day: " + this.dex.getTemplate(Config.potd).name); } }, }, @@ -251,11 +251,11 @@ let BattleFormats = { name: 'Little Cup', desc: "Only allows Pokémon that can evolve and don't have any prior evolutions", onValidateSet(set) { - let template = this.getTemplate(set.species || set.name); - if (template.prevo && this.getTemplate(template.prevo).gen <= this.gen) { + let template = this.dex.getTemplate(set.species || set.name); + if (template.prevo && this.dex.getTemplate(template.prevo).gen <= this.gen) { return [set.species + " isn't the first in its evolution family."]; } - let futureGenEvo = template.evos && this.getTemplate(template.evos[0]).gen > this.gen; + let futureGenEvo = template.evos && this.dex.getTemplate(template.evos[0]).gen > this.gen; if (!template.nfe || futureGenEvo) { return [set.species + " doesn't have an evolution family."]; } @@ -289,7 +289,7 @@ let BattleFormats = { /**@type {{[k: string]: true}} */ let speciesTable = {}; for (const set of team) { - let template = this.getTemplate(set.species); + let template = this.dex.getTemplate(set.species); if (speciesTable[template.num]) { return ["You are limited to one of each Pokémon by Species Clause.", "(You have more than one " + template.baseSpecies + ")"]; } @@ -307,7 +307,7 @@ let BattleFormats = { for (const set of team) { let name = set.name; if (name) { - if (name === this.getTemplate(set.species).baseSpecies) continue; + if (name === this.dex.getTemplate(set.species).baseSpecies) continue; if (nameTable[name]) { return ["Your Pokémon must have different nicknames.", "(You have more than one " + name + ")"]; } @@ -332,7 +332,7 @@ let BattleFormats = { let item = toID(set.item); if (!item) continue; if (itemTable[item]) { - return ["You are limited to one of each item by Item Clause.", "(You have more than one " + this.getItem(item).name + ")"]; + return ["You are limited to one of each item by Item Clause.", "(You have more than one " + this.dex.getItem(item).name + ")"]; } itemTable[item] = true; } @@ -370,7 +370,7 @@ let BattleFormats = { if (ability in base) ability = /** @type {ID} */(base[ability]); if (ability in abilityTable) { if (abilityTable[ability] >= 2) { - return ["You are limited to two of each ability by the Ability Clause.", `(You have more than two ${this.getAbility(ability).name} variants)`]; + return ["You are limited to two of each ability by the Ability Clause.", `(You have more than two ${this.dex.getAbility(ability).name} variants)`]; } abilityTable[ability]++; } else { @@ -390,7 +390,7 @@ let BattleFormats = { let problems = []; if (set.moves) { for (const moveId of set.moves) { - let move = this.getMove(moveId); + let move = this.dex.getMove(moveId); if (move.ohko) problems.push(move.name + ' is banned by OHKO Clause.'); } } @@ -462,7 +462,7 @@ let BattleFormats = { onValidateSet(set, format, setHas) { if (!('move:batonpass' in setHas)) return; - let item = this.getItem(set.item); + let item = this.dex.getItem(set.item); let ability = toID(set.ability); /**@type {boolean | string} */ let speedBoosted = false; @@ -470,7 +470,7 @@ let BattleFormats = { let nonSpeedBoosted = false; for (const moveId of set.moves) { - let move = this.getMove(moveId); + let move = this.dex.getMove(moveId); if (move.id === 'flamecharge' || (move.boosts && move.boosts.spe && move.boosts.spe > 0)) { speedBoosted = true; } @@ -528,7 +528,7 @@ let BattleFormats = { name: 'Z-Move Clause', desc: "Bans Pokémon from holding Z-Crystals", onValidateSet(set) { - const item = this.getItem(set.item); + const item = this.dex.getItem(set.item); if (item.zMove) return [`${set.name || set.species}'s item ${item.name} is banned by Z-Move Clause.`]; }, onBegin() { @@ -625,7 +625,7 @@ let BattleFormats = { /**@type {string[]} */ let typeTable; for (const [i, set] of team.entries()) { - let template = this.getTemplate(set.species); + let template = this.dex.getTemplate(set.species); if (!template.types) return [`Invalid pokemon ${set.name || set.species}`]; if (i === 0) { typeTable = template.types; @@ -634,13 +634,13 @@ let BattleFormats = { typeTable = typeTable.filter(type => template.types.includes(type)); } if (this.gen >= 7) { - let item = this.getItem(set.item); + let item = this.dex.getItem(set.item); if (item.megaStone && template.species === item.megaEvolves) { - template = this.getTemplate(item.megaStone); + template = this.dex.getTemplate(item.megaStone); typeTable = typeTable.filter(type => template.types.includes(type)); } if (item.id === "ultranecroziumz" && template.baseSpecies === "Necrozma") { - template = this.getTemplate("Necrozma-Ultra"); + template = this.dex.getTemplate("Necrozma-Ultra"); typeTable = typeTable.filter(type => template.types.includes(type)); } } @@ -664,7 +664,7 @@ let BattleFormats = { name: 'Arceus EV Clause', desc: "Restricts Arceus to a maximum of 100 EVs in any one stat", onValidateSet(set, format) { - let template = this.getTemplate(set.species); + let template = this.dex.getTemplate(set.species); if (template.num === 493 && set.evs) { for (let stat in set.evs) { // @ts-ignore @@ -684,7 +684,7 @@ let BattleFormats = { onEffectiveness(typeMod, target, type, move) { // The effectiveness of Freeze Dry on Water isn't reverted if (move && move.id === 'freezedry' && type === 'Water') return; - if (move && !this.getImmunity(move, type)) return 1; + if (move && !this.dex.getImmunity(move, type)) return 1; return -typeMod; }, }, diff --git a/data/scripts.js b/data/scripts.js index cb956e6554..b4690e4a5e 100644 --- a/data/scripts.js +++ b/data/scripts.js @@ -18,12 +18,12 @@ let BattleScripts = { */ runMove(moveOrMoveName, pokemon, targetLoc, sourceEffect, zMove, externalMove) { let target = this.getTarget(pokemon, zMove || moveOrMoveName, targetLoc); - let baseMove = this.getActiveMove(moveOrMoveName); + let baseMove = this.dex.getActiveMove(moveOrMoveName); const pranksterBoosted = baseMove.pranksterBoosted; if (baseMove.id !== 'struggle' && !zMove && !externalMove) { let changedMove = this.runEvent('OverrideAction', pokemon, target, baseMove); if (changedMove && changedMove !== true) { - baseMove = this.getActiveMove(changedMove); + baseMove = this.dex.getActiveMove(changedMove); if (pranksterBoosted) baseMove.pranksterBoosted = pranksterBoosted; target = this.resolveTarget(pokemon, baseMove); } @@ -74,7 +74,7 @@ let BattleScripts = { return; } } else { - sourceEffect = this.getEffect('lockedmove'); + sourceEffect = this.dex.getEffect('lockedmove'); } pokemon.moveUsed(move, targetLoc); } @@ -85,7 +85,7 @@ let BattleScripts = { if (zMove) { if (pokemon.illusion) { - this.singleEvent('End', this.getAbility('Illusion'), pokemon.abilityData, pokemon); + this.singleEvent('End', this.dex.getAbility('Illusion'), pokemon.abilityData, pokemon); } this.add('-zpower', pokemon); pokemon.side.zMoveUsed = true; @@ -117,7 +117,7 @@ let BattleScripts = { // @ts-ignore - the Dancer ability can't trigger on a move where target is null because it does not copy failed moves. const dancersTarget = target.side !== dancer.side && pokemon.side === dancer.side ? target : pokemon; // @ts-ignore - this.runMove(move.id, dancer, this.getTargetLoc(dancersTarget, dancer), this.getAbility('dancer'), undefined, true); + this.runMove(move.id, dancer, this.getTargetLoc(dancersTarget, dancer), this.dex.getAbility('dancer'), undefined, true); // Using a Dancer move is enough to spoil Fake Out etc. dancer.activeTurns++; } @@ -146,7 +146,7 @@ let BattleScripts = { if (!sourceEffect && this.effect.id) sourceEffect = this.effect; if (sourceEffect && ['instruct', 'custapberry'].includes(sourceEffect.id)) sourceEffect = null; - let move = this.getActiveMove(moveOrMoveName); + let move = this.dex.getActiveMove(moveOrMoveName); if (move.id === 'weatherball' && zMove) { // Z-Weather Ball only changes types if it's used directly, // not if it's called by Z-Sleep Talk or something. @@ -194,7 +194,7 @@ let BattleScripts = { let movename = move.name; if (move.id === 'hiddenpower') movename = 'Hidden Power'; - if (sourceEffect) attrs += '|[from]' + this.getEffect(sourceEffect); + if (sourceEffect) attrs += '|[from]' + this.dex.getEffect(sourceEffect); if (zMove && move.isZ === true) { attrs = '|[anim]' + movename + attrs; movename = 'Z-' + movename; @@ -400,7 +400,7 @@ let BattleScripts = { return hitResults; } for (let [i, target] of targets.entries()) { - if (target !== pokemon && !this.getImmunity('powder', target)) { + if (target !== pokemon && !this.dex.getImmunity('powder', target)) { this.debug('natural powder immunity'); this.add('-immune', target); hitResults[i] = false; @@ -419,7 +419,7 @@ let BattleScripts = { return hitResults; } for (let [i, target] of targets.entries()) { - if (targets[i].side !== pokemon.side && !this.getImmunity('prankster', target)) { + if (targets[i].side !== pokemon.side && !this.dex.getImmunity('prankster', target)) { this.debug('natural prankster immunity'); if (!target.illusion) this.hint("In gen 7, Dark is immune to Prankster moves."); this.add('-immune', target); @@ -457,7 +457,7 @@ let BattleScripts = { if (accuracy !== true) { if (!move.ignoreAccuracy) { boosts = this.runEvent('ModifyBoost', pokemon, null, null, Object.assign({}, pokemon.boosts)); - boost = this.clampIntRange(boosts['accuracy'], -6, 6); + boost = this.dex.clampIntRange(boosts['accuracy'], -6, 6); if (boost > 0) { accuracy *= boostTable[boost]; } else { @@ -466,7 +466,7 @@ let BattleScripts = { } if (!move.ignoreEvasion) { boosts = this.runEvent('ModifyBoost', target, null, null, Object.assign({}, target.boosts)); - boost = this.clampIntRange(boosts['evasion'], -6, 6); + boost = this.dex.clampIntRange(boosts['evasion'], -6, 6); if (boost > 0) { accuracy /= boostTable[boost]; } else if (boost < 0) { @@ -606,7 +606,7 @@ let BattleScripts = { /** @type {(number | boolean | undefined)[]} */ let moveDamage; // There is no need to recursively check the ´sleepUsable´ flag as Sleep Talk can only be used while asleep. - let isSleepUsable = move.sleepUsable || this.getMove(move.sourceEffect).sleepUsable; + let isSleepUsable = move.sleepUsable || this.dex.getMove(move.sourceEffect).sleepUsable; /** @type {(Pokemon | false | null)[]} */ let targetsCopy = targets.slice(0); @@ -626,7 +626,7 @@ let BattleScripts = { if (accuracy !== true) { if (!move.ignoreAccuracy) { const boosts = this.runEvent('ModifyBoost', pokemon, null, null, Object.assign({}, pokemon.boosts)); - const boost = this.clampIntRange(boosts['accuracy'], -6, 6); + const boost = this.dex.clampIntRange(boosts['accuracy'], -6, 6); if (boost > 0) { accuracy *= boostTable[boost]; } else { @@ -635,7 +635,7 @@ let BattleScripts = { } if (!move.ignoreEvasion) { const boosts = this.runEvent('ModifyBoost', target, null, null, Object.assign({}, target.boosts)); - const boost = this.clampIntRange(boosts['evasion'], -6, 6); + const boost = this.dex.clampIntRange(boosts['evasion'], -6, 6); if (boost > 0) { accuracy /= boostTable[boost]; } else if (boost < 0) { @@ -668,7 +668,7 @@ let BattleScripts = { move.totalDamage += damage[i]; } if (move.mindBlownRecoil) { - this.damage(Math.round(pokemon.maxhp / 2), pokemon, pokemon, this.getEffect('Mind Blown'), true); + this.damage(Math.round(pokemon.maxhp / 2), pokemon, pokemon, this.dex.getEffect('Mind Blown'), true); move.mindBlownRecoil = false; } this.eachEvent('Update'); @@ -688,7 +688,7 @@ let BattleScripts = { if (move.struggleRecoil) { // @ts-ignore - this.directDamage(this.clampIntRange(Math.round(pokemon.maxhp / 4), 1), pokemon, pokemon, {id: 'strugglerecoil'}); + this.directDamage(this.dex.clampIntRange(Math.round(pokemon.maxhp / 4), 1), pokemon, pokemon, {id: 'strugglerecoil'}); } for (let i = 0; i < targetsCopy.length; i++) { @@ -717,7 +717,7 @@ let BattleScripts = { /** @type {(number | boolean | undefined)[]} */ let damage = []; for (let i = 0; i < targets.length; i++) damage[i] = true; - const move = this.getActiveMove(moveOrMoveName); + const move = this.dex.getActiveMove(moveOrMoveName); /** @type {?boolean | number} */ let hitResult = true; if (!moveData) moveData = move; @@ -1024,7 +1024,7 @@ let BattleScripts = { calcRecoilDamage(damageDealt, move) { // @ts-ignore - return this.clampIntRange(Math.round(damageDealt * move.recoil[0] / move.recoil[1]), 1); + return this.dex.clampIntRange(Math.round(damageDealt * move.recoil[0] / move.recoil[1]), 1); }, zMoveTable: { @@ -1076,19 +1076,19 @@ let BattleScripts = { let item = pokemon.getItem(); if (move.name === item.zMoveFrom) { // @ts-ignore - let zMove = this.getActiveMove(item.zMove); + let zMove = this.dex.getActiveMove(item.zMove); zMove.isZPowered = true; return zMove; } } if (move.category === 'Status') { - let zMove = this.getActiveMove(move); + let zMove = this.dex.getActiveMove(move); zMove.isZ = true; zMove.isZPowered = true; return zMove; } - let zMove = this.getActiveMove(this.zMoveTable[move.type]); + let zMove = this.dex.getActiveMove(this.zMoveTable[move.type]); // @ts-ignore zMove.basePower = move.zMovePower; zMove.category = move.category; @@ -1115,10 +1115,10 @@ let BattleScripts = { if (!moveSlot.disabled) { mustStruggle = false; } - let move = this.getMove(moveSlot.move); + let move = this.dex.getMove(moveSlot.move); let zMoveName = this.getZMove(move, pokemon, true) || ''; if (zMoveName) { - let zMove = this.getMove(zMoveName); + let zMove = this.dex.getMove(zMoveName); if (!zMove.isZ && zMove.category === 'Status') zMoveName = "Z-" + zMoveName; zMoves.push({move: zMoveName, target: zMove.target}); } else { @@ -1130,7 +1130,7 @@ let BattleScripts = { }, canMegaEvo(pokemon) { - let altForme = pokemon.baseTemplate.otherFormes && this.getTemplate(pokemon.baseTemplate.otherFormes[0]); + let altForme = pokemon.baseTemplate.otherFormes && this.dex.getTemplate(pokemon.baseTemplate.otherFormes[0]); let item = pokemon.getItem(); if (altForme && altForme.isMega && altForme.requiredMove && pokemon.baseMoves.includes(toID(altForme.requiredMove)) && !item.zMove) return altForme.species; if (item.megaEvolves !== pokemon.baseTemplate.baseSpecies || item.megaStone === pokemon.species) { @@ -1176,7 +1176,7 @@ let BattleScripts = { }, runZPower(move, pokemon) { - const zPower = this.getEffect('zpower'); + const zPower = this.dex.getEffect('zpower'); if (move.category !== 'Status') { this.attrLastMove('[zeffect]'); } else if (move.zMoveBoost) { diff --git a/data/statuses.js b/data/statuses.js index c8bc09cbb6..a4ecd1dc5d 100644 --- a/data/statuses.js +++ b/data/statuses.js @@ -158,7 +158,7 @@ let BattleStatuses = { if (this.effectData.stage < 15) { this.effectData.stage++; } - this.damage(this.clampIntRange(pokemon.maxhp / 16, 1) * this.effectData.stage); + this.damage(this.dex.clampIntRange(pokemon.maxhp / 16, 1) * this.effectData.stage); }, }, confusion: { @@ -379,7 +379,7 @@ let BattleStatuses = { onEnd(target) { const data = this.effectData; // time's up; time to hit! :D - const move = this.getMove(data.move); + const move = this.dex.getMove(data.move); if (target.fainted || target === data.source) { this.hint(`${move.name} did not hit because the target is ${(data.fainted ? 'fainted' : 'the user')}.`); return; @@ -398,7 +398,7 @@ let BattleStatuses = { if (data.source.hasAbility('adaptability') && this.gen >= 6) { data.moveData.stab = 2; } - const hitMove = new this.Data.Move(data.moveData); + const hitMove = new this.dex.Data.Move(data.moveData); this.trySpreadMoveHit([target], data.source, /** @type {ActiveMove} */(/** @type {unknown} */(hitMove))); }, diff --git a/sim/battle.ts b/sim/battle.ts index 6338379697..1d0f648fe4 100644 --- a/sim/battle.ts +++ b/sim/battle.ts @@ -47,18 +47,20 @@ type Part = string | number | boolean | AnyObject | null | undefined; // An individual Side's request state is encapsulated in its `activeRequest` field. export type RequestState = 'teampreview' | 'move' | 'switch' | ''; -export class Battle extends Dex.ModdedDex { +export class Battle { readonly id: ID; readonly debugMode: boolean; readonly deserialized: boolean; readonly strictChoices: boolean; - readonly format: string; + readonly format: Format; readonly formatData: AnyObject; - readonly cachedFormat: Format; readonly gameType: GameType; readonly field: Field; readonly sides: [Side, Side] | [Side, Side, Side, Side]; readonly prngSeed: PRNGSeed; + dex: ModdedDex; + gen: number; + ruleTable: Data.RuleTable; prng: PRNG; rated: boolean | string; reportExactHP: boolean; @@ -110,21 +112,24 @@ export class Battle extends Dex.ModdedDex { readonly send: (type: string, data: string | string[]) => void; + trunc: (num: number, bits?: number) => number; + constructor(options: BattleOptions) { const format = Dex.getFormat(options.formatid, true); - super(format.mod); + this.format = format; + this.dex = Dex.forFormat(format); + this.gen = this.dex.gen; + this.ruleTable = this.dex.getRuleTable(format); this.zMoveTable = {}; - Object.assign(this, this.data.Scripts); + Object.assign(this, this.dex.data.Scripts); if (format.battle) Object.assign(this, format.battle); this.id = ''; this.debugMode = format.debug || !!options.debug; this.deserialized = !!options.deserialized; this.strictChoices = !!options.strictChoices; - this.format = format.id; this.formatData = {id: format.id}; - this.cachedFormat = format; this.gameType = (format.gameType || 'singles'); this.field = new Field(this); const isFourPlayer = this.gameType === 'multi' || this.gameType === 'free-for-all'; @@ -179,6 +184,7 @@ export class Battle extends Dex.ModdedDex { this.SILENT_FAIL = null; this.send = options.send || (() => {}); + this.trunc = this.dex.trunc; // bound function for faster speedSort // (so speedSort doesn't need to bind before use) @@ -198,9 +204,9 @@ export class Battle extends Dex.ModdedDex { } this.inputLog.push(`>start ` + JSON.stringify(inputOptions)); - for (const rule of this.getRuleTable(format).keys()) { + for (const rule of this.ruleTable.keys()) { if (rule.startsWith('+') || rule.startsWith('-') || rule.startsWith('!')) continue; - const subFormat = this.getFormat(rule); + const subFormat = this.dex.getFormat(rule); if (subFormat.exists) { const hasEventHandler = Object.keys(subFormat).some(val => val.startsWith('on') && !['onBegin', 'onValidateTeam', 'onChangeSet', 'onValidateSet'].includes(val) @@ -252,10 +258,6 @@ export class Battle extends Dex.ModdedDex { this.prng = new PRNG(this.prng.startingSeed); } - getFormat(format?: string) { - return format ? super.getFormat(format, true) : this.cachedFormat; - } - suppressingAttackEvents() { return this.activePokemon && this.activePokemon.isActive && this.activeMove && this.activeMove.ignoreAbility; } @@ -862,7 +864,7 @@ export class Battle extends Dex.ModdedDex { const handlers: AnyObject[] = []; let callback; - const format = this.getFormat(); + const format = this.format; // @ts-ignore - dynamic lookup callback = format[callbackName]; // @ts-ignore - dynamic lookup @@ -1061,7 +1063,7 @@ export class Battle extends Dex.ModdedDex { } getMaxTeamSize() { - const teamLengthData = this.getFormat().teamLength; + const teamLengthData = this.format.teamLength; return (teamLengthData && teamLengthData.battle) || 6; } @@ -1272,7 +1274,7 @@ export class Battle extends Dex.ModdedDex { } this.runEvent('SwitchOut', oldActive); oldActive.illusion = null; - this.singleEvent('End', this.getAbility(oldActive.ability), oldActive.abilityData, oldActive); + this.singleEvent('End', this.dex.getAbility(oldActive.ability), oldActive.abilityData, oldActive); oldActive.isActive = false; oldActive.isStarted = false; oldActive.usedItemThisTurn = false; @@ -1381,7 +1383,7 @@ export class Battle extends Dex.ModdedDex { pokemon.trapped = pokemon.maybeTrapped = false; this.runEvent('TrapPokemon', pokemon); - if (!pokemon.knownType || this.getImmunity('trapped', pokemon)) { + if (!pokemon.knownType || this.dex.getImmunity('trapped', pokemon)) { this.runEvent('MaybeTrapPokemon', pokemon); } // canceling switches would leak information @@ -1398,17 +1400,17 @@ export class Battle extends Dex.ModdedDex { // to run it again. continue; } - const ruleTable = this.getRuleTable(this.getFormat()); - if ((ruleTable.has('+hackmons') || !ruleTable.has('obtainableabilities')) && !this.getFormat().team) { + const ruleTable = this.ruleTable; + if ((ruleTable.has('+hackmons') || !ruleTable.has('obtainableabilities')) && !this.format.team) { // hackmons format continue; } else if (abilitySlot === 'H' && template.unreleasedHidden) { // unreleased hidden ability continue; } - const ability = this.getAbility(abilityName); + const ability = this.dex.getAbility(abilityName); if (ruleTable.has('-ability:' + ability.id)) continue; - if (pokemon.knownType && !this.getImmunity('trapped', pokemon)) continue; + if (pokemon.knownType && !this.dex.getImmunity('trapped', pokemon)) continue; this.singleEvent('FoeMaybeTrapPokemon', ability, {}, pokemon, source); } } @@ -1448,7 +1450,7 @@ export class Battle extends Dex.ModdedDex { private maybeTriggerEndlessBattleClause( trappedBySide: boolean[], stalenessBySide: ('internal' | 'external' | undefined)[] ) { - if (!this.getRuleTable(this.getFormat()).has('endlessbattleclause')) return; + if (!this.ruleTable.has('endlessbattleclause')) return; if ((this.turn >= 500 && this.turn % 100 === 0) || (this.turn >= 900 && this.turn % 10 === 0) || @@ -1530,7 +1532,7 @@ export class Battle extends Dex.ModdedDex { this.add('gametype', this.gameType); this.add('gen', this.gen); - const format = this.getFormat(); + const format = this.format; this.add('tier', format.name); if (this.rated) { @@ -1540,9 +1542,9 @@ export class Battle extends Dex.ModdedDex { if (format.onBegin) format.onBegin.call(this); if (format.trunc) this.trunc = format.trunc; - for (const rule of this.getRuleTable(format).keys()) { + for (const rule of this.ruleTable.keys()) { if (rule.startsWith('+') || rule.startsWith('-') || rule.startsWith('!')) continue; - const subFormat = this.getFormat(rule); + const subFormat = this.dex.getFormat(rule); if (subFormat.exists) { if (subFormat.onBegin) subFormat.onBegin.call(this); } @@ -1562,8 +1564,7 @@ export class Battle extends Dex.ModdedDex { restart(send?: (type: string, data: string | string[]) => void) { if (!this.deserialized) throw new Error('Attempt to restart a battle which has not been deserialized'); - const format = this.getFormat(); - if (format.trunc) this.trunc = format.trunc; + if (this.format.trunc) this.trunc = this.format.trunc; // @ts-ignore - readonly this.send = send; @@ -1639,7 +1640,7 @@ export class Battle extends Dex.ModdedDex { ) { if (!targetArray) return [0]; let retVals: (number | false | undefined)[] = []; - if (typeof effect === 'string' || !effect) effect = this.getEffectByID((effect || '') as ID); + if (typeof effect === 'string' || !effect) effect = this.dex.getEffectByID((effect || '') as ID); for (const [i, curDamage] of damage.entries()) { const target = targetArray[i]; let targetDamage = curDamage; @@ -1655,7 +1656,7 @@ export class Battle extends Dex.ModdedDex { retVals[i] = false; continue; } - if (targetDamage !== 0) targetDamage = this.clampIntRange(targetDamage, 1); + if (targetDamage !== 0) targetDamage = this.dex.clampIntRange(targetDamage, 1); if (effect.id !== 'struggle-recoil') { // Struggle recoil is not affected by effects if (effect.effectType === 'Weather' && !target.runStatusImmunity(effect.id)) { @@ -1670,10 +1671,10 @@ export class Battle extends Dex.ModdedDex { continue; } } - if (targetDamage !== 0) targetDamage = this.clampIntRange(targetDamage, 1); + if (targetDamage !== 0) targetDamage = this.dex.clampIntRange(targetDamage, 1); if (this.gen <= 1) { - if (this.currentMod === 'stadium' || + if (this.dex.currentMod === 'stadium' || !['recoil', 'drain'].includes(effect.id) && effect.effectType !== 'Status') { this.lastDamage = targetDamage; } @@ -1707,11 +1708,11 @@ export class Battle extends Dex.ModdedDex { if (targetDamage && effect.effectType === 'Move') { if (this.gen <= 1 && effect.recoil && source) { - const amount = this.clampIntRange(Math.floor(targetDamage * effect.recoil[0] / effect.recoil[1]), 1); + const amount = this.dex.clampIntRange(Math.floor(targetDamage * effect.recoil[0] / effect.recoil[1]), 1); this.damage(amount, source, target, 'recoil'); } if (this.gen <= 4 && effect.drain && source) { - const amount = this.clampIntRange(Math.floor(targetDamage * effect.drain[0] / effect.drain[1]), 1); + const amount = this.dex.clampIntRange(Math.floor(targetDamage * effect.drain[0] / effect.drain[1]), 1); this.heal(amount, source, target, 'drain'); } if (this.gen > 4 && effect.drain && source) { @@ -1761,12 +1762,12 @@ export class Battle extends Dex.ModdedDex { } if (!target || !target.hp) return 0; if (!damage) return 0; - damage = this.clampIntRange(damage, 1); + damage = this.dex.clampIntRange(damage, 1); - if (typeof effect === 'string' || !effect) effect = this.getEffectByID((effect || '') as ID); + if (typeof effect === 'string' || !effect) effect = this.dex.getEffectByID((effect || '') as ID); // In Gen 1 BUT NOT STADIUM, Substitute also takes confusion and HJK recoil damage - if (this.gen <= 1 && this.currentMod !== 'stadium' && + if (this.gen <= 1 && this.dex.currentMod !== 'stadium' && ['confusion', 'jumpkick', 'highjumpkick'].includes(effect.id) && target.volatiles['substitute']) { const hint = "In Gen 1, if a Pokemon with a Substitute hurts itself due to confusion or Jump Kick/Hi Jump Kick recoil and the target"; @@ -1808,7 +1809,7 @@ export class Battle extends Dex.ModdedDex { if (!source) source = this.event.source; if (!effect) effect = this.effect; } - if (effect === 'drain') effect = this.getEffectByID(effect as ID); + if (effect === 'drain') effect = this.dex.getEffectByID(effect as ID); if (damage && damage <= 1) damage = 1; damage = this.trunc(damage); // for things like Liquid Ooze, the Heal event still happens when nothing is healed. @@ -1894,7 +1895,7 @@ export class Battle extends Dex.ModdedDex { } getCategory(move: string | Move) { - return this.getMove(move).category || 'Physical'; + return this.dex.getMove(move).category || 'Physical'; } /** @@ -1907,7 +1908,7 @@ export class Battle extends Dex.ModdedDex { pokemon: Pokemon, target: Pokemon, move: string | number | ActiveMove, suppressMessages: boolean = false ): number | undefined | null | false { - if (typeof move === 'string') move = this.getActiveMove(move); + if (typeof move === 'string') move = this.dex.getActiveMove(move); if (typeof move === 'number') { const basePower = move; @@ -1942,15 +1943,15 @@ export class Battle extends Dex.ModdedDex { basePower = move.basePowerCallback.call(this, pokemon, target, move); } if (!basePower) return basePower === 0 ? undefined : basePower; - basePower = this.clampIntRange(basePower, 1); + basePower = this.dex.clampIntRange(basePower, 1); let critMult; let critRatio = this.runEvent('ModifyCritRatio', pokemon, target, move, move.critRatio || 0); if (this.gen <= 5) { - critRatio = this.clampIntRange(critRatio, 0, 5); + critRatio = this.dex.clampIntRange(critRatio, 0, 5); critMult = [0, 16, 8, 4, 3, 2]; } else { - critRatio = this.clampIntRange(critRatio, 0, 4); + critRatio = this.dex.clampIntRange(critRatio, 0, 4); if (this.gen === 6) { critMult = [0, 16, 8, 2, 1]; } else { @@ -1974,7 +1975,7 @@ export class Battle extends Dex.ModdedDex { basePower = this.runEvent('BasePower', pokemon, target, move, basePower, true); if (!basePower) return 0; - basePower = this.clampIntRange(basePower, 1); + basePower = this.dex.clampIntRange(basePower, 1); const level = pokemon.level; @@ -2071,7 +2072,7 @@ export class Battle extends Dex.ModdedDex { } // types let typeMod = target.runEffectiveness(move); - typeMod = this.clampIntRange(typeMod, -6, 6); + typeMod = this.dex.clampIntRange(typeMod, -6, 6); target.getMoveHitData(move).typeMod = typeMod; if (typeMod > 0) { if (!suppressMessages) this.add('-supereffective', target); @@ -2162,7 +2163,7 @@ export class Battle extends Dex.ModdedDex { } getTarget(pokemon: Pokemon, move: string | Move, targetLoc: number) { - move = this.getMove(move); + move = this.dex.getMove(move); let target; // Fails if the target is the user and the move can't target its own position if (['adjacentAlly', 'any', 'normal'].includes(move.target) && targetLoc === -(pokemon.position + 1) && @@ -2198,7 +2199,7 @@ export class Battle extends Dex.ModdedDex { // moves that can target either allies or foes will only target foes // when used without an explicit target. - move = this.getMove(move); + move = this.dex.getMove(move); if (move.target === 'adjacentAlly') { const allyActives = pokemon.side.active; let adjacentAllies = [allyActives[pokemon.position - 1], allyActives[pokemon.position + 1]]; @@ -2251,7 +2252,7 @@ export class Battle extends Dex.ModdedDex { this.add('faint', faintData.target); faintData.target.side.pokemonLeft--; this.runEvent('Faint', faintData.target, faintData.source, faintData.effect); - this.singleEvent('End', this.getAbility(faintData.target.ability), faintData.target.abilityData, faintData.target); + this.singleEvent('End', this.dex.getAbility(faintData.target.ability), faintData.target.abilityData, faintData.target); faintData.target.clearVolatile(false); faintData.target.fainted = true; faintData.target.isActive = false; @@ -2316,7 +2317,7 @@ export class Battle extends Dex.ModdedDex { if (!action) throw new Error(`Action not passed to resolveAction`); if (!action.side && action.pokemon) action.side = action.pokemon.side; - if (!action.move && action.moveid) action.move = this.getActiveMove(action.moveid); + if (!action.move && action.moveid) action.move = this.dex.getActiveMove(action.moveid); if (!action.choice && action.move) action.choice = 'move'; if (!action.priority && action.priority !== 0) { const priorities = { @@ -2354,7 +2355,7 @@ export class Battle extends Dex.ModdedDex { } } else if (action.choice === 'switch' || action.choice === 'instaswitch') { if (typeof action.pokemon.switchFlag === 'string') { - action.sourceEffect = this.getMove(action.pokemon.switchFlag as ID) as any; + action.sourceEffect = this.dex.getMove(action.pokemon.switchFlag as ID) as any; } action.pokemon.switchFlag = false; if (!action.speed) action.speed = action.pokemon.getActionSpeed(); @@ -2364,7 +2365,7 @@ export class Battle extends Dex.ModdedDex { const deferPriority = this.gen >= 7 && action.mega && action.mega !== 'done'; if (action.move) { let target = null; - action.move = this.getActiveMove(action.move); + action.move = this.dex.getActiveMove(action.move); if (!action.targetLoc) { target = this.resolveTarget(action.pokemon, action.move); @@ -2377,7 +2378,7 @@ export class Battle extends Dex.ModdedDex { if (action.zmove) { const zMoveName = this.getZMove(action.move, action.pokemon, true); if (zMoveName) { - const zMove = this.getActiveMove(zMoveName); + const zMove = this.dex.getActiveMove(zMoveName); if (zMove.exists && zMove.isZ) { move = zMove; } @@ -2509,7 +2510,7 @@ export class Battle extends Dex.ModdedDex { switch (action.choice) { case 'start': { // I GIVE UP, WILL WRESTLE WITH EVENT SYSTEM LATER - const format = this.getFormat(); + const format = this.format; // Remove Pokémon duplicates remaining after `team` decisions. for (const side of this.sides) { @@ -2531,7 +2532,7 @@ export class Battle extends Dex.ModdedDex { } } for (const pokemon of this.getAllPokemon()) { - this.singleEvent('Start', this.getEffectByID(pokemon.speciesid), pokemon.speciesData, pokemon); + this.singleEvent('Start', this.dex.getEffectByID(pokemon.speciesid), pokemon.speciesData, pokemon); } this.midTurn = true; break; @@ -2571,8 +2572,8 @@ export class Battle extends Dex.ModdedDex { return; case 'instaswitch': case 'switch': - if (action.choice === 'switch' && action.pokemon.status && this.data.Abilities.naturalcure) { - this.singleEvent('CheckShow', this.getAbility('naturalcure'), null, action.pokemon); + if (action.choice === 'switch' && action.pokemon.status && this.dex.data.Abilities.naturalcure) { + this.singleEvent('CheckShow', this.dex.getAbility('naturalcure'), null, action.pokemon); } if (action.pokemon.hp) { action.pokemon.beingCalledBack = true; @@ -2596,7 +2597,7 @@ export class Battle extends Dex.ModdedDex { } } action.pokemon.illusion = null; - this.singleEvent('End', this.getAbility(action.pokemon.ability), action.pokemon.abilityData, action.pokemon); + this.singleEvent('End', this.dex.getAbility(action.pokemon.ability), action.pokemon.abilityData, action.pokemon); if (!action.pokemon.hp && !action.pokemon.fainted) { // a pokemon fainted from Pursuit before it could switch if (this.gen <= 4) { @@ -2963,17 +2964,16 @@ export class Battle extends Dex.ModdedDex { // players getTeam(options: PlayerOptions): PokemonSet[] { - const format = this.getFormat(); let team = options.team; if (typeof team === 'string') team = Dex.fastUnpackTeam(team); - if ((!format.team || this.deserialized) && team) return team; + if ((!this.format.team || this.deserialized) && team) return team; if (!options.seed) { options.seed = PRNG.generateSeed(); } if (!this.teamGenerator) { - this.teamGenerator = this.getTeamGenerator(format, options.seed); + this.teamGenerator = this.dex.getTeamGenerator(this.format, options.seed); } else { this.teamGenerator.setSeed(options.seed); } @@ -3007,7 +3007,7 @@ export class Battle extends Dex.ModdedDex { if (options.team) throw new Error(`Player ${slot} already has a team!`); } if (options.team && typeof options.team !== 'string') { - options.team = this.packTeam(options.team); + options.team = this.dex.packTeam(options.team); } if (!didSomething) return; this.inputLog.push(`>player ${slot} ` + JSON.stringify(options)); diff --git a/sim/dex.ts b/sim/dex.ts index cd246b7ead..4bf32cb04d 100644 --- a/sim/dex.ts +++ b/sim/dex.ts @@ -214,7 +214,7 @@ export class ModdedDex { return dexes; } - mod(mod: string): ModdedDex { + mod(mod: string | undefined): ModdedDex { if (!dexes['base'].modsLoaded) dexes['base'].includeMods(); return dexes[mod || 'base']; } diff --git a/sim/field.ts b/sim/field.ts index ad9fa76897..d443f9465e 100644 --- a/sim/field.ts +++ b/sim/field.ts @@ -33,7 +33,7 @@ export class Field { } setWeather(status: string | PureEffect, source: Pokemon | 'debug' | null = null, sourceEffect: Effect | null = null) { - status = this.battle.getEffect(status); + status = this.battle.dex.getEffect(status); if (!sourceEffect && this.battle.effect) sourceEffect = this.battle.effect; if (!source && this.battle.event && this.battle.event.target) source = this.battle.event.target; if (source === 'debug') source = this.battle.sides[0].active[0]; @@ -117,11 +117,11 @@ export class Field { } getWeather() { - return this.battle.getEffectByID(this.weather); + return this.battle.dex.getEffectByID(this.weather); } setTerrain(status: string | Effect, source: Pokemon | 'debug' | null = null, sourceEffect: Effect | null = null) { - status = this.battle.getEffect(status); + status = this.battle.dex.getEffect(status); if (!sourceEffect && this.battle.effect) sourceEffect = this.battle.effect; if (!source && this.battle.event && this.battle.event.target) source = this.battle.event.target; if (source === 'debug') source = this.battle.sides[0].active[0]; @@ -172,7 +172,7 @@ export class Field { } getTerrain() { - return this.battle.getEffectByID(this.terrain); + return this.battle.dex.getEffectByID(this.terrain); } addPseudoWeather( @@ -182,7 +182,7 @@ export class Field { ): boolean { if (!source && this.battle.event && this.battle.event.target) source = this.battle.event.target; if (source === 'debug') source = this.battle.sides[0].active[0]; - status = this.battle.getEffect(status); + status = this.battle.dex.getEffect(status); let effectData = this.pseudoWeather[status.id]; if (effectData) { @@ -207,12 +207,12 @@ export class Field { } getPseudoWeather(status: string | Effect) { - status = this.battle.getEffect(status); + status = this.battle.dex.getEffect(status); return this.pseudoWeather[status.id] ? status : null; } removePseudoWeather(status: string | Effect) { - status = this.battle.getEffect(status); + status = this.battle.dex.getEffect(status); const effectData = this.pseudoWeather[status.id]; if (!effectData) return false; this.battle.singleEvent('End', status, effectData, this); diff --git a/sim/globals.ts b/sim/globals.ts index 65d3beeeb4..a5c437f928 100644 --- a/sim/globals.ts +++ b/sim/globals.ts @@ -996,12 +996,12 @@ interface FormatsData extends EventMethods { checkLearnset?: (this: TeamValidator, move: Move, template: Template, setSources: PokemonSources, set: PokemonSet) => {type: string, [any: string]: any} | null onAfterMega?: (this: Battle, pokemon: Pokemon) => void onBegin?: (this: Battle) => void - onChangeSet?: (this: ModdedDex, set: PokemonSet, format: Format, setHas?: AnyObject, teamHas?: AnyObject) => string[] | void + onChangeSet?: (this: TeamValidator, set: PokemonSet, format: Format, setHas?: AnyObject, teamHas?: AnyObject) => string[] | void onModifyTemplate?: (this: Battle, template: Template, target?: Pokemon, source?: Pokemon, effect?: Effect) => Template | void onStart?: (this: Battle) => void onTeamPreview?: (this: Battle) => void - onValidateSet?: (this: ModdedDex, set: PokemonSet, format: Format, setHas: AnyObject, teamHas: AnyObject) => string[] | void - onValidateTeam?: (this: ModdedDex, team: PokemonSet[], format: Format, teamHas: AnyObject) => string[] | void + onValidateSet?: (this: TeamValidator, set: PokemonSet, format: Format, setHas: AnyObject, teamHas: AnyObject) => string[] | void + onValidateTeam?: (this: TeamValidator, team: PokemonSet[], format: Format, teamHas: AnyObject) => string[] | void validateSet?: (this: TeamValidator, set: PokemonSet, teamHas: AnyObject) => string[] | null validateTeam?: (this: TeamValidator, team: PokemonSet[], removeNicknames: boolean) => string[] | void, trunc?: (n: number) => number; @@ -1100,7 +1100,7 @@ interface ModdedBattleScriptsData extends Partial { debug?: (this: Battle, activity: string) => void getDamage?: (this: Battle, pokemon: Pokemon, target: Pokemon, move: string | number | ActiveMove, suppressMessages: boolean) => number | undefined | null | false getEffect?: (this: Battle, name: string | Effect | null) => Effect - init?: (this: Battle) => void + init?: (this: ModdedDex) => void modifyDamage?: (this: Battle, baseDamage: number, pokemon: Pokemon, target: Pokemon, move: ActiveMove, suppressMessages?: boolean) => void natureModify?: (this: Battle, stats: StatsTable, set: PokemonSet) => StatsTable spreadModify?: (this: Battle, baseStats: StatsTable, set: PokemonSet) => StatsTable diff --git a/sim/pokemon.ts b/sim/pokemon.ts index 6f7619338f..87b5d93451 100644 --- a/sim/pokemon.ts +++ b/sim/pokemon.ts @@ -213,18 +213,18 @@ export class Pokemon { this.side = side; this.battle = side.battle; - const pokemonScripts = this.battle.data.Scripts.pokemon; + const pokemonScripts = this.battle.dex.data.Scripts.pokemon; if (pokemonScripts) Object.assign(this, pokemonScripts); if (typeof set === 'string') set = {name: set}; this.set = set as PokemonSet; - this.baseTemplate = this.battle.getTemplate(set.species || set.name); + this.baseTemplate = this.battle.dex.getTemplate(set.species || set.name); if (!this.baseTemplate.exists) { throw new Error(`Unidentified species: ${this.baseTemplate.name}`); } this.template = this.baseTemplate; - this.species = this.battle.getSpecies(set.species); + this.species = this.battle.dex.getSpecies(set.species); this.speciesid = toID(this.species); if (set.name === set.species || !set.name) { set.name = this.baseTemplate.baseSpecies; @@ -235,23 +235,23 @@ export class Pokemon { this.fullname = this.side.id + ': ' + this.name; this.id = this.fullname; - set.level = this.battle.clampIntRange(set.forcedLevel || set.level || 100, 1, 9999); + set.level = this.battle.dex.clampIntRange(set.forcedLevel || set.level || 100, 1, 9999); this.level = set.level; const genders: {[key: string]: GenderName} = {M: 'M', F: 'F', N: 'N'}; this.gender = genders[set.gender] || this.template.gender || (this.battle.random() * 2 < 1 ? 'M' : 'F'); if (this.gender === 'N') this.gender = ''; - this.happiness = typeof set.happiness === 'number' ? this.battle.clampIntRange(set.happiness, 0, 255) : 255; + this.happiness = typeof set.happiness === 'number' ? this.battle.dex.clampIntRange(set.happiness, 0, 255) : 255; this.pokeball = this.set.pokeball || 'pokeball'; this.baseMoveSlots = []; this.moveSlots = []; if (this.set.moves) { for (const moveid of this.set.moves) { - let move = this.battle.getMove(moveid); + let move = this.battle.dex.getMove(moveid); if (!move.id) continue; if (move.id === 'hiddenpower' && move.type !== 'Normal') { if (!set.hpType) set.hpType = move.type; - move = this.battle.getMove('hiddenpower'); + move = this.battle.dex.getMove('hiddenpower'); } this.baseMoveSlots.push({ move: move.name, @@ -288,10 +288,10 @@ export class Pokemon { if (!this.set.ivs[stat] && this.set.ivs[stat] !== 0) this.set.ivs[stat] = 31; } for (stat in this.set.evs) { - this.set.evs[stat] = this.battle.clampIntRange(this.set.evs[stat], 0, 255); + this.set.evs[stat] = this.battle.dex.clampIntRange(this.set.evs[stat], 0, 255); } for (stat in this.set.ivs) { - this.set.ivs[stat] = this.battle.clampIntRange(this.set.ivs[stat], 0, 31); + this.set.ivs[stat] = this.battle.dex.clampIntRange(this.set.ivs[stat], 0, 31); } if (this.battle.gen && this.battle.gen <= 2) { // We represent DVs using even IVs. Ensure they are in fact even. @@ -300,7 +300,7 @@ export class Pokemon { } } - const hpData = this.battle.getHiddenPower(this.set.ivs); + const hpData = this.battle.dex.getHiddenPower(this.set.ivs); this.hpType = set.hpType || hpData.type; this.hpPower = hpData.power; @@ -513,7 +513,7 @@ export class Pokemon { } const combatPower = Math.floor(Math.floor(statSum * this.level * 6 / 100) + (Math.floor(awakeningSum) * Math.floor((this.level * 4) / 100 + 2))); - return this.battle.clampIntRange(combatPower, 0, 10000); + return this.battle.dex.clampIntRange(combatPower, 0, 10000); } */ @@ -523,7 +523,7 @@ export class Pokemon { } getMoveData(move: string | Move) { - move = this.battle.getMove(move) as Move; + move = this.battle.dex.getMove(move) as Move; for (const moveSlot of this.moveSlots) { if (moveSlot.id === move.id) { return moveSlot; @@ -614,7 +614,7 @@ export class Pokemon { if (!move.flags['charge'] || this.volatiles['twoturnmove'] || (move.id.startsWith('solarb') && this.battle.field.isWeather(['sunnyday', 'desolateland'])) || (this.hasItem('powerherb') && move.id !== 'skydrop')) { - target = this.battle.priorityEvent('RedirectTarget', this, this, this.battle.getActiveMove(move), target); + target = this.battle.priorityEvent('RedirectTarget', this, this, this.battle.dex.getActiveMove(move), target); } } if (target.fainted) { @@ -653,7 +653,7 @@ export class Pokemon { deductPP(move: string | Move, amount?: number | null, target?: Pokemon | null | false) { const gen = this.battle.gen; - move = this.battle.getMove(move) as Move; + move = this.battle.dex.getMove(move) as Move; const ppData = this.getMoveData(move); if (!ppData) return 0; ppData.used = true; @@ -676,7 +676,7 @@ export class Pokemon { gotAttacked(move: string | Move, damage: number | false | undefined, source: Pokemon) { if (!damage) damage = 0; - move = this.battle.getMove(move) as Move; + move = this.battle.dex.getMove(move) as Move; this.attackedBy.push({ source, damage, @@ -716,7 +716,7 @@ export class Pokemon { } // does this happen? return [{ - move: this.battle.getMove(lockedMove).name, + move: this.battle.dex.getMove(lockedMove).name, id: lockedMove, }]; } @@ -729,15 +729,15 @@ export class Pokemon { if (this.battle.gen < 6) moveName += ' ' + this.hpPower; } else if (moveSlot.id === 'return') { // @ts-ignore - Return's basePowerCallback only takes one parameter - moveName = 'Return ' + this.battle.getMove('return')!.basePowerCallback(this); + moveName = 'Return ' + this.battle.dex.getMove('return')!.basePowerCallback(this); } else if (moveSlot.id === 'frustration') { // @ts-ignore - Frustration's basePowerCallback only takes one parameter - moveName = 'Frustration ' + this.battle.getMove('frustration')!.basePowerCallback(this); + moveName = 'Frustration ' + this.battle.dex.getMove('frustration')!.basePowerCallback(this); } let target = moveSlot.target; if (moveSlot.id === 'curse') { if (!this.hasType('Ghost')) { - target = this.battle.getMove('curse').nonGhostTarget || moveSlot.target; + target = this.battle.dex.getMove('curse').nonGhostTarget || moveSlot.target; } } let disabled = moveSlot.disabled; @@ -859,7 +859,7 @@ export class Pokemon { this.clearVolatile(); this.boosts = pokemon.boosts; for (const i in pokemon.volatiles) { - if (this.battle.getEffectByID(i as ID).noCopy) continue; + if (this.battle.dex.getEffectByID(i as ID).noCopy) continue; // shallow clones this.volatiles[i] = Object.assign({}, pokemon.volatiles[i]); if (this.volatiles[i].linkedPokemon) { @@ -970,7 +970,7 @@ export class Pokemon { this.knownType = true; this.weighthg = template.weighthg; - const stats = this.battle.spreadModify(this.template.baseStats, this.set); + const stats = this.battle.dex.spreadModify(this.template.baseStats, this.set); if (!this.baseStoredStats) this.baseStoredStats = stats; let statName: StatNameExceptHP; for (statName in this.storedStats) { @@ -995,7 +995,7 @@ export class Pokemon { formeChange( templateId: string | Template, source: Effect = this.battle.effect, isPermanent?: boolean, message?: string, abilitySlot: '0' | '1' | 'H' | 'S' = '0') { - const rawTemplate = this.battle.getTemplate(templateId); + const rawTemplate = this.battle.dex.getTemplate(templateId); const template = this.setTemplate(rawTemplate, source); if (!template) return false; @@ -1224,7 +1224,7 @@ export class Pokemon { ignoreImmunities: boolean = false ) { if (!this.hp) return false; - status = this.battle.getEffect(status); + status = this.battle.dex.getEffect(status); if (this.battle.event) { if (!source) source = this.battle.event.source; if (!sourceEffect) sourceEffect = this.battle.effect; @@ -1289,7 +1289,7 @@ export class Pokemon { } getStatus() { - return this.battle.getEffectByID(this.status); + return this.battle.dex.getEffectByID(this.status); } eatItem(source?: Pokemon, sourceEffect?: Effect) { @@ -1385,7 +1385,7 @@ export class Pokemon { setItem(item: string | Item, source?: Pokemon, effect?: Effect) { if (!this.hp || !this.isActive) return false; - if (typeof item === 'string') item = this.battle.getItem(item) as Item; + if (typeof item === 'string') item = this.battle.dex.getItem(item) as Item; const effectid = this.battle.effect ? this.battle.effect.id : ''; if (item.id === 'leppaberry') { @@ -1404,7 +1404,7 @@ export class Pokemon { } getItem() { - return this.battle.getItem(this.item); + return this.battle.dex.getItem(this.item); } hasItem(item: string | string[]) { @@ -1420,7 +1420,7 @@ export class Pokemon { setAbility(ability: string | Ability, source?: Pokemon | null, isFromFormeChange?: boolean) { if (!this.hp) return false; - if (typeof ability === 'string') ability = this.battle.getAbility(ability) as Ability; + if (typeof ability === 'string') ability = this.battle.dex.getAbility(ability) as Ability; const oldAbility = this.ability; if (!isFromFormeChange) { const abilities = [ @@ -1430,10 +1430,10 @@ export class Pokemon { if (this.battle.gen >= 7 && (ability.id === 'zenmode' || oldAbility === 'zenmode')) return false; } if (!this.battle.runEvent('SetAbility', this, source, this.battle.effect, ability)) return false; - this.battle.singleEvent('End', this.battle.getAbility(oldAbility), this.abilityData, this, source); + this.battle.singleEvent('End', this.battle.dex.getAbility(oldAbility), this.abilityData, this, source); if (this.battle.effect && this.battle.effect.effectType === 'Move') { - this.battle.add('-endability', this, this.battle.getAbility(oldAbility), '[from] move: ' + - this.battle.getMove(this.battle.effect.id)); + this.battle.add('-endability', this, this.battle.dex.getAbility(oldAbility), '[from] move: ' + + this.battle.dex.getMove(this.battle.effect.id)); } this.ability = ability.id; this.abilityData = {id: ability.id, target: this}; @@ -1445,7 +1445,7 @@ export class Pokemon { } getAbility() { - return this.battle.getAbility(this.ability); + return this.battle.dex.getAbility(this.ability); } hasAbility(ability: string | string[]) { @@ -1460,14 +1460,14 @@ export class Pokemon { } getNature() { - return this.battle.getNature(this.set.nature); + return this.battle.dex.getNature(this.set.nature); } addVolatile( status: string | PureEffect, source: Pokemon | null = null, sourceEffect: Effect | null = null, linkedStatus: string | PureEffect | null = null): boolean | any { let result; - status = this.battle.getEffect(status) as PureEffect; + status = this.battle.dex.getEffect(status) as PureEffect; if (!this.hp && !status.affectsFainted) return false; if (linkedStatus && source && !source.hp) return false; if (this.battle.event) { @@ -1522,14 +1522,14 @@ export class Pokemon { } getVolatile(status: string | Effect) { - status = this.battle.getEffect(status) as Effect; + status = this.battle.dex.getEffect(status) as Effect; if (!this.volatiles[status.id]) return null; return status; } removeVolatile(status: string | Effect) { if (!this.hp) return false; - status = this.battle.getEffect(status) as Effect; + status = this.battle.dex.getEffect(status) as Effect; if (!this.volatiles[status.id]) return false; this.battle.singleEvent('End', status, this.volatiles[status.id], this); const linkedPokemon = this.volatiles[status.id].linkedPokemon; @@ -1647,7 +1647,7 @@ export class Pokemon { runEffectiveness(move: ActiveMove) { let totalTypeMod = 0; for (const type of this.getTypes()) { - let typeMod = this.battle.getEffectiveness(move, type); + let typeMod = this.battle.dex.getEffectiveness(move, type); typeMod = this.battle.singleEvent('Effectiveness', move, null, this, type, move, typeMod); totalTypeMod += this.battle.runEvent('Effectiveness', this, type, move, typeMod); } @@ -1656,7 +1656,7 @@ export class Pokemon { runImmunity(type: string, message?: string | boolean) { if (!type || type === '???') return true; - if (!(type in this.battle.data.TypeChart)) { + if (!(type in this.battle.dex.data.TypeChart)) { if (type === 'Fairy' || type === 'Dark' || type === 'Steel') return true; throw new Error("Use runStatusImmunity for " + type); } @@ -1674,7 +1674,7 @@ export class Pokemon { } } if (!negateResult) return true; - if ((isGrounded === undefined && !this.battle.getImmunity(type, this)) || isGrounded === false) { + if ((isGrounded === undefined && !this.battle.dex.getImmunity(type, this)) || isGrounded === false) { if (message) { this.battle.add('-immune', this); } @@ -1687,7 +1687,7 @@ export class Pokemon { if (this.fainted) return false; if (!type) return true; - if (!this.battle.getImmunity(type, this)) { + if (!this.battle.dex.getImmunity(type, this)) { this.battle.debug('natural status immunity'); if (message) { this.battle.add('-immune', this); diff --git a/sim/side.ts b/sim/side.ts index 74399162a3..76c68f5984 100644 --- a/sim/side.ts +++ b/sim/side.ts @@ -63,7 +63,7 @@ export class Side { lastMove: Move | null; constructor(name: string, battle: Battle, sideNum: number, team: PokemonSet[]) { - const sideScripts = battle.data.Scripts.side; + const sideScripts = battle.dex.data.Scripts.side; if (sideScripts) Object.assign(this, sideScripts); this.battle = battle; @@ -185,7 +185,7 @@ export class Side { return move + toID(pokemon.hpType) + (this.battle.gen < 6 ? '' : pokemon.hpPower); } if (move === 'frustration' || move === 'return') { - const m = this.battle.getMove(move)!; + const m = this.battle.dex.getMove(move)!; // @ts-ignore - Frustration and Return only require the source Pokemon const basePower = m.basePowerCallback(pokemon); return `${move}${basePower}`; @@ -218,7 +218,7 @@ export class Side { if (source === 'debug') source = this.active[0]; if (!source) throw new Error(`setting sidecond without a source`); - status = this.battle.getEffect(status); + status = this.battle.dex.getEffect(status); if (this.sideConditions[status.id]) { if (!status.onRestart) return false; return this.battle.singleEvent('Restart', status, this.sideConditions[status.id], this, source, sourceEffect); @@ -245,7 +245,7 @@ export class Side { if (this.n >= 2 && this.battle.gameType === 'multi') { return this.battle.sides[this.n % 2].getSideCondition(status); } - status = this.battle.getEffect(status) as Effect; + status = this.battle.dex.getEffect(status) as Effect; if (!this.sideConditions[status.id]) return null; return status; } @@ -254,7 +254,7 @@ export class Side { if (this.n >= 2 && this.battle.gameType === 'multi') { return this.battle.sides[this.n % 2].getSideConditionData(status); } - status = this.battle.getEffect(status) as Effect; + status = this.battle.dex.getEffect(status) as Effect; return this.sideConditions[status.id] || null; } @@ -262,7 +262,7 @@ export class Side { if (this.n >= 2 && this.battle.gameType === 'multi') { return this.battle.sides[this.n % 2].removeSideCondition(status); } - status = this.battle.getEffect(status) as Effect; + status = this.battle.dex.getEffect(status) as Effect; if (!this.sideConditions[status.id]) return false; this.battle.singleEvent('End', status, this.sideConditions[status.id], this); delete this.sideConditions[status.id]; @@ -278,7 +278,7 @@ export class Side { if (target instanceof Pokemon) target = target.position; if (!source) throw new Error(`setting sidecond without a source`); - status = this.battle.getEffect(status); + status = this.battle.dex.getEffect(status); if (this.slotConditions[target][status.id]) { if (!status.onRestart) return false; return this.battle.singleEvent('Restart', status, this.slotConditions[target][status.id], this, source, sourceEffect); @@ -303,14 +303,14 @@ export class Side { getSlotCondition(target: Pokemon | number, status: string | Effect) { if (target instanceof Pokemon) target = target.position; - status = this.battle.getEffect(status) as Effect; + status = this.battle.dex.getEffect(status) as Effect; if (!this.slotConditions[target][status.id]) return null; return status; } removeSlotCondition(target: Pokemon | number, status: string | Effect) { if (target instanceof Pokemon) target = target.position; - status = this.battle.getEffect(status) as Effect; + status = this.battle.dex.getEffect(status) as Effect; if (!this.slotConditions[target][status.id]) return false; this.battle.singleEvent('End', status, this.slotConditions[target][status.id], this.active[target]); delete this.slotConditions[target][status.id]; @@ -408,7 +408,7 @@ export class Side { break; } } - const move = this.battle.getMove(moveid); + const move = this.battle.dex.getMove(moveid); // Z-move @@ -420,7 +420,7 @@ export class Side { return this.emitChoiceError(`Can't move: You can't Z-move more than once per battle`); } - if (zMove) targetType = this.battle.getMove(zMove).target; + if (zMove) targetType = this.battle.dex.getMove(zMove).target; // Validate targetting diff --git a/sim/state.ts b/sim/state.ts index d638c21197..c78d57bfa9 100644 --- a/sim/state.ts +++ b/sim/state.ts @@ -6,7 +6,6 @@ */ import {Battle} from './battle'; -import {Dex} from './dex'; import * as Data from './dex-data'; import {Field} from './field'; import {Pokemon} from './pokemon'; @@ -36,7 +35,7 @@ type Referable = Battle | Field | Side | Pokemon | PureEffect | Ability | Item | // Battle inherits from Dex, but all of Dex's fields are redundant - we can // just recreate the Dex from the format. const BATTLE = new Set([ - ...Object.keys(Dex), 'id', 'log', 'inherit', 'cachedFormat', + 'dex', 'gen', 'ruleTable', 'id', 'log', 'inherit', 'format', 'zMoveTable', 'teamGenerator', 'NOT_FAIL', 'FAIL', 'SILENT_FAIL', 'field', 'sides', 'prng', 'hints', 'deserialized', ]); @@ -70,6 +69,7 @@ export const State = new class { // We treat log specially because we only set it back on Battle after everything // else has been deserialized to avoid anything accidentally `add`-ing to it. state.log = battle.log; + state.formatid = battle.format.id; return state; } @@ -83,7 +83,7 @@ export const State = new class { const state: /* Battle */ AnyObject = typeof serialized === 'string' ? JSON.parse(serialized) : serialized; const options = { - formatid: state.format, + formatid: state.formatid, seed: state.prngSeed, rated: state.rated, debug: state.debugMode, @@ -256,7 +256,7 @@ export const State = new class { // a bug in the simulator if it ever happened, but if not, the isActiveMove check can // be extended. private serializeActiveMove(move: ActiveMove, battle: Battle): /* ActiveMove */ AnyObject { - const base = battle.getMove(move.id); + const base = battle.dex.getMove(move.id); const skip = new Set([...ACTIVE_MOVE]); for (const [key, value] of Object.entries(base)) { // This should really be a deepEquals check to see if anything on ActiveMove was @@ -271,7 +271,7 @@ export const State = new class { } private deserializeActiveMove(state: /* ActiveMove */ AnyObject, battle: Battle): ActiveMove { - const move = battle.getActiveMove(this.fromRef(state.move, battle)! as Move); + const move = battle.dex.getActiveMove(this.fromRef(state.move, battle)! as Move); this.deserialize(state, move, ACTIVE_MOVE, battle); return move; } @@ -384,11 +384,11 @@ export const State = new class { switch (type) { case 'Side': return battle.sides[Number(id[1]) - 1]; case 'Pokemon': return battle.sides[Number(id[1]) - 1].pokemon[POSITIONS.indexOf(id[2])]; - case 'Ability': return battle.getAbility(id); - case 'Item': return battle.getItem(id); - case 'Move': return battle.getMove(id); - case 'PureEffect': return battle.getEffect(id); - case 'Template': return battle.getTemplate(id); + case 'Ability': return battle.dex.getAbility(id); + case 'Item': return battle.dex.getItem(id); + case 'Move': return battle.dex.getMove(id); + case 'PureEffect': return battle.dex.getEffect(id); + case 'Template': return battle.dex.getTemplate(id); default: return undefined; // maybe we actually got unlucky and its a string } } diff --git a/sim/team-validator.ts b/sim/team-validator.ts index 858e88b045..686eed998e 100644 --- a/sim/team-validator.ts +++ b/sim/team-validator.ts @@ -173,11 +173,13 @@ export class PokemonSources { export class TeamValidator { readonly format: Format; readonly dex: ModdedDex; + readonly gen: number; readonly ruleTable: import('./dex-data').RuleTable; constructor(format: string | Format) { this.format = Dex.getFormat(format); this.dex = Dex.forFormat(this.format); + this.gen = this.dex.gen; this.ruleTable = this.dex.getRuleTable(this.format); } @@ -263,11 +265,11 @@ export class TeamValidator { for (const rule of ruleTable.keys()) { const subformat = dex.getFormat(rule); if (subformat.onValidateTeam && ruleTable.has(subformat.id)) { - problems = problems.concat(subformat.onValidateTeam.call(dex, team, format, teamHas) || []); + problems = problems.concat(subformat.onValidateTeam.call(this, team, format, teamHas) || []); } } if (format.onValidateTeam) { - problems = problems.concat(format.onValidateTeam.call(dex, team, format, teamHas) || []); + problems = problems.concat(format.onValidateTeam.call(this, team, format, teamHas) || []); } if (!problems.length) return null; @@ -342,11 +344,11 @@ export class TeamValidator { for (const [rule] of ruleTable) { const subformat = dex.getFormat(rule); if (subformat.onChangeSet && ruleTable.has(subformat.id)) { - problems = problems.concat(subformat.onChangeSet.call(dex, set, format, setHas, teamHas) || []); + problems = problems.concat(subformat.onChangeSet.call(this, set, format, setHas, teamHas) || []); } } if (format.onChangeSet) { - problems = problems.concat(format.onChangeSet.call(dex, set, format, setHas, teamHas) || []); + problems = problems.concat(format.onChangeSet.call(this, set, format, setHas, teamHas) || []); } // onChangeSet can modify set.species, set.item, set.ability @@ -613,11 +615,11 @@ export class TeamValidator { if (rule.startsWith('!')) continue; const subformat = dex.getFormat(rule); if (subformat.onValidateSet && ruleTable.has(subformat.id)) { - problems = problems.concat(subformat.onValidateSet.call(dex, set, format, setHas, teamHas) || []); + problems = problems.concat(subformat.onValidateSet.call(this, set, format, setHas, teamHas) || []); } } if (format.onValidateSet) { - problems = problems.concat(format.onValidateSet.call(dex, set, format, setHas, teamHas) || []); + problems = problems.concat(format.onValidateSet.call(this, set, format, setHas, teamHas) || []); } if (!problems.length) { diff --git a/test/sim/abilities/battlearmor.js b/test/sim/abilities/battlearmor.js index 5b15963032..82c0edfc19 100644 --- a/test/sim/abilities/battlearmor.js +++ b/test/sim/abilities/battlearmor.js @@ -16,7 +16,7 @@ describe('Battle Armor', function () { [{species: 'Cryogonal', ability: 'noguard', moves: ['frostbreath']}], ]); let successfulEvent = false; - battle.onEvent('ModifyDamage', battle.getFormat(), function (damage, attacker, defender, move) { + battle.onEvent('ModifyDamage', battle.format, function (damage, attacker, defender, move) { if (move.id === 'frostbreath') { successfulEvent = true; assert.ok(!defender.getMoveHitData(move).crit); @@ -33,7 +33,7 @@ describe('Battle Armor', function () { ]); battle.makeChoices('move quickattack', 'move frostbreath'); let successfulEvent = false; - battle.onEvent('ModifyDamage', battle.getFormat(), function (damage, attacker, defender, move) { + battle.onEvent('ModifyDamage', battle.format, function (damage, attacker, defender, move) { if (move.id === 'frostbreath') { successfulEvent = true; assert.ok(defender.getMoveHitData(move).crit); diff --git a/test/sim/abilities/comatose.js b/test/sim/abilities/comatose.js index 9f22bcabc2..1171fd8199 100644 --- a/test/sim/abilities/comatose.js +++ b/test/sim/abilities/comatose.js @@ -62,14 +62,14 @@ describe('Comatose', function () { battle.setPlayer('p2', {team: [{species: "Smeargle", ability: 'technician', moves: ['hex', 'wakeupslap']}]}); let bp = 0; - battle.onEvent('BasePower', battle.getFormat(), function (basePower, pokemon, target, move) { + battle.onEvent('BasePower', battle.format, function (basePower, pokemon, target, move) { bp = basePower; }); battle.makeChoices('move endure', 'move hex'); - assert.strictEqual(bp, battle.getMove('hex').basePower * 2); + assert.strictEqual(bp, battle.dex.getMove('hex').basePower * 2); battle.makeChoices('move endure', 'move wakeupslap'); - assert.strictEqual(bp, battle.getMove('wakeupslap').basePower * 2); + assert.strictEqual(bp, battle.dex.getMove('wakeupslap').basePower * 2); }); }); diff --git a/test/sim/abilities/desolateland.js b/test/sim/abilities/desolateland.js index 705db74957..bdcec61c07 100644 --- a/test/sim/abilities/desolateland.js +++ b/test/sim/abilities/desolateland.js @@ -74,7 +74,7 @@ describe('Desolate Land', function () { {species: "Venusaur", ability: 'chlorophyll', moves: ['growth']}, {species: "Toxicroak", ability: 'dryskin', moves: ['bulkup']}, ]}); - battle.onEvent('Hit', battle.getFormat(), (target, pokemon, move) => { + battle.onEvent('Hit', battle.format, (target, pokemon, move) => { if (move.id === 'weatherball') { assert.strictEqual(move.type, 'Fire'); } diff --git a/test/sim/abilities/disguise.js b/test/sim/abilities/disguise.js index a7145c9338..46229ad82d 100644 --- a/test/sim/abilities/disguise.js +++ b/test/sim/abilities/disguise.js @@ -80,7 +80,7 @@ describe('Disguise', function () { battle.setPlayer('p1', {team: [{species: 'Mimikyu', ability: 'disguise', moves: ['counter']}]}); battle.setPlayer('p2', {team: [{species: 'Cryogonal', ability: 'noguard', moves: ['frostbreath']}]}); let successfulEvent = false; - battle.onEvent('Damage', battle.getFormat(), function (damage, attacker, defender, move) { + battle.onEvent('Damage', battle.format, function (damage, attacker, defender, move) { if (move.id === 'frostbreath') { successfulEvent = true; assert.ok(!defender.getMoveHitData(move).crit); diff --git a/test/sim/abilities/intimidate.js b/test/sim/abilities/intimidate.js index 4a645d34aa..bc77f13f82 100644 --- a/test/sim/abilities/intimidate.js +++ b/test/sim/abilities/intimidate.js @@ -81,7 +81,7 @@ describe('Intimidate', function () { battle.setPlayer('p1', {team: [{species: "Arcanine", ability: 'intimidate', moves: ['morningsun']}]}); battle.setPlayer('p2', {team: [{species: "Gyarados", ability: 'intimidate', moves: ['dragondance']}]}); let intimidateCount = 0; - battle.onEvent('Boost', battle.getFormat(), function (boost, target, source) { + battle.onEvent('Boost', battle.format, function (boost, target, source) { assert.species(source, intimidateCount === 0 ? 'Arcanine' : 'Gyarados'); intimidateCount++; }); @@ -96,7 +96,7 @@ describe('Intimidate', function () { battle.setPlayer('p1', {team: [{species: "Gyarados", ability: 'intimidate', moves: ['dragondance']}]}); battle.setPlayer('p2', {team: [{species: "Arcanine", ability: 'intimidate', moves: ['morningsun']}]}); intimidateCount = 0; - battle.onEvent('Boost', battle.getFormat(), function (boost, target, source) { + battle.onEvent('Boost', battle.format, function (boost, target, source) { assert.species(source, intimidateCount === 0 ? 'Arcanine' : 'Gyarados'); intimidateCount++; }); @@ -120,7 +120,7 @@ describe('Intimidate', function () { ]}); const [p1active, p2active] = [battle.p1.active, battle.p2.active]; let intimidateCount = 0; - battle.onEvent('Boost', battle.getFormat(), function (boost, target, source) { + battle.onEvent('Boost', battle.format, function (boost, target, source) { assert.species(source, intimidateCount % 2 === 0 ? 'Arcanine' : 'Gyarados'); intimidateCount++; }); diff --git a/test/sim/abilities/parentalbond.js b/test/sim/abilities/parentalbond.js index 107b6763bf..b22cfdc515 100644 --- a/test/sim/abilities/parentalbond.js +++ b/test/sim/abilities/parentalbond.js @@ -14,7 +14,7 @@ describe('Parental Bond', function () { ]); basePowers = []; - battle.onEvent('BasePower', battle.getFormat(), -9, function (bp, attacker, defender, move) { + battle.onEvent('BasePower', battle.format, -9, function (bp, attacker, defender, move) { basePowers.push(this.modify(bp, this.event.modifier)); }); }); @@ -47,7 +47,7 @@ describe('Parental Bond [Gen 6]', function () { ]); basePowers = []; - battle.onEvent('BasePower', battle.getFormat(), -9, function (bp, attacker, defender, move) { + battle.onEvent('BasePower', battle.format, -9, function (bp, attacker, defender, move) { basePowers.push(this.modify(bp, this.event.modifier)); }); }); diff --git a/test/sim/abilities/primordialsea.js b/test/sim/abilities/primordialsea.js index 7ea7bc8c00..358ec25681 100644 --- a/test/sim/abilities/primordialsea.js +++ b/test/sim/abilities/primordialsea.js @@ -73,7 +73,7 @@ describe('Primordial Sea', function () { {species: "Toxicroak", ability: 'dryskin', moves: ['bulkup']}, {species: "Manaphy", ability: 'hydration', item: 'laggingtail', moves: ['rest']}, ]}); - battle.onEvent('Hit', battle.getFormat(), (target, pokemon, move) => { + battle.onEvent('Hit', battle.format, (target, pokemon, move) => { if (move.id === 'weatherball') { assert.strictEqual(move.type, 'Water'); } diff --git a/test/sim/abilities/shellarmor.js b/test/sim/abilities/shellarmor.js index 7c5b80248c..7bc8a662b3 100644 --- a/test/sim/abilities/shellarmor.js +++ b/test/sim/abilities/shellarmor.js @@ -16,7 +16,7 @@ describe('Shell Armor', function () { [{species: 'Cryogonal', ability: 'noguard', moves: ['frostbreath']}], ]); let successfulEvent = false; - battle.onEvent('ModifyDamage', battle.getFormat(), function (damage, attacker, defender, move) { + battle.onEvent('ModifyDamage', battle.format, function (damage, attacker, defender, move) { if (move.id === 'frostbreath') { successfulEvent = true; assert.false(defender.getMoveHitData(move).crit); @@ -32,7 +32,7 @@ describe('Shell Armor', function () { [{species: 'Cryogonal', ability: 'moldbreaker', item: 'zoomlens', moves: ['frostbreath']}], ]); let successfulEvent = false; - battle.onEvent('ModifyDamage', battle.getFormat(), function (damage, attacker, defender, move) { + battle.onEvent('ModifyDamage', battle.format, function (damage, attacker, defender, move) { if (move.id === 'frostbreath') { successfulEvent = true; assert.ok(defender.getMoveHitData(move).crit); diff --git a/test/sim/abilities/shielddust.js b/test/sim/abilities/shielddust.js index b0fd5fbfad..dafe1f5874 100644 --- a/test/sim/abilities/shielddust.js +++ b/test/sim/abilities/shielddust.js @@ -33,7 +33,7 @@ describe('Shield Dust', function () { [{species: 'Talonflame', ability: 'flamebody', item: 'kingsrock', moves: ['flamecharge']}], [{species: 'Clefable', ability: 'shielddust', moves: ['cottonguard']}], ]); - battle.onEvent('ModifyMove', battle.getFormat(), function (move) { + battle.onEvent('ModifyMove', battle.format, function (move) { if (move.secondaries) { for (const secondary of move.secondaries) { secondary.chance = 100; diff --git a/test/sim/abilities/thickfat.js b/test/sim/abilities/thickfat.js index 4397d2c827..03570911bc 100644 --- a/test/sim/abilities/thickfat.js +++ b/test/sim/abilities/thickfat.js @@ -19,7 +19,7 @@ describe('Thick Fat', function () { // should not crit battle.makeChoices('move splash', 'move incinerate'); assert.bounded(target.maxhp - target.hp, [29, 35]); - battle.heal(target.maxhp, target, target, battle.getFormat()); + battle.heal(target.maxhp, target, target, battle.format); battle.resetRNG(); // should not crit battle.makeChoices('move splash', 'move icebeam'); @@ -35,7 +35,7 @@ describe('Thick Fat', function () { // should not crit battle.makeChoices('move splash', 'move incinerate'); assert.bounded(target.maxhp - target.hp, [57, 68]); - battle.heal(target.maxhp, target, target, battle.getFormat()); + battle.heal(target.maxhp, target, target, battle.format); battle.resetRNG(); // should not crit battle.makeChoices('move splash', 'move icebeam'); diff --git a/test/sim/events.js b/test/sim/events.js index d0bc6fa338..9da20a00b3 100644 --- a/test/sim/events.js +++ b/test/sim/events.js @@ -17,14 +17,14 @@ describe('Battle#on', function () { ]); let eventCount = 0; let eventCount2 = 0; - battle.onEvent('Hit', battle.getFormat(), function () { + battle.onEvent('Hit', battle.format, function () { eventCount++; }); - battle.onEvent('Hit', battle.getFormat(), function () { + battle.onEvent('Hit', battle.format, function () { eventCount++; eventCount2++; }); - battle.onEvent('ModifyDamage', battle.getFormat(), function () { + battle.onEvent('ModifyDamage', battle.format, function () { return 5; }); battle.makeChoices('move bulkup', 'move peck'); @@ -46,7 +46,7 @@ describe('Battle#on', function () { }; }; for (let i = 0; i < 9; i++) { - battle.onEvent('ModifyDamage', battle.getFormat(), -i, modHandler(i)); + battle.onEvent('ModifyDamage', battle.format, -i, modHandler(i)); } battle.makeChoices('move bulkup', 'move peck'); assert.strictEqual(eventCount, 9); @@ -59,6 +59,6 @@ describe('Battle#on', function () { ]); assert.throws(battle.onEvent, TypeError); assert.throws(() => { battle.onEvent('Hit'); }, TypeError); - assert.throws(() => { battle.onEvent('Hit', battle.getFormat()); }, TypeError); + assert.throws(() => { battle.onEvent('Hit', battle.format); }, TypeError); }); }); diff --git a/test/sim/items/lansatberry.js b/test/sim/items/lansatberry.js index 95fbceb2bb..619324845b 100644 --- a/test/sim/items/lansatberry.js +++ b/test/sim/items/lansatberry.js @@ -29,7 +29,7 @@ describe('Lansat Berry', function () { let i = 0; let expectedRatio = [1, 1, 1, 1, 1, 3]; - battle.onEvent('ModifyCritRatio', battle.getFormat(), -99, function (critRatio, pokemon) { + battle.onEvent('ModifyCritRatio', battle.format, -99, function (critRatio, pokemon) { assert.strictEqual(critRatio, expectedRatio[i++]); }); diff --git a/test/sim/misc/fusion-combo.js b/test/sim/misc/fusion-combo.js index b4ff9b7407..71fe4bb49b 100644 --- a/test/sim/misc/fusion-combo.js +++ b/test/sim/misc/fusion-combo.js @@ -19,7 +19,7 @@ describe('Fusion Bolt + Fusion Flare', function () { battle.makeChoices(); let bpModifiers = new Map(); - battle.onEvent('BasePower', battle.getFormat(), -100, function (bp, attacker, defender, move) { + battle.onEvent('BasePower', battle.format, -100, function (bp, attacker, defender, move) { bpModifiers.set(move.id, this.event.modifier); }); battle.makeChoices('move fusionbolt 1, move fusionflare 1', 'default'); @@ -37,7 +37,7 @@ describe('Fusion Bolt + Fusion Flare', function () { battle.makeChoices(); let bpModifiers = new Map(); - battle.onEvent('BasePower', battle.getFormat(), -100, function (bp, attacker, defender, move) { + battle.onEvent('BasePower', battle.format, -100, function (bp, attacker, defender, move) { bpModifiers.set(move.id, this.event.modifier); }); battle.makeChoices('move fusionflare 2, move instruct -1', 'default'); @@ -55,7 +55,7 @@ describe('Fusion Bolt + Fusion Flare', function () { battle.makeChoices(); let bpModifiers = new Map(); - battle.onEvent('BasePower', battle.getFormat(), -100, function (bp, attacker, defender, move) { + battle.onEvent('BasePower', battle.format, -100, function (bp, attacker, defender, move) { bpModifiers.set(move.id, this.event.modifier); }); battle.makeChoices('move fusionbolt 1, move fusionflare 1', 'default'); diff --git a/test/sim/misc/statuses.js b/test/sim/misc/statuses.js index 1680098695..1197063df6 100644 --- a/test/sim/misc/statuses.js +++ b/test/sim/misc/statuses.js @@ -150,7 +150,7 @@ describe('Freeze', function () { [{species: 'Shaymin-Sky', ability: 'sturdy', moves: ['sleeptalk']}], ]); // I didn't feel like manually testing seed after seed. Sue me. - battle.onEvent('ModifyMove', battle.getFormat(), function (move) { + battle.onEvent('ModifyMove', battle.format, function (move) { if (move.secondaries) { this.debug('Freeze test: Guaranteeing secondary'); for (const secondary of move.secondaries) { @@ -168,7 +168,7 @@ describe('Freeze', function () { [{species: 'Ditto', ability: 'imposter', moves: ['transform']}], [{species: 'Shaymin-Sky', ability: 'sturdy', moves: ['icebeam', 'sleeptalk']}], ]); - battle.onEvent('ModifyMove', battle.getFormat(), function (move) { + battle.onEvent('ModifyMove', battle.format, function (move) { if (move.secondaries) { this.debug('Freeze test: Guaranteeing secondary'); for (const secondary of move.secondaries) { diff --git a/test/sim/misc/statusmoves.js b/test/sim/misc/statusmoves.js index 8d3d043e14..dff30864f1 100644 --- a/test/sim/misc/statusmoves.js +++ b/test/sim/misc/statusmoves.js @@ -83,7 +83,7 @@ describe('Poison-inflicting status moves [Gen 2]', function () { [{species: "Magneton", moves: ['sleeptalk']}], ]); // Set all moves to perfect accuracy - battle.onEvent('Accuracy', battle.getFormat(), true); + battle.onEvent('Accuracy', battle.format, true); const target = battle.p2.active[0]; for (const move of POISON_STATUS_MOVES) { diff --git a/test/sim/misc/weight.js b/test/sim/misc/weight.js index b763b53e1e..2107612ed2 100644 --- a/test/sim/misc/weight.js +++ b/test/sim/misc/weight.js @@ -16,7 +16,7 @@ describe('Heavy Metal', function () { [{species: "Simisage", ability: 'gluttony', moves: ['grassknot']}], ]); let basePower = 0; - battle.onEvent('BasePower', battle.getFormat(), function (bp, attacker, defender, move) { + battle.onEvent('BasePower', battle.format, function (bp, attacker, defender, move) { if (move.id === 'grassknot') { basePower = bp; } @@ -31,7 +31,7 @@ describe('Heavy Metal', function () { [{species: "Simisage", ability: 'moldbreaker', moves: ['grassknot']}], ]); let basePower = 0; - battle.onEvent('BasePower', battle.getFormat(), function (bp, attacker, defender, move) { + battle.onEvent('BasePower', battle.format, function (bp, attacker, defender, move) { if (move.id === 'grassknot') { basePower = bp; } @@ -52,7 +52,7 @@ describe('Light Metal', function () { [{species: "Simisage", ability: 'gluttony', moves: ['grassknot']}], ]); let basePower = 0; - battle.onEvent('BasePower', battle.getFormat(), function (bp, attacker, defender, move) { + battle.onEvent('BasePower', battle.format, function (bp, attacker, defender, move) { if (move.id === 'grassknot') { basePower = bp; } @@ -67,7 +67,7 @@ describe('Light Metal', function () { [{species: "Simisage", ability: 'moldbreaker', moves: ['grassknot']}], ]); let basePower = 0; - battle.onEvent('BasePower', battle.getFormat(), function (bp, attacker, defender, move) { + battle.onEvent('BasePower', battle.format, function (bp, attacker, defender, move) { if (move.id === 'grassknot') { basePower = bp; } @@ -88,7 +88,7 @@ describe('Float Stone', function () { [{species: "Simisage", ability: 'gluttony', moves: ['grassknot']}], ]); let basePower = 0; - battle.onEvent('BasePower', battle.getFormat(), function (bp, attacker, defender, move) { + battle.onEvent('BasePower', battle.format, function (bp, attacker, defender, move) { if (move.id === 'grassknot') { basePower = bp; } @@ -109,7 +109,7 @@ describe('Autotomize', function () { [{species: "Simisage", ability: 'gluttony', item: 'laggingtail', moves: ['grassknot']}], ]); let basePower = 0; - battle.onEvent('BasePower', battle.getFormat(), function (bp, attacker, defender, move) { + battle.onEvent('BasePower', battle.format, function (bp, attacker, defender, move) { if (move.id === 'grassknot') { basePower = bp; } @@ -126,7 +126,7 @@ describe('Autotomize', function () { [{species: "Simisage", ability: 'gluttony', item: 'laggingtail', moves: ['grassknot']}], ]); let basePower = 0; - battle.onEvent('BasePower', battle.getFormat(), function (bp, attacker, defender, move) { + battle.onEvent('BasePower', battle.format, function (bp, attacker, defender, move) { if (move.id === 'grassknot') { basePower = bp; } @@ -141,7 +141,7 @@ describe('Autotomize', function () { [{species: "Simisage", ability: 'gluttony', item: 'laggingtail', moves: ['grassknot']}], ]); let basePower = 0; - battle.onEvent('BasePower', battle.getFormat(), function (bp, attacker, defender, move) { + battle.onEvent('BasePower', battle.format, function (bp, attacker, defender, move) { if (move.id === 'grassknot') { basePower = bp; } diff --git a/test/sim/moves/counter.js b/test/sim/moves/counter.js index f4eb6f8d57..13050d2bc6 100644 --- a/test/sim/moves/counter.js +++ b/test/sim/moves/counter.js @@ -22,7 +22,7 @@ describe('Counter', function () { battle.setPlayer('p1', {team: [{species: 'Sawk', ability: 'sturdy', moves: ['doublekick']}]}); battle.setPlayer('p2', {team: [{species: 'Throh', ability: 'guts', moves: ['counter']}]}); let lastDamage = 0; - battle.onEvent('Damage', battle.getFormat(), function (damage, attacker, defender, move) { + battle.onEvent('Damage', battle.format, function (damage, attacker, defender, move) { if (move.id === 'doublekick') { lastDamage = damage; } @@ -90,7 +90,7 @@ describe('Mirror Coat', function () { battle.setPlayer('p1', {team: [{species: 'Espeon', ability: 'synchronize', moves: ['watershuriken']}]}); battle.setPlayer('p2', {team: [{species: 'Umbreon', ability: 'synchronize', moves: ['mirrorcoat']}]}); let lastDamage = 0; - battle.onEvent('Damage', battle.getFormat(), function (damage, attacker, defender, move) { + battle.onEvent('Damage', battle.format, function (damage, attacker, defender, move) { if (move.id === 'watershuriken') { lastDamage = damage; } diff --git a/test/sim/moves/followme.js b/test/sim/moves/followme.js index a332135e29..6857a472b7 100644 --- a/test/sim/moves/followme.js +++ b/test/sim/moves/followme.js @@ -25,7 +25,7 @@ describe('Follow Me', function () { {species: 'Alakazam', ability: 'synchronize', moves: ['lowkick']}, ]}); let hitCount = 0; - battle.onEvent('Damage', battle.getFormat(), function (damage, pokemon) { + battle.onEvent('Damage', battle.format, function (damage, pokemon) { if (pokemon.template.speciesid === 'clefable') { hitCount++; } diff --git a/test/sim/moves/rollout.js b/test/sim/moves/rollout.js index f725dfcee9..9277ccf32b 100644 --- a/test/sim/moves/rollout.js +++ b/test/sim/moves/rollout.js @@ -23,7 +23,7 @@ for (const move of moves) { let ebp = 30; let count = 0; - battle.onEvent('BasePower', battle.getFormat(), function (basePower) { + battle.onEvent('BasePower', battle.format, function (basePower) { count++; assert.strictEqual(basePower, ebp); if (count % 5 === 0) { @@ -47,7 +47,7 @@ for (const move of moves) { let ebp = 30; let count = 0; - battle.onEvent('Accuracy', battle.getFormat(), function (accuracy, target, pokemon, move) { + battle.onEvent('Accuracy', battle.format, function (accuracy, target, pokemon, move) { if (move.id === 'recover') return; count++; @@ -58,7 +58,7 @@ for (const move of moves) { return true; } }); - battle.onEvent('BasePower', battle.getFormat(), function (basePower) { + battle.onEvent('BasePower', battle.format, function (basePower) { assert.strictEqual(basePower, ebp); ebp *= 2; }); @@ -77,7 +77,7 @@ for (const move of moves) { let ebp = 30; let count = 0; - battle.onEvent('BeforeMove', battle.getFormat(), function (attacker, defender, move) { + battle.onEvent('BeforeMove', battle.format, function (attacker, defender, move) { if (move.id === 'recover') return; count++; @@ -86,7 +86,7 @@ for (const move of moves) { return false; // Imitate immobilization from Paralysis, etc. } }); - battle.onEvent('BasePower', battle.getFormat(), function (basePower) { + battle.onEvent('BasePower', battle.format, function (basePower) { assert.strictEqual(basePower, ebp); ebp *= 2; }); @@ -104,7 +104,7 @@ for (const move of moves) { ]); let runCount = 0; - battle.onEvent('BasePower', battle.getFormat(), function (basePower) { + battle.onEvent('BasePower', battle.format, function (basePower) { assert.strictEqual(basePower, 60); runCount++; }); @@ -121,7 +121,7 @@ for (const move of moves) { ]); let hitCount = 0; - battle.onEvent('BasePower', battle.getFormat(), function (basePower) { + battle.onEvent('BasePower', battle.format, function (basePower) { assert.strictEqual(basePower, 30); hitCount++; }); diff --git a/test/sim/moves/skydrop.js b/test/sim/moves/skydrop.js index fdcf9632f5..3704701a18 100644 --- a/test/sim/moves/skydrop.js +++ b/test/sim/moves/skydrop.js @@ -161,7 +161,7 @@ describe('Sky Drop', function () { [{species: "Aerodactyl", ability: 'unnerve', moves: ['skydrop']}, {species: "Kabutops", ability: 'swiftswim', moves: ['aquajet']}], [{species: "Lairon", ability: 'sturdy', moves: ['bulkup']}, {species: "Azumarill", ability: 'thickfat', moves: ['aquajet']}], ]); - battle.onEvent('Damage', battle.getFormat(), function (damage, target, source, effect) { + battle.onEvent('Damage', battle.format, function (damage, target, source, effect) { // mod Sky Drop to deal no damage if (effect.id === 'skydrop') return 0; }); diff --git a/test/sim/moves/stompingtantrum.js b/test/sim/moves/stompingtantrum.js index fa3d738992..7537f3168b 100644 --- a/test/sim/moves/stompingtantrum.js +++ b/test/sim/moves/stompingtantrum.js @@ -16,7 +16,7 @@ describe('Stomping Tantrum', function () { [{species: 'Manaphy', ability: 'hydration', moves: ['rest']}], ]); - battle.onEvent('BasePower', battle.getFormat(), function (basePower) { + battle.onEvent('BasePower', battle.format, function (basePower) { assert.strictEqual(basePower, 150); }); @@ -32,7 +32,7 @@ describe('Stomping Tantrum', function () { [{species: 'Manaphy', ability: 'hydration', moves: ['protect', 'tailglow']}], ]); - battle.onEvent('BasePower', battle.getFormat(), function (basePower) { + battle.onEvent('BasePower', battle.format, function (basePower) { assert.strictEqual(basePower, 75); }); @@ -51,7 +51,7 @@ describe('Stomping Tantrum', function () { {species: 'Ho-Oh', ability: 'pressure', moves: ['recover']}, ]}); - battle.onEvent('BasePower', battle.getFormat(), function (basePower, attacker, defender, move) { + battle.onEvent('BasePower', battle.format, function (basePower, attacker, defender, move) { if (move.id === 'stompingtantrum') assert.strictEqual(basePower, 150); }); @@ -65,7 +65,7 @@ describe('Stomping Tantrum', function () { [{species: 'Manaphy', ability: 'hydration', moves: ['rest']}], ]); - battle.onEvent('BasePower', battle.getFormat(), function (basePower) { + battle.onEvent('BasePower', battle.format, function (basePower) { assert.strictEqual(basePower, 75); }); @@ -79,7 +79,7 @@ describe('Stomping Tantrum', function () { [{species: 'Lycanroc-Midnight', ability: 'noguard', moves: ['sleeptalk']}], ]); - battle.onEvent('BasePower', battle.getFormat(), function (basePower, pokemon, target, move) { + battle.onEvent('BasePower', battle.format, function (basePower, pokemon, target, move) { if (move.id === 'stompingtantrum') assert.strictEqual(basePower, 75); }); diff --git a/test/sim/moves/transform.js b/test/sim/moves/transform.js index f0b227fac3..34701c098e 100644 --- a/test/sim/moves/transform.js +++ b/test/sim/moves/transform.js @@ -65,7 +65,7 @@ describe('Transform', function () { for (let i = 0; i < p1poke.moves.length; i++) { let move = p1poke.moves[i]; assert.strictEqual(move, p2poke.moves[i]); - move = battle.getMove(move); + move = battle.dex.getMove(move); let movepp = p1poke.getMoveData(move); assert.strictEqual(movepp.pp, 5); } diff --git a/test/sim/moves/trickroom.js b/test/sim/moves/trickroom.js index 2de985ab24..f150a8ca55 100644 --- a/test/sim/moves/trickroom.js +++ b/test/sim/moves/trickroom.js @@ -85,7 +85,7 @@ describe('Trick Room', function () { battle.p1.active[0].boostBy({spe: 4}); // 1809 Speed battle.p2.active[0].boostBy({spe: 6}); // 1808 Speed - battle.onEvent('BasePower', battle.getFormat(), function (bp, pokemon, target, move) { + battle.onEvent('BasePower', battle.format, function (bp, pokemon, target, move) { if (move.id !== 'gyroball') return; assert.strictEqual(bp, 25); // BP should theoretically be this based on speed values }); diff --git a/test/sim/moves/trumpcard.js b/test/sim/moves/trumpcard.js index 74aaf025a5..83ca15f54b 100644 --- a/test/sim/moves/trumpcard.js +++ b/test/sim/moves/trumpcard.js @@ -17,7 +17,7 @@ describe('Trump Card', function () { ]); const basePowers = []; - battle.onEvent('BasePower', battle.getFormat(), function (bp, attacker, defender, move) { + battle.onEvent('BasePower', battle.format, function (bp, attacker, defender, move) { if (move.id === 'trumpcard') { basePowers.push(bp); } @@ -37,7 +37,7 @@ describe('Trump Card', function () { ]); const basePowers = []; - battle.onEvent('BasePower', battle.getFormat(), function (bp, attacker, defender, move) { + battle.onEvent('BasePower', battle.format, function (bp, attacker, defender, move) { if (move.id === 'trumpcard') { basePowers.push(bp); } @@ -59,7 +59,7 @@ describe('Trump Card', function () { ]); const basePowers = []; - battle.onEvent('BasePower', battle.getFormat(), function (bp, attacker, defender, move) { + battle.onEvent('BasePower', battle.format, function (bp, attacker, defender, move) { if (move.id === 'trumpcard') { basePowers.push(bp); }