2017-09-17 14:10:32 +02:00
# include "global.h"
# include "battle.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"
2017-11-26 11:55:17 +01:00
# include "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-09-19 21:01:12 +02:00
# include "calculate_base_damage.h"
2017-10-06 17:06:45 +02:00
# include "link.h"
2017-11-27 21:24:34 +01:00
# include "berry.h"
2017-09-17 14:10:32 +02:00
extern const struct BattleMove gBattleMoves [ ] ;
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
} ;
2017-10-06 17:06:45 +02:00
u8 GetBattleBank ( u8 caseId )
{
u8 ret = 0 ;
switch ( caseId )
{
case BS_GET_TARGET :
2018-02-06 23:09:39 +01:00
ret = gBattlerTarget ;
2017-10-06 17:06:45 +02:00
break ;
case BS_GET_ATTACKER :
2018-02-06 23:09:39 +01:00
ret = gBattlerAttacker ;
2017-10-06 17:06:45 +02:00
break ;
case BS_GET_EFFECT_BANK :
ret = gEffectBank ;
break ;
2017-11-25 18:42:31 +01:00
case BS_GET_BANK_0 :
2017-10-06 17:06:45 +02:00
ret = 0 ;
break ;
case BS_GET_SCRIPTING_BANK :
2018-02-06 02:46:59 +01:00
ret = gBattleScripting . battler ;
2017-10-06 17:06:45 +02:00
break ;
2017-11-25 18:42:31 +01:00
case BS_GET_gBank1 :
2017-10-06 17:06:45 +02:00
ret = gBank1 ;
break ;
case 5 :
ret = gBank1 ;
break ;
case 4 :
case 6 :
case 8 :
case 9 :
case BS_GET_PLAYER1 :
2018-02-06 02:46:59 +01:00
ret = GetBattlerAtPosition ( B_POSITION_PLAYER_LEFT ) ;
2017-10-06 17:06:45 +02:00
break ;
case BS_GET_OPPONENT1 :
2018-02-06 02:46:59 +01:00
ret = GetBattlerAtPosition ( B_POSITION_OPPONENT_LEFT ) ;
2017-10-06 17:06:45 +02:00
break ;
case BS_GET_PLAYER2 :
2018-02-06 02:46:59 +01:00
ret = GetBattlerAtPosition ( B_POSITION_PLAYER_RIGHT ) ;
2017-10-06 17:06:45 +02:00
break ;
case BS_GET_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
2017-09-22 21:33:49 +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-06 23:09:39 +01:00
gStringBattler = 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 ;
}
u8 CheckMoveLimitations ( u8 bank , u8 unusableMoves , u8 check )
{
u8 holdEffect ;
2017-11-26 13:26:58 +01:00
u16 * choicedMove = & gBattleStruct - > choicedMove [ bank ] ;
2017-09-17 14:10:32 +02:00
s32 i ;
if ( gBattleMons [ bank ] . item = = ITEM_ENIGMA_BERRY )
holdEffect = gEnigmaBerries [ bank ] . holdEffect ;
else
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ bank ] . item ) ;
2018-02-06 23:09:39 +01:00
gStringBattler = bank ;
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
{
if ( gBattleMons [ bank ] . moves [ i ] = = 0 & & check & MOVE_LIMITATION_ZEROMOVE )
unusableMoves | = gBitTable [ i ] ;
if ( gBattleMons [ bank ] . pp [ i ] = = 0 & & check & MOVE_LIMITATION_PP )
unusableMoves | = gBitTable [ i ] ;
if ( gBattleMons [ bank ] . moves [ i ] = = gDisableStructs [ bank ] . disabledMove & & check & MOVE_LIMITATION_DISABLED )
unusableMoves | = gBitTable [ i ] ;
2017-11-26 18:07:00 +01:00
if ( gBattleMons [ bank ] . moves [ i ] = = gLastMoves [ bank ] & & check & MOVE_LIMITATION_TORMENTED & & gBattleMons [ bank ] . status2 & STATUS2_TORMENT )
2017-09-17 14:10:32 +02:00
unusableMoves | = gBitTable [ i ] ;
if ( gDisableStructs [ bank ] . tauntTimer1 & & check & MOVE_LIMITATION_TAUNT & & gBattleMoves [ gBattleMons [ bank ] . moves [ i ] ] . power = = 0 )
unusableMoves | = gBitTable [ i ] ;
2017-09-27 23:43:45 +02:00
if ( GetImprisonedMovesCount ( bank , gBattleMons [ bank ] . moves [ i ] ) & & check & MOVE_LIMITATION_IMPRISION )
2017-09-17 14:10:32 +02:00
unusableMoves | = gBitTable [ i ] ;
if ( gDisableStructs [ bank ] . encoreTimer1 & & gDisableStructs [ bank ] . encoredMove ! = gBattleMons [ bank ] . moves [ i ] )
unusableMoves | = gBitTable [ i ] ;
if ( holdEffect = = HOLD_EFFECT_CHOICE_BAND & & * choicedMove ! = 0 & & * choicedMove ! = 0xFFFF & & * choicedMove ! = gBattleMons [ bank ] . moves [ i ] )
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
if ( unusable = = 0xF ) // all moves are unusable
{
2018-02-06 02:46:59 +01:00
gProtectStructs [ gActiveBattler ] . onlyStruggle = 1 ;
gSelectionBattleScripts [ gActiveBattler ] = BattleScript_NoMovesLeft ;
2017-09-17 14:10:32 +02:00
}
else
{
2018-02-06 02:46:59 +01:00
gProtectStructs [ gActiveBattler ] . onlyStruggle = 0 ;
2017-09-17 14:10:32 +02:00
}
return ( unusable = = 0xF ) ;
}
2017-09-27 23:43:45 +02:00
u8 GetImprisonedMovesCount ( u8 bank , u16 move )
2017-09-17 14:10:32 +02:00
{
s32 i ;
u8 imprisionedMoves = 0 ;
2018-02-06 02:46:59 +01:00
u8 bankSide = GetBattlerSide ( bank ) ;
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-02-06 02:46:59 +01:00
if ( bankSide ! = 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
{
u8 sideBank ;
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-02-06 02:46:59 +01:00
gBattleTurnOrder [ 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-02-06 02:46:59 +01:00
if ( GetWhoStrikesFirst ( gBattleTurnOrder [ i ] , gBattleTurnOrder [ 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 )
{
sideBank = gBattleStruct - > turnSideTracker ;
2018-02-07 22:53:40 +01:00
gActiveBattler = gBattlerAttacker = gSideTimers [ sideBank ] . reflectBattlerId ;
2018-01-16 22:12:38 +01:00
if ( gSideStatuses [ sideBank ] & SIDE_STATUS_REFLECT )
2017-09-17 14:10:32 +02:00
{
if ( - - gSideTimers [ sideBank ] . reflectTimer = = 0 )
{
2018-01-16 22:12:38 +01:00
gSideStatuses [ sideBank ] & = ~ 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 )
{
sideBank = gBattleStruct - > turnSideTracker ;
2018-02-07 22:53:40 +01:00
gActiveBattler = gBattlerAttacker = gSideTimers [ sideBank ] . lightscreenBattlerId ;
2018-01-16 22:12:38 +01:00
if ( gSideStatuses [ sideBank ] & SIDE_STATUS_LIGHTSCREEN )
2017-09-17 14:10:32 +02:00
{
if ( - - gSideTimers [ sideBank ] . lightscreenTimer = = 0 )
{
2018-01-16 22:12:38 +01:00
gSideStatuses [ sideBank ] & = ~ SIDE_STATUS_LIGHTSCREEN ;
2017-11-26 17:15:28 +01:00
BattleScriptExecute ( BattleScript_SideStatusWoreOff ) ;
2017-09-17 14:10:32 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = sideBank ;
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 )
{
sideBank = gBattleStruct - > turnSideTracker ;
2018-02-07 22:53:40 +01:00
gActiveBattler = gBattlerAttacker = gSideTimers [ sideBank ] . mistBattlerId ;
2017-09-17 14:10:32 +02:00
if ( gSideTimers [ sideBank ] . mistTimer ! = 0
& & - - gSideTimers [ sideBank ] . mistTimer = = 0 )
{
2018-01-16 22:12:38 +01:00
gSideStatuses [ sideBank ] & = ~ SIDE_STATUS_MIST ;
2017-11-26 17:15:28 +01:00
BattleScriptExecute ( BattleScript_SideStatusWoreOff ) ;
2017-09-17 14:10:32 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = sideBank ;
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 )
{
sideBank = gBattleStruct - > turnSideTracker ;
2018-02-07 22:53:40 +01:00
gActiveBattler = gBattlerAttacker = gSideTimers [ sideBank ] . safeguardBattlerId ;
2018-01-16 22:12:38 +01:00
if ( gSideStatuses [ sideBank ] & SIDE_STATUS_SAFEGUARD )
2017-09-17 14:10:32 +02:00
{
if ( - - gSideTimers [ sideBank ] . safeguardTimer = = 0 )
{
2018-01-16 22:12:38 +01:00
gSideStatuses [ sideBank ] & = ~ 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-02-06 02:46:59 +01:00
gActiveBattler = gBattleTurnOrder [ gBattleStruct - > turnSideTracker ] ;
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-02-07 22:53:40 +01:00
gActiveBattler = gBattlerAttacker = gBattleTurnOrder [ 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 )
& & gBattleMons [ gStatuses3 [ gActiveBattler ] & STATUS3_LEECHSEED_BANK ] . hp ! = 0
& & gBattleMons [ gActiveBattler ] . hp ! = 0 )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gBattlerTarget = gStatuses3 [ gActiveBattler ] & STATUS3_LEECHSEED_BANK ; //funny how the 'target' is actually the bank that receives HP
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
{
// R/S does not perform this sleep check, which causes the nighmare 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
{
int i ;
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-06 02:46:59 +01:00
gEffectBank = 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-02-07 22:53:40 +01:00
gActiveBattler = gBattlerAttacker = gBattleTurnOrder [ 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
{
int 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-02-06 02:46:59 +01:00
if ( gAbsentBattlerFlags & gBitTable [ i ] & & ! sub_80423F4 ( i , 6 , 6 ) )
gAbsentBattlerFlags & = ~ ( gBitTable [ i ] ) ;
2017-09-17 14:10:32 +02:00
}
// fall through
case 1 :
do
{
2018-02-07 22:53:40 +01:00
gBank1 = gBattlerTarget = gBattleStruct - > faintedActionsBattlerId ;
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 :
sub_803F9EC ( gBank1 ) ;
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-07 22:53:40 +01:00
gBank1 = gBattlerTarget = gBattleStruct - > faintedActionsBattlerId ;
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
{
int 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 ;
gBattleMoveDamage = CalculateBaseDamage ( & gBattleMons [ gBattlerAttacker ] , & gBattleMons [ gBattlerAttacker ] , MOVE_POUND , 0 , 40 , 0 , gBattlerAttacker , gBattlerAttacker ) ;
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 )
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
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 )
2017-09-17 14:10:32 +02:00
gBattlescriptCurrInstr = BattleScript_BideStoringEnergy ;
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
gBattlescriptCurrInstr = BattleScript_BideNoEnergyToAttack ;
}
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-02-06 02:46:59 +01:00
bool8 sub_80423F4 ( u8 battler , u8 r1 , u8 r2 )
2017-09-17 15:19:15 +02:00
{
struct Pokemon * party ;
u8 r7 ;
u8 r6 ;
s32 i ;
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE ) )
return FALSE ;
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-02-06 02:46:59 +01:00
r6 = ( ( battler & 2 ) / 2 ) ;
2017-09-17 15:19:15 +02:00
for ( i = r6 * 3 ; i < r6 * 3 + 3 ; i + + )
{
if ( GetMonData ( & party [ i ] , MON_DATA_HP ) ! = 0
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = 0
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = SPECIES_EGG )
break ;
}
return ( i = = r6 * 3 + 3 ) ;
}
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-02-06 20:48:02 +01:00
r7 = GetBattlerMultiplayerId ( battler ) ;
2017-09-17 15:19:15 +02:00
r6 = sub_806D82C ( r7 ) ;
}
else
{
// FIXME: Compiler insists on moving r4 into r1 before doing the eor
# ifndef NONMATCHING
register u32 var asm ( " r1 " ) ;
# else
u32 var ;
# endif // NONMATCHING
party = gEnemyParty ;
2018-02-06 02:46:59 +01:00
var = battler ^ 1 ;
2017-09-18 12:51:16 +02:00
r6 = ( var ! = 0 ) ? 1 : 0 ;
2017-09-17 15:19:15 +02:00
}
}
else
{
2018-02-06 20:48:02 +01:00
r7 = 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 ;
r6 = sub_806D82C ( r7 ) ;
}
for ( i = r6 * 3 ; i < r6 * 3 + 3 ; i + + )
{
if ( GetMonData ( & party [ i ] , MON_DATA_HP ) ! = 0
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = 0
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = SPECIES_EGG )
break ;
}
return ( i = = r6 * 3 + 3 ) ;
}
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 )
2017-09-17 15:19:15 +02:00
r6 = 0 ;
else
r6 = 3 ;
for ( i = r6 ; i < r6 + 3 ; i + + )
{
if ( GetMonData ( & party [ i ] , MON_DATA_HP ) ! = 0
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = 0
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = SPECIES_EGG )
break ;
}
return ( i = = r6 + 3 ) ;
}
else
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( battler ) = = B_SIDE_OPPONENT )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
r7 = GetBattlerAtPosition ( B_POSITION_OPPONENT_LEFT ) ;
r6 = GetBattlerAtPosition ( B_POSITION_OPPONENT_RIGHT ) ;
2017-09-17 15:19:15 +02:00
party = gEnemyParty ;
}
else
{
2018-02-06 02:46:59 +01:00
r7 = GetBattlerAtPosition ( B_POSITION_PLAYER_LEFT ) ;
r6 = GetBattlerAtPosition ( B_POSITION_PLAYER_RIGHT ) ;
2017-09-17 15:19:15 +02:00
party = gPlayerParty ;
}
if ( r1 = = 6 )
2018-02-06 20:48:02 +01:00
r1 = gBattlerPartyIndexes [ r7 ] ;
2017-09-17 15:19:15 +02:00
if ( r2 = = 6 )
2018-02-06 20:48:02 +01:00
r2 = gBattlerPartyIndexes [ r6 ] ;
2017-09-17 15:19:15 +02:00
for ( i = 0 ; i < 6 ; i + + )
{
if ( GetMonData ( & party [ i ] , MON_DATA_HP ) ! = 0
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = 0
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = SPECIES_EGG
// FIXME: Using index[array] instead of array[index] is BAD!
2017-11-12 17:06:31 +01:00
& & i ! = r1 & & i ! = r2 & & i ! = r7 [ gBattleStruct - > monToSwitchIntoId ] & & i ! = r6 [ gBattleStruct - > monToSwitchIntoId ] )
2017-09-17 15:19:15 +02:00
break ;
}
return ( i = = 6 ) ;
}
}
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-02-06 02:46:59 +01:00
if ( ! WEATHER_HAS_EFFECT & & gBattleMons [ battler ] . type1 ! = TYPE_NORMAL & & gBattleMons [ battler ] . type2 ! = TYPE_NORMAL )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ battler ] . type1 = TYPE_NORMAL ;
gBattleMons [ battler ] . type2 = TYPE_NORMAL ;
2017-09-17 15:19:15 +02:00
return CASTFORM_TO_NORMAL ;
}
if ( ! WEATHER_HAS_EFFECT )
return CASTFORM_NO_CHANGE ;
2018-02-06 02:46:59 +01:00
if ( ! ( gBattleWeather & ( WEATHER_RAIN_ANY | WEATHER_SUN_ANY | WEATHER_HAIL ) ) & & gBattleMons [ battler ] . type1 ! = TYPE_NORMAL & & gBattleMons [ battler ] . type2 ! = TYPE_NORMAL )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ battler ] . type1 = TYPE_NORMAL ;
gBattleMons [ battler ] . type2 = TYPE_NORMAL ;
2017-09-17 15:19:15 +02:00
formChange = CASTFORM_TO_NORMAL ;
}
2018-02-06 02:46:59 +01:00
if ( gBattleWeather & WEATHER_SUN_ANY & & gBattleMons [ battler ] . type1 ! = TYPE_FIRE & & gBattleMons [ battler ] . type2 ! = TYPE_FIRE )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ battler ] . type1 = TYPE_FIRE ;
gBattleMons [ battler ] . type2 = TYPE_FIRE ;
2017-09-17 15:19:15 +02:00
formChange = CASTFORM_TO_FIRE ;
}
2018-02-06 02:46:59 +01:00
if ( gBattleWeather & WEATHER_RAIN_ANY & & gBattleMons [ battler ] . type1 ! = TYPE_WATER & & gBattleMons [ battler ] . type2 ! = TYPE_WATER )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ battler ] . type1 = TYPE_WATER ;
gBattleMons [ battler ] . type2 = TYPE_WATER ;
2017-09-17 15:19:15 +02:00
formChange = CASTFORM_TO_WATER ;
}
2018-02-06 02:46:59 +01:00
if ( gBattleWeather & WEATHER_HAIL & & gBattleMons [ battler ] . type1 ! = TYPE_ICE & & gBattleMons [ battler ] . type2 ! = TYPE_ICE )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ battler ] . type1 = TYPE_ICE ;
gBattleMons [ battler ] . type2 = 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 ;
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 ;
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 ) ;
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_SAFARI ) ) // why isn't that check done at the beginning?
{
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-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . statStages [ STAT_STAGE_SPEED ] < 0xC & & gDisableStructs [ battler ] . isFirstTurn ! = 2 )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ battler ] . statStages [ STAT_STAGE_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-02-07 22:53:40 +01:00
& & ( gSpecialStatuses [ gBattlerTarget ] . physicalDmg | | gSpecialStatuses [ gBattlerTarget ] . specialDmg )
2018-02-06 02:46:59 +01:00
& & gBattleMons [ battler ] . type1 ! = moveType
& & gBattleMons [ battler ] . type2 ! = moveType
& & gBattleMons [ battler ] . hp ! = 0 )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ battler ] . type1 = moveType ;
gBattleMons [ battler ] . type2 = moveType ;
2017-10-12 17:49:24 +02:00
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-02-07 22:53:40 +01:00
& & ( gSpecialStatuses [ gBattlerTarget ] . physicalDmg | | gSpecialStatuses [ gBattlerTarget ] . specialDmg )
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-02-07 22:53:40 +01:00
& & ( gSpecialStatuses [ gBattlerTarget ] . physicalDmg | | gSpecialStatuses [ gBattlerTarget ] . specialDmg )
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-02-07 22:53:40 +01:00
& & ( gSpecialStatuses [ gBattlerTarget ] . physicalDmg | | gSpecialStatuses [ gBattlerTarget ] . specialDmg )
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-02-07 22:53:40 +01:00
& & ( gSpecialStatuses [ gBattlerTarget ] . physicalDmg | | gSpecialStatuses [ gBattlerTarget ] . specialDmg )
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-02-07 22:53:40 +01:00
& & ( gSpecialStatuses [ gBattlerTarget ] . physicalDmg | | gSpecialStatuses [ gBattlerTarget ] . specialDmg )
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-02-07 22:53:40 +01:00
& & ( gSpecialStatuses [ gBattlerTarget ] . physicalDmg | | gSpecialStatuses [ gBattlerTarget ] . specialDmg )
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 ) ;
2017-09-17 15:19:15 +02:00
gBattleStruct - > intimidateBank = i ;
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 ;
2017-09-17 15:19:15 +02:00
gBattleStruct - > intimidateBank = i ;
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 ;
case ABILITYEFFECT_CHECK_BANK_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_FIELD_SPORT : // 14
switch ( gLastUsedAbility )
{
case 0xFD :
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
if ( gStatuses3 [ i ] & STATUS3_MUDSPORT )
effect = i + 1 ;
}
break ;
case 0xFE :
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
if ( gStatuses3 [ i ] & STATUS3_WATERSPORT )
effect = i + 1 ;
}
break ;
default :
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 )
{
gLastUsedAbility = ability ;
effect = i + 1 ;
}
}
break ;
}
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 ;
case ABILITYEFFECT_CHECK_FIELD_EXCEPT_BANK : // 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 ;
case ABILITYEFFECT_COUNT_BANK_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
} ;
u8 ItemBattleEffects ( u8 caseID , u8 bank , bool8 moveTurn )
{
int i = 0 ;
u8 effect = ITEM_NO_EFFECT ;
u8 changedPP = 0 ;
u8 bankHoldEffect , atkHoldEffect , defHoldEffect ;
u8 bankQuality , atkQuality , defQuality ;
u16 atkItem , defItem ;
gLastUsedItem = gBattleMons [ bank ] . item ;
if ( gLastUsedItem = = ITEM_ENIGMA_BERRY )
{
bankHoldEffect = gEnigmaBerries [ bank ] . holdEffect ;
bankQuality = gEnigmaBerries [ bank ] . holdEffectParam ;
}
else
{
bankHoldEffect = ItemId_GetHoldEffect ( gLastUsedItem ) ;
bankQuality = ItemId_GetHoldEffectParam ( gLastUsedItem ) ;
}
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 :
2017-09-17 17:14:32 +02:00
switch ( bankHoldEffect )
{
case HOLD_EFFECT_DOUBLE_PRIZE :
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( bank ) = = 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
{
if ( gBattleMons [ bank ] . statStages [ i ] < 6 )
{
gBattleMons [ bank ] . statStages [ i ] = 6 ;
effect = ITEM_STATS_CHANGE ;
}
}
if ( effect )
{
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = bank ;
2018-02-06 23:09:39 +01:00
gStringBattler = bank ;
gActiveBattler = gBattlerAttacker = bank ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_WhiteHerbEnd2 ) ;
2017-09-17 17:14:32 +02:00
}
break ;
}
break ;
case 1 :
if ( gBattleMons [ bank ] . hp )
{
switch ( bankHoldEffect )
{
case HOLD_EFFECT_RESTORE_HP :
if ( gBattleMons [ bank ] . hp < = gBattleMons [ bank ] . maxHP / 2 & & ! moveTurn )
{
gBattleMoveDamage = bankQuality ;
if ( gBattleMons [ bank ] . hp + bankQuality > gBattleMons [ bank ] . maxHP )
gBattleMoveDamage = gBattleMons [ bank ] . maxHP - gBattleMons [ bank ] . hp ;
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-06 02:46:59 +01:00
if ( GetBattlerSide ( bank ) = = B_SIDE_PLAYER )
2018-02-06 20:48:02 +01:00
mon = & gPlayerParty [ gBattlerPartyIndexes [ bank ] ] ;
2017-09-17 17:14:32 +02:00
else
2018-02-06 20:48:02 +01:00
mon = & gEnemyParty [ gBattlerPartyIndexes [ bank ] ] ;
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 ) ;
if ( changedPP + bankQuality > maxPP )
changedPP = maxPP ;
else
changedPP = changedPP + bankQuality ;
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
{
if ( gBattleMons [ bank ] . statStages [ i ] < 6 )
{
gBattleMons [ bank ] . statStages [ i ] = 6 ;
effect = ITEM_STATS_CHANGE ;
}
}
if ( effect )
{
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = bank ;
2018-02-06 23:09:39 +01:00
gStringBattler = bank ;
gActiveBattler = gBattlerAttacker = bank ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_WhiteHerbEnd2 ) ;
2017-09-17 17:14:32 +02:00
}
break ;
case HOLD_EFFECT_LEFTOVERS :
if ( gBattleMons [ bank ] . hp < gBattleMons [ bank ] . maxHP & & ! moveTurn )
{
gBattleMoveDamage = gBattleMons [ bank ] . maxHP / 16 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
if ( gBattleMons [ bank ] . hp + gBattleMoveDamage > gBattleMons [ bank ] . maxHP )
gBattleMoveDamage = gBattleMons [ bank ] . maxHP - gBattleMons [ bank ] . hp ;
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 ;
RecordItemEffectBattle ( bank , bankHoldEffect ) ;
}
break ;
// nice copy/paste there gamefreak, making a function for confuse berries was too much eh?
case HOLD_EFFECT_CONFUSE_SPICY :
if ( gBattleMons [ bank ] . hp < = gBattleMons [ bank ] . maxHP / 2 & & ! moveTurn )
{
2017-11-27 21:24:34 +01:00
PREPARE_FLAVOR_BUFFER ( gBattleTextBuff1 , FLAVOR_SPICY ) ;
2017-11-26 11:55:17 +01:00
2017-09-17 17:14:32 +02:00
gBattleMoveDamage = gBattleMons [ bank ] . maxHP / bankQuality ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
if ( gBattleMons [ bank ] . hp + gBattleMoveDamage > gBattleMons [ bank ] . maxHP )
gBattleMoveDamage = gBattleMons [ bank ] . maxHP - gBattleMons [ bank ] . hp ;
gBattleMoveDamage * = - 1 ;
2017-11-27 20:03:41 +01:00
if ( GetFlavorRelationByPersonality ( gBattleMons [ bank ] . 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 :
if ( gBattleMons [ bank ] . hp < = gBattleMons [ bank ] . maxHP / 2 & & ! moveTurn )
{
2017-11-27 21:24:34 +01:00
PREPARE_FLAVOR_BUFFER ( gBattleTextBuff1 , FLAVOR_DRY ) ;
2017-11-26 11:55:17 +01:00
2017-09-17 17:14:32 +02:00
gBattleMoveDamage = gBattleMons [ bank ] . maxHP / bankQuality ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
if ( gBattleMons [ bank ] . hp + gBattleMoveDamage > gBattleMons [ bank ] . maxHP )
gBattleMoveDamage = gBattleMons [ bank ] . maxHP - gBattleMons [ bank ] . hp ;
gBattleMoveDamage * = - 1 ;
2017-11-27 20:03:41 +01:00
if ( GetFlavorRelationByPersonality ( gBattleMons [ bank ] . 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 :
if ( gBattleMons [ bank ] . hp < = gBattleMons [ bank ] . maxHP / 2 & & ! moveTurn )
{
2017-11-27 21:24:34 +01:00
PREPARE_FLAVOR_BUFFER ( gBattleTextBuff1 , FLAVOR_SWEET ) ;
2017-11-26 11:55:17 +01:00
2017-09-17 17:14:32 +02:00
gBattleMoveDamage = gBattleMons [ bank ] . maxHP / bankQuality ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
if ( gBattleMons [ bank ] . hp + gBattleMoveDamage > gBattleMons [ bank ] . maxHP )
gBattleMoveDamage = gBattleMons [ bank ] . maxHP - gBattleMons [ bank ] . hp ;
gBattleMoveDamage * = - 1 ;
2017-11-27 20:03:41 +01:00
if ( GetFlavorRelationByPersonality ( gBattleMons [ bank ] . 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 :
if ( gBattleMons [ bank ] . hp < = gBattleMons [ bank ] . maxHP / 2 & & ! moveTurn )
{
2017-11-27 21:24:34 +01:00
PREPARE_FLAVOR_BUFFER ( gBattleTextBuff1 , FLAVOR_BITTER ) ;
2017-11-26 11:55:17 +01:00
2017-09-17 17:14:32 +02:00
gBattleMoveDamage = gBattleMons [ bank ] . maxHP / bankQuality ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
if ( gBattleMons [ bank ] . hp + gBattleMoveDamage > gBattleMons [ bank ] . maxHP )
gBattleMoveDamage = gBattleMons [ bank ] . maxHP - gBattleMons [ bank ] . hp ;
gBattleMoveDamage * = - 1 ;
2017-11-27 20:03:41 +01:00
if ( GetFlavorRelationByPersonality ( gBattleMons [ bank ] . 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 :
if ( gBattleMons [ bank ] . hp < = gBattleMons [ bank ] . maxHP / 2 & & ! moveTurn )
{
2017-11-27 21:24:34 +01:00
PREPARE_FLAVOR_BUFFER ( gBattleTextBuff1 , FLAVOR_SOUR ) ;
2017-11-26 11:55:17 +01:00
2017-09-17 17:14:32 +02:00
gBattleMoveDamage = gBattleMons [ bank ] . maxHP / bankQuality ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
if ( gBattleMons [ bank ] . hp + gBattleMoveDamage > gBattleMons [ bank ] . maxHP )
gBattleMoveDamage = gBattleMons [ bank ] . maxHP - gBattleMons [ bank ] . hp ;
gBattleMoveDamage * = - 1 ;
2017-11-27 20:03:41 +01:00
if ( GetFlavorRelationByPersonality ( gBattleMons [ bank ] . 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 :
if ( gBattleMons [ bank ] . hp < = gBattleMons [ bank ] . maxHP / bankQuality & & ! moveTurn & & gBattleMons [ bank ] . statStages [ STAT_STAGE_ATK ] < 0xC )
{
2017-11-26 11:55:17 +01:00
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , STAT_STAGE_ATK ) ;
PREPARE_STRING_BUFFER ( gBattleTextBuff2 , STRINGID_STATROSE ) ;
2017-09-17 17:14:32 +02:00
gEffectBank = bank ;
2017-11-26 11:55:17 +01:00
SET_STATCHANGER ( STAT_STAGE_ATK , 1 , FALSE ) ;
2017-09-17 17:14:32 +02:00
gBattleScripting . animArg1 = 0xE + STAT_STAGE_ATK ;
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 :
if ( gBattleMons [ bank ] . hp < = gBattleMons [ bank ] . maxHP / bankQuality & & ! moveTurn & & gBattleMons [ bank ] . statStages [ STAT_STAGE_DEF ] < 0xC )
{
2017-11-26 11:55:17 +01:00
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , STAT_STAGE_DEF ) ;
2017-09-17 17:14:32 +02:00
gEffectBank = bank ;
2017-11-26 11:55:17 +01:00
SET_STATCHANGER ( STAT_STAGE_DEF , 1 , FALSE ) ;
2017-09-17 17:14:32 +02:00
gBattleScripting . animArg1 = 0xE + STAT_STAGE_DEF ;
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 :
if ( gBattleMons [ bank ] . hp < = gBattleMons [ bank ] . maxHP / bankQuality & & ! moveTurn & & gBattleMons [ bank ] . statStages [ STAT_STAGE_SPEED ] < 0xC )
{
2017-11-26 11:55:17 +01:00
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , STAT_STAGE_SPEED ) ;
2017-09-17 17:14:32 +02:00
gEffectBank = bank ;
2017-11-26 11:55:17 +01:00
SET_STATCHANGER ( STAT_STAGE_SPEED , 1 , FALSE ) ;
2017-09-17 17:14:32 +02:00
gBattleScripting . animArg1 = 0xE + STAT_STAGE_SPEED ;
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 :
if ( gBattleMons [ bank ] . hp < = gBattleMons [ bank ] . maxHP / bankQuality & & ! moveTurn & & gBattleMons [ bank ] . statStages [ STAT_STAGE_SPATK ] < 0xC )
{
2017-11-26 11:55:17 +01:00
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , STAT_STAGE_SPATK ) ;
2017-09-17 17:14:32 +02:00
gEffectBank = bank ;
2017-11-26 11:55:17 +01:00
SET_STATCHANGER ( STAT_STAGE_SPATK , 1 , FALSE ) ;
2017-09-17 17:14:32 +02:00
gBattleScripting . animArg1 = 0xE + STAT_STAGE_SPATK ;
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 :
if ( gBattleMons [ bank ] . hp < = gBattleMons [ bank ] . maxHP / bankQuality & & ! moveTurn & & gBattleMons [ bank ] . statStages [ STAT_STAGE_SPDEF ] < 0xC )
{
2017-11-26 11:55:17 +01:00
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , STAT_STAGE_SPDEF ) ;
2017-09-17 17:14:32 +02:00
gEffectBank = bank ;
2017-11-26 11:55:17 +01:00
SET_STATCHANGER ( STAT_STAGE_SPDEF , 1 , FALSE ) ;
2017-09-17 17:14:32 +02:00
gBattleScripting . animArg1 = 0xE + STAT_STAGE_SPDEF ;
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 :
if ( gBattleMons [ bank ] . hp < = gBattleMons [ bank ] . maxHP / bankQuality & & ! moveTurn & & ! ( gBattleMons [ bank ] . status2 & STATUS2_FOCUS_ENERGY ) )
{
gBattleMons [ bank ] . 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 :
if ( ! moveTurn & & gBattleMons [ bank ] . hp < = gBattleMons [ bank ] . maxHP / bankQuality )
{
for ( i = 0 ; i < 5 ; i + + )
{
if ( gBattleMons [ bank ] . statStages [ STAT_STAGE_ATK + i ] < 0xC )
break ;
}
if ( i ! = 5 )
{
do
{
i = Random ( ) % 5 ;
} while ( gBattleMons [ bank ] . statStages [ STAT_STAGE_ATK + i ] = = 0xC ) ;
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 ;
gEffectBank = bank ;
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-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_PARALYSIS )
2017-09-17 17:14:32 +02:00
{
2018-01-16 22:12:38 +01:00
gBattleMons [ bank ] . 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-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_PSN_ANY )
2017-09-17 17:14:32 +02:00
{
2018-01-16 22:12:38 +01:00
gBattleMons [ bank ] . 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-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_BURN )
2017-09-17 17:14:32 +02:00
{
2018-01-16 22:12:38 +01:00
gBattleMons [ bank ] . 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-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_FREEZE )
2017-09-17 17:14:32 +02:00
{
2018-01-16 22:12:38 +01:00
gBattleMons [ bank ] . 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-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_SLEEP )
2017-09-17 17:14:32 +02:00
{
2018-01-16 22:12:38 +01:00
gBattleMons [ bank ] . status1 & = ~ ( STATUS1_SLEEP ) ;
2017-09-17 17:14:32 +02:00
gBattleMons [ bank ] . 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 :
if ( gBattleMons [ bank ] . status2 & STATUS2_CONFUSION )
{
gBattleMons [ bank ] . 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-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_ANY | | gBattleMons [ bank ] . status2 & STATUS2_CONFUSION )
2017-09-17 17:14:32 +02:00
{
i = 0 ;
2018-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_PSN_ANY )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_PoisonJpn ) ;
i + + ;
}
2018-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_SLEEP )
2017-09-17 17:14:32 +02:00
{
gBattleMons [ bank ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
StringCopy ( gBattleTextBuff1 , gStatusConditionString_SleepJpn ) ;
i + + ;
}
2018-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_PARALYSIS )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_ParalysisJpn ) ;
i + + ;
}
2018-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_BURN )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_BurnJpn ) ;
i + + ;
}
2018-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_FREEZE )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_IceJpn ) ;
i + + ;
}
if ( gBattleMons [ bank ] . status2 & STATUS2_CONFUSION )
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_ConfusionJpn ) ;
i + + ;
}
if ( ! ( i > 1 ) )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
gBattleMons [ bank ] . status1 = 0 ;
gBattleMons [ bank ] . 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 :
if ( gBattleMons [ bank ] . status2 & STATUS2_INFATUATION )
{
gBattleMons [ bank ] . status2 & = ~ ( STATUS2_INFATUATION ) ;
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-06 02:46:59 +01:00
gBattleScripting . battler = bank ;
2018-02-06 23:09:39 +01:00
gStringBattler = bank ;
gActiveBattler = gBattlerAttacker = bank ;
2017-09-17 17:14:32 +02:00
switch ( effect )
{
case ITEM_STATUS_CHANGE :
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ bank ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-17 17:14:32 +02:00
break ;
case ITEM_PP_CHANGE :
if ( ! ( gBattleMons [ bank ] . status2 & STATUS2_TRANSFORMED ) & & ! ( gDisableStructs [ bank ] . unk18_b & gBitTable [ i ] ) )
gBattleMons [ bank ] . pp [ i ] = changedPP ;
break ;
}
}
}
break ;
case 2 :
break ;
case 3 :
2018-02-06 02:46:59 +01:00
for ( bank = 0 ; bank < gBattlersCount ; bank + + )
2017-09-17 17:14:32 +02:00
{
gLastUsedItem = gBattleMons [ bank ] . item ;
if ( gBattleMons [ bank ] . item = = ITEM_ENIGMA_BERRY )
{
bankHoldEffect = gEnigmaBerries [ bank ] . holdEffect ;
bankQuality = gEnigmaBerries [ bank ] . holdEffectParam ;
}
else
{
bankHoldEffect = ItemId_GetHoldEffect ( gLastUsedItem ) ;
bankQuality = ItemId_GetHoldEffectParam ( gLastUsedItem ) ;
}
switch ( bankHoldEffect )
{
case HOLD_EFFECT_CURE_PAR :
2018-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_PARALYSIS )
2017-09-17 17:14:32 +02:00
{
2018-01-16 22:12:38 +01:00
gBattleMons [ bank ] . 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-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_PSN_ANY )
2017-09-17 17:14:32 +02:00
{
2018-01-16 22:12:38 +01:00
gBattleMons [ bank ] . 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-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_BURN )
2017-09-17 17:14:32 +02:00
{
2018-01-16 22:12:38 +01:00
gBattleMons [ bank ] . 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-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_FREEZE )
2017-09-17 17:14:32 +02:00
{
2018-01-16 22:12:38 +01:00
gBattleMons [ bank ] . 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-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_SLEEP )
2017-09-17 17:14:32 +02:00
{
2018-01-16 22:12:38 +01:00
gBattleMons [ bank ] . status1 & = ~ ( STATUS1_SLEEP ) ;
2017-09-17 17:14:32 +02:00
gBattleMons [ bank ] . 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 :
if ( gBattleMons [ bank ] . status2 & STATUS2_CONFUSION )
{
gBattleMons [ bank ] . 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 :
if ( gBattleMons [ bank ] . status2 & STATUS2_INFATUATION )
{
gBattleMons [ bank ] . status2 & = ~ ( STATUS2_INFATUATION ) ;
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-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_ANY | | gBattleMons [ bank ] . status2 & STATUS2_CONFUSION )
2017-09-17 17:14:32 +02:00
{
2018-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_PSN_ANY )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_PoisonJpn ) ;
}
2018-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_SLEEP )
2017-09-17 17:14:32 +02:00
{
gBattleMons [ bank ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
StringCopy ( gBattleTextBuff1 , gStatusConditionString_SleepJpn ) ;
}
2018-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_PARALYSIS )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_ParalysisJpn ) ;
}
2018-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_BURN )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_BurnJpn ) ;
}
2018-01-16 22:12:38 +01:00
if ( gBattleMons [ bank ] . status1 & STATUS1_FREEZE )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_IceJpn ) ;
}
if ( gBattleMons [ bank ] . status2 & STATUS2_CONFUSION )
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_ConfusionJpn ) ;
}
gBattleMons [ bank ] . status1 = 0 ;
gBattleMons [ bank ] . 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
{
if ( gBattleMons [ bank ] . statStages [ i ] < 6 )
{
gBattleMons [ bank ] . statStages [ i ] = 6 ;
effect = ITEM_STATS_CHANGE ;
}
}
if ( effect )
{
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = bank ;
2018-02-06 23:09:39 +01:00
gStringBattler = bank ;
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-06 02:46:59 +01:00
gBattleScripting . battler = bank ;
2018-02-06 23:09:39 +01:00
gStringBattler = bank ;
2018-02-06 02:46:59 +01:00
gActiveBattler = bank ;
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-02-07 22:53:40 +01:00
& & ( gSpecialStatuses [ gBattlerTarget ] . physicalDmg | | gSpecialStatuses [ gBattlerTarget ] . specialDmg )
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-06 23:09:39 +01:00
gStringBattler = gBattlerAttacker ;
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 ;
}
2017-10-06 00:12:01 +02:00
void ClearFuryCutterDestinyBondGrudge ( u8 bank )
2017-09-17 17:14:32 +02:00
{
gDisableStructs [ bank ] . furyCutterCounter = 0 ;
gBattleMons [ bank ] . status2 & = ~ ( STATUS2_DESTINY_BOND ) ;
gStatuses3 [ bank ] & = ~ ( STATUS3_GRUDGE ) ;
}
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 ] ( ) ;
}
u8 GetMoveTarget ( u16 move , u8 useMoveTarget )
{
u8 targetBank = 0 ;
u8 moveTarget ;
u8 side ;
if ( useMoveTarget )
moveTarget = useMoveTarget - 1 ;
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 )
targetBank = gSideTimers [ side ] . followmeTarget ;
else
{
2018-02-06 23:09:39 +01:00
side = GetBattlerSide ( gBattlerAttacker ) ;
2017-09-17 17:14:32 +02:00
do
{
2018-02-06 02:46:59 +01:00
targetBank = Random ( ) % gBattlersCount ;
2018-02-06 23:09:39 +01:00
} while ( targetBank = = gBattlerAttacker | | side = = GetBattlerSide ( targetBank ) | | gAbsentBattlerFlags & gBitTable [ targetBank ] ) ;
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 )
2017-09-17 17:14:32 +02:00
& & gBattleMons [ targetBank ] . ability ! = ABILITY_LIGHTNING_ROD )
{
2018-02-06 02:46:59 +01:00
targetBank ^ = BIT_FLANK ;
2017-09-17 17:14:32 +02:00
RecordAbilityBattle ( targetBank , gBattleMons [ targetBank ] . ability ) ;
gSpecialStatuses [ targetBank ] . lightningRodRedirected = 1 ;
}
}
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-02-06 23:09:39 +01:00
targetBank = GetBattlerAtPosition ( ( GetBattlerPosition ( gBattlerAttacker ) & BIT_SIDE ) ^ BIT_SIDE ) ;
2018-02-06 02:46:59 +01:00
if ( gAbsentBattlerFlags & gBitTable [ targetBank ] )
targetBank ^ = 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 )
targetBank = 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-02-06 02:46:59 +01:00
targetBank = GetBattlerAtPosition ( B_POSITION_OPPONENT_LEFT ) ;
2017-09-17 17:14:32 +02:00
else
2018-02-06 02:46:59 +01:00
targetBank = GetBattlerAtPosition ( B_POSITION_OPPONENT_RIGHT ) ;
2017-09-17 17:14:32 +02:00
}
else
{
if ( Random ( ) & 1 )
2018-02-06 02:46:59 +01:00
targetBank = GetBattlerAtPosition ( B_POSITION_PLAYER_LEFT ) ;
2017-09-17 17:14:32 +02:00
else
2018-02-06 02:46:59 +01:00
targetBank = GetBattlerAtPosition ( B_POSITION_PLAYER_RIGHT ) ;
2017-09-17 17:14:32 +02:00
}
2018-02-06 02:46:59 +01:00
if ( gAbsentBattlerFlags & gBitTable [ targetBank ] )
targetBank ^ = BIT_FLANK ;
2017-09-17 17:14:32 +02:00
}
else
2018-02-06 23:09:39 +01:00
targetBank = GetBattlerAtPosition ( ( GetBattlerPosition ( gBattlerAttacker ) & BIT_SIDE ) ^ BIT_SIDE ) ;
2017-09-17 17:14:32 +02:00
break ;
2017-09-19 21:01:12 +02:00
case MOVE_TARGET_USER :
case MOVE_TARGET_x10 :
2018-02-06 23:09:39 +01:00
targetBank = gBattlerAttacker ;
2017-09-17 17:14:32 +02:00
break ;
}
2018-02-06 23:09:39 +01:00
* ( gBattleStruct - > moveTarget + gBattlerAttacker ) = targetBank ;
2017-09-17 17:14:32 +02:00
return targetBank ;
}
static bool32 HasObedientBitSet ( u8 bank )
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( bank ) = = B_SIDE_OPPONENT )
2017-09-17 17:14:32 +02:00
return TRUE ;
2018-02-06 20:48:02 +01:00
if ( GetMonData ( & gPlayerParty [ gBattlerPartyIndexes [ bank ] ] , MON_DATA_SPECIES , NULL ) ! = SPECIES_DEOXYS
& & GetMonData ( & gPlayerParty [ gBattlerPartyIndexes [ bank ] ] , MON_DATA_SPECIES , NULL ) ! = SPECIES_MEW )
2017-09-17 17:14:32 +02:00
return TRUE ;
2018-02-06 20:48:02 +01:00
return GetMonData ( & gPlayerParty [ gBattlerPartyIndexes [ bank ] ] , 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
{
gCurrMovePos = gUnknown_020241E9 = Random ( ) & 3 ;
} 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-02-06 23:09:39 +01:00
gBattleMoveDamage = CalculateBaseDamage ( & gBattleMons [ gBattlerAttacker ] , & gBattleMons [ gBattlerAttacker ] , MOVE_POUND , 0 , 40 , 0 , gBattlerAttacker , gBattlerAttacker ) ;
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 ;
}
}
}