Refactor more things to use pokemon.allies/foes

(This will make multi battles easier to implement.)
This commit is contained in:
Guangcong Luo 2021-03-28 20:06:18 -07:00
parent d6e7df506f
commit d18c0a4e1f
16 changed files with 68 additions and 111 deletions

View File

@ -1402,11 +1402,9 @@ export const Formats: FormatList = [
},
field: {
suppressingWeather() {
for (const side of this.battle.sides) {
for (const pokemon of side.active) {
if (pokemon && !pokemon.ignoringAbility() && pokemon.hasAbility('Cloud Nine')) {
return true;
}
for (const pokemon of this.battle.getAllActive()) {
if (pokemon && !pokemon.ignoringAbility() && pokemon.hasAbility('Cloud Nine')) {
return true;
}
}
return false;

View File

@ -126,8 +126,7 @@ export const Abilities: {[abilityid: string]: AbilityData} = {
},
anticipation: {
onStart(pokemon) {
for (const target of pokemon.side.foe.active) {
if (!target || target.fainted) continue;
for (const target of pokemon.foes()) {
for (const moveSlot of target.moveSlots) {
const move = this.dex.getMove(moveSlot.move);
if (move.category === 'Status') continue;
@ -227,8 +226,7 @@ export const Abilities: {[abilityid: string]: AbilityData} = {
onResidualSubOrder: 1,
onResidual(pokemon) {
if (!pokemon.hp) return;
for (const target of pokemon.side.foe.active) {
if (!target?.hp) continue;
for (const target of pokemon.foes()) {
if (target.status === 'slp' || target.hasAbility('comatose')) {
this.damage(target.baseMaxhp / 8, target, pokemon);
}
@ -533,11 +531,9 @@ export const Abilities: {[abilityid: string]: AbilityData} = {
},
curiousmedicine: {
onStart(pokemon) {
for (const ally of pokemon.side.active) {
if (ally !== pokemon) {
ally.clearBoosts();
this.add('-clearboost', ally, '[from] ability: Curious Medicine', '[of] ' + pokemon);
}
for (const ally of pokemon.adjacentAllies()) {
ally.clearBoosts();
this.add('-clearboost', ally, '[from] ability: Curious Medicine', '[of] ' + pokemon);
}
},
name: "Curious Medicine",
@ -771,8 +767,7 @@ export const Abilities: {[abilityid: string]: AbilityData} = {
onStart(pokemon) {
let totaldef = 0;
let totalspd = 0;
for (const target of pokemon.side.foe.active) {
if (!target || target.fainted) continue;
for (const target of pokemon.foes()) {
totaldef += target.getStat('def', false, true);
totalspd += target.getStat('spd', false, true);
}
@ -1109,8 +1104,7 @@ export const Abilities: {[abilityid: string]: AbilityData} = {
onStart(pokemon) {
let warnMoves: (Move | Pokemon)[][] = [];
let warnBp = 1;
for (const target of pokemon.side.foe.active) {
if (target.fainted) continue;
for (const target of pokemon.foes()) {
for (const moveSlot of target.moveSlots) {
const move = this.dex.getMove(moveSlot.move);
let bp = move.basePower;
@ -1147,8 +1141,7 @@ export const Abilities: {[abilityid: string]: AbilityData} = {
},
frisk: {
onStart(pokemon) {
for (const target of pokemon.side.foe.active) {
if (!target?.hp) continue;
for (const target of pokemon.foes()) {
if (target.item) {
this.add('-item', target, target.getItem().name, '[from] ability: Frisk', '[of] ' + pokemon, '[identify]');
}
@ -1359,9 +1352,6 @@ export const Abilities: {[abilityid: string]: AbilityData} = {
onResidualOrder: 5,
onResidualSubOrder: 4,
onResidual(pokemon) {
if (pokemon.side.active.length === 1) {
return;
}
for (const allyActive of pokemon.adjacentAllies()) {
if (allyActive.status && this.randomChance(3, 10)) {
this.add('-activate', pokemon, 'ability: Healer');
@ -2044,14 +2034,8 @@ export const Abilities: {[abilityid: string]: AbilityData} = {
minus: {
onModifySpAPriority: 5,
onModifySpA(spa, pokemon) {
if (pokemon.side.active.length === 1) {
return;
}
for (const allyActive of pokemon.side.active) {
if (
allyActive && allyActive.position !== pokemon.position &&
!allyActive.fainted && allyActive.hasAbility(['minus', 'plus'])
) {
for (const allyActive of pokemon.allies()) {
if (allyActive.hasAbility(['minus', 'plus'])) {
return this.chainModify(1.5);
}
}
@ -2474,7 +2458,7 @@ export const Abilities: {[abilityid: string]: AbilityData} = {
},
pastelveil: {
onStart(pokemon) {
for (const ally of pokemon.allies()) {
for (const ally of pokemon.alliesAndSelf()) {
if (['psn', 'tox'].includes(ally.status)) {
this.add('-activate', pokemon, 'ability: Pastel Veil');
ally.cureStatus();
@ -2593,14 +2577,8 @@ export const Abilities: {[abilityid: string]: AbilityData} = {
plus: {
onModifySpAPriority: 5,
onModifySpA(spa, pokemon) {
if (pokemon.side.active.length === 1) {
return;
}
for (const allyActive of pokemon.side.active) {
if (
allyActive && allyActive.position !== pokemon.position &&
!allyActive.fainted && allyActive.hasAbility(['minus', 'plus'])
) {
for (const allyActive of pokemon.allies()) {
if (allyActive.hasAbility(['minus', 'plus'])) {
return this.chainModify(1.5);
}
}

View File

@ -135,8 +135,7 @@ export const Abilities: {[k: string]: ModdedAbilityData} = {
onStart(pokemon) {
let warnMoves: Move[] = [];
let warnBp = 1;
for (const target of pokemon.side.foe.active) {
if (target.fainted) continue;
for (const target of pokemon.foes()) {
for (const moveSlot of target.moveSlots) {
const move = this.dex.getMove(moveSlot.move);
let bp = move.basePower;

View File

@ -673,8 +673,7 @@ export const Moves: {[k: string]: ModdedMoveData} = {
inherit: true,
flags: {authentic: 1},
onTryHit(pokemon) {
for (const target of pokemon.side.foe.active) {
if (!target || target.fainted) continue;
for (const target of pokemon.foes()) {
for (const move of pokemon.moves) {
if (target.moves.includes(move)) return;
}
@ -720,7 +719,7 @@ export const Moves: {[k: string]: ModdedMoveData} = {
if (target !== source && target.side === this.effectData.target && this.getCategory(move) === 'Special') {
if (!target.getMoveHitData(move).crit && !move.infiltrates) {
this.debug('Light Screen weaken');
if (target.allies().length > 1) return this.chainModify(2, 3);
if (target.alliesAndSelf().length > 1) return this.chainModify(2, 3);
return this.chainModify(0.5);
}
}
@ -1031,7 +1030,7 @@ export const Moves: {[k: string]: ModdedMoveData} = {
if (target !== source && target.side === this.effectData.target && this.getCategory(move) === 'Physical') {
if (!target.getMoveHitData(move).crit && !move.infiltrates) {
this.debug('Reflect weaken');
if (target.allies().length > 1) return this.chainModify(2, 3);
if (target.alliesAndSelf().length > 1) return this.chainModify(2, 3);
return this.chainModify(0.5);
}
}

View File

@ -2,8 +2,7 @@ export const Abilities: {[k: string]: ModdedAbilityData} = {
anticipation: {
inherit: true,
onStart(pokemon) {
for (const target of pokemon.side.foe.active) {
if (!target || target.fainted) continue;
for (const target of pokemon.foes()) {
for (const moveSlot of target.moveSlots) {
const move = this.dex.getMove(moveSlot.move);
if (move.category !== 'Status' && (

View File

@ -330,8 +330,7 @@ export const Abilities: {[k: string]: ModdedAbilityData} = {
}
let totaldef = 0;
let totalspd = 0;
for (const foe of pokemon.side.foe.active) {
if (!foe || foe.fainted) continue;
for (const foe of pokemon.foes()) {
totaldef += foe.storedStats.def;
totalspd += foe.storedStats.spd;
}

View File

@ -301,8 +301,7 @@ export const Abilities: {[abilityid: string]: ModdedAbilityData} = {
shortDesc: "Summons hail on switch-in. If foe has a supereffective or OHKO move, summons rain.",
onStart(source) {
this.field.setWeather('hail');
for (const target of source.side.foe.active) {
if (!target || target.fainted) continue;
for (const target of source.foes()) {
for (const moveSlot of target.moveSlots) {
const move = this.dex.getMove(moveSlot.move);
if (move.category === 'Status') continue;
@ -320,8 +319,7 @@ export const Abilities: {[abilityid: string]: ModdedAbilityData} = {
onAnySwitchIn(pokemon) {
const source = this.effectData.target;
if (pokemon === source) return;
for (const target of source.side.foe.active) {
if (!target || target.fainted) continue;
for (const target of source.foes()) {
for (const moveSlot of target.moveSlots) {
const move = this.dex.getMove(moveSlot.move);
if (move.category === 'Status') continue;
@ -1266,8 +1264,7 @@ export const Abilities: {[abilityid: string]: ModdedAbilityData} = {
onStart(pokemon) {
let totalatk = 0;
let totalspa = 0;
for (const target of pokemon.side.foe.active) {
if (!target || target.fainted) continue;
for (const target of pokemon.foes()) {
totalatk += target.getStat('atk', false, true);
totalspa += target.getStat('spa', false, true);
}

View File

@ -159,11 +159,10 @@ export const Scripts: ModdedBattleScriptsData = {
runMegaEvo(pokemon) {
const speciesid = pokemon.canMegaEvo || pokemon.canUltraBurst;
if (!speciesid) return false;
const side = pokemon.side;
// Pokémon affected by Sky Drop cannot mega evolve. Enforce it here for now.
for (const foeActive of side.foe.active) {
if (foeActive.volatiles['skydrop'] && foeActive.volatiles['skydrop'].source === pokemon) {
for (const foeActive of pokemon.foes()) {
if (foeActive.volatiles['skydrop']?.source === pokemon) {
return false;
}
}
@ -175,7 +174,7 @@ export const Scripts: ModdedBattleScriptsData = {
// Limit one mega evolution
const wasMega = pokemon.canMegaEvo;
for (const ally of side.pokemon) {
for (const ally of pokemon.alliesAndSelf()) {
if (wasMega) {
ally.canMegaEvo = null;
} else {

View File

@ -24,11 +24,10 @@ export const Scripts: ModdedBattleScriptsData = {
// @ts-ignore
const species: Species = this.getMixedSpecies(pokemon.m.originalSpecies, pokemon.canMegaEvo);
const side = pokemon.side;
// Pokémon affected by Sky Drop cannot Mega Evolve. Enforce it here for now.
for (const foeActive of side.foe.active) {
if (foeActive.volatiles['skydrop'] && foeActive.volatiles['skydrop'].source === pokemon) {
for (const foeActive of pokemon.foes()) {
if (foeActive.volatiles['skydrop']?.source === pokemon) {
return false;
}
}

View File

@ -26,11 +26,10 @@ export const Scripts: ModdedBattleScriptsData = {
const isUltraBurst = !pokemon.canMegaEvo;
// @ts-ignore
const species: Species = this.getMixedSpecies(pokemon.m.originalSpecies, pokemon.canMegaEvo || pokemon.canUltraBurst);
const side = pokemon.side;
// Pokémon affected by Sky Drop cannot Mega Evolve. Enforce it here for now.
for (const foeActive of side.foe.active) {
if (foeActive.volatiles['skydrop'] && foeActive.volatiles['skydrop'].source === pokemon) {
for (const foeActive of pokemon.foes()) {
if (foeActive.volatiles['skydrop']?.source === pokemon) {
return false;
}
}

View File

@ -1641,13 +1641,11 @@ export const Abilities: {[k: string]: ModdedAbilityData} = {
onStart(pokemon) {
let totalatk = 0;
let totalspa = 0;
for (const target of pokemon.side.foe.active) {
if (!target || target.fainted) continue;
for (const target of pokemon.foes()) {
totalatk += target.getStat('atk', false, true);
totalspa += target.getStat('spa', false, true);
}
for (const target of pokemon.side.foe.active) {
if (!target || target.fainted) continue;
for (const target of pokemon.foes()) {
this.add('-ability', pokemon, 'BURN IT DOWN!');
if (totalatk && totalatk >= totalspa) {
this.boost({atk: -1}, target, pokemon, null, true);

View File

@ -61,8 +61,7 @@ export const Moves: {[k: string]: ModdedMoveData} = {
},
onHit(target, source, move) {
if (this.randomChance(1, 10)) {
for (const foe of source.side.foe.active) {
if (!foe || foe.fainted) continue;
for (const foe of source.foes()) {
foe.trySetStatus('brn', source);
}
}
@ -4207,8 +4206,7 @@ export const Moves: {[k: string]: ModdedMoveData} = {
onHit(source) {
let totalatk = 0;
let totalspa = 0;
for (const target of source.side.foe.active) {
if (!target || target.fainted) continue;
for (const target of source.foes()) {
totalatk += target.getStat('atk', false, true);
totalspa += target.getStat('spa', false, true);
if (totalatk && totalatk >= totalspa) {

View File

@ -7,11 +7,10 @@ export const Scripts: ModdedBattleScriptsData = {
if (pokemon.name === 'Raj.Shoot' && pokemon.species.name === 'Charizard') pokemon.canMegaEvo = 'Charizard-Mega-X';
const speciesid = pokemon.canMegaEvo || pokemon.canUltraBurst;
if (!speciesid) return false;
const side = pokemon.side;
// Pokémon affected by Sky Drop cannot mega evolve. Enforce it here for now.
for (const foeActive of side.foe.active) {
if (foeActive.volatiles['skydrop'] && foeActive.volatiles['skydrop'].source === pokemon) {
for (const foeActive of pokemon.foes()) {
if (foeActive.volatiles['skydrop']?.source === pokemon) {
return false;
}
}
@ -1013,8 +1012,7 @@ export const Scripts: ModdedBattleScriptsData = {
// canceling switches would leak information
// if a foe might have a trapping ability
if (this.gen > 2) {
for (const source of pokemon.side.foe.active) {
if (!source || source.fainted) continue;
for (const source of pokemon.foes()) {
const species = (source.illusion || source).species;
if (!species.abilities) continue;
for (const abilitySlot in species.abilities) {

View File

@ -5035,17 +5035,11 @@ export const Moves: {[moveid: string]: MoveData} = {
priority: 0,
flags: {protect: 1, mirror: 1},
onHit(target, source, move) {
if (target.side.active.length === 1) {
return;
}
for (const ally of target.adjacentAllies()) {
this.damage(ally.baseMaxhp / 16, ally, source, this.dex.getEffect('Flame Burst'));
}
},
onAfterSubDamage(damage, target, source, move) {
if (target.side.active.length === 1) {
return;
}
for (const ally of target.adjacentAllies()) {
this.damage(ally.baseMaxhp / 16, ally, source, this.dex.getEffect('Flame Burst'));
}
@ -5954,11 +5948,10 @@ export const Moves: {[moveid: string]: MoveData} = {
for (const pokemon of side.active) {
if (
pokemon.hasAbility(['plus', 'minus']) &&
(!pokemon.volatiles['maxguard'] ||
this.runEvent('TryHit', pokemon, source, move))
) {
(!pokemon.volatiles['maxguard'] || this.runEvent('TryHit', pokemon, source, move))
) {
targets.push(pokemon);
}
}
}
if (!targets.length) return false;
let didSomething = false;
@ -6154,7 +6147,7 @@ export const Moves: {[moveid: string]: MoveData} = {
isMax: "Butterfree",
self: {
onHit(source) {
for (const pokemon of source.side.foe.active) {
for (const pokemon of source.foes()) {
const result = this.random(3);
if (result === 0) {
pokemon.trySetStatus('slp', source);
@ -6223,7 +6216,7 @@ export const Moves: {[moveid: string]: MoveData} = {
isMax: "Centiskorch",
self: {
onHit(source) {
for (const pokemon of source.side.foe.active) {
for (const pokemon of source.foes()) {
pokemon.addVolatile('partiallytrapped', source, this.dex.getActiveMove('G-Max Centiferno'));
}
},
@ -6246,7 +6239,7 @@ export const Moves: {[moveid: string]: MoveData} = {
isMax: "Machamp",
self: {
onHit(source) {
for (const pokemon of source.side.active) {
for (const pokemon of source.alliesAndSelf()) {
pokemon.addVolatile('gmaxchistrike');
}
},
@ -6288,7 +6281,7 @@ export const Moves: {[moveid: string]: MoveData} = {
isMax: "Eevee",
self: {
onHit(source) {
for (const pokemon of source.side.foe.active) {
for (const pokemon of source.foes()) {
pokemon.addVolatile('attract');
}
},
@ -6311,7 +6304,7 @@ export const Moves: {[moveid: string]: MoveData} = {
isMax: "Duraludon",
self: {
onHit(source) {
for (const pokemon of source.side.foe.active) {
for (const pokemon of source.foes()) {
let move: Move | ActiveMove | null = pokemon.lastMove;
if (!move || move.isZ) continue;
if (move.isMax && move.baseMove) move = this.dex.getMove(move.baseMove);
@ -6360,7 +6353,7 @@ export const Moves: {[moveid: string]: MoveData} = {
isMax: "Alcremie",
self: {
onHit(target, source, move) {
for (const pokemon of source.side.active) {
for (const pokemon of source.alliesAndSelf()) {
this.heal(pokemon.maxhp / 6, pokemon, source, move);
}
},
@ -6400,7 +6393,7 @@ export const Moves: {[moveid: string]: MoveData} = {
isMax: "Kingler",
self: {
onHit(source) {
for (const pokemon of source.side.foe.active) {
for (const pokemon of source.foes()) {
this.boost({spe: -2}, pokemon);
}
},
@ -6423,7 +6416,7 @@ export const Moves: {[moveid: string]: MoveData} = {
isMax: "Meowth",
self: {
onHit(source) {
for (const pokemon of source.side.foe.active) {
for (const pokemon of source.foes()) {
pokemon.addVolatile('confusion');
}
},
@ -6481,7 +6474,7 @@ export const Moves: {[moveid: string]: MoveData} = {
isMax: "Garbodor",
self: {
onHit(source) {
for (const pokemon of source.side.foe.active) {
for (const pokemon of source.foes()) {
pokemon.trySetStatus('psn', source);
}
},
@ -6503,7 +6496,7 @@ export const Moves: {[moveid: string]: MoveData} = {
isMax: "Melmetal",
self: {
onHit(source) {
for (const pokemon of source.side.foe.active) {
for (const pokemon of source.foes()) {
if (!pokemon.volatiles['dynamax']) pokemon.addVolatile('torment');
}
},
@ -6559,8 +6552,8 @@ export const Moves: {[moveid: string]: MoveData} = {
self: {
onHit(source) {
if (this.random(2) === 0) return;
for (const pokemon of source.side.active) {
if (!pokemon.hp || pokemon.item) continue;
for (const pokemon of source.alliesAndSelf()) {
if (pokemon.item) continue;
if (pokemon.lastItem && this.dex.getItem(pokemon.lastItem).isBerry) {
const item = pokemon.lastItem;
@ -6608,7 +6601,7 @@ export const Moves: {[moveid: string]: MoveData} = {
isMax: "Sandaconda",
self: {
onHit(source) {
for (const pokemon of source.side.foe.active) {
for (const pokemon of source.foes()) {
pokemon.addVolatile('partiallytrapped', source, this.dex.getActiveMove('G-Max Sandblast'));
}
},
@ -6631,7 +6624,7 @@ export const Moves: {[moveid: string]: MoveData} = {
isMax: "Hatterene",
self: {
onHit(source) {
for (const pokemon of source.side.foe.active) {
for (const pokemon of source.foes()) {
pokemon.addVolatile('confusion', source);
}
},
@ -6738,7 +6731,7 @@ export const Moves: {[moveid: string]: MoveData} = {
isMax: "Toxtricity",
self: {
onHit(source) {
for (const pokemon of source.side.foe.active) {
for (const pokemon of source.foes()) {
const result = this.random(2);
if (result === 0) {
pokemon.trySetStatus('par', source);
@ -6789,7 +6782,7 @@ export const Moves: {[moveid: string]: MoveData} = {
isMax: "Flapple",
self: {
onHit(source) {
for (const pokemon of source.side.foe.active) {
for (const pokemon of source.foes()) {
this.boost({evasion: -1}, pokemon);
}
},
@ -6812,7 +6805,7 @@ export const Moves: {[moveid: string]: MoveData} = {
isMax: "Gengar",
self: {
onHit(source) {
for (const pokemon of source.side.foe.active) {
for (const pokemon of source.foes()) {
pokemon.addVolatile('trapped', source, null, 'trapper');
}
},

View File

@ -811,7 +811,7 @@ export class Battle {
}
if (target instanceof Pokemon && target.isActive) {
handlers = this.findPokemonEventHandlers(target, `on${eventName}`);
for (const allyActive of target.allies()) {
for (const allyActive of target.alliesAndSelf()) {
handlers.push(...this.findPokemonEventHandlers(allyActive, `onAlly${eventName}`));
handlers.push(...this.findPokemonEventHandlers(allyActive, `onAny${eventName}`));
}

View File

@ -605,7 +605,7 @@ export class Pokemon {
});
}
allies(): Pokemon[] {
alliesAndSelf(): Pokemon[] {
let allies = this.side.active;
if (this.battle.gameType === 'multi') {
const team = this.side.n % 2;
@ -616,8 +616,12 @@ export class Pokemon {
return allies.filter(ally => ally && !ally.fainted);
}
allies(): Pokemon[] {
return this.alliesAndSelf().filter(ally => ally !== this);
}
adjacentAllies(): Pokemon[] {
return this.allies().filter(ally => this.isAdjacent(ally));
return this.alliesAndSelf().filter(ally => this.isAdjacent(ally));
}
foes(): Pokemon[] {
@ -680,7 +684,7 @@ export class Pokemon {
case 'allySide':
case 'allyTeam':
if (!move.target.startsWith('foe')) {
targets.push(...this.allies());
targets.push(...this.alliesAndSelf());
}
if (!move.target.startsWith('ally')) {
targets.push(...this.foes());
@ -699,7 +703,7 @@ export class Pokemon {
}
break;
case 'allies':
targets = this.allies();
targets = this.alliesAndSelf();
break;
default:
const selectedTarget = target;