2023-04-12 11:57:15 -04:00
import * as ModifierTypes from './modifier-type' ;
2023-04-20 19:44:56 -04:00
import { LearnMovePhase , LevelUpPhase , 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" ;
import { addTextObject , TextStyle } from "../ui/text" ;
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-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-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-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 ) ;
for ( let modifier of modifiers ) {
const icon = modifier . getIcon ( this . scene as BattleScene ) ;
this . add ( icon ) ;
2023-04-19 14:07:38 -04:00
this . setModifierIconPosition ( icon , modifiers . length ) ;
2023-03-28 14:54:52 -04:00
}
}
2023-04-19 14:07:38 -04:00
setModifierIconPosition ( icon : Phaser.GameObjects.Container , modifierCount : integer ) {
let rowIcons : integer = 12 + 6 * Math . max ( ( Math . ceil ( modifierCount / 12 ) - 2 ) , 0 ) ;
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-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-06-01 11:22:34 -04:00
clone ( ) : TempBattleStatBoosterModifier {
return new TempBattleStatBoosterModifier ( this . type as ModifierTypes . TempBattleStatBoosterModifierType , this . battlesLeft , this . stackCount ) ;
}
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-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 ) ;
const iconAtlasKey = isIconShown ? pokemon . species . getIconAtlasKey ( ) : 'pokemon_icons_0' ;
const pokemonIcon = scene . add . sprite ( 0 , 8 , iconAtlasKey ) ;
if ( pokemon . species . isObtainable ( ) ) {
const iconKey = isIconShown ? pokemon . getIconKey ( ) : 'pkmn_icon__000' ;
pokemonIcon . play ( iconKey ) . stop ( ) ;
} else {
2023-04-26 16:07:29 -04:00
if ( pokemon . species . speciesId === Species . ETERNATUS )
pokemonIcon . setScale ( 0.5 , 0.5 ) ;
else
pokemonIcon . setPosition ( - 8 , 0 ) ;
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-04-21 14:05:16 -04:00
constructor ( type : ModifierType , pokemonId : integer , moveType : Type , boostPercent : integer , stackCount? : integer ) {
super ( type , pokemonId , stackCount ) ;
2023-04-14 18:21:33 -04:00
this . moveType = moveType ;
this . boostMultiplier = boostPercent * 0.01 ;
}
2023-04-21 14:05:16 -04:00
matchType ( modifier : Modifier ) {
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 ) ;
}
matchType ( modifier : Modifier ) {
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 } ! ` ) ) ;
}
return true ;
}
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 ;
if ( ! flinched . value && Utils . randInt ( 10 ) < this . getStackCount ( ) )
flinched . value = true ;
return true ;
}
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-04-20 20:15:16 -04:00
}
return true ;
}
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 )
( args [ 0 ] as Utils . BooleanHolder ) . value = this . getStackCount ( ) === this . getMaxStackCount ( ) || Utils . randInt ( this . getMaxStackCount ( ) ) < this . getStackCount ( ) ;
return true ;
}
2023-07-06 19:47:52 -04:00
getMaxStackCount ( ) : integer {
2023-04-20 15:46:05 -04:00
return 4 ;
}
}
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-10-09 16:57:25 -04:00
private restorePercent : integer ;
2023-04-20 15:46:05 -04:00
public fainted : boolean ;
2023-03-28 14:54:52 -04:00
2023-10-09 16:57:25 -04:00
constructor ( type : ModifierType , pokemonId : integer , restorePoints : integer , restorePercent : integer , 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-09 16:57:25 -04:00
pokemon . hp = Math . min ( pokemon . hp + Math . ceil ( Math . max ( Math . floor ( ( this . restorePercent * 0.01 ) * pokemon . getMaxHp ( ) ) , restorePoints ) ) , 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-03 12:50:31 -04:00
if ( pokemon . level <= pokemon . scene . getMaxExpLevel ( ) ) {
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
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-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-04-21 14:05:16 -04:00
constructor ( type : ModifierType , boostPercent : integer , stackCount? : integer ) {
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-04-21 14:05:16 -04:00
constructor ( type : ModifierTypes . PokemonExpBoosterModifierType , pokemonId : integer , boostPercent : integer , stackCount? : integer ) {
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-03-30 23:02:35 -04:00
apply ( _args : any [ ] ) : boolean {
2023-03-28 14:54:52 -04:00
return true ;
}
2023-03-30 23:02:35 -04:00
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-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 ;
}
apply ( _args : any [ ] ) : boolean {
return true ;
}
clone ( ) : ExpBalanceModifier {
2023-04-21 14:05:16 -04:00
return new ExpBalanceModifier ( this . type , this . stackCount ) ;
2023-04-19 22:51:46 -04:00
}
getMaxStackCount ( ) : integer {
return 1 ;
}
}
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-07-05 13:53:28 -04:00
( args [ 0 ] as Utils . IntegerHolder ) . value = Math . floor ( Math . pow ( ( args [ 0 ] as Utils . IntegerHolder ) . value * 0.5 , Math . sqrt ( this . getStackCount ( ) ) + 1 ) ) ;
2023-03-28 14:54:52 -04:00
return true ;
}
2023-03-30 23:02:35 -04:00
getMaxStackCount ( ) : integer {
2023-07-05 13:53:28 -04:00
return 5 ;
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 ;
}
}
export class ContactHeldItemTransferChanceModifier extends HeldItemTransferModifier {
private chance : number ;
constructor ( type : ModifierType , pokemonId : integer , chancePercent : integer , stackCount? : integer ) {
super ( type , pokemonId , stackCount ) ;
this . chance = chancePercent / 100 ;
}
matchType ( modifier : Modifier ) : boolean {
return modifier instanceof ContactHeldItemTransferChanceModifier ;
}
clone ( ) : ContactHeldItemTransferChanceModifier {
return new ContactHeldItemTransferChanceModifier ( this . type , this . pokemonId , this . chance * 100 , this . stackCount ) ;
}
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-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-03-28 14:54:52 -04:00
}