2023-04-12 11:57:15 -04:00
import * as ModifierTypes from './modifier-type' ;
2023-10-28 13:24:57 -04:00
import { LearnMovePhase , LevelUpPhase , ObtainStatusEffectPhase , PokemonHealPhase } from "../battle-phases" ;
2023-10-03 12:50:31 -04:00
import BattleScene from "../battle-scene" ;
2023-04-20 15:46:05 -04:00
import { getLevelTotalExp } from "../data/exp" ;
import { PokeballType } from "../data/pokeball" ;
2023-04-23 18:40:21 -04:00
import Pokemon , { PlayerPokemon } from "../pokemon" ;
2023-04-20 15:46:05 -04:00
import { Stat } from "../data/pokemon-stat" ;
2023-11-02 00:55:20 -04:00
import { addTextObject , getModifierTierTextTint , TextStyle } from "../ui/text" ;
2023-04-20 15:46:05 -04:00
import { Type } from '../data/type' ;
import { EvolutionPhase } from '../evolution-phase' ;
import { pokemonEvolutions } from '../data/pokemon-evolutions' ;
import { getPokemonMessage } from '../messages' ;
import * as Utils from "../utils" ;
import { TempBattleStat } from '../data/temp-battle-stat' ;
import { BerryType , getBerryEffectFunc , getBerryPredicate } from '../data/berry' ;
2023-04-26 16:07:29 -04:00
import { Species } from '../data/species' ;
2023-10-29 17:58:54 -04:00
import { StatusEffect , getStatusEffectDescriptor } from '../data/status-effect' ;
2023-11-12 00:31:40 -05:00
import { MoneyAchv } from '../system/achv' ;
2023-03-28 14:54:52 -04:00
2023-04-12 11:57:15 -04:00
type ModifierType = ModifierTypes . ModifierType ;
2023-04-14 18:21:33 -04:00
export type ModifierPredicate = ( modifier : Modifier ) = > boolean ;
2023-04-12 11:57:15 -04:00
2023-10-31 21:43:22 -04:00
const iconOverflowIndex = 24 ;
2023-03-28 14:54:52 -04:00
export class ModifierBar extends Phaser . GameObjects . Container {
2023-04-20 19:44:56 -04:00
private player : boolean ;
2023-10-31 21:43:22 -04:00
private modifierCache : PersistentModifier [ ] ;
2023-03-28 14:54:52 -04:00
2023-04-20 19:44:56 -04:00
constructor ( scene : BattleScene , enemy? : boolean ) {
super ( scene , 1 + ( enemy ? 302 : 0 ) , 2 ) ;
this . player = ! enemy ;
2023-03-28 14:54:52 -04:00
this . setScale ( 0.5 ) ;
}
2023-04-09 19:15:21 -04:00
updateModifiers ( modifiers : PersistentModifier [ ] ) {
this . removeAll ( true ) ;
2023-10-24 10:05:07 -04:00
const visibleIconModifiers = modifiers . filter ( m = > m . isIconVisible ( this . scene as BattleScene ) ) ;
2023-10-31 21:43:22 -04:00
visibleIconModifiers . sort ( ( a : Modifier , b : Modifier ) = > {
const aId = a instanceof PokemonHeldItemModifier ? a.pokemonId : 4294967295 ;
const bId = b instanceof PokemonHeldItemModifier ? b.pokemonId : 4294967295 ;
return aId < bId ? 1 : aId > bId ? - 1 : 0 ;
} ) ;
2023-11-02 00:55:20 -04:00
const thisArg = this ;
2023-10-31 21:43:22 -04:00
visibleIconModifiers . forEach ( ( modifier : PersistentModifier , i : integer ) = > {
2023-04-09 19:15:21 -04:00
const icon = modifier . getIcon ( this . scene as BattleScene ) ;
2023-10-31 21:43:22 -04:00
if ( i >= iconOverflowIndex )
icon . setVisible ( false ) ;
2023-04-09 19:15:21 -04:00
this . add ( icon ) ;
2023-10-24 10:05:07 -04:00
this . setModifierIconPosition ( icon , visibleIconModifiers . length ) ;
2023-11-02 00:55:20 -04:00
icon . setInteractive ( new Phaser . Geom . Rectangle ( 0 , 0 , 32 , 32 ) , Phaser . Geom . Rectangle . Contains ) ;
icon . on ( 'pointerover' , ( ) = > {
( this . scene as BattleScene ) . ui . showTooltip ( modifier . type . name , modifier . type . description ) ;
if ( this . modifierCache && this . modifierCache . length > iconOverflowIndex )
thisArg . updateModifierOverflowVisibility ( true ) ;
} ) ;
icon . on ( 'pointerout' , ( ) = > {
( this . scene as BattleScene ) . ui . hideTooltip ( ) ;
if ( this . modifierCache && this . modifierCache . length > iconOverflowIndex )
thisArg . updateModifierOverflowVisibility ( false ) ;
} ) ;
2023-10-31 21:43:22 -04:00
} ) ;
this . modifierCache = modifiers ;
}
updateModifierOverflowVisibility ( ignoreLimit : boolean ) {
for ( let modifier of this . getAll ( ) . map ( m = > m as Phaser . GameObjects . Container ) . slice ( iconOverflowIndex ) )
modifier . setVisible ( ignoreLimit ) ;
2023-03-28 14:54:52 -04:00
}
2023-04-19 14:07:38 -04:00
setModifierIconPosition ( icon : Phaser.GameObjects.Container , modifierCount : integer ) {
2023-10-31 21:43:22 -04:00
let rowIcons : integer = 12 + 6 * Math . max ( ( Math . ceil ( Math . min ( modifierCount , 24 ) / 12 ) - 2 ) , 0 ) ;
2023-04-19 14:07:38 -04:00
const x = ( this . getIndex ( icon ) % rowIcons ) * 26 / ( rowIcons / 12 ) ;
const y = Math . floor ( this . getIndex ( icon ) / rowIcons ) * 20 ;
2023-03-28 14:54:52 -04:00
2023-04-20 19:44:56 -04:00
icon . setPosition ( this . player ? x : - x , y ) ;
2023-03-28 14:54:52 -04:00
}
}
export abstract class Modifier {
public type : ModifierType ;
constructor ( type : ModifierType ) {
this . type = type ;
}
2023-04-09 19:15:21 -04:00
match ( _modifier : Modifier ) : boolean {
return false ;
2023-03-28 14:54:52 -04:00
}
shouldApply ( _args : any [ ] ) : boolean {
return true ;
}
abstract apply ( args : any [ ] ) : boolean ;
2023-04-09 19:15:21 -04:00
}
export abstract class PersistentModifier extends Modifier {
public stackCount : integer ;
public virtualStackCount : integer ;
2023-04-21 14:05:16 -04:00
constructor ( type : ModifierType , stackCount : integer ) {
2023-04-09 19:15:21 -04:00
super ( type ) ;
2023-04-21 14:05:16 -04:00
this . stackCount = stackCount === undefined ? 1 : stackCount ;
2023-04-09 19:15:21 -04:00
this . virtualStackCount = 0 ;
}
add ( modifiers : PersistentModifier [ ] , virtual : boolean ) : boolean {
for ( let modifier of modifiers ) {
2023-04-20 11:29:26 -04:00
if ( this . match ( modifier ) )
2023-04-21 22:59:09 -04:00
return modifier . incrementStack ( this . stackCount , virtual ) ;
2023-04-09 19:15:21 -04:00
}
if ( virtual ) {
this . virtualStackCount += this . stackCount ;
this . stackCount = 0 ;
}
modifiers . push ( this ) ;
return true ;
}
abstract clone ( ) : PersistentModifier ;
2023-04-28 15:03:42 -04:00
getArgs ( ) : any [ ] {
return [ ] ;
}
2023-04-21 14:05:16 -04:00
incrementStack ( amount : integer , virtual : boolean ) : boolean {
if ( this . getStackCount ( ) + amount <= this . getMaxStackCount ( ) ) {
2023-04-09 19:15:21 -04:00
if ( ! virtual )
2023-04-21 14:05:16 -04:00
this . stackCount += amount ;
2023-04-09 19:15:21 -04:00
else
2023-04-21 14:05:16 -04:00
this . virtualStackCount += amount ;
2023-04-20 11:29:26 -04:00
return true ;
2023-04-09 19:15:21 -04:00
}
2023-04-20 11:29:26 -04:00
return false ;
2023-04-09 19:15:21 -04:00
}
2023-03-28 14:54:52 -04:00
2023-04-09 19:15:21 -04:00
getStackCount ( ) : integer {
return this . stackCount + this . virtualStackCount ;
2023-03-30 23:02:35 -04:00
}
getMaxStackCount ( ) : integer {
return 99 ;
2023-03-28 14:54:52 -04:00
}
2023-10-24 10:05:07 -04:00
isIconVisible ( scene : BattleScene ) : boolean {
return true ;
}
2023-04-23 18:40:21 -04:00
getIcon ( scene : BattleScene , forSummary? : boolean ) : Phaser . GameObjects . Container {
2023-03-28 14:54:52 -04:00
const container = scene . add . container ( 0 , 0 ) ;
const item = scene . add . sprite ( 0 , 12 , 'items' ) ;
item . setFrame ( this . type . iconImage ) ;
item . setOrigin ( 0 , 0.5 ) ;
container . add ( item ) ;
const stackText = this . getIconStackText ( scene ) ;
if ( stackText )
container . add ( stackText ) ;
2023-04-09 19:15:21 -04:00
const virtualStackText = this . getIconStackText ( scene , true ) ;
if ( virtualStackText )
container . add ( virtualStackText ) ;
2023-03-28 14:54:52 -04:00
return container ;
}
2023-04-09 19:15:21 -04:00
getIconStackText ( scene : BattleScene , virtual? : boolean ) : Phaser . GameObjects . Text {
if ( this . getMaxStackCount ( ) === 1 || ( virtual && ! this . virtualStackCount ) )
2023-03-28 14:54:52 -04:00
return null ;
2023-04-09 19:15:21 -04:00
const isStackMax = this . getStackCount ( ) >= this . getMaxStackCount ( ) ;
const maxColor = '#f89890' ;
const maxStrokeColor = '#984038' ;
if ( virtual ) {
2023-04-18 22:09:37 -04:00
const virtualText = addTextObject ( scene , 27 , 12 , ` + ${ this . virtualStackCount . toString ( ) } ` , TextStyle . PARTY , { fontSize : '66px' , color : ! isStackMax ? '#40c8f8' : maxColor } ) ;
2023-04-09 19:15:21 -04:00
virtualText . setShadow ( 0 , 0 , null ) ;
virtualText . setStroke ( ! isStackMax ? '#006090' : maxStrokeColor , 16 )
virtualText . setOrigin ( 1 , 0 ) ;
return virtualText ;
}
const text = addTextObject ( scene , 8 , 12 , this . stackCount . toString ( ) , TextStyle . PARTY , { fontSize : '66px' , color : ! isStackMax ? '#f8f8f8' : maxColor } ) ;
text . setShadow ( 0 , 0 , null ) ;
2023-03-28 14:54:52 -04:00
text . setStroke ( '#424242' , 16 )
2023-04-09 19:15:21 -04:00
text . setOrigin ( 0 , 0 ) ;
2023-03-28 14:54:52 -04:00
return text ;
}
}
export abstract class ConsumableModifier extends Modifier {
constructor ( type : ModifierType ) {
super ( type ) ;
}
2023-04-09 19:15:21 -04:00
add ( _modifiers : Modifier [ ] ) : boolean {
2023-03-28 14:54:52 -04:00
return true ;
}
shouldApply ( args : any [ ] ) : boolean {
2023-03-30 23:02:35 -04:00
return super . shouldApply ( args ) && args . length === 1 && args [ 0 ] instanceof BattleScene ;
2023-03-28 14:54:52 -04:00
}
}
2023-04-12 11:57:15 -04:00
export class AddPokeballModifier extends ConsumableModifier {
2023-03-28 14:54:52 -04:00
private pokeballType : PokeballType ;
private count : integer ;
constructor ( type : ModifierType , pokeballType : PokeballType , count : integer ) {
super ( type ) ;
this . pokeballType = pokeballType ;
this . count = count ;
}
apply ( args : any [ ] ) : boolean {
2023-04-01 22:59:07 -04:00
const pokeballCounts = ( args [ 0 ] as BattleScene ) . pokeballCounts ;
pokeballCounts [ this . pokeballType ] = Math . min ( pokeballCounts [ this . pokeballType ] + this . count , 99 ) ;
2023-03-28 14:54:52 -04:00
return true ;
}
}
2023-06-01 11:22:34 -04:00
export abstract class LapsingPersistentModifier extends PersistentModifier {
protected battlesLeft : integer ;
constructor ( type : ModifierTypes . ModifierType , battlesLeft? : integer , stackCount? : integer ) {
super ( type , stackCount ) ;
this . battlesLeft = battlesLeft ;
}
lapse ( ) : boolean {
return ! ! -- this . battlesLeft ;
}
getIcon ( scene : BattleScene ) : Phaser . GameObjects . Container {
const container = super . getIcon ( scene ) ;
const battleCountText = addTextObject ( scene , 27 , 0 , this . battlesLeft . toString ( ) , TextStyle . PARTY , { fontSize : '66px' , color : '#f89890' } ) ;
battleCountText . setShadow ( 0 , 0 , null ) ;
battleCountText . setStroke ( '#984038' , 16 )
battleCountText . setOrigin ( 1 , 0 ) ;
container . add ( battleCountText ) ;
return container ;
}
}
export class DoubleBattleChanceBoosterModifier extends LapsingPersistentModifier {
constructor ( type : ModifierTypes . DoubleBattleChanceBoosterModifierType , battlesLeft : integer , stackCount? : integer ) {
super ( type , battlesLeft , stackCount ) ;
}
2023-06-01 13:54:52 -04:00
match ( modifier : Modifier ) : boolean {
if ( modifier instanceof DoubleBattleChanceBoosterModifier )
return ( modifier as DoubleBattleChanceBoosterModifier ) . battlesLeft === this . battlesLeft ;
return false ;
}
2023-11-12 12:49:06 -05:00
clone ( ) : DoubleBattleChanceBoosterModifier {
return new DoubleBattleChanceBoosterModifier ( this . type as ModifierTypes . DoubleBattleChanceBoosterModifierType , this . battlesLeft , this . stackCount ) ;
2023-06-01 11:22:34 -04:00
}
getArgs ( ) : any [ ] {
return [ this . battlesLeft ] ;
}
apply ( args : any [ ] ) : boolean {
const doubleBattleChance = args [ 0 ] as Utils . NumberHolder ;
doubleBattleChance . value = Math . ceil ( doubleBattleChance . value / 2 ) ;
return true ;
}
}
export class TempBattleStatBoosterModifier extends LapsingPersistentModifier {
2023-04-20 15:46:05 -04:00
private tempBattleStat : TempBattleStat ;
2023-04-18 22:09:37 -04:00
2023-04-28 15:03:42 -04:00
constructor ( type : ModifierTypes . TempBattleStatBoosterModifierType , tempBattleStat : TempBattleStat , battlesLeft? : integer , stackCount? : integer ) {
2023-06-01 11:22:34 -04:00
super ( type , battlesLeft || 5 , stackCount ) ;
2023-04-18 22:09:37 -04:00
this . tempBattleStat = tempBattleStat ;
}
2023-06-01 13:54:52 -04:00
match ( modifier : Modifier ) : boolean {
if ( modifier instanceof TempBattleStatBoosterModifier )
return ( modifier as TempBattleStatBoosterModifier ) . tempBattleStat === this . tempBattleStat
&& ( modifier as TempBattleStatBoosterModifier ) . battlesLeft === this . battlesLeft ;
return false ;
}
2023-04-18 22:09:37 -04:00
clone ( ) : TempBattleStatBoosterModifier {
2023-06-01 11:22:34 -04:00
return new TempBattleStatBoosterModifier ( this . type as ModifierTypes . TempBattleStatBoosterModifierType , this . tempBattleStat , this . battlesLeft , this . stackCount ) ;
2023-04-18 22:09:37 -04:00
}
2023-04-28 15:03:42 -04:00
getArgs ( ) : any [ ] {
return [ this . tempBattleStat , this . battlesLeft ] ;
}
2023-04-18 22:09:37 -04:00
apply ( args : any [ ] ) : boolean {
2023-04-20 15:46:05 -04:00
const tempBattleStat = args [ 0 ] as TempBattleStat ;
2023-04-18 22:09:37 -04:00
if ( tempBattleStat === this . tempBattleStat ) {
const statLevel = args [ 1 ] as Utils . IntegerHolder ;
statLevel . value = Math . min ( statLevel . value + 1 , 6 ) ;
return true ;
}
return false ;
}
}
2023-04-26 19:19:39 -04:00
export class MapModifier extends PersistentModifier {
constructor ( type : ModifierType , stackCount? : integer ) {
super ( type , stackCount ) ;
}
clone ( ) : MapModifier {
return new MapModifier ( this . type , this . stackCount ) ;
}
apply ( args : any [ ] ) : boolean {
return true ;
}
2023-05-19 16:13:11 -04:00
getMaxStackCount ( ) : integer {
2023-04-26 19:19:39 -04:00
return 1 ;
}
}
2023-04-09 19:15:21 -04:00
export abstract class PokemonHeldItemModifier extends PersistentModifier {
2023-03-28 14:54:52 -04:00
public pokemonId : integer ;
2023-04-21 14:05:16 -04:00
constructor ( type : ModifierType , pokemonId : integer , stackCount : integer ) {
super ( type , stackCount ) ;
2023-03-28 14:54:52 -04:00
this . pokemonId = pokemonId ;
}
2023-04-21 14:05:16 -04:00
abstract matchType ( _modifier : Modifier ) : boolean ;
match ( modifier : Modifier ) {
return this . matchType ( modifier ) && ( modifier as PokemonHeldItemModifier ) . pokemonId === this . pokemonId ;
}
2023-04-28 15:03:42 -04:00
getArgs ( ) : any [ ] {
return [ this . pokemonId ] ;
}
2023-03-28 14:54:52 -04:00
shouldApply ( args : any [ ] ) : boolean {
2023-03-30 23:02:35 -04:00
return super . shouldApply ( args ) && args . length && args [ 0 ] instanceof Pokemon && ( this . pokemonId === - 1 || ( args [ 0 ] as Pokemon ) . id === this . pokemonId ) ;
2023-03-28 14:54:52 -04:00
}
2023-05-31 19:54:57 -04:00
getTransferrable ( withinParty : boolean ) {
return true ;
}
2023-10-24 10:05:07 -04:00
isIconVisible ( scene : BattleScene ) : boolean {
2023-10-31 21:43:22 -04:00
return this . getPokemon ( scene ) . isOnField ( ) ;
2023-10-24 10:05:07 -04:00
}
2023-04-23 18:40:21 -04:00
getIcon ( scene : BattleScene , forSummary? : boolean ) : Phaser . GameObjects . Container {
const container = ! forSummary ? scene . add . container ( 0 , 0 ) : super . getIcon ( scene ) ;
2023-03-28 14:54:52 -04:00
2023-04-23 18:40:21 -04:00
if ( ! forSummary ) {
const pokemon = this . getPokemon ( scene ) ;
2023-10-23 13:48:56 -04:00
const isIconShown = pokemon instanceof PlayerPokemon || scene . currentBattle . seenEnemyPartyMemberIds . has ( pokemon . id ) ;
2023-10-24 15:17:41 -04:00
const iconAtlasKey = isIconShown ? pokemon . getIconAtlasKey ( ) : 'pokemon_icons_0' ;
2023-10-23 13:48:56 -04:00
const pokemonIcon = scene . add . sprite ( 0 , 8 , iconAtlasKey ) ;
2023-11-28 21:35:52 -05:00
if ( pokemon . getSpeciesForm ( ) . generation <= 5 ) {
2023-10-23 13:48:56 -04:00
const iconKey = isIconShown ? pokemon . getIconKey ( ) : 'pkmn_icon__000' ;
pokemonIcon . play ( iconKey ) . stop ( ) ;
2023-11-28 23:05:35 -05:00
} else
2023-04-26 16:07:29 -04:00
pokemonIcon . setFrame ( pokemon . getIconId ( ) ) ;
2023-04-23 18:40:21 -04:00
pokemonIcon . setOrigin ( 0 , 0.5 ) ;
2023-03-28 14:54:52 -04:00
2023-04-23 18:40:21 -04:00
container . add ( pokemonIcon ) ;
2023-03-28 14:54:52 -04:00
2023-04-23 18:40:21 -04:00
const item = scene . add . sprite ( 16 , this . virtualStackCount ? 8 : 16 , 'items' ) ;
item . setScale ( 0.5 ) ;
item . setOrigin ( 0 , 0.5 ) ;
item . setTexture ( 'items' , this . type . iconImage ) ;
container . add ( item ) ;
2023-04-14 01:08:44 -04:00
2023-04-23 18:40:21 -04:00
const stackText = this . getIconStackText ( scene ) ;
if ( stackText )
container . add ( stackText ) ;
2023-04-14 01:08:44 -04:00
2023-04-23 18:40:21 -04:00
const virtualStackText = this . getIconStackText ( scene , true ) ;
if ( virtualStackText )
container . add ( virtualStackText ) ;
} else
container . setScale ( 0.5 ) ;
2023-04-14 01:08:44 -04:00
2023-03-28 14:54:52 -04:00
return container ;
}
2023-04-22 22:14:53 -04:00
getPokemon ( scene : BattleScene ) : Pokemon {
return scene . getPokemonById ( this . pokemonId ) ;
2023-03-28 14:54:52 -04:00
}
}
2023-04-09 19:15:21 -04:00
export class PokemonBaseStatModifier extends PokemonHeldItemModifier {
2023-03-28 14:54:52 -04:00
protected stat : Stat ;
2023-04-21 14:05:16 -04:00
constructor ( type : ModifierTypes . PokemonBaseStatBoosterModifierType , pokemonId : integer , stat : Stat , stackCount? : integer ) {
super ( type , pokemonId , stackCount ) ;
2023-03-28 14:54:52 -04:00
this . stat = stat ;
}
2023-04-21 14:05:16 -04:00
matchType ( modifier : Modifier ) : boolean {
if ( modifier instanceof PokemonBaseStatModifier )
return ( modifier as PokemonBaseStatModifier ) . stat === this . stat ;
2023-04-09 19:15:21 -04:00
return false ;
}
2023-03-28 14:54:52 -04:00
2023-04-09 19:15:21 -04:00
clone ( ) : PersistentModifier {
2023-04-21 14:05:16 -04:00
return new PokemonBaseStatModifier ( this . type as ModifierTypes . PokemonBaseStatBoosterModifierType , this . pokemonId , this . stat , this . stackCount ) ;
2023-03-28 14:54:52 -04:00
}
2023-04-28 15:03:42 -04:00
getArgs ( ) : any [ ] {
return super . getArgs ( ) . concat ( this . stat ) ;
}
2023-03-28 14:54:52 -04:00
shouldApply ( args : any [ ] ) : boolean {
2023-10-23 13:48:56 -04:00
return super . shouldApply ( args ) && args . length === 2 && args [ 1 ] instanceof Array ;
2023-03-28 14:54:52 -04:00
}
apply ( args : any [ ] ) : boolean {
2023-04-09 19:15:21 -04:00
args [ 1 ] [ this . stat ] = Math . min ( Math . floor ( args [ 1 ] [ this . stat ] * ( 1 + this . getStackCount ( ) * 0.2 ) ) , 999999 ) ;
2023-03-28 14:54:52 -04:00
return true ;
}
2023-05-31 19:54:57 -04:00
getTransferrable ( _withinParty : boolean ) : boolean {
return false ;
}
2023-04-14 01:08:44 -04:00
}
2023-03-28 14:54:52 -04:00
2023-04-14 18:21:33 -04:00
export class AttackTypeBoosterModifier extends PokemonHeldItemModifier {
private moveType : Type ;
private boostMultiplier : number ;
2023-11-05 10:56:09 -05:00
constructor ( type : ModifierType , pokemonId : integer , moveType : Type , boostPercent : number , stackCount? : integer ) {
2023-04-21 14:05:16 -04:00
super ( type , pokemonId , stackCount ) ;
2023-04-14 18:21:33 -04:00
this . moveType = moveType ;
this . boostMultiplier = boostPercent * 0.01 ;
}
2023-11-10 21:11:36 -05:00
matchType ( modifier : Modifier ) : boolean {
2023-04-21 14:05:16 -04:00
if ( modifier instanceof AttackTypeBoosterModifier ) {
const attackTypeBoosterModifier = modifier as AttackTypeBoosterModifier ;
return attackTypeBoosterModifier . moveType === this . moveType && attackTypeBoosterModifier . boostMultiplier === this . boostMultiplier ;
}
2023-04-14 18:21:33 -04:00
}
clone() {
2023-04-21 14:05:16 -04:00
return new AttackTypeBoosterModifier ( this . type , this . pokemonId , this . moveType , this . boostMultiplier * 100 , this . stackCount ) ;
2023-04-14 18:21:33 -04:00
}
2023-04-28 15:03:42 -04:00
getArgs ( ) : any [ ] {
return super . getArgs ( ) . concat ( [ this . moveType , this . boostMultiplier * 100 ] ) ;
}
2023-04-14 18:21:33 -04:00
shouldApply ( args : any [ ] ) : boolean {
return super . shouldApply ( args ) && args . length === 2 && args [ 1 ] instanceof Utils . NumberHolder ;
}
apply ( args : any [ ] ) : boolean {
( args [ 1 ] as Utils . NumberHolder ) . value = Math . floor ( ( args [ 1 ] as Utils . NumberHolder ) . value * ( 1 + ( this . getStackCount ( ) * this . boostMultiplier ) ) ) ;
return true ;
}
}
2023-04-23 21:31:06 -04:00
export class SurviveDamageModifier extends PokemonHeldItemModifier {
constructor ( type : ModifierType , pokemonId : integer , stackCount? : integer ) {
super ( type , pokemonId , stackCount ) ;
}
2023-11-10 21:11:36 -05:00
matchType ( modifier : Modifier ) : boolean {
2023-04-23 21:31:06 -04:00
return modifier instanceof SurviveDamageModifier ;
}
clone() {
return new SurviveDamageModifier ( this . type , this . pokemonId , this . stackCount ) ;
}
shouldApply ( args : any [ ] ) : boolean {
return super . shouldApply ( args ) && args . length === 2 && args [ 1 ] instanceof Utils . BooleanHolder ;
}
apply ( args : any [ ] ) : boolean {
const pokemon = args [ 0 ] as Pokemon ;
const surviveDamage = args [ 1 ] as Utils . BooleanHolder ;
2023-04-25 01:32:48 -04:00
if ( ! surviveDamage . value && Utils . randInt ( 10 ) < this . getStackCount ( ) ) {
2023-04-23 21:31:06 -04:00
surviveDamage . value = true ;
pokemon . scene . queueMessage ( getPokemonMessage ( pokemon , ` hung on \ nusing its ${ this . type . name } ! ` ) ) ;
2023-10-29 17:58:54 -04:00
return true ;
2023-04-23 21:31:06 -04:00
}
2023-10-29 17:58:54 -04:00
return false ;
2023-04-23 21:31:06 -04:00
}
2023-05-19 16:13:11 -04:00
getMaxStackCount ( ) : integer {
2023-04-23 21:31:06 -04:00
return 5 ;
}
}
2023-04-25 01:32:48 -04:00
export class FlinchChanceModifier extends PokemonHeldItemModifier {
constructor ( type : ModifierType , pokemonId : integer , stackCount? : integer ) {
super ( type , pokemonId , stackCount ) ;
}
matchType ( modifier : Modifier ) {
return modifier instanceof FlinchChanceModifier ;
}
clone() {
return new FlinchChanceModifier ( this . type , this . pokemonId , this . stackCount ) ;
}
shouldApply ( args : any [ ] ) : boolean {
return super . shouldApply ( args ) && args . length === 2 && args [ 1 ] instanceof Utils . BooleanHolder ;
}
apply ( args : any [ ] ) : boolean {
const flinched = args [ 1 ] as Utils . BooleanHolder ;
2023-10-29 17:58:54 -04:00
if ( ! flinched . value && Utils . randInt ( 10 ) < this . getStackCount ( ) ) {
2023-04-25 01:32:48 -04:00
flinched . value = true ;
2023-10-29 17:58:54 -04:00
return true ;
}
2023-04-25 01:32:48 -04:00
2023-10-29 17:58:54 -04:00
return false ;
2023-04-25 01:32:48 -04:00
}
2023-07-06 19:47:52 -04:00
getMaxStackCount ( ) : integer {
2023-04-25 01:32:48 -04:00
return 3 ;
}
}
2023-04-20 20:15:16 -04:00
export class TurnHealModifier extends PokemonHeldItemModifier {
2023-04-21 14:05:16 -04:00
constructor ( type : ModifierType , pokemonId : integer , stackCount? : integer ) {
super ( type , pokemonId , stackCount ) ;
2023-04-20 20:15:16 -04:00
}
2023-04-21 14:05:16 -04:00
matchType ( modifier : Modifier ) {
2023-04-20 20:15:16 -04:00
return modifier instanceof TurnHealModifier ;
}
clone() {
2023-04-21 14:05:16 -04:00
return new TurnHealModifier ( this . type , this . pokemonId , this . stackCount ) ;
2023-04-20 20:15:16 -04:00
}
apply ( args : any [ ] ) : boolean {
const pokemon = args [ 0 ] as Pokemon ;
if ( pokemon . getHpRatio ( ) < 1 ) {
const scene = pokemon . scene ;
2023-05-18 11:11:06 -04:00
scene . unshiftPhase ( new PokemonHealPhase ( scene , pokemon . getBattlerIndex ( ) ,
Math . max ( Math . floor ( pokemon . getMaxHp ( ) / 16 ) * this . stackCount , 1 ) , getPokemonMessage ( pokemon , ` 's ${ this . type . name } \ nrestored its HP a little! ` ) , true ) ) ;
2023-10-29 17:58:54 -04:00
return true ;
2023-04-20 20:15:16 -04:00
}
2023-10-29 17:58:54 -04:00
return false ;
2023-04-20 20:15:16 -04:00
}
2023-07-06 19:47:52 -04:00
getMaxStackCount ( ) : integer {
2023-04-23 21:31:06 -04:00
return 4 ;
2023-04-20 20:15:16 -04:00
}
}
2023-04-14 01:08:44 -04:00
export class HitHealModifier extends PokemonHeldItemModifier {
2023-04-21 14:05:16 -04:00
constructor ( type : ModifierType , pokemonId : integer , stackCount? : integer ) {
super ( type , pokemonId , stackCount ) ;
2023-04-14 01:08:44 -04:00
}
2023-03-28 14:54:52 -04:00
2023-04-21 14:05:16 -04:00
matchType ( modifier : Modifier ) {
2023-04-14 01:08:44 -04:00
return modifier instanceof HitHealModifier ;
}
2023-03-28 14:54:52 -04:00
2023-04-14 01:08:44 -04:00
clone() {
2023-04-21 14:05:16 -04:00
return new HitHealModifier ( this . type , this . pokemonId , this . stackCount ) ;
2023-04-14 01:08:44 -04:00
}
2023-03-28 14:54:52 -04:00
2023-04-14 01:08:44 -04:00
apply ( args : any [ ] ) : boolean {
2023-04-20 19:44:56 -04:00
const pokemon = args [ 0 ] as Pokemon ;
2023-04-09 19:15:21 -04:00
2023-04-14 01:08:44 -04:00
if ( pokemon . turnData . damageDealt && pokemon . getHpRatio ( ) < 1 ) {
2023-04-14 18:21:33 -04:00
const scene = pokemon . scene ;
2023-05-18 11:11:06 -04:00
scene . unshiftPhase ( new PokemonHealPhase ( scene , pokemon . getBattlerIndex ( ) ,
Math . max ( Math . floor ( pokemon . turnData . damageDealt / 8 ) * this . stackCount , 1 ) , getPokemonMessage ( pokemon , ` 's ${ this . type . name } \ nrestored its HP a little! ` ) , true ) ) ;
2023-04-14 01:08:44 -04:00
}
return true ;
2023-03-28 14:54:52 -04:00
}
2023-04-20 20:15:16 -04:00
2023-07-06 19:47:52 -04:00
getMaxStackCount ( ) : integer {
2023-04-23 21:31:06 -04:00
return 4 ;
2023-04-20 20:15:16 -04:00
}
2023-03-28 14:54:52 -04:00
}
2023-04-23 12:35:16 -04:00
export class LevelIncrementBoosterModifier extends PersistentModifier {
constructor ( type : ModifierType , stackCount? : integer ) {
super ( type , stackCount ) ;
}
match ( modifier : Modifier ) {
return modifier instanceof LevelIncrementBoosterModifier ;
}
clone() {
return new LevelIncrementBoosterModifier ( this . type , this . stackCount ) ;
}
shouldApply ( args : any [ ] ) : boolean {
return super . shouldApply ( args ) && args [ 0 ] instanceof Utils . IntegerHolder ;
}
apply ( args : any [ ] ) : boolean {
( args [ 0 ] as Utils . IntegerHolder ) . value += this . getStackCount ( ) ;
return true ;
}
}
2023-04-20 15:46:05 -04:00
export class BerryModifier extends PokemonHeldItemModifier {
public berryType : BerryType ;
public consumed : boolean ;
2023-04-21 14:05:16 -04:00
constructor ( type : ModifierType , pokemonId : integer , berryType : BerryType , stackCount? : integer ) {
super ( type , pokemonId , stackCount ) ;
2023-04-20 15:46:05 -04:00
this . berryType = berryType ;
this . consumed = false ;
}
2023-04-21 14:05:16 -04:00
matchType ( modifier : Modifier ) {
return modifier instanceof BerryModifier && ( modifier as BerryModifier ) . berryType === this . berryType ;
2023-04-20 15:46:05 -04:00
}
clone() {
2023-04-21 14:05:16 -04:00
return new BerryModifier ( this . type , this . pokemonId , this . berryType , this . stackCount ) ;
2023-04-20 15:46:05 -04:00
}
2023-04-28 15:03:42 -04:00
getArgs ( ) : any [ ] {
return super . getArgs ( ) . concat ( this . berryType ) ;
}
2023-04-20 15:46:05 -04:00
shouldApply ( args : any [ ] ) : boolean {
return ! this . consumed && super . shouldApply ( args ) && getBerryPredicate ( this . berryType ) ( args [ 0 ] as Pokemon ) ;
}
apply ( args : any [ ] ) : boolean {
const pokemon = args [ 0 ] as Pokemon ;
const preserve = new Utils . BooleanHolder ( false ) ;
2023-04-20 19:44:56 -04:00
pokemon . scene . applyModifiers ( PreserveBerryModifier , pokemon . isPlayer ( ) , preserve ) ;
2023-04-20 15:46:05 -04:00
getBerryEffectFunc ( this . berryType ) ( pokemon ) ;
if ( ! preserve . value )
this . consumed = true ;
return true ;
}
}
export class PreserveBerryModifier extends PersistentModifier {
2023-04-21 14:05:16 -04:00
constructor ( type : ModifierType , stackCount? : integer ) {
super ( type , stackCount ) ;
2023-04-20 15:46:05 -04:00
}
match ( modifier : Modifier ) {
return modifier instanceof PreserveBerryModifier ;
}
clone() {
2023-04-21 14:05:16 -04:00
return new PreserveBerryModifier ( this . type , this . stackCount ) ;
2023-04-20 15:46:05 -04:00
}
shouldApply ( args : any [ ] ) : boolean {
return super . shouldApply ( args ) && args [ 0 ] instanceof Utils . BooleanHolder ;
}
apply ( args : any [ ] ) : boolean {
if ( ! ( args [ 0 ] as Utils . BooleanHolder ) . value )
2023-10-27 23:18:18 -04:00
( args [ 0 ] as Utils . BooleanHolder ) . value = Utils . randInt ( this . getMaxStackCount ( ) ) < this . getStackCount ( ) ;
2023-04-20 15:46:05 -04:00
return true ;
}
2023-07-06 19:47:52 -04:00
getMaxStackCount ( ) : integer {
2023-10-27 23:18:18 -04:00
return 3 ;
2023-04-20 15:46:05 -04:00
}
}
2023-06-06 08:16:07 -04:00
export class PokemonInstantReviveModifier extends PokemonHeldItemModifier {
constructor ( type : ModifierType , pokemonId : integer , stackCount? : integer ) {
super ( type , pokemonId , stackCount ) ;
}
matchType ( modifier : Modifier ) {
return modifier instanceof PokemonInstantReviveModifier ;
}
clone() {
return new PokemonInstantReviveModifier ( this . type , this . pokemonId , this . stackCount ) ;
}
apply ( args : any [ ] ) : boolean {
const pokemon = args [ 0 ] as Pokemon ;
2023-06-06 10:14:53 -04:00
pokemon . scene . unshiftPhase ( new PokemonHealPhase ( pokemon . scene , pokemon . getBattlerIndex ( ) ,
2023-10-22 10:41:49 -04:00
Math . max ( Math . floor ( pokemon . getMaxHp ( ) / 2 ) , 1 ) , getPokemonMessage ( pokemon , ` was revived \ nby its ${ this . type . name } ! ` ) , false , false , true ) ) ;
pokemon . resetStatus ( ) ;
2023-06-06 08:16:07 -04:00
return true ;
}
getMaxStackCount ( ) : integer {
return 10 ;
}
}
2023-04-09 19:15:21 -04:00
export abstract class ConsumablePokemonModifier extends ConsumableModifier {
public pokemonId : integer ;
2023-03-28 14:54:52 -04:00
constructor ( type : ModifierType , pokemonId : integer ) {
2023-04-09 19:15:21 -04:00
super ( type ) ;
this . pokemonId = pokemonId ;
2023-03-28 14:54:52 -04:00
}
2023-04-09 19:15:21 -04:00
shouldApply ( args : any [ ] ) : boolean {
2023-04-20 19:44:56 -04:00
return args . length && args [ 0 ] instanceof PlayerPokemon && ( this . pokemonId === - 1 || ( args [ 0 ] as PlayerPokemon ) . id === this . pokemonId ) ;
2023-04-09 19:15:21 -04:00
}
getPokemon ( scene : BattleScene ) {
return scene . getParty ( ) . find ( p = > p . id === this . pokemonId ) ;
2023-03-28 14:54:52 -04:00
}
}
export class PokemonHpRestoreModifier extends ConsumablePokemonModifier {
2023-04-09 19:15:21 -04:00
private restorePoints : integer ;
2023-11-05 10:56:09 -05:00
private restorePercent : number ;
2023-04-20 15:46:05 -04:00
public fainted : boolean ;
2023-03-28 14:54:52 -04:00
2023-11-05 10:56:09 -05:00
constructor ( type : ModifierType , pokemonId : integer , restorePoints : integer , restorePercent : number , fainted? : boolean ) {
2023-03-28 14:54:52 -04:00
super ( type , pokemonId ) ;
2023-04-09 19:15:21 -04:00
this . restorePoints = restorePoints ;
2023-10-09 16:57:25 -04:00
this . restorePercent = restorePercent ;
2023-03-30 10:50:46 -04:00
this . fainted = ! ! fainted ;
2023-03-28 14:54:52 -04:00
}
2023-04-09 19:15:21 -04:00
shouldApply ( args : any [ ] ) : boolean {
return super . shouldApply ( args ) && ( this . fainted || ( args . length > 1 && typeof ( args [ 1 ] ) === 'number' ) ) ;
}
2023-03-28 14:54:52 -04:00
apply ( args : any [ ] ) : boolean {
const pokemon = args [ 0 ] as Pokemon ;
2023-04-09 19:15:21 -04:00
if ( ! pokemon . hp === this . fainted ) {
let restorePoints = this . restorePoints ;
if ( ! this . fainted )
restorePoints = Math . floor ( restorePoints * ( args [ 1 ] as number ) ) ;
2023-04-16 18:40:32 -04:00
else
pokemon . resetStatus ( ) ;
2023-10-26 22:01:25 -04:00
pokemon . hp = Math . min ( pokemon . hp + Math . max ( Math . ceil ( Math . max ( Math . floor ( ( this . restorePercent * 0.01 ) * pokemon . getMaxHp ( ) ) , restorePoints ) ) , 1 ) , pokemon . getMaxHp ( ) ) ;
2023-04-09 19:15:21 -04:00
}
2023-03-28 14:54:52 -04:00
return true ;
}
}
2023-04-18 22:23:06 -04:00
export class PokemonStatusHealModifier extends ConsumablePokemonModifier {
constructor ( type : ModifierType , pokemonId : integer ) {
super ( type , pokemonId ) ;
}
apply ( args : any [ ] ) : boolean {
const pokemon = args [ 0 ] as Pokemon ;
pokemon . resetStatus ( ) ;
return true ;
}
}
2023-04-11 11:04:39 -04:00
export abstract class ConsumablePokemonMoveModifier extends ConsumablePokemonModifier {
public moveIndex : integer ;
2023-04-04 21:10:11 -04:00
2023-04-11 11:04:39 -04:00
constructor ( type : ModifierType , pokemonId : integer , moveIndex : integer ) {
2023-04-04 21:10:11 -04:00
super ( type , pokemonId ) ;
2023-04-11 11:04:39 -04:00
this . moveIndex = moveIndex ;
}
}
export class PokemonPpRestoreModifier extends ConsumablePokemonMoveModifier {
private restorePoints : integer ;
constructor ( type : ModifierType , pokemonId : integer , moveIndex : integer , restorePoints : integer ) {
super ( type , pokemonId , moveIndex ) ;
2023-04-04 21:10:11 -04:00
this . restorePoints = restorePoints ;
}
2023-04-11 11:04:39 -04:00
apply ( args : any [ ] ) : boolean {
const pokemon = args [ 0 ] as Pokemon ;
2023-05-06 00:42:01 -04:00
const move = pokemon . getMoveset ( ) [ this . moveIndex ] ;
2023-04-11 11:04:39 -04:00
move . ppUsed = this . restorePoints >= - 1 ? Math . max ( move . ppUsed - this . restorePoints , 0 ) : 0 ;
return true ;
}
}
export class PokemonAllMovePpRestoreModifier extends ConsumablePokemonModifier {
private restorePoints : integer ;
constructor ( type : ModifierType , pokemonId : integer , restorePoints : integer ) {
super ( type , pokemonId ) ;
this . restorePoints = restorePoints ;
2023-04-04 21:10:11 -04:00
}
apply ( args : any [ ] ) : boolean {
const pokemon = args [ 0 ] as Pokemon ;
2023-05-06 00:42:01 -04:00
for ( let move of pokemon . getMoveset ( ) )
2023-04-11 11:04:39 -04:00
move . ppUsed = this . restorePoints >= - 1 ? Math . max ( move . ppUsed - this . restorePoints , 0 ) : 0 ;
2023-04-04 21:10:11 -04:00
return true ;
}
}
2023-04-04 18:28:21 -04:00
export class PokemonLevelIncrementModifier extends ConsumablePokemonModifier {
constructor ( type : ModifierType , pokemonId : integer ) {
super ( type , pokemonId ) ;
}
apply ( args : any [ ] ) : boolean {
const pokemon = args [ 0 ] as PlayerPokemon ;
2023-04-23 12:35:16 -04:00
const levelCount = new Utils . IntegerHolder ( 1 ) ;
pokemon . scene . applyModifiers ( LevelIncrementBoosterModifier , true , levelCount ) ;
pokemon . level += levelCount . value ;
2023-10-28 18:38:22 -04:00
if ( pokemon . level <= pokemon . scene . getMaxExpLevel ( true ) ) {
2023-04-19 14:07:38 -04:00
pokemon . exp = getLevelTotalExp ( pokemon . level , pokemon . species . growthRate ) ;
pokemon . levelExp = 0 ;
}
2023-04-04 18:28:21 -04:00
2023-04-14 18:21:33 -04:00
pokemon . scene . unshiftPhase ( new LevelUpPhase ( pokemon . scene , pokemon . scene . getParty ( ) . indexOf ( pokemon ) , pokemon . level - 1 , pokemon . level ) ) ;
2023-04-04 18:28:21 -04:00
return true ;
}
}
2023-04-08 00:21:44 -04:00
export class TmModifier extends ConsumablePokemonModifier {
2023-04-12 11:57:15 -04:00
constructor ( type : ModifierTypes . TmModifierType , pokemonId : integer ) {
2023-04-08 00:21:44 -04:00
super ( type , pokemonId ) ;
}
apply ( args : any [ ] ) : boolean {
const pokemon = args [ 0 ] as PlayerPokemon ;
2023-04-14 18:21:33 -04:00
pokemon . scene . unshiftPhase ( new LearnMovePhase ( pokemon . scene , pokemon . scene . getParty ( ) . indexOf ( pokemon ) , ( this . type as ModifierTypes . TmModifierType ) . moveId ) ) ;
2023-04-08 00:21:44 -04:00
2023-11-08 17:30:07 -05:00
return true ;
}
}
export class RememberMoveModifier extends ConsumablePokemonModifier {
public levelMoveIndex : integer ;
constructor ( type : ModifierTypes . ModifierType , pokemonId : integer , levelMoveIndex : integer ) {
super ( type , pokemonId ) ;
this . levelMoveIndex = levelMoveIndex ;
}
apply ( args : any [ ] ) : boolean {
const pokemon = args [ 0 ] as PlayerPokemon ;
pokemon . scene . unshiftPhase ( new LearnMovePhase ( pokemon . scene , pokemon . scene . getParty ( ) . indexOf ( pokemon ) , pokemon . getLearnableLevelMoves ( ) [ this . levelMoveIndex ] ) ) ;
2023-04-08 00:21:44 -04:00
return true ;
}
}
2023-04-14 18:21:33 -04:00
export class EvolutionItemModifier extends ConsumablePokemonModifier {
constructor ( type : ModifierTypes . EvolutionItemModifierType , pokemonId : integer ) {
super ( type , pokemonId ) ;
}
apply ( args : any [ ] ) : boolean {
const pokemon = args [ 0 ] as PlayerPokemon ;
const matchingEvolution = pokemonEvolutions [ pokemon . species . speciesId ] . find ( e = > e . item === ( this . type as ModifierTypes . EvolutionItemModifierType ) . evolutionItem
&& ( ! e . condition || e . condition . predicate ( pokemon ) ) ) ;
if ( matchingEvolution ) {
pokemon . scene . unshiftPhase ( new EvolutionPhase ( pokemon . scene , pokemon . scene . getParty ( ) . indexOf ( pokemon ) , matchingEvolution , pokemon . level - 1 ) ) ;
return true ;
}
return false ;
}
}
2023-11-04 00:32:12 -04:00
export class FusePokemonModifier extends ConsumablePokemonModifier {
public fusePokemonId : integer ;
constructor ( type : ModifierType , pokemonId : integer , fusePokemonId : integer ) {
super ( type , pokemonId ) ;
this . fusePokemonId = fusePokemonId ;
}
shouldApply ( args : any [ ] ) : boolean {
return super . shouldApply ( args ) && args [ 1 ] instanceof PlayerPokemon && this . fusePokemonId === ( args [ 1 ] as PlayerPokemon ) . id ;
}
apply ( args : any [ ] ) : boolean {
( args [ 0 ] as PlayerPokemon ) . fuse ( args [ 1 ] as PlayerPokemon ) ;
return true ;
}
}
export class UnfusePokemonModifier extends ConsumablePokemonModifier {
constructor ( type : ModifierType , pokemonId : integer ) {
super ( type , pokemonId ) ;
}
apply ( args : any [ ] ) : boolean {
( args [ 0 ] as PlayerPokemon ) . unfuse ( ) ;
return true ;
}
}
2023-04-28 16:35:03 -04:00
export class MultipleParticipantExpBonusModifier extends PersistentModifier {
2023-04-21 14:05:16 -04:00
constructor ( type : ModifierType , stackCount? : integer ) {
super ( type , stackCount ) ;
2023-04-09 19:15:21 -04:00
}
2023-04-28 16:35:03 -04:00
match ( modifier : Modifier ) : boolean {
return modifier instanceof MultipleParticipantExpBonusModifier ;
2023-04-09 19:15:21 -04:00
}
2023-04-28 16:35:03 -04:00
apply ( _args : any [ ] ) : boolean {
return true ;
2023-04-09 19:15:21 -04:00
}
2023-04-28 16:35:03 -04:00
clone ( ) : MultipleParticipantExpBonusModifier {
return new MultipleParticipantExpBonusModifier ( this . type , this . stackCount ) ;
2023-04-09 19:15:21 -04:00
}
2023-04-28 16:35:03 -04:00
getMaxStackCount ( ) : integer {
return 5 ;
2023-04-09 19:15:21 -04:00
}
}
export class HealingBoosterModifier extends PersistentModifier {
private multiplier : number ;
2023-04-21 14:05:16 -04:00
constructor ( type : ModifierType , multiplier : number , stackCount? : integer ) {
super ( type , stackCount ) ;
2023-04-09 19:15:21 -04:00
this . multiplier = multiplier ;
}
match ( modifier : Modifier ) : boolean {
return modifier instanceof HealingBoosterModifier ;
}
clone ( ) : HealingBoosterModifier {
2023-04-21 14:05:16 -04:00
return new HealingBoosterModifier ( this . type , this . multiplier , this . stackCount ) ;
2023-04-09 19:15:21 -04:00
}
2023-04-28 15:03:42 -04:00
getArgs ( ) : any [ ] {
return [ this . multiplier ] ;
}
2023-04-09 19:15:21 -04:00
apply ( args : any [ ] ) : boolean {
const healingMultiplier = args [ 0 ] as Utils . IntegerHolder ;
2023-07-06 19:47:52 -04:00
healingMultiplier . value = Math . floor ( healingMultiplier . value * ( this . multiplier + ( this . getStackCount ( ) - 1 ) ) ) ;
2023-04-09 19:15:21 -04:00
return true ;
}
2023-04-23 21:31:06 -04:00
2023-07-06 19:47:52 -04:00
getMaxStackCount ( ) : integer {
return 3 ;
2023-04-23 21:31:06 -04:00
}
2023-04-09 19:15:21 -04:00
}
export class ExpBoosterModifier extends PersistentModifier {
2023-03-30 00:13:56 -04:00
private boostMultiplier : integer ;
2023-11-05 10:56:09 -05:00
constructor ( type : ModifierType , boostPercent : number , stackCount? : integer ) {
2023-04-21 14:05:16 -04:00
super ( type , stackCount ) ;
2023-03-30 00:13:56 -04:00
this . boostMultiplier = boostPercent * 0.01 ;
2023-03-28 14:54:52 -04:00
}
2023-04-09 19:15:21 -04:00
match ( modifier : Modifier ) : boolean {
if ( modifier instanceof ExpBoosterModifier ) {
const expModifier = modifier as ExpBoosterModifier ;
return expModifier . boostMultiplier === this . boostMultiplier ;
2023-03-28 14:54:52 -04:00
}
2023-04-09 19:15:21 -04:00
return false ;
}
2023-03-28 14:54:52 -04:00
2023-04-09 19:15:21 -04:00
clone ( ) : ExpBoosterModifier {
2023-04-21 14:05:16 -04:00
return new ExpBoosterModifier ( this . type , this . boostMultiplier * 100 , this . stackCount ) ;
2023-03-28 14:54:52 -04:00
}
2023-04-28 15:03:42 -04:00
getArgs ( ) : any [ ] {
return [ this . boostMultiplier * 100 ] ;
}
2023-03-28 14:54:52 -04:00
apply ( args : any [ ] ) : boolean {
2023-04-09 19:15:21 -04:00
( args [ 0 ] as Utils . NumberHolder ) . value = Math . floor ( ( args [ 0 ] as Utils . NumberHolder ) . value * ( 1 + ( this . getStackCount ( ) * this . boostMultiplier ) ) ) ;
2023-03-30 23:02:35 -04:00
return true ;
}
2023-07-06 19:47:52 -04:00
getStackCount ( ) : integer {
return this . boostMultiplier < 1 ? super . getStackCount ( ) : 10 ;
}
2023-03-30 23:02:35 -04:00
}
2023-04-19 19:55:22 -04:00
export class PokemonExpBoosterModifier extends PokemonHeldItemModifier {
private boostMultiplier : integer ;
2023-11-05 10:56:09 -05:00
constructor ( type : ModifierTypes . PokemonExpBoosterModifierType , pokemonId : integer , boostPercent : number , stackCount? : integer ) {
2023-04-21 14:05:16 -04:00
super ( type , pokemonId , stackCount ) ;
2023-04-19 19:55:22 -04:00
this . boostMultiplier = boostPercent * 0.01 ;
}
2023-04-21 14:05:16 -04:00
matchType ( modifier : Modifier ) : boolean {
2023-04-19 19:55:22 -04:00
if ( modifier instanceof PokemonExpBoosterModifier ) {
const pokemonExpModifier = modifier as PokemonExpBoosterModifier ;
2023-04-21 14:05:16 -04:00
return pokemonExpModifier . boostMultiplier === this . boostMultiplier ;
2023-04-19 19:55:22 -04:00
}
return false ;
}
clone ( ) : PersistentModifier {
2023-04-21 14:05:16 -04:00
return new PokemonExpBoosterModifier ( this . type as ModifierTypes . PokemonExpBoosterModifierType , this . pokemonId , this . boostMultiplier * 100 , this . stackCount ) ;
2023-04-19 19:55:22 -04:00
}
2023-04-28 15:03:42 -04:00
getArgs ( ) : any [ ] {
return super . getArgs ( ) . concat ( this . boostMultiplier * 100 ) ;
}
2023-04-19 19:55:22 -04:00
shouldApply ( args : any [ ] ) : boolean {
return super . shouldApply ( args ) && args . length === 2 && args [ 1 ] instanceof Utils . NumberHolder ;
}
apply ( args : any [ ] ) : boolean {
( args [ 1 ] as Utils . NumberHolder ) . value = Math . floor ( ( args [ 1 ] as Utils . NumberHolder ) . value * ( 1 + ( this . getStackCount ( ) * this . boostMultiplier ) ) ) ;
return true ;
}
}
2023-04-09 19:15:21 -04:00
export class ExpShareModifier extends PersistentModifier {
2023-04-21 14:05:16 -04:00
constructor ( type : ModifierType , stackCount? : integer ) {
super ( type , stackCount ) ;
2023-03-30 23:02:35 -04:00
}
2023-03-28 14:54:52 -04:00
2023-04-19 00:35:06 -04:00
match ( modifier : Modifier ) : boolean {
return modifier instanceof ExpShareModifier ;
}
2023-04-09 19:15:21 -04:00
clone ( ) : ExpShareModifier {
2023-04-21 14:05:16 -04:00
return new ExpShareModifier ( this . type , this . stackCount ) ;
2023-04-09 19:15:21 -04:00
}
2023-11-10 21:11:36 -05:00
apply ( _args : any [ ] ) : boolean {
return true ;
}
2023-03-30 23:02:35 -04:00
getMaxStackCount ( ) : integer {
return 5 ;
}
2023-03-28 14:54:52 -04:00
}
2023-04-19 22:51:46 -04:00
export class ExpBalanceModifier extends PersistentModifier {
2023-04-21 14:05:16 -04:00
constructor ( type : ModifierType , stackCount? : integer ) {
super ( type , stackCount ) ;
2023-04-19 22:51:46 -04:00
}
match ( modifier : Modifier ) : boolean {
return modifier instanceof ExpBalanceModifier ;
}
2023-11-10 21:11:36 -05:00
clone ( ) : ExpBalanceModifier {
return new ExpBalanceModifier ( this . type , this . stackCount ) ;
}
2023-04-19 22:51:46 -04:00
apply ( _args : any [ ] ) : boolean {
return true ;
}
2023-11-10 21:11:36 -05:00
getMaxStackCount ( ) : integer {
return 1 ;
}
}
export class MoneyMultiplierModifier extends PersistentModifier {
constructor ( type : ModifierType , stackCount? : integer ) {
super ( type , stackCount ) ;
}
match ( modifier : Modifier ) : boolean {
return modifier instanceof MoneyMultiplierModifier ;
}
clone ( ) : MoneyMultiplierModifier {
return new MoneyMultiplierModifier ( this . type , this . stackCount ) ;
}
apply ( args : any [ ] ) : boolean {
( args [ 0 ] as Utils . IntegerHolder ) . value += Math . floor ( ( args [ 0 ] as Utils . IntegerHolder ) . value * 0.2 * this . getStackCount ( ) ) ;
return true ;
2023-04-19 22:51:46 -04:00
}
getMaxStackCount ( ) : integer {
2023-11-10 21:11:36 -05:00
return 5 ;
}
}
export class DamageMoneyRewardModifier extends PokemonHeldItemModifier {
constructor ( type : ModifierType , pokemonId : integer , stackCount? : integer ) {
super ( type , pokemonId , stackCount ) ;
}
matchType ( modifier : Modifier ) : boolean {
return modifier instanceof DamageMoneyRewardModifier ;
}
clone ( ) : DamageMoneyRewardModifier {
return new DamageMoneyRewardModifier ( this . type , this . pokemonId , this . stackCount ) ;
}
apply ( args : any [ ] ) : boolean {
const scene = ( args [ 0 ] as Pokemon ) . scene ;
const moneyAmount = new Utils . IntegerHolder ( Math . floor ( ( args [ 1 ] as Utils . IntegerHolder ) . value * ( 0.2 * this . getStackCount ( ) ) ) ) ;
scene . applyModifiers ( MoneyMultiplierModifier , true , moneyAmount ) ;
scene . money += moneyAmount . value ;
scene . updateMoneyText ( ) ;
2023-11-12 00:31:40 -05:00
scene . validateAchvs ( MoneyAchv ) ;
2023-11-10 21:11:36 -05:00
return true ;
}
getMaxStackCount ( ) : integer {
return 5 ;
}
}
export class MoneyInterestModifier extends PersistentModifier {
constructor ( type : ModifierType , stackCount? : integer ) {
super ( type , stackCount ) ;
}
match ( modifier : Modifier ) : boolean {
return modifier instanceof MoneyInterestModifier ;
}
apply ( args : any [ ] ) : boolean {
const scene = args [ 0 ] as BattleScene ;
const interestAmount = Math . floor ( scene . money * 0.2 * this . getStackCount ( ) ) ;
scene . money += interestAmount ;
scene . updateMoneyText ( ) ;
2023-11-12 00:31:40 -05:00
scene . validateAchvs ( MoneyAchv ) ;
2023-11-10 21:11:36 -05:00
scene . queueMessage ( ` You received interest of ₽ ${ interestAmount . toLocaleString ( 'en-US' ) } \ nfrom the ${ this . type . name } ! ` , null , true ) ;
return true ;
}
clone ( ) : MoneyInterestModifier {
return new MoneyInterestModifier ( this . type , this . stackCount ) ;
}
getMaxStackCount ( ) : integer {
return 5 ;
2023-04-19 22:51:46 -04:00
}
}
2023-10-29 22:18:02 -04:00
export class HiddenAbilityRateBoosterModifier extends PersistentModifier {
constructor ( type : ModifierType , stackCount? : integer ) {
super ( type , stackCount ) ;
}
match ( modifier : Modifier ) : boolean {
return modifier instanceof HiddenAbilityRateBoosterModifier ;
}
clone ( ) : HiddenAbilityRateBoosterModifier {
return new HiddenAbilityRateBoosterModifier ( this . type , this . stackCount ) ;
}
apply ( args : any [ ] ) : boolean {
( args [ 0 ] as Utils . IntegerHolder ) . value *= Math . pow ( 2 , - 1 - this . getStackCount ( ) ) ;
return true ;
}
getMaxStackCount ( ) : integer {
return 4 ;
}
}
2023-04-09 19:15:21 -04:00
export class ShinyRateBoosterModifier extends PersistentModifier {
2023-04-21 14:05:16 -04:00
constructor ( type : ModifierType , stackCount? : integer ) {
super ( type , stackCount ) ;
2023-03-28 14:54:52 -04:00
}
2023-04-09 19:15:21 -04:00
match ( modifier : Modifier ) : boolean {
return modifier instanceof ShinyRateBoosterModifier ;
}
2023-03-28 14:54:52 -04:00
2023-04-09 19:15:21 -04:00
clone ( ) : ShinyRateBoosterModifier {
2023-04-21 14:05:16 -04:00
return new ShinyRateBoosterModifier ( this . type , this . stackCount ) ;
2023-03-28 14:54:52 -04:00
}
apply ( args : any [ ] ) : boolean {
2023-10-28 22:08:06 -04:00
( args [ 0 ] as Utils . IntegerHolder ) . value /= Math . pow ( 2 , - 3 - this . getStackCount ( ) ) ;
2023-03-28 14:54:52 -04:00
return true ;
}
2023-03-30 23:02:35 -04:00
getMaxStackCount ( ) : integer {
2023-10-28 22:08:06 -04:00
return 4 ;
2023-03-30 23:02:35 -04:00
}
2023-03-28 14:54:52 -04:00
}
2023-04-28 19:26:41 -04:00
export class SwitchEffectTransferModifier extends PokemonHeldItemModifier {
constructor ( type : ModifierType , pokemonId : integer , stackCount? : integer ) {
super ( type , pokemonId , stackCount ) ;
}
matchType ( modifier : Modifier ) : boolean {
return modifier instanceof SwitchEffectTransferModifier ;
}
clone ( ) : SwitchEffectTransferModifier {
return new SwitchEffectTransferModifier ( this . type , this . pokemonId , this . stackCount ) ;
}
apply ( args : any [ ] ) : boolean {
return true ;
}
getMaxStackCount ( ) : integer {
return 1 ;
}
}
2023-05-05 16:55:46 -04:00
export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier {
2023-04-23 10:24:22 -04:00
constructor ( type : ModifierType , pokemonId : integer , stackCount? : integer ) {
super ( type , pokemonId , stackCount ) ;
2023-04-21 15:45:48 -04:00
}
apply ( args : any [ ] ) : boolean {
2023-04-23 10:24:22 -04:00
const pokemon = args [ 0 ] as Pokemon ;
2023-05-19 16:13:11 -04:00
const opponents = pokemon . getOpponents ( ) ;
if ( ! opponents . length )
2023-04-29 01:40:24 -04:00
return false ;
2023-04-23 10:24:22 -04:00
2023-05-19 16:13:11 -04:00
const targetPokemon = opponents [ Utils . randInt ( opponents . length ) ] ;
2023-05-05 16:55:46 -04:00
const transferredItemCount = this . getTransferredItemCount ( ) ;
if ( ! transferredItemCount )
return false ;
2023-05-31 19:54:57 -04:00
const withinParty = pokemon . isPlayer ( ) === targetPokemon . isPlayer ( ) ;
2023-04-23 10:24:22 -04:00
const transferredModifierTypes : ModifierTypes.ModifierType [ ] = [ ] ;
const itemModifiers = pokemon . scene . findModifiers ( m = > m instanceof PokemonHeldItemModifier
2023-05-31 19:54:57 -04:00
&& ( m as PokemonHeldItemModifier ) . pokemonId === targetPokemon . id && m . getTransferrable ( withinParty ) , targetPokemon . isPlayer ( ) ) as PokemonHeldItemModifier [ ] ;
2023-04-23 10:24:22 -04:00
2023-05-05 16:55:46 -04:00
for ( let i = 0 ; i < transferredItemCount ; i ++ ) {
2023-04-23 10:24:22 -04:00
if ( ! itemModifiers . length )
break ;
const randItemIndex = Utils . randInt ( itemModifiers . length ) ;
const randItem = itemModifiers [ randItemIndex ] ;
if ( pokemon . scene . tryTransferHeldItemModifier ( randItem , pokemon , false , false ) ) {
transferredModifierTypes . push ( randItem . type ) ;
itemModifiers . splice ( randItemIndex , 1 ) ;
}
}
2023-04-21 15:45:48 -04:00
2023-04-23 10:24:22 -04:00
for ( let mt of transferredModifierTypes )
2023-05-05 16:55:46 -04:00
pokemon . scene . queueMessage ( this . getTransferMessage ( pokemon , targetPokemon , mt ) ) ;
2023-04-21 15:45:48 -04:00
2023-04-23 10:24:22 -04:00
return ! ! transferredModifierTypes . length ;
2023-04-21 15:45:48 -04:00
}
2023-05-05 16:55:46 -04:00
abstract getTransferredItemCount ( ) : integer
abstract getTransferMessage ( pokemon : Pokemon , targetPokemon : Pokemon , item : ModifierTypes.ModifierType ) : string
}
export class TurnHeldItemTransferModifier extends HeldItemTransferModifier {
constructor ( type : ModifierType , pokemonId : integer , stackCount? : integer ) {
super ( type , pokemonId , stackCount ) ;
}
matchType ( modifier : Modifier ) : boolean {
return modifier instanceof TurnHeldItemTransferModifier ;
}
clone ( ) : TurnHeldItemTransferModifier {
return new TurnHeldItemTransferModifier ( this . type , this . pokemonId , this . stackCount ) ;
}
2023-05-31 19:54:57 -04:00
getTransferrable ( withinParty : boolean ) {
return withinParty ;
}
2023-05-05 16:55:46 -04:00
getTransferredItemCount ( ) : integer {
return this . getStackCount ( ) ;
}
getTransferMessage ( pokemon : Pokemon , targetPokemon : Pokemon , item : ModifierTypes.ModifierType ) : string {
return getPokemonMessage ( targetPokemon , ` 's ${ item . name } was absorbed \ nby ${ pokemon . name } 's ${ this . type . name } ! ` ) ;
}
getMaxStackCount ( ) : integer {
return 3 ;
}
}
2023-11-10 21:30:11 -05:00
export class ContactHeldItemTransferChanceModifier extends HeldItemTransferModifier {
2023-05-05 16:55:46 -04:00
private chance : number ;
2023-11-05 10:56:09 -05:00
constructor ( type : ModifierType , pokemonId : integer , chancePercent : number , stackCount? : integer ) {
2023-05-05 16:55:46 -04:00
super ( type , pokemonId , stackCount ) ;
this . chance = chancePercent / 100 ;
}
matchType ( modifier : Modifier ) : boolean {
2023-11-10 21:30:11 -05:00
return modifier instanceof ContactHeldItemTransferChanceModifier ;
2023-05-05 16:55:46 -04:00
}
2023-11-10 21:30:11 -05:00
clone ( ) : ContactHeldItemTransferChanceModifier {
return new ContactHeldItemTransferChanceModifier ( this . type , this . pokemonId , this . chance * 100 , this . stackCount ) ;
2023-05-05 16:55:46 -04:00
}
getArgs ( ) : any [ ] {
return super . getArgs ( ) . concat ( this . chance * 100 ) ;
}
getTransferredItemCount ( ) : integer {
return Math . random ( ) < ( this . chance * this . getStackCount ( ) ) ? 1 : 0 ;
}
getTransferMessage ( pokemon : Pokemon , targetPokemon : Pokemon , item : ModifierTypes.ModifierType ) : string {
return getPokemonMessage ( targetPokemon , ` 's ${ item . name } was snatched \ nby ${ pokemon . name } 's ${ this . type . name } ! ` ) ;
}
2023-07-06 19:47:52 -04:00
getMaxStackCount ( ) : integer {
2023-05-05 16:55:46 -04:00
return 5 ;
}
2023-04-21 15:45:48 -04:00
}
2023-11-12 12:49:06 -05:00
export class IvScannerModifier extends PersistentModifier {
constructor ( type : ModifierType , stackCount? : integer ) {
super ( type , stackCount ) ;
}
match ( modifier : Modifier ) : boolean {
return modifier instanceof IvScannerModifier ;
}
clone ( ) : IvScannerModifier {
return new IvScannerModifier ( this . type , this . stackCount ) ;
}
apply ( args : any [ ] ) : boolean {
return true ;
}
getMaxStackCount ( ) : integer {
return 5 ;
}
}
2023-04-09 19:15:21 -04:00
export class ExtraModifierModifier extends PersistentModifier {
2023-04-21 14:05:16 -04:00
constructor ( type : ModifierType , stackCount? : integer ) {
super ( type , stackCount ) ;
2023-03-30 10:50:46 -04:00
}
2023-04-20 01:07:39 -04:00
match ( modifier : Modifier ) : boolean {
return modifier instanceof ExtraModifierModifier ;
}
2023-04-09 19:15:21 -04:00
clone ( ) : ExtraModifierModifier {
2023-04-21 14:05:16 -04:00
return new ExtraModifierModifier ( this . type , this . stackCount ) ;
2023-04-09 19:15:21 -04:00
}
2023-03-30 10:50:46 -04:00
apply ( args : any [ ] ) : boolean {
2023-04-09 19:15:21 -04:00
( args [ 0 ] as Utils . IntegerHolder ) . value += this . getStackCount ( ) ;
2023-03-30 10:50:46 -04:00
return true ;
}
2023-04-23 01:37:58 -04:00
2023-04-28 19:26:41 -04:00
getMaxStackCount ( ) : integer {
2023-04-23 01:37:58 -04:00
return 3 ;
}
2023-10-28 13:24:57 -04:00
}
2023-11-05 10:56:09 -05:00
export abstract class EnemyPersistentModifier extends PersistentModifier {
2023-10-28 13:24:57 -04:00
constructor ( type : ModifierType , stackCount? : integer ) {
super ( type , stackCount ) ;
}
2023-10-29 16:05:17 -04:00
2023-11-05 10:56:09 -05:00
getMaxStackCount ( ) : integer {
2023-10-31 17:38:44 -04:00
return this . type . tier ? 1 : 5 ;
2023-10-29 16:05:17 -04:00
}
2023-10-28 13:24:57 -04:00
}
2023-11-05 10:56:09 -05:00
abstract class EnemyDamageMultiplierModifier extends EnemyPersistentModifier {
protected damageMultiplier : number ;
2023-10-29 17:58:54 -04:00
2023-11-05 10:56:09 -05:00
constructor ( type : ModifierType , damageMultiplier : number , stackCount? : integer ) {
2023-10-28 13:24:57 -04:00
super ( type , stackCount ) ;
2023-10-29 17:58:54 -04:00
2023-11-05 10:56:09 -05:00
this . damageMultiplier = damageMultiplier ;
}
apply ( args : any [ ] ) : boolean {
( args [ 0 ] as Utils . NumberHolder ) . value = Math . floor ( ( args [ 0 ] as Utils . NumberHolder ) . value * Math . pow ( this . damageMultiplier , this . getStackCount ( ) ) ) ;
return true ;
}
getMaxStackCount ( ) : integer {
return 99 ;
}
}
export class EnemyDamageBoosterModifier extends EnemyDamageMultiplierModifier {
constructor ( type : ModifierType , boostPercent : number , stackCount? : integer ) {
super ( type , 1 + ( ( boostPercent || 20 ) * 0.01 ) , stackCount ) ;
2023-10-28 13:24:57 -04:00
}
match ( modifier : Modifier ) : boolean {
2023-10-29 17:58:54 -04:00
return modifier instanceof EnemyDamageBoosterModifier && modifier . damageMultiplier === this . damageMultiplier ;
2023-10-28 13:24:57 -04:00
}
clone ( ) : EnemyDamageBoosterModifier {
2023-10-29 17:58:54 -04:00
return new EnemyDamageBoosterModifier ( this . type , ( this . damageMultiplier - 1 ) * 100 , this . stackCount ) ;
2023-10-28 13:24:57 -04:00
}
2023-10-31 17:38:44 -04:00
getArgs ( ) : any [ ] {
return [ ( this . damageMultiplier - 1 ) * 100 ] ;
}
2023-10-28 13:24:57 -04:00
}
2023-11-05 10:56:09 -05:00
export class EnemyDamageReducerModifier extends EnemyDamageMultiplierModifier {
constructor ( type : ModifierType , reductionPercent : number , stackCount? : integer ) {
super ( type , 1 - ( ( reductionPercent || 10 ) * 0.01 ) , stackCount ) ;
2023-10-28 13:24:57 -04:00
}
match ( modifier : Modifier ) : boolean {
2023-10-29 17:58:54 -04:00
return modifier instanceof EnemyDamageReducerModifier && modifier . damageMultiplier === this . damageMultiplier ;
2023-10-28 13:24:57 -04:00
}
clone ( ) : EnemyDamageReducerModifier {
2023-10-29 17:58:54 -04:00
return new EnemyDamageReducerModifier ( this . type , ( 1 - this . damageMultiplier ) * 100 , this . stackCount ) ;
2023-10-28 13:24:57 -04:00
}
2023-10-31 17:38:44 -04:00
getArgs ( ) : any [ ] {
return [ ( 1 - this . damageMultiplier ) * 100 ] ;
}
2023-10-28 13:24:57 -04:00
}
2023-11-05 10:56:09 -05:00
export class EnemyTurnHealModifier extends EnemyPersistentModifier {
private healPercent : number ;
2023-10-29 17:58:54 -04:00
2023-11-05 10:56:09 -05:00
constructor ( type : ModifierType , healPercent : number , stackCount? : integer ) {
2023-10-29 17:58:54 -04:00
super ( type , stackCount ) ;
2023-10-31 17:38:44 -04:00
this . healPercent = healPercent || 10 ;
2023-10-29 17:58:54 -04:00
}
match ( modifier : Modifier ) : boolean {
return modifier instanceof EnemyTurnHealModifier && modifier . healPercent === this . healPercent ;
}
clone ( ) : EnemyTurnHealModifier {
return new EnemyTurnHealModifier ( this . type , this . healPercent , this . stackCount ) ;
}
2023-10-31 17:38:44 -04:00
getArgs ( ) : any [ ] {
return [ this . healPercent ] ;
}
2023-10-29 17:58:54 -04:00
apply ( args : any [ ] ) : boolean {
const pokemon = args [ 0 ] as Pokemon ;
if ( pokemon . getHpRatio ( ) < 1 ) {
const scene = pokemon . scene ;
scene . unshiftPhase ( new PokemonHealPhase ( scene , pokemon . getBattlerIndex ( ) ,
Math . max ( Math . floor ( pokemon . getMaxHp ( ) / ( 100 / this . healPercent ) ) * this . stackCount , 1 ) , getPokemonMessage ( pokemon , ` \ nrestored some HP! ` ) , true ) ) ;
return true ;
}
return false ;
}
2023-11-05 10:56:09 -05:00
getMaxStackCount ( ) : integer {
return 20 ;
}
2023-10-29 17:58:54 -04:00
}
2023-11-05 10:56:09 -05:00
export class EnemyAttackStatusEffectChanceModifier extends EnemyPersistentModifier {
2023-10-28 13:24:57 -04:00
public effect : StatusEffect ;
2023-10-29 16:05:17 -04:00
private chance : number ;
2023-10-28 13:24:57 -04:00
2023-11-05 10:56:09 -05:00
constructor ( type : ModifierType , effect : StatusEffect , chancePercent : number , stackCount? : integer ) {
2023-10-28 13:24:57 -04:00
super ( type , stackCount ) ;
this . effect = effect ;
2023-10-31 17:38:44 -04:00
this . chance = ( chancePercent || 10 ) / 100 ;
2023-10-28 13:24:57 -04:00
}
match ( modifier : Modifier ) : boolean {
2023-10-29 17:58:54 -04:00
return modifier instanceof EnemyAttackStatusEffectChanceModifier && modifier . effect === this . effect && modifier . chance === this . chance ;
2023-10-28 13:24:57 -04:00
}
2023-10-29 17:58:54 -04:00
clone ( ) : EnemyAttackStatusEffectChanceModifier {
return new EnemyAttackStatusEffectChanceModifier ( this . type , this . effect , this . chance * 100 , this . stackCount ) ;
2023-10-28 13:24:57 -04:00
}
2023-10-31 17:38:44 -04:00
getArgs ( ) : any [ ] {
return [ this . effect , this . chance * 100 ] ;
}
2023-10-28 13:24:57 -04:00
apply ( args : any [ ] ) : boolean {
const target = ( args [ 0 ] as Pokemon ) ;
2023-10-31 17:38:44 -04:00
if ( Math . random ( ) < this . chance * this . getStackCount ( ) ) {
2023-10-28 13:24:57 -04:00
target . scene . unshiftPhase ( new ObtainStatusEffectPhase ( target . scene , target . getBattlerIndex ( ) , this . effect ) ) ;
2023-10-29 16:05:17 -04:00
return true ;
}
2023-10-28 13:24:57 -04:00
2023-10-29 16:05:17 -04:00
return false ;
2023-10-28 13:24:57 -04:00
}
2023-10-29 16:05:17 -04:00
}
2023-10-28 13:24:57 -04:00
2023-11-05 10:56:09 -05:00
export class EnemyStatusEffectHealChanceModifier extends EnemyPersistentModifier {
2023-10-29 17:58:54 -04:00
private chance : number ;
2023-11-05 10:56:09 -05:00
constructor ( type : ModifierType , chancePercent : number , stackCount? : integer ) {
2023-10-29 17:58:54 -04:00
super ( type , stackCount ) ;
2023-10-31 17:38:44 -04:00
this . chance = ( chancePercent || 10 ) / 100 ;
2023-10-29 17:58:54 -04:00
}
match ( modifier : Modifier ) : boolean {
return modifier instanceof EnemyStatusEffectHealChanceModifier && modifier . chance === this . chance ;
}
clone ( ) : EnemyStatusEffectHealChanceModifier {
return new EnemyStatusEffectHealChanceModifier ( this . type , this . chance * 100 , this . stackCount ) ;
}
2023-10-31 17:38:44 -04:00
getArgs ( ) : any [ ] {
return [ this . chance * 100 ] ;
}
2023-10-29 17:58:54 -04:00
apply ( args : any [ ] ) : boolean {
const target = ( args [ 0 ] as Pokemon ) ;
2023-10-31 17:38:44 -04:00
if ( target . status && Math . random ( ) < this . chance * this . getStackCount ( ) ) {
2023-10-29 17:58:54 -04:00
target . scene . queueMessage ( getPokemonMessage ( target , ` was cured of its \ n ${ getStatusEffectDescriptor ( target . status . effect ) } ! ` ) ) ;
target . resetStatus ( ) ;
target . updateInfo ( ) ;
return true ;
}
return false ;
}
}
2023-11-05 10:56:09 -05:00
export class EnemyInstantReviveChanceModifier extends EnemyPersistentModifier {
2023-10-29 16:05:17 -04:00
public fullHeal : boolean ;
private chance : number ;
2023-11-05 10:56:09 -05:00
constructor ( type : ModifierType , healFull : boolean , chancePercent : number , stackCount? : integer ) {
2023-10-29 16:05:17 -04:00
super ( type , stackCount ) ;
this . fullHeal = healFull ;
2023-10-31 17:38:44 -04:00
this . chance = ( chancePercent || healFull ? 2 : 5 ) / 100 ;
2023-10-29 16:05:17 -04:00
}
2023-10-31 14:47:12 -04:00
match ( modifier : Modifier ) {
2023-10-29 17:58:54 -04:00
return modifier instanceof EnemyInstantReviveChanceModifier && modifier . fullHeal === this . fullHeal && modifier . chance === this . chance ;
2023-10-29 16:05:17 -04:00
}
clone() {
2023-10-29 17:58:54 -04:00
return new EnemyInstantReviveChanceModifier ( this . type , this . fullHeal , this . chance * 100 , this . stackCount ) ;
2023-10-29 16:05:17 -04:00
}
2023-10-31 17:38:44 -04:00
getArgs ( ) : any [ ] {
return [ this . fullHeal , this . chance * 100 ] ;
}
2023-10-29 16:05:17 -04:00
apply ( args : any [ ] ) : boolean {
2023-10-31 17:38:44 -04:00
if ( Math . random ( ) >= this . chance * this . getStackCount ( ) )
2023-10-29 16:05:17 -04:00
return false ;
const pokemon = args [ 0 ] as Pokemon ;
pokemon . scene . unshiftPhase ( new PokemonHealPhase ( pokemon . scene , pokemon . getBattlerIndex ( ) ,
Math . max ( Math . floor ( pokemon . getMaxHp ( ) / ( this . fullHeal ? 1 : 2 ) ) , 1 ) , getPokemonMessage ( pokemon , ` was revived \ nby its ${ this . type . name } ! ` ) , false , false , true ) ) ;
pokemon . resetStatus ( ) ;
return true ;
2023-10-28 13:24:57 -04:00
}
2023-11-05 10:56:09 -05:00
getMaxStackCount ( ) : integer {
return 10 ;
}
2023-03-28 14:54:52 -04:00
}