2024-02-29 20:08:50 -05:00
import Pokemon , { HitResult , PokemonMove } from "../field/pokemon" ;
2024-01-13 12:24:24 -05:00
import { Type } from "./type" ;
2023-04-26 23:33:13 -04:00
import * as Utils from "../utils" ;
2023-04-27 01:14:15 -04:00
import { BattleStat , getBattleStatName } from "./battle-stat" ;
2024-03-09 21:57:33 -05:00
import { PokemonHealPhase , ShowAbilityPhase , StatChangePhase } from "../phases" ;
2023-04-27 01:14:15 -04:00
import { getPokemonMessage } from "../messages" ;
2023-04-27 14:30:03 -04:00
import { Weather , WeatherType } from "./weather" ;
2024-01-13 12:24:24 -05:00
import { BattlerTag } from "./battler-tags" ;
import { BattlerTagType } from "./enums/battler-tag-type" ;
2024-04-11 05:16:09 +01:00
import { StatusEffect , getStatusEffectDescriptor , getStatusEffectHealText } from "./status-effect" ;
2024-04-14 13:15:01 -04:00
import { Gender } from "./gender" ;
2024-05-03 22:40:34 -04:00
import Move , { AttackMove , MoveCategory , MoveFlags , MoveTarget , RecoilAttr , StatusMoveTypeImmunityAttr , FlinchAttr , OneHitKOAttr , HitHealAttr , StrengthSapHealAttr , allMoves , StatusMove } from "./move" ;
2024-04-21 23:05:36 -04:00
import { ArenaTagSide , ArenaTrapTag } from "./arena-tag" ;
2024-01-15 23:29:22 -05:00
import { ArenaTagType } from "./enums/arena-tag-type" ;
2023-10-29 01:28:56 -04:00
import { Stat } from "./pokemon-stat" ;
2023-12-22 01:16:56 -05:00
import { PokemonHeldItemModifier } from "../modifier/modifier" ;
2024-01-13 12:24:24 -05:00
import { Moves } from "./enums/moves" ;
2024-03-13 12:23:31 -05:00
import { TerrainType } from "./terrain" ;
2024-03-30 00:53:35 -04:00
import { SpeciesFormChangeManualTrigger } from "./pokemon-forms" ;
2024-04-11 09:24:03 -04:00
import { Abilities } from "./enums/abilities" ;
2024-04-25 03:10:09 +02:00
import i18next , { Localizable } from "#app/plugins/i18n.js" ;
2024-04-25 14:29:05 -04:00
import { Command } from "../ui/command-ui-handler" ;
2024-05-05 07:52:27 -07:00
import Battle from "#app/battle.js" ;
import { ability } from "#app/locales/en/ability.js" ;
2023-04-26 23:33:13 -04:00
2024-04-25 03:10:09 +02:00
export class Ability implements Localizable {
2023-04-15 20:36:19 -04:00
public id : Abilities ;
2024-04-24 22:42:09 -04:00
private nameAppend : string ;
2023-04-15 20:36:19 -04:00
public name : string ;
public description : string ;
public generation : integer ;
2024-04-11 09:24:03 -04:00
public isBypassFaint : boolean ;
2024-03-14 00:40:57 -04:00
public isIgnorable : boolean ;
2023-04-27 14:30:03 -04:00
public attrs : AbAttr [ ] ;
public conditions : AbAttrCondition [ ] ;
2023-04-15 20:36:19 -04:00
2024-04-25 03:10:09 +02:00
constructor ( id : Abilities , generation : integer ) {
2023-04-15 20:36:19 -04:00
this . id = id ;
2024-04-24 22:42:09 -04:00
this . nameAppend = '' ;
2023-04-15 20:36:19 -04:00
this . generation = generation ;
2023-04-26 23:33:13 -04:00
this . attrs = [ ] ;
2023-04-27 14:30:03 -04:00
this . conditions = [ ] ;
2024-04-25 03:10:09 +02:00
this . localize ( ) ;
}
localize ( ) : void {
const i18nKey = Abilities [ this . id ] . split ( '_' ) . filter ( f = > f ) . map ( ( f , i ) = > i ? ` ${ f [ 0 ] } ${ f . slice ( 1 ) . toLowerCase ( ) } ` : f . toLowerCase ( ) ) . join ( '' ) as string ;
2024-04-24 22:42:09 -04:00
this . name = this . id ? ` ${ i18next . t ( ` ability: ${ i18nKey } .name ` ) as string } ${ this . nameAppend } ` : '' ;
2024-04-25 03:10:09 +02:00
this . description = this . id ? i18next . t ( ` ability: ${ i18nKey } .description ` ) as string : '' ;
2023-04-26 23:33:13 -04:00
}
2023-04-27 14:30:03 -04:00
getAttrs ( attrType : { new ( . . . args : any [ ] ) : AbAttr } ) : AbAttr [ ] {
2023-04-26 23:33:13 -04:00
return this . attrs . filter ( a = > a instanceof attrType ) ;
}
2023-04-27 14:30:03 -04:00
attr < T extends new ( ...args : any [ ] ) = > AbAttr > ( AttrType : T , . . . args : ConstructorParameters < T > ) : Ability {
2023-04-26 23:33:13 -04:00
const attr = new AttrType ( . . . args ) ;
this . attrs . push ( attr ) ;
return this ;
2023-04-15 20:36:19 -04:00
}
2023-04-27 14:30:03 -04:00
2023-12-23 01:21:01 -05:00
conditionalAttr < T extends new ( ...args : any [ ] ) = > AbAttr > ( condition : AbAttrCondition , AttrType : T , . . . args : ConstructorParameters < T > ) : Ability {
const attr = new AttrType ( . . . args ) ;
attr . addCondition ( condition ) ;
this . attrs . push ( attr ) ;
2024-04-07 22:27:07 -07:00
2023-12-23 01:21:01 -05:00
return this ;
}
2024-04-07 22:27:07 -07:00
2023-05-01 22:07:00 -04:00
hasAttr ( attrType : { new ( . . . args : any [ ] ) : AbAttr } ) : boolean {
return ! ! this . getAttrs ( attrType ) . length ;
}
2024-04-11 09:24:03 -04:00
bypassFaint ( ) : Ability {
this . isBypassFaint = true ;
2023-12-22 23:57:05 -05:00
return this ;
}
2024-03-14 00:40:57 -04:00
ignorable ( ) : Ability {
this . isIgnorable = true ;
return this ;
}
2023-04-27 14:30:03 -04:00
condition ( condition : AbAttrCondition ) : Ability {
this . conditions . push ( condition ) ;
return this ;
}
2024-04-25 03:10:09 +02:00
partial ( ) : this {
2024-04-24 22:42:09 -04:00
this . nameAppend += ' (P)' ;
2024-04-25 03:10:09 +02:00
return this ;
}
unimplemented ( ) : this {
2024-04-24 22:42:09 -04:00
this . nameAppend += ' (N)' ;
2024-04-25 03:10:09 +02:00
return this ;
}
2023-04-15 20:36:19 -04:00
}
2024-04-11 09:24:03 -04:00
type AbAttrApplyFunc < TAttr extends AbAttr > = ( attr : TAttr , passive : boolean ) = > boolean | Promise < boolean > ;
2023-04-27 14:30:03 -04:00
type AbAttrCondition = ( pokemon : Pokemon ) = > boolean ;
2023-12-23 01:21:01 -05:00
type PokemonAttackCondition = ( user : Pokemon , target : Pokemon , move : Move ) = > boolean ;
type PokemonDefendCondition = ( target : Pokemon , user : Pokemon , move : Move ) = > boolean ;
2024-04-14 14:20:00 -04:00
type PokemonStatChangeCondition = ( target : Pokemon , statsChanged : BattleStat [ ] , levels : integer ) = > boolean ;
2023-12-23 01:21:01 -05:00
2023-04-27 14:30:03 -04:00
export abstract class AbAttr {
2023-05-06 12:13:35 -04:00
public showAbility : boolean ;
2023-12-23 01:21:01 -05:00
private extraCondition : AbAttrCondition ;
2023-05-06 12:13:35 -04:00
2024-03-18 21:22:27 -04:00
constructor ( showAbility : boolean = true ) {
this . showAbility = showAbility ;
2023-05-06 12:13:35 -04:00
}
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean | Promise < boolean > {
2023-04-27 14:30:03 -04:00
return false ;
}
2024-04-11 09:24:03 -04:00
getTriggerMessage ( pokemon : Pokemon , abilityName : string , . . . args : any [ ] ) : string {
2023-04-27 01:14:15 -04:00
return null ;
}
2023-04-27 14:30:03 -04:00
getCondition ( ) : AbAttrCondition {
2023-12-23 01:21:01 -05:00
return this . extraCondition || null ;
}
addCondition ( condition : AbAttrCondition ) : AbAttr {
this . extraCondition = condition ;
return this ;
2023-04-27 14:30:03 -04:00
}
}
export class BlockRecoilDamageAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2023-04-27 14:30:03 -04:00
cancelled . value = true ;
return true ;
}
2024-04-11 09:24:03 -04:00
getTriggerMessage ( pokemon : Pokemon , abilityName : string , . . . args : any [ ] ) {
return getPokemonMessage ( pokemon , ` 's ${ abilityName } \ nprotected it from recoil! ` ) ;
2023-04-27 14:30:03 -04:00
}
2023-04-27 01:14:15 -04:00
}
2023-04-26 23:33:13 -04:00
2023-05-18 11:11:06 -04:00
export class DoubleBattleChanceAbAttr extends AbAttr {
constructor ( ) {
super ( false ) ;
}
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2023-05-18 11:11:06 -04:00
const doubleChance = ( args [ 0 ] as Utils . IntegerHolder ) ;
doubleChance . value = Math . max ( doubleChance . value / 2 , 1 ) ;
return true ;
}
}
2024-03-30 00:53:35 -04:00
export class PostBattleInitAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
applyPostBattleInit ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean | Promise < boolean > {
2024-03-30 00:53:35 -04:00
return false ;
}
}
export class PostBattleInitFormChangeAbAttr extends PostBattleInitAbAttr {
private formFunc : ( p : Pokemon ) = > integer ;
constructor ( formFunc : ( ( p : Pokemon ) = > integer ) ) {
super ( true ) ;
this . formFunc = formFunc ;
}
2024-04-11 09:24:03 -04:00
applyPostBattleInit ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
2024-03-30 00:53:35 -04:00
const formIndex = this . formFunc ( pokemon ) ;
if ( formIndex !== pokemon . formIndex )
return pokemon . scene . triggerPokemonFormChange ( pokemon , SpeciesFormChangeManualTrigger , false ) ;
return false ;
}
}
2024-04-02 18:03:49 -05:00
export class PostBattleInitStatChangeAbAttr extends PostBattleInitAbAttr {
private stats : BattleStat [ ] ;
private levels : integer ;
private selfTarget : boolean ;
constructor ( stats : BattleStat | BattleStat [ ] , levels : integer , selfTarget? : boolean ) {
super ( ) ;
this . stats = typeof ( stats ) === 'number'
? [ stats as BattleStat ]
: stats as BattleStat [ ] ;
this . levels = levels ;
this . selfTarget = ! ! selfTarget ;
}
2024-04-11 09:24:03 -04:00
applyPostBattleInit ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
2024-04-02 18:03:49 -05:00
const statChangePhases : StatChangePhase [ ] = [ ] ;
if ( this . selfTarget )
statChangePhases . push ( new StatChangePhase ( pokemon . scene , pokemon . getBattlerIndex ( ) , true , this . stats , this . levels ) ) ;
else {
for ( let opponent of pokemon . getOpponents ( ) )
statChangePhases . push ( new StatChangePhase ( pokemon . scene , opponent . getBattlerIndex ( ) , false , this . stats , this . levels ) ) ;
}
for ( let statChangePhase of statChangePhases ) {
if ( ! this . selfTarget && ! statChangePhase . getPokemon ( ) . summonData )
pokemon . scene . pushPhase ( statChangePhase ) ; // TODO: This causes the ability bar to be shown at the wrong time
else
pokemon . scene . unshiftPhase ( statChangePhase ) ;
}
return true ;
}
}
2023-12-22 01:16:56 -05:00
type PreDefendAbAttrCondition = ( pokemon : Pokemon , attacker : Pokemon , move : PokemonMove ) = > boolean ;
2023-04-27 14:30:03 -04:00
export class PreDefendAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
applyPreDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean | Promise < boolean > {
2023-04-26 23:33:13 -04:00
return false ;
}
}
2024-04-17 22:09:28 -06:00
export class PreDefendFormChangeAbAttr extends PreDefendAbAttr {
private formFunc : ( p : Pokemon ) = > integer ;
constructor ( formFunc : ( ( p : Pokemon ) = > integer ) ) {
super ( true ) ;
this . formFunc = formFunc ;
}
applyPreDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
const formIndex = this . formFunc ( pokemon ) ;
if ( formIndex !== pokemon . formIndex ) {
pokemon . scene . triggerPokemonFormChange ( pokemon , SpeciesFormChangeManualTrigger , false ) ;
return true ;
}
return false ;
}
}
2024-04-02 01:03:29 -04:00
export class PreDefendFullHpEndureAbAttr extends PreDefendAbAttr {
2024-04-11 09:24:03 -04:00
applyPreDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-05-05 08:38:55 -07:00
if ( pokemon . getMaxHp ( ) <= 1 && ( pokemon . getHpRatio ( ) < 1 || ( args [ 0 ] as Utils . NumberHolder ) . value < pokemon . hp ) )
2024-03-09 23:49:00 +01:00
return false ;
2024-04-06 01:48:42 -04:00
return pokemon . addTag ( BattlerTagType . STURDY , 1 ) ;
2024-03-09 23:49:00 +01:00
}
}
2023-05-04 14:06:31 -04:00
export class BlockItemTheftAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2023-10-26 20:02:30 -04:00
cancelled . value = true ;
2023-05-04 14:06:31 -04:00
return true ;
}
2024-04-11 09:24:03 -04:00
getTriggerMessage ( pokemon : Pokemon , abilityName : string , . . . args : any [ ] ) {
return getPokemonMessage ( pokemon , ` 's ${ abilityName } \ nprevents item theft! ` ) ;
2023-05-04 14:06:31 -04:00
}
}
2023-10-26 20:02:30 -04:00
export class StabBoostAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-03-26 09:32:02 -04:00
if ( ( args [ 0 ] as Utils . NumberHolder ) . value > 1 ) {
2023-11-26 09:53:16 -05:00
( args [ 0 ] as Utils . NumberHolder ) . value += 0.5 ;
2024-03-26 09:32:02 -04:00
return true ;
}
2023-10-26 20:02:30 -04:00
2024-03-26 09:32:02 -04:00
return false ;
2023-10-26 20:02:30 -04:00
}
}
2023-12-23 01:21:01 -05:00
export class ReceivedMoveDamageMultiplierAbAttr extends PreDefendAbAttr {
2024-04-17 22:09:28 -06:00
protected condition : PokemonDefendCondition ;
2023-05-02 15:56:41 -04:00
private powerMultiplier : number ;
2023-12-23 01:21:01 -05:00
constructor ( condition : PokemonDefendCondition , powerMultiplier : number ) {
2023-05-02 15:56:41 -04:00
super ( ) ;
2023-12-23 01:21:01 -05:00
this . condition = condition ;
2023-05-02 15:56:41 -04:00
this . powerMultiplier = powerMultiplier ;
}
2024-04-11 09:24:03 -04:00
applyPreDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2023-12-23 01:21:01 -05:00
if ( this . condition ( pokemon , attacker , move . getMove ( ) ) ) {
2023-05-02 15:56:41 -04:00
( args [ 0 ] as Utils . NumberHolder ) . value *= this . powerMultiplier ;
return true ;
}
return false ;
}
}
2023-12-23 01:21:01 -05:00
export class ReceivedTypeDamageMultiplierAbAttr extends ReceivedMoveDamageMultiplierAbAttr {
constructor ( moveType : Type , powerMultiplier : number ) {
super ( ( user , target , move ) = > move . type === moveType , powerMultiplier ) ;
}
}
2024-04-17 22:09:28 -06:00
export class PreDefendMovePowerToOneAbAttr extends ReceivedMoveDamageMultiplierAbAttr {
constructor ( condition : PokemonDefendCondition ) {
super ( condition , 1 ) ;
}
applyPreDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
if ( this . condition ( pokemon , attacker , move . getMove ( ) ) ) {
( args [ 0 ] as Utils . NumberHolder ) . value = 1 ;
return true ;
}
return false ;
}
}
2023-04-27 14:30:03 -04:00
export class TypeImmunityAbAttr extends PreDefendAbAttr {
2023-04-26 23:33:13 -04:00
private immuneType : Type ;
2023-04-27 14:30:03 -04:00
private condition : AbAttrCondition ;
2023-04-26 23:33:13 -04:00
2023-04-27 14:30:03 -04:00
constructor ( immuneType : Type , condition? : AbAttrCondition ) {
2023-04-26 23:33:13 -04:00
super ( ) ;
this . immuneType = immuneType ;
2023-04-27 14:30:03 -04:00
this . condition = condition ;
2023-04-26 23:33:13 -04:00
}
2024-04-11 09:24:03 -04:00
applyPreDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-03-04 20:28:55 -05:00
if ( ( move . getMove ( ) instanceof AttackMove || move . getMove ( ) . getAttrs ( StatusMoveTypeImmunityAttr ) . find ( attr = > ( attr as StatusMoveTypeImmunityAttr ) . immuneType === this . immuneType ) ) && move . getMove ( ) . type === this . immuneType ) {
2023-04-26 23:33:13 -04:00
( args [ 0 ] as Utils . NumberHolder ) . value = 0 ;
return true ;
}
return false ;
}
2023-04-27 14:30:03 -04:00
getCondition ( ) : AbAttrCondition {
return this . condition ;
}
2023-04-26 23:33:13 -04:00
}
2023-05-02 15:56:41 -04:00
export class TypeImmunityHealAbAttr extends TypeImmunityAbAttr {
constructor ( immuneType : Type ) {
super ( immuneType ) ;
}
2024-04-11 09:24:03 -04:00
applyPreDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
const ret = super . applyPreDefend ( pokemon , passive , attacker , move , cancelled , args ) ;
2023-05-02 15:56:41 -04:00
2023-05-18 11:11:06 -04:00
if ( ret ) {
2024-02-28 11:34:55 -05:00
if ( pokemon . getHpRatio ( ) < 1 ) {
const simulated = args . length > 1 && args [ 1 ] ;
if ( ! simulated ) {
2024-04-11 09:24:03 -04:00
const abilityName = ( ! passive ? pokemon . getAbility ( ) : pokemon . getPassiveAbility ( ) ) . name ;
2024-02-28 11:34:55 -05:00
pokemon . scene . unshiftPhase ( new PokemonHealPhase ( pokemon . scene , pokemon . getBattlerIndex ( ) ,
2024-04-11 09:24:03 -04:00
Math . max ( Math . floor ( pokemon . getMaxHp ( ) / 4 ) , 1 ) , getPokemonMessage ( pokemon , ` 's ${ abilityName } \ nrestored its HP a little! ` ) , true ) ) ;
2024-02-28 11:34:55 -05:00
}
}
2023-05-02 15:56:41 -04:00
return true ;
}
return false ;
}
}
2023-04-27 14:30:03 -04:00
class TypeImmunityStatChangeAbAttr extends TypeImmunityAbAttr {
2023-04-26 23:33:13 -04:00
private stat : BattleStat ;
private levels : integer ;
2023-04-27 14:30:03 -04:00
constructor ( immuneType : Type , stat : BattleStat , levels : integer , condition? : AbAttrCondition ) {
super ( immuneType , condition ) ;
2023-04-26 23:33:13 -04:00
this . stat = stat ;
this . levels = levels ;
}
2024-04-11 09:24:03 -04:00
applyPreDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
const ret = super . applyPreDefend ( pokemon , passive , attacker , move , cancelled , args ) ;
2023-04-26 23:33:13 -04:00
if ( ret ) {
cancelled . value = true ;
2024-02-28 11:34:55 -05:00
const simulated = args . length > 1 && args [ 1 ] ;
if ( ! simulated )
pokemon . scene . unshiftPhase ( new StatChangePhase ( pokemon . scene , pokemon . getBattlerIndex ( ) , true , [ this . stat ] , this . levels ) ) ;
2023-04-26 23:33:13 -04:00
}
return ret ;
}
}
2023-04-27 14:30:03 -04:00
class TypeImmunityAddBattlerTagAbAttr extends TypeImmunityAbAttr {
private tagType : BattlerTagType ;
private turnCount : integer ;
constructor ( immuneType : Type , tagType : BattlerTagType , turnCount : integer , condition? : AbAttrCondition ) {
super ( immuneType , condition ) ;
this . tagType = tagType ;
this . turnCount = turnCount ;
}
2024-04-11 09:24:03 -04:00
applyPreDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
const ret = super . applyPreDefend ( pokemon , passive , attacker , move , cancelled , args ) ;
2023-04-27 14:30:03 -04:00
if ( ret ) {
cancelled . value = true ;
2024-02-28 11:34:55 -05:00
const simulated = args . length > 1 && args [ 1 ] ;
if ( ! simulated )
pokemon . addTag ( this . tagType , this . turnCount , undefined , pokemon . id ) ;
2023-04-27 14:30:03 -04:00
}
return ret ;
}
}
2023-04-27 14:56:30 -04:00
export class NonSuperEffectiveImmunityAbAttr extends TypeImmunityAbAttr {
constructor ( condition? : AbAttrCondition ) {
super ( null , condition ) ;
}
2024-04-11 09:24:03 -04:00
applyPreDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-05-06 00:27:56 -05:00
if ( move . getMove ( ) instanceof AttackMove && pokemon . getAttackTypeEffectiveness ( move . getMove ( ) . type , attacker ) < 2 ) {
2023-04-27 14:56:30 -04:00
cancelled . value = true ;
( args [ 0 ] as Utils . NumberHolder ) . value = 0 ;
return true ;
}
return false ;
}
2024-04-11 09:24:03 -04:00
getTriggerMessage ( pokemon : Pokemon , abilityName : string , . . . args : any [ ] ) : string {
return getPokemonMessage ( pokemon , ` avoided damage \ nwith ${ abilityName } ! ` ) ;
2023-04-27 14:56:30 -04:00
}
}
2023-05-04 12:57:55 -04:00
export class PostDefendAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
applyPostDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean | Promise < boolean > {
2023-05-04 12:57:55 -04:00
return false ;
}
}
2024-04-17 22:09:28 -06:00
export class PostDefendDisguiseAbAttr extends PostDefendAbAttr {
applyPostDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
if ( pokemon . formIndex == 0 && pokemon . battleData . hitCount != 0 && ( move . getMove ( ) . category == MoveCategory . SPECIAL || move . getMove ( ) . category == MoveCategory . PHYSICAL ) ) {
const recoilDamage = Math . ceil ( ( pokemon . getMaxHp ( ) / 8 ) - attacker . turnData . damageDealt ) ;
if ( ! recoilDamage )
return false ;
pokemon . damageAndUpdate ( recoilDamage , HitResult . OTHER ) ;
2024-04-25 20:51:04 -04:00
pokemon . turnData . damageTaken += recoilDamage ;
2024-04-17 22:09:28 -06:00
pokemon . scene . queueMessage ( getPokemonMessage ( pokemon , '\'s disguise was busted!' ) ) ;
return true ;
}
return false ;
}
}
export class PostDefendFormChangeAbAttr extends PostDefendAbAttr {
private formFunc : ( p : Pokemon ) = > integer ;
constructor ( formFunc : ( ( p : Pokemon ) = > integer ) ) {
super ( true ) ;
this . formFunc = formFunc ;
}
applyPostDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
const formIndex = this . formFunc ( pokemon ) ;
if ( formIndex !== pokemon . formIndex ) {
pokemon . scene . triggerPokemonFormChange ( pokemon , SpeciesFormChangeManualTrigger , false ) ;
return true ;
}
return false ;
}
}
2024-04-15 19:48:33 +03:00
export class FieldPriorityMoveImmunityAbAttr extends PreDefendAbAttr {
applyPreDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
const attackPriority = new Utils . IntegerHolder ( move . getMove ( ) . priority ) ;
applyAbAttrs ( IncrementMovePriorityAbAttr , attacker , null , move . getMove ( ) , attackPriority ) ;
if ( attackPriority . value > 0 && ! move . getMove ( ) . isMultiTarget ( ) ) {
cancelled . value = true ;
return true ;
}
return false ;
}
}
2024-04-14 14:20:00 -04:00
export class PostStatChangeAbAttr extends AbAttr {
applyPostStatChange ( pokemon : Pokemon , statsChanged : BattleStat [ ] , levelChanged : integer , selfTarget : boolean , args : any [ ] ) : boolean | Promise < boolean > {
return false ;
}
}
2023-12-22 01:16:56 -05:00
export class MoveImmunityAbAttr extends PreDefendAbAttr {
private immuneCondition : PreDefendAbAttrCondition ;
constructor ( immuneCondition : PreDefendAbAttrCondition ) {
super ( true ) ;
this . immuneCondition = immuneCondition ;
}
2024-04-11 09:24:03 -04:00
applyPreDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2023-12-22 01:16:56 -05:00
if ( this . immuneCondition ( pokemon , attacker , move ) ) {
cancelled . value = true ;
return true ;
}
return false ;
}
2024-04-11 09:24:03 -04:00
getTriggerMessage ( pokemon : Pokemon , abilityName : string , . . . args : any [ ] ) : string {
2023-12-22 01:16:56 -05:00
return ` It doesn \ 't affect ${ pokemon . name } ! ` ;
}
}
2024-04-17 01:09:15 -04:00
export class MoveImmunityStatChangeAbAttr extends MoveImmunityAbAttr {
private stat : BattleStat ;
private levels : integer ;
constructor ( immuneCondition : PreDefendAbAttrCondition , stat : BattleStat , levels : integer ) {
super ( immuneCondition ) ;
this . stat = stat ;
this . levels = levels ;
}
applyPreDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
const ret = super . applyPreDefend ( pokemon , passive , attacker , move , cancelled , args )
if ( ret ) {
pokemon . scene . unshiftPhase ( new StatChangePhase ( pokemon . scene , pokemon . getBattlerIndex ( ) , true , [ this . stat ] , this . levels ) ) ;
}
return ret ;
}
}
2024-04-22 04:02:10 +01:00
export class ReverseDrainAbAttr extends PostDefendAbAttr {
applyPostDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
if ( ! ! move . getMove ( ) . getAttrs ( HitHealAttr ) . length || ! ! move . getMove ( ) . getAttrs ( StrengthSapHealAttr ) . length ) {
pokemon . scene . queueMessage ( getPokemonMessage ( attacker , ` sucked up the liquid ooze! ` ) ) ;
return true ;
}
return false ;
}
}
2024-04-05 00:24:43 +02:00
export class PostDefendStatChangeAbAttr extends PostDefendAbAttr {
private condition : PokemonDefendCondition ;
private stat : BattleStat ;
private levels : integer ;
2024-04-06 22:18:12 -05:00
private selfTarget : boolean ;
2024-04-05 00:24:43 +02:00
2024-04-06 22:18:12 -05:00
constructor ( condition : PokemonDefendCondition , stat : BattleStat , levels : integer , selfTarget : boolean = true ) {
2024-04-05 00:24:43 +02:00
super ( true ) ;
this . condition = condition ;
this . stat = stat ;
this . levels = levels ;
2024-04-06 22:18:12 -05:00
this . selfTarget = selfTarget ;
2024-04-05 00:24:43 +02:00
}
2024-04-11 09:24:03 -04:00
applyPostDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
2024-04-05 00:24:43 +02:00
if ( this . condition ( pokemon , attacker , move . getMove ( ) ) ) {
2024-04-06 22:18:12 -05:00
pokemon . scene . unshiftPhase ( new StatChangePhase ( pokemon . scene , ( this . selfTarget ? pokemon : attacker ) . getBattlerIndex ( ) , true , [ this . stat ] , this . levels ) ) ;
2024-04-05 00:24:43 +02:00
return true ;
}
return false ;
}
}
2024-05-03 13:55:46 -07:00
export class PostDefendHpGatedStatChangeAbAttr extends PostDefendAbAttr {
private condition : PokemonDefendCondition ;
private hpGate : number ;
private stats : BattleStat [ ] ;
private levels : integer ;
private selfTarget : boolean ;
constructor ( condition : PokemonDefendCondition , hpGate : number , stats : BattleStat [ ] , levels : integer , selfTarget : boolean = true ) {
super ( true ) ;
this . condition = condition ;
this . hpGate = hpGate ;
this . stats = stats ;
this . levels = levels ;
this . selfTarget = selfTarget ;
}
applyPostDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
const hpGateFlat : integer = Math . ceil ( pokemon . getMaxHp ( ) * this . hpGate )
const lastAttackReceived = pokemon . turnData . attacksReceived [ pokemon . turnData . attacksReceived . length - 1 ]
if ( this . condition ( pokemon , attacker , move . getMove ( ) ) && ( pokemon . hp <= hpGateFlat && ( pokemon . hp + lastAttackReceived . damage ) > hpGateFlat ) ) {
pokemon . scene . unshiftPhase ( new StatChangePhase ( pokemon . scene , ( this . selfTarget ? pokemon : attacker ) . getBattlerIndex ( ) , true , this . stats , this . levels ) ) ;
return true ;
}
return false ;
}
}
2024-04-19 20:08:09 +01:00
export class PostDefendApplyArenaTrapTagAbAttr extends PostDefendAbAttr {
private condition : PokemonDefendCondition ;
2024-04-21 23:05:36 -04:00
private tagType : ArenaTagType ;
2024-04-19 20:08:09 +01:00
constructor ( condition : PokemonDefendCondition , tagType : ArenaTagType ) {
super ( true ) ;
this . condition = condition ;
this . tagType = tagType ;
}
applyPostDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
if ( this . condition ( pokemon , attacker , move . getMove ( ) ) ) {
const tag = pokemon . scene . arena . getTag ( this . tagType ) as ArenaTrapTag ;
if ( ! pokemon . scene . arena . getTag ( this . tagType ) || tag . layers < tag . maxLayers ) {
pokemon . scene . arena . addTag ( this . tagType , 0 , undefined , pokemon . id , pokemon . isPlayer ( ) ? ArenaTagSide.ENEMY : ArenaTagSide.PLAYER ) ;
return true ;
}
}
return false ;
}
}
2024-04-17 01:09:15 -04:00
export class PostDefendApplyBattlerTagAbAttr extends PostDefendAbAttr {
private condition : PokemonDefendCondition ;
private tagType : BattlerTagType ;
constructor ( condition : PokemonDefendCondition , tagType : BattlerTagType ) {
super ( true ) ;
this . condition = condition ;
this . tagType = tagType ;
}
applyPostDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
if ( this . condition ( pokemon , attacker , move . getMove ( ) ) ) {
pokemon . addTag ( this . tagType , undefined , undefined , pokemon . id ) ;
return true ;
}
return false ;
}
}
2023-05-06 00:42:01 -04:00
export class PostDefendTypeChangeAbAttr extends PostDefendAbAttr {
2024-04-11 09:24:03 -04:00
applyPostDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
2023-05-18 11:11:06 -04:00
if ( hitResult < HitResult . NO_EFFECT ) {
2023-05-06 00:42:01 -04:00
const type = move . getMove ( ) . type ;
2024-02-17 00:40:03 -05:00
const pokemonTypes = pokemon . getTypes ( true ) ;
2023-05-08 18:48:35 -04:00
if ( pokemonTypes . length !== 1 || pokemonTypes [ 0 ] !== type ) {
pokemon . summonData . types = [ type ] ;
2023-05-06 00:42:01 -04:00
return true ;
}
}
return false ;
}
2024-04-11 09:24:03 -04:00
getTriggerMessage ( pokemon : Pokemon , abilityName : string , . . . args : any [ ] ) : string {
return getPokemonMessage ( pokemon , ` 's ${ abilityName } \ nmade it the ${ Utils . toReadableString ( Type [ pokemon . getTypes ( true ) [ 0 ] ] ) } type! ` ) ;
2023-05-06 00:42:01 -04:00
}
}
2024-03-14 00:40:57 -04:00
export class PostDefendTerrainChangeAbAttr extends PostDefendAbAttr {
private terrainType : TerrainType ;
constructor ( terrainType : TerrainType ) {
super ( ) ;
this . terrainType = terrainType ;
}
2024-04-11 09:24:03 -04:00
applyPostDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
2024-03-14 00:40:57 -04:00
if ( hitResult < HitResult . NO_EFFECT )
2024-03-25 10:22:16 -04:00
return pokemon . scene . arena . trySetTerrain ( this . terrainType , true ) ;
2024-03-14 00:40:57 -04:00
return false ;
}
}
2023-05-04 12:57:55 -04:00
export class PostDefendContactApplyStatusEffectAbAttr extends PostDefendAbAttr {
private chance : integer ;
private effects : StatusEffect [ ] ;
constructor ( chance : integer , . . . effects : StatusEffect [ ] ) {
super ( ) ;
this . chance = chance ;
this . effects = effects ;
}
2024-04-11 09:24:03 -04:00
applyPostDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
2024-04-06 21:04:40 -04:00
if ( move . getMove ( ) . checkFlag ( MoveFlags . MAKES_CONTACT , attacker , pokemon ) && ! attacker . status && ( this . chance === - 1 || pokemon . randSeedInt ( 100 ) < this . chance ) ) {
2024-01-02 21:31:59 -05:00
const effect = this . effects . length === 1 ? this . effects [ 0 ] : this . effects [ pokemon . randSeedInt ( this . effects . length ) ] ;
2024-03-23 10:54:16 -04:00
return attacker . trySetStatus ( effect , true ) ;
2023-05-04 12:57:55 -04:00
}
return false ;
}
}
2024-05-01 17:47:32 -04:00
export class EffectSporeAbAttr extends PostDefendContactApplyStatusEffectAbAttr {
constructor ( ) {
super ( 10 , StatusEffect . POISON , StatusEffect . PARALYSIS , StatusEffect . SLEEP ) ;
}
applyPostDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
if ( attacker . hasAbility ( Abilities . OVERCOAT ) || attacker . isOfType ( Type . GRASS ) ) {
return false ;
}
return super . applyPostDefend ( pokemon , passive , attacker , move , hitResult , args ) ;
}
}
2023-05-04 12:57:55 -04:00
export class PostDefendContactApplyTagChanceAbAttr extends PostDefendAbAttr {
private chance : integer ;
private tagType : BattlerTagType ;
private turnCount : integer ;
constructor ( chance : integer , tagType : BattlerTagType , turnCount? : integer ) {
super ( ) ;
this . tagType = tagType ;
this . chance = chance ;
this . turnCount = turnCount ;
}
2024-04-11 09:24:03 -04:00
applyPostDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
2024-01-02 21:31:59 -05:00
if ( move . getMove ( ) . checkFlag ( MoveFlags . MAKES_CONTACT , attacker , pokemon ) && pokemon . randSeedInt ( 100 ) < this . chance )
2024-03-23 10:54:16 -04:00
return attacker . addTag ( this . tagType , this . turnCount , move . moveId , attacker . id ) ;
2023-05-04 12:57:55 -04:00
return false ;
}
}
2023-10-26 21:12:53 -07:00
export class PostDefendCritStatChangeAbAttr extends PostDefendAbAttr {
private stat : BattleStat ;
private levels : integer ;
constructor ( stat : BattleStat , levels : integer ) {
2024-04-06 21:04:40 -04:00
super ( ) ;
2023-10-26 21:12:53 -07:00
this . stat = stat ;
this . levels = levels ;
}
2024-04-11 09:24:03 -04:00
applyPostDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
2023-10-26 21:12:53 -07:00
pokemon . scene . unshiftPhase ( new StatChangePhase ( pokemon . scene , pokemon . getBattlerIndex ( ) , true , [ this . stat ] , this . levels ) ) ;
return true ;
}
getCondition ( ) : AbAttrCondition {
return ( pokemon : Pokemon ) = > pokemon . turnData . attacksReceived . length && pokemon . turnData . attacksReceived [ pokemon . turnData . attacksReceived . length - 1 ] . critical ;
}
}
2024-04-06 21:04:40 -04:00
export class PostDefendContactDamageAbAttr extends PostDefendAbAttr {
private damageRatio : integer ;
constructor ( damageRatio : integer ) {
super ( ) ;
this . damageRatio = damageRatio ;
}
2024-04-11 09:24:03 -04:00
applyPostDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
2024-04-06 21:04:40 -04:00
if ( move . getMove ( ) . checkFlag ( MoveFlags . MAKES_CONTACT , attacker , pokemon ) ) {
attacker . damageAndUpdate ( Math . ceil ( attacker . getMaxHp ( ) * ( 1 / this . damageRatio ) ) , HitResult . OTHER ) ;
2024-04-25 20:51:04 -04:00
attacker . turnData . damageTaken += Math . ceil ( attacker . getMaxHp ( ) * ( 1 / this . damageRatio ) ) ;
2024-04-06 21:04:40 -04:00
return true ;
}
return false ;
}
2024-04-11 09:24:03 -04:00
getTriggerMessage ( pokemon : Pokemon , abilityName : string , . . . args : any [ ] ) : string {
return getPokemonMessage ( pokemon , ` 's ${ abilityName } \ nhurt its attacker! ` ) ;
2024-04-06 21:04:40 -04:00
}
}
2024-04-07 14:01:48 -05:00
export class PostDefendWeatherChangeAbAttr extends PostDefendAbAttr {
private weatherType : WeatherType ;
constructor ( weatherType : WeatherType ) {
super ( ) ;
this . weatherType = weatherType ;
}
2024-04-11 09:24:03 -04:00
applyPostDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
2024-04-07 14:01:48 -05:00
if ( ! pokemon . scene . arena . weather ? . isImmutable ( ) )
return pokemon . scene . arena . trySetWeather ( this . weatherType , true ) ;
return false ;
}
}
2024-04-14 13:21:34 +10:00
export class PostDefendAbilitySwapAbAttr extends PostDefendAbAttr {
constructor ( ) {
super ( ) ;
}
applyPostDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
if ( move . getMove ( ) . checkFlag ( MoveFlags . MAKES_CONTACT , attacker , pokemon ) && ! attacker . getAbility ( ) . hasAttr ( UnswappableAbilityAbAttr ) ) {
const tempAbilityId = attacker . getAbility ( ) . id ;
attacker . summonData . ability = pokemon . getAbility ( ) . id ;
pokemon . summonData . ability = tempAbilityId ;
return true ;
}
return false ;
}
getTriggerMessage ( pokemon : Pokemon , abilityName : string , . . . args : any [ ] ) : string {
return getPokemonMessage ( pokemon , ` swapped \ nabilities with its target! ` ) ;
}
}
export class PostDefendAbilityGiveAbAttr extends PostDefendAbAttr {
2024-05-03 22:30:23 -04:00
private ability : Abilities ;
constructor ( ability : Abilities ) {
2024-04-14 13:21:34 +10:00
super ( ) ;
2024-05-03 22:30:23 -04:00
this . ability = ability ;
2024-04-14 13:21:34 +10:00
}
applyPostDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
if ( move . getMove ( ) . checkFlag ( MoveFlags . MAKES_CONTACT , attacker , pokemon ) && ! attacker . getAbility ( ) . hasAttr ( UnsuppressableAbilityAbAttr ) && ! attacker . getAbility ( ) . hasAttr ( PostDefendAbilityGiveAbAttr ) ) {
2024-05-03 22:30:23 -04:00
attacker . summonData . ability = this . ability ;
2024-04-14 13:21:34 +10:00
return true ;
}
return false ;
}
getTriggerMessage ( pokemon : Pokemon , abilityName : string , . . . args : any [ ] ) : string {
return getPokemonMessage ( pokemon , ` gave its target \ n ${ abilityName } ! ` ) ;
}
}
2024-04-14 14:20:00 -04:00
export class PostStatChangeStatChangeAbAttr extends PostStatChangeAbAttr {
private condition : PokemonStatChangeCondition ;
private statsToChange : BattleStat [ ] ;
private levels : integer ;
constructor ( condition : PokemonStatChangeCondition , statsToChange : BattleStat [ ] , levels : integer ) {
super ( true ) ;
this . condition = condition ;
this . statsToChange = statsToChange ;
this . levels = levels ;
}
applyPostStatChange ( pokemon : Pokemon , statsChanged : BattleStat [ ] , levelsChanged : integer , selfTarget : boolean , args : any [ ] ) : boolean {
if ( this . condition ( pokemon , statsChanged , levelsChanged ) && ! selfTarget ) {
pokemon . scene . unshiftPhase ( new StatChangePhase ( pokemon . scene , ( pokemon ) . getBattlerIndex ( ) , true , this . statsToChange , this . levels ) ) ;
return true ;
}
return false ;
}
}
2023-04-27 14:30:03 -04:00
export class PreAttackAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
applyPreAttack ( pokemon : Pokemon , passive : boolean , defender : Pokemon , move : PokemonMove , args : any [ ] ) : boolean | Promise < boolean > {
2023-04-27 14:30:03 -04:00
return false ;
}
}
export class VariableMovePowerAbAttr extends PreAttackAbAttr {
2024-04-11 09:24:03 -04:00
applyPreAttack ( pokemon : Pokemon , passive : boolean , defender : Pokemon , move : PokemonMove , args : any [ ] ) : boolean {
2023-04-27 14:30:03 -04:00
//const power = args[0] as Utils.NumberHolder;
2024-04-07 22:27:07 -07:00
return false ;
}
}
export class VariableMoveTypeAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-04-07 22:27:07 -07:00
//const power = args[0] as Utils.IntegerHolder;
2023-04-27 14:30:03 -04:00
return false ;
}
}
2024-04-07 22:27:07 -07:00
export class MoveTypeChangePowerMultiplierAbAttr extends VariableMoveTypeAbAttr {
private matchType : Type ;
private newType : Type ;
private powerMultiplier : number ;
constructor ( matchType : Type , newType : Type , powerMultiplier : number ) {
super ( true ) ;
this . matchType = matchType ;
this . newType = newType ;
this . powerMultiplier = powerMultiplier ;
}
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-04-07 22:27:07 -07:00
const type = ( args [ 0 ] as Utils . IntegerHolder ) ;
if ( type . value == this . matchType ) {
type . value = this . newType ;
( args [ 1 ] as Utils . NumberHolder ) . value *= this . powerMultiplier ;
return true ;
}
return false ;
}
}
2024-04-25 21:42:41 -04:00
export class FieldPreventExplosiveMovesAbAttr extends AbAttr {
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean | Promise < boolean > {
cancelled . value = true ;
return true ;
}
}
2024-04-14 13:15:01 -04:00
export class MoveTypeChangeAttr extends PreAttackAbAttr {
private newType : Type ;
private powerMultiplier : number ;
private condition : PokemonAttackCondition ;
constructor ( newType : Type , powerMultiplier : number , condition : PokemonAttackCondition ) {
super ( true ) ;
this . newType = newType ;
this . powerMultiplier = powerMultiplier ;
this . condition = condition ;
}
applyPreAttack ( pokemon : Pokemon , passive : boolean , defender : Pokemon , move : PokemonMove , args : any [ ] ) : boolean {
if ( this . condition ( pokemon , defender , move . getMove ( ) ) ) {
const type = ( args [ 0 ] as Utils . IntegerHolder ) ;
type . value = this . newType ;
( args [ 1 ] as Utils . NumberHolder ) . value *= this . powerMultiplier ;
return true ;
}
return false ;
}
}
2023-12-23 01:21:01 -05:00
export class MovePowerBoostAbAttr extends VariableMovePowerAbAttr {
private condition : PokemonAttackCondition ;
private powerMultiplier : number ;
2023-12-14 11:48:59 -06:00
2024-05-01 18:17:12 -04:00
constructor ( condition : PokemonAttackCondition , powerMultiplier : number , showAbility : boolean = true ) {
super ( showAbility ) ;
2023-12-23 01:21:01 -05:00
this . condition = condition ;
this . powerMultiplier = powerMultiplier ;
2023-12-14 11:48:59 -06:00
}
2024-04-11 09:24:03 -04:00
applyPreAttack ( pokemon : Pokemon , passive : boolean , defender : Pokemon , move : PokemonMove , args : any [ ] ) : boolean {
2023-12-23 01:21:01 -05:00
if ( this . condition ( pokemon , defender , move . getMove ( ) ) ) {
( args [ 0 ] as Utils . NumberHolder ) . value *= this . powerMultiplier ;
2023-12-14 11:48:59 -06:00
return true ;
}
return false ;
}
}
2023-12-23 01:21:01 -05:00
export class MoveTypePowerBoostAbAttr extends MovePowerBoostAbAttr {
constructor ( boostedType : Type , powerMultiplier? : number ) {
super ( ( pokemon , defender , move ) = > move . type === boostedType , powerMultiplier || 1.5 ) ;
2023-04-27 14:30:03 -04:00
}
2023-12-23 01:21:01 -05:00
}
2023-04-27 14:30:03 -04:00
2023-12-23 01:21:01 -05:00
export class LowHpMoveTypePowerBoostAbAttr extends MoveTypePowerBoostAbAttr {
constructor ( boostedType : Type ) {
super ( boostedType ) ;
2023-04-27 14:30:03 -04:00
}
getCondition ( ) : AbAttrCondition {
return ( pokemon ) = > pokemon . getHpRatio ( ) <= 0.33 ;
}
}
2024-03-14 00:40:57 -04:00
export class FieldVariableMovePowerAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
applyPreAttack ( pokemon : Pokemon , passive : boolean , defender : Pokemon , move : PokemonMove , args : any [ ] ) : boolean {
2024-03-14 00:40:57 -04:00
//const power = args[0] as Utils.NumberHolder;
return false ;
}
}
export class FieldMovePowerBoostAbAttr extends FieldVariableMovePowerAbAttr {
private condition : PokemonAttackCondition ;
private powerMultiplier : number ;
constructor ( condition : PokemonAttackCondition , powerMultiplier : number ) {
super ( false ) ;
this . condition = condition ;
this . powerMultiplier = powerMultiplier ;
}
2024-04-11 09:24:03 -04:00
applyPreAttack ( pokemon : Pokemon , passive : boolean , defender : Pokemon , move : PokemonMove , args : any [ ] ) : boolean {
2024-03-14 00:40:57 -04:00
if ( this . condition ( pokemon , defender , move . getMove ( ) ) ) {
( args [ 0 ] as Utils . NumberHolder ) . value *= this . powerMultiplier ;
return true ;
}
return false ;
}
}
export class FieldMoveTypePowerBoostAbAttr extends FieldMovePowerBoostAbAttr {
constructor ( boostedType : Type , powerMultiplier? : number ) {
super ( ( pokemon , defender , move ) = > move . type === boostedType , powerMultiplier || 1.5 ) ;
}
}
2023-05-02 00:11:31 -04:00
export class BattleStatMultiplierAbAttr extends AbAttr {
private battleStat : BattleStat ;
private multiplier : number ;
2024-04-30 09:47:10 -06:00
private condition : PokemonAttackCondition ;
2023-05-02 00:11:31 -04:00
2024-04-30 09:47:10 -06:00
constructor ( battleStat : BattleStat , multiplier : number , condition? : PokemonAttackCondition ) {
2023-12-22 22:04:30 -05:00
super ( false ) ;
2023-05-02 00:11:31 -04:00
this . battleStat = battleStat ;
this . multiplier = multiplier ;
2024-04-30 09:47:10 -06:00
this . condition = condition ;
2023-05-02 00:11:31 -04:00
}
2024-04-11 09:24:03 -04:00
applyBattleStat ( pokemon : Pokemon , passive : boolean , battleStat : BattleStat , statValue : Utils.NumberHolder , args : any [ ] ) : boolean | Promise < boolean > {
2024-04-30 09:47:10 -06:00
const move = ( args [ 0 ] as Move ) ;
if ( battleStat === this . battleStat && ( ! this . condition || this . condition ( pokemon , null , move ) ) ) {
2023-05-02 00:11:31 -04:00
statValue . value *= this . multiplier ;
return true ;
}
return false ;
}
}
2023-12-22 01:16:56 -05:00
export class PostAttackAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
applyPostAttack ( pokemon : Pokemon , passive : boolean , defender : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean | Promise < boolean > {
2023-12-22 01:16:56 -05:00
return false ;
}
}
export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr {
2023-12-23 01:21:01 -05:00
private condition : PokemonAttackCondition ;
constructor ( condition? : PokemonAttackCondition ) {
super ( ) ;
this . condition = condition ;
}
2024-04-11 09:24:03 -04:00
applyPostAttack ( pokemon : Pokemon , passive : boolean , defender : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : Promise < boolean > {
2023-12-22 21:42:47 -05:00
return new Promise < boolean > ( resolve = > {
2023-12-23 01:21:01 -05:00
if ( hitResult < HitResult . NO_EFFECT && ( ! this . condition || this . condition ( pokemon , defender , move . getMove ( ) ) ) ) {
2023-12-22 21:42:47 -05:00
const heldItems = this . getTargetHeldItems ( defender ) . filter ( i = > i . getTransferrable ( false ) ) ;
if ( heldItems . length ) {
2024-01-02 21:31:59 -05:00
const stolenItem = heldItems [ pokemon . randSeedInt ( heldItems . length ) ] ;
2023-12-22 21:42:47 -05:00
pokemon . scene . tryTransferHeldItemModifier ( stolenItem , pokemon , false , false ) . then ( success = > {
if ( success )
pokemon . scene . queueMessage ( getPokemonMessage ( pokemon , ` stole \ n ${ defender . name } 's ${ stolenItem . type . name } ! ` ) ) ;
resolve ( success ) ;
} ) ;
return ;
}
2023-12-22 01:16:56 -05:00
}
2023-12-22 21:42:47 -05:00
resolve ( false ) ;
} ) ;
2023-12-22 01:16:56 -05:00
}
getTargetHeldItems ( target : Pokemon ) : PokemonHeldItemModifier [ ] {
return target . scene . findModifiers ( m = > m instanceof PokemonHeldItemModifier
&& ( m as PokemonHeldItemModifier ) . pokemonId === target . id , target . isPlayer ( ) ) as PokemonHeldItemModifier [ ] ;
}
}
2024-04-14 11:13:17 -06:00
export class PostAttackApplyStatusEffectAbAttr extends PostAttackAbAttr {
private contactRequired : boolean ;
2024-03-27 23:02:49 -05:00
private chance : integer ;
private effects : StatusEffect [ ] ;
2024-04-14 11:13:17 -06:00
constructor ( contactRequired : boolean , chance : integer , . . . effects : StatusEffect [ ] ) {
2024-03-27 23:02:49 -05:00
super ( ) ;
2024-04-14 11:13:17 -06:00
this . contactRequired = contactRequired ;
2024-03-27 23:02:49 -05:00
this . chance = chance ;
this . effects = effects ;
}
2024-04-11 09:24:03 -04:00
applyPostAttack ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
2024-04-14 11:13:17 -06:00
if ( pokemon != attacker && ( ! this . contactRequired || move . getMove ( ) . checkFlag ( MoveFlags . MAKES_CONTACT , attacker , pokemon ) ) && pokemon . randSeedInt ( 100 ) < this . chance && ! pokemon . status ) {
2024-03-27 23:02:49 -05:00
const effect = this . effects . length === 1 ? this . effects [ 0 ] : this . effects [ pokemon . randSeedInt ( this . effects . length ) ] ;
return attacker . trySetStatus ( effect , true ) ;
}
return false ;
}
}
2024-04-14 11:13:17 -06:00
export class PostAttackContactApplyStatusEffectAbAttr extends PostAttackApplyStatusEffectAbAttr {
constructor ( chance : integer , . . . effects : StatusEffect [ ] ) {
super ( true , chance , . . . effects ) ;
}
}
2024-04-19 09:33:35 -04:00
export class PostAttackApplyBattlerTagAbAttr extends PostAttackAbAttr {
private contactRequired : boolean ;
private chance : ( user : Pokemon , target : Pokemon , move : PokemonMove ) = > integer ;
private effects : BattlerTagType [ ] ;
constructor ( contactRequired : boolean , chance : ( user : Pokemon , target : Pokemon , move : PokemonMove ) = > integer , . . . effects : BattlerTagType [ ] ) {
super ( ) ;
this . contactRequired = contactRequired ;
this . chance = chance ;
this . effects = effects ;
}
applyPostAttack ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
if ( pokemon != attacker && ( ! this . contactRequired || move . getMove ( ) . checkFlag ( MoveFlags . MAKES_CONTACT , attacker , pokemon ) ) && pokemon . randSeedInt ( 100 ) < this . chance ( attacker , pokemon , move ) && ! pokemon . status ) {
const effect = this . effects . length === 1 ? this . effects [ 0 ] : this . effects [ pokemon . randSeedInt ( this . effects . length ) ] ;
return attacker . addTag ( effect ) ;
}
return false ;
}
}
2023-12-23 01:21:01 -05:00
export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr {
private condition : PokemonDefendCondition ;
constructor ( condition? : PokemonDefendCondition ) {
super ( ) ;
this . condition = condition ;
}
2024-04-11 09:24:03 -04:00
applyPostDefend ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : Promise < boolean > {
2023-12-23 01:21:01 -05:00
return new Promise < boolean > ( resolve = > {
if ( hitResult < HitResult . NO_EFFECT && ( ! this . condition || this . condition ( pokemon , attacker , move . getMove ( ) ) ) ) {
const heldItems = this . getTargetHeldItems ( attacker ) . filter ( i = > i . getTransferrable ( false ) ) ;
if ( heldItems . length ) {
2024-01-02 21:31:59 -05:00
const stolenItem = heldItems [ pokemon . randSeedInt ( heldItems . length ) ] ;
2023-12-23 01:21:01 -05:00
pokemon . scene . tryTransferHeldItemModifier ( stolenItem , pokemon , false , false ) . then ( success = > {
if ( success )
pokemon . scene . queueMessage ( getPokemonMessage ( pokemon , ` stole \ n ${ attacker . name } 's ${ stolenItem . type . name } ! ` ) ) ;
resolve ( success ) ;
} ) ;
return ;
}
}
resolve ( false ) ;
} ) ;
}
getTargetHeldItems ( target : Pokemon ) : PokemonHeldItemModifier [ ] {
return target . scene . findModifiers ( m = > m instanceof PokemonHeldItemModifier
&& ( m as PokemonHeldItemModifier ) . pokemonId === target . id , target . isPlayer ( ) ) as PokemonHeldItemModifier [ ] ;
}
}
2024-03-29 22:08:27 -04:00
export class PostVictoryAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
applyPostVictory ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean | Promise < boolean > {
2024-03-29 22:08:27 -04:00
return false ;
}
}
class PostVictoryStatChangeAbAttr extends PostVictoryAbAttr {
private stat : BattleStat | ( ( p : Pokemon ) = > BattleStat ) ;
private levels : integer ;
constructor ( stat : BattleStat | ( ( p : Pokemon ) = > BattleStat ) , levels : integer ) {
super ( ) ;
this . stat = stat ;
this . levels = levels ;
}
2024-04-11 09:24:03 -04:00
applyPostVictory ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean | Promise < boolean > {
2024-03-29 22:08:27 -04:00
const stat = typeof this . stat === 'function'
? this . stat ( pokemon )
: this . stat ;
pokemon . scene . unshiftPhase ( new StatChangePhase ( pokemon . scene , pokemon . getBattlerIndex ( ) , true , [ stat ] , this . levels ) ) ;
return true ;
}
}
2024-04-29 19:43:51 -05:00
export class PostVictoryFormChangeAbAttr extends PostVictoryAbAttr {
private formFunc : ( p : Pokemon ) = > integer ;
constructor ( formFunc : ( ( p : Pokemon ) = > integer ) ) {
super ( true ) ;
this . formFunc = formFunc ;
}
applyPostVictory ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean | Promise < boolean > {
const formIndex = this . formFunc ( pokemon ) ;
if ( formIndex !== pokemon . formIndex ) {
pokemon . scene . triggerPokemonFormChange ( pokemon , SpeciesFormChangeManualTrigger , false ) ;
return true ;
}
return false ;
}
}
2024-04-08 00:20:24 +03:00
export class PostKnockOutAbAttr extends AbAttr {
2024-04-14 13:21:34 +10:00
applyPostKnockOut ( pokemon : Pokemon , passive : boolean , knockedOut : Pokemon , args : any [ ] ) : boolean | Promise < boolean > {
2024-04-08 00:20:24 +03:00
return false ;
}
}
export class PostKnockOutStatChangeAbAttr extends PostKnockOutAbAttr {
private stat : BattleStat | ( ( p : Pokemon ) = > BattleStat ) ;
private levels : integer ;
constructor ( stat : BattleStat | ( ( p : Pokemon ) = > BattleStat ) , levels : integer ) {
super ( ) ;
this . stat = stat ;
this . levels = levels ;
}
2024-04-14 13:21:34 +10:00
applyPostKnockOut ( pokemon : Pokemon , passive : boolean , knockedOut : Pokemon , args : any [ ] ) : boolean | Promise < boolean > {
2024-04-08 00:20:24 +03:00
const stat = typeof this . stat === 'function'
? this . stat ( pokemon )
: this . stat ;
pokemon . scene . unshiftPhase ( new StatChangePhase ( pokemon . scene , pokemon . getBattlerIndex ( ) , true , [ stat ] , this . levels ) ) ;
return true ;
}
}
2024-04-14 13:21:34 +10:00
export class CopyFaintedAllyAbilityAbAttr extends PostKnockOutAbAttr {
constructor ( ) {
super ( ) ;
}
applyPostKnockOut ( pokemon : Pokemon , passive : boolean , knockedOut : Pokemon , args : any [ ] ) : boolean | Promise < boolean > {
if ( pokemon . isPlayer ( ) === knockedOut . isPlayer ( ) && ! knockedOut . getAbility ( ) . hasAttr ( UncopiableAbilityAbAttr ) ) {
pokemon . summonData . ability = knockedOut . getAbility ( ) . id ;
pokemon . scene . queueMessage ( getPokemonMessage ( knockedOut , ` 's ${ allAbilities [ knockedOut . getAbility ( ) . id ] . name } was taken over! ` ) ) ;
return true ;
}
return false ;
}
}
2023-11-05 23:27:40 -05:00
export class IgnoreOpponentStatChangesAbAttr extends AbAttr {
constructor ( ) {
super ( false ) ;
}
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) {
2023-11-05 23:27:40 -05:00
( args [ 0 ] as Utils . IntegerHolder ) . value = 0 ;
return true ;
}
}
2024-05-05 07:52:27 -07:00
export class IntimidateImmunityAbAttr extends AbAttr {
constructor ( ) {
super ( false ) ;
}
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
cancelled . value = true ;
return true ;
}
getTriggerMessage ( pokemon : Pokemon , abilityName : string , . . . args : any [ ] ) : string {
return getPokemonMessage ( pokemon , ` 's ${ abilityName } prevented it from being Intimidated! ` ) ;
}
}
export class PostIntimidateStatChangeAbAttr extends AbAttr {
private stats : BattleStat [ ] ;
private levels : integer ;
private overwrites : boolean ;
constructor ( stats : BattleStat [ ] , levels : integer , overwrites? : boolean ) {
super ( true )
this . stats = stats
this . levels = levels
this . overwrites = ! ! overwrites
}
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
pokemon . scene . pushPhase ( new StatChangePhase ( pokemon . scene , pokemon . getBattlerIndex ( ) , false , this . stats , this . levels ) ) ;
cancelled . value = this . overwrites ;
return true ;
}
}
2023-05-04 12:57:55 -04:00
export class PostSummonAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
applyPostSummon ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean | Promise < boolean > {
2023-05-04 12:57:55 -04:00
return false ;
}
}
2023-10-30 00:16:23 -04:00
export class PostSummonMessageAbAttr extends PostSummonAbAttr {
private messageFunc : ( pokemon : Pokemon ) = > string ;
constructor ( messageFunc : ( pokemon : Pokemon ) = > string ) {
super ( true ) ;
this . messageFunc = messageFunc ;
}
2024-04-11 09:24:03 -04:00
applyPostSummon ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
2023-10-30 00:16:23 -04:00
pokemon . scene . queueMessage ( this . messageFunc ( pokemon ) ) ;
return true ;
}
}
2023-05-06 12:13:35 -04:00
export class PostSummonAddBattlerTagAbAttr extends PostSummonAbAttr {
private tagType : BattlerTagType ;
private turnCount : integer ;
2023-12-22 22:46:05 -05:00
constructor ( tagType : BattlerTagType , turnCount : integer , showAbility? : boolean ) {
super ( showAbility ) ;
2023-05-06 12:13:35 -04:00
this . tagType = tagType ;
this . turnCount = turnCount ;
}
2024-04-11 09:24:03 -04:00
applyPostSummon ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
2023-05-06 12:13:35 -04:00
return pokemon . addTag ( this . tagType , this . turnCount ) ;
}
}
export class PostSummonStatChangeAbAttr extends PostSummonAbAttr {
private stats : BattleStat [ ] ;
private levels : integer ;
private selfTarget : boolean ;
2024-05-05 07:52:27 -07:00
private intimidate : boolean ;
2023-05-06 12:13:35 -04:00
2024-05-05 07:52:27 -07:00
constructor ( stats : BattleStat | BattleStat [ ] , levels : integer , selfTarget? : boolean , intimidate? : boolean ) {
super ( false ) ;
2023-05-06 12:13:35 -04:00
this . stats = typeof ( stats ) === 'number'
? [ stats as BattleStat ]
: stats as BattleStat [ ] ;
this . levels = levels ;
this . selfTarget = ! ! selfTarget ;
2024-05-05 07:52:27 -07:00
this . intimidate = ! ! intimidate ;
2023-05-06 12:13:35 -04:00
}
2024-04-11 09:24:03 -04:00
applyPostSummon ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
2024-05-05 07:52:27 -07:00
queueShowAbility ( pokemon , passive ) ; // TODO: Better solution than manually showing the ability here
if ( this . selfTarget ) {
pokemon . scene . pushPhase ( new StatChangePhase ( pokemon . scene , pokemon . getBattlerIndex ( ) , true , this . stats , this . levels ) ) ;
return true ;
2023-05-18 11:11:06 -04:00
}
2024-05-05 07:52:27 -07:00
for ( let opponent of pokemon . getOpponents ( ) ) {
const cancelled = new Utils . BooleanHolder ( false )
if ( this . intimidate ) {
applyAbAttrs ( IntimidateImmunityAbAttr , opponent , cancelled ) ;
applyAbAttrs ( PostIntimidateStatChangeAbAttr , opponent , cancelled ) ;
}
if ( ! cancelled . value ) {
const statChangePhase = new StatChangePhase ( pokemon . scene , opponent . getBattlerIndex ( ) , false , this . stats , this . levels ) ;
2023-05-18 11:11:06 -04:00
pokemon . scene . unshiftPhase ( statChangePhase ) ;
2024-05-05 07:52:27 -07:00
}
2023-05-18 11:11:06 -04:00
}
2023-05-06 12:13:35 -04:00
return true ;
}
}
2024-04-23 09:43:35 -04:00
export class PostSummonAllyHealAbAttr extends PostSummonAbAttr {
private healRatio : number ;
private showAnim : boolean ;
constructor ( healRatio : number , showAnim : boolean = false ) {
super ( ) ;
this . healRatio = healRatio || 4 ;
this . showAnim = showAnim ;
}
applyPostSummon ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
const target = pokemon . getAlly ( ) ;
if ( target ? . isActive ( true ) ) {
target . scene . unshiftPhase ( new PokemonHealPhase ( target . scene , target . getBattlerIndex ( ) ,
Math . max ( Math . floor ( pokemon . getMaxHp ( ) / this . healRatio ) , 1 ) , getPokemonMessage ( target , ` drank down all the \ nmatcha that ${ pokemon . name } made! ` ) , true , ! this . showAnim ) ) ;
return true ;
}
return false ;
}
}
2024-04-12 16:08:04 -04:00
export class DownloadAbAttr extends PostSummonAbAttr {
private enemyDef : integer ;
private enemySpDef : integer ;
private stats : BattleStat [ ] ;
applyPostSummon ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
this . enemyDef = 0 ;
this . enemySpDef = 0 ;
for ( let opponent of pokemon . getOpponents ( ) ) {
this . enemyDef += opponent . stats [ BattleStat . DEF ] ;
this . enemySpDef += opponent . stats [ BattleStat . SPDEF ] ;
}
if ( this . enemyDef < this . enemySpDef )
this . stats = [ BattleStat . ATK ] ;
else
this . stats = [ BattleStat . SPATK ] ;
if ( this . enemyDef > 0 && this . enemySpDef > 0 ) { // only activate if there's actually an enemy to download from
pokemon . scene . unshiftPhase ( new StatChangePhase ( pokemon . scene , pokemon . getBattlerIndex ( ) , false , this . stats , 1 ) ) ;
return true ;
}
return false ;
}
}
2023-05-04 12:57:55 -04:00
export class PostSummonWeatherChangeAbAttr extends PostSummonAbAttr {
private weatherType : WeatherType ;
constructor ( weatherType : WeatherType ) {
super ( ) ;
this . weatherType = weatherType ;
}
2024-04-11 09:24:03 -04:00
applyPostSummon ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
2023-05-04 12:57:55 -04:00
if ( ! pokemon . scene . arena . weather ? . isImmutable ( ) )
2024-03-25 10:22:16 -04:00
return pokemon . scene . arena . trySetWeather ( this . weatherType , true ) ;
2023-05-04 12:57:55 -04:00
return false ;
}
}
2024-03-13 12:23:31 -05:00
export class PostSummonTerrainChangeAbAttr extends PostSummonAbAttr {
private terrainType : TerrainType ;
constructor ( terrainType : TerrainType ) {
super ( ) ;
this . terrainType = terrainType ;
}
2024-04-11 09:24:03 -04:00
applyPostSummon ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
2024-03-25 10:22:16 -04:00
return pokemon . scene . arena . trySetTerrain ( this . terrainType , true ) ;
2024-03-13 12:23:31 -05:00
}
}
2024-03-30 00:53:35 -04:00
export class PostSummonFormChangeAbAttr extends PostSummonAbAttr {
private formFunc : ( p : Pokemon ) = > integer ;
constructor ( formFunc : ( ( p : Pokemon ) = > integer ) ) {
super ( true ) ;
this . formFunc = formFunc ;
}
2024-04-11 09:24:03 -04:00
applyPostSummon ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
2024-03-30 00:53:35 -04:00
const formIndex = this . formFunc ( pokemon ) ;
if ( formIndex !== pokemon . formIndex )
return pokemon . scene . triggerPokemonFormChange ( pokemon , SpeciesFormChangeManualTrigger , false ) ;
return false ;
}
}
2024-04-14 13:21:34 +10:00
export class TraceAbAttr extends PostSummonAbAttr {
applyPostSummon ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
const targets = pokemon . getOpponents ( ) ;
2024-04-15 22:52:13 +03:00
if ( ! targets . length )
return false ;
2024-04-30 09:47:10 -06:00
2024-04-14 13:21:34 +10:00
let target : Pokemon ;
if ( targets . length > 1 )
pokemon . scene . executeWithSeedOffset ( ( ) = > target = Utils . randSeedItem ( targets ) , pokemon . scene . currentBattle . waveIndex ) ;
else
target = targets [ 0 ] ;
// Wonder Guard is normally uncopiable so has the attribute, but trace specifically can copy it
if ( target . getAbility ( ) . hasAttr ( UncopiableAbilityAbAttr ) && target . getAbility ( ) . id !== Abilities . WONDER_GUARD )
return false ;
pokemon . summonData . ability = target . getAbility ( ) . id ;
pokemon . scene . queueMessage ( getPokemonMessage ( pokemon , ` traced ${ target . name } 's \ n ${ allAbilities [ target . getAbility ( ) . id ] . name } ! ` ) ) ;
return true ;
}
}
2023-10-29 01:28:56 -04:00
export class PostSummonTransformAbAttr extends PostSummonAbAttr {
constructor ( ) {
super ( true ) ;
}
2024-04-11 09:24:03 -04:00
applyPostSummon ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
2023-10-29 01:28:56 -04:00
const targets = pokemon . getOpponents ( ) ;
2024-04-30 09:47:10 -06:00
if ( ! targets . length )
return false ;
2023-10-29 01:28:56 -04:00
let target : Pokemon ;
if ( targets . length > 1 )
2024-02-17 00:40:03 -05:00
pokemon . scene . executeWithSeedOffset ( ( ) = > target = Utils . randSeedItem ( targets ) , pokemon . scene . currentBattle . waveIndex ) ;
2023-10-29 01:28:56 -04:00
else
target = targets [ 0 ] ;
pokemon . summonData . speciesForm = target . getSpeciesForm ( ) ;
2023-11-24 15:12:26 -05:00
pokemon . summonData . fusionSpeciesForm = target . getFusionSpeciesForm ( ) ;
2024-04-14 12:23:49 -04:00
pokemon . summonData . ability = target . getAbility ( ) . id ;
2023-10-29 01:28:56 -04:00
pokemon . summonData . gender = target . getGender ( ) ;
2023-11-24 15:12:26 -05:00
pokemon . summonData . fusionGender = target . getFusionGender ( ) ;
2023-10-29 01:28:56 -04:00
pokemon . summonData . stats = [ pokemon . stats [ Stat . HP ] ] . concat ( target . stats . slice ( 1 ) ) ;
pokemon . summonData . battleStats = target . summonData . battleStats . slice ( 0 ) ;
pokemon . summonData . moveset = target . getMoveset ( ) . map ( m = > new PokemonMove ( m . moveId , m . ppUsed , m . ppUp ) ) ;
pokemon . summonData . types = target . getTypes ( ) ;
pokemon . scene . playSound ( 'PRSFX- Transform' ) ;
2023-11-24 15:12:26 -05:00
2024-03-27 23:44:11 -04:00
pokemon . loadAssets ( false ) . then ( ( ) = > pokemon . playAnim ( ) ) ;
2023-10-29 01:28:56 -04:00
pokemon . scene . queueMessage ( getPokemonMessage ( pokemon , ` transformed \ ninto ${ target . name } ! ` ) ) ;
return true ;
}
}
2024-01-16 00:28:03 -05:00
export class PreSwitchOutAbAttr extends AbAttr {
constructor ( ) {
super ( true ) ;
}
2024-04-11 09:24:03 -04:00
applyPreSwitchOut ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean | Promise < boolean > {
2024-01-16 00:28:03 -05:00
return false ;
}
}
export class PreSwitchOutResetStatusAbAttr extends PreSwitchOutAbAttr {
2024-04-11 09:24:03 -04:00
applyPreSwitchOut ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean | Promise < boolean > {
2024-01-16 00:28:03 -05:00
if ( pokemon . status ) {
pokemon . resetStatus ( ) ;
pokemon . updateInfo ( ) ;
return true ;
}
return false ;
}
}
2024-04-05 17:32:36 +03:00
export class PreSwitchOutHealAbAttr extends PreSwitchOutAbAttr {
2024-04-11 09:24:03 -04:00
applyPreSwitchOut ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean | Promise < boolean > {
2024-04-05 17:32:36 +03:00
if ( pokemon . getHpRatio ( ) < 1 ) {
const healAmount = Math . floor ( pokemon . getMaxHp ( ) * 0.33 ) ;
pokemon . heal ( healAmount ) ;
pokemon . updateInfo ( ) ;
return true ;
}
return false ;
}
}
2023-04-27 14:30:03 -04:00
export class PreStatChangeAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
applyPreStatChange ( pokemon : Pokemon , passive : boolean , stat : BattleStat , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean | Promise < boolean > {
2023-04-26 23:33:13 -04:00
return false ;
}
}
2023-05-06 12:13:35 -04:00
export class ProtectStatAbAttr extends PreStatChangeAbAttr {
2023-04-27 01:14:15 -04:00
private protectedStat : BattleStat ;
2023-04-26 23:33:13 -04:00
2023-04-27 01:14:15 -04:00
constructor ( protectedStat? : BattleStat ) {
2023-04-26 23:33:13 -04:00
super ( ) ;
2023-04-27 01:14:15 -04:00
this . protectedStat = protectedStat ;
2023-04-26 23:33:13 -04:00
}
2024-04-11 09:24:03 -04:00
applyPreStatChange ( pokemon : Pokemon , passive : boolean , stat : BattleStat , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2023-04-27 01:14:15 -04:00
if ( this . protectedStat === undefined || stat === this . protectedStat ) {
2023-04-26 23:33:13 -04:00
cancelled . value = true ;
return true ;
}
return false ;
}
2023-04-27 01:14:15 -04:00
2024-04-11 09:24:03 -04:00
getTriggerMessage ( pokemon : Pokemon , abilityName : string , . . . args : any [ ] ) : string {
return getPokemonMessage ( pokemon , ` 's ${ abilityName } \ nprevents lowering its ${ this . protectedStat !== undefined ? getBattleStatName ( this . protectedStat ) : 'stats' } ! ` ) ;
2023-04-27 01:14:15 -04:00
}
2023-04-26 23:33:13 -04:00
}
2023-05-04 12:57:55 -04:00
export class PreSetStatusAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
applyPreSetStatus ( pokemon : Pokemon , passive : boolean , effect : StatusEffect , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean | Promise < boolean > {
2023-05-04 12:57:55 -04:00
return false ;
}
}
export class StatusEffectImmunityAbAttr extends PreSetStatusAbAttr {
private immuneEffects : StatusEffect [ ] ;
constructor ( . . . immuneEffects : StatusEffect [ ] ) {
super ( ) ;
this . immuneEffects = immuneEffects ;
}
2023-05-01 22:07:00 -04:00
2024-04-11 09:24:03 -04:00
applyPreSetStatus ( pokemon : Pokemon , passive : boolean , effect : StatusEffect , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2023-05-04 12:57:55 -04:00
if ( ! this . immuneEffects . length || this . immuneEffects . indexOf ( effect ) > - 1 ) {
cancelled . value = true ;
return true ;
}
return false ;
}
2024-04-11 09:24:03 -04:00
getTriggerMessage ( pokemon : Pokemon , abilityName : string , . . . args : any [ ] ) : string {
return getPokemonMessage ( pokemon , ` 's ${ abilityName } \ nprevents ${ this . immuneEffects . length ? getStatusEffectDescriptor ( args [ 0 ] as StatusEffect ) : 'status problems' } ! ` ) ;
2023-05-04 12:57:55 -04:00
}
}
export class PreApplyBattlerTagAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
applyPreApplyBattlerTag ( pokemon : Pokemon , passive : boolean , tag : BattlerTag , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean | Promise < boolean > {
2023-05-04 12:57:55 -04:00
return false ;
}
}
export class BattlerTagImmunityAbAttr extends PreApplyBattlerTagAbAttr {
private immuneTagType : BattlerTagType ;
constructor ( immuneTagType : BattlerTagType ) {
super ( ) ;
this . immuneTagType = immuneTagType ;
}
2024-04-11 09:24:03 -04:00
applyPreApplyBattlerTag ( pokemon : Pokemon , passive : boolean , tag : BattlerTag , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2023-05-04 12:57:55 -04:00
if ( tag . tagType === this . immuneTagType ) {
cancelled . value = true ;
return true ;
}
return false ;
}
2024-04-11 09:24:03 -04:00
getTriggerMessage ( pokemon : Pokemon , abilityName : string , . . . args : any [ ] ) : string {
return getPokemonMessage ( pokemon , ` 's ${ abilityName } \ nprevents ${ ( args [ 0 ] as BattlerTag ) . getDescriptor ( ) } ! ` ) ;
2023-05-04 12:57:55 -04:00
}
}
2024-03-14 00:40:57 -04:00
export class BlockCritAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-03-14 00:40:57 -04:00
( args [ 0 ] as Utils . BooleanHolder ) . value = true ;
return true ;
}
}
2023-04-30 23:58:16 -04:00
2024-04-12 22:21:56 +01:00
export class BonusCritAbAttr extends AbAttr {
2024-04-12 19:31:08 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-04-12 22:21:56 +01:00
( args [ 0 ] as Utils . BooleanHolder ) . value = true ;
return true ;
}
}
2024-05-04 01:56:13 +10:00
export class MultCritAbAttr extends AbAttr {
public multAmount : number ;
constructor ( multAmount : number ) {
super ( true ) ;
this . multAmount = multAmount ;
}
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
const critMult = args [ 0 ] as Utils . NumberHolder ;
if ( critMult . value > 1 ) {
critMult . value *= this . multAmount ;
return true ;
}
return false ;
}
}
2024-04-02 15:14:07 -04:00
export class BlockNonDirectDamageAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-04-02 15:14:07 -04:00
cancelled . value = true ;
return true ;
}
}
2024-03-09 23:49:00 +01:00
export class BlockOneHitKOAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-04-02 15:14:07 -04:00
cancelled . value = true ;
2024-03-09 23:49:00 +01:00
return true ;
}
}
2024-03-28 16:24:11 -04:00
export class IncrementMovePriorityAbAttr extends AbAttr {
2024-04-08 17:10:07 +03:00
private moveIncrementFunc : ( pokemon : Pokemon , move : Move ) = > boolean ;
private increaseAmount : integer ;
2024-03-28 16:24:11 -04:00
2024-04-08 17:10:07 +03:00
constructor ( moveIncrementFunc : ( pokemon : Pokemon , move : Move ) = > boolean , increaseAmount = 1 ) {
2024-03-28 16:24:11 -04:00
super ( true ) ;
this . moveIncrementFunc = moveIncrementFunc ;
2024-04-08 17:10:07 +03:00
this . increaseAmount = increaseAmount ;
2024-03-28 16:24:11 -04:00
}
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-04-08 17:10:07 +03:00
if ( ! this . moveIncrementFunc ( pokemon , args [ 0 ] as Move ) )
2024-03-28 16:24:11 -04:00
return false ;
2024-04-08 17:10:07 +03:00
( args [ 1 ] as Utils . IntegerHolder ) . value += this . increaseAmount ;
2024-03-28 16:24:11 -04:00
return true ;
}
}
2023-12-10 22:29:13 -05:00
export class IgnoreContactAbAttr extends AbAttr { }
2023-04-27 14:30:03 -04:00
export class PreWeatherEffectAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
applyPreWeatherEffect ( pokemon : Pokemon , passive : boolean , weather : Weather , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean | Promise < boolean > {
2023-04-27 14:30:03 -04:00
return false ;
}
}
export class PreWeatherDamageAbAttr extends PreWeatherEffectAbAttr { }
export class BlockWeatherDamageAttr extends PreWeatherDamageAbAttr {
2023-05-02 15:56:41 -04:00
private weatherTypes : WeatherType [ ] ;
constructor ( . . . weatherTypes : WeatherType [ ] ) {
super ( ) ;
this . weatherTypes = weatherTypes ;
}
2024-04-11 09:24:03 -04:00
applyPreWeatherEffect ( pokemon : Pokemon , passive : boolean , weather : Weather , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2023-05-02 15:56:41 -04:00
if ( ! this . weatherTypes . length || this . weatherTypes . indexOf ( weather ? . weatherType ) > - 1 )
cancelled . value = true ;
2023-04-27 14:30:03 -04:00
return true ;
}
}
export class SuppressWeatherEffectAbAttr extends PreWeatherEffectAbAttr {
2023-05-02 22:27:04 -04:00
public affectsImmutable : boolean ;
2023-04-27 14:30:03 -04:00
constructor ( affectsImmutable? : boolean ) {
super ( ) ;
this . affectsImmutable = affectsImmutable ;
}
2024-04-11 09:24:03 -04:00
applyPreWeatherEffect ( pokemon : Pokemon , passive : boolean , weather : Weather , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2023-04-27 14:30:03 -04:00
if ( this . affectsImmutable || weather . isImmutable ( ) ) {
cancelled . value = true ;
return true ;
}
return false ;
}
}
2023-05-02 15:56:41 -04:00
function getWeatherCondition ( . . . weatherTypes : WeatherType [ ] ) : AbAttrCondition {
return ( pokemon : Pokemon ) = > {
if ( pokemon . scene . arena . weather ? . isEffectSuppressed ( pokemon . scene ) )
return false ;
const weatherType = pokemon . scene . arena . weather ? . weatherType ;
return weatherType && weatherTypes . indexOf ( weatherType ) > - 1 ;
} ;
}
2024-04-21 23:01:11 -04:00
function getAnticipationCondition ( ) : AbAttrCondition {
return ( pokemon : Pokemon ) = > {
for ( let opponent of pokemon . getOpponents ( ) ) {
for ( let move of opponent . moveset ) {
// move is super effective
2024-05-06 00:27:56 -05:00
if ( move . getMove ( ) instanceof AttackMove && pokemon . getAttackTypeEffectiveness ( move . getMove ( ) . type , opponent ) >= 2 ) {
2024-04-21 23:01:11 -04:00
return true ;
}
// move is a OHKO
if ( move . getMove ( ) . findAttr ( attr = > attr instanceof OneHitKOAttr ) ) {
return true ;
}
// edge case for hidden power, type is computed
if ( move . getMove ( ) . id === Moves . HIDDEN_POWER ) {
const iv_val = Math . floor ( ( ( opponent . ivs [ Stat . HP ] & 1 )
+ ( opponent . ivs [ Stat . ATK ] & 1 ) * 2
+ ( opponent . ivs [ Stat . DEF ] & 1 ) * 4
+ ( opponent . ivs [ Stat . SPD ] & 1 ) * 8
+ ( opponent . ivs [ Stat . SPATK ] & 1 ) * 16
+ ( opponent . ivs [ Stat . SPDEF ] & 1 ) * 32 ) * 15 / 63 ) ;
const type = [
Type . FIGHTING , Type . FLYING , Type . POISON , Type . GROUND ,
Type . ROCK , Type . BUG , Type . GHOST , Type . STEEL ,
Type . FIRE , Type . WATER , Type . GRASS , Type . ELECTRIC ,
Type . PSYCHIC , Type . ICE , Type . DRAGON , Type . DARK ] [ iv_val ] ;
2024-05-06 00:27:56 -05:00
if ( pokemon . getAttackTypeEffectiveness ( type , opponent ) >= 2 ) {
2024-04-21 23:01:11 -04:00
return true ;
}
}
}
}
return false ;
} ;
}
2024-05-07 14:35:15 +10:00
/ * *
* Creates an ability condition that causes the ability to fail if that ability
* has already been used by that pokemon that battle . It requires an ability to
* be specified due to current limitations in how conditions on abilities work .
* @param { Abilities } ability The ability to check if it ' s already been applied
* @returns { AbAttrCondition } The condition
* /
function getOncePerBattleCondition ( ability : Abilities ) : AbAttrCondition {
return ( pokemon : Pokemon ) = > {
return ! pokemon . battleData ? . abilitiesApplied . includes ( ability ) ;
}
}
2024-05-03 22:10:40 -04:00
export class ForewarnAbAttr extends PostSummonAbAttr {
constructor ( ) {
super ( true ) ;
}
applyPostSummon ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
let maxPowerSeen = 0 ;
let maxMove = "" ;
let movePower = 0 ;
for ( let opponent of pokemon . getOpponents ( ) ) {
for ( let move of opponent . moveset ) {
if ( move . getMove ( ) instanceof StatusMove ) {
movePower = 1 ;
} else if ( move . getMove ( ) . findAttr ( attr = > attr instanceof OneHitKOAttr ) ) {
movePower = 150 ;
} else if ( move . getMove ( ) . id === Moves . COUNTER || move . getMove ( ) . id === Moves . MIRROR_COAT || move . getMove ( ) . id === Moves . METAL_BURST ) {
movePower = 120 ;
} else if ( move . getMove ( ) . power === - 1 ) {
movePower = 80 ;
} else {
movePower = move . getMove ( ) . power ;
}
if ( movePower > maxPowerSeen ) {
maxPowerSeen = movePower ;
maxMove = move . getName ( ) ;
}
}
}
pokemon . scene . queueMessage ( getPokemonMessage ( pokemon , " was forewarned about " + maxMove + "!" ) ) ;
return true ;
}
}
export class FriskAbAttr extends PostSummonAbAttr {
constructor ( ) {
super ( true ) ;
}
applyPostSummon ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
for ( let opponent of pokemon . getOpponents ( ) ) {
pokemon . scene . queueMessage ( getPokemonMessage ( pokemon , " frisked " + opponent . name + "\'s " + opponent . getAbility ( ) . name + "!" ) ) ;
}
return true ;
}
}
2024-03-18 21:22:27 -04:00
export class PostWeatherChangeAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
applyPostWeatherChange ( pokemon : Pokemon , passive : boolean , weather : WeatherType , args : any [ ] ) : boolean {
2024-03-18 21:22:27 -04:00
return false ;
}
}
export class PostWeatherChangeAddBattlerTagAttr extends PostWeatherChangeAbAttr {
private tagType : BattlerTagType ;
private turnCount : integer ;
private weatherTypes : WeatherType [ ] ;
constructor ( tagType : BattlerTagType , turnCount : integer , . . . weatherTypes : WeatherType [ ] ) {
super ( ) ;
this . tagType = tagType ;
this . turnCount = turnCount ;
this . weatherTypes = weatherTypes ;
}
2024-04-11 09:24:03 -04:00
applyPostWeatherChange ( pokemon : Pokemon , passive : boolean , weather : WeatherType , args : any [ ] ) : boolean {
2024-03-18 21:22:27 -04:00
console . log ( this . weatherTypes . find ( w = > weather === w ) , WeatherType [ weather ] ) ;
if ( ! this . weatherTypes . find ( w = > weather === w ) )
return false ;
return pokemon . addTag ( this . tagType , this . turnCount ) ;
}
}
2023-05-02 15:56:41 -04:00
export class PostWeatherLapseAbAttr extends AbAttr {
protected weatherTypes : WeatherType [ ] ;
2023-04-27 14:30:03 -04:00
constructor ( . . . weatherTypes : WeatherType [ ] ) {
super ( ) ;
this . weatherTypes = weatherTypes ;
}
2024-04-11 09:24:03 -04:00
applyPostWeatherLapse ( pokemon : Pokemon , passive : boolean , weather : Weather , args : any [ ] ) : boolean | Promise < boolean > {
2023-05-02 15:56:41 -04:00
return false ;
}
getCondition ( ) : AbAttrCondition {
return getWeatherCondition ( . . . this . weatherTypes ) ;
}
}
export class PostWeatherLapseHealAbAttr extends PostWeatherLapseAbAttr {
private healFactor : integer ;
constructor ( healFactor : integer , . . . weatherTypes : WeatherType [ ] ) {
super ( . . . weatherTypes ) ;
this . healFactor = healFactor ;
}
2024-04-11 09:24:03 -04:00
applyPostWeatherLapse ( pokemon : Pokemon , passive : boolean , weather : Weather , args : any [ ] ) : boolean {
2023-05-02 15:56:41 -04:00
if ( pokemon . getHpRatio ( ) < 1 ) {
2023-04-27 14:30:03 -04:00
const scene = pokemon . scene ;
2024-04-11 09:24:03 -04:00
const abilityName = ( ! passive ? pokemon . getAbility ( ) : pokemon . getPassiveAbility ( ) ) . name ;
2023-05-18 11:11:06 -04:00
scene . unshiftPhase ( new PokemonHealPhase ( scene , pokemon . getBattlerIndex ( ) ,
2024-04-11 09:24:03 -04:00
Math . max ( Math . floor ( pokemon . getMaxHp ( ) / ( 16 / this . healFactor ) ) , 1 ) , getPokemonMessage ( pokemon , ` 's ${ abilityName } \ nrestored its HP a little! ` ) , true ) ) ;
2023-05-02 15:56:41 -04:00
return true ;
}
return false ;
}
}
export class PostWeatherLapseDamageAbAttr extends PostWeatherLapseAbAttr {
private damageFactor : integer ;
constructor ( damageFactor : integer , . . . weatherTypes : WeatherType [ ] ) {
super ( . . . weatherTypes ) ;
this . damageFactor = damageFactor ;
}
2024-04-11 09:24:03 -04:00
applyPostWeatherLapse ( pokemon : Pokemon , passive : boolean , weather : Weather , args : any [ ] ) : boolean {
2023-05-02 15:56:41 -04:00
if ( pokemon . getHpRatio ( ) < 1 ) {
const scene = pokemon . scene ;
2024-04-11 09:24:03 -04:00
const abilityName = ( ! passive ? pokemon . getAbility ( ) : pokemon . getPassiveAbility ( ) ) . name ;
scene . queueMessage ( getPokemonMessage ( pokemon , ` is hurt \ nby its ${ abilityName } ! ` ) ) ;
2024-03-01 10:15:43 -05:00
pokemon . damageAndUpdate ( Math . ceil ( pokemon . getMaxHp ( ) / ( 16 / this . damageFactor ) ) , HitResult . OTHER ) ;
2023-04-27 14:30:03 -04:00
return true ;
}
return false ;
}
}
2024-03-18 21:22:27 -04:00
export class PostTerrainChangeAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
applyPostTerrainChange ( pokemon : Pokemon , passive : boolean , terrain : TerrainType , args : any [ ] ) : boolean {
2024-03-18 21:22:27 -04:00
return false ;
}
}
export class PostTerrainChangeAddBattlerTagAttr extends PostTerrainChangeAbAttr {
private tagType : BattlerTagType ;
private turnCount : integer ;
private terrainTypes : TerrainType [ ] ;
constructor ( tagType : BattlerTagType , turnCount : integer , . . . terrainTypes : TerrainType [ ] ) {
super ( ) ;
this . tagType = tagType ;
this . turnCount = turnCount ;
this . terrainTypes = terrainTypes ;
}
2024-04-11 09:24:03 -04:00
applyPostTerrainChange ( pokemon : Pokemon , passive : boolean , terrain : TerrainType , args : any [ ] ) : boolean {
2024-04-25 01:23:45 -04:00
if ( ! this . terrainTypes . find ( t = > t === terrain ) )
2024-03-18 21:22:27 -04:00
return false ;
return pokemon . addTag ( this . tagType , this . turnCount ) ;
}
}
2024-03-13 12:23:31 -05:00
function getTerrainCondition ( . . . terrainTypes : TerrainType [ ] ) : AbAttrCondition {
return ( pokemon : Pokemon ) = > {
const terrainType = pokemon . scene . arena . terrain ? . terrainType ;
return terrainType && terrainTypes . indexOf ( terrainType ) > - 1 ;
} ;
}
2023-12-10 22:29:13 -05:00
export class PostTurnAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
applyPostTurn ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean | Promise < boolean > {
2023-12-10 22:29:13 -05:00
return false ;
}
}
2024-04-11 05:16:09 +01:00
export class PostTurnResetStatusAbAttr extends PostTurnAbAttr {
2024-04-11 09:24:03 -04:00
applyPostTurn ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
2024-04-11 05:16:09 +01:00
if ( pokemon . status ) {
pokemon . scene . queueMessage ( getPokemonMessage ( pokemon , getStatusEffectHealText ( pokemon . status ? . effect ) ) ) ;
pokemon . resetStatus ( ) ;
pokemon . updateInfo ( ) ;
return true ;
}
return false ;
}
}
2024-04-25 01:23:45 -04:00
export class MoodyAbAttr extends PostTurnAbAttr {
constructor ( ) {
super ( true ) ;
}
applyPostTurn ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
let selectableStats = [ BattleStat . ATK , BattleStat . DEF , BattleStat . SPATK , BattleStat . SPDEF , BattleStat . SPD ] ;
2024-05-03 22:30:23 -04:00
let increaseStatArray = selectableStats . filter ( s = > pokemon . summonData . battleStats [ s ] < 6 ) ;
let decreaseStatArray = selectableStats . filter ( s = > pokemon . summonData . battleStats [ s ] > - 6 ) ;
if ( increaseStatArray . length > 0 ) {
let increaseStat = increaseStatArray [ Utils . randInt ( increaseStatArray . length ) ] ;
decreaseStatArray = decreaseStatArray . filter ( s = > s !== increaseStat ) ;
pokemon . scene . unshiftPhase ( new StatChangePhase ( pokemon . scene , pokemon . getBattlerIndex ( ) , true , [ increaseStat ] , 2 ) ) ;
}
if ( decreaseStatArray . length > 0 ) {
let decreaseStat = selectableStats [ Utils . randInt ( selectableStats . length ) ] ;
pokemon . scene . unshiftPhase ( new StatChangePhase ( pokemon . scene , pokemon . getBattlerIndex ( ) , true , [ decreaseStat ] , - 1 ) ) ;
}
2024-04-25 01:23:45 -04:00
return true ;
}
}
2023-12-22 01:16:56 -05:00
export class PostTurnStatChangeAbAttr extends PostTurnAbAttr {
private stats : BattleStat [ ] ;
private levels : integer ;
constructor ( stats : BattleStat | BattleStat [ ] , levels : integer ) {
super ( true ) ;
this . stats = Array . isArray ( stats )
? stats
: [ stats ] ;
this . levels = levels ;
}
2024-04-11 09:24:03 -04:00
applyPostTurn ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
2023-12-22 01:16:56 -05:00
pokemon . scene . unshiftPhase ( new StatChangePhase ( pokemon . scene , pokemon . getBattlerIndex ( ) , true , this . stats , this . levels ) ) ;
2023-12-10 22:29:13 -05:00
return true ;
}
}
export class PostTurnHealAbAttr extends PostTurnAbAttr {
2024-04-11 09:24:03 -04:00
applyPostTurn ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
2023-12-10 22:29:13 -05:00
if ( pokemon . getHpRatio ( ) < 1 ) {
const scene = pokemon . scene ;
2024-04-11 09:24:03 -04:00
const abilityName = ( ! passive ? pokemon . getAbility ( ) : pokemon . getPassiveAbility ( ) ) . name ;
2023-12-10 22:29:13 -05:00
scene . unshiftPhase ( new PokemonHealPhase ( scene , pokemon . getBattlerIndex ( ) ,
2024-04-11 09:24:03 -04:00
Math . max ( Math . floor ( pokemon . getMaxHp ( ) / 16 ) , 1 ) , getPokemonMessage ( pokemon , ` 's ${ abilityName } \ nrestored its HP a little! ` ) , true ) ) ;
2023-12-10 22:29:13 -05:00
return true ;
}
return false ;
}
}
2024-03-30 00:53:35 -04:00
export class PostTurnFormChangeAbAttr extends PostTurnAbAttr {
private formFunc : ( p : Pokemon ) = > integer ;
constructor ( formFunc : ( ( p : Pokemon ) = > integer ) ) {
super ( true ) ;
this . formFunc = formFunc ;
}
2024-04-11 09:24:03 -04:00
applyPostTurn ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
2024-03-30 00:53:35 -04:00
const formIndex = this . formFunc ( pokemon ) ;
if ( formIndex !== pokemon . formIndex ) {
pokemon . scene . triggerPokemonFormChange ( pokemon , SpeciesFormChangeManualTrigger , false ) ;
return true ;
}
return false ;
}
}
2024-04-08 09:31:30 -04:00
export class PostBiomeChangeAbAttr extends AbAttr { }
export class PostBiomeChangeWeatherChangeAbAttr extends PostBiomeChangeAbAttr {
private weatherType : WeatherType ;
constructor ( weatherType : WeatherType ) {
super ( ) ;
this . weatherType = weatherType ;
}
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-04-08 09:31:30 -04:00
if ( ! pokemon . scene . arena . weather ? . isImmutable ( ) )
return pokemon . scene . arena . trySetWeather ( this . weatherType , true ) ;
return false ;
}
}
export class PostBiomeChangeTerrainChangeAbAttr extends PostBiomeChangeAbAttr {
private terrainType : TerrainType ;
constructor ( terrainType : TerrainType ) {
super ( ) ;
this . terrainType = terrainType ;
}
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-04-08 09:31:30 -04:00
return pokemon . scene . arena . trySetTerrain ( this . terrainType , true ) ;
}
}
2023-11-06 16:11:38 +13:00
export class StatChangeMultiplierAbAttr extends AbAttr {
private multiplier : integer ;
constructor ( multiplier : integer ) {
super ( true ) ;
this . multiplier = multiplier ;
}
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2023-11-06 16:11:38 +13:00
( args [ 0 ] as Utils . IntegerHolder ) . value *= this . multiplier ;
return true ;
}
}
2024-05-04 16:38:53 -07:00
export class StatChangeCopyAbAttr extends AbAttr {
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean | Promise < boolean > {
pokemon . scene . unshiftPhase ( new StatChangePhase ( pokemon . scene , pokemon . getBattlerIndex ( ) , true , ( args [ 0 ] as BattleStat [ ] ) , ( args [ 1 ] as integer ) , true , false , false ) ) ;
return true ;
}
}
2024-03-14 00:40:57 -04:00
export class BypassBurnDamageReductionAbAttr extends AbAttr {
constructor ( ) {
super ( false ) ;
}
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-03-14 00:40:57 -04:00
cancelled . value = true ;
return true ;
}
}
2023-12-22 01:16:56 -05:00
export class DoubleBerryEffectAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2023-12-22 01:16:56 -05:00
( args [ 0 ] as Utils . NumberHolder ) . value *= 2 ;
return true ;
}
}
2023-12-23 01:21:01 -05:00
export class PreventBerryUseAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2023-12-23 01:21:01 -05:00
cancelled . value = true ;
return true ;
}
}
2023-12-22 18:08:37 -04:00
export class RunSuccessAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2023-12-22 18:08:37 -04:00
( args [ 0 ] as Utils . IntegerHolder ) . value = 256 ;
return true ;
}
}
2023-05-04 12:57:55 -04:00
export class CheckTrappedAbAttr extends AbAttr {
2023-12-22 22:04:30 -05:00
constructor ( ) {
super ( false ) ;
}
2024-04-11 09:24:03 -04:00
applyCheckTrapped ( pokemon : Pokemon , passive : boolean , trapped : Utils.BooleanHolder , args : any [ ] ) : boolean | Promise < boolean > {
2023-05-04 12:57:55 -04:00
return false ;
}
}
export class ArenaTrapAbAttr extends CheckTrappedAbAttr {
2024-04-11 09:24:03 -04:00
applyCheckTrapped ( pokemon : Pokemon , passive : boolean , trapped : Utils.BooleanHolder , args : any [ ] ) : boolean {
2023-05-04 12:57:55 -04:00
trapped . value = true ;
return true ;
}
2024-04-11 09:24:03 -04:00
getTriggerMessage ( pokemon : Pokemon , abilityName : string , . . . args : any [ ] ) : string {
return getPokemonMessage ( pokemon , ` \ 's ${ abilityName } \ nprevents switching! ` ) ;
2023-05-04 12:57:55 -04:00
}
}
2023-12-22 18:08:37 -04:00
export class MaxMultiHitAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2023-12-22 18:08:37 -04:00
( args [ 0 ] as Utils . IntegerHolder ) . value = 0 ;
return true ;
}
}
2024-03-06 21:05:23 -05:00
export class PostBattleAbAttr extends AbAttr {
constructor ( ) {
super ( true ) ;
}
2024-04-11 09:24:03 -04:00
applyPostBattle ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
2024-03-06 21:05:23 -05:00
return false ;
}
}
export class PostBattleLootAbAttr extends PostBattleAbAttr {
2024-04-11 09:24:03 -04:00
applyPostBattle ( pokemon : Pokemon , passive : boolean , args : any [ ] ) : boolean {
2024-03-06 21:05:23 -05:00
const postBattleLoot = pokemon . scene . currentBattle . postBattleLoot ;
if ( postBattleLoot . length ) {
const randItem = Utils . randSeedItem ( postBattleLoot ) ;
if ( pokemon . scene . tryTransferHeldItemModifier ( randItem , pokemon , false , true , true ) ) {
2024-03-08 14:49:17 -05:00
postBattleLoot . splice ( postBattleLoot . indexOf ( randItem ) , 1 ) ;
2024-03-06 21:05:23 -05:00
pokemon . scene . queueMessage ( getPokemonMessage ( pokemon , ` picked up \ n ${ randItem . type . name } ! ` ) ) ;
return true ;
}
}
return false ;
}
}
2024-04-09 18:05:15 -04:00
export class PostFaintAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
applyPostFaint ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
2024-04-09 18:05:15 -04:00
return false ;
}
}
export class PostFaintContactDamageAbAttr extends PostFaintAbAttr {
private damageRatio : integer ;
constructor ( damageRatio : integer ) {
super ( ) ;
this . damageRatio = damageRatio ;
}
2024-04-11 09:24:03 -04:00
applyPostFaint ( pokemon : Pokemon , passive : boolean , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , args : any [ ] ) : boolean {
2024-04-09 18:05:15 -04:00
if ( move . getMove ( ) . checkFlag ( MoveFlags . MAKES_CONTACT , attacker , pokemon ) ) {
2024-04-25 21:42:41 -04:00
const cancelled = new Utils . BooleanHolder ( false ) ;
pokemon . scene . getField ( true ) . map ( p = > applyAbAttrs ( FieldPreventExplosiveMovesAbAttr , p , cancelled ) )
if ( cancelled ) {
return false ;
}
2024-04-09 18:05:15 -04:00
attacker . damageAndUpdate ( Math . ceil ( attacker . getMaxHp ( ) * ( 1 / this . damageRatio ) ) , HitResult . OTHER ) ;
2024-04-25 20:51:04 -04:00
attacker . turnData . damageTaken += Math . ceil ( attacker . getMaxHp ( ) * ( 1 / this . damageRatio ) ) ;
2024-04-09 18:05:15 -04:00
return true ;
}
return false ;
}
2024-04-11 09:24:03 -04:00
getTriggerMessage ( pokemon : Pokemon , abilityName : string , . . . args : any [ ] ) : string {
return getPokemonMessage ( pokemon , ` 's ${ abilityName } hurt \ nits attacker! ` ) ;
2024-04-09 18:05:15 -04:00
}
}
2024-03-11 20:55:41 -04:00
export class RedirectMoveAbAttr extends AbAttr {
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-03-11 20:55:41 -04:00
if ( this . canRedirect ( args [ 0 ] as Moves ) ) {
const target = args [ 1 ] as Utils . IntegerHolder ;
const newTarget = pokemon . getBattlerIndex ( ) ;
if ( target . value !== newTarget ) {
target . value = newTarget ;
return true ;
}
}
return false ;
}
canRedirect ( moveId : Moves ) : boolean {
const move = allMoves [ moveId ] ;
return ! ! [ MoveTarget . NEAR_OTHER , MoveTarget . OTHER ] . find ( t = > move . moveTarget === t ) ;
}
}
export class RedirectTypeMoveAbAttr extends RedirectMoveAbAttr {
public type : Type ;
constructor ( type : Type ) {
super ( ) ;
this . type = type ;
}
canRedirect ( moveId : Moves ) : boolean {
return super . canRedirect ( moveId ) && allMoves [ moveId ] . type === this . type ;
}
}
2024-01-16 00:28:03 -05:00
export class ReduceStatusEffectDurationAbAttr extends AbAttr {
private statusEffect : StatusEffect ;
constructor ( statusEffect : StatusEffect ) {
super ( true ) ;
this . statusEffect = statusEffect ;
}
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-01-16 00:28:03 -05:00
if ( args [ 0 ] === this . statusEffect ) {
( args [ 1 ] as Utils . IntegerHolder ) . value = Math . floor ( ( args [ 1 ] as Utils . IntegerHolder ) . value / 2 ) ;
return true ;
}
return false ;
}
}
export class FlinchEffectAbAttr extends AbAttr {
constructor ( ) {
super ( true ) ;
}
}
export class FlinchStatChangeAbAttr extends FlinchEffectAbAttr {
private stats : BattleStat [ ] ;
private levels : integer ;
constructor ( stats : BattleStat | BattleStat [ ] , levels : integer ) {
super ( ) ;
this . stats = Array . isArray ( stats )
? stats
: [ stats ] ;
this . levels = levels ;
}
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-01-16 00:28:03 -05:00
pokemon . scene . unshiftPhase ( new StatChangePhase ( pokemon . scene , pokemon . getBattlerIndex ( ) , true , this . stats , this . levels ) ) ;
return true ;
}
}
2024-04-11 09:24:03 -04:00
export class IncreasePpAbAttr extends AbAttr { }
2024-05-05 07:52:27 -07:00
export class ForceSwitchOutImmunityAbAttr extends AbAttr {
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-05-05 10:54:22 -07:00
cancelled . value = true ;
2024-05-05 07:52:27 -07:00
return true ;
}
}
2024-01-16 00:28:03 -05:00
export class ReduceBerryUseThresholdAbAttr extends AbAttr {
constructor ( ) {
2024-04-11 09:24:03 -04:00
super ( ) ;
2024-01-16 00:28:03 -05:00
}
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-01-16 00:28:03 -05:00
const hpRatio = pokemon . getHpRatio ( ) ;
if ( args [ 0 ] . value < hpRatio ) {
args [ 0 ] . value *= 2 ;
return args [ 0 ] . value >= hpRatio ;
}
return false ;
}
}
2023-12-10 22:29:13 -05:00
export class WeightMultiplierAbAttr extends AbAttr {
private multiplier : integer ;
constructor ( multiplier : integer ) {
2024-04-11 09:24:03 -04:00
super ( ) ;
2023-12-10 22:29:13 -05:00
this . multiplier = multiplier ;
}
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2023-12-10 22:29:13 -05:00
( args [ 0 ] as Utils . NumberHolder ) . value *= this . multiplier ;
return true ;
}
}
2024-01-05 22:24:05 -05:00
export class SyncEncounterNatureAbAttr extends AbAttr {
constructor ( ) {
super ( false ) ;
}
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-04-02 23:00:56 -04:00
( args [ 0 ] as Pokemon ) . setNature ( pokemon . getNature ( ) ) ;
2024-01-05 22:24:05 -05:00
return true ;
}
}
2024-03-14 00:40:57 -04:00
export class MoveAbilityBypassAbAttr extends AbAttr {
2024-04-18 15:44:03 +10:00
private moveIgnoreFunc : ( pokemon : Pokemon , move : Move ) = > boolean ;
constructor ( moveIgnoreFunc ? : ( pokemon : Pokemon , move : Move ) = > boolean ) {
super ( false ) ;
this . moveIgnoreFunc = moveIgnoreFunc || ( ( pokemon , move ) = > true ) ;
}
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
if ( this . moveIgnoreFunc ( pokemon , ( args [ 0 ] as Move ) ) ) {
cancelled . value = true ;
return true ;
}
return false ;
}
}
export class SuppressFieldAbilitiesAbAttr extends AbAttr {
2024-03-14 00:40:57 -04:00
constructor ( ) {
super ( false ) ;
}
2024-04-11 09:24:03 -04:00
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-04-18 15:44:03 +10:00
const ability = ( args [ 0 ] as Ability ) ;
if ( ! ability . hasAttr ( UnsuppressableAbilityAbAttr ) && ! ability . hasAttr ( SuppressFieldAbilitiesAbAttr ) ) {
cancelled . value = true ;
return true ;
}
return false ;
2024-03-14 00:40:57 -04:00
}
}
2024-04-21 15:26:30 +10:00
export class AlwaysHitAbAttr extends AbAttr { }
2024-04-13 11:08:32 +10:00
export class UncopiableAbilityAbAttr extends AbAttr {
constructor ( ) {
super ( false ) ;
}
}
export class UnsuppressableAbilityAbAttr extends AbAttr {
constructor ( ) {
super ( false ) ;
}
}
export class UnswappableAbilityAbAttr extends AbAttr {
constructor ( ) {
super ( false ) ;
}
}
export class NoTransformAbilityAbAttr extends AbAttr {
2024-03-04 21:32:11 -05:00
constructor ( ) {
super ( false ) ;
}
}
2024-04-19 04:27:34 +10:00
export class NoFusionAbilityAbAttr extends AbAttr {
constructor ( ) {
super ( false ) ;
}
}
2024-05-06 00:27:56 -05:00
export class IgnoreTypeImmunityAbAttr extends AbAttr {
defenderType : Type ;
allowedMoveTypes : Type [ ] ;
constructor ( defenderType : Type , allowedMoveTypes : Type [ ] ) {
super ( true ) ;
this . defenderType = defenderType ;
this . allowedMoveTypes = allowedMoveTypes ;
}
apply ( pokemon : Pokemon , passive : boolean , cancelled : Utils.BooleanHolder , args : any [ ] ) : boolean {
2024-05-08 00:32:38 -05:00
if ( this . defenderType === ( args [ 1 ] as Type ) && this . allowedMoveTypes . includes ( args [ 0 ] as Type ) ) {
cancelled . value = true ;
return true ;
2024-05-06 00:27:56 -05:00
}
2024-05-08 00:32:38 -05:00
return false ;
2024-05-06 00:27:56 -05:00
}
}
2023-12-22 22:04:30 -05:00
function applyAbAttrsInternal < TAttr extends AbAttr > ( attrType : { new ( . . . args : any [ ] ) : TAttr } ,
2024-04-11 09:24:03 -04:00
pokemon : Pokemon , applyFunc : AbAttrApplyFunc < TAttr > , args : any [ ] , isAsync : boolean = false , showAbilityInstant : boolean = false , quiet : boolean = false , passive : boolean = false ) : Promise < void > {
2023-12-22 21:42:47 -05:00
return new Promise ( resolve = > {
2024-04-11 09:24:03 -04:00
if ( ! pokemon . canApplyAbility ( passive ) ) {
if ( ! passive )
return applyAbAttrsInternal ( attrType , pokemon , applyFunc , args , isAsync , showAbilityInstant , quiet , true ) . then ( ( ) = > resolve ( ) ) ;
else
return resolve ( ) ;
}
2023-04-27 14:30:03 -04:00
2024-04-11 09:24:03 -04:00
const ability = ( ! passive ? pokemon . getAbility ( ) : pokemon . getPassiveAbility ( ) ) ;
2023-12-22 22:04:30 -05:00
const attrs = ability . getAttrs ( attrType ) as TAttr [ ] ;
2023-04-27 14:30:03 -04:00
2023-12-22 21:42:47 -05:00
const clearSpliceQueueAndResolve = ( ) = > {
pokemon . scene . clearPhaseQueueSplice ( ) ;
2024-04-11 09:24:03 -04:00
if ( ! passive )
return applyAbAttrsInternal ( attrType , pokemon , applyFunc , args , isAsync , showAbilityInstant , quiet , true ) . then ( ( ) = > resolve ( ) ) ;
else
return resolve ( ) ;
2023-12-22 21:42:47 -05:00
} ;
const applyNextAbAttr = ( ) = > {
if ( attrs . length )
applyAbAttr ( attrs . shift ( ) ) ;
else
clearSpliceQueueAndResolve ( ) ;
} ;
2023-12-22 22:04:30 -05:00
const applyAbAttr = ( attr : TAttr ) = > {
2023-12-22 21:42:47 -05:00
if ( ! canApplyAttr ( pokemon , attr ) )
return applyNextAbAttr ( ) ;
pokemon . scene . setPhaseQueueSplice ( ) ;
const onApplySuccess = ( ) = > {
2024-05-07 14:35:15 +10:00
if ( pokemon . battleData && ! pokemon . battleData . abilitiesApplied . includes ( ability . id ) ) {
pokemon . battleData . abilitiesApplied . push ( ability . id ) ;
}
2024-02-28 11:34:55 -05:00
if ( attr . showAbility && ! quiet ) {
2023-12-22 22:04:30 -05:00
if ( showAbilityInstant )
2024-04-11 09:24:03 -04:00
pokemon . scene . abilityBar . showAbility ( pokemon , passive ) ;
2023-12-22 22:04:30 -05:00
else
2024-04-11 09:24:03 -04:00
queueShowAbility ( pokemon , passive ) ;
2023-12-22 22:04:30 -05:00
}
2024-02-28 11:34:55 -05:00
if ( ! quiet ) {
2024-04-11 09:24:03 -04:00
const message = attr . getTriggerMessage ( pokemon , ( ! passive ? pokemon . getAbility ( ) : pokemon . getPassiveAbility ( ) ) . name , args ) ;
2024-02-28 11:34:55 -05:00
if ( message ) {
if ( isAsync )
pokemon . scene . ui . showText ( message , null , ( ) = > pokemon . scene . ui . showText ( null , 0 ) , null , true ) ;
else
pokemon . scene . queueMessage ( message ) ;
}
2023-12-22 22:04:30 -05:00
}
2023-12-22 21:42:47 -05:00
} ;
2024-04-11 09:24:03 -04:00
const result = applyFunc ( attr , passive ) ;
2023-12-22 21:42:47 -05:00
if ( result instanceof Promise ) {
result . then ( success = > {
if ( success )
onApplySuccess ( ) ;
applyNextAbAttr ( ) ;
} ) ;
} else {
if ( result )
onApplySuccess ( ) ;
applyNextAbAttr ( ) ;
}
} ;
applyNextAbAttr ( ) ;
} ) ;
2023-04-27 14:30:03 -04:00
}
2023-12-22 22:04:30 -05:00
export function applyAbAttrs ( attrType : { new ( . . . args : any [ ] ) : AbAttr } , pokemon : Pokemon , cancelled : Utils.BooleanHolder , . . . args : any [ ] ) : Promise < void > {
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < AbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . apply ( pokemon , passive , cancelled , args ) , args ) ;
2023-12-22 22:04:30 -05:00
}
2024-03-30 00:53:35 -04:00
export function applyPostBattleInitAbAttrs ( attrType : { new ( . . . args : any [ ] ) : PostBattleInitAbAttr } ,
pokemon : Pokemon , . . . args : any [ ] ) : Promise < void > {
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < PostBattleInitAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyPostBattleInit ( pokemon , passive , args ) , args ) ;
2024-03-30 00:53:35 -04:00
}
2023-04-27 14:30:03 -04:00
export function applyPreDefendAbAttrs ( attrType : { new ( . . . args : any [ ] ) : PreDefendAbAttr } ,
2023-12-22 21:42:47 -05:00
pokemon : Pokemon , attacker : Pokemon , move : PokemonMove , cancelled : Utils.BooleanHolder , . . . args : any [ ] ) : Promise < void > {
2024-02-28 11:34:55 -05:00
const simulated = args . length > 1 && args [ 1 ] ;
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < PreDefendAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyPreDefend ( pokemon , passive , attacker , move , cancelled , args ) , args , false , false , simulated ) ;
2023-04-27 14:30:03 -04:00
}
2023-05-04 12:57:55 -04:00
export function applyPostDefendAbAttrs ( attrType : { new ( . . . args : any [ ] ) : PostDefendAbAttr } ,
2023-12-22 21:42:47 -05:00
pokemon : Pokemon , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , . . . args : any [ ] ) : Promise < void > {
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < PostDefendAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyPostDefend ( pokemon , passive , attacker , move , hitResult , args ) , args ) ;
2023-12-22 21:42:47 -05:00
}
2023-05-02 00:11:31 -04:00
2023-12-22 21:42:47 -05:00
export function applyBattleStatMultiplierAbAttrs ( attrType : { new ( . . . args : any [ ] ) : BattleStatMultiplierAbAttr } ,
pokemon : Pokemon , battleStat : BattleStat , statValue : Utils.NumberHolder , . . . args : any [ ] ) : Promise < void > {
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < BattleStatMultiplierAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyBattleStat ( pokemon , passive , battleStat , statValue , args ) , args ) ;
2023-05-02 00:11:31 -04:00
}
2023-04-27 14:30:03 -04:00
export function applyPreAttackAbAttrs ( attrType : { new ( . . . args : any [ ] ) : PreAttackAbAttr } ,
2023-12-22 21:42:47 -05:00
pokemon : Pokemon , defender : Pokemon , move : PokemonMove , . . . args : any [ ] ) : Promise < void > {
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < PreAttackAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyPreAttack ( pokemon , passive , defender , move , args ) , args ) ;
2023-04-27 14:30:03 -04:00
}
2023-12-22 01:16:56 -05:00
export function applyPostAttackAbAttrs ( attrType : { new ( . . . args : any [ ] ) : PostAttackAbAttr } ,
2023-12-22 21:42:47 -05:00
pokemon : Pokemon , defender : Pokemon , move : PokemonMove , hitResult : HitResult , . . . args : any [ ] ) : Promise < void > {
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < PostAttackAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyPostAttack ( pokemon , passive , defender , move , hitResult , args ) , args ) ;
2023-12-22 01:16:56 -05:00
}
2024-04-08 00:20:24 +03:00
export function applyPostKnockOutAbAttrs ( attrType : { new ( . . . args : any [ ] ) : PostKnockOutAbAttr } ,
2024-04-14 13:21:34 +10:00
pokemon : Pokemon , knockedOut : Pokemon , . . . args : any [ ] ) : Promise < void > {
return applyAbAttrsInternal < PostKnockOutAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyPostKnockOut ( pokemon , passive , knockedOut , args ) , args ) ;
2024-04-08 00:20:24 +03:00
}
2024-03-29 22:08:27 -04:00
export function applyPostVictoryAbAttrs ( attrType : { new ( . . . args : any [ ] ) : PostVictoryAbAttr } ,
pokemon : Pokemon , . . . args : any [ ] ) : Promise < void > {
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < PostVictoryAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyPostVictory ( pokemon , passive , args ) , args ) ;
2024-03-29 22:08:27 -04:00
}
2023-05-04 12:57:55 -04:00
export function applyPostSummonAbAttrs ( attrType : { new ( . . . args : any [ ] ) : PostSummonAbAttr } ,
2023-12-22 21:42:47 -05:00
pokemon : Pokemon , . . . args : any [ ] ) : Promise < void > {
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < PostSummonAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyPostSummon ( pokemon , passive , args ) , args ) ;
2023-05-04 12:57:55 -04:00
}
2024-01-16 00:28:03 -05:00
export function applyPreSwitchOutAbAttrs ( attrType : { new ( . . . args : any [ ] ) : PreSwitchOutAbAttr } ,
pokemon : Pokemon , . . . args : any [ ] ) : Promise < void > {
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < PreSwitchOutAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyPreSwitchOut ( pokemon , passive , args ) , args , false , true ) ;
2024-01-16 00:28:03 -05:00
}
2023-04-27 14:30:03 -04:00
export function applyPreStatChangeAbAttrs ( attrType : { new ( . . . args : any [ ] ) : PreStatChangeAbAttr } ,
2023-12-22 21:42:47 -05:00
pokemon : Pokemon , stat : BattleStat , cancelled : Utils.BooleanHolder , . . . args : any [ ] ) : Promise < void > {
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < PreStatChangeAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyPreStatChange ( pokemon , passive , stat , cancelled , args ) , args ) ;
2023-04-26 23:33:13 -04:00
}
2024-04-14 14:20:00 -04:00
export function applyPostStatChangeAbAttrs ( attrType : { new ( . . . args : any [ ] ) : PostStatChangeAbAttr } ,
pokemon : Pokemon , stats : BattleStat [ ] , levels : integer , selfTarget : boolean , . . . args : any [ ] ) : Promise < void > {
return applyAbAttrsInternal < PostStatChangeAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyPostStatChange ( pokemon , stats , levels , selfTarget , args ) , args ) ;
}
2023-05-04 12:57:55 -04:00
export function applyPreSetStatusAbAttrs ( attrType : { new ( . . . args : any [ ] ) : PreSetStatusAbAttr } ,
2023-12-22 21:42:47 -05:00
pokemon : Pokemon , effect : StatusEffect , cancelled : Utils.BooleanHolder , . . . args : any [ ] ) : Promise < void > {
2024-03-09 21:57:33 -05:00
const simulated = args . length > 1 && args [ 1 ] ;
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < PreSetStatusAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyPreSetStatus ( pokemon , passive , effect , cancelled , args ) , args , false , false , ! simulated ) ;
2023-05-04 12:57:55 -04:00
}
export function applyPreApplyBattlerTagAbAttrs ( attrType : { new ( . . . args : any [ ] ) : PreApplyBattlerTagAbAttr } ,
2023-12-22 21:42:47 -05:00
pokemon : Pokemon , tag : BattlerTag , cancelled : Utils.BooleanHolder , . . . args : any [ ] ) : Promise < void > {
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < PreApplyBattlerTagAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyPreApplyBattlerTag ( pokemon , passive , tag , cancelled , args ) , args ) ;
2023-05-04 12:57:55 -04:00
}
2023-04-27 14:30:03 -04:00
export function applyPreWeatherEffectAbAttrs ( attrType : { new ( . . . args : any [ ] ) : PreWeatherEffectAbAttr } ,
2023-12-22 21:42:47 -05:00
pokemon : Pokemon , weather : Weather , cancelled : Utils.BooleanHolder , . . . args : any [ ] ) : Promise < void > {
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < PreWeatherDamageAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyPreWeatherEffect ( pokemon , passive , weather , cancelled , args ) , args , false , true ) ;
2023-04-27 14:30:03 -04:00
}
2023-05-02 15:56:41 -04:00
export function applyPostTurnAbAttrs ( attrType : { new ( . . . args : any [ ] ) : PostTurnAbAttr } ,
2023-12-22 21:42:47 -05:00
pokemon : Pokemon , . . . args : any [ ] ) : Promise < void > {
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < PostTurnAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyPostTurn ( pokemon , passive , args ) , args ) ;
2023-05-02 15:56:41 -04:00
}
2024-03-18 21:22:27 -04:00
export function applyPostWeatherChangeAbAttrs ( attrType : { new ( . . . args : any [ ] ) : PostWeatherChangeAbAttr } ,
pokemon : Pokemon , weather : WeatherType , . . . args : any [ ] ) : Promise < void > {
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < PostWeatherChangeAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyPostWeatherChange ( pokemon , passive , weather , args ) , args ) ;
2024-03-18 21:22:27 -04:00
}
2023-04-27 14:30:03 -04:00
export function applyPostWeatherLapseAbAttrs ( attrType : { new ( . . . args : any [ ] ) : PostWeatherLapseAbAttr } ,
2023-12-22 21:42:47 -05:00
pokemon : Pokemon , weather : Weather , . . . args : any [ ] ) : Promise < void > {
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < PostWeatherLapseAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyPostWeatherLapse ( pokemon , passive , weather , args ) , args ) ;
2023-04-27 14:30:03 -04:00
}
2024-03-18 21:22:27 -04:00
export function applyPostTerrainChangeAbAttrs ( attrType : { new ( . . . args : any [ ] ) : PostTerrainChangeAbAttr } ,
pokemon : Pokemon , terrain : TerrainType , . . . args : any [ ] ) : Promise < void > {
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < PostTerrainChangeAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyPostTerrainChange ( pokemon , passive , terrain , args ) , args ) ;
2024-03-18 21:22:27 -04:00
}
2023-05-04 12:57:55 -04:00
export function applyCheckTrappedAbAttrs ( attrType : { new ( . . . args : any [ ] ) : CheckTrappedAbAttr } ,
2023-12-22 21:42:47 -05:00
pokemon : Pokemon , trapped : Utils.BooleanHolder , . . . args : any [ ] ) : Promise < void > {
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < CheckTrappedAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyCheckTrapped ( pokemon , passive , trapped , args ) , args , true ) ;
2023-05-04 12:57:55 -04:00
}
2024-03-06 21:05:23 -05:00
export function applyPostBattleAbAttrs ( attrType : { new ( . . . args : any [ ] ) : PostBattleAbAttr } ,
pokemon : Pokemon , . . . args : any [ ] ) : Promise < void > {
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < PostBattleAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyPostBattle ( pokemon , passive , args ) , args ) ;
2024-03-06 21:05:23 -05:00
}
2024-04-09 18:05:15 -04:00
export function applyPostFaintAbAttrs ( attrType : { new ( . . . args : any [ ] ) : PostFaintAbAttr } ,
pokemon : Pokemon , attacker : Pokemon , move : PokemonMove , hitResult : HitResult , . . . args : any [ ] ) : Promise < void > {
2024-04-11 09:24:03 -04:00
return applyAbAttrsInternal < PostFaintAbAttr > ( attrType , pokemon , ( attr , passive ) = > attr . applyPostFaint ( pokemon , passive , attacker , move , hitResult , args ) , args ) ;
2024-04-09 18:05:15 -04:00
}
2023-04-27 14:30:03 -04:00
function canApplyAttr ( pokemon : Pokemon , attr : AbAttr ) : boolean {
const condition = attr . getCondition ( ) ;
return ! condition || condition ( pokemon ) ;
}
2024-04-11 09:24:03 -04:00
function queueShowAbility ( pokemon : Pokemon , passive : boolean ) : void {
pokemon . scene . unshiftPhase ( new ShowAbilityPhase ( pokemon . scene , pokemon . id , passive ) ) ;
2023-04-27 14:30:03 -04:00
pokemon . scene . clearPhaseQueueSplice ( ) ;
2023-04-26 23:33:13 -04:00
}
2024-04-25 03:10:09 +02:00
export const allAbilities = [ new Ability ( Abilities . NONE , 3 ) ] ;
2023-04-27 14:30:03 -04:00
export function initAbilities() {
2023-12-05 17:12:39 -05:00
allAbilities . push (
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . STENCH , 3 )
2024-04-19 09:33:35 -04:00
. attr ( PostAttackApplyBattlerTagAbAttr , false , ( user , target , move ) = > ! move . getMove ( ) . findAttr ( attr = > attr instanceof FlinchAttr ) ? 10 : 0 , BattlerTagType . FLINCHED ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . DRIZZLE , 3 )
2024-04-08 09:31:30 -04:00
. attr ( PostSummonWeatherChangeAbAttr , WeatherType . RAIN )
. attr ( PostBiomeChangeWeatherChangeAbAttr , WeatherType . RAIN ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SPEED_BOOST , 3 )
2023-12-22 01:16:56 -05:00
. attr ( PostTurnStatChangeAbAttr , BattleStat . SPD , 1 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . BATTLE_ARMOR , 3 )
2024-03-14 00:40:57 -04:00
. attr ( BlockCritAbAttr )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . STURDY , 3 )
2024-04-02 01:03:29 -04:00
. attr ( PreDefendFullHpEndureAbAttr )
2024-03-14 00:40:57 -04:00
. attr ( BlockOneHitKOAbAttr )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . DAMP , 3 )
2024-04-25 21:42:41 -04:00
. attr ( FieldPreventExplosiveMovesAbAttr )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . LIMBER , 3 )
2024-03-14 00:40:57 -04:00
. attr ( StatusEffectImmunityAbAttr , StatusEffect . PARALYSIS )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SAND_VEIL , 3 )
2023-12-05 17:12:39 -05:00
. attr ( BattleStatMultiplierAbAttr , BattleStat . EVA , 1.2 )
. attr ( BlockWeatherDamageAttr , WeatherType . SANDSTORM )
2024-03-14 00:40:57 -04:00
. condition ( getWeatherCondition ( WeatherType . SANDSTORM ) )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . STATIC , 3 )
2024-05-05 17:26:28 +03:00
. attr ( PostDefendContactApplyStatusEffectAbAttr , 30 , StatusEffect . PARALYSIS )
. bypassFaint ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . VOLT_ABSORB , 3 )
2024-03-14 00:40:57 -04:00
. attr ( TypeImmunityHealAbAttr , Type . ELECTRIC )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . WATER_ABSORB , 3 )
2024-03-14 00:40:57 -04:00
. attr ( TypeImmunityHealAbAttr , Type . WATER )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . OBLIVIOUS , 3 )
2024-03-14 00:40:57 -04:00
. attr ( BattlerTagImmunityAbAttr , BattlerTagType . INFATUATED )
2024-05-05 07:52:27 -07:00
. attr ( IntimidateImmunityAbAttr )
2024-03-14 00:40:57 -04:00
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . CLOUD_NINE , 3 )
2024-04-19 13:03:19 -04:00
. attr ( SuppressWeatherEffectAbAttr , true ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . COMPOUND_EYES , 3 )
2023-05-02 15:56:41 -04:00
. attr ( BattleStatMultiplierAbAttr , BattleStat . ACC , 1.3 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . INSOMNIA , 3 )
2023-05-04 12:57:55 -04:00
. attr ( StatusEffectImmunityAbAttr , StatusEffect . SLEEP )
2024-03-14 00:40:57 -04:00
. attr ( BattlerTagImmunityAbAttr , BattlerTagType . DROWSY )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . COLOR_CHANGE , 3 )
2023-12-05 17:12:39 -05:00
. attr ( PostDefendTypeChangeAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . IMMUNITY , 3 )
2024-04-08 13:21:06 -04:00
. attr ( StatusEffectImmunityAbAttr , StatusEffect . POISON , StatusEffect . TOXIC )
2024-03-14 00:40:57 -04:00
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . FLASH_FIRE , 3 )
2024-03-14 00:40:57 -04:00
. attr ( TypeImmunityAddBattlerTagAbAttr , Type . FIRE , BattlerTagType . FIRE_BOOST , 1 , ( pokemon : Pokemon ) = > ! pokemon . status || pokemon . status . effect !== StatusEffect . FREEZE )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SHIELD_DUST , 3 )
. ignorable ( )
. unimplemented ( ) ,
new Ability ( Abilities . OWN_TEMPO , 3 )
2024-04-13 11:08:32 +10:00
. attr ( BattlerTagImmunityAbAttr , BattlerTagType . CONFUSED )
2024-05-05 07:52:27 -07:00
. attr ( IntimidateImmunityAbAttr )
2024-04-13 11:08:32 +10:00
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SUCTION_CUPS , 3 )
2024-05-05 07:52:27 -07:00
. attr ( ForceSwitchOutImmunityAbAttr )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . INTIMIDATE , 3 )
2024-05-05 07:52:27 -07:00
. attr ( PostSummonStatChangeAbAttr , BattleStat . ATK , - 1 , false , true ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SHADOW_TAG , 3 )
2023-12-05 17:12:39 -05:00
. attr ( ArenaTrapAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . ROUGH_SKIN , 3 )
2024-04-06 21:04:40 -04:00
. attr ( PostDefendContactDamageAbAttr , 8 )
2024-04-11 09:24:03 -04:00
. bypassFaint ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . WONDER_GUARD , 3 )
2024-03-04 21:32:11 -05:00
. attr ( NonSuperEffectiveImmunityAbAttr )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
2024-03-14 00:40:57 -04:00
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . LEVITATE , 3 )
2024-04-16 14:31:30 -04:00
. attr ( TypeImmunityAbAttr , Type . GROUND , ( pokemon : Pokemon ) = > ! pokemon . getTag ( BattlerTagType . IGNORE_FLYING ) && ! pokemon . scene . arena . getTag ( ArenaTagType . GRAVITY ) && ! pokemon . getTag ( BattlerTagType . GROUNDED ) )
2024-03-14 00:40:57 -04:00
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . EFFECT_SPORE , 3 )
2024-05-01 17:47:32 -04:00
. attr ( EffectSporeAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SYNCHRONIZE , 3 )
. attr ( SyncEncounterNatureAbAttr )
. unimplemented ( ) ,
new Ability ( Abilities . CLEAR_BODY , 3 )
2024-03-14 00:40:57 -04:00
. attr ( ProtectStatAbAttr )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . NATURAL_CURE , 3 )
2024-01-16 00:28:03 -05:00
. attr ( PreSwitchOutResetStatusAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . LIGHTNING_ROD , 3 )
2024-03-11 20:55:41 -04:00
. attr ( RedirectTypeMoveAbAttr , Type . ELECTRIC )
2024-03-14 00:40:57 -04:00
. attr ( TypeImmunityStatChangeAbAttr , Type . ELECTRIC , BattleStat . SPATK , 1 )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SERENE_GRACE , 3 )
. unimplemented ( ) ,
new Ability ( Abilities . SWIFT_SWIM , 3 )
2023-12-05 17:12:39 -05:00
. attr ( BattleStatMultiplierAbAttr , BattleStat . SPD , 2 )
. condition ( getWeatherCondition ( WeatherType . RAIN , WeatherType . HEAVY_RAIN ) ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . CHLOROPHYLL , 3 )
2023-12-05 17:12:39 -05:00
. attr ( BattleStatMultiplierAbAttr , BattleStat . SPD , 2 )
. condition ( getWeatherCondition ( WeatherType . SUNNY , WeatherType . HARSH_SUN ) ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . ILLUMINATE , 3 )
2024-03-14 00:40:57 -04:00
. attr ( ProtectStatAbAttr , BattleStat . ACC )
. attr ( DoubleBattleChanceAbAttr )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . TRACE , 3 )
2024-04-14 13:21:34 +10:00
. attr ( TraceAbAttr )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . HUGE_POWER , 3 )
2024-03-14 14:09:25 -05:00
. attr ( BattleStatMultiplierAbAttr , BattleStat . ATK , 2 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . POISON_POINT , 3 )
2024-05-05 17:26:28 +03:00
. attr ( PostDefendContactApplyStatusEffectAbAttr , 30 , StatusEffect . POISON )
. bypassFaint ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . INNER_FOCUS , 3 )
2024-03-14 00:40:57 -04:00
. attr ( BattlerTagImmunityAbAttr , BattlerTagType . FLINCHED )
2024-05-05 07:52:27 -07:00
. attr ( IntimidateImmunityAbAttr )
2024-03-14 00:40:57 -04:00
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . MAGMA_ARMOR , 3 )
2024-03-14 00:40:57 -04:00
. attr ( StatusEffectImmunityAbAttr , StatusEffect . FREEZE )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . WATER_VEIL , 3 )
2024-03-14 00:40:57 -04:00
. attr ( StatusEffectImmunityAbAttr , StatusEffect . BURN )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . MAGNET_PULL , 3 )
2023-12-05 17:12:39 -05:00
/ * . a t t r ( A r e n a T r a p A b A t t r )
2024-04-25 03:10:09 +02:00
. condition ( ( pokemon : Pokemon ) = > pokemon . getOpponent ( ) ? . isOfType ( Type . STEEL ) ) * /
. unimplemented ( ) ,
new Ability ( Abilities . SOUNDPROOF , 3 )
2024-03-14 00:40:57 -04:00
. attr ( MoveImmunityAbAttr , ( pokemon , attacker , move ) = > pokemon !== attacker && move . getMove ( ) . hasFlag ( MoveFlags . SOUND_BASED ) )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . RAIN_DISH , 3 )
2023-05-02 15:56:41 -04:00
. attr ( PostWeatherLapseHealAbAttr , 1 , WeatherType . RAIN , WeatherType . HEAVY_RAIN ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SAND_STREAM , 3 )
2024-04-08 09:31:30 -04:00
. attr ( PostSummonWeatherChangeAbAttr , WeatherType . SANDSTORM )
. attr ( PostBiomeChangeWeatherChangeAbAttr , WeatherType . SANDSTORM ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . PRESSURE , 3 )
2024-04-20 23:09:59 -04:00
. attr ( IncreasePpAbAttr )
2023-12-15 23:07:32 -05:00
. attr ( PostSummonMessageAbAttr , ( pokemon : Pokemon ) = > getPokemonMessage ( pokemon , ' is exerting its Pressure!' ) ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . THICK_FAT , 3 )
2023-05-06 12:13:35 -04:00
. attr ( ReceivedTypeDamageMultiplierAbAttr , Type . FIRE , 0.5 )
2024-03-14 00:40:57 -04:00
. attr ( ReceivedTypeDamageMultiplierAbAttr , Type . ICE , 0.5 )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . EARLY_BIRD , 3 )
2024-01-16 00:28:03 -05:00
. attr ( ReduceStatusEffectDurationAbAttr , StatusEffect . SLEEP ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . FLAME_BODY , 3 )
2024-05-05 17:26:28 +03:00
. attr ( PostDefendContactApplyStatusEffectAbAttr , 30 , StatusEffect . BURN )
. bypassFaint ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . RUN_AWAY , 3 )
2023-12-22 18:08:37 -04:00
. attr ( RunSuccessAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . KEEN_EYE , 3 )
2024-03-14 00:40:57 -04:00
. attr ( ProtectStatAbAttr , BattleStat . ACC )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . HYPER_CUTTER , 3 )
2024-03-14 00:40:57 -04:00
. attr ( ProtectStatAbAttr , BattleStat . ATK )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . PICKUP , 3 )
2024-03-06 21:05:23 -05:00
. attr ( PostBattleLootAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . TRUANT , 3 )
2023-12-22 22:46:05 -05:00
. attr ( PostSummonAddBattlerTagAbAttr , BattlerTagType . TRUANT , 1 , false ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . HUSTLE , 3 )
2024-04-30 09:47:10 -06:00
. attr ( BattleStatMultiplierAbAttr , BattleStat . ATK , 1.5 , ( user , target , move ) = > move . category == MoveCategory . PHYSICAL )
. attr ( BattleStatMultiplierAbAttr , BattleStat . ACC , 0.8 , ( user , target , move ) = > move . category == MoveCategory . PHYSICAL ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . CUTE_CHARM , 3 )
2023-12-05 17:12:39 -05:00
. attr ( PostDefendContactApplyTagChanceAbAttr , 30 , BattlerTagType . INFATUATED ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . PLUS , 3 )
. unimplemented ( ) ,
new Ability ( Abilities . MINUS , 3 )
. unimplemented ( ) ,
new Ability ( Abilities . FORECAST , 3 )
2024-04-19 04:27:34 +10:00
. attr ( UncopiableAbilityAbAttr )
2024-04-25 03:10:09 +02:00
. attr ( NoFusionAbilityAbAttr )
. unimplemented ( ) ,
new Ability ( Abilities . STICKY_HOLD , 3 )
2023-12-22 23:57:05 -05:00
. attr ( BlockItemTheftAbAttr )
2024-04-11 09:24:03 -04:00
. bypassFaint ( )
2024-03-14 00:40:57 -04:00
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SHED_SKIN , 3 )
2024-04-12 19:02:24 -05:00
. conditionalAttr ( pokemon = > ! Utils . randSeedInt ( 3 ) , PostTurnResetStatusAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . GUTS , 3 )
2024-03-14 00:40:57 -04:00
. attr ( BypassBurnDamageReductionAbAttr )
. conditionalAttr ( pokemon = > ! ! pokemon . status , BattleStatMultiplierAbAttr , BattleStat . ATK , 1.5 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . MARVEL_SCALE , 3 )
2024-03-14 00:40:57 -04:00
. conditionalAttr ( pokemon = > ! ! pokemon . status , BattleStatMultiplierAbAttr , BattleStat . DEF , 1.5 )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . LIQUID_OOZE , 3 )
2024-04-22 04:02:10 +01:00
. attr ( ReverseDrainAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . OVERGROW , 3 )
2023-12-05 17:12:39 -05:00
. attr ( LowHpMoveTypePowerBoostAbAttr , Type . GRASS ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . BLAZE , 3 )
2023-12-05 17:12:39 -05:00
. attr ( LowHpMoveTypePowerBoostAbAttr , Type . FIRE ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . TORRENT , 3 )
2023-12-05 17:12:39 -05:00
. attr ( LowHpMoveTypePowerBoostAbAttr , Type . WATER ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SWARM , 3 )
2023-12-05 17:12:39 -05:00
. attr ( LowHpMoveTypePowerBoostAbAttr , Type . BUG ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . ROCK_HEAD , 3 )
2023-12-05 17:12:39 -05:00
. attr ( BlockRecoilDamageAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . DROUGHT , 3 )
2024-04-08 09:31:30 -04:00
. attr ( PostSummonWeatherChangeAbAttr , WeatherType . SUNNY )
. attr ( PostBiomeChangeWeatherChangeAbAttr , WeatherType . SUNNY ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . ARENA_TRAP , 3 )
2024-04-26 12:58:57 -05:00
. attr ( ArenaTrapAbAttr )
. attr ( DoubleBattleChanceAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . VITAL_SPIRIT , 3 )
2023-05-04 12:57:55 -04:00
. attr ( StatusEffectImmunityAbAttr , StatusEffect . SLEEP )
2024-03-14 00:40:57 -04:00
. attr ( BattlerTagImmunityAbAttr , BattlerTagType . DROWSY )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . WHITE_SMOKE , 3 )
2024-03-14 00:40:57 -04:00
. attr ( ProtectStatAbAttr )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . PURE_POWER , 3 )
2024-03-14 14:09:25 -05:00
. attr ( BattleStatMultiplierAbAttr , BattleStat . ATK , 2 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SHELL_ARMOR , 3 )
2024-03-14 00:40:57 -04:00
. attr ( BlockCritAbAttr )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . AIR_LOCK , 3 )
2023-12-05 17:12:39 -05:00
. attr ( SuppressWeatherEffectAbAttr , true ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . TANGLED_FEET , 4 )
2024-03-14 00:40:57 -04:00
. conditionalAttr ( pokemon = > ! ! pokemon . getTag ( BattlerTagType . CONFUSED ) , BattleStatMultiplierAbAttr , BattleStat . EVA , 2 )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . MOTOR_DRIVE , 4 )
2024-03-14 00:40:57 -04:00
. attr ( TypeImmunityStatChangeAbAttr , Type . ELECTRIC , BattleStat . SPD , 1 )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . RIVALRY , 4 )
2024-05-01 18:17:12 -04:00
. attr ( MovePowerBoostAbAttr , ( user , target , move ) = > user . gender !== Gender . GENDERLESS && target . gender !== Gender . GENDERLESS && user . gender === target . gender , 1.25 , true )
2024-04-14 13:15:01 -04:00
. attr ( MovePowerBoostAbAttr , ( user , target , move ) = > user . gender !== Gender . GENDERLESS && target . gender !== Gender . GENDERLESS && user . gender !== target . gender , 0.75 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . STEADFAST , 4 )
2024-01-16 00:28:03 -05:00
. attr ( FlinchStatChangeAbAttr , BattleStat . SPD , 1 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SNOW_CLOAK , 4 )
2023-12-05 17:12:39 -05:00
. attr ( BattleStatMultiplierAbAttr , BattleStat . EVA , 1.2 )
2024-03-14 00:40:57 -04:00
. attr ( BlockWeatherDamageAttr , WeatherType . HAIL )
2024-04-15 22:47:39 +02:00
. condition ( getWeatherCondition ( WeatherType . HAIL , WeatherType . SNOW ) )
2024-03-14 00:40:57 -04:00
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . GLUTTONY , 4 )
2024-01-16 00:28:03 -05:00
. attr ( ReduceBerryUseThresholdAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . ANGER_POINT , 4 )
2023-10-26 21:12:53 -07:00
. attr ( PostDefendCritStatChangeAbAttr , BattleStat . ATK , 6 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . UNBURDEN , 4 )
. unimplemented ( ) ,
new Ability ( Abilities . HEATPROOF , 4 )
2024-03-14 00:40:57 -04:00
. attr ( ReceivedTypeDamageMultiplierAbAttr , Type . FIRE , 0.5 )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SIMPLE , 4 )
2024-03-14 00:40:57 -04:00
. attr ( StatChangeMultiplierAbAttr , 2 )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . DRY_SKIN , 4 )
2023-05-02 15:56:41 -04:00
. attr ( PostWeatherLapseDamageAbAttr , 2 , WeatherType . SUNNY , WeatherType . HARSH_SUN )
. attr ( PostWeatherLapseHealAbAttr , 2 , WeatherType . RAIN , WeatherType . HEAVY_RAIN )
2023-05-06 12:13:35 -04:00
. attr ( ReceivedTypeDamageMultiplierAbAttr , Type . FIRE , 1.25 )
2024-03-14 00:40:57 -04:00
. attr ( TypeImmunityHealAbAttr , Type . WATER )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . DOWNLOAD , 4 )
2024-04-12 16:08:04 -04:00
. attr ( DownloadAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . IRON_FIST , 4 )
2023-12-23 01:21:01 -05:00
. attr ( MovePowerBoostAbAttr , ( user , target , move ) = > move . hasFlag ( MoveFlags . PUNCHING_MOVE ) , 1.2 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . POISON_HEAL , 4 )
. unimplemented ( ) ,
new Ability ( Abilities . ADAPTABILITY , 4 )
2023-12-05 17:12:39 -05:00
. attr ( StabBoostAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SKILL_LINK , 4 )
2023-12-22 18:08:37 -04:00
. attr ( MaxMultiHitAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . HYDRATION , 4 )
2024-04-11 05:16:09 +01:00
. attr ( PostTurnResetStatusAbAttr )
. condition ( getWeatherCondition ( WeatherType . RAIN , WeatherType . HEAVY_RAIN ) ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SOLAR_POWER , 4 )
2023-11-28 22:20:10 +09:00
. attr ( PostWeatherLapseDamageAbAttr , 2 , WeatherType . SUNNY , WeatherType . HARSH_SUN )
. attr ( BattleStatMultiplierAbAttr , BattleStat . SPATK , 1.5 )
. condition ( getWeatherCondition ( WeatherType . SUNNY , WeatherType . HARSH_SUN ) ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . QUICK_FEET , 4 )
2024-04-17 22:09:28 -06:00
. conditionalAttr ( pokemon = > pokemon . status ? pokemon . status . effect === StatusEffect.PARALYSIS : false , BattleStatMultiplierAbAttr , BattleStat . SPD , 2 )
2024-04-14 13:15:01 -04:00
. conditionalAttr ( pokemon = > ! ! pokemon . status , BattleStatMultiplierAbAttr , BattleStat . SPD , 1.5 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . NORMALIZE , 4 )
2024-04-14 13:15:01 -04:00
. attr ( MoveTypeChangeAttr , Type . NORMAL , 1.2 , ( user , target , move ) = > move . id !== Moves . HIDDEN_POWER && move . id !== Moves . WEATHER_BALL &&
move . id !== Moves . NATURAL_GIFT && move . id !== Moves . JUDGMENT && move . id !== Moves . TECHNO_BLAST ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SNIPER , 4 )
2024-05-04 01:56:13 +10:00
. attr ( MultCritAbAttr , 1.5 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . MAGIC_GUARD , 4 )
2024-04-02 15:14:07 -04:00
. attr ( BlockNonDirectDamageAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . NO_GUARD , 4 )
2024-04-21 15:26:30 +10:00
. attr ( AlwaysHitAbAttr )
. attr ( DoubleBattleChanceAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . STALL , 4 )
. unimplemented ( ) ,
new Ability ( Abilities . TECHNICIAN , 4 )
2023-12-23 01:21:01 -05:00
. attr ( MovePowerBoostAbAttr , ( user , target , move ) = > move . power <= 60 , 1.5 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . LEAF_GUARD , 4 )
2023-12-05 17:12:39 -05:00
. attr ( StatusEffectImmunityAbAttr )
2024-03-14 00:40:57 -04:00
. condition ( getWeatherCondition ( WeatherType . SUNNY , WeatherType . HARSH_SUN ) )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . KLUTZ , 4 )
. unimplemented ( ) ,
new Ability ( Abilities . MOLD_BREAKER , 4 )
2024-03-14 00:40:57 -04:00
. attr ( PostSummonMessageAbAttr , ( pokemon : Pokemon ) = > getPokemonMessage ( pokemon , ' breaks the mold!' ) )
. attr ( MoveAbilityBypassAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SUPER_LUCK , 4 )
. attr ( BonusCritAbAttr )
. partial ( ) ,
new Ability ( Abilities . AFTERMATH , 4 )
2024-04-09 18:05:15 -04:00
. attr ( PostFaintContactDamageAbAttr , 4 )
2024-04-11 09:24:03 -04:00
. bypassFaint ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . ANTICIPATION , 4 )
2024-04-21 23:01:11 -04:00
. conditionalAttr ( getAnticipationCondition ( ) , PostSummonMessageAbAttr , ( pokemon : Pokemon ) = > getPokemonMessage ( pokemon , ' shuddered!' ) ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . FOREWARN , 4 )
2024-05-03 22:10:40 -04:00
. attr ( ForewarnAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . UNAWARE , 4 )
2024-03-14 00:40:57 -04:00
. attr ( IgnoreOpponentStatChangesAbAttr )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . TINTED_LENS , 4 )
2024-05-06 00:27:56 -05:00
. attr ( MovePowerBoostAbAttr , ( user , target , move ) = > target . getAttackTypeEffectiveness ( move . type , user ) <= 0.5 , 2 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . FILTER , 4 )
2024-05-06 00:27:56 -05:00
. attr ( ReceivedMoveDamageMultiplierAbAttr , ( target , user , move ) = > target . getAttackTypeEffectiveness ( move . type , user ) >= 2 , 0.75 )
2024-03-14 00:40:57 -04:00
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SLOW_START , 4 )
2023-12-22 22:46:05 -05:00
. attr ( PostSummonAddBattlerTagAbAttr , BattlerTagType . SLOW_START , 5 ) ,
2024-05-06 00:27:56 -05:00
new Ability ( Abilities . SCRAPPY , 4 )
. attr ( IgnoreTypeImmunityAbAttr , Type . GHOST , [ Type . NORMAL , Type . FIGHTING ] )
. attr ( IntimidateImmunityAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . STORM_DRAIN , 4 )
2024-03-11 20:55:41 -04:00
. attr ( RedirectTypeMoveAbAttr , Type . WATER )
2024-03-14 00:40:57 -04:00
. attr ( TypeImmunityStatChangeAbAttr , Type . WATER , BattleStat . SPATK , 1 )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . ICE_BODY , 4 )
2024-04-15 22:47:39 +02:00
. attr ( BlockWeatherDamageAttr , WeatherType . HAIL )
. attr ( PostWeatherLapseHealAbAttr , 1 , WeatherType . HAIL , WeatherType . SNOW ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SOLID_ROCK , 4 )
2024-05-06 00:27:56 -05:00
. attr ( ReceivedMoveDamageMultiplierAbAttr , ( target , user , move ) = > target . getAttackTypeEffectiveness ( move . type , user ) >= 2 , 0.75 )
2024-03-14 00:40:57 -04:00
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SNOW_WARNING , 4 )
2024-04-15 22:47:39 +02:00
. attr ( PostSummonWeatherChangeAbAttr , WeatherType . SNOW )
. attr ( PostBiomeChangeWeatherChangeAbAttr , WeatherType . SNOW ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . HONEY_GATHER , 4 )
. unimplemented ( ) ,
new Ability ( Abilities . FRISK , 4 )
2024-05-03 22:10:40 -04:00
. attr ( FriskAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . RECKLESS , 4 )
2024-05-07 23:28:35 -05:00
. attr ( MovePowerBoostAbAttr , ( user , target , move ) = > move . hasFlag ( MoveFlags . RECKLESS_MOVE ) , 1.2 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . MULTITYPE , 4 )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
2024-04-19 04:27:34 +10:00
. attr ( UnsuppressableAbilityAbAttr )
2024-04-25 03:10:09 +02:00
. attr ( NoFusionAbilityAbAttr )
. unimplemented ( ) ,
new Ability ( Abilities . FLOWER_GIFT , 4 )
2024-03-30 18:55:37 -05:00
. conditionalAttr ( getWeatherCondition ( WeatherType . SUNNY || WeatherType . HARSH_SUN ) , BattleStatMultiplierAbAttr , BattleStat . ATK , 1.5 )
. conditionalAttr ( getWeatherCondition ( WeatherType . SUNNY || WeatherType . HARSH_SUN ) , BattleStatMultiplierAbAttr , BattleStat . SPDEF , 1.5 )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
2024-04-19 04:27:34 +10:00
. attr ( NoFusionAbilityAbAttr )
2024-04-25 03:10:09 +02:00
. ignorable ( )
. partial ( ) ,
new Ability ( Abilities . BAD_DREAMS , 4 )
. unimplemented ( ) ,
new Ability ( Abilities . PICKPOCKET , 5 )
2023-12-23 01:21:01 -05:00
. attr ( PostDefendStealHeldItemAbAttr , ( target , user , move ) = > move . hasFlag ( MoveFlags . MAKES_CONTACT ) ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SHEER_FORCE , 5 )
. unimplemented ( ) ,
new Ability ( Abilities . CONTRARY , 5 )
2024-03-14 00:40:57 -04:00
. attr ( StatChangeMultiplierAbAttr , - 1 )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . UNNERVE , 5 )
2023-12-23 01:21:01 -05:00
. attr ( PreventBerryUseAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . DEFIANT , 5 )
2024-04-14 14:20:00 -04:00
. attr ( PostStatChangeStatChangeAbAttr , ( target , statsChanged , levels ) = > levels < 0 , [ BattleStat . ATK ] , 2 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . DEFEATIST , 5 )
2024-03-13 13:54:15 +01:00
. attr ( BattleStatMultiplierAbAttr , BattleStat . ATK , 0.5 )
. attr ( BattleStatMultiplierAbAttr , BattleStat . SPATK , 0.5 )
. condition ( ( pokemon ) = > pokemon . getHpRatio ( ) <= 0.5 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . CURSED_BODY , 5 )
. unimplemented ( ) ,
new Ability ( Abilities . HEALER , 5 )
. unimplemented ( ) ,
new Ability ( Abilities . FRIEND_GUARD , 5 )
. ignorable ( )
. unimplemented ( ) ,
new Ability ( Abilities . WEAK_ARMOR , 5 )
2024-04-05 00:24:43 +02:00
. attr ( PostDefendStatChangeAbAttr , ( target , user , move ) = > move . category === MoveCategory . PHYSICAL , BattleStat . DEF , - 1 )
. attr ( PostDefendStatChangeAbAttr , ( target , user , move ) = > move . category === MoveCategory . PHYSICAL , BattleStat . SPD , 2 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . HEAVY_METAL , 5 )
2024-03-14 00:40:57 -04:00
. attr ( WeightMultiplierAbAttr , 2 )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . LIGHT_METAL , 5 )
2024-03-14 00:40:57 -04:00
. attr ( WeightMultiplierAbAttr , 0.5 )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . MULTISCALE , 5 )
Implement Multiscale, Solid Rock, Filter, Justified, Water Compaction, Soul-Heart, Shadow Shield, Prism Armor (#46)
* Implement Multiscale, Solid Rock, Filter, Justified, Water Compaction, Soul-Heart, Shadow Shield, Prism Armor
fix
fix
* Update src/data/ability.ts
---------
Co-authored-by: Samuel H <flashfireex@gmail.com>
2024-04-06 22:39:55 +03:00
. attr ( ReceivedMoveDamageMultiplierAbAttr , ( target , user , move ) = > target . getHpRatio ( ) === 1 , 0.5 )
2024-03-14 00:40:57 -04:00
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . TOXIC_BOOST , 5 )
2023-12-23 01:21:01 -05:00
. attr ( MovePowerBoostAbAttr , ( user , target , move ) = > move . category === MoveCategory . PHYSICAL && ( user . status ? . effect === StatusEffect . POISON || user . status ? . effect === StatusEffect . TOXIC ) , 1.5 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . FLARE_BOOST , 5 )
2023-12-23 01:21:01 -05:00
. attr ( MovePowerBoostAbAttr , ( user , target , move ) = > move . category === MoveCategory . SPECIAL && user . status ? . effect === StatusEffect . BURN , 1.5 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . HARVEST , 5 )
. unimplemented ( ) ,
new Ability ( Abilities . TELEPATHY , 5 )
. ignorable ( )
. unimplemented ( ) ,
new Ability ( Abilities . MOODY , 5 )
2024-04-25 01:23:45 -04:00
. attr ( MoodyAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . OVERCOAT , 5 )
2023-12-23 01:21:01 -05:00
. attr ( BlockWeatherDamageAttr )
2024-03-14 00:40:57 -04:00
. attr ( MoveImmunityAbAttr , ( pokemon , attacker , move ) = > pokemon !== attacker && move . getMove ( ) . hasFlag ( MoveFlags . POWDER_MOVE ) )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . POISON_TOUCH , 5 )
2024-03-27 23:02:49 -05:00
. attr ( PostAttackContactApplyStatusEffectAbAttr , 30 , StatusEffect . POISON ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . REGENERATOR , 5 )
2024-04-05 17:32:36 +03:00
. attr ( PreSwitchOutHealAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . BIG_PECKS , 5 )
2024-03-14 00:40:57 -04:00
. attr ( ProtectStatAbAttr , BattleStat . DEF )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SAND_RUSH , 5 )
2023-11-28 12:34:19 +09:00
. attr ( BattleStatMultiplierAbAttr , BattleStat . SPD , 2 )
. attr ( BlockWeatherDamageAttr , WeatherType . SANDSTORM )
. condition ( getWeatherCondition ( WeatherType . SANDSTORM ) ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . WONDER_SKIN , 5 )
. ignorable ( )
. unimplemented ( ) ,
new Ability ( Abilities . ANALYTIC , 5 )
2024-04-25 14:29:05 -04:00
. attr ( MovePowerBoostAbAttr , ( user , target , move ) = > ! ! target . getLastXMoves ( 1 ) . find ( m = > m . turn === target . scene . currentBattle . turn ) || user . scene . currentBattle . turnCommands [ target . getBattlerIndex ( ) ] . command !== Command . FIGHT , 1.3 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . ILLUSION , 5 )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
2024-04-25 03:10:09 +02:00
. attr ( UnswappableAbilityAbAttr )
. unimplemented ( ) ,
new Ability ( Abilities . IMPOSTER , 5 )
2024-04-13 11:08:32 +10:00
. attr ( PostSummonTransformAbAttr )
. attr ( UncopiableAbilityAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . INFILTRATOR , 5 )
. unimplemented ( ) ,
new Ability ( Abilities . MUMMY , 5 )
2024-05-03 22:30:23 -04:00
. attr ( PostDefendAbilityGiveAbAttr , Abilities . MUMMY )
2024-04-14 13:21:34 +10:00
. bypassFaint ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . MOXIE , 5 )
2024-03-29 22:08:27 -04:00
. attr ( PostVictoryStatChangeAbAttr , BattleStat . ATK , 1 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . JUSTIFIED , 5 )
Implement Multiscale, Solid Rock, Filter, Justified, Water Compaction, Soul-Heart, Shadow Shield, Prism Armor (#46)
* Implement Multiscale, Solid Rock, Filter, Justified, Water Compaction, Soul-Heart, Shadow Shield, Prism Armor
fix
fix
* Update src/data/ability.ts
---------
Co-authored-by: Samuel H <flashfireex@gmail.com>
2024-04-06 22:39:55 +03:00
. attr ( PostDefendStatChangeAbAttr , ( target , user , move ) = > move . type === Type . DARK && move . category !== MoveCategory . STATUS , BattleStat . ATK , 1 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . RATTLED , 5 )
2024-04-17 01:09:15 -04:00
. attr ( PostDefendStatChangeAbAttr , ( target , user , move ) = > move . category !== MoveCategory . STATUS && ( move . type === Type . DARK || move . type === Type . BUG ||
2024-04-25 03:10:09 +02:00
move . type === Type . GHOST ) , BattleStat . SPD , 1 )
2024-05-05 07:52:27 -07:00
. attr ( PostIntimidateStatChangeAbAttr , [ BattleStat . SPD ] , 1 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . MAGIC_BOUNCE , 5 )
. ignorable ( )
. unimplemented ( ) ,
new Ability ( Abilities . SAP_SIPPER , 5 )
2024-03-14 00:40:57 -04:00
. attr ( TypeImmunityStatChangeAbAttr , Type . GRASS , BattleStat . ATK , 1 )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . PRANKSTER , 5 )
2024-04-08 17:10:07 +03:00
. attr ( IncrementMovePriorityAbAttr , ( pokemon , move : Move ) = > move . category === MoveCategory . STATUS ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SAND_FORCE , 5 )
2023-12-23 01:21:01 -05:00
. attr ( MoveTypePowerBoostAbAttr , Type . ROCK , 1.3 )
. attr ( MoveTypePowerBoostAbAttr , Type . GROUND , 1.3 )
. attr ( MoveTypePowerBoostAbAttr , Type . STEEL , 1.3 )
. attr ( BlockWeatherDamageAttr , WeatherType . SANDSTORM )
. condition ( getWeatherCondition ( WeatherType . SANDSTORM ) ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . IRON_BARBS , 5 )
2024-04-09 18:05:15 -04:00
. attr ( PostDefendContactDamageAbAttr , 8 )
2024-04-11 09:24:03 -04:00
. bypassFaint ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . ZEN_MODE , 5 )
2024-04-14 20:30:54 -05:00
. attr ( PostBattleInitFormChangeAbAttr , p = > p . getHpRatio ( ) <= 0.5 ? 1 : 0 )
. attr ( PostSummonFormChangeAbAttr , p = > p . getHpRatio ( ) <= 0.5 ? 1 : 0 )
. attr ( PostTurnFormChangeAbAttr , p = > p . getHpRatio ( ) <= 0.5 ? 1 : 0 )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
2024-04-19 04:27:34 +10:00
. attr ( UnsuppressableAbilityAbAttr )
. attr ( NoFusionAbilityAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . VICTORY_STAR , 5 )
. attr ( BattleStatMultiplierAbAttr , BattleStat . ACC , 1.1 )
. partial ( ) ,
new Ability ( Abilities . TURBOBLAZE , 5 )
2024-03-13 23:56:18 -05:00
. attr ( PostSummonMessageAbAttr , ( pokemon : Pokemon ) = > getPokemonMessage ( pokemon , ' is radiating a blazing aura!' ) )
2024-03-14 00:40:57 -04:00
. attr ( MoveAbilityBypassAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . TERAVOLT , 5 )
2024-03-13 23:56:18 -05:00
. attr ( PostSummonMessageAbAttr , ( pokemon : Pokemon ) = > getPokemonMessage ( pokemon , ' is radiating a bursting aura!' ) )
2024-03-14 00:40:57 -04:00
. attr ( MoveAbilityBypassAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . AROMA_VEIL , 6 )
. ignorable ( )
. unimplemented ( ) ,
new Ability ( Abilities . FLOWER_VEIL , 6 )
. ignorable ( )
. unimplemented ( ) ,
new Ability ( Abilities . CHEEK_POUCH , 6 )
. unimplemented ( ) ,
new Ability ( Abilities . PROTEAN , 6 )
. unimplemented ( ) ,
new Ability ( Abilities . FUR_COAT , 6 )
2024-03-14 00:40:57 -04:00
. attr ( ReceivedMoveDamageMultiplierAbAttr , ( target , user , move ) = > move . category === MoveCategory . PHYSICAL , 0.5 )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . MAGICIAN , 6 )
2023-12-22 01:16:56 -05:00
. attr ( PostAttackStealHeldItemAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . BULLETPROOF , 6 )
2024-03-14 00:40:57 -04:00
. attr ( MoveImmunityAbAttr , ( pokemon , attacker , move ) = > pokemon !== attacker && move . getMove ( ) . hasFlag ( MoveFlags . BALLBOMB_MOVE ) )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . COMPETITIVE , 6 )
2024-04-14 21:50:26 +01:00
. attr ( PostStatChangeStatChangeAbAttr , ( target , statsChanged , levels ) = > levels < 0 , [ BattleStat . SPATK ] , 2 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . STRONG_JAW , 6 )
2024-02-22 23:24:44 -06:00
. attr ( MovePowerBoostAbAttr , ( user , target , move ) = > move . hasFlag ( MoveFlags . BITING_MOVE ) , 1.5 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . REFRIGERATE , 6 )
2024-04-07 22:27:07 -07:00
. attr ( MoveTypeChangePowerMultiplierAbAttr , Type . NORMAL , Type . ICE , 1.2 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SWEET_VEIL , 6 )
2024-04-17 01:09:15 -04:00
. attr ( StatusEffectImmunityAbAttr , StatusEffect . SLEEP )
. attr ( BattlerTagImmunityAbAttr , BattlerTagType . DROWSY )
2024-04-25 03:10:09 +02:00
. ignorable ( )
. partial ( ) ,
new Ability ( Abilities . STANCE_CHANGE , 6 )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
2024-04-19 04:27:34 +10:00
. attr ( UnsuppressableAbilityAbAttr )
. attr ( NoFusionAbilityAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . GALE_WINGS , 6 )
2024-04-08 17:10:07 +03:00
. attr ( IncrementMovePriorityAbAttr , ( pokemon , move ) = > pokemon . getHpRatio ( ) === 1 && move . type === Type . FLYING ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . MEGA_LAUNCHER , 6 )
2023-12-23 01:21:01 -05:00
. attr ( MovePowerBoostAbAttr , ( user , target , move ) = > move . hasFlag ( MoveFlags . PULSE_MOVE ) , 1.5 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . GRASS_PELT , 6 )
2024-04-13 11:08:32 +10:00
. conditionalAttr ( getTerrainCondition ( TerrainType . GRASSY ) , BattleStatMultiplierAbAttr , BattleStat . DEF , 1.5 )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SYMBIOSIS , 6 )
. unimplemented ( ) ,
new Ability ( Abilities . TOUGH_CLAWS , 6 )
2023-12-23 01:21:01 -05:00
. attr ( MovePowerBoostAbAttr , ( user , target , move ) = > move . hasFlag ( MoveFlags . MAKES_CONTACT ) , 1.3 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . PIXILATE , 6 )
2024-04-07 22:27:07 -07:00
. attr ( MoveTypeChangePowerMultiplierAbAttr , Type . NORMAL , Type . FAIRY , 1.2 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . GOOEY , 6 )
2024-04-06 22:18:12 -05:00
. attr ( PostDefendStatChangeAbAttr , ( target , user , move ) = > move . hasFlag ( MoveFlags . MAKES_CONTACT ) , BattleStat . SPD , - 1 , false ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . AERILATE , 6 )
2024-04-07 22:27:07 -07:00
. attr ( MoveTypeChangePowerMultiplierAbAttr , Type . NORMAL , Type . FLYING , 1.2 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . PARENTAL_BOND , 6 )
. unimplemented ( ) ,
new Ability ( Abilities . DARK_AURA , 6 )
2024-03-14 00:40:57 -04:00
. attr ( PostSummonMessageAbAttr , ( pokemon : Pokemon ) = > getPokemonMessage ( pokemon , ' is radiating a Dark Aura!' ) )
. attr ( FieldMoveTypePowerBoostAbAttr , Type . DARK , 4 / 3 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . FAIRY_AURA , 6 )
2024-03-14 00:40:57 -04:00
. attr ( PostSummonMessageAbAttr , ( pokemon : Pokemon ) = > getPokemonMessage ( pokemon , ' is radiating a Fairy Aura!' ) )
. attr ( FieldMoveTypePowerBoostAbAttr , Type . FAIRY , 4 / 3 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . AURA_BREAK , 6 )
. ignorable ( )
. unimplemented ( ) ,
new Ability ( Abilities . PRIMORDIAL_SEA , 6 )
2024-04-08 09:31:30 -04:00
. attr ( PostSummonWeatherChangeAbAttr , WeatherType . HEAVY_RAIN )
. attr ( PostBiomeChangeWeatherChangeAbAttr , WeatherType . HEAVY_RAIN ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . DESOLATE_LAND , 6 )
2024-04-08 09:31:30 -04:00
. attr ( PostSummonWeatherChangeAbAttr , WeatherType . HARSH_SUN )
. attr ( PostBiomeChangeWeatherChangeAbAttr , WeatherType . HARSH_SUN ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . DELTA_STREAM , 6 )
2024-04-08 09:31:30 -04:00
. attr ( PostSummonWeatherChangeAbAttr , WeatherType . STRONG_WINDS )
. attr ( PostBiomeChangeWeatherChangeAbAttr , WeatherType . STRONG_WINDS ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . STAMINA , 7 )
2024-04-06 21:50:17 -05:00
. attr ( PostDefendStatChangeAbAttr , ( target , user , move ) = > move . category !== MoveCategory . STATUS , BattleStat . DEF , 1 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . WIMP_OUT , 7 )
. unimplemented ( ) ,
new Ability ( Abilities . EMERGENCY_EXIT , 7 )
. unimplemented ( ) ,
new Ability ( Abilities . WATER_COMPACTION , 7 )
2024-04-06 21:50:17 -05:00
. attr ( PostDefendStatChangeAbAttr , ( target , user , move ) = > move . type === Type . WATER , BattleStat . DEF , 2 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . MERCILESS , 7 )
. unimplemented ( ) ,
new Ability ( Abilities . SHIELDS_DOWN , 7 )
2024-04-14 20:30:54 -05:00
. attr ( PostBattleInitFormChangeAbAttr , p = > p . formIndex % 7 + ( p . getHpRatio ( ) <= 0.5 ? 7 : 0 ) )
. attr ( PostSummonFormChangeAbAttr , p = > p . formIndex % 7 + ( p . getHpRatio ( ) <= 0.5 ? 7 : 0 ) )
. attr ( PostTurnFormChangeAbAttr , p = > p . formIndex % 7 + ( p . getHpRatio ( ) <= 0.5 ? 7 : 0 ) )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
2024-04-19 04:27:34 +10:00
. attr ( UnsuppressableAbilityAbAttr )
2024-04-25 03:10:09 +02:00
. attr ( NoFusionAbilityAbAttr )
. partial ( ) ,
new Ability ( Abilities . STAKEOUT , 7 )
2024-04-25 14:29:05 -04:00
. attr ( MovePowerBoostAbAttr , ( user , target , move ) = > user . scene . currentBattle . turnCommands [ target . getBattlerIndex ( ) ] . command === Command . POKEMON , 2 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . WATER_BUBBLE , 7 )
2023-12-23 01:21:01 -05:00
. attr ( ReceivedTypeDamageMultiplierAbAttr , Type . FIRE , 0.5 )
2024-03-14 00:40:57 -04:00
. attr ( MoveTypePowerBoostAbAttr , Type . WATER , 1 )
. attr ( StatusEffectImmunityAbAttr , StatusEffect . BURN )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . STEELWORKER , 7 )
2023-12-14 11:48:59 -06:00
. attr ( MoveTypePowerBoostAbAttr , Type . STEEL ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . BERSERK , 7 )
2024-05-03 13:55:46 -07:00
. attr ( PostDefendHpGatedStatChangeAbAttr , ( target , user , move ) = > move . category !== MoveCategory . STATUS , 0.5 , [ BattleStat . SPATK ] , 1 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SLUSH_RUSH , 7 )
2023-11-24 14:45:58 +09:00
. attr ( BattleStatMultiplierAbAttr , BattleStat . SPD , 2 )
2024-04-15 22:47:39 +02:00
. condition ( getWeatherCondition ( WeatherType . HAIL , WeatherType . SNOW ) ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . LONG_REACH , 7 )
2023-12-10 22:29:13 -05:00
. attr ( IgnoreContactAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . LIQUID_VOICE , 7 )
2024-04-14 13:15:01 -04:00
. attr ( MoveTypeChangeAttr , Type . WATER , 1 , ( user , target , move ) = > move . hasFlag ( MoveFlags . SOUND_BASED ) ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . TRIAGE , 7 )
2024-04-08 17:10:07 +03:00
. attr ( IncrementMovePriorityAbAttr , ( pokemon , move ) = > move . hasFlag ( MoveFlags . TRIAGE_MOVE ) , 3 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . GALVANIZE , 7 )
2024-04-07 22:27:07 -07:00
. attr ( MoveTypeChangePowerMultiplierAbAttr , Type . NORMAL , Type . ELECTRIC , 1.2 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SURGE_SURFER , 7 )
2024-03-14 00:40:57 -04:00
. conditionalAttr ( getTerrainCondition ( TerrainType . ELECTRIC ) , BattleStatMultiplierAbAttr , BattleStat . SPD , 2 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SCHOOLING , 7 )
2024-03-30 09:06:57 -04:00
. attr ( PostBattleInitFormChangeAbAttr , p = > p . level < 20 || p . getHpRatio ( ) <= 0.25 ? 0 : 1 )
. attr ( PostSummonFormChangeAbAttr , p = > p . level < 20 || p . getHpRatio ( ) <= 0.25 ? 0 : 1 )
. attr ( PostTurnFormChangeAbAttr , p = > p . level < 20 || p . getHpRatio ( ) <= 0.25 ? 0 : 1 )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
2024-04-19 04:27:34 +10:00
. attr ( UnsuppressableAbilityAbAttr )
. attr ( NoFusionAbilityAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . DISGUISE , 7 )
2024-05-06 00:27:56 -05:00
. attr ( PreDefendMovePowerToOneAbAttr , ( target , user , move ) = > target . formIndex == 0 && target . getAttackTypeEffectiveness ( move . type , user ) > 0 )
2024-04-17 22:09:28 -06:00
. attr ( PostSummonFormChangeAbAttr , p = > p . battleData . hitCount === 0 ? 0 : 1 )
. attr ( PostBattleInitFormChangeAbAttr , p = > p . battleData . hitCount === 0 ? 0 : 1 )
. attr ( PostDefendFormChangeAbAttr , p = > p . battleData . hitCount === 0 ? 0 : 1 )
. attr ( PreDefendFormChangeAbAttr , p = > p . battleData . hitCount === 0 ? 0 : 1 )
. attr ( PostDefendDisguiseAbAttr )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
. attr ( UnsuppressableAbilityAbAttr )
. attr ( NoTransformAbilityAbAttr )
2024-04-19 04:27:34 +10:00
. attr ( NoFusionAbilityAbAttr )
2024-04-25 03:10:09 +02:00
. ignorable ( )
. partial ( ) ,
new Ability ( Abilities . BATTLE_BOND , 7 )
2024-04-29 19:43:51 -05:00
. attr ( PostVictoryFormChangeAbAttr , p = > p . getFormKey ( ) ? 2 : 1 )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
2024-04-19 04:27:34 +10:00
. attr ( UnsuppressableAbilityAbAttr )
2024-05-04 18:50:12 -07:00
. attr ( NoFusionAbilityAbAttr ) ,
2024-04-29 19:43:51 -05:00
new Ability ( Abilities . POWER_CONSTRUCT , 7 ) // TODO: 10% Power Construct Zygarde isn't accounted for yet. If changed, update Zygarde's getSpeciesFormIndex entry accordingly
. attr ( PostBattleInitFormChangeAbAttr , p = > p . getHpRatio ( ) <= 0.5 ? 4 : 2 )
. attr ( PostSummonFormChangeAbAttr , p = > p . getHpRatio ( ) <= 0.5 ? 4 : 2 )
. attr ( PostTurnFormChangeAbAttr , p = > p . getHpRatio ( ) <= 0.5 ? 4 : 2 )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
2024-04-19 04:27:34 +10:00
. attr ( UnsuppressableAbilityAbAttr )
2024-04-25 03:10:09 +02:00
. attr ( NoFusionAbilityAbAttr )
2024-04-29 19:43:51 -05:00
. partial ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . CORROSION , 7 )
. unimplemented ( ) ,
new Ability ( Abilities . COMATOSE , 7 )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
2024-04-25 03:10:09 +02:00
. attr ( UnsuppressableAbilityAbAttr )
. unimplemented ( ) ,
new Ability ( Abilities . QUEENLY_MAJESTY , 7 )
2024-04-15 19:48:33 +03:00
. attr ( FieldPriorityMoveImmunityAbAttr )
2024-03-14 00:40:57 -04:00
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . INNARDS_OUT , 7 )
. unimplemented ( ) ,
new Ability ( Abilities . DANCER , 7 )
. unimplemented ( ) ,
new Ability ( Abilities . BATTERY , 7 )
. unimplemented ( ) ,
new Ability ( Abilities . FLUFFY , 7 )
2023-12-23 01:21:01 -05:00
. attr ( ReceivedMoveDamageMultiplierAbAttr , ( target , user , move ) = > move . hasFlag ( MoveFlags . MAKES_CONTACT ) , 0.5 )
2024-03-14 00:40:57 -04:00
. attr ( ReceivedMoveDamageMultiplierAbAttr , ( target , user , move ) = > move . type === Type . FIRE , 2 )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . DAZZLING , 7 )
2024-04-15 19:48:33 +03:00
. attr ( FieldPriorityMoveImmunityAbAttr )
2024-03-14 00:40:57 -04:00
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SOUL_HEART , 7 )
2024-04-08 00:20:24 +03:00
. attr ( PostKnockOutStatChangeAbAttr , BattleStat . SPATK , 1 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . TANGLING_HAIR , 7 )
2024-04-06 22:18:12 -05:00
. attr ( PostDefendStatChangeAbAttr , ( target , user , move ) = > move . hasFlag ( MoveFlags . MAKES_CONTACT ) , BattleStat . SPD , - 1 , false ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . RECEIVER , 7 )
2024-04-14 13:21:34 +10:00
. attr ( CopyFaintedAllyAbilityAbAttr )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . POWER_OF_ALCHEMY , 7 )
2024-04-14 13:21:34 +10:00
. attr ( CopyFaintedAllyAbilityAbAttr )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . BEAST_BOOST , 7 )
2024-03-30 00:53:35 -04:00
. attr ( PostVictoryStatChangeAbAttr , p = > {
const battleStats = Utils . getEnumValues ( BattleStat ) . slice ( 0 , - 3 ) . map ( s = > s as BattleStat ) ;
let highestBattleStat = 0 ;
let highestBattleStatIndex = 0 ;
battleStats . map ( ( bs : BattleStat , i : integer ) = > {
const stat = p . getStat ( bs + 1 ) ;
if ( stat > highestBattleStat ) {
highestBattleStatIndex = i ;
highestBattleStat = stat ;
}
} ) ;
return highestBattleStatIndex ;
} , 1 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . RKS_SYSTEM , 7 )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
2024-04-19 04:27:34 +10:00
. attr ( UnsuppressableAbilityAbAttr )
2024-04-25 03:10:09 +02:00
. attr ( NoFusionAbilityAbAttr )
. unimplemented ( ) ,
new Ability ( Abilities . ELECTRIC_SURGE , 7 )
2024-04-08 09:31:30 -04:00
. attr ( PostSummonTerrainChangeAbAttr , TerrainType . ELECTRIC )
. attr ( PostBiomeChangeTerrainChangeAbAttr , TerrainType . ELECTRIC ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . PSYCHIC_SURGE , 7 )
2024-04-08 09:31:30 -04:00
. attr ( PostSummonTerrainChangeAbAttr , TerrainType . PSYCHIC )
. attr ( PostBiomeChangeTerrainChangeAbAttr , TerrainType . PSYCHIC ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . MISTY_SURGE , 7 )
2024-04-08 09:31:30 -04:00
. attr ( PostSummonTerrainChangeAbAttr , TerrainType . MISTY )
. attr ( PostBiomeChangeTerrainChangeAbAttr , TerrainType . MISTY ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . GRASSY_SURGE , 7 )
2024-04-08 09:31:30 -04:00
. attr ( PostSummonTerrainChangeAbAttr , TerrainType . GRASSY )
. attr ( PostBiomeChangeTerrainChangeAbAttr , TerrainType . GRASSY ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . FULL_METAL_BODY , 7 )
2023-12-23 01:21:01 -05:00
. attr ( ProtectStatAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SHADOW_SHIELD , 7 )
Implement Multiscale, Solid Rock, Filter, Justified, Water Compaction, Soul-Heart, Shadow Shield, Prism Armor (#46)
* Implement Multiscale, Solid Rock, Filter, Justified, Water Compaction, Soul-Heart, Shadow Shield, Prism Armor
fix
fix
* Update src/data/ability.ts
---------
Co-authored-by: Samuel H <flashfireex@gmail.com>
2024-04-06 22:39:55 +03:00
. attr ( ReceivedMoveDamageMultiplierAbAttr , ( target , user , move ) = > target . getHpRatio ( ) === 1 , 0.5 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . PRISM_ARMOR , 7 )
2024-05-06 00:27:56 -05:00
. attr ( ReceivedMoveDamageMultiplierAbAttr , ( target , user , move ) = > target . getAttackTypeEffectiveness ( move . type , user ) >= 2 , 0.75 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . NEUROFORCE , 7 )
2024-05-06 00:27:56 -05:00
. attr ( MovePowerBoostAbAttr , ( user , target , move ) = > target . getAttackTypeEffectiveness ( move . type , user ) >= 2 , 1.25 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . INTREPID_SWORD , 8 )
2024-05-07 14:35:15 +10:00
. attr ( PostSummonStatChangeAbAttr , BattleStat . ATK , 1 , true )
. condition ( getOncePerBattleCondition ( Abilities . INTREPID_SWORD ) ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . DAUNTLESS_SHIELD , 8 )
2024-05-07 14:35:15 +10:00
. attr ( PostSummonStatChangeAbAttr , BattleStat . DEF , 1 , true )
. condition ( getOncePerBattleCondition ( Abilities . DAUNTLESS_SHIELD ) ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . LIBERO , 8 )
. unimplemented ( ) ,
new Ability ( Abilities . BALL_FETCH , 8 )
. unimplemented ( ) ,
new Ability ( Abilities . COTTON_DOWN , 8 )
. unimplemented ( ) ,
new Ability ( Abilities . PROPELLER_TAIL , 8 )
. unimplemented ( ) ,
new Ability ( Abilities . MIRROR_ARMOR , 8 )
. ignorable ( )
. unimplemented ( ) ,
new Ability ( Abilities . GULP_MISSILE , 8 )
2024-04-13 11:08:32 +10:00
. attr ( UnsuppressableAbilityAbAttr )
2024-04-19 04:27:34 +10:00
. attr ( NoTransformAbilityAbAttr )
2024-04-25 03:10:09 +02:00
. attr ( NoFusionAbilityAbAttr )
. unimplemented ( ) ,
new Ability ( Abilities . STALWART , 8 )
. unimplemented ( ) ,
new Ability ( Abilities . STEAM_ENGINE , 8 )
2024-04-16 23:17:47 -04:00
. attr ( PostDefendStatChangeAbAttr , ( target , user , move ) = > ( move . type === Type . FIRE || move . type === Type . WATER ) && move . category !== MoveCategory . STATUS , BattleStat . SPD , 6 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . PUNK_ROCK , 8 )
2023-12-23 01:21:01 -05:00
. attr ( MovePowerBoostAbAttr , ( user , target , move ) = > move . hasFlag ( MoveFlags . SOUND_BASED ) , 1.3 )
2024-03-14 00:40:57 -04:00
. attr ( ReceivedMoveDamageMultiplierAbAttr , ( target , user , move ) = > move . hasFlag ( MoveFlags . SOUND_BASED ) , 0.5 )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SAND_SPIT , 8 )
2024-04-07 14:01:48 -05:00
. attr ( PostDefendWeatherChangeAbAttr , WeatherType . SANDSTORM ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . ICE_SCALES , 8 )
2024-04-07 19:36:56 +01:00
. attr ( ReceivedMoveDamageMultiplierAbAttr , ( target , user , move ) = > move . category === MoveCategory . SPECIAL , 0.5 )
2024-03-14 00:40:57 -04:00
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . RIPEN , 8 )
2023-12-22 01:16:56 -05:00
. attr ( DoubleBerryEffectAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . ICE_FACE , 8 )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
. attr ( UnsuppressableAbilityAbAttr )
. attr ( NoTransformAbilityAbAttr )
2024-04-19 04:27:34 +10:00
. attr ( NoFusionAbilityAbAttr )
2024-04-25 03:10:09 +02:00
. ignorable ( )
. unimplemented ( ) ,
new Ability ( Abilities . POWER_SPOT , 8 )
. unimplemented ( ) ,
new Ability ( Abilities . MIMICRY , 8 )
. unimplemented ( ) ,
new Ability ( Abilities . SCREEN_CLEANER , 8 )
. unimplemented ( ) ,
new Ability ( Abilities . STEELY_SPIRIT , 8 )
. unimplemented ( ) ,
new Ability ( Abilities . PERISH_BODY , 8 )
. unimplemented ( ) ,
new Ability ( Abilities . WANDERING_SPIRIT , 8 )
2024-04-14 13:21:34 +10:00
. attr ( PostDefendAbilitySwapAbAttr )
2024-04-25 03:10:09 +02:00
. bypassFaint ( )
. partial ( ) ,
new Ability ( Abilities . GORILLA_TACTICS , 8 )
. unimplemented ( ) ,
new Ability ( Abilities . NEUTRALIZING_GAS , 8 )
2024-04-18 15:44:03 +10:00
. attr ( SuppressFieldAbilitiesAbAttr )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
2024-04-25 03:10:09 +02:00
. attr ( NoTransformAbilityAbAttr )
2024-05-03 22:29:30 -04:00
. attr ( PostSummonMessageAbAttr , ( pokemon : Pokemon ) = > getPokemonMessage ( pokemon , '\'s Neutralizing Gas filled the area!' ) )
2024-04-25 03:10:09 +02:00
. partial ( ) ,
new Ability ( Abilities . PASTEL_VEIL , 8 )
2024-04-08 13:21:06 -04:00
. attr ( StatusEffectImmunityAbAttr , StatusEffect . POISON , StatusEffect . TOXIC )
2024-03-14 00:40:57 -04:00
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . HUNGER_SWITCH , 8 )
2024-03-30 12:01:49 -05:00
. attr ( PostTurnFormChangeAbAttr , p = > p . getFormKey ? 0 : 1 )
2024-04-13 11:08:32 +10:00
. attr ( PostTurnFormChangeAbAttr , p = > p . getFormKey ? 1 : 0 )
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
2024-04-19 04:27:34 +10:00
. attr ( NoTransformAbilityAbAttr )
2024-05-05 22:12:10 -07:00
. attr ( NoFusionAbilityAbAttr )
. condition ( ( pokemon ) = > ! pokemon . isTerastallized ( ) ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . QUICK_DRAW , 8 )
. unimplemented ( ) ,
new Ability ( Abilities . UNSEEN_FIST , 8 )
. unimplemented ( ) ,
new Ability ( Abilities . CURIOUS_MEDICINE , 8 )
. unimplemented ( ) ,
new Ability ( Abilities . TRANSISTOR , 8 )
2023-12-14 11:48:59 -06:00
. attr ( MoveTypePowerBoostAbAttr , Type . ELECTRIC ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . DRAGONS_MAW , 8 )
2023-12-14 11:48:59 -06:00
. attr ( MoveTypePowerBoostAbAttr , Type . DRAGON ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . CHILLING_NEIGH , 8 )
2024-03-29 22:17:26 -05:00
. attr ( PostVictoryStatChangeAbAttr , BattleStat . ATK , 1 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . GRIM_NEIGH , 8 )
2024-03-29 22:17:26 -05:00
. attr ( PostVictoryStatChangeAbAttr , BattleStat . SPATK , 1 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . AS_ONE_GLASTRIER , 8 )
2024-03-29 22:17:26 -05:00
. attr ( PreventBerryUseAbAttr )
2024-04-13 11:08:32 +10:00
. attr ( PostVictoryStatChangeAbAttr , BattleStat . ATK , 1 )
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
. attr ( UnsuppressableAbilityAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . AS_ONE_SPECTRIER , 8 )
2024-03-29 22:17:26 -05:00
. attr ( PreventBerryUseAbAttr )
2024-04-13 11:08:32 +10:00
. attr ( PostVictoryStatChangeAbAttr , BattleStat . SPATK , 1 )
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
. attr ( UnsuppressableAbilityAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . LINGERING_AROMA , 9 )
2024-05-03 22:30:23 -04:00
. attr ( PostDefendAbilityGiveAbAttr , Abilities . LINGERING_AROMA )
2024-04-14 13:21:34 +10:00
. bypassFaint ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SEED_SOWER , 9 )
2024-03-14 00:40:57 -04:00
. attr ( PostDefendTerrainChangeAbAttr , TerrainType . GRASSY ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . THERMAL_EXCHANGE , 9 )
2024-04-17 01:09:15 -04:00
. attr ( PostDefendStatChangeAbAttr , ( target , user , move ) = > move . type === Type . FIRE && move . category !== MoveCategory . STATUS , BattleStat . ATK , 1 )
2024-03-14 00:40:57 -04:00
. attr ( StatusEffectImmunityAbAttr , StatusEffect . BURN )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . ANGER_SHELL , 9 )
2024-05-03 13:55:46 -07:00
. attr ( PostDefendHpGatedStatChangeAbAttr , ( target , user , move ) = > move . category !== MoveCategory . STATUS , 0.5 , [ BattleStat . ATK , BattleStat . SPATK , BattleStat . SPD ] , 1 )
. attr ( PostDefendHpGatedStatChangeAbAttr , ( target , user , move ) = > move . category !== MoveCategory . STATUS , 0.5 , [ BattleStat . DEF , BattleStat . SPDEF ] , - 1 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . PURIFYING_SALT , 9 )
2023-12-23 01:21:01 -05:00
. attr ( StatusEffectImmunityAbAttr )
2024-03-14 00:40:57 -04:00
. attr ( ReceivedTypeDamageMultiplierAbAttr , Type . GHOST , 0.5 )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . WELL_BAKED_BODY , 9 )
2024-03-14 00:40:57 -04:00
. attr ( TypeImmunityStatChangeAbAttr , Type . FIRE , BattleStat . DEF , 2 )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . WIND_RIDER , 9 )
2024-04-17 01:09:15 -04:00
. attr ( MoveImmunityStatChangeAbAttr , ( pokemon , attacker , move ) = > pokemon !== attacker && move . getMove ( ) . hasFlag ( MoveFlags . WIND_MOVE ) , BattleStat . ATK , 1 )
2024-04-25 03:10:09 +02:00
. ignorable ( )
. partial ( ) ,
new Ability ( Abilities . GUARD_DOG , 9 )
2024-05-05 07:52:27 -07:00
. attr ( PostIntimidateStatChangeAbAttr , [ BattleStat . ATK ] , 1 , true )
. attr ( ForceSwitchOutImmunityAbAttr )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . ROCKY_PAYLOAD , 9 )
2023-12-14 11:48:59 -06:00
. attr ( MoveTypePowerBoostAbAttr , Type . ROCK ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . WIND_POWER , 9 )
. attr ( PostDefendApplyBattlerTagAbAttr , ( target , user , move ) = > move . hasFlag ( MoveFlags . WIND_MOVE ) , BattlerTagType . CHARGED )
. partial ( ) ,
new Ability ( Abilities . ZERO_TO_HERO , 9 )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
. attr ( UnsuppressableAbilityAbAttr )
2024-04-19 04:27:34 +10:00
. attr ( NoTransformAbilityAbAttr )
2024-04-25 03:10:09 +02:00
. attr ( NoFusionAbilityAbAttr )
. unimplemented ( ) ,
new Ability ( Abilities . COMMANDER , 9 )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
2024-04-25 03:10:09 +02:00
. attr ( UnswappableAbilityAbAttr )
. unimplemented ( ) ,
new Ability ( Abilities . ELECTROMORPHOSIS , 9 )
2024-04-17 01:09:15 -04:00
. attr ( PostDefendApplyBattlerTagAbAttr , ( target , user , move ) = > move . category !== MoveCategory . STATUS , BattlerTagType . CHARGED ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . PROTOSYNTHESIS , 9 )
2024-03-18 21:22:27 -04:00
. conditionalAttr ( getWeatherCondition ( WeatherType . SUNNY , WeatherType . HARSH_SUN ) , PostSummonAddBattlerTagAbAttr , BattlerTagType . PROTOSYNTHESIS , 0 , true )
. attr ( PostWeatherChangeAddBattlerTagAttr , BattlerTagType . PROTOSYNTHESIS , 0 , WeatherType . SUNNY , WeatherType . HARSH_SUN )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
2024-05-06 03:26:11 +03:00
. attr ( NoTransformAbilityAbAttr )
. partial ( ) , // While setting the tag, the getbattlestat should ignore all modifiers to stats except stat stages
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . QUARK_DRIVE , 9 )
2024-03-18 21:22:27 -04:00
. conditionalAttr ( getTerrainCondition ( TerrainType . ELECTRIC ) , PostSummonAddBattlerTagAbAttr , BattlerTagType . QUARK_DRIVE , 0 , true )
. attr ( PostTerrainChangeAddBattlerTagAttr , BattlerTagType . QUARK_DRIVE , 0 , TerrainType . ELECTRIC )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
2024-05-06 03:26:11 +03:00
. attr ( NoTransformAbilityAbAttr )
. partial ( ) , // While setting the tag, the getbattlestat should ignore all modifiers to stats except stat stages
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . GOOD_AS_GOLD , 9 )
2024-04-01 22:16:16 -05:00
. attr ( MoveImmunityAbAttr , ( pokemon , attacker , move ) = > pokemon !== attacker && move . getMove ( ) . category === MoveCategory . STATUS )
2024-04-25 03:10:09 +02:00
. ignorable ( )
. partial ( ) ,
new Ability ( Abilities . VESSEL_OF_RUIN , 9 )
. ignorable ( )
. unimplemented ( ) ,
new Ability ( Abilities . SWORD_OF_RUIN , 9 )
. ignorable ( )
. unimplemented ( ) ,
new Ability ( Abilities . TABLETS_OF_RUIN , 9 )
. ignorable ( )
. unimplemented ( ) ,
new Ability ( Abilities . BEADS_OF_RUIN , 9 )
. ignorable ( )
. unimplemented ( ) ,
new Ability ( Abilities . ORICHALCUM_PULSE , 9 )
2023-12-23 01:21:01 -05:00
. attr ( PostSummonWeatherChangeAbAttr , WeatherType . SUNNY )
2024-04-08 09:31:30 -04:00
. attr ( PostBiomeChangeWeatherChangeAbAttr , WeatherType . SUNNY )
2024-04-13 11:08:32 +10:00
. conditionalAttr ( getWeatherCondition ( WeatherType . SUNNY , WeatherType . HARSH_SUN ) , BattleStatMultiplierAbAttr , BattleStat . ATK , 4 / 3 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . HADRON_ENGINE , 9 )
2024-03-13 12:23:31 -05:00
. attr ( PostSummonTerrainChangeAbAttr , TerrainType . ELECTRIC )
2024-04-08 09:31:30 -04:00
. attr ( PostBiomeChangeTerrainChangeAbAttr , TerrainType . ELECTRIC )
2024-04-13 11:08:32 +10:00
. conditionalAttr ( getTerrainCondition ( TerrainType . ELECTRIC ) , BattleStatMultiplierAbAttr , BattleStat . SPATK , 4 / 3 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . OPPORTUNIST , 9 )
2024-05-04 16:38:53 -07:00
. attr ( StatChangeCopyAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . CUD_CHEW , 9 )
. unimplemented ( ) ,
new Ability ( Abilities . SHARPNESS , 9 )
2023-12-23 01:21:01 -05:00
. attr ( MovePowerBoostAbAttr , ( user , target , move ) = > move . hasFlag ( MoveFlags . SLICING_MOVE ) , 1.5 ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SUPREME_OVERLORD , 9 )
. unimplemented ( ) ,
new Ability ( Abilities . COSTAR , 9 )
. unimplemented ( ) ,
new Ability ( Abilities . TOXIC_DEBRIS , 9 )
2024-04-19 20:08:09 +01:00
. attr ( PostDefendApplyArenaTrapTagAbAttr , ( target , user , move ) = > move . category === MoveCategory . PHYSICAL , ArenaTagType . TOXIC_SPIKES )
. bypassFaint ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . ARMOR_TAIL , 9 )
2024-04-15 19:48:33 +03:00
. attr ( FieldPriorityMoveImmunityAbAttr )
2024-03-14 00:40:57 -04:00
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . EARTH_EATER , 9 )
2024-03-14 00:40:57 -04:00
. attr ( TypeImmunityHealAbAttr , Type . GROUND )
. ignorable ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . MYCELIUM_MIGHT , 9 )
. attr ( MoveAbilityBypassAbAttr , ( pokemon , move : Move ) = > move . category === MoveCategory . STATUS )
. partial ( ) ,
new Ability ( Abilities . MINDS_EYE , 9 )
2024-05-06 00:27:56 -05:00
. attr ( IgnoreTypeImmunityAbAttr , Type . GHOST , [ Type . NORMAL , Type . FIGHTING ] )
2024-05-08 00:32:38 -05:00
. ignorable ( ) // TODO: evasiveness bypass should not be ignored, but accuracy immunity should
. partial ( ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . SUPERSWEET_SYRUP , 9 )
2024-05-06 23:47:20 -05:00
. attr ( PostSummonStatChangeAbAttr , BattleStat . EVA , - 1 )
. condition ( getOncePerBattleCondition ( Abilities . SUPERSWEET_SYRUP ) ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . HOSPITALITY , 9 )
2024-04-23 09:43:35 -04:00
. attr ( PostSummonAllyHealAbAttr , 4 , true ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . TOXIC_CHAIN , 9 )
2024-04-14 11:13:17 -06:00
. attr ( PostAttackApplyStatusEffectAbAttr , false , 30 , StatusEffect . TOXIC ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . EMBODY_ASPECT_TEAL , 9 )
2024-04-13 11:08:32 +10:00
. attr ( PostBattleInitStatChangeAbAttr , BattleStat . SPD , 1 , true )
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
. attr ( NoTransformAbilityAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . EMBODY_ASPECT_WELLSPRING , 9 )
2024-04-13 11:08:32 +10:00
. attr ( PostBattleInitStatChangeAbAttr , BattleStat . SPDEF , 1 , true )
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
. attr ( NoTransformAbilityAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . EMBODY_ASPECT_HEARTHFLAME , 9 )
2024-04-13 11:08:32 +10:00
. attr ( PostBattleInitStatChangeAbAttr , BattleStat . ATK , 1 , true )
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
. attr ( NoTransformAbilityAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . EMBODY_ASPECT_CORNERSTONE , 9 )
2024-04-13 11:08:32 +10:00
. attr ( PostBattleInitStatChangeAbAttr , BattleStat . DEF , 1 , true )
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
. attr ( NoTransformAbilityAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . TERA_SHIFT , 9 )
2024-04-13 11:08:32 +10:00
. attr ( PostSummonFormChangeAbAttr , p = > p . getFormKey ( ) ? 0 : 1 )
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
. attr ( UnsuppressableAbilityAbAttr )
2024-04-19 04:27:34 +10:00
. attr ( NoTransformAbilityAbAttr )
. attr ( NoFusionAbilityAbAttr ) ,
2024-04-25 03:10:09 +02:00
new Ability ( Abilities . TERA_SHELL , 9 )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
2024-04-25 03:10:09 +02:00
. ignorable ( )
. unimplemented ( ) ,
new Ability ( Abilities . TERAFORM_ZERO , 9 )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
2024-04-25 03:10:09 +02:00
. attr ( UnswappableAbilityAbAttr )
. unimplemented ( ) ,
new Ability ( Abilities . POISON_PUPPETEER , 9 )
2024-04-13 11:08:32 +10:00
. attr ( UncopiableAbilityAbAttr )
. attr ( UnswappableAbilityAbAttr )
2024-04-25 03:10:09 +02:00
. unimplemented ( ) ,
2023-04-27 14:30:03 -04:00
) ;
2024-04-07 19:36:56 +01:00
}