2017-09-17 14:10:32 +02:00
# include "global.h"
# include "battle.h"
2018-02-08 11:17:41 +01:00
# include "constants/battle_script_commands.h"
2017-12-05 18:55:48 +01:00
# include "constants/abilities.h"
2017-12-11 19:27:51 +01:00
# include "constants/moves.h"
2017-12-05 18:55:48 +01:00
# include "constants/hold_effects.h"
2017-12-31 16:28:57 +01:00
# include "constants/battle_anim.h"
2017-09-17 14:10:32 +02:00
# include "pokemon.h"
2017-12-11 19:27:51 +01:00
# include "constants/species.h"
2017-09-17 14:10:32 +02:00
# include "item.h"
2017-12-05 18:55:48 +01:00
# include "constants/items.h"
2017-09-17 14:10:32 +02:00
# include "util.h"
2017-12-05 18:55:48 +01:00
# include "constants/battle_move_effects.h"
2017-11-25 18:42:31 +01:00
# include "battle_scripts.h"
2017-12-05 19:27:33 +01:00
# include "random.h"
2017-09-17 14:10:32 +02:00
# include "text.h"
# include "string_util.h"
# include "battle_message.h"
2018-02-08 00:35:13 +01:00
# include "constants/battle_string_ids.h"
2017-09-28 17:38:07 +02:00
# include "battle_ai_script_commands.h"
2017-09-20 00:28:00 +02:00
# include "battle_controllers.h"
2017-09-17 17:14:32 +02:00
# include "event_data.h"
2017-10-06 17:06:45 +02:00
# include "link.h"
2017-11-27 21:24:34 +01:00
# include "berry.h"
2018-07-14 16:41:14 +02:00
# include "pokedex.h"
2017-09-17 14:10:32 +02:00
2017-09-17 15:19:15 +02:00
extern u8 weather_get_current ( void ) ;
2017-10-06 17:06:45 +02:00
2017-10-06 19:09:37 +02:00
// rom const data
static const u16 sSoundMovesTable [ ] =
{
MOVE_GROWL , MOVE_ROAR , MOVE_SING , MOVE_SUPERSONIC , MOVE_SCREECH , MOVE_SNORE ,
MOVE_UPROAR , MOVE_METAL_SOUND , MOVE_GRASS_WHISTLE , MOVE_HYPER_VOICE , 0xFFFF
} ;
2018-07-14 18:58:45 +02:00
static const u8 sAbilitiesAffectedByMoldBreaker [ ] =
{
[ ABILITY_BATTLE_ARMOR ] = 1 ,
[ ABILITY_CLEAR_BODY ] = 1 ,
[ ABILITY_DAMP ] = 1 ,
[ ABILITY_DRY_SKIN ] = 1 ,
[ ABILITY_FILTER ] = 1 ,
[ ABILITY_FLASH_FIRE ] = 1 ,
[ ABILITY_FLOWER_GIFT ] = 1 ,
[ ABILITY_HEATPROOF ] = 1 ,
[ ABILITY_HYPER_CUTTER ] = 1 ,
[ ABILITY_IMMUNITY ] = 1 ,
[ ABILITY_INNER_FOCUS ] = 1 ,
[ ABILITY_INSOMNIA ] = 1 ,
[ ABILITY_KEEN_EYE ] = 1 ,
[ ABILITY_LEAF_GUARD ] = 1 ,
[ ABILITY_LEVITATE ] = 1 ,
[ ABILITY_LIGHTNING_ROD ] = 1 ,
[ ABILITY_LIMBER ] = 1 ,
[ ABILITY_MAGMA_ARMOR ] = 1 ,
[ ABILITY_MARVEL_SCALE ] = 1 ,
[ ABILITY_MOTOR_DRIVE ] = 1 ,
[ ABILITY_OBLIVIOUS ] = 1 ,
[ ABILITY_OWN_TEMPO ] = 1 ,
[ ABILITY_SAND_VEIL ] = 1 ,
[ ABILITY_SHELL_ARMOR ] = 1 ,
[ ABILITY_SHIELD_DUST ] = 1 ,
[ ABILITY_SIMPLE ] = 1 ,
[ ABILITY_SNOW_CLOAK ] = 1 ,
[ ABILITY_SOLID_ROCK ] = 1 ,
[ ABILITY_SOUNDPROOF ] = 1 ,
[ ABILITY_STICKY_HOLD ] = 1 ,
[ ABILITY_STORM_DRAIN ] = 1 ,
[ ABILITY_STURDY ] = 1 ,
[ ABILITY_SUCTION_CUPS ] = 1 ,
[ ABILITY_TANGLED_FEET ] = 1 ,
[ ABILITY_THICK_FAT ] = 1 ,
[ ABILITY_UNAWARE ] = 1 ,
[ ABILITY_VITAL_SPIRIT ] = 1 ,
[ ABILITY_VOLT_ABSORB ] = 1 ,
[ ABILITY_WATER_ABSORB ] = 1 ,
[ ABILITY_WATER_VEIL ] = 1 ,
[ ABILITY_WHITE_SMOKE ] = 1 ,
[ ABILITY_WONDER_GUARD ] = 1 ,
[ ABILITY_BIG_PECKS ] = 1 ,
[ ABILITY_CONTRARY ] = 1 ,
[ ABILITY_FRIEND_GUARD ] = 1 ,
[ ABILITY_HEAVY_METAL ] = 1 ,
[ ABILITY_LIGHT_METAL ] = 1 ,
[ ABILITY_MAGIC_BOUNCE ] = 1 ,
[ ABILITY_MULTISCALE ] = 1 ,
[ ABILITY_SAP_SIPPER ] = 1 ,
[ ABILITY_TELEPATHY ] = 1 ,
[ ABILITY_WONDER_SKIN ] = 1 ,
[ ABILITY_AROMA_VEIL ] = 1 ,
[ ABILITY_BULLETPROOF ] = 1 ,
[ ABILITY_FLOWER_VEIL ] = 1 ,
[ ABILITY_FUR_COAT ] = 1 ,
[ ABILITY_OVERCOAT ] = 1 ,
[ ABILITY_SWEET_VEIL ] = 1 ,
[ ABILITY_DAZZLING ] = 1 ,
[ ABILITY_DISGUISE ] = 1 ,
[ ABILITY_FLUFFY ] = 1 ,
[ ABILITY_QUEENLY_MAJESTY ] = 1 ,
[ ABILITY_WATER_BUBBLE ] = 1 ,
} ;
static const u8 sFlailHpScaleToPowerTable [ ] =
{
1 , 200 ,
4 , 150 ,
9 , 100 ,
16 , 80 ,
32 , 40 ,
48 , 20
} ;
// format: min. weight (hectograms), base power
static const u16 sWeightToDamageTable [ ] =
{
100 , 20 ,
250 , 40 ,
500 , 60 ,
1000 , 80 ,
2000 , 100 ,
0xFFFF , 0xFFFF
} ;
static const u16 sSpeedDiffToDmgTable [ ] =
{
40 , 60 , 80 , 120 , 150
} ;
static const u8 sHoldEffectToType [ ] [ 2 ] =
{
{ HOLD_EFFECT_BUG_POWER , TYPE_BUG } ,
{ HOLD_EFFECT_STEEL_POWER , TYPE_STEEL } ,
{ HOLD_EFFECT_GROUND_POWER , TYPE_GROUND } ,
{ HOLD_EFFECT_ROCK_POWER , TYPE_ROCK } ,
{ HOLD_EFFECT_GRASS_POWER , TYPE_GRASS } ,
{ HOLD_EFFECT_DARK_POWER , TYPE_DARK } ,
{ HOLD_EFFECT_FIGHTING_POWER , TYPE_FIGHTING } ,
{ HOLD_EFFECT_ELECTRIC_POWER , TYPE_ELECTRIC } ,
{ HOLD_EFFECT_WATER_POWER , TYPE_WATER } ,
{ HOLD_EFFECT_FLYING_POWER , TYPE_FLYING } ,
{ HOLD_EFFECT_POISON_POWER , TYPE_POISON } ,
{ HOLD_EFFECT_ICE_POWER , TYPE_ICE } ,
{ HOLD_EFFECT_GHOST_POWER , TYPE_GHOST } ,
{ HOLD_EFFECT_PSYCHIC_POWER , TYPE_PSYCHIC } ,
{ HOLD_EFFECT_FIRE_POWER , TYPE_FIRE } ,
{ HOLD_EFFECT_DRAGON_POWER , TYPE_DRAGON } ,
{ HOLD_EFFECT_NORMAL_POWER , TYPE_NORMAL } ,
{ HOLD_EFFECT_FAIRY_POWER , TYPE_FAIRY } ,
} ;
// code
2018-02-08 11:17:41 +01:00
u8 GetBattlerForBattleScript ( u8 caseId )
2017-10-06 17:06:45 +02:00
{
u8 ret = 0 ;
switch ( caseId )
{
2018-02-08 11:17:41 +01:00
case BS_TARGET :
2018-02-06 23:09:39 +01:00
ret = gBattlerTarget ;
2017-10-06 17:06:45 +02:00
break ;
2018-02-08 11:17:41 +01:00
case BS_ATTACKER :
2018-02-06 23:09:39 +01:00
ret = gBattlerAttacker ;
2017-10-06 17:06:45 +02:00
break ;
2018-02-08 11:17:41 +01:00
case BS_EFFECT_BATTLER :
ret = gEffectBattler ;
2017-10-06 17:06:45 +02:00
break ;
2018-07-01 11:15:42 +02:00
case BS_BATTLER_0 :
2017-10-06 17:06:45 +02:00
ret = 0 ;
break ;
2018-02-08 11:17:41 +01:00
case BS_SCRIPTING :
2018-02-06 02:46:59 +01:00
ret = gBattleScripting . battler ;
2017-10-06 17:06:45 +02:00
break ;
2018-02-08 11:17:41 +01:00
case BS_FAINTED :
ret = gBattlerFainted ;
2017-10-06 17:06:45 +02:00
break ;
case 5 :
2018-02-08 11:17:41 +01:00
ret = gBattlerFainted ;
2017-10-06 17:06:45 +02:00
break ;
case 4 :
case 6 :
case 8 :
case 9 :
2018-02-08 11:17:41 +01:00
case BS_PLAYER1 :
2018-02-06 02:46:59 +01:00
ret = GetBattlerAtPosition ( B_POSITION_PLAYER_LEFT ) ;
2017-10-06 17:06:45 +02:00
break ;
2018-02-08 11:17:41 +01:00
case BS_OPPONENT1 :
2018-02-06 02:46:59 +01:00
ret = GetBattlerAtPosition ( B_POSITION_OPPONENT_LEFT ) ;
2017-10-06 17:06:45 +02:00
break ;
2018-02-08 11:17:41 +01:00
case BS_PLAYER2 :
2018-02-06 02:46:59 +01:00
ret = GetBattlerAtPosition ( B_POSITION_PLAYER_RIGHT ) ;
2017-10-06 17:06:45 +02:00
break ;
2018-02-08 11:17:41 +01:00
case BS_OPPONENT2 :
2018-02-06 02:46:59 +01:00
ret = GetBattlerAtPosition ( B_POSITION_OPPONENT_RIGHT ) ;
2017-10-06 17:06:45 +02:00
break ;
}
return ret ;
}
2018-02-06 02:46:59 +01:00
void PressurePPLose ( u8 defender , u8 attacker , u16 move )
2017-10-06 17:06:45 +02:00
{
s32 i ;
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ defender ] . ability ! = ABILITY_PRESSURE )
2017-10-06 17:06:45 +02:00
return ;
for ( i = 0 ; i < 4 ; i + + )
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ attacker ] . moves [ i ] = = move )
2017-10-06 17:06:45 +02:00
break ;
}
if ( i = = 4 ) // mons don't share any moves
return ;
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ attacker ] . pp [ i ] ! = 0 )
gBattleMons [ attacker ] . pp [ i ] - - ;
2017-10-06 17:06:45 +02:00
2018-02-06 02:46:59 +01:00
if ( ! ( gBattleMons [ attacker ] . status2 & STATUS2_TRANSFORMED )
& & ! ( gDisableStructs [ attacker ] . unk18_b & gBitTable [ i ] ) )
2017-10-06 17:06:45 +02:00
{
2018-02-06 02:46:59 +01:00
gActiveBattler = attacker ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_PPMOVE1_BATTLE + i , 0 , 1 , & gBattleMons [ gActiveBattler ] . pp [ i ] ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-10-06 17:06:45 +02:00
}
}
2018-02-06 02:46:59 +01:00
void PressurePPLoseOnUsingImprision ( u8 attacker )
2017-10-06 17:06:45 +02:00
{
s32 i , j ;
s32 imprisionPos = 4 ;
2018-02-06 02:46:59 +01:00
u8 atkSide = GetBattlerSide ( attacker ) ;
2017-10-06 17:06:45 +02:00
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-10-06 17:06:45 +02:00
{
2018-02-06 02:46:59 +01:00
if ( atkSide ! = GetBattlerSide ( i ) & & gBattleMons [ i ] . ability = = ABILITY_PRESSURE )
2017-10-06 17:06:45 +02:00
{
for ( j = 0 ; j < 4 ; j + + )
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ attacker ] . moves [ j ] = = MOVE_IMPRISON )
2017-10-06 17:06:45 +02:00
break ;
}
if ( j ! = 4 )
{
imprisionPos = j ;
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ attacker ] . pp [ j ] ! = 0 )
gBattleMons [ attacker ] . pp [ j ] - - ;
2017-10-06 17:06:45 +02:00
}
}
}
if ( imprisionPos ! = 4
2018-02-06 02:46:59 +01:00
& & ! ( gBattleMons [ attacker ] . status2 & STATUS2_TRANSFORMED )
& & ! ( gDisableStructs [ attacker ] . unk18_b & gBitTable [ imprisionPos ] ) )
2017-10-06 17:06:45 +02:00
{
2018-02-06 02:46:59 +01:00
gActiveBattler = attacker ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_PPMOVE1_BATTLE + imprisionPos , 0 , 1 , & gBattleMons [ gActiveBattler ] . pp [ imprisionPos ] ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-10-06 17:06:45 +02:00
}
}
2018-02-06 02:46:59 +01:00
void PressurePPLoseOnUsingPerishSong ( u8 attacker )
2017-10-06 17:06:45 +02:00
{
s32 i , j ;
s32 perishSongPos = 4 ;
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-10-06 17:06:45 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ i ] . ability = = ABILITY_PRESSURE & & i ! = attacker )
2017-10-06 17:06:45 +02:00
{
for ( j = 0 ; j < 4 ; j + + )
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ attacker ] . moves [ j ] = = MOVE_PERISH_SONG )
2017-10-06 17:06:45 +02:00
break ;
}
if ( j ! = 4 )
{
perishSongPos = j ;
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ attacker ] . pp [ j ] ! = 0 )
gBattleMons [ attacker ] . pp [ j ] - - ;
2017-10-06 17:06:45 +02:00
}
}
}
if ( perishSongPos ! = 4
2018-02-06 02:46:59 +01:00
& & ! ( gBattleMons [ attacker ] . status2 & STATUS2_TRANSFORMED )
& & ! ( gDisableStructs [ attacker ] . unk18_b & gBitTable [ perishSongPos ] ) )
2017-10-06 17:06:45 +02:00
{
2018-02-06 02:46:59 +01:00
gActiveBattler = attacker ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_PPMOVE1_BATTLE + perishSongPos , 0 , 1 , & gBattleMons [ gActiveBattler ] . pp [ perishSongPos ] ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-10-06 17:06:45 +02:00
}
}
2018-02-06 20:48:02 +01:00
void MarkAllBattlersForControllerExec ( void ) // unused
2017-10-06 17:06:45 +02:00
{
s32 i ;
if ( gBattleTypeFlags & BATTLE_TYPE_LINK )
{
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2018-02-06 20:48:02 +01:00
gBattleControllerExecFlags | = gBitTable [ i ] < < 0x1C ;
2017-10-06 17:06:45 +02:00
}
else
{
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2018-02-06 20:48:02 +01:00
gBattleControllerExecFlags | = gBitTable [ i ] ;
2017-10-06 17:06:45 +02:00
}
}
2018-02-06 20:48:02 +01:00
void MarkBattlerForControllerExec ( u8 battlerId )
2017-10-06 17:06:45 +02:00
{
if ( gBattleTypeFlags & BATTLE_TYPE_LINK )
2018-02-06 20:48:02 +01:00
gBattleControllerExecFlags | = gBitTable [ battlerId ] < < 0x1C ;
2017-10-06 17:06:45 +02:00
else
2018-02-06 20:48:02 +01:00
gBattleControllerExecFlags | = gBitTable [ battlerId ] ;
2017-10-06 17:06:45 +02:00
}
void sub_803F850 ( u8 arg0 )
{
s32 i ;
2017-10-13 17:09:36 +02:00
for ( i = 0 ; i < GetLinkPlayerCount ( ) ; i + + )
2018-02-06 20:48:02 +01:00
gBattleControllerExecFlags | = gBitTable [ arg0 ] < < ( i < < 2 ) ;
2017-10-06 17:06:45 +02:00
2018-02-06 20:48:02 +01:00
gBattleControllerExecFlags & = ~ ( 0x10000000 < < arg0 ) ;
2017-10-06 17:06:45 +02:00
}
2018-02-06 02:46:59 +01:00
void CancelMultiTurnMoves ( u8 battler )
2017-10-06 17:06:45 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ battler ] . status2 & = ~ ( STATUS2_MULTIPLETURNS ) ;
gBattleMons [ battler ] . status2 & = ~ ( STATUS2_LOCK_CONFUSE ) ;
gBattleMons [ battler ] . status2 & = ~ ( STATUS2_UPROAR ) ;
gBattleMons [ battler ] . status2 & = ~ ( STATUS2_BIDE ) ;
2017-10-06 17:06:45 +02:00
2018-02-06 02:46:59 +01:00
gStatuses3 [ battler ] & = ~ ( STATUS3_SEMI_INVULNERABLE ) ;
2017-10-06 17:06:45 +02:00
2018-02-06 02:46:59 +01:00
gDisableStructs [ battler ] . rolloutCounter1 = 0 ;
gDisableStructs [ battler ] . furyCutterCounter = 0 ;
2017-10-06 17:06:45 +02:00
}
2018-02-06 02:46:59 +01:00
bool8 WasUnableToUseMove ( u8 battler )
2017-10-06 17:06:45 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gProtectStructs [ battler ] . prlzImmobility
| | gProtectStructs [ battler ] . targetNotAffected
| | gProtectStructs [ battler ] . usedImprisionedMove
| | gProtectStructs [ battler ] . loveImmobility
| | gProtectStructs [ battler ] . usedDisabledMove
| | gProtectStructs [ battler ] . usedTauntedMove
| | gProtectStructs [ battler ] . flag2Unknown
| | gProtectStructs [ battler ] . flinchImmobility
| | gProtectStructs [ battler ] . confusionSelfDmg )
2017-10-06 17:06:45 +02:00
return TRUE ;
else
return FALSE ;
}
2018-02-06 02:46:59 +01:00
void PrepareStringBattle ( u16 stringId , u8 battler )
2017-10-06 17:06:45 +02:00
{
2018-02-06 02:46:59 +01:00
gActiveBattler = battler ;
2018-02-06 20:48:02 +01:00
BtlController_EmitPrintString ( 0 , stringId ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-10-06 17:06:45 +02:00
}
void ResetSentPokesToOpponentValue ( void )
{
s32 i ;
u32 bits = 0 ;
gSentPokesToOpponent [ 0 ] = 0 ;
gSentPokesToOpponent [ 1 ] = 0 ;
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + = 2 )
2018-02-06 20:48:02 +01:00
bits | = gBitTable [ gBattlerPartyIndexes [ i ] ] ;
2017-10-06 17:06:45 +02:00
2018-02-06 02:46:59 +01:00
for ( i = 1 ; i < gBattlersCount ; i + = 2 )
gSentPokesToOpponent [ ( i & BIT_FLANK ) > > 1 ] = bits ;
2017-10-06 17:06:45 +02:00
}
2018-02-06 02:46:59 +01:00
void sub_803F9EC ( u8 battler )
2017-10-06 17:06:45 +02:00
{
s32 i = 0 ;
u32 bits = 0 ;
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( battler ) = = B_SIDE_OPPONENT )
2017-10-06 17:06:45 +02:00
{
2018-02-06 02:46:59 +01:00
u8 flank = ( ( battler & BIT_FLANK ) > > 1 ) ;
gSentPokesToOpponent [ flank ] = 0 ;
2017-10-06 17:06:45 +02:00
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + = 2 )
2017-10-06 17:06:45 +02:00
{
2018-02-06 02:46:59 +01:00
if ( ! ( gAbsentBattlerFlags & gBitTable [ i ] ) )
2018-02-06 20:48:02 +01:00
bits | = gBitTable [ gBattlerPartyIndexes [ i ] ] ;
2017-10-06 17:06:45 +02:00
}
2018-02-06 02:46:59 +01:00
gSentPokesToOpponent [ flank ] = bits ;
2017-10-06 17:06:45 +02:00
}
}
2018-02-06 02:46:59 +01:00
void sub_803FA70 ( u8 battler )
2017-10-06 17:06:45 +02:00
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( battler ) = = B_SIDE_OPPONENT )
2017-10-06 17:06:45 +02:00
{
2018-02-06 02:46:59 +01:00
sub_803F9EC ( battler ) ;
2017-10-06 17:06:45 +02:00
}
else
{
s32 i ;
2018-02-06 02:46:59 +01:00
for ( i = 1 ; i < gBattlersCount ; i + + )
2018-02-06 20:48:02 +01:00
gSentPokesToOpponent [ ( i & BIT_FLANK ) > > 1 ] | = gBitTable [ gBattlerPartyIndexes [ battler ] ] ;
2017-10-06 17:06:45 +02:00
}
}
2017-09-17 14:10:32 +02:00
2018-07-01 11:15:42 +02:00
void BattleScriptPush ( const u8 * bsPtr )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleResources - > battleScriptsStack - > ptr [ gBattleResources - > battleScriptsStack - > size + + ] = bsPtr ;
2017-09-17 14:10:32 +02:00
}
2017-09-22 21:33:49 +02:00
void BattleScriptPushCursor ( void )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleResources - > battleScriptsStack - > ptr [ gBattleResources - > battleScriptsStack - > size + + ] = gBattlescriptCurrInstr ;
2017-09-17 14:10:32 +02:00
}
2017-09-22 21:33:49 +02:00
void BattleScriptPop ( void )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gBattlescriptCurrInstr = gBattleResources - > battleScriptsStack - > ptr [ - - gBattleResources - > battleScriptsStack - > size ] ;
2017-09-17 14:10:32 +02:00
}
2017-10-03 21:35:27 +02:00
u8 TrySetCantSelectMoveBattleScript ( void )
2017-09-17 14:10:32 +02:00
{
u8 limitations = 0 ;
2018-02-06 02:46:59 +01:00
u16 move = gBattleMons [ gActiveBattler ] . moves [ gBattleBufferB [ gActiveBattler ] [ 2 ] ] ;
2017-09-17 14:10:32 +02:00
u8 holdEffect ;
2018-02-06 02:46:59 +01:00
u16 * choicedMove = & gBattleStruct - > choicedMove [ gActiveBattler ] ;
2017-09-17 14:10:32 +02:00
2018-02-06 02:46:59 +01:00
if ( gDisableStructs [ gActiveBattler ] . disabledMove = = move & & move ! = 0 )
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = gActiveBattler ;
2017-09-17 14:10:32 +02:00
gCurrentMove = move ;
if ( gBattleTypeFlags & BATTLE_TYPE_PALACE )
{
2018-02-06 02:46:59 +01:00
gPalaceSelectionBattleScripts [ gActiveBattler ] = BattleScript_SelectingDisabledMoveInPalace ;
gProtectStructs [ gActiveBattler ] . flag_x10 = 1 ;
2017-09-17 14:10:32 +02:00
}
else
{
2018-02-06 02:46:59 +01:00
gSelectionBattleScripts [ gActiveBattler ] = BattleScript_SelectingDisabledMove ;
2017-09-17 14:10:32 +02:00
limitations = 1 ;
}
}
2018-02-06 02:46:59 +01:00
if ( move = = gLastMoves [ gActiveBattler ] & & move ! = MOVE_STRUGGLE & & ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_TORMENT ) )
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
CancelMultiTurnMoves ( gActiveBattler ) ;
2017-09-17 14:10:32 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_PALACE )
{
2018-02-06 02:46:59 +01:00
gPalaceSelectionBattleScripts [ gActiveBattler ] = BattleScript_SelectingTormentedMoveInPalace ;
gProtectStructs [ gActiveBattler ] . flag_x10 = 1 ;
2017-09-17 14:10:32 +02:00
}
else
{
2018-02-06 02:46:59 +01:00
gSelectionBattleScripts [ gActiveBattler ] = BattleScript_SelectingTormentedMove ;
2017-09-17 14:10:32 +02:00
limitations + + ;
}
}
2018-02-06 02:46:59 +01:00
if ( gDisableStructs [ gActiveBattler ] . tauntTimer1 ! = 0 & & gBattleMoves [ move ] . power = = 0 )
2017-09-17 14:10:32 +02:00
{
gCurrentMove = move ;
if ( gBattleTypeFlags & BATTLE_TYPE_PALACE )
{
2018-02-06 02:46:59 +01:00
gPalaceSelectionBattleScripts [ gActiveBattler ] = BattleScript_SelectingNotAllowedMoveTauntInPalace ;
gProtectStructs [ gActiveBattler ] . flag_x10 = 1 ;
2017-09-17 14:10:32 +02:00
}
else
{
2018-02-06 02:46:59 +01:00
gSelectionBattleScripts [ gActiveBattler ] = BattleScript_SelectingNotAllowedMoveTaunt ;
2017-09-17 14:10:32 +02:00
limitations + + ;
}
}
2018-02-06 02:46:59 +01:00
if ( GetImprisonedMovesCount ( gActiveBattler , move ) )
2017-09-17 14:10:32 +02:00
{
gCurrentMove = move ;
if ( gBattleTypeFlags & BATTLE_TYPE_PALACE )
{
2018-02-06 02:46:59 +01:00
gPalaceSelectionBattleScripts [ gActiveBattler ] = BattleScript_SelectingImprisionedMoveInPalace ;
gProtectStructs [ gActiveBattler ] . flag_x10 = 1 ;
2017-09-17 14:10:32 +02:00
}
else
{
2018-02-06 02:46:59 +01:00
gSelectionBattleScripts [ gActiveBattler ] = BattleScript_SelectingImprisionedMove ;
2017-09-17 14:10:32 +02:00
limitations + + ;
}
}
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . item = = ITEM_ENIGMA_BERRY )
holdEffect = gEnigmaBerries [ gActiveBattler ] . holdEffect ;
2017-09-17 14:10:32 +02:00
else
2018-02-06 02:46:59 +01:00
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ gActiveBattler ] . item ) ;
2017-09-17 14:10:32 +02:00
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gActiveBattler ;
2017-09-17 14:10:32 +02:00
if ( holdEffect = = HOLD_EFFECT_CHOICE_BAND & & * choicedMove ! = 0 & & * choicedMove ! = 0xFFFF & & * choicedMove ! = move )
{
gCurrentMove = * choicedMove ;
2018-02-06 02:46:59 +01:00
gLastUsedItem = gBattleMons [ gActiveBattler ] . item ;
2017-09-17 14:10:32 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_PALACE )
{
2018-02-06 02:46:59 +01:00
gProtectStructs [ gActiveBattler ] . flag_x10 = 1 ;
2017-09-17 14:10:32 +02:00
}
else
{
2018-02-06 02:46:59 +01:00
gSelectionBattleScripts [ gActiveBattler ] = BattleScript_SelectingNotAllowedMoveChoiceItem ;
2017-09-17 14:10:32 +02:00
limitations + + ;
}
}
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . pp [ gBattleBufferB [ gActiveBattler ] [ 2 ] ] = = 0 )
2017-09-17 14:10:32 +02:00
{
if ( gBattleTypeFlags & BATTLE_TYPE_PALACE )
{
2018-02-06 02:46:59 +01:00
gProtectStructs [ gActiveBattler ] . flag_x10 = 1 ;
2017-09-17 14:10:32 +02:00
}
else
{
2018-02-06 02:46:59 +01:00
gSelectionBattleScripts [ gActiveBattler ] = BattleScript_SelectingMoveWithNoPP ;
2017-09-17 14:10:32 +02:00
limitations + + ;
}
}
return limitations ;
}
2018-02-08 11:17:41 +01:00
u8 CheckMoveLimitations ( u8 battlerId , u8 unusableMoves , u8 check )
2017-09-17 14:10:32 +02:00
{
u8 holdEffect ;
2018-02-08 11:17:41 +01:00
u16 * choicedMove = & gBattleStruct - > choicedMove [ battlerId ] ;
2017-09-17 14:10:32 +02:00
s32 i ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . item = = ITEM_ENIGMA_BERRY )
holdEffect = gEnigmaBerries [ battlerId ] . holdEffect ;
2017-09-17 14:10:32 +02:00
else
2018-02-08 11:17:41 +01:00
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ battlerId ] . item ) ;
2017-09-17 14:10:32 +02:00
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = battlerId ;
2017-09-17 14:10:32 +02:00
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < MAX_BATTLERS_COUNT ; i + + )
2017-09-17 14:10:32 +02:00
{
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . moves [ i ] = = 0 & & check & MOVE_LIMITATION_ZEROMOVE )
2017-09-17 14:10:32 +02:00
unusableMoves | = gBitTable [ i ] ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . pp [ i ] = = 0 & & check & MOVE_LIMITATION_PP )
2017-09-17 14:10:32 +02:00
unusableMoves | = gBitTable [ i ] ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . moves [ i ] = = gDisableStructs [ battlerId ] . disabledMove & & check & MOVE_LIMITATION_DISABLED )
2017-09-17 14:10:32 +02:00
unusableMoves | = gBitTable [ i ] ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . moves [ i ] = = gLastMoves [ battlerId ] & & check & MOVE_LIMITATION_TORMENTED & & gBattleMons [ battlerId ] . status2 & STATUS2_TORMENT )
2017-09-17 14:10:32 +02:00
unusableMoves | = gBitTable [ i ] ;
2018-02-08 11:17:41 +01:00
if ( gDisableStructs [ battlerId ] . tauntTimer1 & & check & MOVE_LIMITATION_TAUNT & & gBattleMoves [ gBattleMons [ battlerId ] . moves [ i ] ] . power = = 0 )
2017-09-17 14:10:32 +02:00
unusableMoves | = gBitTable [ i ] ;
2018-02-08 11:17:41 +01:00
if ( GetImprisonedMovesCount ( battlerId , gBattleMons [ battlerId ] . moves [ i ] ) & & check & MOVE_LIMITATION_IMPRISION )
2017-09-17 14:10:32 +02:00
unusableMoves | = gBitTable [ i ] ;
2018-02-08 11:17:41 +01:00
if ( gDisableStructs [ battlerId ] . encoreTimer1 & & gDisableStructs [ battlerId ] . encoredMove ! = gBattleMons [ battlerId ] . moves [ i ] )
2017-09-17 14:10:32 +02:00
unusableMoves | = gBitTable [ i ] ;
2018-02-08 11:17:41 +01:00
if ( holdEffect = = HOLD_EFFECT_CHOICE_BAND & & * choicedMove ! = 0 & & * choicedMove ! = 0xFFFF & & * choicedMove ! = gBattleMons [ battlerId ] . moves [ i ] )
2017-09-17 14:10:32 +02:00
unusableMoves | = gBitTable [ i ] ;
}
return unusableMoves ;
}
bool8 AreAllMovesUnusable ( void )
{
u8 unusable ;
2018-02-06 02:46:59 +01:00
unusable = CheckMoveLimitations ( gActiveBattler , 0 , 0xFF ) ;
2017-09-17 14:10:32 +02:00
2018-07-01 11:15:42 +02:00
if ( unusable = = 0xF ) // All moves are unusable.
2017-09-17 14:10:32 +02:00
{
2018-07-07 19:57:09 +02:00
gProtectStructs [ gActiveBattler ] . noValidMoves = 1 ;
2018-02-06 02:46:59 +01:00
gSelectionBattleScripts [ gActiveBattler ] = BattleScript_NoMovesLeft ;
2017-09-17 14:10:32 +02:00
}
else
{
2018-07-07 19:57:09 +02:00
gProtectStructs [ gActiveBattler ] . noValidMoves = 0 ;
2017-09-17 14:10:32 +02:00
}
return ( unusable = = 0xF ) ;
}
2018-02-08 11:17:41 +01:00
u8 GetImprisonedMovesCount ( u8 battlerId , u16 move )
2017-09-17 14:10:32 +02:00
{
s32 i ;
u8 imprisionedMoves = 0 ;
2018-07-01 11:15:42 +02:00
u8 BattlerSide = GetBattlerSide ( battlerId ) ;
2017-09-17 14:10:32 +02:00
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
if ( BattlerSide ! = GetBattlerSide ( i ) & & gStatuses3 [ i ] & STATUS3_IMPRISONED_OTHERS )
2017-09-17 14:10:32 +02:00
{
s32 j ;
for ( j = 0 ; j < 4 ; j + + )
{
if ( move = = gBattleMons [ i ] . moves [ j ] )
break ;
}
if ( j < 4 )
imprisionedMoves + + ;
}
}
return imprisionedMoves ;
}
u8 UpdateTurnCounters ( void )
{
u8 effect = 0 ;
s32 i ;
2018-02-06 23:09:39 +01:00
for ( gBattlerAttacker = 0 ; gBattlerAttacker < gBattlersCount & & gAbsentBattlerFlags & gBitTable [ gBattlerAttacker ] ; gBattlerAttacker + + )
2017-09-17 14:10:32 +02:00
{
}
2018-02-06 23:09:39 +01:00
for ( gBattlerTarget = 0 ; gBattlerTarget < gBattlersCount & & gAbsentBattlerFlags & gBitTable [ gBattlerTarget ] ; gBattlerTarget + + )
2017-09-17 14:10:32 +02:00
{
}
do
{
2018-07-01 11:15:42 +02:00
u8 side ;
2017-09-17 14:10:32 +02:00
2018-02-07 22:53:40 +01:00
switch ( gBattleStruct - > turnCountersTracker )
2017-09-17 14:10:32 +02:00
{
case 0 :
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 14:10:32 +02:00
{
2018-06-28 21:06:32 +02:00
gBattlerByTurnOrder [ i ] = i ;
2017-09-17 14:10:32 +02:00
}
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount - 1 ; i + + )
2017-09-17 14:10:32 +02:00
{
s32 j ;
2018-02-06 02:46:59 +01:00
for ( j = i + 1 ; j < gBattlersCount ; j + + )
2017-09-17 14:10:32 +02:00
{
2018-06-28 21:06:32 +02:00
if ( GetWhoStrikesFirst ( gBattlerByTurnOrder [ i ] , gBattlerByTurnOrder [ j ] , 0 ) )
2017-10-04 19:25:14 +02:00
SwapTurnOrder ( i , j ) ;
2017-09-17 14:10:32 +02:00
}
}
// It's stupid, but won't match without it
{
2018-02-07 22:53:40 +01:00
u8 * var = & gBattleStruct - > turnCountersTracker ;
2017-09-17 14:10:32 +02:00
( * var ) + + ;
gBattleStruct - > turnSideTracker = 0 ;
}
// fall through
case 1 :
while ( gBattleStruct - > turnSideTracker < 2 )
{
2018-07-01 11:15:42 +02:00
side = gBattleStruct - > turnSideTracker ;
gActiveBattler = gBattlerAttacker = gSideTimers [ side ] . reflectBattlerId ;
if ( gSideStatuses [ side ] & SIDE_STATUS_REFLECT )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
if ( - - gSideTimers [ side ] . reflectTimer = = 0 )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
gSideStatuses [ side ] & = ~ SIDE_STATUS_REFLECT ;
2017-11-26 17:15:28 +01:00
BattleScriptExecute ( BattleScript_SideStatusWoreOff ) ;
2017-11-26 13:26:58 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , MOVE_REFLECT ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
}
gBattleStruct - > turnSideTracker + + ;
if ( effect )
break ;
}
if ( ! effect )
{
2018-02-07 22:53:40 +01:00
gBattleStruct - > turnCountersTracker + + ;
2017-09-17 14:10:32 +02:00
gBattleStruct - > turnSideTracker = 0 ;
}
break ;
case 2 :
while ( gBattleStruct - > turnSideTracker < 2 )
{
2018-07-01 11:15:42 +02:00
side = gBattleStruct - > turnSideTracker ;
gActiveBattler = gBattlerAttacker = gSideTimers [ side ] . lightscreenBattlerId ;
if ( gSideStatuses [ side ] & SIDE_STATUS_LIGHTSCREEN )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
if ( - - gSideTimers [ side ] . lightscreenTimer = = 0 )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
gSideStatuses [ side ] & = ~ SIDE_STATUS_LIGHTSCREEN ;
2017-11-26 17:15:28 +01:00
BattleScriptExecute ( BattleScript_SideStatusWoreOff ) ;
2018-07-01 11:15:42 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = side ;
2017-11-26 13:26:58 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , MOVE_LIGHT_SCREEN ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
}
gBattleStruct - > turnSideTracker + + ;
if ( effect )
break ;
}
if ( ! effect )
{
2018-02-07 22:53:40 +01:00
gBattleStruct - > turnCountersTracker + + ;
2017-09-17 14:10:32 +02:00
gBattleStruct - > turnSideTracker = 0 ;
}
break ;
case 3 :
while ( gBattleStruct - > turnSideTracker < 2 )
{
2018-07-01 11:15:42 +02:00
side = gBattleStruct - > turnSideTracker ;
gActiveBattler = gBattlerAttacker = gSideTimers [ side ] . mistBattlerId ;
if ( gSideTimers [ side ] . mistTimer ! = 0
& & - - gSideTimers [ side ] . mistTimer = = 0 )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
gSideStatuses [ side ] & = ~ SIDE_STATUS_MIST ;
2017-11-26 17:15:28 +01:00
BattleScriptExecute ( BattleScript_SideStatusWoreOff ) ;
2018-07-01 11:15:42 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = side ;
2017-11-26 13:26:58 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , MOVE_MIST ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
gBattleStruct - > turnSideTracker + + ;
if ( effect )
break ;
}
if ( ! effect )
{
2018-02-07 22:53:40 +01:00
gBattleStruct - > turnCountersTracker + + ;
2017-09-17 14:10:32 +02:00
gBattleStruct - > turnSideTracker = 0 ;
}
break ;
case 4 :
while ( gBattleStruct - > turnSideTracker < 2 )
{
2018-07-01 11:15:42 +02:00
side = gBattleStruct - > turnSideTracker ;
gActiveBattler = gBattlerAttacker = gSideTimers [ side ] . safeguardBattlerId ;
if ( gSideStatuses [ side ] & SIDE_STATUS_SAFEGUARD )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
if ( - - gSideTimers [ side ] . safeguardTimer = = 0 )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
gSideStatuses [ side ] & = ~ SIDE_STATUS_SAFEGUARD ;
2017-11-26 17:15:28 +01:00
BattleScriptExecute ( BattleScript_SafeguardEnds ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
}
gBattleStruct - > turnSideTracker + + ;
if ( effect )
break ;
}
if ( ! effect )
{
2018-02-07 22:53:40 +01:00
gBattleStruct - > turnCountersTracker + + ;
2017-09-17 14:10:32 +02:00
gBattleStruct - > turnSideTracker = 0 ;
}
break ;
case 5 :
2018-02-06 02:46:59 +01:00
while ( gBattleStruct - > turnSideTracker < gBattlersCount )
2017-09-17 14:10:32 +02:00
{
2018-06-28 21:06:32 +02:00
gActiveBattler = gBattlerByTurnOrder [ gBattleStruct - > turnSideTracker ] ;
2018-02-06 02:46:59 +01:00
if ( gWishFutureKnock . wishCounter [ gActiveBattler ] ! = 0
& & - - gWishFutureKnock . wishCounter [ gActiveBattler ] = = 0
& & gBattleMons [ gActiveBattler ] . hp ! = 0 )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gBattlerTarget = gActiveBattler ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_WishComesTrue ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
gBattleStruct - > turnSideTracker + + ;
if ( effect )
break ;
}
if ( ! effect )
{
2018-02-07 22:53:40 +01:00
gBattleStruct - > turnCountersTracker + + ;
2017-09-17 14:10:32 +02:00
}
break ;
case 6 :
if ( gBattleWeather & WEATHER_RAIN_ANY )
{
if ( ! ( gBattleWeather & WEATHER_RAIN_PERMANENT ) )
{
if ( - - gWishFutureKnock . weatherDuration = = 0 )
{
gBattleWeather & = ~ WEATHER_RAIN_TEMPORARY ;
gBattleWeather & = ~ WEATHER_RAIN_DOWNPOUR ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
}
else if ( gBattleWeather & WEATHER_RAIN_DOWNPOUR )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
else if ( gBattleWeather & WEATHER_RAIN_DOWNPOUR )
2017-11-26 17:15:28 +01:00
{
2017-09-17 14:10:32 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
2017-11-26 17:15:28 +01:00
}
2017-09-17 14:10:32 +02:00
else
2017-11-26 17:15:28 +01:00
{
2017-09-17 14:10:32 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
2017-11-26 17:15:28 +01:00
}
BattleScriptExecute ( BattleScript_RainContinuesOrEnds ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
2018-02-07 22:53:40 +01:00
gBattleStruct - > turnCountersTracker + + ;
2017-09-17 14:10:32 +02:00
break ;
case 7 :
if ( gBattleWeather & WEATHER_SANDSTORM_ANY )
{
if ( ! ( gBattleWeather & WEATHER_SANDSTORM_PERMANENT ) & & - - gWishFutureKnock . weatherDuration = = 0 )
{
gBattleWeather & = ~ WEATHER_SANDSTORM_TEMPORARY ;
2017-11-26 17:15:28 +01:00
gBattlescriptCurrInstr = BattleScript_SandStormHailEnds ;
2017-09-17 14:10:32 +02:00
}
else
2017-11-26 17:15:28 +01:00
{
gBattlescriptCurrInstr = BattleScript_DamagingWeatherContinues ;
}
2017-09-17 14:10:32 +02:00
2017-11-26 17:15:28 +01:00
gBattleScripting . animArg1 = B_ANIM_SANDSTORM_CONTINUES ;
2017-09-17 14:10:32 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( gBattlescriptCurrInstr ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
2018-02-07 22:53:40 +01:00
gBattleStruct - > turnCountersTracker + + ;
2017-09-17 14:10:32 +02:00
break ;
case 8 :
if ( gBattleWeather & WEATHER_SUN_ANY )
{
if ( ! ( gBattleWeather & WEATHER_SUN_PERMANENT ) & & - - gWishFutureKnock . weatherDuration = = 0 )
{
gBattleWeather & = ~ WEATHER_SUN_TEMPORARY ;
2017-11-26 17:15:28 +01:00
gBattlescriptCurrInstr = BattleScript_SunlightFaded ;
2017-09-17 14:10:32 +02:00
}
else
2017-11-26 17:15:28 +01:00
{
gBattlescriptCurrInstr = BattleScript_SunlightContinues ;
}
2017-09-17 14:10:32 +02:00
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( gBattlescriptCurrInstr ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
2018-02-07 22:53:40 +01:00
gBattleStruct - > turnCountersTracker + + ;
2017-09-17 14:10:32 +02:00
break ;
case 9 :
if ( gBattleWeather & WEATHER_HAIL )
{
if ( - - gWishFutureKnock . weatherDuration = = 0 )
{
gBattleWeather & = ~ WEATHER_HAIL ;
2017-11-26 17:15:28 +01:00
gBattlescriptCurrInstr = BattleScript_SandStormHailEnds ;
2017-09-17 14:10:32 +02:00
}
else
2017-11-26 13:26:58 +01:00
{
2017-11-26 17:15:28 +01:00
gBattlescriptCurrInstr = BattleScript_DamagingWeatherContinues ;
2017-11-26 13:26:58 +01:00
}
2017-09-17 14:10:32 +02:00
2017-11-26 13:26:58 +01:00
gBattleScripting . animArg1 = B_ANIM_HAIL_CONTINUES ;
2017-09-17 14:10:32 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( gBattlescriptCurrInstr ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
2018-02-07 22:53:40 +01:00
gBattleStruct - > turnCountersTracker + + ;
2017-09-17 14:10:32 +02:00
break ;
case 10 :
effect + + ;
break ;
}
} while ( effect = = 0 ) ;
return ( gBattleMainFunc ! = BattleTurnPassed ) ;
}
# define TURNBASED_MAX_CASE 19
u8 TurnBasedEffects ( void )
{
u8 effect = 0 ;
gHitMarker | = ( HITMARKER_GRUDGE | HITMARKER_x20 ) ;
2018-02-07 22:53:40 +01:00
while ( gBattleStruct - > turnEffectsBattlerId < gBattlersCount & & gBattleStruct - > turnEffectsTracker < = TURNBASED_MAX_CASE )
2017-09-17 14:10:32 +02:00
{
2018-06-28 21:06:32 +02:00
gActiveBattler = gBattlerAttacker = gBattlerByTurnOrder [ gBattleStruct - > turnEffectsBattlerId ] ;
2018-02-06 02:46:59 +01:00
if ( gAbsentBattlerFlags & gBitTable [ gActiveBattler ] )
2017-09-17 14:10:32 +02:00
{
2018-02-07 22:53:40 +01:00
gBattleStruct - > turnEffectsBattlerId + + ;
2017-09-17 14:10:32 +02:00
}
else
{
switch ( gBattleStruct - > turnEffectsTracker )
{
case 0 : // ingrain
2018-02-06 02:46:59 +01:00
if ( ( gStatuses3 [ gActiveBattler ] & STATUS3_ROOTED )
& & gBattleMons [ gActiveBattler ] . hp ! = gBattleMons [ gActiveBattler ] . maxHP
& & gBattleMons [ gActiveBattler ] . hp ! = 0 )
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gBattleMons [ gActiveBattler ] . maxHP / 16 ;
2017-09-17 14:10:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleMoveDamage * = - 1 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_IngrainTurnHeal ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
gBattleStruct - > turnEffectsTracker + + ;
break ;
case 1 : // end turn abilities
2018-02-06 02:46:59 +01:00
if ( AbilityBattleEffects ( ABILITYEFFECT_ENDTURN , gActiveBattler , 0 , 0 , 0 ) )
2017-09-17 14:10:32 +02:00
effect + + ;
gBattleStruct - > turnEffectsTracker + + ;
break ;
case 2 : // item effects
2018-02-06 02:46:59 +01:00
if ( ItemBattleEffects ( 1 , gActiveBattler , 0 ) )
2017-09-17 14:10:32 +02:00
effect + + ;
gBattleStruct - > turnEffectsTracker + + ;
break ;
case 18 : // item effects again
2018-02-06 02:46:59 +01:00
if ( ItemBattleEffects ( 1 , gActiveBattler , 1 ) )
2017-09-17 14:10:32 +02:00
effect + + ;
gBattleStruct - > turnEffectsTracker + + ;
break ;
case 3 : // leech seed
2018-02-06 02:46:59 +01:00
if ( ( gStatuses3 [ gActiveBattler ] & STATUS3_LEECHSEED )
2018-07-01 11:15:42 +02:00
& & gBattleMons [ gStatuses3 [ gActiveBattler ] & STATUS3_LEECHSEED_BATTLER ] . hp ! = 0
2018-02-06 02:46:59 +01:00
& & gBattleMons [ gActiveBattler ] . hp ! = 0 )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
gBattlerTarget = gStatuses3 [ gActiveBattler ] & STATUS3_LEECHSEED_BATTLER ; // Notice gBattlerTarget is actually the HP receiver.
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gBattleMons [ gActiveBattler ] . maxHP / 8 ;
2017-09-17 14:10:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2018-02-06 23:09:39 +01:00
gBattleScripting . animArg1 = gBattlerTarget ;
gBattleScripting . animArg2 = gBattlerAttacker ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_LeechSeedTurnDrain ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
gBattleStruct - > turnEffectsTracker + + ;
break ;
case 4 : // poison
2018-02-06 02:46:59 +01:00
if ( ( gBattleMons [ gActiveBattler ] . status1 & STATUS1_POISON ) & & gBattleMons [ gActiveBattler ] . hp ! = 0 )
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gBattleMons [ gActiveBattler ] . maxHP / 8 ;
2017-09-17 14:10:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_PoisonTurnDmg ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
gBattleStruct - > turnEffectsTracker + + ;
break ;
case 5 : // toxic poison
2018-02-06 02:46:59 +01:00
if ( ( gBattleMons [ gActiveBattler ] . status1 & STATUS1_TOXIC_POISON ) & & gBattleMons [ gActiveBattler ] . hp ! = 0 )
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gBattleMons [ gActiveBattler ] . maxHP / 16 ;
2017-09-17 14:10:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2018-02-06 02:46:59 +01:00
if ( ( gBattleMons [ gActiveBattler ] . status1 & 0xF00 ) ! = 0xF00 ) // not 16 turns
gBattleMons [ gActiveBattler ] . status1 + = 0x100 ;
gBattleMoveDamage * = ( gBattleMons [ gActiveBattler ] . status1 & 0xF00 ) > > 8 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_PoisonTurnDmg ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
gBattleStruct - > turnEffectsTracker + + ;
break ;
case 6 : // burn
2018-02-06 02:46:59 +01:00
if ( ( gBattleMons [ gActiveBattler ] . status1 & STATUS1_BURN ) & & gBattleMons [ gActiveBattler ] . hp ! = 0 )
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gBattleMons [ gActiveBattler ] . maxHP / 8 ;
2017-09-17 14:10:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BurnTurnDmg ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
gBattleStruct - > turnEffectsTracker + + ;
break ;
case 7 : // spooky nightmares
2018-02-06 02:46:59 +01:00
if ( ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_NIGHTMARE ) & & gBattleMons [ gActiveBattler ] . hp ! = 0 )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
// R/S does not perform this sleep check, which causes the nightmare effect to
// persist even after the affected Pokemon has been awakened by Shed Skin.
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . status1 & STATUS1_SLEEP )
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gBattleMons [ gActiveBattler ] . maxHP / 4 ;
2017-09-17 14:10:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_NightmareTurnDmg ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
else
{
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . status2 & = ~ STATUS2_NIGHTMARE ;
2017-09-17 14:10:32 +02:00
}
}
gBattleStruct - > turnEffectsTracker + + ;
break ;
case 8 : // curse
2018-02-06 02:46:59 +01:00
if ( ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_CURSED ) & & gBattleMons [ gActiveBattler ] . hp ! = 0 )
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gBattleMons [ gActiveBattler ] . maxHP / 4 ;
2017-09-17 14:10:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_CurseTurnDmg ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
gBattleStruct - > turnEffectsTracker + + ;
break ;
case 9 : // wrap
2018-02-06 02:46:59 +01:00
if ( ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_WRAPPED ) & & gBattleMons [ gActiveBattler ] . hp ! = 0 )
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . status2 - = 0x2000 ;
if ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_WRAPPED ) // damaged by wrap
2017-09-17 14:10:32 +02:00
{
// This is the only way I could get this array access to match.
2018-02-06 02:46:59 +01:00
gBattleScripting . animArg1 = * ( gBattleStruct - > wrappedMove + gActiveBattler * 2 + 0 ) ;
gBattleScripting . animArg2 = * ( gBattleStruct - > wrappedMove + gActiveBattler * 2 + 1 ) ;
2017-11-26 13:26:58 +01:00
gBattleTextBuff1 [ 0 ] = B_BUFF_PLACEHOLDER_BEGIN ;
gBattleTextBuff1 [ 1 ] = B_BUFF_MOVE ;
2018-02-06 02:46:59 +01:00
gBattleTextBuff1 [ 2 ] = * ( gBattleStruct - > wrappedMove + gActiveBattler * 2 + 0 ) ;
gBattleTextBuff1 [ 3 ] = * ( gBattleStruct - > wrappedMove + gActiveBattler * 2 + 1 ) ;
2017-09-17 14:10:32 +02:00
gBattleTextBuff1 [ 4 ] = EOS ;
gBattlescriptCurrInstr = BattleScript_WrapTurnDmg ;
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gBattleMons [ gActiveBattler ] . maxHP / 16 ;
2017-09-17 14:10:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
}
else // broke free
{
2017-11-26 13:26:58 +01:00
gBattleTextBuff1 [ 0 ] = B_BUFF_PLACEHOLDER_BEGIN ;
gBattleTextBuff1 [ 1 ] = B_BUFF_MOVE ;
2018-02-06 02:46:59 +01:00
gBattleTextBuff1 [ 2 ] = * ( gBattleStruct - > wrappedMove + gActiveBattler * 2 + 0 ) ;
gBattleTextBuff1 [ 3 ] = * ( gBattleStruct - > wrappedMove + gActiveBattler * 2 + 1 ) ;
2017-09-17 14:10:32 +02:00
gBattleTextBuff1 [ 4 ] = EOS ;
gBattlescriptCurrInstr = BattleScript_WrapEnds ;
}
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( gBattlescriptCurrInstr ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
gBattleStruct - > turnEffectsTracker + + ;
break ;
case 10 : // uproar
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_UPROAR )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
for ( gBattlerAttacker = 0 ; gBattlerAttacker < gBattlersCount ; gBattlerAttacker + + )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
if ( ( gBattleMons [ gBattlerAttacker ] . status1 & STATUS1_SLEEP )
& & gBattleMons [ gBattlerAttacker ] . ability ! = ABILITY_SOUNDPROOF )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status1 & = ~ ( STATUS1_SLEEP ) ;
gBattleMons [ gBattlerAttacker ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
2017-09-17 14:10:32 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
2017-11-26 17:26:11 +01:00
BattleScriptExecute ( BattleScript_MonWokeUpInUproar ) ;
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gActiveBattler ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-17 14:10:32 +02:00
break ;
}
}
2018-02-06 23:09:39 +01:00
if ( gBattlerAttacker ! = gBattlersCount )
2017-09-17 14:10:32 +02:00
{
effect = 2 ; // a pokemon was awaken
break ;
}
else
{
2018-02-06 23:09:39 +01:00
gBattlerAttacker = gActiveBattler ;
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . status2 - = 0x10 ; // uproar timer goes down
if ( WasUnableToUseMove ( gActiveBattler ) )
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
CancelMultiTurnMoves ( gActiveBattler ) ;
2017-09-17 14:10:32 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
2018-02-06 02:46:59 +01:00
else if ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_UPROAR )
2017-09-17 14:10:32 +02:00
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . status2 | = STATUS2_MULTIPLETURNS ;
2017-09-17 14:10:32 +02:00
}
else
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
2018-02-06 02:46:59 +01:00
CancelMultiTurnMoves ( gActiveBattler ) ;
2017-09-17 14:10:32 +02:00
}
2017-11-26 17:26:11 +01:00
BattleScriptExecute ( BattleScript_PrintUproarOverTurns ) ;
2017-09-17 14:10:32 +02:00
effect = 1 ;
}
}
if ( effect ! = 2 )
gBattleStruct - > turnEffectsTracker + + ;
break ;
case 11 : // thrash
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_LOCK_CONFUSE )
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . status2 - = 0x400 ;
if ( WasUnableToUseMove ( gActiveBattler ) )
CancelMultiTurnMoves ( gActiveBattler ) ;
else if ( ! ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_LOCK_CONFUSE )
& & ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_MULTIPLETURNS ) )
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . status2 & = ~ ( STATUS2_MULTIPLETURNS ) ;
if ( ! ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_CONFUSION ) )
2017-09-17 14:10:32 +02:00
{
2017-11-26 13:26:58 +01:00
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_CONFUSION | MOVE_EFFECT_AFFECTS_USER ;
2017-09-17 14:10:32 +02:00
SetMoveEffect ( 1 , 0 ) ;
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_CONFUSION )
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_ThrashConfuses ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
}
}
gBattleStruct - > turnEffectsTracker + + ;
break ;
case 12 : // disable
2018-02-06 02:46:59 +01:00
if ( gDisableStructs [ gActiveBattler ] . disableTimer1 ! = 0 )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
s32 i ;
2017-09-17 14:10:32 +02:00
for ( i = 0 ; i < 4 ; i + + )
{
2018-02-06 02:46:59 +01:00
if ( gDisableStructs [ gActiveBattler ] . disabledMove = = gBattleMons [ gActiveBattler ] . moves [ i ] )
2017-09-17 14:10:32 +02:00
break ;
}
if ( i = = 4 ) // pokemon does not have the disabled move anymore
{
2018-02-06 02:46:59 +01:00
gDisableStructs [ gActiveBattler ] . disabledMove = 0 ;
gDisableStructs [ gActiveBattler ] . disableTimer1 = 0 ;
2017-09-17 14:10:32 +02:00
}
2018-02-06 02:46:59 +01:00
else if ( - - gDisableStructs [ gActiveBattler ] . disableTimer1 = = 0 ) // disable ends
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
gDisableStructs [ gActiveBattler ] . disabledMove = 0 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_DisabledNoMore ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
}
gBattleStruct - > turnEffectsTracker + + ;
break ;
case 13 : // encore
2018-02-06 02:46:59 +01:00
if ( gDisableStructs [ gActiveBattler ] . encoreTimer1 ! = 0 )
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . moves [ gDisableStructs [ gActiveBattler ] . encoredMovePos ] ! = gDisableStructs [ gActiveBattler ] . encoredMove ) // pokemon does not have the encored move anymore
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
gDisableStructs [ gActiveBattler ] . encoredMove = 0 ;
gDisableStructs [ gActiveBattler ] . encoreTimer1 = 0 ;
2017-09-17 14:10:32 +02:00
}
2018-02-06 02:46:59 +01:00
else if ( - - gDisableStructs [ gActiveBattler ] . encoreTimer1 = = 0
| | gBattleMons [ gActiveBattler ] . pp [ gDisableStructs [ gActiveBattler ] . encoredMovePos ] = = 0 )
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
gDisableStructs [ gActiveBattler ] . encoredMove = 0 ;
gDisableStructs [ gActiveBattler ] . encoreTimer1 = 0 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_EncoredNoMore ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
}
gBattleStruct - > turnEffectsTracker + + ;
break ;
case 14 : // lock-on decrement
2018-02-06 02:46:59 +01:00
if ( gStatuses3 [ gActiveBattler ] & STATUS3_ALWAYS_HITS )
gStatuses3 [ gActiveBattler ] - = 0x8 ;
2017-09-17 14:10:32 +02:00
gBattleStruct - > turnEffectsTracker + + ;
break ;
case 15 : // charge
2018-02-06 02:46:59 +01:00
if ( gDisableStructs [ gActiveBattler ] . chargeTimer1 & & - - gDisableStructs [ gActiveBattler ] . chargeTimer1 = = 0 )
gStatuses3 [ gActiveBattler ] & = ~ STATUS3_CHARGED_UP ;
2017-09-17 14:10:32 +02:00
gBattleStruct - > turnEffectsTracker + + ;
break ;
case 16 : // taunt
2018-02-06 02:46:59 +01:00
if ( gDisableStructs [ gActiveBattler ] . tauntTimer1 )
gDisableStructs [ gActiveBattler ] . tauntTimer1 - - ;
2017-09-17 14:10:32 +02:00
gBattleStruct - > turnEffectsTracker + + ;
break ;
case 17 : // yawn
2018-02-06 02:46:59 +01:00
if ( gStatuses3 [ gActiveBattler ] & STATUS3_YAWN )
{
gStatuses3 [ gActiveBattler ] - = 0x800 ;
if ( ! ( gStatuses3 [ gActiveBattler ] & STATUS3_YAWN ) & & ! ( gBattleMons [ gActiveBattler ] . status1 & STATUS1_ANY )
& & gBattleMons [ gActiveBattler ] . ability ! = ABILITY_VITAL_SPIRIT
& & gBattleMons [ gActiveBattler ] . ability ! = ABILITY_INSOMNIA & & ! UproarWakeUpCheck ( gActiveBattler ) )
{
CancelMultiTurnMoves ( gActiveBattler ) ;
gBattleMons [ gActiveBattler ] . status1 | = ( Random ( ) & 3 ) + 2 ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gActiveBattler ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2018-02-08 11:17:41 +01:00
gEffectBattler = gActiveBattler ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_YawnMakesAsleep ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
}
gBattleStruct - > turnEffectsTracker + + ;
break ;
case 19 : // done
gBattleStruct - > turnEffectsTracker = 0 ;
2018-02-07 22:53:40 +01:00
gBattleStruct - > turnEffectsBattlerId + + ;
2017-09-17 14:10:32 +02:00
break ;
}
if ( effect ! = 0 )
return effect ;
}
}
gHitMarker & = ~ ( HITMARKER_GRUDGE | HITMARKER_x20 ) ;
return 0 ;
}
2017-12-02 14:08:55 +01:00
bool8 HandleWishPerishSongOnTurnEnd ( void )
2017-09-17 14:10:32 +02:00
{
gHitMarker | = ( HITMARKER_GRUDGE | HITMARKER_x20 ) ;
2017-12-02 14:08:55 +01:00
switch ( gBattleStruct - > wishPerishSongState )
2017-09-17 14:10:32 +02:00
{
case 0 :
2018-02-07 22:53:40 +01:00
while ( gBattleStruct - > wishPerishSongBattlerId < gBattlersCount )
2017-09-17 14:10:32 +02:00
{
2018-02-07 22:53:40 +01:00
gActiveBattler = gBattleStruct - > wishPerishSongBattlerId ;
2018-02-06 02:46:59 +01:00
if ( gAbsentBattlerFlags & gBitTable [ gActiveBattler ] )
2017-09-17 14:10:32 +02:00
{
2018-02-07 22:53:40 +01:00
gBattleStruct - > wishPerishSongBattlerId + + ;
2017-09-17 14:10:32 +02:00
continue ;
}
2018-02-07 22:53:40 +01:00
gBattleStruct - > wishPerishSongBattlerId + + ;
2018-02-06 02:46:59 +01:00
if ( gWishFutureKnock . futureSightCounter [ gActiveBattler ] ! = 0
& & - - gWishFutureKnock . futureSightCounter [ gActiveBattler ] = = 0
& & gBattleMons [ gActiveBattler ] . hp ! = 0 )
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gWishFutureKnock . futureSightMove [ gActiveBattler ] = = MOVE_FUTURE_SIGHT )
2017-09-17 14:10:32 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
2018-02-06 02:46:59 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , gWishFutureKnock . futureSightMove [ gActiveBattler ] ) ;
2017-11-26 13:26:58 +01:00
2018-02-06 23:09:39 +01:00
gBattlerTarget = gActiveBattler ;
gBattlerAttacker = gWishFutureKnock . futureSightAttacker [ gActiveBattler ] ;
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gWishFutureKnock . futureSightDmg [ gActiveBattler ] ;
2018-02-07 22:53:40 +01:00
gSpecialStatuses [ gBattlerTarget ] . dmg = 0xFFFF ;
2017-11-26 17:26:11 +01:00
BattleScriptExecute ( BattleScript_MonTookFutureAttack ) ;
2017-09-17 14:10:32 +02:00
2018-02-06 02:46:59 +01:00
if ( gWishFutureKnock . futureSightCounter [ gActiveBattler ] = = 0
& & gWishFutureKnock . futureSightCounter [ gActiveBattler ^ BIT_FLANK ] = = 0 )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gSideStatuses [ GET_BATTLER_SIDE ( gBattlerTarget ) ] & = ~ ( SIDE_STATUS_FUTUREATTACK ) ;
2017-09-17 14:10:32 +02:00
}
2017-11-26 13:26:58 +01:00
return TRUE ;
2017-09-17 14:10:32 +02:00
}
}
// Why do I have to keep doing this to match?
{
2017-12-02 14:08:55 +01:00
u8 * state = & gBattleStruct - > wishPerishSongState ;
* state = 1 ;
2018-02-07 22:53:40 +01:00
gBattleStruct - > wishPerishSongBattlerId = 0 ;
2017-09-17 14:10:32 +02:00
}
// fall through
case 1 :
2018-02-07 22:53:40 +01:00
while ( gBattleStruct - > wishPerishSongBattlerId < gBattlersCount )
2017-09-17 14:10:32 +02:00
{
2018-06-28 21:06:32 +02:00
gActiveBattler = gBattlerAttacker = gBattlerByTurnOrder [ gBattleStruct - > wishPerishSongBattlerId ] ;
2018-02-06 02:46:59 +01:00
if ( gAbsentBattlerFlags & gBitTable [ gActiveBattler ] )
2017-09-17 14:10:32 +02:00
{
2018-02-07 22:53:40 +01:00
gBattleStruct - > wishPerishSongBattlerId + + ;
2017-09-17 14:10:32 +02:00
continue ;
}
2018-02-07 22:53:40 +01:00
gBattleStruct - > wishPerishSongBattlerId + + ;
2018-02-06 02:46:59 +01:00
if ( gStatuses3 [ gActiveBattler ] & STATUS3_PERISH_SONG )
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
PREPARE_BYTE_NUMBER_BUFFER ( gBattleTextBuff1 , 1 , gDisableStructs [ gActiveBattler ] . perishSongTimer1 ) ;
if ( gDisableStructs [ gActiveBattler ] . perishSongTimer1 = = 0 )
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
gStatuses3 [ gActiveBattler ] & = ~ STATUS3_PERISH_SONG ;
gBattleMoveDamage = gBattleMons [ gActiveBattler ] . hp ;
2017-11-26 17:26:11 +01:00
gBattlescriptCurrInstr = BattleScript_PerishSongTakesLife ;
2017-09-17 14:10:32 +02:00
}
else
{
2018-02-06 02:46:59 +01:00
gDisableStructs [ gActiveBattler ] . perishSongTimer1 - - ;
2017-11-26 17:26:11 +01:00
gBattlescriptCurrInstr = BattleScript_PerishSongCountGoesDown ;
2017-09-17 14:10:32 +02:00
}
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( gBattlescriptCurrInstr ) ;
2017-11-26 13:26:58 +01:00
return TRUE ;
2017-09-17 14:10:32 +02:00
}
}
// Hm...
{
2017-12-02 14:08:55 +01:00
u8 * state = & gBattleStruct - > wishPerishSongState ;
* state = 2 ;
2018-02-07 22:53:40 +01:00
gBattleStruct - > wishPerishSongBattlerId = 0 ;
2017-09-17 14:10:32 +02:00
}
// fall through
case 2 :
if ( ( gBattleTypeFlags & BATTLE_TYPE_ARENA )
2017-09-17 15:19:15 +02:00
& & gBattleStruct - > field_DA = = 2
2017-09-17 14:10:32 +02:00
& & gBattleMons [ 0 ] . hp ! = 0 & & gBattleMons [ 1 ] . hp ! = 0 )
{
s32 i ;
for ( i = 0 ; i < 2 ; i + + )
CancelMultiTurnMoves ( i ) ;
2017-11-25 18:42:31 +01:00
gBattlescriptCurrInstr = BattleScript_82DB8F3 ;
BattleScriptExecute ( BattleScript_82DB8F3 ) ;
2017-12-02 14:08:55 +01:00
gBattleStruct - > wishPerishSongState + + ;
2017-11-26 13:26:58 +01:00
return TRUE ;
2017-09-17 14:10:32 +02:00
}
break ;
}
gHitMarker & = ~ ( HITMARKER_GRUDGE | HITMARKER_x20 ) ;
2017-11-26 13:26:58 +01:00
return FALSE ;
2017-09-17 14:10:32 +02:00
}
2017-12-02 14:08:55 +01:00
# define FAINTED_ACTIONS_MAX_CASE 7
2017-09-17 14:10:32 +02:00
2017-12-02 14:08:55 +01:00
bool8 HandleFaintedMonActions ( void )
2017-09-17 14:10:32 +02:00
{
if ( gBattleTypeFlags & BATTLE_TYPE_SAFARI )
return FALSE ;
do
{
2018-07-01 11:15:42 +02:00
s32 i ;
2017-12-02 14:08:55 +01:00
switch ( gBattleStruct - > faintedActionsState )
2017-09-17 14:10:32 +02:00
{
case 0 :
2018-02-07 22:53:40 +01:00
gBattleStruct - > faintedActionsBattlerId = 0 ;
2017-12-02 14:08:55 +01:00
gBattleStruct - > faintedActionsState + + ;
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
if ( gAbsentBattlerFlags & gBitTable [ i ] & & ! HasNoMonsToSwitch ( i , 6 , 6 ) )
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags & = ~ ( gBitTable [ i ] ) ;
2017-09-17 14:10:32 +02:00
}
// fall through
case 1 :
do
{
2018-02-08 11:17:41 +01:00
gBattlerFainted = gBattlerTarget = gBattleStruct - > faintedActionsBattlerId ;
2018-02-07 22:53:40 +01:00
if ( gBattleMons [ gBattleStruct - > faintedActionsBattlerId ] . hp = = 0
& & ! ( gBattleStruct - > field_DF & gBitTable [ gBattlerPartyIndexes [ gBattleStruct - > faintedActionsBattlerId ] ] )
& & ! ( gAbsentBattlerFlags & gBitTable [ gBattleStruct - > faintedActionsBattlerId ] ) )
2017-09-17 14:10:32 +02:00
{
2017-12-02 14:08:55 +01:00
BattleScriptExecute ( BattleScript_GiveExp ) ;
gBattleStruct - > faintedActionsState = 2 ;
2017-09-17 14:10:32 +02:00
return TRUE ;
}
2018-02-07 22:53:40 +01:00
} while ( + + gBattleStruct - > faintedActionsBattlerId ! = gBattlersCount ) ;
2017-12-02 14:08:55 +01:00
gBattleStruct - > faintedActionsState = 3 ;
2017-09-17 14:10:32 +02:00
break ;
case 2 :
2018-02-08 11:17:41 +01:00
sub_803F9EC ( gBattlerFainted ) ;
2018-02-07 22:53:40 +01:00
if ( + + gBattleStruct - > faintedActionsBattlerId = = gBattlersCount )
2017-12-02 14:08:55 +01:00
gBattleStruct - > faintedActionsState = 3 ;
2017-09-17 14:10:32 +02:00
else
2017-12-02 14:08:55 +01:00
gBattleStruct - > faintedActionsState = 1 ;
2017-09-17 14:10:32 +02:00
break ;
case 3 :
2018-02-07 22:53:40 +01:00
gBattleStruct - > faintedActionsBattlerId = 0 ;
2017-12-02 14:08:55 +01:00
gBattleStruct - > faintedActionsState + + ;
2017-09-17 14:10:32 +02:00
// fall through
case 4 :
do
{
2018-02-08 11:17:41 +01:00
gBattlerFainted = gBattlerTarget = gBattleStruct - > faintedActionsBattlerId ;
2018-02-07 22:53:40 +01:00
if ( gBattleMons [ gBattleStruct - > faintedActionsBattlerId ] . hp = = 0
& & ! ( gAbsentBattlerFlags & gBitTable [ gBattleStruct - > faintedActionsBattlerId ] ) )
2017-09-17 14:10:32 +02:00
{
2017-12-02 14:08:55 +01:00
BattleScriptExecute ( BattleScript_HandleFaintedMon ) ;
gBattleStruct - > faintedActionsState = 5 ;
2017-09-17 14:10:32 +02:00
return TRUE ;
}
2018-02-07 22:53:40 +01:00
} while ( + + gBattleStruct - > faintedActionsBattlerId ! = gBattlersCount ) ;
2017-12-02 14:08:55 +01:00
gBattleStruct - > faintedActionsState = 6 ;
2017-09-17 14:10:32 +02:00
break ;
case 5 :
2018-02-07 22:53:40 +01:00
if ( + + gBattleStruct - > faintedActionsBattlerId = = gBattlersCount )
2017-12-02 14:08:55 +01:00
gBattleStruct - > faintedActionsState = 6 ;
2017-09-17 14:10:32 +02:00
else
2017-12-02 14:08:55 +01:00
gBattleStruct - > faintedActionsState = 4 ;
2017-09-17 14:10:32 +02:00
break ;
case 6 :
2017-09-17 15:19:15 +02:00
if ( AbilityBattleEffects ( ABILITYEFFECT_INTIMIDATE1 , 0 , 0 , 0 , 0 ) | | AbilityBattleEffects ( ABILITYEFFECT_TRACE , 0 , 0 , 0 , 0 ) | | ItemBattleEffects ( 1 , 0 , 1 ) | | AbilityBattleEffects ( ABILITYEFFECT_FORECAST , 0 , 0 , 0 , 0 ) )
2017-09-17 14:10:32 +02:00
return TRUE ;
2017-12-02 14:08:55 +01:00
gBattleStruct - > faintedActionsState + + ;
2017-09-17 14:10:32 +02:00
break ;
2017-12-02 14:08:55 +01:00
case FAINTED_ACTIONS_MAX_CASE :
2017-09-17 14:10:32 +02:00
break ;
}
2017-12-02 14:08:55 +01:00
} while ( gBattleStruct - > faintedActionsState ! = FAINTED_ACTIONS_MAX_CASE ) ;
2017-09-17 14:10:32 +02:00
return FALSE ;
}
2017-10-06 00:12:01 +02:00
void TryClearRageStatuses ( void )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
s32 i ;
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
if ( ( gBattleMons [ i ] . status2 & STATUS2_RAGE ) & & gChosenMoveByBattler [ i ] ! = MOVE_RAGE )
2017-09-17 14:10:32 +02:00
gBattleMons [ i ] . status2 & = ~ ( STATUS2_RAGE ) ;
}
}
# define ATKCANCELLER_MAX_CASE 14
u8 AtkCanceller_UnableToUseMove ( void )
{
u8 effect = 0 ;
2017-12-03 00:47:21 +01:00
s32 * bideDmg = & gBattleScripting . bideDmg ;
2017-09-17 14:10:32 +02:00
do
{
switch ( gBattleStruct - > atkCancellerTracker )
{
case 0 : // flags clear
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 & = ~ ( STATUS2_DESTINY_BOND ) ;
gStatuses3 [ gBattlerAttacker ] & = ~ ( STATUS3_GRUDGE ) ;
2017-09-17 14:10:32 +02:00
gBattleStruct - > atkCancellerTracker + + ;
break ;
case 1 : // check being asleep
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . status1 & STATUS1_SLEEP )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
if ( UproarWakeUpCheck ( gBattlerAttacker ) )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status1 & = ~ ( STATUS1_SLEEP ) ;
gBattleMons [ gBattlerAttacker ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 14:10:32 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp ;
effect = 2 ;
}
else
{
u8 toSub ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . ability = = ABILITY_EARLY_BIRD )
2017-09-17 14:10:32 +02:00
toSub = 2 ;
else
toSub = 1 ;
2018-02-06 23:09:39 +01:00
if ( ( gBattleMons [ gBattlerAttacker ] . status1 & STATUS1_SLEEP ) < toSub )
gBattleMons [ gBattlerAttacker ] . status1 & = ~ ( STATUS1_SLEEP ) ;
2017-09-17 14:10:32 +02:00
else
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status1 - = toSub ;
if ( gBattleMons [ gBattlerAttacker ] . status1 & STATUS1_SLEEP )
2017-09-17 14:10:32 +02:00
{
if ( gCurrentMove ! = MOVE_SNORE & & gCurrentMove ! = MOVE_SLEEP_TALK )
{
gBattlescriptCurrInstr = BattleScript_MoveUsedIsAsleep ;
gHitMarker | = HITMARKER_UNABLE_TO_USE_MOVE ;
effect = 2 ;
}
}
else
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 14:10:32 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp ;
effect = 2 ;
}
}
}
gBattleStruct - > atkCancellerTracker + + ;
break ;
case 2 : // check being frozen
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . status1 & STATUS1_FREEZE )
2017-09-17 14:10:32 +02:00
{
if ( Random ( ) % 5 )
{
if ( gBattleMoves [ gCurrentMove ] . effect ! = EFFECT_THAW_HIT ) // unfreezing via a move effect happens in case 13
{
gBattlescriptCurrInstr = BattleScript_MoveUsedIsFrozen ;
gHitMarker | = HITMARKER_NO_ATTACKSTRING ;
}
else
{
gBattleStruct - > atkCancellerTracker + + ;
break ;
}
}
else // unfreeze
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status1 & = ~ ( STATUS1_FREEZE ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 14:10:32 +02:00
gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
effect = 2 ;
}
gBattleStruct - > atkCancellerTracker + + ;
break ;
case 3 : // truant
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . ability = = ABILITY_TRUANT & & gDisableStructs [ gBattlerAttacker ] . truantCounter )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
CancelMultiTurnMoves ( gBattlerAttacker ) ;
2017-09-17 14:10:32 +02:00
gHitMarker | = HITMARKER_UNABLE_TO_USE_MOVE ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround ;
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-17 14:10:32 +02:00
effect = 1 ;
}
gBattleStruct - > atkCancellerTracker + + ;
break ;
case 4 : // recharge
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_RECHARGE )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 & = ~ ( STATUS2_RECHARGE ) ;
gDisableStructs [ gBattlerAttacker ] . rechargeCounter = 0 ;
CancelMultiTurnMoves ( gBattlerAttacker ) ;
2017-09-17 14:10:32 +02:00
gBattlescriptCurrInstr = BattleScript_MoveUsedMustRecharge ;
gHitMarker | = HITMARKER_UNABLE_TO_USE_MOVE ;
effect = 1 ;
}
gBattleStruct - > atkCancellerTracker + + ;
break ;
case 5 : // flinch
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_FLINCHED )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 & = ~ ( STATUS2_FLINCHED ) ;
gProtectStructs [ gBattlerAttacker ] . flinchImmobility = 1 ;
CancelMultiTurnMoves ( gBattlerAttacker ) ;
2017-09-17 14:10:32 +02:00
gBattlescriptCurrInstr = BattleScript_MoveUsedFlinched ;
gHitMarker | = HITMARKER_UNABLE_TO_USE_MOVE ;
effect = 1 ;
}
gBattleStruct - > atkCancellerTracker + + ;
break ;
case 6 : // disabled move
2018-02-06 23:09:39 +01:00
if ( gDisableStructs [ gBattlerAttacker ] . disabledMove = = gCurrentMove & & gDisableStructs [ gBattlerAttacker ] . disabledMove ! = 0 )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . usedDisabledMove = 1 ;
gBattleScripting . battler = gBattlerAttacker ;
CancelMultiTurnMoves ( gBattlerAttacker ) ;
2017-09-17 14:10:32 +02:00
gBattlescriptCurrInstr = BattleScript_MoveUsedIsDisabled ;
gHitMarker | = HITMARKER_UNABLE_TO_USE_MOVE ;
effect = 1 ;
}
gBattleStruct - > atkCancellerTracker + + ;
break ;
case 7 : // taunt
2018-02-06 23:09:39 +01:00
if ( gDisableStructs [ gBattlerAttacker ] . tauntTimer1 & & gBattleMoves [ gCurrentMove ] . power = = 0 )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . usedTauntedMove = 1 ;
CancelMultiTurnMoves ( gBattlerAttacker ) ;
2017-09-17 14:10:32 +02:00
gBattlescriptCurrInstr = BattleScript_MoveUsedIsTaunted ;
gHitMarker | = HITMARKER_UNABLE_TO_USE_MOVE ;
effect = 1 ;
}
gBattleStruct - > atkCancellerTracker + + ;
break ;
case 8 : // imprisoned
2018-02-06 23:09:39 +01:00
if ( GetImprisonedMovesCount ( gBattlerAttacker , gCurrentMove ) )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . usedImprisionedMove = 1 ;
CancelMultiTurnMoves ( gBattlerAttacker ) ;
2017-09-17 14:10:32 +02:00
gBattlescriptCurrInstr = BattleScript_MoveUsedIsImprisoned ;
gHitMarker | = HITMARKER_UNABLE_TO_USE_MOVE ;
effect = 1 ;
}
gBattleStruct - > atkCancellerTracker + + ;
break ;
case 9 : // confusion
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_CONFUSION )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 - - ;
if ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_CONFUSION )
2017-09-17 14:10:32 +02:00
{
if ( Random ( ) & 1 )
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 14:10:32 +02:00
}
else // confusion dmg
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
2018-02-06 23:09:39 +01:00
gBattlerTarget = gBattlerAttacker ;
2018-07-14 19:29:25 +02:00
gBattleMoveDamage = CalculateMoveDamage ( MOVE_NONE , gBattlerAttacker , gBattlerAttacker , TYPE_MYSTERY , 40 , FALSE ) ;
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . confusionSelfDmg = 1 ;
2017-09-17 14:10:32 +02:00
gHitMarker | = HITMARKER_UNABLE_TO_USE_MOVE ;
}
gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfused ;
}
else // snapped out of confusion
{
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 14:10:32 +02:00
gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfusedNoMore ;
}
effect = 1 ;
}
gBattleStruct - > atkCancellerTracker + + ;
break ;
case 10 : // paralysis
2018-02-06 23:09:39 +01:00
if ( ( gBattleMons [ gBattlerAttacker ] . status1 & STATUS1_PARALYSIS ) & & ( Random ( ) % 4 ) = = 0 )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . prlzImmobility = 1 ;
2017-09-17 14:10:32 +02:00
// This is removed in Emerald for some reason
2018-02-06 23:09:39 +01:00
//CancelMultiTurnMoves(gBattlerAttacker);
2017-09-17 14:10:32 +02:00
gBattlescriptCurrInstr = BattleScript_MoveUsedIsParalyzed ;
gHitMarker | = HITMARKER_UNABLE_TO_USE_MOVE ;
effect = 1 ;
}
gBattleStruct - > atkCancellerTracker + + ;
break ;
case 11 : // infatuation
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_INFATUATION )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleScripting . battler = CountTrailingZeroBits ( ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_INFATUATION ) > > 0x10 ) ;
2017-09-17 14:10:32 +02:00
if ( Random ( ) & 1 )
2018-07-01 11:15:42 +02:00
{
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2018-07-01 11:15:42 +02:00
}
2017-09-17 14:10:32 +02:00
else
{
2017-09-22 21:33:49 +02:00
BattleScriptPush ( BattleScript_MoveUsedIsParalyzedCantAttack ) ;
2017-09-17 14:10:32 +02:00
gHitMarker | = HITMARKER_UNABLE_TO_USE_MOVE ;
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . loveImmobility = 1 ;
CancelMultiTurnMoves ( gBattlerAttacker ) ;
2017-09-17 14:10:32 +02:00
}
gBattlescriptCurrInstr = BattleScript_MoveUsedIsInLove ;
effect = 1 ;
}
gBattleStruct - > atkCancellerTracker + + ;
break ;
case 12 : // bide
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_BIDE )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 - = 0x100 ;
if ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_BIDE )
2018-07-01 11:15:42 +02:00
{
2017-09-17 14:10:32 +02:00
gBattlescriptCurrInstr = BattleScript_BideStoringEnergy ;
2018-07-01 11:15:42 +02:00
}
2017-09-17 14:10:32 +02:00
else
{
// This is removed in Emerald for some reason
2018-02-06 23:09:39 +01:00
//gBattleMons[gBattlerAttacker].status2 &= ~(STATUS2_MULTIPLETURNS);
if ( gTakenDmg [ gBattlerAttacker ] )
2017-09-17 14:10:32 +02:00
{
gCurrentMove = MOVE_BIDE ;
2018-02-06 23:09:39 +01:00
* bideDmg = gTakenDmg [ gBattlerAttacker ] * 2 ;
2018-02-07 22:53:40 +01:00
gBattlerTarget = gTakenDmgByBattler [ gBattlerAttacker ] ;
2018-02-06 23:09:39 +01:00
if ( gAbsentBattlerFlags & gBitTable [ gBattlerTarget ] )
gBattlerTarget = GetMoveTarget ( MOVE_BIDE , 1 ) ;
2017-09-17 14:10:32 +02:00
gBattlescriptCurrInstr = BattleScript_BideAttack ;
}
else
2018-07-01 11:15:42 +02:00
{
2017-09-17 14:10:32 +02:00
gBattlescriptCurrInstr = BattleScript_BideNoEnergyToAttack ;
2018-07-01 11:15:42 +02:00
}
2017-09-17 14:10:32 +02:00
}
effect = 1 ;
}
gBattleStruct - > atkCancellerTracker + + ;
break ;
case 13 : // move thawing
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . status1 & STATUS1_FREEZE )
2017-09-17 14:10:32 +02:00
{
if ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_THAW_HIT )
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status1 & = ~ ( STATUS1_FREEZE ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 14:10:32 +02:00
gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
effect = 2 ;
}
gBattleStruct - > atkCancellerTracker + + ;
break ;
2017-11-26 13:26:58 +01:00
case ATKCANCELLER_MAX_CASE :
2017-09-17 14:10:32 +02:00
break ;
}
} while ( gBattleStruct - > atkCancellerTracker ! = ATKCANCELLER_MAX_CASE & & effect = = 0 ) ;
if ( effect = = 2 )
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gActiveBattler ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-17 14:10:32 +02:00
}
return effect ;
}
2017-09-17 15:19:15 +02:00
2018-07-01 11:15:42 +02:00
bool8 HasNoMonsToSwitch ( u8 battler , u8 partyIdBattlerOn1 , u8 partyIdBattlerOn2 )
2017-09-17 15:19:15 +02:00
{
2018-07-01 11:15:42 +02:00
struct Pokemon * party ;
u8 id1 , id2 ;
2017-09-17 15:19:15 +02:00
s32 i ;
2018-07-01 11:15:42 +02:00
2017-09-17 15:19:15 +02:00
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE ) )
return FALSE ;
2018-07-01 11:15:42 +02:00
2017-09-17 15:19:15 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER )
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( battler ) = = B_SIDE_PLAYER )
2017-09-17 15:19:15 +02:00
party = gPlayerParty ;
else
party = gEnemyParty ;
2018-07-01 11:15:42 +02:00
id1 = ( ( battler & BIT_FLANK ) / 2 ) ;
for ( i = id1 * 3 ; i < id1 * 3 + 3 ; i + + )
2017-09-17 15:19:15 +02:00
{
if ( GetMonData ( & party [ i ] , MON_DATA_HP ) ! = 0
2018-07-01 11:15:42 +02:00
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = SPECIES_NONE
2017-09-17 15:19:15 +02:00
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = SPECIES_EGG )
break ;
}
2018-07-01 11:15:42 +02:00
return ( i = = id1 * 3 + 3 ) ;
2017-09-17 15:19:15 +02:00
}
else if ( gBattleTypeFlags & BATTLE_TYPE_MULTI )
{
if ( gBattleTypeFlags & BATTLE_TYPE_x800000 )
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( battler ) = = B_SIDE_PLAYER )
2017-09-17 15:19:15 +02:00
{
party = gPlayerParty ;
2018-07-01 11:15:42 +02:00
id2 = GetBattlerMultiplayerId ( battler ) ;
id1 = GetLinkTrainerFlankId ( id2 ) ;
2017-09-17 15:19:15 +02:00
}
else
{
2018-07-01 11:15:42 +02:00
// FIXME: Compiler insists on moving r4 into r1 before doing the eor.
2017-09-17 15:19:15 +02:00
# ifndef NONMATCHING
2018-07-01 11:15:42 +02:00
register u32 var asm ( " r1 " ) ;
2017-09-17 15:19:15 +02:00
# else
2018-07-01 11:15:42 +02:00
u32 var ;
2017-09-17 15:19:15 +02:00
# endif // NONMATCHING
party = gEnemyParty ;
2018-07-01 11:15:42 +02:00
var = battler ^ BIT_SIDE ;
if ( var = = 0 )
id1 = 0 ;
else
id1 = 1 ;
2017-09-17 15:19:15 +02:00
}
}
else
{
2018-07-01 11:15:42 +02:00
id2 = GetBattlerMultiplayerId ( battler ) ;
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( battler ) = = B_SIDE_PLAYER )
2017-09-17 15:19:15 +02:00
party = gPlayerParty ;
else
party = gEnemyParty ;
2018-07-01 11:15:42 +02:00
id1 = GetLinkTrainerFlankId ( id2 ) ;
2017-09-17 15:19:15 +02:00
}
2018-07-01 11:15:42 +02:00
for ( i = id1 * 3 ; i < id1 * 3 + 3 ; i + + )
2017-09-17 15:19:15 +02:00
{
if ( GetMonData ( & party [ i ] , MON_DATA_HP ) ! = 0
2018-07-01 11:15:42 +02:00
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = SPECIES_NONE
2017-09-17 15:19:15 +02:00
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = SPECIES_EGG )
break ;
}
2018-07-01 11:15:42 +02:00
return ( i = = id1 * 3 + 3 ) ;
2017-09-17 15:19:15 +02:00
}
2018-02-06 02:46:59 +01:00
else if ( ( gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS ) & & GetBattlerSide ( battler ) = = B_SIDE_OPPONENT )
2017-09-17 15:19:15 +02:00
{
party = gEnemyParty ;
2018-02-06 02:46:59 +01:00
if ( battler = = 1 )
2018-07-01 11:15:42 +02:00
id1 = 0 ;
2017-09-17 15:19:15 +02:00
else
2018-07-01 11:15:42 +02:00
id1 = 3 ;
for ( i = id1 ; i < id1 + 3 ; i + + )
2017-09-17 15:19:15 +02:00
{
if ( GetMonData ( & party [ i ] , MON_DATA_HP ) ! = 0
2018-07-01 11:15:42 +02:00
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = SPECIES_NONE
2017-09-17 15:19:15 +02:00
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = SPECIES_EGG )
break ;
}
2018-07-01 11:15:42 +02:00
return ( i = = id1 + 3 ) ;
2017-09-17 15:19:15 +02:00
}
else
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( battler ) = = B_SIDE_OPPONENT )
2017-09-17 15:19:15 +02:00
{
2018-07-01 11:15:42 +02:00
id2 = GetBattlerAtPosition ( B_POSITION_OPPONENT_LEFT ) ;
id1 = GetBattlerAtPosition ( B_POSITION_OPPONENT_RIGHT ) ;
2017-09-17 15:19:15 +02:00
party = gEnemyParty ;
}
else
{
2018-07-01 11:15:42 +02:00
id2 = GetBattlerAtPosition ( B_POSITION_PLAYER_LEFT ) ;
id1 = GetBattlerAtPosition ( B_POSITION_PLAYER_RIGHT ) ;
2017-09-17 15:19:15 +02:00
party = gPlayerParty ;
}
2018-07-01 11:15:42 +02:00
if ( partyIdBattlerOn1 = = PARTY_SIZE )
partyIdBattlerOn1 = gBattlerPartyIndexes [ id2 ] ;
if ( partyIdBattlerOn2 = = PARTY_SIZE )
partyIdBattlerOn2 = gBattlerPartyIndexes [ id1 ] ;
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2017-09-17 15:19:15 +02:00
{
if ( GetMonData ( & party [ i ] , MON_DATA_HP ) ! = 0
2018-07-01 11:15:42 +02:00
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = SPECIES_NONE
2017-09-17 15:19:15 +02:00
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = SPECIES_EGG
2018-07-01 11:15:42 +02:00
& & i ! = partyIdBattlerOn1 & & i ! = partyIdBattlerOn2
& & i ! = * ( gBattleStruct - > monToSwitchIntoId + id2 ) & & i ! = id1 [ gBattleStruct - > monToSwitchIntoId ] )
2017-09-17 15:19:15 +02:00
break ;
}
2018-07-01 11:15:42 +02:00
return ( i = = PARTY_SIZE ) ;
2017-09-17 15:19:15 +02:00
}
}
enum
{
CASTFORM_NO_CHANGE , //0
CASTFORM_TO_NORMAL , //1
CASTFORM_TO_FIRE , //2
CASTFORM_TO_WATER , //3
CASTFORM_TO_ICE , //4
} ;
2018-02-06 02:46:59 +01:00
u8 CastformDataTypeChange ( u8 battler )
2017-09-17 15:19:15 +02:00
{
u8 formChange = 0 ;
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . species ! = SPECIES_CASTFORM | | gBattleMons [ battler ] . ability ! = ABILITY_FORECAST | | gBattleMons [ battler ] . hp = = 0 )
2017-09-17 15:19:15 +02:00
return CASTFORM_NO_CHANGE ;
2018-03-01 00:59:52 +01:00
if ( ! WEATHER_HAS_EFFECT & & ! IS_BATTLER_OF_TYPE ( battler , TYPE_NORMAL ) )
2017-09-17 15:19:15 +02:00
{
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE ( battler , TYPE_NORMAL ) ;
2017-09-17 15:19:15 +02:00
return CASTFORM_TO_NORMAL ;
}
if ( ! WEATHER_HAS_EFFECT )
return CASTFORM_NO_CHANGE ;
2018-03-01 00:59:52 +01:00
if ( ! ( gBattleWeather & ( WEATHER_RAIN_ANY | WEATHER_SUN_ANY | WEATHER_HAIL_ANY ) ) & & ! IS_BATTLER_OF_TYPE ( battler , TYPE_NORMAL ) )
2017-09-17 15:19:15 +02:00
{
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE ( battler , TYPE_NORMAL ) ;
2017-09-17 15:19:15 +02:00
formChange = CASTFORM_TO_NORMAL ;
}
2018-03-01 00:59:52 +01:00
if ( gBattleWeather & WEATHER_SUN_ANY & & ! IS_BATTLER_OF_TYPE ( battler , TYPE_FIRE ) )
2017-09-17 15:19:15 +02:00
{
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE ( battler , TYPE_FIRE ) ;
2017-09-17 15:19:15 +02:00
formChange = CASTFORM_TO_FIRE ;
}
2018-03-01 00:59:52 +01:00
if ( gBattleWeather & WEATHER_RAIN_ANY & & ! IS_BATTLER_OF_TYPE ( battler , TYPE_WATER ) )
2017-09-17 15:19:15 +02:00
{
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE ( battler , TYPE_WATER ) ;
2017-09-17 15:19:15 +02:00
formChange = CASTFORM_TO_WATER ;
}
2018-03-01 00:59:52 +01:00
if ( gBattleWeather & WEATHER_HAIL_ANY & & ! IS_BATTLER_OF_TYPE ( battler , TYPE_ICE ) )
2017-09-17 15:19:15 +02:00
{
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE ( battler , TYPE_ICE ) ;
2017-09-17 15:19:15 +02:00
formChange = CASTFORM_TO_ICE ;
}
return formChange ;
}
2017-10-12 17:49:24 +02:00
// The largest function in the game, but even it could not save itself from decompiling.
2018-02-06 02:46:59 +01:00
u8 AbilityBattleEffects ( u8 caseID , u8 battler , u8 ability , u8 special , u16 moveArg )
2017-09-17 15:19:15 +02:00
{
u8 effect = 0 ;
2017-10-12 17:49:24 +02:00
struct Pokemon * pokeAtk ;
struct Pokemon * pokeDef ;
2017-09-17 15:19:15 +02:00
u16 speciesAtk ;
u16 speciesDef ;
u32 pidAtk ;
u32 pidDef ;
2018-02-06 23:09:39 +01:00
if ( gBattlerAttacker > = gBattlersCount )
gBattlerAttacker = battler ;
2018-07-01 11:15:42 +02:00
2018-02-06 23:09:39 +01:00
if ( GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_PLAYER )
pokeAtk = & gPlayerParty [ gBattlerPartyIndexes [ gBattlerAttacker ] ] ;
2017-09-17 15:19:15 +02:00
else
2018-02-06 23:09:39 +01:00
pokeAtk = & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ] ] ;
2017-09-17 15:19:15 +02:00
2018-02-06 23:09:39 +01:00
if ( gBattlerTarget > = gBattlersCount )
gBattlerTarget = battler ;
2018-07-01 11:15:42 +02:00
2018-02-06 23:09:39 +01:00
if ( GetBattlerSide ( gBattlerTarget ) = = B_SIDE_PLAYER )
pokeDef = & gPlayerParty [ gBattlerPartyIndexes [ gBattlerTarget ] ] ;
2017-09-17 15:19:15 +02:00
else
2018-02-06 23:09:39 +01:00
pokeDef = & gEnemyParty [ gBattlerPartyIndexes [ gBattlerTarget ] ] ;
2017-09-17 15:19:15 +02:00
speciesAtk = GetMonData ( pokeAtk , MON_DATA_SPECIES ) ;
pidAtk = GetMonData ( pokeAtk , MON_DATA_PERSONALITY ) ;
speciesDef = GetMonData ( pokeDef , MON_DATA_SPECIES ) ;
pidDef = GetMonData ( pokeDef , MON_DATA_PERSONALITY ) ;
2018-07-01 11:15:42 +02:00
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_SAFARI ) ) // Why isn't that check done at the beginning?
2017-09-17 15:19:15 +02:00
{
2017-10-12 17:49:24 +02:00
u8 moveType ;
s32 i ;
2017-09-17 15:19:15 +02:00
u16 move ;
u8 side ;
2017-10-12 17:49:24 +02:00
u8 target1 ;
2017-09-17 15:19:15 +02:00
if ( special )
gLastUsedAbility = special ;
else
2018-02-06 02:46:59 +01:00
gLastUsedAbility = gBattleMons [ battler ] . ability ;
2017-09-17 15:19:15 +02:00
if ( moveArg )
move = moveArg ;
else
move = gCurrentMove ;
2017-11-26 13:26:58 +01:00
GET_MOVE_TYPE ( move , moveType ) ;
2017-09-17 15:19:15 +02:00
switch ( caseID )
{
case ABILITYEFFECT_ON_SWITCHIN : // 0
2018-02-06 23:09:39 +01:00
if ( gBattlerAttacker > = gBattlersCount )
gBattlerAttacker = battler ;
2017-09-17 15:19:15 +02:00
switch ( gLastUsedAbility )
2017-09-18 23:44:55 +02:00
{
2017-10-02 23:32:39 +02:00
case ABILITYEFFECT_SWITCH_IN_WEATHER :
2017-10-12 17:49:24 +02:00
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_RECORDED ) )
2017-09-18 23:44:55 +02:00
{
2017-10-12 17:49:24 +02:00
switch ( weather_get_current ( ) )
2017-09-17 15:19:15 +02:00
{
2017-10-12 17:49:24 +02:00
case 3 :
case 5 :
case 13 :
if ( ! ( gBattleWeather & WEATHER_RAIN_ANY ) )
{
gBattleWeather = ( WEATHER_RAIN_TEMPORARY | WEATHER_RAIN_PERMANENT ) ;
gBattleScripting . animArg1 = B_ANIM_RAIN_CONTINUES ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = battler ;
2017-10-12 17:49:24 +02:00
effect + + ;
}
break ;
case 8 :
if ( ! ( gBattleWeather & WEATHER_SANDSTORM_ANY ) )
{
gBattleWeather = ( WEATHER_SANDSTORM_PERMANENT | WEATHER_SANDSTORM_TEMPORARY ) ;
gBattleScripting . animArg1 = B_ANIM_SANDSTORM_CONTINUES ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = battler ;
2017-10-12 17:49:24 +02:00
effect + + ;
}
break ;
case 12 :
if ( ! ( gBattleWeather & WEATHER_SUN_ANY ) )
{
gBattleWeather = ( WEATHER_SUN_PERMANENT | WEATHER_SUN_TEMPORARY ) ;
gBattleScripting . animArg1 = B_ANIM_SUN_CONTINUES ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = battler ;
2017-10-12 17:49:24 +02:00
effect + + ;
}
break ;
2017-09-17 15:19:15 +02:00
}
2017-09-18 23:44:55 +02:00
}
if ( effect )
2017-09-17 15:19:15 +02:00
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = weather_get_current ( ) ;
2017-11-26 17:15:28 +01:00
BattleScriptPushCursorAndCallback ( BattleScript_OverworldWeatherStarts ) ;
2017-09-17 15:19:15 +02:00
}
2017-09-18 23:44:55 +02:00
break ;
case ABILITY_DRIZZLE :
if ( ! ( gBattleWeather & WEATHER_RAIN_PERMANENT ) )
2017-09-17 15:19:15 +02:00
{
gBattleWeather = ( WEATHER_RAIN_PERMANENT | WEATHER_RAIN_TEMPORARY ) ;
2017-09-28 15:34:21 +02:00
BattleScriptPushCursorAndCallback ( BattleScript_DrizzleActivates ) ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = battler ;
2017-09-17 15:19:15 +02:00
effect + + ;
}
2017-09-18 23:44:55 +02:00
break ;
case ABILITY_SAND_STREAM :
if ( ! ( gBattleWeather & WEATHER_SANDSTORM_PERMANENT ) )
2017-09-17 15:19:15 +02:00
{
gBattleWeather = ( WEATHER_SANDSTORM_PERMANENT | WEATHER_SANDSTORM_TEMPORARY ) ;
2017-09-28 15:34:21 +02:00
BattleScriptPushCursorAndCallback ( BattleScript_SandstreamActivates ) ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = battler ;
2017-09-17 15:19:15 +02:00
effect + + ;
}
2017-09-18 23:44:55 +02:00
break ;
case ABILITY_DROUGHT :
2017-09-17 15:19:15 +02:00
if ( ! ( gBattleWeather & WEATHER_SUN_PERMANENT ) )
{
gBattleWeather = ( WEATHER_SUN_PERMANENT | WEATHER_SUN_TEMPORARY ) ;
2017-09-28 15:34:21 +02:00
BattleScriptPushCursorAndCallback ( BattleScript_DroughtActivates ) ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = battler ;
2017-09-17 15:19:15 +02:00
effect + + ;
}
2017-09-18 23:44:55 +02:00
break ;
case ABILITY_INTIMIDATE :
2018-02-06 02:46:59 +01:00
if ( ! ( gSpecialStatuses [ battler ] . intimidatedPoke ) )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
gStatuses3 [ battler ] | = STATUS3_INTIMIDATE_POKES ;
gSpecialStatuses [ battler ] . intimidatedPoke = 1 ;
2017-09-17 15:19:15 +02:00
}
2017-09-18 23:44:55 +02:00
break ;
case ABILITY_FORECAST :
2018-02-06 02:46:59 +01:00
effect = CastformDataTypeChange ( battler ) ;
2017-09-17 15:19:15 +02:00
if ( effect ! = 0 )
{
2017-09-28 15:34:21 +02:00
BattleScriptPushCursorAndCallback ( BattleScript_CastformChange ) ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = battler ;
2017-10-12 17:49:24 +02:00
* ( & gBattleStruct - > formToChangeInto ) = effect - 1 ;
2017-09-17 15:19:15 +02:00
}
2017-09-18 23:44:55 +02:00
break ;
case ABILITY_TRACE :
2018-02-06 02:46:59 +01:00
if ( ! ( gSpecialStatuses [ battler ] . traced ) )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
gStatuses3 [ battler ] | = STATUS3_TRACE ;
gSpecialStatuses [ battler ] . traced = 1 ;
2017-09-17 15:19:15 +02:00
}
2017-09-18 23:44:55 +02:00
break ;
case ABILITY_CLOUD_NINE :
case ABILITY_AIR_LOCK :
{
2018-02-06 02:46:59 +01:00
// that's a weird choice for a variable, why not use i or battler?
for ( target1 = 0 ; target1 < gBattlersCount ; target1 + + )
2017-09-17 15:19:15 +02:00
{
2017-10-12 17:49:24 +02:00
effect = CastformDataTypeChange ( target1 ) ;
2017-09-17 15:19:15 +02:00
if ( effect ! = 0 )
{
2017-09-28 15:34:21 +02:00
BattleScriptPushCursorAndCallback ( BattleScript_CastformChange ) ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = target1 ;
2017-10-12 17:49:24 +02:00
* ( & gBattleStruct - > formToChangeInto ) = effect - 1 ;
2017-09-17 15:19:15 +02:00
break ;
}
}
2017-09-18 23:44:55 +02:00
}
break ;
}
break ;
2017-09-17 15:19:15 +02:00
case ABILITYEFFECT_ENDTURN : // 1
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . hp ! = 0 )
2017-09-17 15:19:15 +02:00
{
2018-02-06 23:09:39 +01:00
gBattlerAttacker = battler ;
2017-09-17 15:19:15 +02:00
switch ( gLastUsedAbility )
{
case ABILITY_RAIN_DISH :
if ( WEATHER_HAS_EFFECT & & ( gBattleWeather & WEATHER_RAIN_ANY )
2018-02-06 02:46:59 +01:00
& & gBattleMons [ battler ] . maxHP > gBattleMons [ battler ] . hp )
2017-09-17 15:19:15 +02:00
{
2017-10-12 17:49:24 +02:00
gLastUsedAbility = ABILITY_RAIN_DISH ; // why
2017-09-28 15:34:21 +02:00
BattleScriptPushCursorAndCallback ( BattleScript_RainDishActivates ) ;
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gBattleMons [ battler ] . maxHP / 16 ;
2017-09-17 15:19:15 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleMoveDamage * = - 1 ;
effect + + ;
}
break ;
case ABILITY_SHED_SKIN :
2018-02-06 02:46:59 +01:00
if ( ( gBattleMons [ battler ] . status1 & STATUS1_ANY ) & & ( Random ( ) % 3 ) = = 0 )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . status1 & ( STATUS1_POISON | STATUS1_TOXIC_POISON ) )
2017-09-17 15:19:15 +02:00
StringCopy ( gBattleTextBuff1 , gStatusConditionString_PoisonJpn ) ;
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . status1 & STATUS1_SLEEP )
2017-09-17 15:19:15 +02:00
StringCopy ( gBattleTextBuff1 , gStatusConditionString_SleepJpn ) ;
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . status1 & STATUS1_PARALYSIS )
2017-09-17 15:19:15 +02:00
StringCopy ( gBattleTextBuff1 , gStatusConditionString_ParalysisJpn ) ;
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . status1 & STATUS1_BURN )
2017-09-17 15:19:15 +02:00
StringCopy ( gBattleTextBuff1 , gStatusConditionString_BurnJpn ) ;
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . status1 & STATUS1_FREEZE )
2017-09-17 15:19:15 +02:00
StringCopy ( gBattleTextBuff1 , gStatusConditionString_IceJpn ) ;
2018-02-06 02:46:59 +01:00
gBattleMons [ battler ] . status1 = 0 ;
gBattleMons [ battler ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ; // fix nightmare glitch
gBattleScripting . battler = gActiveBattler = battler ;
2017-09-28 15:34:21 +02:00
BattleScriptPushCursorAndCallback ( BattleScript_ShedSkinActivates ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ battler ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-17 15:19:15 +02:00
effect + + ;
}
break ;
case ABILITY_SPEED_BOOST :
2018-02-08 12:13:29 +01:00
if ( gBattleMons [ battler ] . statStages [ STAT_SPEED ] < 0xC & & gDisableStructs [ battler ] . isFirstTurn ! = 2 )
2017-09-17 15:19:15 +02:00
{
2018-02-08 12:13:29 +01:00
gBattleMons [ battler ] . statStages [ STAT_SPEED ] + + ;
2017-09-17 15:19:15 +02:00
gBattleScripting . animArg1 = 0x11 ;
gBattleScripting . animArg2 = 0 ;
2017-09-28 15:34:21 +02:00
BattleScriptPushCursorAndCallback ( BattleScript_SpeedBoostActivates ) ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = battler ;
2017-09-17 15:19:15 +02:00
effect + + ;
}
break ;
case ABILITY_TRUANT :
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerAttacker ] . truantCounter ^ = 1 ;
2017-09-17 15:19:15 +02:00
break ;
}
}
break ;
case ABILITYEFFECT_MOVES_BLOCK : // 2
if ( gLastUsedAbility = = ABILITY_SOUNDPROOF )
{
2017-10-06 19:09:37 +02:00
for ( i = 0 ; sSoundMovesTable [ i ] ! = 0xFFFF ; i + + )
2017-09-17 15:19:15 +02:00
{
2017-10-06 19:09:37 +02:00
if ( sSoundMovesTable [ i ] = = move )
2017-09-17 15:19:15 +02:00
break ;
}
2017-10-06 19:09:37 +02:00
if ( sSoundMovesTable [ i ] ! = 0xFFFF )
2017-09-17 15:19:15 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_MULTIPLETURNS )
2017-09-17 15:19:15 +02:00
gHitMarker | = HITMARKER_NO_PPDEDUCT ;
gBattlescriptCurrInstr = BattleScript_SoundproofProtected ;
effect = 1 ;
}
}
break ;
case ABILITYEFFECT_ABSORBING : // 3
if ( move )
{
switch ( gLastUsedAbility )
{
case ABILITY_VOLT_ABSORB :
if ( moveType = = TYPE_ELECTRIC & & gBattleMoves [ move ] . power ! = 0 )
{
2018-02-06 23:09:39 +01:00
if ( gProtectStructs [ gBattlerAttacker ] . notFirstStrike )
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_MoveHPDrain ;
else
gBattlescriptCurrInstr = BattleScript_MoveHPDrain_PPLoss ;
2017-10-12 17:49:24 +02:00
2017-09-17 15:19:15 +02:00
effect = 1 ;
}
break ;
case ABILITY_WATER_ABSORB :
if ( moveType = = TYPE_WATER & & gBattleMoves [ move ] . power ! = 0 )
{
2018-02-06 23:09:39 +01:00
if ( gProtectStructs [ gBattlerAttacker ] . notFirstStrike )
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_MoveHPDrain ;
else
gBattlescriptCurrInstr = BattleScript_MoveHPDrain_PPLoss ;
2017-10-12 17:49:24 +02:00
2017-09-17 15:19:15 +02:00
effect = 1 ;
}
break ;
case ABILITY_FLASH_FIRE :
2018-02-06 02:46:59 +01:00
if ( moveType = = TYPE_FIRE & & ! ( gBattleMons [ battler ] . status1 & STATUS1_FREEZE ) )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
if ( ! ( gBattleResources - > flags - > flags [ battler ] & UNKNOWN_FLAG_FLASH_FIRE ) )
2017-09-17 15:19:15 +02:00
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
2018-02-06 23:09:39 +01:00
if ( gProtectStructs [ gBattlerAttacker ] . notFirstStrike )
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_FlashFireBoost ;
else
gBattlescriptCurrInstr = BattleScript_FlashFireBoost_PPLoss ;
2017-10-12 17:49:24 +02:00
2018-02-06 02:46:59 +01:00
gBattleResources - > flags - > flags [ battler ] | = UNKNOWN_FLAG_FLASH_FIRE ;
2017-09-17 15:19:15 +02:00
effect = 2 ;
}
else
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
2018-02-06 23:09:39 +01:00
if ( gProtectStructs [ gBattlerAttacker ] . notFirstStrike )
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_FlashFireBoost ;
else
gBattlescriptCurrInstr = BattleScript_FlashFireBoost_PPLoss ;
2017-10-12 17:49:24 +02:00
2017-09-17 15:19:15 +02:00
effect = 2 ;
}
}
break ;
}
if ( effect = = 1 )
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . maxHP = = gBattleMons [ battler ] . hp )
2017-09-17 15:19:15 +02:00
{
2018-02-06 23:09:39 +01:00
if ( ( gProtectStructs [ gBattlerAttacker ] . notFirstStrike ) )
2017-11-26 17:15:28 +01:00
gBattlescriptCurrInstr = BattleScript_MonMadeMoveUseless ;
2017-09-17 15:19:15 +02:00
else
2017-11-26 17:15:28 +01:00
gBattlescriptCurrInstr = BattleScript_MonMadeMoveUseless_PPLoss ;
2017-09-17 15:19:15 +02:00
}
else
{
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gBattleMons [ battler ] . maxHP / 4 ;
2017-09-17 15:19:15 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleMoveDamage * = - 1 ;
}
}
}
break ;
case ABILITYEFFECT_CONTACT : // 4
switch ( gLastUsedAbility )
{
case ABILITY_COLOR_CHANGE :
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2017-09-17 15:19:15 +02:00
& & move ! = MOVE_STRUGGLE
& & gBattleMoves [ move ] . power ! = 0
2018-03-01 00:59:52 +01:00
& & TARGET_TURN_DAMAGED
& & ! IS_BATTLER_OF_TYPE ( battler , moveType )
2018-02-06 02:46:59 +01:00
& & gBattleMons [ battler ] . hp ! = 0 )
2017-09-17 15:19:15 +02:00
{
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE ( battler , moveType ) ;
PREPARE_TYPE_BUFFER ( gBattleTextBuff1 , moveType ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_ColorChangeActivates ;
effect + + ;
}
break ;
case ABILITY_ROUGH_SKIN :
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2018-02-06 23:09:39 +01:00
& & gBattleMons [ gBattlerAttacker ] . hp ! = 0
& & ! gProtectStructs [ gBattlerAttacker ] . confusionSelfDmg
2018-03-01 00:59:52 +01:00
& & TARGET_TURN_DAMAGED
2017-09-17 15:19:15 +02:00
& & ( gBattleMoves [ move ] . flags & FLAG_MAKES_CONTACT ) )
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . maxHP / 16 ;
2017-09-17 15:19:15 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_RoughSkinActivates ;
effect + + ;
}
break ;
case ABILITY_EFFECT_SPORE :
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2018-02-06 23:09:39 +01:00
& & gBattleMons [ gBattlerAttacker ] . hp ! = 0
& & ! gProtectStructs [ gBattlerAttacker ] . confusionSelfDmg
2018-03-01 00:59:52 +01:00
& & TARGET_TURN_DAMAGED
2017-09-17 15:19:15 +02:00
& & ( gBattleMoves [ move ] . flags & FLAG_MAKES_CONTACT )
& & ( Random ( ) % 10 ) = = 0 )
{
do
{
gBattleCommunication [ MOVE_EFFECT_BYTE ] = Random ( ) & 3 ;
} while ( gBattleCommunication [ MOVE_EFFECT_BYTE ] = = 0 ) ;
2017-10-12 17:49:24 +02:00
if ( gBattleCommunication [ MOVE_EFFECT_BYTE ] = = MOVE_EFFECT_BURN )
gBattleCommunication [ MOVE_EFFECT_BYTE ] + = 2 ; // 5 MOVE_EFFECT_PARALYSIS
gBattleCommunication [ MOVE_EFFECT_BYTE ] + = MOVE_EFFECT_AFFECTS_USER ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect ;
gHitMarker | = HITMARKER_IGNORE_SAFEGUARD ;
effect + + ;
}
break ;
case ABILITY_POISON_POINT :
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2018-02-06 23:09:39 +01:00
& & gBattleMons [ gBattlerAttacker ] . hp ! = 0
& & ! gProtectStructs [ gBattlerAttacker ] . confusionSelfDmg
2018-03-01 00:59:52 +01:00
& & TARGET_TURN_DAMAGED
2017-09-17 15:19:15 +02:00
& & ( gBattleMoves [ move ] . flags & FLAG_MAKES_CONTACT )
& & ( Random ( ) % 3 ) = = 0 )
{
2017-10-12 17:49:24 +02:00
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_POISON ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect ;
gHitMarker | = HITMARKER_IGNORE_SAFEGUARD ;
effect + + ;
}
break ;
case ABILITY_STATIC :
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2018-02-06 23:09:39 +01:00
& & gBattleMons [ gBattlerAttacker ] . hp ! = 0
& & ! gProtectStructs [ gBattlerAttacker ] . confusionSelfDmg
2018-03-01 00:59:52 +01:00
& & TARGET_TURN_DAMAGED
2017-09-17 15:19:15 +02:00
& & ( gBattleMoves [ move ] . flags & FLAG_MAKES_CONTACT )
& & ( Random ( ) % 3 ) = = 0 )
{
2017-10-12 17:49:24 +02:00
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_PARALYSIS ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect ;
gHitMarker | = HITMARKER_IGNORE_SAFEGUARD ;
effect + + ;
}
break ;
case ABILITY_FLAME_BODY :
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2018-02-06 23:09:39 +01:00
& & gBattleMons [ gBattlerAttacker ] . hp ! = 0
& & ! gProtectStructs [ gBattlerAttacker ] . confusionSelfDmg
2017-09-17 15:19:15 +02:00
& & ( gBattleMoves [ move ] . flags & FLAG_MAKES_CONTACT )
2018-03-01 00:59:52 +01:00
& & TARGET_TURN_DAMAGED
2017-09-17 15:19:15 +02:00
& & ( Random ( ) % 3 ) = = 0 )
{
2017-10-12 17:49:24 +02:00
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_BURN ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect ;
gHitMarker | = HITMARKER_IGNORE_SAFEGUARD ;
effect + + ;
}
break ;
case ABILITY_CUTE_CHARM :
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2018-02-06 23:09:39 +01:00
& & gBattleMons [ gBattlerAttacker ] . hp ! = 0
& & ! gProtectStructs [ gBattlerAttacker ] . confusionSelfDmg
2017-09-17 15:19:15 +02:00
& & ( gBattleMoves [ move ] . flags & FLAG_MAKES_CONTACT )
2018-03-01 00:59:52 +01:00
& & TARGET_TURN_DAMAGED
2018-02-06 23:09:39 +01:00
& & gBattleMons [ gBattlerTarget ] . hp ! = 0
2017-09-17 15:19:15 +02:00
& & ( Random ( ) % 3 ) = = 0
2018-02-06 23:09:39 +01:00
& & gBattleMons [ gBattlerAttacker ] . ability ! = ABILITY_OBLIVIOUS
2017-09-17 15:19:15 +02:00
& & GetGenderFromSpeciesAndPersonality ( speciesAtk , pidAtk ) ! = GetGenderFromSpeciesAndPersonality ( speciesDef , pidDef )
2018-02-06 23:09:39 +01:00
& & ! ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_INFATUATION )
2017-10-12 17:49:24 +02:00
& & GetGenderFromSpeciesAndPersonality ( speciesAtk , pidAtk ) ! = MON_GENDERLESS
& & GetGenderFromSpeciesAndPersonality ( speciesDef , pidDef ) ! = MON_GENDERLESS )
2017-09-17 15:19:15 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 | = STATUS2_INFATUATED_WITH ( gBattlerTarget ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_CuteCharmActivates ;
effect + + ;
}
break ;
}
break ;
case ABILITYEFFECT_IMMUNITY : // 5
2018-02-06 02:46:59 +01:00
for ( battler = 0 ; battler < gBattlersCount ; battler + + )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
switch ( gBattleMons [ battler ] . ability )
2017-09-17 15:19:15 +02:00
{
2017-11-26 17:15:28 +01:00
case ABILITY_IMMUNITY :
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . status1 & ( STATUS1_POISON | STATUS1_TOXIC_POISON | STATUS1_TOXIC_COUNTER ) )
2017-09-17 15:19:15 +02:00
{
2017-11-26 17:15:28 +01:00
StringCopy ( gBattleTextBuff1 , gStatusConditionString_PoisonJpn ) ;
effect = 1 ;
}
break ;
case ABILITY_OWN_TEMPO :
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . status2 & STATUS2_CONFUSION )
2017-11-26 17:15:28 +01:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_ConfusionJpn ) ;
effect = 2 ;
}
break ;
case ABILITY_LIMBER :
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . status1 & STATUS1_PARALYSIS )
2017-11-26 17:15:28 +01:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_ParalysisJpn ) ;
effect = 1 ;
}
break ;
case ABILITY_INSOMNIA :
case ABILITY_VITAL_SPIRIT :
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . status1 & STATUS1_SLEEP )
2017-11-26 17:15:28 +01:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ battler ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
2017-11-26 17:15:28 +01:00
StringCopy ( gBattleTextBuff1 , gStatusConditionString_SleepJpn ) ;
effect = 1 ;
}
break ;
case ABILITY_WATER_VEIL :
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . status1 & STATUS1_BURN )
2017-11-26 17:15:28 +01:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_BurnJpn ) ;
effect = 1 ;
}
break ;
case ABILITY_MAGMA_ARMOR :
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . status1 & STATUS1_FREEZE )
2017-11-26 17:15:28 +01:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_IceJpn ) ;
effect = 1 ;
}
break ;
case ABILITY_OBLIVIOUS :
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . status2 & STATUS2_INFATUATION )
2017-11-26 17:15:28 +01:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_LoveJpn ) ;
effect = 3 ;
}
break ;
}
if ( effect )
{
switch ( effect )
{
case 1 : // status cleared
2018-02-06 02:46:59 +01:00
gBattleMons [ battler ] . status1 = 0 ;
2017-09-17 15:19:15 +02:00
break ;
2017-11-26 17:15:28 +01:00
case 2 : // get rid of confusion
2018-02-06 02:46:59 +01:00
gBattleMons [ battler ] . status2 & = ~ ( STATUS2_CONFUSION ) ;
2017-09-17 15:19:15 +02:00
break ;
2017-11-26 17:15:28 +01:00
case 3 : // get rid of infatuation
2018-02-06 02:46:59 +01:00
gBattleMons [ battler ] . status2 & = ~ ( STATUS2_INFATUATION ) ;
2017-09-17 15:19:15 +02:00
break ;
}
2017-10-12 17:49:24 +02:00
2017-11-26 17:15:28 +01:00
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_AbilityCuredStatus ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = battler ;
gActiveBattler = battler ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gActiveBattler ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-11-26 17:15:28 +01:00
return effect ;
2017-09-17 15:19:15 +02:00
}
}
break ;
case ABILITYEFFECT_FORECAST : // 6
2018-02-06 02:46:59 +01:00
for ( battler = 0 ; battler < gBattlersCount ; battler + + )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . ability = = ABILITY_FORECAST )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
effect = CastformDataTypeChange ( battler ) ;
2017-10-12 17:49:24 +02:00
if ( effect )
2017-09-17 15:19:15 +02:00
{
2017-10-12 17:49:24 +02:00
BattleScriptPushCursorAndCallback ( BattleScript_CastformChange ) ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = battler ;
2017-10-12 17:49:24 +02:00
* ( & gBattleStruct - > formToChangeInto ) = effect - 1 ;
return effect ;
2017-09-17 15:19:15 +02:00
}
}
}
break ;
case ABILITYEFFECT_SYNCHRONIZE : // 7
if ( gLastUsedAbility = = ABILITY_SYNCHRONIZE & & ( gHitMarker & HITMARKER_SYNCHRONISE_EFFECT ) )
{
gHitMarker & = ~ ( HITMARKER_SYNCHRONISE_EFFECT ) ;
2017-10-12 17:49:24 +02:00
gBattleStruct - > synchronizeMoveEffect & = ~ ( MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN ) ;
if ( gBattleStruct - > synchronizeMoveEffect = = MOVE_EFFECT_TOXIC )
gBattleStruct - > synchronizeMoveEffect = MOVE_EFFECT_POISON ;
gBattleCommunication [ MOVE_EFFECT_BYTE ] = gBattleStruct - > synchronizeMoveEffect + MOVE_EFFECT_AFFECTS_USER ;
2018-02-06 23:09:39 +01:00
gBattleScripting . battler = gBattlerTarget ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_SynchronizeActivates ;
gHitMarker | = HITMARKER_IGNORE_SAFEGUARD ;
effect + + ;
}
break ;
case ABILITYEFFECT_ATK_SYNCHRONIZE : // 8
if ( gLastUsedAbility = = ABILITY_SYNCHRONIZE & & ( gHitMarker & HITMARKER_SYNCHRONISE_EFFECT ) )
{
gHitMarker & = ~ ( HITMARKER_SYNCHRONISE_EFFECT ) ;
2017-10-12 17:49:24 +02:00
gBattleStruct - > synchronizeMoveEffect & = ~ ( MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN ) ;
if ( gBattleStruct - > synchronizeMoveEffect = = MOVE_EFFECT_TOXIC )
gBattleStruct - > synchronizeMoveEffect = MOVE_EFFECT_POISON ;
2017-09-17 15:19:15 +02:00
gBattleCommunication [ MOVE_EFFECT_BYTE ] = gBattleStruct - > synchronizeMoveEffect ;
2018-02-06 23:09:39 +01:00
gBattleScripting . battler = gBattlerAttacker ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_SynchronizeActivates ;
gHitMarker | = HITMARKER_IGNORE_SAFEGUARD ;
effect + + ;
}
break ;
case ABILITYEFFECT_INTIMIDATE1 : // 9
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
if ( gBattleMons [ i ] . ability = = ABILITY_INTIMIDATE & & gStatuses3 [ i ] & STATUS3_INTIMIDATE_POKES )
{
gLastUsedAbility = ABILITY_INTIMIDATE ;
gStatuses3 [ i ] & = ~ ( STATUS3_INTIMIDATE_POKES ) ;
2017-11-25 18:42:31 +01:00
BattleScriptPushCursorAndCallback ( BattleScript_82DB4B8 ) ;
2018-07-01 11:15:42 +02:00
gBattleStruct - > intimidateBattler = i ;
2017-09-17 15:19:15 +02:00
effect + + ;
break ;
}
}
break ;
case ABILITYEFFECT_TRACE : // 11
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
if ( gBattleMons [ i ] . ability = = ABILITY_TRACE & & ( gStatuses3 [ i ] & STATUS3_TRACE ) )
{
2017-10-12 17:49:24 +02:00
u8 target2 ;
2018-02-06 02:46:59 +01:00
side = ( GetBattlerPosition ( i ) ^ BIT_SIDE ) & BIT_SIDE ; // side of the opposing pokemon
target1 = GetBattlerAtPosition ( side ) ;
target2 = GetBattlerAtPosition ( side + BIT_FLANK ) ;
2017-09-17 15:19:15 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
{
if ( gBattleMons [ target1 ] . ability ! = 0 & & gBattleMons [ target1 ] . hp ! = 0
& & gBattleMons [ target2 ] . ability ! = 0 & & gBattleMons [ target2 ] . hp ! = 0 )
{
2018-02-06 02:46:59 +01:00
gActiveBattler = GetBattlerAtPosition ( ( ( Random ( ) & 1 ) * 2 ) | side ) ;
gBattleMons [ i ] . ability = gBattleMons [ gActiveBattler ] . ability ;
gLastUsedAbility = gBattleMons [ gActiveBattler ] . ability ;
2017-09-17 15:19:15 +02:00
effect + + ;
}
else if ( gBattleMons [ target1 ] . ability ! = 0 & & gBattleMons [ target1 ] . hp ! = 0 )
{
2018-02-06 02:46:59 +01:00
gActiveBattler = target1 ;
gBattleMons [ i ] . ability = gBattleMons [ gActiveBattler ] . ability ;
gLastUsedAbility = gBattleMons [ gActiveBattler ] . ability ;
2017-09-17 15:19:15 +02:00
effect + + ;
}
else if ( gBattleMons [ target2 ] . ability ! = 0 & & gBattleMons [ target2 ] . hp ! = 0 )
{
2018-02-06 02:46:59 +01:00
gActiveBattler = target2 ;
gBattleMons [ i ] . ability = gBattleMons [ gActiveBattler ] . ability ;
gLastUsedAbility = gBattleMons [ gActiveBattler ] . ability ;
2017-09-17 15:19:15 +02:00
effect + + ;
}
}
else
{
2018-02-06 02:46:59 +01:00
gActiveBattler = target1 ;
2017-09-17 15:19:15 +02:00
if ( gBattleMons [ target1 ] . ability & & gBattleMons [ target1 ] . hp )
{
gBattleMons [ i ] . ability = gBattleMons [ target1 ] . ability ;
gLastUsedAbility = gBattleMons [ target1 ] . ability ;
effect + + ;
}
}
if ( effect )
{
2017-09-28 15:34:21 +02:00
BattleScriptPushCursorAndCallback ( BattleScript_TraceActivates ) ;
2017-09-17 15:19:15 +02:00
gStatuses3 [ i ] & = ~ ( STATUS3_TRACE ) ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = i ;
2017-09-17 15:19:15 +02:00
2018-02-06 20:48:02 +01:00
PREPARE_MON_NICK_WITH_PREFIX_BUFFER ( gBattleTextBuff1 , gActiveBattler , gBattlerPartyIndexes [ gActiveBattler ] )
2017-10-12 17:49:24 +02:00
PREPARE_ABILITY_BUFFER ( gBattleTextBuff2 , gLastUsedAbility )
2017-09-17 15:19:15 +02:00
break ;
}
}
}
break ;
case ABILITYEFFECT_INTIMIDATE2 : // 10
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
if ( gBattleMons [ i ] . ability = = ABILITY_INTIMIDATE & & ( gStatuses3 [ i ] & STATUS3_INTIMIDATE_POKES ) )
{
gLastUsedAbility = ABILITY_INTIMIDATE ;
gStatuses3 [ i ] & = ~ ( STATUS3_INTIMIDATE_POKES ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-11-25 18:42:31 +01:00
gBattlescriptCurrInstr = BattleScript_82DB4C1 ;
2018-07-01 11:15:42 +02:00
gBattleStruct - > intimidateBattler = i ;
2017-09-17 15:19:15 +02:00
effect + + ;
break ;
}
}
break ;
case ABILITYEFFECT_CHECK_OTHER_SIDE : // 12
2018-02-06 02:46:59 +01:00
side = GetBattlerSide ( battler ) ;
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( i ) ! = side & & gBattleMons [ i ] . ability = = ability )
2017-09-17 15:19:15 +02:00
{
gLastUsedAbility = ability ;
effect = i + 1 ;
}
}
break ;
2018-07-01 11:15:42 +02:00
case ABILITYEFFECT_CHECK_BATTLER_SIDE : // 13
2018-02-06 02:46:59 +01:00
side = GetBattlerSide ( battler ) ;
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( i ) = = side & & gBattleMons [ i ] . ability = = ability )
2017-09-17 15:19:15 +02:00
{
gLastUsedAbility = ability ;
effect = i + 1 ;
}
}
break ;
case ABILITYEFFECT_CHECK_ON_FIELD : // 19
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
if ( gBattleMons [ i ] . ability = = ability & & gBattleMons [ i ] . hp ! = 0 )
{
gLastUsedAbility = ability ;
effect = i + 1 ;
}
}
break ;
2018-07-01 11:15:42 +02:00
case ABILITYEFFECT_CHECK_FIELD_EXCEPT_BATTLER : // 15
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ i ] . ability = = ability & & i ! = battler )
2017-09-17 15:19:15 +02:00
{
gLastUsedAbility = ability ;
effect = i + 1 ;
}
}
break ;
2017-09-27 23:43:45 +02:00
case ABILITYEFFECT_COUNT_OTHER_SIDE : // 16
2018-02-06 02:46:59 +01:00
side = GetBattlerSide ( battler ) ;
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( i ) ! = side & & gBattleMons [ i ] . ability = = ability )
2017-09-17 15:19:15 +02:00
{
gLastUsedAbility = ability ;
effect + + ;
}
}
break ;
2018-07-01 11:15:42 +02:00
case ABILITYEFFECT_COUNT_BATTLER_SIDE : // 17
2018-02-06 02:46:59 +01:00
side = GetBattlerSide ( battler ) ;
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( i ) = = side & & gBattleMons [ i ] . ability = = ability )
2017-09-17 15:19:15 +02:00
{
gLastUsedAbility = ability ;
effect + + ;
}
}
break ;
case ABILITYEFFECT_COUNT_ON_FIELD : // 18
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ i ] . ability = = ability & & i ! = battler )
2017-09-17 15:19:15 +02:00
{
gLastUsedAbility = ability ;
effect + + ;
}
}
break ;
}
2017-10-12 17:49:24 +02:00
if ( effect & & caseID < ABILITYEFFECT_CHECK_OTHER_SIDE & & gLastUsedAbility ! = 0xFF )
2018-02-06 02:46:59 +01:00
RecordAbilityBattle ( battler , gLastUsedAbility ) ;
2017-09-17 15:19:15 +02:00
}
return effect ;
}
2017-09-17 17:14:32 +02:00
2017-11-26 13:26:58 +01:00
void BattleScriptExecute ( const u8 * BS_ptr )
2017-09-17 17:14:32 +02:00
{
gBattlescriptCurrInstr = BS_ptr ;
2018-02-06 23:09:39 +01:00
gBattleResources - > battleCallbackStack - > function [ gBattleResources - > battleCallbackStack - > size + + ] = gBattleMainFunc ;
2017-10-06 00:12:01 +02:00
gBattleMainFunc = RunBattleScriptCommands_PopCallbacksStack ;
gCurrentActionFuncId = 0 ;
2017-09-17 17:14:32 +02:00
}
2017-11-26 13:26:58 +01:00
void BattleScriptPushCursorAndCallback ( const u8 * BS_ptr )
2017-09-17 17:14:32 +02:00
{
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattlescriptCurrInstr = BS_ptr ;
2018-02-06 23:09:39 +01:00
gBattleResources - > battleCallbackStack - > function [ gBattleResources - > battleCallbackStack - > size + + ] = gBattleMainFunc ;
2017-10-06 00:12:01 +02:00
gBattleMainFunc = RunBattleScriptCommands ;
2017-09-17 17:14:32 +02:00
}
enum
{
ITEM_NO_EFFECT , // 0
ITEM_STATUS_CHANGE , // 1
ITEM_EFFECT_OTHER , // 2
ITEM_PP_CHANGE , // 3
ITEM_HP_CHANGE , // 4
ITEM_STATS_CHANGE , // 5
} ;
2018-02-08 11:17:41 +01:00
u8 ItemBattleEffects ( u8 caseID , u8 battlerId , bool8 moveTurn )
2017-09-17 17:14:32 +02:00
{
int i = 0 ;
u8 effect = ITEM_NO_EFFECT ;
u8 changedPP = 0 ;
2018-07-01 11:15:42 +02:00
u8 BattlerHoldEffect , atkHoldEffect , defHoldEffect ;
u8 BattlerQuality , atkQuality , defQuality ;
2017-09-17 17:14:32 +02:00
u16 atkItem , defItem ;
2018-02-08 11:17:41 +01:00
gLastUsedItem = gBattleMons [ battlerId ] . item ;
2017-09-17 17:14:32 +02:00
if ( gLastUsedItem = = ITEM_ENIGMA_BERRY )
{
2018-07-01 11:15:42 +02:00
BattlerHoldEffect = gEnigmaBerries [ battlerId ] . holdEffect ;
BattlerQuality = gEnigmaBerries [ battlerId ] . holdEffectParam ;
2017-09-17 17:14:32 +02:00
}
else
{
2018-07-01 11:15:42 +02:00
BattlerHoldEffect = ItemId_GetHoldEffect ( gLastUsedItem ) ;
BattlerQuality = ItemId_GetHoldEffectParam ( gLastUsedItem ) ;
2017-09-17 17:14:32 +02:00
}
2018-02-06 23:09:39 +01:00
atkItem = gBattleMons [ gBattlerAttacker ] . item ;
2017-09-17 17:14:32 +02:00
if ( atkItem = = ITEM_ENIGMA_BERRY )
{
2018-02-06 23:09:39 +01:00
atkHoldEffect = gEnigmaBerries [ gBattlerAttacker ] . holdEffect ;
atkQuality = gEnigmaBerries [ gBattlerAttacker ] . holdEffectParam ;
2017-09-17 17:14:32 +02:00
}
else
{
atkHoldEffect = ItemId_GetHoldEffect ( atkItem ) ;
atkQuality = ItemId_GetHoldEffectParam ( atkItem ) ;
}
// def variables are unused
2018-02-06 23:09:39 +01:00
defItem = gBattleMons [ gBattlerTarget ] . item ;
2017-09-17 17:14:32 +02:00
if ( defItem = = ITEM_ENIGMA_BERRY )
{
2018-02-06 23:09:39 +01:00
defHoldEffect = gEnigmaBerries [ gBattlerTarget ] . holdEffect ;
defQuality = gEnigmaBerries [ gBattlerTarget ] . holdEffectParam ;
2017-09-17 17:14:32 +02:00
}
else
{
defHoldEffect = ItemId_GetHoldEffect ( defItem ) ;
defQuality = ItemId_GetHoldEffectParam ( defItem ) ;
}
switch ( caseID )
{
2017-10-06 00:12:01 +02:00
case ITEMEFFECT_ON_SWITCH_IN :
2018-07-01 11:15:42 +02:00
switch ( BattlerHoldEffect )
2017-09-17 17:14:32 +02:00
{
case HOLD_EFFECT_DOUBLE_PRIZE :
2018-02-08 11:17:41 +01:00
if ( GetBattlerSide ( battlerId ) = = B_SIDE_PLAYER )
2017-09-17 17:14:32 +02:00
gBattleStruct - > moneyMultiplier = 2 ;
break ;
case HOLD_EFFECT_RESTORE_STATS :
2017-11-26 11:55:17 +01:00
for ( i = 0 ; i < BATTLE_STATS_NO ; i + + )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . statStages [ i ] < 6 )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . statStages [ i ] = 6 ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATS_CHANGE ;
}
}
if ( effect )
{
2018-02-08 11:17:41 +01:00
gBattleScripting . battler = battlerId ;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = battlerId ;
2018-02-08 11:17:41 +01:00
gActiveBattler = gBattlerAttacker = battlerId ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_WhiteHerbEnd2 ) ;
2017-09-17 17:14:32 +02:00
}
break ;
}
break ;
case 1 :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp )
2017-09-17 17:14:32 +02:00
{
2018-07-01 11:15:42 +02:00
switch ( BattlerHoldEffect )
2017-09-17 17:14:32 +02:00
{
case HOLD_EFFECT_RESTORE_HP :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / 2 & & ! moveTurn )
2017-09-17 17:14:32 +02:00
{
2018-07-01 11:15:42 +02:00
gBattleMoveDamage = BattlerQuality ;
if ( gBattleMons [ battlerId ] . hp + BattlerQuality > gBattleMons [ battlerId ] . maxHP )
2018-02-08 11:17:41 +01:00
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP - gBattleMons [ battlerId ] . hp ;
2017-09-17 17:14:32 +02:00
gBattleMoveDamage * = - 1 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_ItemHealHP_RemoveItem ) ;
2017-09-17 17:14:32 +02:00
effect = 4 ;
}
break ;
case HOLD_EFFECT_RESTORE_PP :
if ( ! moveTurn )
{
2017-11-26 11:55:17 +01:00
struct Pokemon * mon ;
2017-09-17 17:14:32 +02:00
u8 ppBonuses ;
u16 move ;
2018-02-08 11:17:41 +01:00
if ( GetBattlerSide ( battlerId ) = = B_SIDE_PLAYER )
mon = & gPlayerParty [ gBattlerPartyIndexes [ battlerId ] ] ;
2017-09-17 17:14:32 +02:00
else
2018-02-08 11:17:41 +01:00
mon = & gEnemyParty [ gBattlerPartyIndexes [ battlerId ] ] ;
2017-09-17 17:14:32 +02:00
for ( i = 0 ; i < 4 ; i + + )
{
2017-11-26 11:55:17 +01:00
move = GetMonData ( mon , MON_DATA_MOVE1 + i ) ;
changedPP = GetMonData ( mon , MON_DATA_PP1 + i ) ;
ppBonuses = GetMonData ( mon , MON_DATA_PP_BONUSES ) ;
2017-09-17 17:14:32 +02:00
if ( move & & changedPP = = 0 )
break ;
}
if ( i ! = 4 )
{
u8 maxPP = CalculatePPWithBonus ( move , ppBonuses , i ) ;
2018-07-01 11:15:42 +02:00
if ( changedPP + BattlerQuality > maxPP )
2017-09-17 17:14:32 +02:00
changedPP = maxPP ;
else
2018-07-01 11:15:42 +02:00
changedPP = changedPP + BattlerQuality ;
2017-11-26 11:55:17 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , move ) ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryPPHealEnd2 ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , i + REQUEST_PPMOVE1_BATTLE , 0 , 1 , & changedPP ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_PP_CHANGE ;
}
}
break ;
case HOLD_EFFECT_RESTORE_STATS :
2017-11-26 11:55:17 +01:00
for ( i = 0 ; i < BATTLE_STATS_NO ; i + + )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . statStages [ i ] < 6 )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . statStages [ i ] = 6 ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATS_CHANGE ;
}
}
if ( effect )
{
2018-02-08 11:17:41 +01:00
gBattleScripting . battler = battlerId ;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = battlerId ;
2018-02-08 11:17:41 +01:00
gActiveBattler = gBattlerAttacker = battlerId ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_WhiteHerbEnd2 ) ;
2017-09-17 17:14:32 +02:00
}
break ;
case HOLD_EFFECT_LEFTOVERS :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp < gBattleMons [ battlerId ] . maxHP & & ! moveTurn )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP / 16 ;
2017-09-17 17:14:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp + gBattleMoveDamage > gBattleMons [ battlerId ] . maxHP )
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP - gBattleMons [ battlerId ] . hp ;
2017-09-17 17:14:32 +02:00
gBattleMoveDamage * = - 1 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_ItemHealHP_End2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_HP_CHANGE ;
2018-07-01 11:15:42 +02:00
RecordItemEffectBattle ( battlerId , BattlerHoldEffect ) ;
2017-09-17 17:14:32 +02:00
}
break ;
// nice copy/paste there gamefreak, making a function for confuse berries was too much eh?
case HOLD_EFFECT_CONFUSE_SPICY :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / 2 & & ! moveTurn )
2017-09-17 17:14:32 +02:00
{
2017-11-27 21:24:34 +01:00
PREPARE_FLAVOR_BUFFER ( gBattleTextBuff1 , FLAVOR_SPICY ) ;
2017-11-26 11:55:17 +01:00
2018-07-01 11:15:42 +02:00
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP / BattlerQuality ;
2017-09-17 17:14:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp + gBattleMoveDamage > gBattleMons [ battlerId ] . maxHP )
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP - gBattleMons [ battlerId ] . hp ;
2017-09-17 17:14:32 +02:00
gBattleMoveDamage * = - 1 ;
2018-02-08 11:17:41 +01:00
if ( GetFlavorRelationByPersonality ( gBattleMons [ battlerId ] . personality , FLAVOR_SPICY ) < 0 )
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryConfuseHealEnd2 ) ;
2017-09-17 17:14:32 +02:00
else
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_ItemHealHP_RemoveItem ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_HP_CHANGE ;
}
break ;
case HOLD_EFFECT_CONFUSE_DRY :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / 2 & & ! moveTurn )
2017-09-17 17:14:32 +02:00
{
2017-11-27 21:24:34 +01:00
PREPARE_FLAVOR_BUFFER ( gBattleTextBuff1 , FLAVOR_DRY ) ;
2017-11-26 11:55:17 +01:00
2018-07-01 11:15:42 +02:00
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP / BattlerQuality ;
2017-09-17 17:14:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp + gBattleMoveDamage > gBattleMons [ battlerId ] . maxHP )
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP - gBattleMons [ battlerId ] . hp ;
2017-09-17 17:14:32 +02:00
gBattleMoveDamage * = - 1 ;
2018-02-08 11:17:41 +01:00
if ( GetFlavorRelationByPersonality ( gBattleMons [ battlerId ] . personality , FLAVOR_DRY ) < 0 )
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryConfuseHealEnd2 ) ;
2017-09-17 17:14:32 +02:00
else
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_ItemHealHP_RemoveItem ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_HP_CHANGE ;
}
break ;
case HOLD_EFFECT_CONFUSE_SWEET :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / 2 & & ! moveTurn )
2017-09-17 17:14:32 +02:00
{
2017-11-27 21:24:34 +01:00
PREPARE_FLAVOR_BUFFER ( gBattleTextBuff1 , FLAVOR_SWEET ) ;
2017-11-26 11:55:17 +01:00
2018-07-01 11:15:42 +02:00
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP / BattlerQuality ;
2017-09-17 17:14:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp + gBattleMoveDamage > gBattleMons [ battlerId ] . maxHP )
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP - gBattleMons [ battlerId ] . hp ;
2017-09-17 17:14:32 +02:00
gBattleMoveDamage * = - 1 ;
2018-02-08 11:17:41 +01:00
if ( GetFlavorRelationByPersonality ( gBattleMons [ battlerId ] . personality , FLAVOR_SWEET ) < 0 )
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryConfuseHealEnd2 ) ;
2017-09-17 17:14:32 +02:00
else
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_ItemHealHP_RemoveItem ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_HP_CHANGE ;
}
break ;
case HOLD_EFFECT_CONFUSE_BITTER :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / 2 & & ! moveTurn )
2017-09-17 17:14:32 +02:00
{
2017-11-27 21:24:34 +01:00
PREPARE_FLAVOR_BUFFER ( gBattleTextBuff1 , FLAVOR_BITTER ) ;
2017-11-26 11:55:17 +01:00
2018-07-01 11:15:42 +02:00
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP / BattlerQuality ;
2017-09-17 17:14:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp + gBattleMoveDamage > gBattleMons [ battlerId ] . maxHP )
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP - gBattleMons [ battlerId ] . hp ;
2017-09-17 17:14:32 +02:00
gBattleMoveDamage * = - 1 ;
2018-02-08 11:17:41 +01:00
if ( GetFlavorRelationByPersonality ( gBattleMons [ battlerId ] . personality , FLAVOR_BITTER ) < 0 )
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryConfuseHealEnd2 ) ;
2017-09-17 17:14:32 +02:00
else
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_ItemHealHP_RemoveItem ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_HP_CHANGE ;
}
break ;
case HOLD_EFFECT_CONFUSE_SOUR :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / 2 & & ! moveTurn )
2017-09-17 17:14:32 +02:00
{
2017-11-27 21:24:34 +01:00
PREPARE_FLAVOR_BUFFER ( gBattleTextBuff1 , FLAVOR_SOUR ) ;
2017-11-26 11:55:17 +01:00
2018-07-01 11:15:42 +02:00
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP / BattlerQuality ;
2017-09-17 17:14:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp + gBattleMoveDamage > gBattleMons [ battlerId ] . maxHP )
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP - gBattleMons [ battlerId ] . hp ;
2017-09-17 17:14:32 +02:00
gBattleMoveDamage * = - 1 ;
2018-02-08 11:17:41 +01:00
if ( GetFlavorRelationByPersonality ( gBattleMons [ battlerId ] . personality , FLAVOR_SOUR ) < 0 )
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryConfuseHealEnd2 ) ;
2017-09-17 17:14:32 +02:00
else
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_ItemHealHP_RemoveItem ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_HP_CHANGE ;
}
break ;
// copy/paste again, smh
case HOLD_EFFECT_ATTACK_UP :
2018-07-01 11:15:42 +02:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / BattlerQuality & & ! moveTurn & & gBattleMons [ battlerId ] . statStages [ STAT_ATK ] < 0xC )
2017-09-17 17:14:32 +02:00
{
2018-02-08 12:13:29 +01:00
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , STAT_ATK ) ;
2017-11-26 11:55:17 +01:00
PREPARE_STRING_BUFFER ( gBattleTextBuff2 , STRINGID_STATROSE ) ;
2017-09-17 17:14:32 +02:00
2018-02-08 11:17:41 +01:00
gEffectBattler = battlerId ;
2018-02-08 12:13:29 +01:00
SET_STATCHANGER ( STAT_ATK , 1 , FALSE ) ;
gBattleScripting . animArg1 = 0xE + STAT_ATK ;
2017-09-17 17:14:32 +02:00
gBattleScripting . animArg2 = 0 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryStatRaiseEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATS_CHANGE ;
}
break ;
case HOLD_EFFECT_DEFENSE_UP :
2018-07-01 11:15:42 +02:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / BattlerQuality & & ! moveTurn & & gBattleMons [ battlerId ] . statStages [ STAT_DEF ] < 0xC )
2017-09-17 17:14:32 +02:00
{
2018-02-08 12:13:29 +01:00
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , STAT_DEF ) ;
2017-09-17 17:14:32 +02:00
2018-02-08 11:17:41 +01:00
gEffectBattler = battlerId ;
2018-02-08 12:13:29 +01:00
SET_STATCHANGER ( STAT_DEF , 1 , FALSE ) ;
gBattleScripting . animArg1 = 0xE + STAT_DEF ;
2017-09-17 17:14:32 +02:00
gBattleScripting . animArg2 = 0 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryStatRaiseEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATS_CHANGE ;
}
break ;
case HOLD_EFFECT_SPEED_UP :
2018-07-01 11:15:42 +02:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / BattlerQuality & & ! moveTurn & & gBattleMons [ battlerId ] . statStages [ STAT_SPEED ] < 0xC )
2017-09-17 17:14:32 +02:00
{
2018-02-08 12:13:29 +01:00
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , STAT_SPEED ) ;
2017-09-17 17:14:32 +02:00
2018-02-08 11:17:41 +01:00
gEffectBattler = battlerId ;
2018-02-08 12:13:29 +01:00
SET_STATCHANGER ( STAT_SPEED , 1 , FALSE ) ;
gBattleScripting . animArg1 = 0xE + STAT_SPEED ;
2017-09-17 17:14:32 +02:00
gBattleScripting . animArg2 = 0 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryStatRaiseEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATS_CHANGE ;
}
break ;
case HOLD_EFFECT_SP_ATTACK_UP :
2018-07-01 11:15:42 +02:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / BattlerQuality & & ! moveTurn & & gBattleMons [ battlerId ] . statStages [ STAT_SPATK ] < 0xC )
2017-09-17 17:14:32 +02:00
{
2018-02-08 12:13:29 +01:00
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , STAT_SPATK ) ;
2017-09-17 17:14:32 +02:00
2018-02-08 11:17:41 +01:00
gEffectBattler = battlerId ;
2018-02-08 12:13:29 +01:00
SET_STATCHANGER ( STAT_SPATK , 1 , FALSE ) ;
gBattleScripting . animArg1 = 0xE + STAT_SPATK ;
2017-09-17 17:14:32 +02:00
gBattleScripting . animArg2 = 0 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryStatRaiseEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATS_CHANGE ;
}
break ;
case HOLD_EFFECT_SP_DEFENSE_UP :
2018-07-01 11:15:42 +02:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / BattlerQuality & & ! moveTurn & & gBattleMons [ battlerId ] . statStages [ STAT_SPDEF ] < 0xC )
2017-09-17 17:14:32 +02:00
{
2018-02-08 12:13:29 +01:00
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , STAT_SPDEF ) ;
2017-09-17 17:14:32 +02:00
2018-02-08 11:17:41 +01:00
gEffectBattler = battlerId ;
2018-02-08 12:13:29 +01:00
SET_STATCHANGER ( STAT_SPDEF , 1 , FALSE ) ;
gBattleScripting . animArg1 = 0xE + STAT_SPDEF ;
2017-09-17 17:14:32 +02:00
gBattleScripting . animArg2 = 0 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryStatRaiseEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATS_CHANGE ;
}
break ;
case HOLD_EFFECT_CRITICAL_UP :
2018-07-01 11:15:42 +02:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / BattlerQuality & & ! moveTurn & & ! ( gBattleMons [ battlerId ] . status2 & STATUS2_FOCUS_ENERGY ) )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status2 | = STATUS2_FOCUS_ENERGY ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryFocusEnergyEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_EFFECT_OTHER ;
}
break ;
case HOLD_EFFECT_RANDOM_STAT_UP :
2018-07-01 11:15:42 +02:00
if ( ! moveTurn & & gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / BattlerQuality )
2017-09-17 17:14:32 +02:00
{
for ( i = 0 ; i < 5 ; i + + )
{
2018-02-08 12:13:29 +01:00
if ( gBattleMons [ battlerId ] . statStages [ STAT_ATK + i ] < 0xC )
2017-09-17 17:14:32 +02:00
break ;
}
if ( i ! = 5 )
{
do
{
i = Random ( ) % 5 ;
2018-02-08 12:13:29 +01:00
} while ( gBattleMons [ battlerId ] . statStages [ STAT_ATK + i ] = = 0xC ) ;
2017-09-17 17:14:32 +02:00
2017-11-26 11:55:17 +01:00
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , i + 1 ) ;
gBattleTextBuff2 [ 0 ] = B_BUFF_PLACEHOLDER_BEGIN ;
gBattleTextBuff2 [ 1 ] = B_BUFF_STRING ;
gBattleTextBuff2 [ 2 ] = STRINGID_STATSHARPLY ;
gBattleTextBuff2 [ 3 ] = STRINGID_STATSHARPLY > > 8 ;
gBattleTextBuff2 [ 4 ] = B_BUFF_STRING ;
gBattleTextBuff2 [ 5 ] = STRINGID_STATROSE ;
gBattleTextBuff2 [ 6 ] = STRINGID_STATROSE > > 8 ;
2017-09-17 17:14:32 +02:00
gBattleTextBuff2 [ 7 ] = EOS ;
2018-02-08 11:17:41 +01:00
gEffectBattler = battlerId ;
2017-11-26 11:55:17 +01:00
SET_STATCHANGER ( i + 1 , 2 , FALSE ) ;
2017-09-17 17:14:32 +02:00
gBattleScripting . animArg1 = 0x21 + i + 6 ;
gBattleScripting . animArg2 = 0 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryStatRaiseEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATS_CHANGE ;
}
}
break ;
case HOLD_EFFECT_CURE_PAR :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_PARALYSIS )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 & = ~ ( STATUS1_PARALYSIS ) ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryCurePrlzEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_PSN :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_PSN_ANY )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 & = ~ ( STATUS1_PSN_ANY | STATUS1_TOXIC_COUNTER ) ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryCurePsnEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_BRN :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_BURN )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 & = ~ ( STATUS1_BURN ) ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryCureBrnEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_FRZ :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_FREEZE )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 & = ~ ( STATUS1_FREEZE ) ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryCureFrzEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_SLP :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_SLEEP )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 & = ~ ( STATUS1_SLEEP ) ;
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryCureSlpEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_CONFUSION :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status2 & STATUS2_CONFUSION )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_CONFUSION ) ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryCureConfusionEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_EFFECT_OTHER ;
}
break ;
case HOLD_EFFECT_CURE_STATUS :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_ANY | | gBattleMons [ battlerId ] . status2 & STATUS2_CONFUSION )
2017-09-17 17:14:32 +02:00
{
i = 0 ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_PSN_ANY )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_PoisonJpn ) ;
i + + ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_SLEEP )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
2017-09-17 17:14:32 +02:00
StringCopy ( gBattleTextBuff1 , gStatusConditionString_SleepJpn ) ;
i + + ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_PARALYSIS )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_ParalysisJpn ) ;
i + + ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_BURN )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_BurnJpn ) ;
i + + ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_FREEZE )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_IceJpn ) ;
i + + ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status2 & STATUS2_CONFUSION )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_ConfusionJpn ) ;
i + + ;
}
if ( ! ( i > 1 ) )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 = 0 ;
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_CONFUSION ) ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryCureChosenStatusEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_ATTRACT :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status2 & STATUS2_INFATUATION )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_INFATUATION ) ;
2017-09-17 17:14:32 +02:00
StringCopy ( gBattleTextBuff1 , gStatusConditionString_LoveJpn ) ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryCureChosenStatusEnd2 ) ;
2017-09-17 17:14:32 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
effect = ITEM_EFFECT_OTHER ;
}
break ;
}
if ( effect )
{
2018-02-08 11:17:41 +01:00
gBattleScripting . battler = battlerId ;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = battlerId ;
2018-02-08 11:17:41 +01:00
gActiveBattler = gBattlerAttacker = battlerId ;
2017-09-17 17:14:32 +02:00
switch ( effect )
{
case ITEM_STATUS_CHANGE :
2018-02-08 11:17:41 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ battlerId ] . status1 ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-17 17:14:32 +02:00
break ;
case ITEM_PP_CHANGE :
2018-02-08 11:17:41 +01:00
if ( ! ( gBattleMons [ battlerId ] . status2 & STATUS2_TRANSFORMED ) & & ! ( gDisableStructs [ battlerId ] . unk18_b & gBitTable [ i ] ) )
gBattleMons [ battlerId ] . pp [ i ] = changedPP ;
2017-09-17 17:14:32 +02:00
break ;
}
}
}
break ;
case 2 :
break ;
case 3 :
2018-02-08 11:17:41 +01:00
for ( battlerId = 0 ; battlerId < gBattlersCount ; battlerId + + )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gLastUsedItem = gBattleMons [ battlerId ] . item ;
if ( gBattleMons [ battlerId ] . item = = ITEM_ENIGMA_BERRY )
2017-09-17 17:14:32 +02:00
{
2018-07-01 11:15:42 +02:00
BattlerHoldEffect = gEnigmaBerries [ battlerId ] . holdEffect ;
BattlerQuality = gEnigmaBerries [ battlerId ] . holdEffectParam ;
2017-09-17 17:14:32 +02:00
}
else
{
2018-07-01 11:15:42 +02:00
BattlerHoldEffect = ItemId_GetHoldEffect ( gLastUsedItem ) ;
BattlerQuality = ItemId_GetHoldEffectParam ( gLastUsedItem ) ;
2017-09-17 17:14:32 +02:00
}
2018-07-01 11:15:42 +02:00
switch ( BattlerHoldEffect )
2017-09-17 17:14:32 +02:00
{
case HOLD_EFFECT_CURE_PAR :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_PARALYSIS )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 & = ~ ( STATUS1_PARALYSIS ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattlescriptCurrInstr = BattleScript_BerryCureParRet ;
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_PSN :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_PSN_ANY )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 & = ~ ( STATUS1_PSN_ANY | STATUS1_TOXIC_COUNTER ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattlescriptCurrInstr = BattleScript_BerryCurePsnRet ;
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_BRN :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_BURN )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 & = ~ ( STATUS1_BURN ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattlescriptCurrInstr = BattleScript_BerryCureBrnRet ;
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_FRZ :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_FREEZE )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 & = ~ ( STATUS1_FREEZE ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattlescriptCurrInstr = BattleScript_BerryCureFrzRet ;
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_SLP :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_SLEEP )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 & = ~ ( STATUS1_SLEEP ) ;
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattlescriptCurrInstr = BattleScript_BerryCureSlpRet ;
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_CONFUSION :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status2 & STATUS2_CONFUSION )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_CONFUSION ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattlescriptCurrInstr = BattleScript_BerryCureConfusionRet ;
effect = ITEM_EFFECT_OTHER ;
}
break ;
case HOLD_EFFECT_CURE_ATTRACT :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status2 & STATUS2_INFATUATION )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_INFATUATION ) ;
2017-09-17 17:14:32 +02:00
StringCopy ( gBattleTextBuff1 , gStatusConditionString_LoveJpn ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
gBattlescriptCurrInstr = BattleScript_BerryCureChosenStatusRet ;
effect = ITEM_EFFECT_OTHER ;
}
break ;
case HOLD_EFFECT_CURE_STATUS :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_ANY | | gBattleMons [ battlerId ] . status2 & STATUS2_CONFUSION )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_PSN_ANY )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_PoisonJpn ) ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_SLEEP )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
2017-09-17 17:14:32 +02:00
StringCopy ( gBattleTextBuff1 , gStatusConditionString_SleepJpn ) ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_PARALYSIS )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_ParalysisJpn ) ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_BURN )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_BurnJpn ) ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_FREEZE )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_IceJpn ) ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status2 & STATUS2_CONFUSION )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_ConfusionJpn ) ;
}
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 = 0 ;
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_CONFUSION ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
gBattlescriptCurrInstr = BattleScript_BerryCureChosenStatusRet ;
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_RESTORE_STATS :
2017-11-26 11:55:17 +01:00
for ( i = 0 ; i < BATTLE_STATS_NO ; i + + )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . statStages [ i ] < 6 )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . statStages [ i ] = 6 ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATS_CHANGE ;
}
}
if ( effect )
{
2018-02-08 11:17:41 +01:00
gBattleScripting . battler = battlerId ;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = battlerId ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattlescriptCurrInstr = BattleScript_WhiteHerbRet ;
return effect ; // unnecessary return
}
break ;
}
if ( effect )
{
2018-02-08 11:17:41 +01:00
gBattleScripting . battler = battlerId ;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = battlerId ;
2018-02-08 11:17:41 +01:00
gActiveBattler = battlerId ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gActiveBattler ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-17 17:14:32 +02:00
break ;
}
}
break ;
case 4 :
if ( gBattleMoveDamage )
{
switch ( atkHoldEffect )
{
case HOLD_EFFECT_FLINCH :
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2018-03-01 00:59:52 +01:00
& & TARGET_TURN_DAMAGED
2017-09-17 17:14:32 +02:00
& & ( Random ( ) % 100 ) < atkQuality
& & gBattleMoves [ gCurrentMove ] . flags & FLAG_KINGSROCK_AFFECTED
2018-02-06 23:09:39 +01:00
& & gBattleMons [ gBattlerTarget ] . hp )
2017-09-17 17:14:32 +02:00
{
2017-12-02 14:08:55 +01:00
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_FLINCH ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
SetMoveEffect ( 0 , 0 ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPop ( ) ;
2017-09-17 17:14:32 +02:00
}
break ;
case HOLD_EFFECT_SHELL_BELL :
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2018-02-07 22:53:40 +01:00
& & gSpecialStatuses [ gBattlerTarget ] . dmg ! = 0
& & gSpecialStatuses [ gBattlerTarget ] . dmg ! = 0xFFFF
2018-02-06 23:09:39 +01:00
& & gBattlerAttacker ! = gBattlerTarget
& & gBattleMons [ gBattlerAttacker ] . hp ! = gBattleMons [ gBattlerAttacker ] . maxHP
& & gBattleMons [ gBattlerAttacker ] . hp ! = 0 )
2017-09-17 17:14:32 +02:00
{
gLastUsedItem = atkItem ;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerAttacker ;
2018-02-06 23:09:39 +01:00
gBattleScripting . battler = gBattlerAttacker ;
2018-02-07 22:53:40 +01:00
gBattleMoveDamage = ( gSpecialStatuses [ gBattlerTarget ] . dmg / atkQuality ) * - 1 ;
2017-09-17 17:14:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = - 1 ;
2018-02-07 22:53:40 +01:00
gSpecialStatuses [ gBattlerTarget ] . dmg = 0 ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattlescriptCurrInstr = BattleScript_ItemHealHP_Ret ;
effect + + ;
}
break ;
}
}
break ;
}
return effect ;
}
2018-02-08 11:17:41 +01:00
void ClearFuryCutterDestinyBondGrudge ( u8 battlerId )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gDisableStructs [ battlerId ] . furyCutterCounter = 0 ;
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_DESTINY_BOND ) ;
gStatuses3 [ battlerId ] & = ~ ( STATUS3_GRUDGE ) ;
2017-09-17 17:14:32 +02:00
}
2017-10-06 17:06:45 +02:00
void HandleAction_RunBattleScript ( void ) // identical to RunBattleScriptCommands
2017-09-17 17:14:32 +02:00
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-17 17:14:32 +02:00
gBattleScriptingCommandsTable [ * gBattlescriptCurrInstr ] ( ) ;
}
2018-03-01 00:59:52 +01:00
u8 GetMoveTarget ( u16 move , u8 setTarget )
2017-09-17 17:14:32 +02:00
{
2018-07-01 11:15:42 +02:00
u8 targetBattler = 0 ;
2017-09-17 17:14:32 +02:00
u8 moveTarget ;
u8 side ;
2018-03-01 00:59:52 +01:00
if ( setTarget )
moveTarget = setTarget - 1 ;
2017-09-17 17:14:32 +02:00
else
moveTarget = gBattleMoves [ move ] . target ;
switch ( moveTarget )
{
2017-09-19 21:01:12 +02:00
case MOVE_TARGET_SELECTED :
2018-02-06 23:09:39 +01:00
side = GetBattlerSide ( gBattlerAttacker ) ^ BIT_SIDE ;
2017-09-17 17:14:32 +02:00
if ( gSideTimers [ side ] . followmeTimer & & gBattleMons [ gSideTimers [ side ] . followmeTarget ] . hp )
2018-07-01 11:15:42 +02:00
targetBattler = gSideTimers [ side ] . followmeTarget ;
2017-09-17 17:14:32 +02:00
else
{
2018-02-06 23:09:39 +01:00
side = GetBattlerSide ( gBattlerAttacker ) ;
2017-09-17 17:14:32 +02:00
do
{
2018-07-01 11:15:42 +02:00
targetBattler = Random ( ) % gBattlersCount ;
} while ( targetBattler = = gBattlerAttacker | | side = = GetBattlerSide ( targetBattler ) | | gAbsentBattlerFlags & gBitTable [ targetBattler ] ) ;
2017-09-17 17:14:32 +02:00
if ( gBattleMoves [ move ] . type = = TYPE_ELECTRIC
2018-02-06 23:09:39 +01:00
& & AbilityBattleEffects ( ABILITYEFFECT_COUNT_OTHER_SIDE , gBattlerAttacker , ABILITY_LIGHTNING_ROD , 0 , 0 )
2018-07-01 11:15:42 +02:00
& & gBattleMons [ targetBattler ] . ability ! = ABILITY_LIGHTNING_ROD )
2017-09-17 17:14:32 +02:00
{
2018-07-01 11:15:42 +02:00
targetBattler ^ = BIT_FLANK ;
RecordAbilityBattle ( targetBattler , gBattleMons [ targetBattler ] . ability ) ;
gSpecialStatuses [ targetBattler ] . lightningRodRedirected = 1 ;
2017-09-17 17:14:32 +02:00
}
}
break ;
2017-09-19 21:01:12 +02:00
case MOVE_TARGET_DEPENDS :
case MOVE_TARGET_BOTH :
case MOVE_TARGET_FOES_AND_ALLY :
case MOVE_TARGET_OPPONENTS_FIELD :
2018-07-01 11:15:42 +02:00
targetBattler = GetBattlerAtPosition ( ( GetBattlerPosition ( gBattlerAttacker ) & BIT_SIDE ) ^ BIT_SIDE ) ;
if ( gAbsentBattlerFlags & gBitTable [ targetBattler ] )
targetBattler ^ = BIT_FLANK ;
2017-09-17 17:14:32 +02:00
break ;
2017-09-19 21:01:12 +02:00
case MOVE_TARGET_RANDOM :
2018-02-06 23:09:39 +01:00
side = GetBattlerSide ( gBattlerAttacker ) ^ BIT_SIDE ;
2017-09-17 17:14:32 +02:00
if ( gSideTimers [ side ] . followmeTimer & & gBattleMons [ gSideTimers [ side ] . followmeTarget ] . hp )
2018-07-01 11:15:42 +02:00
targetBattler = gSideTimers [ side ] . followmeTarget ;
2017-09-19 21:01:12 +02:00
else if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE & & moveTarget & MOVE_TARGET_RANDOM )
2017-09-17 17:14:32 +02:00
{
2018-02-06 23:09:39 +01:00
if ( GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_PLAYER )
2017-09-17 17:14:32 +02:00
{
if ( Random ( ) & 1 )
2018-07-01 11:15:42 +02:00
targetBattler = GetBattlerAtPosition ( B_POSITION_OPPONENT_LEFT ) ;
2017-09-17 17:14:32 +02:00
else
2018-07-01 11:15:42 +02:00
targetBattler = GetBattlerAtPosition ( B_POSITION_OPPONENT_RIGHT ) ;
2017-09-17 17:14:32 +02:00
}
else
{
if ( Random ( ) & 1 )
2018-07-01 11:15:42 +02:00
targetBattler = GetBattlerAtPosition ( B_POSITION_PLAYER_LEFT ) ;
2017-09-17 17:14:32 +02:00
else
2018-07-01 11:15:42 +02:00
targetBattler = GetBattlerAtPosition ( B_POSITION_PLAYER_RIGHT ) ;
2017-09-17 17:14:32 +02:00
}
2018-07-01 11:15:42 +02:00
if ( gAbsentBattlerFlags & gBitTable [ targetBattler ] )
targetBattler ^ = BIT_FLANK ;
2017-09-17 17:14:32 +02:00
}
else
2018-07-01 11:15:42 +02:00
targetBattler = GetBattlerAtPosition ( ( GetBattlerPosition ( gBattlerAttacker ) & BIT_SIDE ) ^ BIT_SIDE ) ;
2017-09-17 17:14:32 +02:00
break ;
2018-02-26 13:24:46 +01:00
case MOVE_TARGET_USER_OR_SELECTED :
2017-09-19 21:01:12 +02:00
case MOVE_TARGET_USER :
2018-07-01 11:15:42 +02:00
targetBattler = gBattlerAttacker ;
2017-09-17 17:14:32 +02:00
break ;
}
2018-07-01 11:15:42 +02:00
* ( gBattleStruct - > moveTarget + gBattlerAttacker ) = targetBattler ;
2017-09-17 17:14:32 +02:00
2018-07-01 11:15:42 +02:00
return targetBattler ;
2017-09-17 17:14:32 +02:00
}
2018-02-08 11:17:41 +01:00
static bool32 HasObedientBitSet ( u8 battlerId )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
if ( GetBattlerSide ( battlerId ) = = B_SIDE_OPPONENT )
2017-09-17 17:14:32 +02:00
return TRUE ;
2018-02-08 11:17:41 +01:00
if ( GetMonData ( & gPlayerParty [ gBattlerPartyIndexes [ battlerId ] ] , MON_DATA_SPECIES , NULL ) ! = SPECIES_DEOXYS
& & GetMonData ( & gPlayerParty [ gBattlerPartyIndexes [ battlerId ] ] , MON_DATA_SPECIES , NULL ) ! = SPECIES_MEW )
2017-09-17 17:14:32 +02:00
return TRUE ;
2018-02-08 11:17:41 +01:00
return GetMonData ( & gPlayerParty [ gBattlerPartyIndexes [ battlerId ] ] , MON_DATA_OBEDIENCE , NULL ) ;
2017-09-17 17:14:32 +02:00
}
2017-12-02 14:08:55 +01:00
u8 IsMonDisobedient ( void )
2017-09-17 17:14:32 +02:00
{
s32 rnd ;
s32 calc ;
u8 obedienceLevel = 0 ;
if ( gBattleTypeFlags & ( BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000 ) )
return 0 ;
2018-02-06 23:09:39 +01:00
if ( GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_OPPONENT )
2017-09-17 17:14:32 +02:00
return 0 ;
2018-02-06 23:09:39 +01:00
if ( HasObedientBitSet ( gBattlerAttacker ) ) // only if species is Mew or Deoxys
2017-09-17 17:14:32 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER & & GetBattlerPosition ( gBattlerAttacker ) = = 2 )
2017-09-17 17:14:32 +02:00
return 0 ;
if ( gBattleTypeFlags & BATTLE_TYPE_FRONTIER )
return 0 ;
if ( gBattleTypeFlags & BATTLE_TYPE_RECORDED )
return 0 ;
2018-02-06 23:09:39 +01:00
if ( ! IsOtherTrainer ( gBattleMons [ gBattlerAttacker ] . otId , gBattleMons [ gBattlerAttacker ] . otName ) )
2017-09-17 17:14:32 +02:00
return 0 ;
2017-11-08 22:20:10 +01:00
if ( FlagGet ( FLAG_BADGE08_GET ) )
2017-09-17 17:14:32 +02:00
return 0 ;
obedienceLevel = 10 ;
2017-11-08 22:20:10 +01:00
if ( FlagGet ( FLAG_BADGE02_GET ) )
2017-09-17 17:14:32 +02:00
obedienceLevel = 30 ;
2017-11-08 22:20:10 +01:00
if ( FlagGet ( FLAG_BADGE04_GET ) )
2017-09-17 17:14:32 +02:00
obedienceLevel = 50 ;
2017-11-08 22:20:10 +01:00
if ( FlagGet ( FLAG_BADGE06_GET ) )
2017-09-17 17:14:32 +02:00
obedienceLevel = 70 ;
}
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . level < = obedienceLevel )
2017-09-17 17:14:32 +02:00
return 0 ;
rnd = ( Random ( ) & 255 ) ;
2018-02-06 23:09:39 +01:00
calc = ( gBattleMons [ gBattlerAttacker ] . level + obedienceLevel ) * rnd > > 8 ;
2017-09-17 17:14:32 +02:00
if ( calc < obedienceLevel )
return 0 ;
// is not obedient
if ( gCurrentMove = = MOVE_RAGE )
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 & = ~ ( STATUS2_RAGE ) ;
if ( gBattleMons [ gBattlerAttacker ] . status1 & STATUS1_SLEEP & & ( gCurrentMove = = MOVE_SNORE | | gCurrentMove = = MOVE_SLEEP_TALK ) )
2017-09-17 17:14:32 +02:00
{
2017-11-25 18:42:31 +01:00
gBattlescriptCurrInstr = BattleScript_82DB695 ;
2017-09-17 17:14:32 +02:00
return 1 ;
}
rnd = ( Random ( ) & 255 ) ;
2018-02-06 23:09:39 +01:00
calc = ( gBattleMons [ gBattlerAttacker ] . level + obedienceLevel ) * rnd > > 8 ;
2017-09-17 17:14:32 +02:00
if ( calc < obedienceLevel )
{
2018-02-06 23:09:39 +01:00
calc = CheckMoveLimitations ( gBattlerAttacker , gBitTable [ gCurrMovePos ] , 0xFF ) ;
2017-09-17 17:14:32 +02:00
if ( calc = = 0xF ) // all moves cannot be used
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = Random ( ) & 3 ;
gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround ;
return 1 ;
}
else // use a random move
{
do
{
2018-02-08 11:17:41 +01:00
gCurrMovePos = gChosenMovePos = Random ( ) & 3 ;
2017-09-17 17:14:32 +02:00
} while ( gBitTable [ gCurrMovePos ] & calc ) ;
2018-02-06 23:09:39 +01:00
gRandomMove = gBattleMons [ gBattlerAttacker ] . moves [ gCurrMovePos ] ;
2017-11-26 17:15:28 +01:00
gBattlescriptCurrInstr = BattleScript_IgnoresAndUsesRandomMove ;
2018-02-06 23:09:39 +01:00
gBattlerTarget = GetMoveTarget ( gRandomMove , 0 ) ;
2017-09-17 17:14:32 +02:00
gHitMarker | = HITMARKER_x200000 ;
return 2 ;
}
}
else
{
2018-02-06 23:09:39 +01:00
obedienceLevel = gBattleMons [ gBattlerAttacker ] . level - obedienceLevel ;
2017-09-17 17:14:32 +02:00
calc = ( Random ( ) & 255 ) ;
2018-02-06 23:09:39 +01:00
if ( calc < obedienceLevel & & ! ( gBattleMons [ gBattlerAttacker ] . status1 & STATUS1_ANY ) & & gBattleMons [ gBattlerAttacker ] . ability ! = ABILITY_VITAL_SPIRIT & & gBattleMons [ gBattlerAttacker ] . ability ! = ABILITY_INSOMNIA )
2017-09-17 17:14:32 +02:00
{
// try putting asleep
int i ;
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 17:14:32 +02:00
{
if ( gBattleMons [ i ] . status2 & STATUS2_UPROAR )
break ;
}
2018-02-06 02:46:59 +01:00
if ( i = = gBattlersCount )
2017-09-17 17:14:32 +02:00
{
2017-11-26 17:15:28 +01:00
gBattlescriptCurrInstr = BattleScript_IgnoresAndFallsAsleep ;
2017-09-17 17:14:32 +02:00
return 1 ;
}
}
calc - = obedienceLevel ;
if ( calc < obedienceLevel )
{
2018-07-14 19:29:25 +02:00
gBattleMoveDamage = CalculateMoveDamage ( MOVE_NONE , gBattlerAttacker , gBattlerAttacker , TYPE_MYSTERY , 40 , FALSE ) ;
2018-02-06 23:09:39 +01:00
gBattlerTarget = gBattlerAttacker ;
2017-11-25 18:42:31 +01:00
gBattlescriptCurrInstr = BattleScript_82DB6F0 ;
2017-09-17 17:14:32 +02:00
gHitMarker | = HITMARKER_UNABLE_TO_USE_MOVE ;
return 2 ;
}
else
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = Random ( ) & 3 ;
gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround ;
return 1 ;
}
}
}
2018-07-14 16:41:14 +02:00
u32 GetBattlerAbility ( u8 battlerId )
{
if ( gStatuses3 [ battlerId ] & STATUS3_GASTRO_ACID )
return ABILITY_NONE ;
else if ( ( gBattleMons [ gBattlerAttacker ] . ability = = ABILITY_MOLD_BREAKER
| | gBattleMons [ gBattlerAttacker ] . ability = = ABILITY_TERAVOLT
| | gBattleMons [ gBattlerAttacker ] . ability = = ABILITY_TURBOBLAZE )
& & sAbilitiesAffectedByMoldBreaker [ gBattleMons [ battlerId ] . ability ]
& & gBattlerByTurnOrder [ gCurrentTurnActionNumber ] = = gBattlerAttacker
& & gActionsByTurnOrder [ gBattlerByTurnOrder [ gBattlerAttacker ] ] = = B_ACTION_USE_MOVE
& & gCurrentTurnActionNumber < gBattlersCount
& & ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_GASTRO_ACID ) )
return ABILITY_NONE ;
else
return gBattleMons [ battlerId ] . ability ;
}
u32 GetBattlerHoldEffect ( u8 battlerId , bool32 checkNegating )
{
if ( checkNegating )
{
if ( gStatuses3 [ battlerId ] & STATUS3_EMBARGO )
return HOLD_EFFECT_NONE ;
if ( gFieldStatuses & STATUS_FIELD_MAGIC_ROOM )
return HOLD_EFFECT_NONE ;
if ( gBattleMons [ battlerId ] . ability = = ABILITY_KLUTZ & & ! ( gStatuses3 [ battlerId ] & STATUS3_GASTRO_ACID ) )
return HOLD_EFFECT_NONE ;
}
gPotentialItemEffectBattler = battlerId ;
if ( gBattleMons [ battlerId ] . item = = ITEM_ENIGMA_BERRY )
return gEnigmaBerries [ battlerId ] . holdEffect ;
else
return ItemId_GetHoldEffect ( gBattleMons [ battlerId ] . item ) ;
}
u32 GetBattlerHoldEffectParam ( u8 battlerId )
{
if ( gBattleMons [ battlerId ] . item = = ITEM_ENIGMA_BERRY )
return gEnigmaBerries [ battlerId ] . holdEffectParam ;
else
return ItemId_GetHoldEffectParam ( gBattleMons [ battlerId ] . item ) ;
}
bool32 IsMoveMakingContact ( u16 move , u8 battlerAtk )
{
if ( ! ( gBattleMoves [ move ] . flags & FLAG_MAKES_CONTACT ) )
return FALSE ;
else if ( GetBattlerAbility ( battlerAtk ) = = ABILITY_LONG_REACH )
return FALSE ;
else if ( GetBattlerHoldEffect ( battlerAtk , TRUE ) = = HOLD_EFFECT_PROTECTIVE_PADS )
return FALSE ;
else
return TRUE ;
}
bool32 IsBattlerGrounded ( u8 battlerId )
{
if ( GetBattlerHoldEffect ( battlerId , TRUE ) = = HOLD_EFFECT_IRON_BALL )
return TRUE ;
else if ( gFieldStatuses & STATUS_FIELD_GRAVITY )
return TRUE ;
else if ( gStatuses3 [ battlerId ] & STATUS3_ROOTED )
return TRUE ;
else if ( gStatuses3 [ battlerId ] & STATUS3_SMACKED_DOWN )
return TRUE ;
else if ( gStatuses3 [ battlerId ] & STATUS3_TELEKINESIS )
return FALSE ;
else if ( GetBattlerAbility ( battlerId ) = = ABILITY_LEVITATE )
return FALSE ;
else if ( IS_BATTLER_OF_TYPE ( battlerId , TYPE_FLYING ) )
return FALSE ;
else
return TRUE ;
}
bool32 IsBattlerAlive ( u8 battlerId )
{
if ( gBattleMons [ battlerId ] . hp = = 0 )
return FALSE ;
else if ( battlerId > = gBattlersCount )
return FALSE ;
else if ( gAbsentBattlerFlags & gBitTable [ battlerId ] )
return FALSE ;
else
return TRUE ;
}
u8 GetBattleMonMoveSlot ( struct BattlePokemon * battleMon , u16 move )
{
u8 i ;
for ( i = 0 ; i < 4 ; i + + )
{
if ( battleMon - > moves [ i ] = = move )
break ;
}
return i ;
}
u32 GetBattlerWeight ( u8 battlerId )
{
u32 weight = GetPokedexHeightWeight ( SpeciesToNationalPokedexNum ( gBattleMons [ battlerId ] . species ) , 1 ) ;
u32 ability = GetBattlerAbility ( battlerId ) ;
u32 holdEffect = GetBattlerHoldEffect ( battlerId , TRUE ) ;
if ( ability = = ABILITY_HEAVY_METAL )
weight * = 2 ;
else if ( ability = = ABILITY_LIGHT_METAL )
weight / = 2 ;
if ( holdEffect = = HOLD_EFFECT_FLOAT_STONE )
weight / = 2 ;
if ( gDisableStructs [ battlerId ] . autonomizeCount )
weight - = 1000 * gDisableStructs [ battlerId ] . autonomizeCount ;
if ( weight = = 0 )
weight = 1 ;
return weight ;
}
u32 CountBattlerStatIncreases ( u8 battlerId , bool32 countEvasionAcc )
{
u32 i ;
u32 count = 0 ;
for ( i = 0 ; i < BATTLE_STATS_NO ; i + + )
{
if ( ( i = = STAT_ACC | | i = = STAT_EVASION ) & & ! countEvasionAcc )
continue ;
if ( gBattleMons [ battlerId ] . statStages [ i ] > 6 ) // Stat is increased.
count + = gBattleMons [ battlerId ] . statStages [ i ] - 6 ;
}
return count ;
}
u32 GetMoveTargetCount ( u16 move , u8 battlerAtk , u8 battlerDef )
{
switch ( gBattleMoves [ move ] . target )
{
case MOVE_TARGET_BOTH :
return IsBattlerAlive ( battlerDef )
+ IsBattlerAlive ( BATTLE_PARTNER ( battlerDef ) ) ;
case MOVE_TARGET_FOES_AND_ALLY :
return IsBattlerAlive ( battlerDef )
+ IsBattlerAlive ( BATTLE_PARTNER ( battlerDef ) )
+ IsBattlerAlive ( BATTLE_PARTNER ( battlerAtk ) ) ;
case MOVE_TARGET_OPPONENTS_FIELD :
return 1 ;
case MOVE_TARGET_DEPENDS :
case MOVE_TARGET_SELECTED :
case MOVE_TARGET_RANDOM :
case MOVE_TARGET_USER_OR_SELECTED :
return IsBattlerAlive ( battlerDef ) ;
case MOVE_TARGET_USER :
return IsBattlerAlive ( battlerAtk ) ;
default :
return 0 ;
}
}
2018-07-14 19:29:25 +02:00
s32 CalculateMoveDamage ( u16 move , u8 battlerAtk , u8 battlerDef , u8 moveType , s32 fixedBasePower , bool32 isCrit )
{
}