mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-06-02 22:08:36 -05:00
Merge 9c5003631f into 6765d8422d
This commit is contained in:
commit
bc35b3f4f6
|
|
@ -373,18 +373,20 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
beadsofruin: {
|
||||
onStart(pokemon) {
|
||||
if (this.suppressingAbility(pokemon)) return;
|
||||
this.add('-ability', pokemon, 'Beads of Ruin');
|
||||
this.field.addSourcedPseudoWeather('beadsofruin', pokemon, this.effect);
|
||||
},
|
||||
onAnyModifySpD(spd, target, source, move) {
|
||||
const abilityHolder = this.effectState.target;
|
||||
if (target.hasAbility('Beads of Ruin')) return;
|
||||
if (!move.ruinedSpD?.hasAbility('Beads of Ruin')) move.ruinedSpD = abilityHolder;
|
||||
if (move.ruinedSpD !== abilityHolder) return;
|
||||
this.debug('Beads of Ruin SpD drop');
|
||||
return this.chainModify(0.75);
|
||||
onEnd(pokemon) {
|
||||
this.field.removePseudoWeatherSource('beadsofruin', pokemon);
|
||||
},
|
||||
flags: {},
|
||||
condition: {
|
||||
onModifySpD(spd, target, source, move) {
|
||||
if (this.field.pseudoWeather['beadsofruin'].activeSources.includes(target)) return;
|
||||
this.debug('Beads of Ruin SpD drop');
|
||||
return this.chainModify(0.75);
|
||||
},
|
||||
},
|
||||
flags: { breakable: 1 },
|
||||
name: "Beads of Ruin",
|
||||
rating: 4.5,
|
||||
num: 284,
|
||||
|
|
@ -2862,60 +2864,56 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
onSwitchInPriority: 2,
|
||||
onSwitchIn(pokemon) {
|
||||
this.add('-ability', pokemon, 'Neutralizing Gas');
|
||||
pokemon.abilityState.ending = false;
|
||||
const strongWeathers = ['desolateland', 'primordialsea', 'deltastream'];
|
||||
for (const target of this.getAllActive()) {
|
||||
if (target.hasItem('Ability Shield')) {
|
||||
this.add('-block', target, 'item: Ability Shield');
|
||||
continue;
|
||||
}
|
||||
// Can't suppress a Tatsugiri inside of Dondozo already
|
||||
if (target.volatiles['commanding']) {
|
||||
continue;
|
||||
}
|
||||
if (target.illusion) {
|
||||
this.singleEvent('End', this.dex.abilities.get('Illusion'), target.abilityState, target, pokemon, 'neutralizinggas');
|
||||
}
|
||||
if (target.volatiles['slowstart']) {
|
||||
delete target.volatiles['slowstart'];
|
||||
this.add('-end', target, 'Slow Start', '[silent]');
|
||||
}
|
||||
if (strongWeathers.includes(target.getAbility().id)) {
|
||||
this.singleEvent('End', this.dex.abilities.get(target.getAbility().id), target.abilityState, target, pokemon, 'neutralizinggas');
|
||||
}
|
||||
}
|
||||
this.field.addSourcedPseudoWeather('neutralizinggas', pokemon, this.effect);
|
||||
},
|
||||
onEnd(source) {
|
||||
if (source.transformed) return;
|
||||
for (const pokemon of this.getAllActive()) {
|
||||
if (pokemon !== source && pokemon.hasAbility('Neutralizing Gas')) {
|
||||
return;
|
||||
}
|
||||
onEnd(pokemon) {
|
||||
if (!this.getAllActive().some(active => active !== pokemon && active.hasAbility('neutralizinggas'))) {
|
||||
this.add('-end', pokemon, 'ability: Neutralizing Gas');
|
||||
}
|
||||
this.add('-end', source, 'ability: Neutralizing Gas');
|
||||
|
||||
// FIXME this happens before the pokemon switches out, should be the opposite order.
|
||||
// Not an easy fix since we cant use a supported event. Would need some kind of special event that
|
||||
// gathers events to run after the switch and then runs them when the ability is no longer accessible.
|
||||
// (If you're tackling this, do note extreme weathers have the same issue)
|
||||
|
||||
// Mark this pokemon's ability as ending so Pokemon#ignoringAbility skips it
|
||||
if (source.abilityState.ending) return;
|
||||
source.abilityState.ending = true;
|
||||
const sortedActive = this.getAllActive();
|
||||
this.speedSort(sortedActive);
|
||||
for (const pokemon of sortedActive) {
|
||||
if (pokemon !== source) {
|
||||
this.field.removePseudoWeatherSource('neutralizinggas', pokemon);
|
||||
},
|
||||
condition: {
|
||||
onFieldStart() {
|
||||
const strongWeathers = ['desolateland', 'primordialsea', 'deltastream'];
|
||||
for (const target of this.getAllActive()) {
|
||||
if (target.hasItem('Ability Shield')) {
|
||||
this.add('-block', target, 'item: Ability Shield');
|
||||
continue;
|
||||
}
|
||||
// Can't suppress a Tatsugiri inside of Dondozo already
|
||||
if (target.volatiles['commanding']) continue;
|
||||
if (target.illusion) {
|
||||
this.singleEvent('End', this.dex.abilities.get('Illusion'), target.abilityState, target, null, 'neutralizinggas');
|
||||
}
|
||||
if (target.volatiles['slowstart']) {
|
||||
delete target.volatiles['slowstart'];
|
||||
this.add('-end', target, 'Slow Start', '[silent]');
|
||||
}
|
||||
if (strongWeathers.includes(target.getAbility().id)) {
|
||||
this.singleEvent('End', this.dex.abilities.get(target.getAbility().id), target.abilityState, target, null, 'neutralizinggas');
|
||||
}
|
||||
}
|
||||
},
|
||||
onFieldEnd() {
|
||||
const sortedActive = this.getAllActive();
|
||||
this.speedSort(sortedActive);
|
||||
for (const pokemon of sortedActive) {
|
||||
if (pokemon.getAbility().flags['cantsuppress']) continue; // does not interact with e.g Ice Face, Zen Mode
|
||||
if (pokemon.hasItem('abilityshield')) continue; // don't restart abilities that weren't suppressed
|
||||
|
||||
// Will be suppressed by Pokemon#ignoringAbility if needed
|
||||
this.singleEvent('Start', pokemon.getAbility(), pokemon.abilityState, pokemon);
|
||||
if (pokemon.ability === "gluttony") {
|
||||
if (pokemon.ability === 'gluttony') {
|
||||
pokemon.abilityState.gluttony = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
|
||||
name: "Neutralizing Gas",
|
||||
|
|
@ -4775,18 +4773,20 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
swordofruin: {
|
||||
onStart(pokemon) {
|
||||
if (this.suppressingAbility(pokemon)) return;
|
||||
this.add('-ability', pokemon, 'Sword of Ruin');
|
||||
this.field.addSourcedPseudoWeather('swordofruin', pokemon, this.effect);
|
||||
},
|
||||
onAnyModifyDef(def, target, source, move) {
|
||||
const abilityHolder = this.effectState.target;
|
||||
if (target.hasAbility('Sword of Ruin')) return;
|
||||
if (!move.ruinedDef?.hasAbility('Sword of Ruin')) move.ruinedDef = abilityHolder;
|
||||
if (move.ruinedDef !== abilityHolder) return;
|
||||
this.debug('Sword of Ruin Def drop');
|
||||
return this.chainModify(0.75);
|
||||
onEnd(pokemon) {
|
||||
this.field.removePseudoWeatherSource('swordofruin', pokemon);
|
||||
},
|
||||
flags: {},
|
||||
condition: {
|
||||
onModifyDef(def, target, source, move) {
|
||||
if (this.field.pseudoWeather['swordofruin'].activeSources.includes(target)) return;
|
||||
this.debug('Sword of Ruin Def drop');
|
||||
return this.chainModify(0.75);
|
||||
},
|
||||
},
|
||||
flags: { breakable: 1 },
|
||||
name: "Sword of Ruin",
|
||||
rating: 4.5,
|
||||
num: 285,
|
||||
|
|
@ -4828,18 +4828,20 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
tabletsofruin: {
|
||||
onStart(pokemon) {
|
||||
if (this.suppressingAbility(pokemon)) return;
|
||||
this.add('-ability', pokemon, 'Tablets of Ruin');
|
||||
this.field.addSourcedPseudoWeather('tabletsofruin', pokemon, this.effect);
|
||||
},
|
||||
onAnyModifyAtk(atk, source, target, move) {
|
||||
const abilityHolder = this.effectState.target;
|
||||
if (source.hasAbility('Tablets of Ruin')) return;
|
||||
if (!move.ruinedAtk) move.ruinedAtk = abilityHolder;
|
||||
if (move.ruinedAtk !== abilityHolder) return;
|
||||
this.debug('Tablets of Ruin Atk drop');
|
||||
return this.chainModify(0.75);
|
||||
onEnd(pokemon) {
|
||||
this.field.removePseudoWeatherSource('tabletsofruin', pokemon);
|
||||
},
|
||||
flags: {},
|
||||
condition: {
|
||||
onModifyAtk(atk, target, source, move) {
|
||||
if (this.field.pseudoWeather['tabletsofruin'].activeSources.includes(target)) return;
|
||||
this.debug('Tablets of Ruin Atk drop');
|
||||
return this.chainModify(0.75);
|
||||
},
|
||||
},
|
||||
flags: { breakable: 1 },
|
||||
name: "Tablets of Ruin",
|
||||
rating: 4.5,
|
||||
num: 284,
|
||||
|
|
@ -5241,18 +5243,20 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
vesselofruin: {
|
||||
onStart(pokemon) {
|
||||
if (this.suppressingAbility(pokemon)) return;
|
||||
this.add('-ability', pokemon, 'Vessel of Ruin');
|
||||
this.field.addSourcedPseudoWeather('vesselofruin', pokemon, this.effect);
|
||||
},
|
||||
onAnyModifySpA(spa, source, target, move) {
|
||||
const abilityHolder = this.effectState.target;
|
||||
if (source.hasAbility('Vessel of Ruin')) return;
|
||||
if (!move.ruinedSpA) move.ruinedSpA = abilityHolder;
|
||||
if (move.ruinedSpA !== abilityHolder) return;
|
||||
this.debug('Vessel of Ruin SpA drop');
|
||||
return this.chainModify(0.75);
|
||||
onEnd(pokemon) {
|
||||
this.field.removePseudoWeatherSource('vesselofruin', pokemon);
|
||||
},
|
||||
flags: {},
|
||||
condition: {
|
||||
onModifySpA(spa, target, source, move) {
|
||||
if (this.field.pseudoWeather['vesselofruin'].activeSources.includes(target)) return;
|
||||
this.debug('Vessel of Ruin SpA drop');
|
||||
return this.chainModify(0.75);
|
||||
},
|
||||
},
|
||||
flags: { breakable: 1 },
|
||||
name: "Vessel of Ruin",
|
||||
rating: 4.5,
|
||||
num: 284,
|
||||
|
|
|
|||
|
|
@ -230,22 +230,23 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
desc: "Active Pokemon without this Ability have their Defense multiplied by 0.85x. This Pokemon's moves and their effects ignore certain Abilities of other Pokemon.",
|
||||
name: "Quag of Ruin",
|
||||
onStart(pokemon) {
|
||||
if (this.suppressingAbility(pokemon)) return;
|
||||
this.add('-ability', pokemon, 'Quag of Ruin');
|
||||
this.field.addSourcedPseudoWeather('quagofruin', pokemon, this.effect);
|
||||
},
|
||||
onAnyModifyDef(def, target, source, move) {
|
||||
if (!move) return;
|
||||
const abilityHolder = this.effectState.target;
|
||||
if (target.hasAbility('Quag of Ruin')) return;
|
||||
if (!move.ruinedDef?.hasAbility('Quag of Ruin')) move.ruinedDef = abilityHolder;
|
||||
if (move.ruinedDef !== abilityHolder) return;
|
||||
this.debug('Quag of Ruin Def drop');
|
||||
return this.chainModify(0.85);
|
||||
onEnd(pokemon) {
|
||||
this.field.removePseudoWeatherSource('quagofruin', pokemon);
|
||||
},
|
||||
condition: {
|
||||
onModifyDef(def, target, source, move) {
|
||||
if (this.field.pseudoWeather['quagofruin'].activeSources.includes(target)) return;
|
||||
this.debug('Quag of Ruin Def drop');
|
||||
return this.chainModify(0.85);
|
||||
},
|
||||
},
|
||||
onModifyMove(move) {
|
||||
move.ignoreAbility = true;
|
||||
},
|
||||
flags: {},
|
||||
flags: { breakable: 1 },
|
||||
gen: 9,
|
||||
},
|
||||
clodofruin: {
|
||||
|
|
@ -254,15 +255,17 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
name: "Clod of Ruin",
|
||||
onStart(pokemon) {
|
||||
this.add('-ability', pokemon, 'Clod of Ruin');
|
||||
this.field.addSourcedPseudoWeather('clodofruin', pokemon, this.effect);
|
||||
},
|
||||
onAnyModifyAtk(atk, target, source, move) {
|
||||
if (!move) return;
|
||||
const abilityHolder = this.effectState.target;
|
||||
if (target.hasAbility('Clod of Ruin')) return;
|
||||
if (!move.ruinedAtk?.hasAbility('Clod of Ruin')) move.ruinedAtk = abilityHolder;
|
||||
if (move.ruinedAtk !== abilityHolder) return;
|
||||
this.debug('Clod of Ruin Atk drop');
|
||||
return this.chainModify(0.85);
|
||||
onEnd(pokemon) {
|
||||
this.field.removePseudoWeatherSource('clodofruin', pokemon);
|
||||
},
|
||||
condition: {
|
||||
onModifyAtk(atk, target, source, move) {
|
||||
if (this.field.pseudoWeather['clodofruin'].activeSources.includes(target)) return;
|
||||
this.debug('Clod of Ruin Atk drop');
|
||||
return this.chainModify(0.85);
|
||||
},
|
||||
},
|
||||
onAnyModifyBoost(boosts, pokemon) {
|
||||
const unawareUser = this.effectState.target;
|
||||
|
|
@ -474,11 +477,17 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
onStart(pokemon) {
|
||||
this.add('-ability', pokemon, 'Blitz of Ruin');
|
||||
this.add('-message', `${pokemon.name}'s Blitz of Ruin lowered the Speed of all surrounding Pokémon!`);
|
||||
this.field.addSourcedPseudoWeather('blitzofruin', pokemon, this.effect);
|
||||
},
|
||||
onAnyModifySpe(spe, pokemon) {
|
||||
if (!pokemon.hasAbility('Blitz of Ruin')) {
|
||||
onEnd(pokemon) {
|
||||
this.field.removePseudoWeatherSource('blitzofruin', pokemon);
|
||||
},
|
||||
condition: {
|
||||
onModifySpe(spe, target) {
|
||||
if (this.field.pseudoWeather['blitzofruin'].activeSources.includes(target)) return;
|
||||
this.debug('Blitz of Ruin Spe drop');
|
||||
return this.chainModify(0.75);
|
||||
}
|
||||
},
|
||||
},
|
||||
flags: { breakable: 1 },
|
||||
},
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ export class BattleActions {
|
|||
// will definitely switch out at this point
|
||||
|
||||
this.battle.singleEvent('End', oldActive.getAbility(), oldActive.abilityState, oldActive);
|
||||
this.battle.field.removeSourceFromPseudoWeather(oldActive);
|
||||
this.battle.singleEvent('End', oldActive.getItem(), oldActive.itemState, oldActive);
|
||||
|
||||
// if a pokemon is forced out by Whirlwind/etc or Eject Button/Pack, it can't use its chosen move
|
||||
|
|
|
|||
|
|
@ -599,16 +599,16 @@ export class Battle {
|
|||
// it's changed; call it off
|
||||
return relayVar;
|
||||
}
|
||||
if (eventid === 'SwitchIn' && effect.effectType === 'Ability' && effect.flags['breakable'] &&
|
||||
this.suppressingAbility(target as Pokemon)) {
|
||||
this.debug(eventid + ' handler suppressed by Mold Breaker');
|
||||
return relayVar;
|
||||
}
|
||||
if (eventid !== 'Start' && eventid !== 'TakeItem' && eventid !== 'SetAbility' && effect.effectType === 'Item' &&
|
||||
(target instanceof Pokemon) && target.ignoringItem()) {
|
||||
this.debug(eventid + ' handler suppressed by Embargo, Klutz or Magic Room');
|
||||
return relayVar;
|
||||
}
|
||||
if ((['SwitchIn', 'Start', 'End', 'SwitchOut']).includes(eventid) && effect.effectType === 'Ability' &&
|
||||
effect.flags['breakable'] && this.suppressingAbility(target as Pokemon)) {
|
||||
this.debug(eventid + ' handler suppressed by Mold Breaker');
|
||||
return relayVar;
|
||||
}
|
||||
if (eventid !== 'End' && effect.effectType === 'Ability' && (target instanceof Pokemon) && target.ignoringAbility()) {
|
||||
this.debug(eventid + ' handler suppressed by Gastro Acid or Neutralizing Gas');
|
||||
return relayVar;
|
||||
|
|
|
|||
|
|
@ -339,10 +339,6 @@ export interface ActiveMove extends MutableMove {
|
|||
totalDamage?: number | false;
|
||||
typeChangerBoosted?: Effect;
|
||||
infiltrates?: boolean;
|
||||
ruinedAtk?: Pokemon;
|
||||
ruinedDef?: Pokemon;
|
||||
ruinedSpA?: Pokemon;
|
||||
ruinedSpD?: Pokemon;
|
||||
|
||||
/**
|
||||
* Has this move been boosted by a Z-crystal or used by a Dynamax Pokemon? Usually the same as
|
||||
|
|
|
|||
45
sim/field.ts
45
sim/field.ts
|
|
@ -229,6 +229,51 @@ export class Field {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a field effect if it is not already active and maintain a list of sources.
|
||||
* The field effect is only removed when all sources deactivate it.
|
||||
*/
|
||||
addSourcedPseudoWeather(
|
||||
status: string | Condition,
|
||||
source: Pokemon,
|
||||
sourceEffect: Effect | null = null
|
||||
): boolean {
|
||||
const returnValue = this.addPseudoWeather(status, source, sourceEffect);
|
||||
status = this.battle.dex.conditions.get(status);
|
||||
const state = this.pseudoWeather[status.id];
|
||||
if (state) {
|
||||
if (!state.activeSources) state.activeSources = [];
|
||||
state.activeSources.push(source);
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a source from a field effect. If no sources remain, the effect is removed.
|
||||
*/
|
||||
removePseudoWeatherSource(status: string | Effect, source: Pokemon) {
|
||||
status = this.battle.dex.conditions.get(status);
|
||||
const state = this.pseudoWeather[status.id];
|
||||
if (!state) return false;
|
||||
if (!state.activeSources) throw new Error(`removing pseudoweather without a source`);
|
||||
state.activeSources = state.activeSources.filter((s: Pokemon) => s !== source);
|
||||
if (state.activeSources.length) return false;
|
||||
delete this.pseudoWeather[status.id];
|
||||
this.battle.singleEvent('FieldEnd', status, state, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a source from all active field effects. Used when a Pokemon leaves the field.
|
||||
*/
|
||||
removeSourceFromPseudoWeather(source: Pokemon) {
|
||||
for (const id in this.pseudoWeather) {
|
||||
if (this.pseudoWeather[id].activeSources) {
|
||||
this.removePseudoWeatherSource(id, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
// deallocate ourself
|
||||
|
||||
|
|
|
|||
|
|
@ -870,15 +870,9 @@ export class Pokemon {
|
|||
if (this.getAbility().flags['cantsuppress']) return false;
|
||||
if (this.volatiles['gastroacid']) return true;
|
||||
|
||||
// Check if any active pokemon have the ability Neutralizing Gas
|
||||
if (this.hasItem('Ability Shield') || this.ability === ('neutralizinggas' as ID)) return false;
|
||||
for (const pokemon of this.battle.getAllActive()) {
|
||||
// can't use hasAbility because it would lead to infinite recursion
|
||||
if (pokemon.ability === ('neutralizinggas' as ID) && !pokemon.volatiles['gastroacid'] &&
|
||||
!pokemon.transformed && !pokemon.abilityState.ending && !this.volatiles['commanding']) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (this.volatiles['commanding']) return false;
|
||||
if (this.battle.field.getPseudoWeather('neutralizinggas')) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ describe(`Sword of Ruin`, () => {
|
|||
});
|
||||
|
||||
it(`should not lower the Defense of other Pokemon with the Sword of Ruin Ability`, () => {
|
||||
battle = common.createBattle({ forceRandomChance: false }, [[
|
||||
battle = common.createBattle([[
|
||||
{ species: 'wynaut', ability: 'swordofruin', moves: ['sleeptalk'] },
|
||||
], [
|
||||
{ species: 'chienpao', ability: 'swordofruin', moves: ['aerialace'] },
|
||||
|
|
@ -33,4 +33,78 @@ describe(`Sword of Ruin`, () => {
|
|||
const damage = wynaut.maxhp - wynaut.hp;
|
||||
assert.bounded(damage, [90, 107]);
|
||||
});
|
||||
|
||||
it(`effect should end if its ability is changed`, () => {
|
||||
battle = common.createBattle([[
|
||||
{ species: 'wynaut', ability: 'shellarmor', moves: ['worryseed'] },
|
||||
], [
|
||||
{ species: 'chienpao', ability: 'swordofruin', moves: ['aerialace'] },
|
||||
]]);
|
||||
battle.makeChoices();
|
||||
const wynaut = battle.p1.active[0];
|
||||
const hp = wynaut.hp;
|
||||
let damage = wynaut.maxhp - hp;
|
||||
assert.bounded(damage, [120, 142]);
|
||||
|
||||
battle.makeChoices();
|
||||
damage = hp - wynaut.hp;
|
||||
assert.bounded(damage, [90, 107]);
|
||||
});
|
||||
|
||||
it(`effect should not end if its ability is changed by a Mold Breaker move, but should end after switching out`, () => {
|
||||
battle = common.createBattle([[
|
||||
{ species: 'wynaut', ability: 'moldbreaker', moves: ['worryseed', 'recover'] },
|
||||
], [
|
||||
{ species: 'chienpao', ability: 'swordofruin', moves: ['aerialace'] },
|
||||
{ species: 'weavile', moves: ['aerialace'] },
|
||||
]]);
|
||||
battle.makeChoices();
|
||||
const wynaut = battle.p1.active[0];
|
||||
let damage = wynaut.maxhp - wynaut.hp;
|
||||
assert.bounded(damage, [120, 142]);
|
||||
|
||||
let hp = wynaut.hp;
|
||||
battle.makeChoices();
|
||||
damage = hp - wynaut.hp;
|
||||
assert.bounded(damage, [120, 142]);
|
||||
|
||||
battle.makeChoices('move recover', 'switch weavile');
|
||||
|
||||
hp = wynaut.hp;
|
||||
battle.makeChoices();
|
||||
damage = hp - wynaut.hp;
|
||||
assert.bounded(damage, [90, 107]);
|
||||
});
|
||||
|
||||
it(`should not lower the Defense of other Pokemon that lost its ability to a Mold Breaker move`, () => {
|
||||
battle = common.createBattle([[
|
||||
{ species: 'wynaut', ability: 'swordofruin', moves: ['sleeptalk'] },
|
||||
], [
|
||||
{ species: 'magikarp', ability: 'moldbreaker', moves: ['worryseed'] },
|
||||
{ species: 'chienpao', ability: 'swordofruin', moves: ['aerialace'] },
|
||||
]]);
|
||||
battle.makeChoices();
|
||||
battle.makeChoices('auto', 'switch 2');
|
||||
battle.makeChoices();
|
||||
const wynaut = battle.p1.active[0];
|
||||
const damage = wynaut.maxhp - wynaut.hp;
|
||||
assert.bounded(damage, [90, 107]);
|
||||
});
|
||||
|
||||
it(`should lower the Defense of other Pokemon dragged in by a Mold Breaker move`, () => {
|
||||
battle = common.createBattle([[
|
||||
{ species: 'wynaut', ability: 'moldbreaker', moves: ['roar'] },
|
||||
{ species: 'chienpao', ability: 'swordofruin', moves: ['aerialace'] },
|
||||
], [
|
||||
{ species: 'wynaut', moves: ['sleeptalk'] },
|
||||
{ species: 'chienpao', ability: 'swordofruin', moves: ['aerialace', 'sleeptalk'] },
|
||||
]]);
|
||||
battle.makeChoices();
|
||||
battle.makeChoices('switch 2', 'move sleeptalk');
|
||||
const regularPao = battle.p1.active[0];
|
||||
const moldedPao = battle.p2.active[0];
|
||||
battle.makeChoices();
|
||||
assert.bounded(regularPao.maxhp - regularPao.hp, [61, 72]);
|
||||
assert.bounded(moldedPao.maxhp - moldedPao.hp, [81, 96]);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user