2023-04-12 11:57:15 -04:00
import * as ModifierTypes from './modifier-type' ;
2024-03-09 21:57:33 -05:00
import { LearnMovePhase , LevelUpPhase , PokemonHealPhase } from "../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" ;
2024-02-29 20:08:50 -05:00
import Pokemon , { PlayerPokemon } from "../field/pokemon" ;
2023-04-20 15:46:05 -04:00
import { Stat } from "../data/pokemon-stat" ;
2023-12-07 17:43:56 -05:00
import { addTextObject , 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' ;
2024-03-09 21:57:33 -05:00
import { StatusEffect , getStatusEffectHealText } from '../data/status-effect' ;
2024-02-18 22:21:57 -05:00
import { MoneyAchv , achvs } from '../system/achv' ;
2023-12-19 23:51:48 -05:00
import { VoucherType } from '../system/voucher' ;
2023-12-23 01:21:01 -05:00
import { PreventBerryUseAbAttr , applyAbAttrs } from '../data/ability' ;
2024-01-09 23:34:43 -05:00
import { FormChangeItem , SpeciesFormChangeItemTrigger } from '../data/pokemon-forms' ;
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' , ( ) = > {
2024-01-18 17:22:18 -05:00
( this . scene as BattleScene ) . ui . showTooltip ( modifier . type . name , modifier . type . getDescription ( this . scene as BattleScene ) ) ;
2023-11-02 00:55:20 -04:00
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
} ) ;
2023-12-16 10:15:25 -05:00
for ( let icon of this . getAll ( ) )
this . sendToBack ( icon ) ;
2023-10-31 21:43:22 -04:00
this . modifierCache = modifiers ;
}
updateModifierOverflowVisibility ( ignoreLimit : boolean ) {
2024-02-21 21:31:56 -05:00
for ( let modifier of this . getAll ( ) . map ( m = > m as Phaser . GameObjects . Container ) . slice ( 0 , this . getAll ( ) . length - iconOverflowIndex ) )
2023-10-31 21:43:22 -04:00
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 ;
}
2023-12-09 00:33:29 -05:00
add ( modifiers : PersistentModifier [ ] , virtual : boolean , scene : BattleScene ) : boolean {
2023-04-09 19:15:21 -04:00
for ( let modifier of modifiers ) {
2023-04-20 11:29:26 -04:00
if ( this . match ( modifier ) )
2023-12-09 00:33:29 -05:00
return modifier . incrementStack ( scene , 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-12-09 00:33:29 -05:00
incrementStack ( scene : BattleScene , amount : integer , virtual : boolean ) : boolean {
if ( this . getStackCount ( ) + amount <= this . getMaxStackCount ( scene ) ) {
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
}
2023-12-09 00:33:29 -05:00
abstract getMaxStackCount ( scene : BattleScene , forThreshold? : boolean ) : integer
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 {
2023-12-09 00:33:29 -05:00
if ( this . getMaxStackCount ( scene ) === 1 || ( virtual && ! this . virtualStackCount ) )
2023-03-28 14:54:52 -04:00
return null ;
2023-12-09 00:33:29 -05:00
const isStackMax = this . getStackCount ( ) >= this . getMaxStackCount ( scene ) ;
2023-04-09 19:15:21 -04:00
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-12-19 23:51:48 -05:00
export class AddVoucherModifier extends ConsumableModifier {
private voucherType : VoucherType ;
private count : integer ;
constructor ( type : ModifierType , voucherType : VoucherType , count : integer ) {
super ( type ) ;
this . voucherType = voucherType ;
this . count = count ;
}
apply ( args : any [ ] ) : boolean {
const voucherCounts = ( args [ 0 ] as BattleScene ) . gameData . voucherCounts ;
voucherCounts [ this . voucherType ] += this . count ;
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 ;
}
2024-02-17 00:40:03 -05:00
lapse ( args : any [ ] ) : boolean {
2023-06-01 11:22:34 -04:00
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 ;
}
2023-12-09 00:33:29 -05:00
2024-02-17 00:40:03 -05:00
getBattlesLeft ( ) : integer {
return this . battlesLeft ;
}
2023-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene , forThreshold? : boolean ) : number {
return 99 ;
}
2023-06-01 11:22:34 -04:00
}
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-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene ) : integer {
2023-04-26 19:19:39 -04:00
return 1 ;
}
}
2023-12-07 17:43:56 -05:00
export class MegaEvolutionAccessModifier extends PersistentModifier {
constructor ( type : ModifierType , stackCount? : integer ) {
super ( type , stackCount ) ;
}
clone ( ) : MegaEvolutionAccessModifier {
return new MegaEvolutionAccessModifier ( this . type , this . stackCount ) ;
}
apply ( args : any [ ] ) : boolean {
return true ;
}
2023-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene ) : integer {
2023-12-07 17:43:56 -05:00
return 1 ;
}
}
2024-02-13 23:21:44 -06:00
export class GigantamaxAccessModifier extends PersistentModifier {
constructor ( type : ModifierType , stackCount? : integer ) {
super ( type , stackCount ) ;
}
clone ( ) : GigantamaxAccessModifier {
return new GigantamaxAccessModifier ( this . type , this . stackCount ) ;
}
apply ( args : any [ ] ) : boolean {
return true ;
}
getMaxStackCount ( scene : BattleScene ) : integer {
return 1 ;
}
}
2024-02-17 00:40:03 -05:00
export class TerastallizeAccessModifier extends PersistentModifier {
constructor ( type : ModifierType , stackCount? : integer ) {
super ( type , stackCount ) ;
}
clone ( ) : TerastallizeAccessModifier {
return new TerastallizeAccessModifier ( this . type , this . stackCount ) ;
}
apply ( args : any [ ] ) : boolean {
return true ;
}
getMaxStackCount ( scene : BattleScene ) : integer {
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-12-08 19:43:14 -05:00
const pokemonIcon = scene . add . sprite ( - 2 , 10 , iconAtlasKey ) ;
2023-12-07 00:52:20 -05: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-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene , forThreshold? : boolean ) : integer {
const pokemon = this . getPokemon ( scene ) ;
if ( pokemon . isPlayer ( ) && forThreshold )
return scene . getParty ( ) . map ( p = > this . getMaxHeldItemCount ( p ) ) . reduce ( ( stackCount : integer , maxStackCount : integer ) = > Math . max ( stackCount , maxStackCount ) , 0 ) ;
return this . getMaxHeldItemCount ( pokemon ) ;
}
abstract getMaxHeldItemCount ( pokemon : Pokemon ) : integer
2023-03-28 14:54:52 -04:00
}
2024-02-17 00:40:03 -05:00
export abstract class LapsingPokemonHeldItemModifier extends PokemonHeldItemModifier {
protected battlesLeft : integer ;
constructor ( type : ModifierTypes . ModifierType , pokemonId : integer , battlesLeft? : integer , stackCount? : integer ) {
super ( type , pokemonId , stackCount ) ;
this . battlesLeft = battlesLeft ;
}
lapse ( args : any [ ] ) : boolean {
return ! ! -- this . battlesLeft ;
}
getIcon ( scene : BattleScene , forSummary? : boolean ) : Phaser . GameObjects . Container {
const container = super . getIcon ( scene , forSummary ) ;
if ( this . getPokemon ( scene ) . isPlayer ( ) ) {
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 ;
}
getBattlesLeft ( ) : integer {
return this . battlesLeft ;
}
getMaxStackCount ( scene : BattleScene , forThreshold? : boolean ) : number {
return 1 ;
}
}
export class TerastallizeModifier extends LapsingPokemonHeldItemModifier {
public teraType : Type ;
constructor ( type : ModifierTypes . TerastallizeModifierType , pokemonId : integer , teraType : Type , battlesLeft? : integer , stackCount? : integer ) {
super ( type , pokemonId , battlesLeft || 10 , stackCount ) ;
this . teraType = teraType ;
}
matchType ( modifier : Modifier ) : boolean {
if ( modifier instanceof TerastallizeModifier && modifier . teraType === this . teraType )
return true ;
return false ;
}
clone ( ) : TerastallizeModifier {
return new TerastallizeModifier ( this . type as ModifierTypes . TerastallizeModifierType , this . pokemonId , this . teraType , this . battlesLeft , this . stackCount ) ;
}
getArgs ( ) : any [ ] {
return [ this . pokemonId , this . teraType , this . battlesLeft ] ;
}
apply ( args : any [ ] ) : boolean {
const pokemon = args [ 0 ] as Pokemon ;
2024-02-19 10:25:28 -05:00
if ( pokemon . isPlayer ( ) ) {
pokemon . scene . validateAchv ( achvs . TERASTALLIZE ) ;
if ( this . teraType === Type . STELLAR )
pokemon . scene . validateAchv ( achvs . STELLAR_TERASTALLIZE ) ;
}
2024-02-17 00:40:03 -05:00
pokemon . updateSpritePipelineData ( ) ;
return true ;
}
lapse ( args : any [ ] ) : boolean {
const ret = super . lapse ( args ) ;
if ( ! ret ) {
const pokemon = args [ 0 ] as Pokemon ;
pokemon . updateSpritePipelineData ( ) ;
}
return ret ;
}
getMaxHeldItemCount ( pokemon : Pokemon ) : integer {
return 1 ;
}
}
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-12-09 00:33:29 -05:00
args [ 1 ] [ this . stat ] = Math . min ( Math . floor ( args [ 1 ] [ this . stat ] * ( 1 + this . getStackCount ( ) * 0.1 ) ) , 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-12-08 21:59:03 -05:00
2023-12-09 00:33:29 -05:00
getMaxHeldItemCount ( pokemon : Pokemon ) : integer {
return pokemon . ivs [ this . stat ] ;
2023-12-08 21:59:03 -05:00
}
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-12-09 00:33:29 -05:00
getMaxHeldItemCount ( pokemon : Pokemon ) : integer {
return 10 ;
}
2023-04-14 18:21:33 -04:00
}
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 ;
2024-01-02 21:31:59 -05:00
if ( ! surviveDamage . value && pokemon . randSeedInt ( 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-12-09 00:33:29 -05:00
getMaxHeldItemCount ( pokemon : Pokemon ) : 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 {
2024-01-02 21:31:59 -05:00
const pokemon = args [ 0 ] as Pokemon ;
2023-04-25 01:32:48 -04:00
const flinched = args [ 1 ] as Utils . BooleanHolder ;
2024-01-02 21:31:59 -05:00
if ( ! flinched . value && pokemon . randSeedInt ( 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-12-09 00:33:29 -05:00
getMaxHeldItemCount ( pokemon : Pokemon ) : 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-12-09 00:33:29 -05:00
getMaxHeldItemCount ( pokemon : Pokemon ) : 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-12-09 00:33:29 -05:00
getMaxHeldItemCount ( pokemon : Pokemon ) : 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-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene , forThreshold? : boolean ) : number {
return 99 ;
}
2023-04-23 12:35:16 -04:00
}
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 ;
2023-12-23 01:21:01 -05:00
const cancelled = new Utils . BooleanHolder ( false ) ;
pokemon . getOpponents ( ) . map ( opp = > applyAbAttrs ( PreventBerryUseAbAttr , opp , cancelled ) ) ;
if ( cancelled . value ) {
pokemon . scene . queueMessage ( getPokemonMessage ( pokemon , ' is too\nnervous to eat berries!' ) ) ;
return false ;
}
2023-04-20 15:46:05 -04:00
const preserve = new Utils . BooleanHolder ( false ) ;
2024-01-02 21:31:59 -05:00
pokemon . scene . applyModifiers ( PreserveBerryModifier , pokemon . isPlayer ( ) , pokemon , preserve ) ;
2023-04-20 19:44:56 -04:00
2023-04-20 15:46:05 -04:00
getBerryEffectFunc ( this . berryType ) ( pokemon ) ;
if ( ! preserve . value )
this . consumed = true ;
return true ;
}
2023-12-09 00:33:29 -05:00
getMaxHeldItemCount ( pokemon : Pokemon ) : integer {
return 10 ;
}
2023-04-20 15:46:05 -04:00
}
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 {
2024-01-02 21:31:59 -05:00
return super . shouldApply ( args ) && args [ 0 ] instanceof Pokemon && args [ 1 ] instanceof Utils . BooleanHolder ;
2023-04-20 15:46:05 -04:00
}
apply ( args : any [ ] ) : boolean {
2024-01-02 21:31:59 -05:00
if ( ! ( args [ 1 ] as Utils . BooleanHolder ) . value )
( args [ 1 ] as Utils . BooleanHolder ) . value = ( args [ 0 ] as Pokemon ) . randSeedInt ( this . getMaxStackCount ( null ) ) < this . getStackCount ( ) ;
2023-04-20 15:46:05 -04:00
return true ;
}
2023-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene ) : 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 ;
}
2023-12-09 00:33:29 -05:00
getMaxHeldItemCount ( pokemon : Pokemon ) : integer {
2023-12-08 21:59:03 -05:00
return 1 ;
2023-06-06 08:16:07 -04:00
}
}
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 ;
2024-02-04 00:30:19 -05:00
private healStatus : boolean ;
2023-04-20 15:46:05 -04:00
public fainted : boolean ;
2023-03-28 14:54:52 -04:00
2024-02-04 00:30:19 -05:00
constructor ( type : ModifierType , pokemonId : integer , restorePoints : integer , restorePercent : number , healStatus : boolean , 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 ;
2024-02-04 00:30:19 -05:00
this . healStatus = healStatus ;
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 ) ) ;
2024-02-04 00:30:19 -05:00
if ( this . fainted || this . healStatus )
2023-04-16 18:40:32 -04:00
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 ] ;
2024-01-26 18:36:23 -05:00
move . ppUsed = this . restorePoints > - 1 ? Math . max ( move . ppUsed - this . restorePoints , 0 ) : 0 ;
2023-04-11 11:04:39 -04:00
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 ( ) )
2024-01-26 18:36:23 -05:00
move . ppUsed = this . restorePoints > - 1 ? Math . max ( move . ppUsed - this . restorePoints , 0 ) : 0 ;
2023-04-04 21:10:11 -04:00
return true ;
}
}
2024-01-12 19:05:00 -05:00
export class PokemonPpUpModifier extends ConsumablePokemonMoveModifier {
private upPoints : integer ;
constructor ( type : ModifierType , pokemonId : integer , moveIndex : integer , upPoints : integer ) {
super ( type , pokemonId , moveIndex ) ;
this . upPoints = upPoints ;
}
apply ( args : any [ ] ) : boolean {
const pokemon = args [ 0 ] as Pokemon ;
const move = pokemon . getMoveset ( ) [ this . moveIndex ] ;
move . ppUp = Math . min ( move . ppUp + this . upPoints , move . ppUp + 3 ) ;
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 ;
2024-02-29 16:41:14 -05: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
2023-12-07 17:43:56 -05:00
&& ( e . evoFormKey === null || ( e . preFormKey || '' ) === pokemon . getFormKey ( ) )
2023-04-14 18:21:33 -04:00
&& ( ! e . condition || e . condition . predicate ( pokemon ) ) ) ;
if ( matchingEvolution ) {
2024-01-09 23:34:43 -05:00
pokemon . scene . unshiftPhase ( new EvolutionPhase ( pokemon . scene , pokemon , matchingEvolution , pokemon . level - 1 ) ) ;
2023-04-14 18:21:33 -04:00
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-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene ) : integer {
2023-04-28 16:35:03 -04:00
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 ;
2024-02-19 22:54:11 -05:00
healingMultiplier . value *= 1 + ( ( this . multiplier - 1 ) * this . getStackCount ( ) ) ;
2023-04-09 19:15:21 -04:00
return true ;
}
2023-04-23 21:31:06 -04:00
2023-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene ) : integer {
2024-02-19 22:54:11 -05:00
return 5 ;
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-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene , forThreshold? : boolean ) : integer {
return 99 ;
}
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-12-09 00:33:29 -05:00
getMaxHeldItemCount ( pokemon : Pokemon ) : integer {
return 99 ;
}
2023-04-19 19:55:22 -04:00
}
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-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene ) : integer {
2023-03-30 23:02:35 -04:00
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-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene ) : integer {
2023-11-10 21:11:36 -05:00
return 1 ;
}
}
2023-12-21 23:00:45 -05:00
export class PokemonFriendshipBoosterModifier extends PokemonHeldItemModifier {
constructor ( type : ModifierTypes . PokemonFriendshipBoosterModifierType , pokemonId : integer , stackCount? : integer ) {
super ( type , pokemonId , stackCount ) ;
}
matchType ( modifier : Modifier ) : boolean {
return modifier instanceof PokemonFriendshipBoosterModifier ;
}
clone ( ) : PersistentModifier {
return new PokemonFriendshipBoosterModifier ( this . type as ModifierTypes . PokemonFriendshipBoosterModifierType , this . pokemonId , this . stackCount ) ;
}
apply ( args : any [ ] ) : boolean {
( args [ 1 ] as Utils . IntegerHolder ) . value *= 1 + 0.5 * this . getStackCount ( ) ;
return true ;
}
getMaxHeldItemCount ( pokemon : Pokemon ) : integer {
return 5 ;
}
}
2024-01-09 00:06:11 -05:00
export class PokemonNatureWeightModifier extends PokemonHeldItemModifier {
constructor ( type : ModifierTypes . ModifierType , pokemonId : integer , stackCount? : integer ) {
super ( type , pokemonId , stackCount ) ;
}
matchType ( modifier : Modifier ) : boolean {
return modifier instanceof PokemonNatureWeightModifier ;
}
clone ( ) : PersistentModifier {
return new PokemonNatureWeightModifier ( this . type , this . pokemonId , this . stackCount ) ;
}
apply ( args : any [ ] ) : boolean {
const multiplier = args [ 1 ] as Utils . IntegerHolder ;
if ( multiplier . value !== 1 ) {
multiplier . value += 0.05 * this . getStackCount ( ) * ( multiplier . value > 1 ? 1 : - 1 ) ;
return true ;
}
return false ;
}
getMaxHeldItemCount ( pokemon : Pokemon ) : integer {
return 5 ;
}
}
2024-01-09 23:34:43 -05:00
export class PokemonFormChangeItemModifier extends PokemonHeldItemModifier {
public formChangeItem : FormChangeItem ;
public active : boolean ;
constructor ( type : ModifierTypes . FormChangeItemModifierType , pokemonId : integer , formChangeItem : FormChangeItem , active : boolean , stackCount? : integer ) {
super ( type , pokemonId , stackCount ) ;
this . formChangeItem = formChangeItem ;
this . active = active ;
}
matchType ( modifier : Modifier ) : boolean {
return modifier instanceof PokemonFormChangeItemModifier && modifier . formChangeItem === this . formChangeItem ;
}
clone ( ) : PersistentModifier {
return new PokemonFormChangeItemModifier ( this . type as ModifierTypes . FormChangeItemModifierType , this . pokemonId , this . formChangeItem , this . active , this . stackCount ) ;
}
getArgs ( ) : any [ ] {
return super . getArgs ( ) . concat ( this . formChangeItem , this . active ) ;
}
apply ( args : any [ ] ) : boolean {
const pokemon = args [ 0 ] as Pokemon ;
2024-02-17 00:40:03 -05:00
const active = args [ 1 ] as boolean ;
let switchActive = this . active && ! active ;
if ( switchActive )
this . active = false ;
const ret = pokemon . scene . triggerPokemonFormChange ( pokemon , SpeciesFormChangeItemTrigger ) ;
if ( switchActive )
this . active = true ;
2024-01-09 23:34:43 -05:00
2024-02-17 00:40:03 -05:00
return ret ;
2024-01-09 23:34:43 -05:00
}
getMaxHeldItemCount ( pokemon : Pokemon ) : integer {
return 1 ;
}
}
2024-01-18 17:22:18 -05:00
export class MoneyRewardModifier extends ConsumableModifier {
private moneyMultiplier : number ;
constructor ( type : ModifierType , moneyMultiplier : number ) {
super ( type ) ;
this . moneyMultiplier = moneyMultiplier ;
}
apply ( args : any [ ] ) : boolean {
const scene = args [ 0 ] as BattleScene ;
2024-02-04 00:30:19 -05:00
const moneyAmount = new Utils . IntegerHolder ( scene . getWaveMoneyAmount ( this . moneyMultiplier ) ) ;
2024-01-18 17:22:18 -05:00
scene . applyModifiers ( MoneyMultiplierModifier , true , moneyAmount ) ;
scene . money += moneyAmount . value ;
scene . updateMoneyText ( ) ;
scene . validateAchvs ( MoneyAchv ) ;
return true ;
}
}
2023-11-10 21:11:36 -05:00
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
}
2023-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene ) : 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 ;
}
2023-12-09 00:33:29 -05:00
getMaxHeldItemCount ( pokemon : Pokemon ) : integer {
2023-11-10 21:11:36 -05:00
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 ;
2023-11-30 16:53:34 -05:00
const interestAmount = Math . floor ( scene . money * 0.1 * this . getStackCount ( ) ) ;
2023-11-10 21:11:36 -05:00
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 ) ;
}
2023-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene ) : integer {
2023-11-10 21:11:36 -05:00
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 ;
}
2023-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene ) : integer {
2023-10-29 22:18:02 -04:00
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-12-19 23:51:48 -05:00
( args [ 0 ] as Utils . IntegerHolder ) . value *= Math . pow ( 2 , 2 + this . getStackCount ( ) ) ;
2023-03-28 14:54:52 -04:00
return true ;
}
2023-03-30 23:02:35 -04:00
2023-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene ) : 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 ;
}
2023-12-09 00:33:29 -05:00
getMaxHeldItemCount ( pokemon : Pokemon ) : integer {
2023-04-28 19:26:41 -04:00
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
2024-01-02 21:31:59 -05:00
const targetPokemon = opponents [ pokemon . randSeedInt ( opponents . length ) ] ;
2023-05-19 16:13:11 -04:00
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 [ ] ;
2024-02-22 00:34:54 -05:00
let highestItemTier = itemModifiers . map ( m = > m . type . getOrInferTier ( ) ) . reduce ( ( highestTier , tier ) = > Math . max ( tier , highestTier ) , 0 ) ;
let tierItemModifiers = itemModifiers . filter ( m = > m . type . getOrInferTier ( ) === highestItemTier ) ;
2023-12-22 23:57:05 -05:00
let heldItemTransferPromises : Promise < void > [ ] = [ ] ;
2023-04-23 10:24:22 -04:00
2023-05-05 16:55:46 -04:00
for ( let i = 0 ; i < transferredItemCount ; i ++ ) {
2024-02-22 00:34:54 -05:00
if ( ! tierItemModifiers . length ) {
while ( highestItemTier -- && ! tierItemModifiers . length )
tierItemModifiers = itemModifiers . filter ( m = > m . type . tier === highestItemTier ) ;
if ( ! tierItemModifiers . length )
break ;
}
2024-01-02 21:31:59 -05:00
const randItemIndex = pokemon . randSeedInt ( itemModifiers . length ) ;
2023-04-23 10:24:22 -04:00
const randItem = itemModifiers [ randItemIndex ] ;
2023-12-22 23:57:05 -05:00
heldItemTransferPromises . push ( pokemon . scene . tryTransferHeldItemModifier ( randItem , pokemon , false , false , true ) . then ( success = > {
if ( success ) {
transferredModifierTypes . push ( randItem . type ) ;
itemModifiers . splice ( randItemIndex , 1 ) ;
}
} ) ) ;
2023-04-23 10:24:22 -04:00
}
2023-04-21 15:45:48 -04:00
2023-12-22 23:57:05 -05:00
Promise . all ( heldItemTransferPromises ) . then ( ( ) = > {
for ( let mt of transferredModifierTypes )
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 } ! ` ) ;
}
2023-12-09 00:33:29 -05:00
getMaxHeldItemCount ( pokemon : Pokemon ) : integer {
2023-12-22 23:57:05 -05:00
return 1 ;
2023-05-05 16:55:46 -04:00
}
}
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 {
2024-02-28 14:57:11 -05:00
return Phaser . Math . RND . realInRange ( 0 , 1 ) < ( this . chance * this . getStackCount ( ) ) ? 1 : 0 ;
2023-05-05 16:55:46 -04:00
}
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-12-09 00:33:29 -05:00
getMaxHeldItemCount ( pokemon : Pokemon ) : 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 ;
}
2023-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene ) : integer {
2023-11-12 12:49:06 -05:00
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-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene ) : 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-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene ) : integer {
2024-02-28 11:55:35 -05:00
return 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 ;
}
2023-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene ) : integer {
2023-11-05 10:56:09 -05:00
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
2023-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene ) : integer {
2023-11-05 10:56:09 -05:00
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 ) ;
2024-03-09 21:57:33 -05:00
if ( Phaser . Math . RND . realInRange ( 0 , 1 ) < ( this . chance * this . getStackCount ( ) ) )
return target . trySetStatus ( this . effect , 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 ) ;
2024-02-28 14:57:11 -05:00
if ( target . status && Phaser . Math . RND . realInRange ( 0 , 1 ) < ( this . chance * this . getStackCount ( ) ) ) {
2024-02-28 15:15:27 -05:00
target . scene . queueMessage ( getPokemonMessage ( target , getStatusEffectHealText ( target . status . effect ) ) ) ;
2023-10-29 17:58:54 -04:00
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 {
2024-02-28 14:57:11 -05:00
if ( Phaser . Math . RND . realInRange ( 0 , 1 ) >= ( 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
2024-03-11 00:16:24 -04:00
getMaxStackCount ( scene : BattleScene ) : integer {
return 10 ;
}
}
export class EnemyFusionChanceModifier extends EnemyPersistentModifier {
private chance : number ;
constructor ( type : ModifierType , chancePercent : number , stackCount? : integer ) {
super ( type , stackCount ) ;
this . chance = chancePercent / 100 ;
}
match ( modifier : Modifier ) {
return modifier instanceof EnemyFusionChanceModifier && modifier . chance === this . chance ;
}
clone() {
return new EnemyFusionChanceModifier ( this . type , this . chance * 100 , this . stackCount ) ;
}
getArgs ( ) : any [ ] {
return [ this . chance * 100 ] ;
}
apply ( args : any [ ] ) : boolean {
if ( Phaser . Math . RND . realInRange ( 0 , 1 ) >= ( this . chance * this . getStackCount ( ) ) )
return false ;
( args [ 0 ] as Utils . BooleanHolder ) . value = true ;
return true ;
}
2023-12-09 00:33:29 -05:00
getMaxStackCount ( scene : BattleScene ) : integer {
2023-11-05 10:56:09 -05:00
return 10 ;
}
2023-03-28 14:54:52 -04:00
}