2017-09-17 14:10:32 +02:00
# include "global.h"
# include "battle.h"
2019-03-31 19:15:39 +02:00
# include "battle_anim.h"
2020-10-26 10:52:00 +01:00
# include "battle_arena.h"
# include "battle_pyramid.h"
# include "battle_util.h"
2017-09-17 14:10:32 +02:00
# include "pokemon.h"
2020-10-26 10:52:00 +01:00
# include "international_string_util.h"
2017-09-17 14:10:32 +02:00
# include "item.h"
# include "util.h"
2017-11-25 18:42:31 +01:00
# include "battle_scripts.h"
2017-12-05 19:27:33 +01:00
# include "random.h"
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
# include "text.h"
2020-10-26 10:52:00 +01:00
# include "safari_zone.h"
# include "sound.h"
# include "sprite.h"
2017-09-17 14:10:32 +02:00
# include "string_util.h"
2020-10-26 10:52:00 +01:00
# include "task.h"
# include "trig.h"
# include "window.h"
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
# include "battle_message.h"
2017-09-28 17:38:07 +02:00
# include "battle_ai_script_commands.h"
2017-09-20 00:28:00 +02:00
# include "battle_controllers.h"
2017-09-17 17:14:32 +02:00
# include "event_data.h"
2017-10-06 17:06:45 +02:00
# include "link.h"
2018-12-08 19:43:21 +01:00
# include "field_weather.h"
2019-09-16 05:47:07 +02:00
# include "constants/abilities.h"
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
# include "constants/battle_anim.h"
2019-09-16 05:47:07 +02:00
# include "constants/battle_move_effects.h"
# include "constants/battle_script_commands.h"
# include "constants/battle_string_ids.h"
# include "constants/hold_effects.h"
# include "constants/items.h"
# include "constants/moves.h"
2020-10-26 10:52:00 +01:00
# include "constants/songs.h"
2019-09-16 05:47:07 +02:00
# include "constants/species.h"
# include "constants/weather.h"
2017-10-06 17:06:45 +02:00
2020-10-26 10:52:00 +01:00
/*
NOTE : The data and functions in this file up until ( but not including ) sSoundMovesTable
are actually part of battle_main . c . They needed to be moved to this file in order to
match the ROM ; this is also why sSoundMovesTable ' s declaration is in the middle of
functions instead of at the top of the file with the other declarations .
*/
extern const u8 * const gBattleScriptsForMoveEffects [ ] ;
extern const u8 * const gBattlescriptsForBallThrow [ ] ;
extern const u8 * const gBattlescriptsForRunningByItem [ ] ;
extern const u8 * const gBattlescriptsForUsingItem [ ] ;
extern const u8 * const gBattlescriptsForSafariActions [ ] ;
static const u8 sPkblToEscapeFactor [ ] [ 3 ] = { { 0 , 0 , 0 } , { 3 , 5 , 0 } , { 2 , 3 , 0 } , { 1 , 2 , 0 } , { 1 , 1 , 0 } } ;
static const u8 sGoNearCounterToCatchFactor [ ] = { 4 , 3 , 2 , 1 } ;
static const u8 sGoNearCounterToEscapeFactor [ ] = { 4 , 4 , 4 , 4 } ;
void HandleAction_UseMove ( void )
{
u8 side ;
u8 var = 4 ;
gBattlerAttacker = gBattlerByTurnOrder [ gCurrentTurnActionNumber ] ;
if ( * ( & gBattleStruct - > field_91 ) & gBitTable [ gBattlerAttacker ] )
{
gCurrentActionFuncId = B_ACTION_FINISHED ;
return ;
}
gCritMultiplier = 1 ;
gBattleScripting . dmgMultiplier = 1 ;
gBattleStruct - > atkCancellerTracker = 0 ;
gMoveResultFlags = 0 ;
gMultiHitCounter = 0 ;
gBattleCommunication [ 6 ] = 0 ;
gCurrMovePos = gChosenMovePos = * ( gBattleStruct - > chosenMovePositions + gBattlerAttacker ) ;
// choose move
if ( gProtectStructs [ gBattlerAttacker ] . noValidMoves )
{
gProtectStructs [ gBattlerAttacker ] . noValidMoves = 0 ;
gCurrentMove = gChosenMove = MOVE_STRUGGLE ;
gHitMarker | = HITMARKER_NO_PPDEDUCT ;
* ( gBattleStruct - > moveTarget + gBattlerAttacker ) = GetMoveTarget ( MOVE_STRUGGLE , 0 ) ;
}
else if ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_MULTIPLETURNS | | gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_RECHARGE )
{
gCurrentMove = gChosenMove = gLockedMoves [ gBattlerAttacker ] ;
}
// encore forces you to use the same move
else if ( gDisableStructs [ gBattlerAttacker ] . encoredMove ! = MOVE_NONE
& & gDisableStructs [ gBattlerAttacker ] . encoredMove = = gBattleMons [ gBattlerAttacker ] . moves [ gDisableStructs [ gBattlerAttacker ] . encoredMovePos ] )
{
gCurrentMove = gChosenMove = gDisableStructs [ gBattlerAttacker ] . encoredMove ;
gCurrMovePos = gChosenMovePos = gDisableStructs [ gBattlerAttacker ] . encoredMovePos ;
* ( gBattleStruct - > moveTarget + gBattlerAttacker ) = GetMoveTarget ( gCurrentMove , 0 ) ;
}
// check if the encored move wasn't overwritten
else if ( gDisableStructs [ gBattlerAttacker ] . encoredMove ! = MOVE_NONE
& & gDisableStructs [ gBattlerAttacker ] . encoredMove ! = gBattleMons [ gBattlerAttacker ] . moves [ gDisableStructs [ gBattlerAttacker ] . encoredMovePos ] )
{
gCurrMovePos = gChosenMovePos = gDisableStructs [ gBattlerAttacker ] . encoredMovePos ;
gCurrentMove = gChosenMove = gBattleMons [ gBattlerAttacker ] . moves [ gCurrMovePos ] ;
gDisableStructs [ gBattlerAttacker ] . encoredMove = MOVE_NONE ;
gDisableStructs [ gBattlerAttacker ] . encoredMovePos = 0 ;
gDisableStructs [ gBattlerAttacker ] . encoreTimer = 0 ;
* ( gBattleStruct - > moveTarget + gBattlerAttacker ) = GetMoveTarget ( gCurrentMove , 0 ) ;
}
else if ( gBattleMons [ gBattlerAttacker ] . moves [ gCurrMovePos ] ! = gChosenMoveByBattler [ gBattlerAttacker ] )
{
gCurrentMove = gChosenMove = gBattleMons [ gBattlerAttacker ] . moves [ gCurrMovePos ] ;
* ( gBattleStruct - > moveTarget + gBattlerAttacker ) = GetMoveTarget ( gCurrentMove , 0 ) ;
}
else
{
gCurrentMove = gChosenMove = gBattleMons [ gBattlerAttacker ] . moves [ gCurrMovePos ] ;
}
if ( gBattleMons [ gBattlerAttacker ] . hp ! = 0 )
{
if ( GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_PLAYER )
gBattleResults . lastUsedMovePlayer = gCurrentMove ;
else
gBattleResults . lastUsedMoveOpponent = gCurrentMove ;
}
// choose target
side = GetBattlerSide ( gBattlerAttacker ) ^ BIT_SIDE ;
if ( gSideTimers [ side ] . followmeTimer ! = 0
& & gBattleMoves [ gCurrentMove ] . target = = MOVE_TARGET_SELECTED
& & GetBattlerSide ( gBattlerAttacker ) ! = GetBattlerSide ( gSideTimers [ side ] . followmeTarget )
& & gBattleMons [ gSideTimers [ side ] . followmeTarget ] . hp ! = 0 )
{
gBattlerTarget = gSideTimers [ side ] . followmeTarget ;
}
else if ( ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
& & gSideTimers [ side ] . followmeTimer = = 0
& & ( gBattleMoves [ gCurrentMove ] . power ! = 0
| | gBattleMoves [ gCurrentMove ] . target ! = MOVE_TARGET_USER )
& & gBattleMons [ * ( gBattleStruct - > moveTarget + gBattlerAttacker ) ] . ability ! = ABILITY_LIGHTNING_ROD
& & gBattleMoves [ gCurrentMove ] . type = = TYPE_ELECTRIC )
{
side = GetBattlerSide ( gBattlerAttacker ) ;
for ( gActiveBattler = 0 ; gActiveBattler < gBattlersCount ; gActiveBattler + + )
{
if ( side ! = GetBattlerSide ( gActiveBattler )
& & * ( gBattleStruct - > moveTarget + gBattlerAttacker ) ! = gActiveBattler
& & gBattleMons [ gActiveBattler ] . ability = = ABILITY_LIGHTNING_ROD
& & GetBattlerTurnOrderNum ( gActiveBattler ) < var )
{
var = GetBattlerTurnOrderNum ( gActiveBattler ) ;
}
}
if ( var = = 4 )
{
if ( gBattleMoves [ gChosenMove ] . target & MOVE_TARGET_RANDOM )
{
if ( GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_PLAYER )
{
if ( Random ( ) & 1 )
gBattlerTarget = GetBattlerAtPosition ( B_POSITION_OPPONENT_LEFT ) ;
else
gBattlerTarget = GetBattlerAtPosition ( B_POSITION_OPPONENT_RIGHT ) ;
}
else
{
if ( Random ( ) & 1 )
gBattlerTarget = GetBattlerAtPosition ( B_POSITION_PLAYER_LEFT ) ;
else
gBattlerTarget = GetBattlerAtPosition ( B_POSITION_PLAYER_RIGHT ) ;
}
}
else
{
gBattlerTarget = * ( gBattleStruct - > moveTarget + gBattlerAttacker ) ;
}
if ( gAbsentBattlerFlags & gBitTable [ gBattlerTarget ] )
{
if ( GetBattlerSide ( gBattlerAttacker ) ! = GetBattlerSide ( gBattlerTarget ) )
{
gBattlerTarget = GetBattlerAtPosition ( GetBattlerPosition ( gBattlerTarget ) ^ BIT_FLANK ) ;
}
else
{
gBattlerTarget = GetBattlerAtPosition ( GetBattlerPosition ( gBattlerAttacker ) ^ BIT_SIDE ) ;
if ( gAbsentBattlerFlags & gBitTable [ gBattlerTarget ] )
gBattlerTarget = GetBattlerAtPosition ( GetBattlerPosition ( gBattlerTarget ) ^ BIT_FLANK ) ;
}
}
}
else
{
gActiveBattler = gBattlerByTurnOrder [ var ] ;
RecordAbilityBattle ( gActiveBattler , gBattleMons [ gActiveBattler ] . ability ) ;
gSpecialStatuses [ gActiveBattler ] . lightningRodRedirected = 1 ;
gBattlerTarget = gActiveBattler ;
}
}
else if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE
& & gBattleMoves [ gChosenMove ] . target & MOVE_TARGET_RANDOM )
{
if ( GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_PLAYER )
{
if ( Random ( ) & 1 )
gBattlerTarget = GetBattlerAtPosition ( B_POSITION_OPPONENT_LEFT ) ;
else
gBattlerTarget = GetBattlerAtPosition ( B_POSITION_OPPONENT_RIGHT ) ;
}
else
{
if ( Random ( ) & 1 )
gBattlerTarget = GetBattlerAtPosition ( B_POSITION_PLAYER_LEFT ) ;
else
gBattlerTarget = GetBattlerAtPosition ( B_POSITION_PLAYER_RIGHT ) ;
}
if ( gAbsentBattlerFlags & gBitTable [ gBattlerTarget ]
& & GetBattlerSide ( gBattlerAttacker ) ! = GetBattlerSide ( gBattlerTarget ) )
{
gBattlerTarget = GetBattlerAtPosition ( GetBattlerPosition ( gBattlerTarget ) ^ BIT_FLANK ) ;
}
}
else
{
gBattlerTarget = * ( gBattleStruct - > moveTarget + gBattlerAttacker ) ;
if ( gAbsentBattlerFlags & gBitTable [ gBattlerTarget ] )
{
if ( GetBattlerSide ( gBattlerAttacker ) ! = GetBattlerSide ( gBattlerTarget ) )
{
gBattlerTarget = GetBattlerAtPosition ( GetBattlerPosition ( gBattlerTarget ) ^ BIT_FLANK ) ;
}
else
{
gBattlerTarget = GetBattlerAtPosition ( GetBattlerPosition ( gBattlerAttacker ) ^ BIT_SIDE ) ;
if ( gAbsentBattlerFlags & gBitTable [ gBattlerTarget ] )
gBattlerTarget = GetBattlerAtPosition ( GetBattlerPosition ( gBattlerTarget ) ^ BIT_FLANK ) ;
}
}
}
// choose battlescript
if ( gBattleTypeFlags & BATTLE_TYPE_PALACE
& & gProtectStructs [ gBattlerAttacker ] . palaceUnableToUseMove )
{
if ( gBattleMons [ gBattlerAttacker ] . hp = = 0 )
{
gCurrentActionFuncId = B_ACTION_FINISHED ;
return ;
}
else if ( gPalaceSelectionBattleScripts [ gBattlerAttacker ] ! = NULL )
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 4 ;
gBattlescriptCurrInstr = gPalaceSelectionBattleScripts [ gBattlerAttacker ] ;
gPalaceSelectionBattleScripts [ gBattlerAttacker ] = NULL ;
}
else
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 4 ;
gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround ;
}
}
else
{
gBattlescriptCurrInstr = gBattleScriptsForMoveEffects [ gBattleMoves [ gCurrentMove ] . effect ] ;
}
if ( gBattleTypeFlags & BATTLE_TYPE_ARENA )
BattleArena_AddMindPoints ( gBattlerAttacker ) ;
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT ;
}
void HandleAction_Switch ( void )
{
gBattlerAttacker = gBattlerByTurnOrder [ gCurrentTurnActionNumber ] ;
gBattle_BG0_X = 0 ;
gBattle_BG0_Y = 0 ;
gActionSelectionCursor [ gBattlerAttacker ] = 0 ;
gMoveSelectionCursor [ gBattlerAttacker ] = 0 ;
PREPARE_MON_NICK_BUFFER ( gBattleTextBuff1 , gBattlerAttacker , * ( gBattleStruct - > field_58 + gBattlerAttacker ) )
gBattleScripting . battler = gBattlerAttacker ;
gBattlescriptCurrInstr = BattleScript_ActionSwitch ;
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT ;
if ( gBattleResults . playerSwitchesCounter < 255 )
gBattleResults . playerSwitchesCounter + + ;
}
void HandleAction_UseItem ( void )
{
gBattlerAttacker = gBattlerTarget = gBattlerByTurnOrder [ gCurrentTurnActionNumber ] ;
gBattle_BG0_X = 0 ;
gBattle_BG0_Y = 0 ;
ClearFuryCutterDestinyBondGrudge ( gBattlerAttacker ) ;
gLastUsedItem = gBattleBufferB [ gBattlerAttacker ] [ 1 ] | ( gBattleBufferB [ gBattlerAttacker ] [ 2 ] < < 8 ) ;
if ( gLastUsedItem < = LAST_BALL ) // is ball
{
gBattlescriptCurrInstr = gBattlescriptsForBallThrow [ gLastUsedItem ] ;
}
else if ( gLastUsedItem = = ITEM_POKE_DOLL | | gLastUsedItem = = ITEM_FLUFFY_TAIL )
{
gBattlescriptCurrInstr = gBattlescriptsForRunningByItem [ 0 ] ;
}
else if ( GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_PLAYER )
{
gBattlescriptCurrInstr = gBattlescriptsForUsingItem [ 0 ] ;
}
else
{
gBattleScripting . battler = gBattlerAttacker ;
switch ( * ( gBattleStruct - > AI_itemType + ( gBattlerAttacker > > 1 ) ) )
{
case AI_ITEM_FULL_RESTORE :
case AI_ITEM_HEAL_HP :
break ;
case AI_ITEM_CURE_CONDITION :
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
if ( * ( gBattleStruct - > AI_itemFlags + gBattlerAttacker / 2 ) & 1 )
{
if ( * ( gBattleStruct - > AI_itemFlags + gBattlerAttacker / 2 ) & 0x3E )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 5 ;
}
else
{
while ( ! ( * ( gBattleStruct - > AI_itemFlags + gBattlerAttacker / 2 ) & 1 ) )
{
* ( gBattleStruct - > AI_itemFlags + gBattlerAttacker / 2 ) > > = 1 ;
gBattleCommunication [ MULTISTRING_CHOOSER ] + + ;
}
}
break ;
case AI_ITEM_X_STAT :
gBattleCommunication [ MULTISTRING_CHOOSER ] = 4 ;
if ( * ( gBattleStruct - > AI_itemFlags + ( gBattlerAttacker > > 1 ) ) & 0x80 )
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 5 ;
}
else
{
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , STAT_ATK )
PREPARE_STRING_BUFFER ( gBattleTextBuff2 , CHAR_X )
while ( ! ( ( * ( gBattleStruct - > AI_itemFlags + ( gBattlerAttacker > > 1 ) ) ) & 1 ) )
{
* ( gBattleStruct - > AI_itemFlags + gBattlerAttacker / 2 ) > > = 1 ;
gBattleTextBuff1 [ 2 ] + + ;
}
gBattleScripting . animArg1 = gBattleTextBuff1 [ 2 ] + 14 ;
gBattleScripting . animArg2 = 0 ;
}
break ;
case AI_ITEM_GUARD_SPECS :
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
break ;
}
gBattlescriptCurrInstr = gBattlescriptsForUsingItem [ * ( gBattleStruct - > AI_itemType + gBattlerAttacker / 2 ) ] ;
}
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT ;
}
bool8 TryRunFromBattle ( u8 battler )
{
bool8 effect = FALSE ;
u8 holdEffect ;
u8 pyramidMultiplier ;
u8 speedVar ;
if ( gBattleMons [ battler ] . item = = ITEM_ENIGMA_BERRY )
holdEffect = gEnigmaBerries [ battler ] . holdEffect ;
else
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ battler ] . item ) ;
gPotentialItemEffectBattler = battler ;
if ( holdEffect = = HOLD_EFFECT_CAN_ALWAYS_RUN )
{
gLastUsedItem = gBattleMons [ battler ] . item ;
gProtectStructs [ battler ] . fleeFlag = 1 ;
effect + + ;
}
else if ( gBattleMons [ battler ] . ability = = ABILITY_RUN_AWAY )
{
if ( InBattlePyramid ( ) )
{
gBattleStruct - > runTries + + ;
pyramidMultiplier = GetPyramidRunMultiplier ( ) ;
speedVar = ( gBattleMons [ battler ] . speed * pyramidMultiplier ) / ( gBattleMons [ BATTLE_OPPOSITE ( battler ) ] . speed ) + ( gBattleStruct - > runTries * 30 ) ;
if ( speedVar > ( Random ( ) & 0xFF ) )
{
gLastUsedAbility = ABILITY_RUN_AWAY ;
gProtectStructs [ battler ] . fleeFlag = 2 ;
effect + + ;
}
}
else
{
gLastUsedAbility = ABILITY_RUN_AWAY ;
gProtectStructs [ battler ] . fleeFlag = 2 ;
effect + + ;
}
}
else if ( gBattleTypeFlags & ( BATTLE_TYPE_FRONTIER | BATTLE_TYPE_TRAINER_HILL ) & & gBattleTypeFlags & BATTLE_TYPE_TRAINER )
{
effect + + ;
}
else
{
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE ) )
{
if ( InBattlePyramid ( ) )
{
pyramidMultiplier = GetPyramidRunMultiplier ( ) ;
speedVar = ( gBattleMons [ battler ] . speed * pyramidMultiplier ) / ( gBattleMons [ BATTLE_OPPOSITE ( battler ) ] . speed ) + ( gBattleStruct - > runTries * 30 ) ;
if ( speedVar > ( Random ( ) & 0xFF ) )
effect + + ;
}
else if ( gBattleMons [ battler ] . speed < gBattleMons [ BATTLE_OPPOSITE ( battler ) ] . speed )
{
speedVar = ( gBattleMons [ battler ] . speed * 128 ) / ( gBattleMons [ BATTLE_OPPOSITE ( battler ) ] . speed ) + ( gBattleStruct - > runTries * 30 ) ;
if ( speedVar > ( Random ( ) & 0xFF ) )
effect + + ;
}
else // same speed or faster
{
effect + + ;
}
}
gBattleStruct - > runTries + + ;
}
if ( effect )
{
gCurrentTurnActionNumber = gBattlersCount ;
gBattleOutcome = B_OUTCOME_RAN ;
}
return effect ;
}
void HandleAction_Run ( void )
{
gBattlerAttacker = gBattlerByTurnOrder [ gCurrentTurnActionNumber ] ;
2021-01-13 21:17:32 +01:00
if ( gBattleTypeFlags & ( BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK ) )
2020-10-26 10:52:00 +01:00
{
gCurrentTurnActionNumber = gBattlersCount ;
for ( gActiveBattler = 0 ; gActiveBattler < gBattlersCount ; gActiveBattler + + )
{
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_PLAYER )
{
if ( gChosenActionByBattler [ gActiveBattler ] = = B_ACTION_RUN )
gBattleOutcome | = B_OUTCOME_LOST ;
}
else
{
if ( gChosenActionByBattler [ gActiveBattler ] = = B_ACTION_RUN )
gBattleOutcome | = B_OUTCOME_WON ;
}
}
gBattleOutcome | = B_OUTCOME_LINK_BATTLE_RAN ;
gSaveBlock2Ptr - > frontier . disableRecordBattle = TRUE ;
}
else
{
if ( GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_PLAYER )
{
if ( ! TryRunFromBattle ( gBattlerAttacker ) ) // failed to run away
{
ClearFuryCutterDestinyBondGrudge ( gBattlerAttacker ) ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 3 ;
gBattlescriptCurrInstr = BattleScript_PrintFailedToRunString ;
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT ;
}
}
else
{
if ( gBattleMons [ gBattlerAttacker ] . status2 & ( STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION ) )
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 4 ;
gBattlescriptCurrInstr = BattleScript_PrintFailedToRunString ;
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT ;
}
else
{
gCurrentTurnActionNumber = gBattlersCount ;
gBattleOutcome = B_OUTCOME_MON_FLED ;
}
}
}
}
void HandleAction_WatchesCarefully ( void )
{
gBattlerAttacker = gBattlerByTurnOrder [ gCurrentTurnActionNumber ] ;
gBattle_BG0_X = 0 ;
gBattle_BG0_Y = 0 ;
gBattlescriptCurrInstr = gBattlescriptsForSafariActions [ 0 ] ;
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT ;
}
void HandleAction_SafariZoneBallThrow ( void )
{
gBattlerAttacker = gBattlerByTurnOrder [ gCurrentTurnActionNumber ] ;
gBattle_BG0_X = 0 ;
gBattle_BG0_Y = 0 ;
gNumSafariBalls - - ;
gLastUsedItem = ITEM_SAFARI_BALL ;
gBattlescriptCurrInstr = gBattlescriptsForBallThrow [ ITEM_SAFARI_BALL ] ;
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT ;
}
void HandleAction_ThrowPokeblock ( void )
{
gBattlerAttacker = gBattlerByTurnOrder [ gCurrentTurnActionNumber ] ;
gBattle_BG0_X = 0 ;
gBattle_BG0_Y = 0 ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = gBattleBufferB [ gBattlerAttacker ] [ 1 ] - 1 ;
gLastUsedItem = gBattleBufferB [ gBattlerAttacker ] [ 2 ] ;
if ( gBattleResults . pokeblockThrows < 0xFF )
gBattleResults . pokeblockThrows + + ;
if ( gBattleStruct - > safariPkblThrowCounter < 3 )
gBattleStruct - > safariPkblThrowCounter + + ;
if ( gBattleStruct - > safariEscapeFactor > 1 )
{
2020-12-13 05:28:01 +01:00
// BUG: safariEscapeFactor can become 0 below. This causes the pokeblock throw glitch.
# ifdef BUGFIX
if ( gBattleStruct - > safariEscapeFactor < = sPkblToEscapeFactor [ gBattleStruct - > safariPkblThrowCounter ] [ gBattleCommunication [ MULTISTRING_CHOOSER ] ] )
# else
2020-10-26 10:52:00 +01:00
if ( gBattleStruct - > safariEscapeFactor < sPkblToEscapeFactor [ gBattleStruct - > safariPkblThrowCounter ] [ gBattleCommunication [ MULTISTRING_CHOOSER ] ] )
2020-12-13 05:28:01 +01:00
# endif
2020-10-26 10:52:00 +01:00
gBattleStruct - > safariEscapeFactor = 1 ;
else
gBattleStruct - > safariEscapeFactor - = sPkblToEscapeFactor [ gBattleStruct - > safariPkblThrowCounter ] [ gBattleCommunication [ MULTISTRING_CHOOSER ] ] ;
}
gBattlescriptCurrInstr = gBattlescriptsForSafariActions [ 2 ] ;
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT ;
}
void HandleAction_GoNear ( void )
{
gBattlerAttacker = gBattlerByTurnOrder [ gCurrentTurnActionNumber ] ;
gBattle_BG0_X = 0 ;
gBattle_BG0_Y = 0 ;
gBattleStruct - > safariCatchFactor + = sGoNearCounterToCatchFactor [ gBattleStruct - > safariGoNearCounter ] ;
if ( gBattleStruct - > safariCatchFactor > 20 )
gBattleStruct - > safariCatchFactor = 20 ;
gBattleStruct - > safariEscapeFactor + = sGoNearCounterToEscapeFactor [ gBattleStruct - > safariGoNearCounter ] ;
if ( gBattleStruct - > safariEscapeFactor > 20 )
gBattleStruct - > safariEscapeFactor = 20 ;
if ( gBattleStruct - > safariGoNearCounter < 3 )
{
gBattleStruct - > safariGoNearCounter + + ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
else
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ; // Can't get closer.
}
gBattlescriptCurrInstr = gBattlescriptsForSafariActions [ 1 ] ;
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT ;
}
void HandleAction_SafariZoneRun ( void )
{
gBattlerAttacker = gBattlerByTurnOrder [ gCurrentTurnActionNumber ] ;
PlaySE ( SE_FLEE ) ;
gCurrentTurnActionNumber = gBattlersCount ;
gBattleOutcome = B_OUTCOME_RAN ;
}
void HandleAction_WallyBallThrow ( void )
{
gBattlerAttacker = gBattlerByTurnOrder [ gCurrentTurnActionNumber ] ;
gBattle_BG0_X = 0 ;
gBattle_BG0_Y = 0 ;
PREPARE_MON_NICK_BUFFER ( gBattleTextBuff1 , gBattlerAttacker , gBattlerPartyIndexes [ gBattlerAttacker ] )
gBattlescriptCurrInstr = gBattlescriptsForSafariActions [ 3 ] ;
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT ;
gActionsByTurnOrder [ 1 ] = B_ACTION_FINISHED ;
}
void HandleAction_TryFinish ( void )
{
if ( ! HandleFaintedMonActions ( ) )
{
gBattleStruct - > faintedActionsState = 0 ;
gCurrentActionFuncId = B_ACTION_FINISHED ;
}
}
void HandleAction_NothingIsFainted ( void )
{
gCurrentTurnActionNumber + + ;
gCurrentActionFuncId = gActionsByTurnOrder [ gCurrentTurnActionNumber ] ;
gHitMarker & = ~ ( HITMARKER_DESTINYBOND | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED
| HITMARKER_NO_PPDEDUCT | HITMARKER_IGNORE_SAFEGUARD | HITMARKER_IGNORE_ON_AIR
| HITMARKER_IGNORE_UNDERGROUND | HITMARKER_IGNORE_UNDERWATER | HITMARKER_x100000
| HITMARKER_OBEYS | HITMARKER_x10 | HITMARKER_SYNCHRONISE_EFFECT
| HITMARKER_CHARGING | HITMARKER_x4000000 ) ;
}
void HandleAction_ActionFinished ( void )
{
* ( gBattleStruct - > monToSwitchIntoId + gBattlerByTurnOrder [ gCurrentTurnActionNumber ] ) = 6 ;
gCurrentTurnActionNumber + + ;
gCurrentActionFuncId = gActionsByTurnOrder [ gCurrentTurnActionNumber ] ;
SpecialStatusesClear ( ) ;
gHitMarker & = ~ ( HITMARKER_DESTINYBOND | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED
| HITMARKER_NO_PPDEDUCT | HITMARKER_IGNORE_SAFEGUARD | HITMARKER_IGNORE_ON_AIR
| HITMARKER_IGNORE_UNDERGROUND | HITMARKER_IGNORE_UNDERWATER | HITMARKER_x100000
| HITMARKER_OBEYS | HITMARKER_x10 | HITMARKER_SYNCHRONISE_EFFECT
| HITMARKER_CHARGING | HITMARKER_x4000000 ) ;
gCurrentMove = 0 ;
gBattleMoveDamage = 0 ;
gMoveResultFlags = 0 ;
gBattleScripting . animTurn = 0 ;
gBattleScripting . animTargetsHit = 0 ;
gLastLandedMoves [ gBattlerAttacker ] = 0 ;
gLastHitByType [ gBattlerAttacker ] = 0 ;
gBattleStruct - > dynamicMoveType = 0 ;
gDynamicBasePower = 0 ;
gBattleScripting . moveendState = 0 ;
gBattleCommunication [ 3 ] = 0 ;
gBattleCommunication [ 4 ] = 0 ;
gBattleScripting . multihitMoveEffect = 0 ;
gBattleResources - > battleScriptsStack - > size = 0 ;
}
2017-10-06 19:09:37 +02:00
// rom const data
static const u16 sSoundMovesTable [ ] =
{
MOVE_GROWL , MOVE_ROAR , MOVE_SING , MOVE_SUPERSONIC , MOVE_SCREECH , MOVE_SNORE ,
MOVE_UPROAR , MOVE_METAL_SOUND , MOVE_GRASS_WHISTLE , MOVE_HYPER_VOICE , 0xFFFF
} ;
2018-02-08 11:17:41 +01:00
u8 GetBattlerForBattleScript ( u8 caseId )
2017-10-06 17:06:45 +02:00
{
u8 ret = 0 ;
switch ( caseId )
{
2018-02-08 11:17:41 +01:00
case BS_TARGET :
2018-02-06 23:09:39 +01:00
ret = gBattlerTarget ;
2017-10-06 17:06:45 +02:00
break ;
2018-02-08 11:17:41 +01:00
case BS_ATTACKER :
2018-02-06 23:09:39 +01:00
ret = gBattlerAttacker ;
2017-10-06 17:06:45 +02:00
break ;
2018-02-08 11:17:41 +01:00
case BS_EFFECT_BATTLER :
ret = gEffectBattler ;
2017-10-06 17:06:45 +02:00
break ;
2018-07-01 11:15:42 +02:00
case BS_BATTLER_0 :
2017-10-06 17:06:45 +02:00
ret = 0 ;
break ;
2018-02-08 11:17:41 +01:00
case BS_SCRIPTING :
2018-02-06 02:46:59 +01:00
ret = gBattleScripting . battler ;
2017-10-06 17:06:45 +02:00
break ;
2018-02-08 11:17:41 +01:00
case BS_FAINTED :
ret = gBattlerFainted ;
2017-10-06 17:06:45 +02:00
break ;
case 5 :
2018-02-08 11:17:41 +01:00
ret = gBattlerFainted ;
2017-10-06 17:06:45 +02:00
break ;
case 4 :
case 6 :
case 8 :
case 9 :
2018-02-08 11:17:41 +01:00
case BS_PLAYER1 :
2018-02-06 02:46:59 +01:00
ret = GetBattlerAtPosition ( B_POSITION_PLAYER_LEFT ) ;
2017-10-06 17:06:45 +02:00
break ;
2018-02-08 11:17:41 +01:00
case BS_OPPONENT1 :
2018-02-06 02:46:59 +01:00
ret = GetBattlerAtPosition ( B_POSITION_OPPONENT_LEFT ) ;
2017-10-06 17:06:45 +02:00
break ;
2018-02-08 11:17:41 +01:00
case BS_PLAYER2 :
2018-02-06 02:46:59 +01:00
ret = GetBattlerAtPosition ( B_POSITION_PLAYER_RIGHT ) ;
2017-10-06 17:06:45 +02:00
break ;
2018-02-08 11:17:41 +01:00
case BS_OPPONENT2 :
2018-02-06 02:46:59 +01:00
ret = GetBattlerAtPosition ( B_POSITION_OPPONENT_RIGHT ) ;
2017-10-06 17:06:45 +02:00
break ;
}
return ret ;
}
2019-01-19 22:32:25 +01:00
void PressurePPLose ( u8 target , u8 attacker , u16 move )
2017-10-06 17:06:45 +02:00
{
2019-01-19 22:32:25 +01:00
int moveIndex ;
2017-10-06 17:06:45 +02:00
2019-01-19 22:32:25 +01:00
if ( gBattleMons [ target ] . ability ! = ABILITY_PRESSURE )
2017-10-06 17:06:45 +02:00
return ;
2019-01-19 22:32:25 +01:00
for ( moveIndex = 0 ; moveIndex < MAX_MON_MOVES ; moveIndex + + )
2017-10-06 17:06:45 +02:00
{
2019-01-19 22:32:25 +01:00
if ( gBattleMons [ attacker ] . moves [ moveIndex ] = = move )
2017-10-06 17:06:45 +02:00
break ;
}
2019-01-19 22:32:25 +01:00
if ( moveIndex = = MAX_MON_MOVES )
2017-10-06 17:06:45 +02:00
return ;
2019-01-19 22:32:25 +01:00
if ( gBattleMons [ attacker ] . pp [ moveIndex ] ! = 0 )
gBattleMons [ attacker ] . pp [ moveIndex ] - - ;
2017-10-06 17:06:45 +02:00
2018-02-06 02:46:59 +01:00
if ( ! ( gBattleMons [ attacker ] . status2 & STATUS2_TRANSFORMED )
2019-01-19 22:32:25 +01:00
& & ! ( gDisableStructs [ attacker ] . mimickedMoves & gBitTable [ moveIndex ] ) )
2017-10-06 17:06:45 +02:00
{
2018-02-06 02:46:59 +01:00
gActiveBattler = attacker ;
2019-01-19 22:32:25 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_PPMOVE1_BATTLE + moveIndex , 0 , 1 , & gBattleMons [ gActiveBattler ] . pp [ moveIndex ] ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-10-06 17:06:45 +02:00
}
}
2019-03-02 23:40:38 +01:00
void PressurePPLoseOnUsingImprison ( u8 attacker )
2017-10-06 17:06:45 +02:00
{
2019-01-19 22:32:25 +01:00
int i , j ;
2019-03-02 23:40:38 +01:00
int imprisonPos = 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
{
2018-12-25 18:50:15 +01:00
for ( j = 0 ; j < MAX_MON_MOVES ; j + + )
2017-10-06 17:06:45 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ attacker ] . moves [ j ] = = MOVE_IMPRISON )
2017-10-06 17:06:45 +02:00
break ;
}
2018-12-25 18:50:15 +01:00
if ( j ! = MAX_MON_MOVES )
2017-10-06 17:06:45 +02:00
{
2019-03-02 23:40:38 +01:00
imprisonPos = 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
}
}
}
2019-03-02 23:40:38 +01:00
if ( imprisonPos ! = 4
2018-02-06 02:46:59 +01:00
& & ! ( gBattleMons [ attacker ] . status2 & STATUS2_TRANSFORMED )
2019-03-02 23:40:38 +01:00
& & ! ( gDisableStructs [ attacker ] . mimickedMoves & gBitTable [ imprisonPos ] ) )
2017-10-06 17:06:45 +02:00
{
2018-02-06 02:46:59 +01:00
gActiveBattler = attacker ;
2019-03-02 23:40:38 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_PPMOVE1_BATTLE + imprisonPos , 0 , 1 , & gBattleMons [ gActiveBattler ] . pp [ imprisonPos ] ) ;
2018-02-06 20:48:02 +01:00
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
{
2019-01-19 22:32:25 +01:00
int i , j ;
int perishSongPos = 4 ;
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 ( gBattleMons [ i ] . ability = = ABILITY_PRESSURE & & i ! = attacker )
2017-10-06 17:06:45 +02:00
{
2018-12-25 18:50:15 +01:00
for ( j = 0 ; j < MAX_MON_MOVES ; j + + )
2017-10-06 17:06:45 +02:00
{
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 ;
}
2018-12-25 18:50:15 +01:00
if ( j ! = MAX_MON_MOVES )
2017-10-06 17:06:45 +02:00
{
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
}
}
}
2018-12-25 18:50:15 +01:00
if ( perishSongPos ! = MAX_MON_MOVES
2018-02-06 02:46:59 +01:00
& & ! ( gBattleMons [ attacker ] . status2 & STATUS2_TRANSFORMED )
2019-01-19 22:32:25 +01:00
& & ! ( gDisableStructs [ attacker ] . mimickedMoves & 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
{
2019-01-19 22:32:25 +01:00
int i ;
2017-10-06 17:06:45 +02:00
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
}
2021-01-22 08:48:22 +01:00
void MarkBattlerReceivedLinkData ( u8 battlerId )
2017-10-06 17:06:45 +02:00
{
s32 i ;
2017-10-13 17:09:36 +02:00
for ( i = 0 ; i < GetLinkPlayerCount ( ) ; i + + )
2021-01-22 08:48:22 +01:00
gBattleControllerExecFlags | = gBitTable [ battlerId ] < < ( i < < 2 ) ;
2017-10-06 17:06:45 +02:00
2021-01-22 08:48:22 +01:00
gBattleControllerExecFlags & = ~ ( 0x10000000 < < battlerId ) ;
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-10-14 18:10:54 +02:00
gDisableStructs [ battler ] . rolloutTimer = 0 ;
2018-02-06 02:46:59 +01:00
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
2019-03-02 23:40:38 +01:00
| | gProtectStructs [ battler ] . usedImprisonedMove
2018-02-06 02:46:59 +01:00
| | 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
}
2020-07-28 04:22:16 +02:00
void OpponentSwitchInResetSentPokesToOpponentValue ( 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
}
}
2020-07-28 00:10:42 +02:00
void UpdateSentPokesToOpponentValue ( 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
{
2020-07-28 04:22:16 +02:00
OpponentSwitchInResetSentPokesToOpponentValue ( battler ) ;
2017-10-06 17:06:45 +02:00
}
else
{
s32 i ;
2018-02-06 02:46:59 +01:00
for ( i = 1 ; i < gBattlersCount ; i + + )
2018-02-06 20:48:02 +01:00
gSentPokesToOpponent [ ( i & BIT_FLANK ) > > 1 ] | = gBitTable [ gBattlerPartyIndexes [ battler ] ] ;
2017-10-06 17:06:45 +02:00
}
}
2017-09-17 14:10:32 +02:00
2018-07-01 11:15:42 +02:00
void BattleScriptPush ( const u8 * bsPtr )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleResources - > battleScriptsStack - > ptr [ gBattleResources - > battleScriptsStack - > size + + ] = bsPtr ;
2017-09-17 14:10:32 +02:00
}
2017-09-22 21:33:49 +02:00
void BattleScriptPushCursor ( void )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleResources - > battleScriptsStack - > ptr [ gBattleResources - > battleScriptsStack - > size + + ] = gBattlescriptCurrInstr ;
2017-09-17 14:10:32 +02:00
}
2017-09-22 21:33:49 +02:00
void BattleScriptPop ( void )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gBattlescriptCurrInstr = gBattleResources - > battleScriptsStack - > ptr [ - - gBattleResources - > battleScriptsStack - > size ] ;
2017-09-17 14:10:32 +02:00
}
2017-10-03 21:35:27 +02:00
u8 TrySetCantSelectMoveBattleScript ( void )
2017-09-17 14:10:32 +02:00
{
u8 limitations = 0 ;
2018-02-06 02:46:59 +01:00
u16 move = gBattleMons [ gActiveBattler ] . moves [ gBattleBufferB [ gActiveBattler ] [ 2 ] ] ;
2017-09-17 14:10:32 +02:00
u8 holdEffect ;
2018-02-06 02:46:59 +01:00
u16 * choicedMove = & gBattleStruct - > choicedMove [ gActiveBattler ] ;
2017-09-17 14:10:32 +02:00
2019-01-19 22:32:25 +01:00
if ( gDisableStructs [ gActiveBattler ] . disabledMove = = move & & move ! = MOVE_NONE )
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 ;
2019-01-29 22:22:02 +01:00
gProtectStructs [ gActiveBattler ] . palaceUnableToUseMove = 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 ;
2019-01-29 22:22:02 +01:00
gProtectStructs [ gActiveBattler ] . palaceUnableToUseMove = 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-10-14 18:10:54 +02:00
if ( gDisableStructs [ gActiveBattler ] . tauntTimer ! = 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 ;
2019-01-29 22:22:02 +01:00
gProtectStructs [ gActiveBattler ] . palaceUnableToUseMove = 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 )
{
2019-03-02 23:40:38 +01:00
gPalaceSelectionBattleScripts [ gActiveBattler ] = BattleScript_SelectingImprisonedMoveInPalace ;
2019-01-29 22:22:02 +01:00
gProtectStructs [ gActiveBattler ] . palaceUnableToUseMove = 1 ;
2017-09-17 14:10:32 +02:00
}
else
{
2019-03-02 23:40:38 +01:00
gSelectionBattleScripts [ gActiveBattler ] = BattleScript_SelectingImprisonedMove ;
2017-09-17 14:10:32 +02:00
limitations + + ;
}
}
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . item = = ITEM_ENIGMA_BERRY )
holdEffect = gEnigmaBerries [ gActiveBattler ] . holdEffect ;
2017-09-17 14:10:32 +02:00
else
2018-02-06 02:46:59 +01:00
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ gActiveBattler ] . item ) ;
2017-09-17 14:10:32 +02:00
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gActiveBattler ;
2017-09-17 14:10:32 +02:00
if ( holdEffect = = HOLD_EFFECT_CHOICE_BAND & & * choicedMove ! = 0 & & * choicedMove ! = 0xFFFF & & * choicedMove ! = move )
{
gCurrentMove = * choicedMove ;
2018-02-06 02:46:59 +01:00
gLastUsedItem = gBattleMons [ gActiveBattler ] . item ;
2017-09-17 14:10:32 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_PALACE )
{
2019-01-29 22:22:02 +01:00
gProtectStructs [ gActiveBattler ] . palaceUnableToUseMove = 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 )
{
2019-01-29 22:22:02 +01:00
gProtectStructs [ gActiveBattler ] . palaceUnableToUseMove = 1 ;
2017-09-17 14:10:32 +02:00
}
else
{
2018-02-06 02:46:59 +01:00
gSelectionBattleScripts [ gActiveBattler ] = BattleScript_SelectingMoveWithNoPP ;
2017-09-17 14:10:32 +02:00
limitations + + ;
}
}
return limitations ;
}
2018-02-08 11:17:41 +01:00
u8 CheckMoveLimitations ( u8 battlerId , u8 unusableMoves , u8 check )
2017-09-17 14:10:32 +02:00
{
u8 holdEffect ;
2018-02-08 11:17:41 +01:00
u16 * choicedMove = & gBattleStruct - > choicedMove [ battlerId ] ;
2017-09-17 14:10:32 +02:00
s32 i ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . item = = ITEM_ENIGMA_BERRY )
holdEffect = gEnigmaBerries [ battlerId ] . holdEffect ;
2017-09-17 14:10:32 +02:00
else
2018-02-08 11:17:41 +01:00
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ battlerId ] . item ) ;
2017-09-17 14:10:32 +02:00
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = battlerId ;
2017-09-17 14:10:32 +02:00
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-17 14:10:32 +02:00
{
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . moves [ i ] = = 0 & & check & MOVE_LIMITATION_ZEROMOVE )
2017-09-17 14:10:32 +02:00
unusableMoves | = gBitTable [ i ] ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . pp [ i ] = = 0 & & check & MOVE_LIMITATION_PP )
2017-09-17 14:10:32 +02:00
unusableMoves | = gBitTable [ i ] ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . moves [ i ] = = gDisableStructs [ battlerId ] . disabledMove & & check & MOVE_LIMITATION_DISABLED )
2017-09-17 14:10:32 +02:00
unusableMoves | = gBitTable [ i ] ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . moves [ i ] = = gLastMoves [ battlerId ] & & check & MOVE_LIMITATION_TORMENTED & & gBattleMons [ battlerId ] . status2 & STATUS2_TORMENT )
2017-09-17 14:10:32 +02:00
unusableMoves | = gBitTable [ i ] ;
2018-10-14 18:10:54 +02:00
if ( gDisableStructs [ battlerId ] . tauntTimer & & check & MOVE_LIMITATION_TAUNT & & gBattleMoves [ gBattleMons [ battlerId ] . moves [ i ] ] . power = = 0 )
2017-09-17 14:10:32 +02:00
unusableMoves | = gBitTable [ i ] ;
2019-03-02 23:40:38 +01:00
if ( GetImprisonedMovesCount ( battlerId , gBattleMons [ battlerId ] . moves [ i ] ) & & check & MOVE_LIMITATION_IMPRISON )
2017-09-17 14:10:32 +02:00
unusableMoves | = gBitTable [ i ] ;
2018-10-14 18:10:54 +02:00
if ( gDisableStructs [ battlerId ] . encoreTimer & & gDisableStructs [ battlerId ] . encoredMove ! = gBattleMons [ battlerId ] . moves [ i ] )
2017-09-17 14:10:32 +02:00
unusableMoves | = gBitTable [ i ] ;
2018-02-08 11:17:41 +01:00
if ( holdEffect = = HOLD_EFFECT_CHOICE_BAND & & * choicedMove ! = 0 & & * choicedMove ! = 0xFFFF & & * choicedMove ! = gBattleMons [ battlerId ] . moves [ i ] )
2017-09-17 14:10:32 +02:00
unusableMoves | = gBitTable [ i ] ;
}
return unusableMoves ;
}
bool8 AreAllMovesUnusable ( void )
{
u8 unusable ;
2018-02-06 02:46:59 +01:00
unusable = CheckMoveLimitations ( gActiveBattler , 0 , 0xFF ) ;
2017-09-17 14:10:32 +02:00
2018-07-01 11:15:42 +02:00
if ( unusable = = 0xF ) // All moves are unusable.
2017-09-17 14:10:32 +02:00
{
2018-07-07 19:57:09 +02:00
gProtectStructs [ gActiveBattler ] . noValidMoves = 1 ;
2018-02-06 02:46:59 +01:00
gSelectionBattleScripts [ gActiveBattler ] = BattleScript_NoMovesLeft ;
2017-09-17 14:10:32 +02:00
}
else
{
2018-07-07 19:57:09 +02:00
gProtectStructs [ gActiveBattler ] . noValidMoves = 0 ;
2017-09-17 14:10:32 +02:00
}
return ( unusable = = 0xF ) ;
}
2018-02-08 11:17:41 +01:00
u8 GetImprisonedMovesCount ( u8 battlerId , u16 move )
2017-09-17 14:10:32 +02:00
{
s32 i ;
2019-03-02 23:40:38 +01:00
u8 imprisonedMoves = 0 ;
2018-07-16 20:47:30 +02:00
u8 battlerSide = GetBattlerSide ( battlerId ) ;
2017-09-17 14:10:32 +02:00
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 14:10:32 +02:00
{
2018-07-16 20:47:30 +02:00
if ( battlerSide ! = GetBattlerSide ( i ) & & gStatuses3 [ i ] & STATUS3_IMPRISONED_OTHERS )
2017-09-17 14:10:32 +02:00
{
s32 j ;
2018-12-25 18:50:15 +01:00
for ( j = 0 ; j < MAX_MON_MOVES ; j + + )
2017-09-17 14:10:32 +02:00
{
if ( move = = gBattleMons [ i ] . moves [ j ] )
break ;
}
2018-12-25 18:50:15 +01:00
if ( j < MAX_MON_MOVES )
2019-03-02 23:40:38 +01:00
imprisonedMoves + + ;
2017-09-17 14:10:32 +02:00
}
}
2019-03-02 23:40:38 +01:00
return imprisonedMoves ;
2017-09-17 14:10:32 +02:00
}
2018-08-03 00:13:44 +02:00
enum
{
2018-08-03 00:24:10 +02:00
ENDTURN_ORDER ,
ENDTURN_REFLECT ,
ENDTURN_LIGHT_SCREEN ,
ENDTURN_MIST ,
ENDTURN_SAFEGUARD ,
ENDTURN_WISH ,
ENDTURN_RAIN ,
ENDTURN_SANDSTORM ,
ENDTURN_SUN ,
ENDTURN_HAIL ,
ENDTURN_FIELD_COUNT ,
2018-08-03 00:13:44 +02:00
} ;
u8 DoFieldEndTurnEffects ( void )
2017-09-17 14:10:32 +02:00
{
u8 effect = 0 ;
s32 i ;
2018-02-06 23:09:39 +01:00
for ( gBattlerAttacker = 0 ; gBattlerAttacker < gBattlersCount & & gAbsentBattlerFlags & gBitTable [ gBattlerAttacker ] ; gBattlerAttacker + + )
2017-09-17 14:10:32 +02:00
{
}
2018-02-06 23:09:39 +01:00
for ( gBattlerTarget = 0 ; gBattlerTarget < gBattlersCount & & gAbsentBattlerFlags & gBitTable [ gBattlerTarget ] ; gBattlerTarget + + )
2017-09-17 14:10:32 +02:00
{
}
do
{
2018-07-01 11:15:42 +02:00
u8 side ;
2017-09-17 14:10:32 +02:00
2018-02-07 22:53:40 +01:00
switch ( gBattleStruct - > turnCountersTracker )
2017-09-17 14:10:32 +02:00
{
2018-08-03 00:13:44 +02:00
case ENDTURN_ORDER :
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 14:10:32 +02:00
{
2018-06-28 21:06:32 +02:00
gBattlerByTurnOrder [ i ] = i ;
2017-09-17 14:10:32 +02:00
}
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount - 1 ; i + + )
2017-09-17 14:10:32 +02:00
{
s32 j ;
2018-02-06 02:46:59 +01:00
for ( j = i + 1 ; j < gBattlersCount ; j + + )
2017-09-17 14:10:32 +02:00
{
2018-06-28 21:06:32 +02:00
if ( GetWhoStrikesFirst ( gBattlerByTurnOrder [ i ] , gBattlerByTurnOrder [ j ] , 0 ) )
2017-10-04 19:25:14 +02:00
SwapTurnOrder ( i , j ) ;
2017-09-17 14:10:32 +02:00
}
}
// It's stupid, but won't match without it
{
2018-02-07 22:53:40 +01:00
u8 * var = & gBattleStruct - > turnCountersTracker ;
2017-09-17 14:10:32 +02:00
( * var ) + + ;
gBattleStruct - > turnSideTracker = 0 ;
}
// fall through
2018-08-03 00:13:44 +02:00
case ENDTURN_REFLECT :
2017-09-17 14:10:32 +02:00
while ( gBattleStruct - > turnSideTracker < 2 )
{
2018-07-01 11:15:42 +02:00
side = gBattleStruct - > turnSideTracker ;
gActiveBattler = gBattlerAttacker = gSideTimers [ side ] . reflectBattlerId ;
if ( gSideStatuses [ side ] & SIDE_STATUS_REFLECT )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
if ( - - gSideTimers [ side ] . reflectTimer = = 0 )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
gSideStatuses [ side ] & = ~ SIDE_STATUS_REFLECT ;
2017-11-26 17:15:28 +01:00
BattleScriptExecute ( BattleScript_SideStatusWoreOff ) ;
2017-11-26 13:26:58 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , MOVE_REFLECT ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
}
gBattleStruct - > turnSideTracker + + ;
if ( effect )
break ;
}
if ( ! effect )
{
2018-02-07 22:53:40 +01:00
gBattleStruct - > turnCountersTracker + + ;
2017-09-17 14:10:32 +02:00
gBattleStruct - > turnSideTracker = 0 ;
}
break ;
2018-08-03 00:13:44 +02:00
case ENDTURN_LIGHT_SCREEN :
2017-09-17 14:10:32 +02:00
while ( gBattleStruct - > turnSideTracker < 2 )
{
2018-07-01 11:15:42 +02:00
side = gBattleStruct - > turnSideTracker ;
gActiveBattler = gBattlerAttacker = gSideTimers [ side ] . lightscreenBattlerId ;
if ( gSideStatuses [ side ] & SIDE_STATUS_LIGHTSCREEN )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
if ( - - gSideTimers [ side ] . lightscreenTimer = = 0 )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
gSideStatuses [ side ] & = ~ SIDE_STATUS_LIGHTSCREEN ;
2017-11-26 17:15:28 +01:00
BattleScriptExecute ( BattleScript_SideStatusWoreOff ) ;
2018-07-01 11:15:42 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = side ;
2017-11-26 13:26:58 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , MOVE_LIGHT_SCREEN ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
}
gBattleStruct - > turnSideTracker + + ;
if ( effect )
break ;
}
if ( ! effect )
{
2018-02-07 22:53:40 +01:00
gBattleStruct - > turnCountersTracker + + ;
2017-09-17 14:10:32 +02:00
gBattleStruct - > turnSideTracker = 0 ;
}
break ;
2018-08-03 00:13:44 +02:00
case ENDTURN_MIST :
2017-09-17 14:10:32 +02:00
while ( gBattleStruct - > turnSideTracker < 2 )
{
2018-07-01 11:15:42 +02:00
side = gBattleStruct - > turnSideTracker ;
gActiveBattler = gBattlerAttacker = gSideTimers [ side ] . mistBattlerId ;
if ( gSideTimers [ side ] . mistTimer ! = 0
& & - - gSideTimers [ side ] . mistTimer = = 0 )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
gSideStatuses [ side ] & = ~ SIDE_STATUS_MIST ;
2017-11-26 17:15:28 +01:00
BattleScriptExecute ( BattleScript_SideStatusWoreOff ) ;
2018-07-01 11:15:42 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = side ;
2017-11-26 13:26:58 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , MOVE_MIST ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
gBattleStruct - > turnSideTracker + + ;
if ( effect )
break ;
}
if ( ! effect )
{
2018-02-07 22:53:40 +01:00
gBattleStruct - > turnCountersTracker + + ;
2017-09-17 14:10:32 +02:00
gBattleStruct - > turnSideTracker = 0 ;
}
break ;
2018-08-03 00:13:44 +02:00
case ENDTURN_SAFEGUARD :
2017-09-17 14:10:32 +02:00
while ( gBattleStruct - > turnSideTracker < 2 )
{
2018-07-01 11:15:42 +02:00
side = gBattleStruct - > turnSideTracker ;
gActiveBattler = gBattlerAttacker = gSideTimers [ side ] . safeguardBattlerId ;
if ( gSideStatuses [ side ] & SIDE_STATUS_SAFEGUARD )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
if ( - - gSideTimers [ side ] . safeguardTimer = = 0 )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
gSideStatuses [ side ] & = ~ SIDE_STATUS_SAFEGUARD ;
2017-11-26 17:15:28 +01:00
BattleScriptExecute ( BattleScript_SafeguardEnds ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
}
gBattleStruct - > turnSideTracker + + ;
if ( effect )
break ;
}
if ( ! effect )
{
2018-02-07 22:53:40 +01:00
gBattleStruct - > turnCountersTracker + + ;
2017-09-17 14:10:32 +02:00
gBattleStruct - > turnSideTracker = 0 ;
}
break ;
2018-08-03 00:13:44 +02:00
case ENDTURN_WISH :
2018-02-06 02:46:59 +01:00
while ( gBattleStruct - > turnSideTracker < gBattlersCount )
2017-09-17 14:10:32 +02:00
{
2018-06-28 21:06:32 +02:00
gActiveBattler = gBattlerByTurnOrder [ gBattleStruct - > turnSideTracker ] ;
2018-02-06 02:46:59 +01:00
if ( gWishFutureKnock . wishCounter [ gActiveBattler ] ! = 0
& & - - gWishFutureKnock . wishCounter [ gActiveBattler ] = = 0
& & gBattleMons [ gActiveBattler ] . hp ! = 0 )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gBattlerTarget = gActiveBattler ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_WishComesTrue ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
gBattleStruct - > turnSideTracker + + ;
if ( effect )
break ;
}
if ( ! effect )
{
2018-02-07 22:53:40 +01:00
gBattleStruct - > turnCountersTracker + + ;
2017-09-17 14:10:32 +02:00
}
break ;
2018-08-03 00:13:44 +02:00
case ENDTURN_RAIN :
2017-09-17 14:10:32 +02:00
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 ;
2018-08-03 00:13:44 +02:00
case ENDTURN_SANDSTORM :
2017-09-17 14:10:32 +02:00
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 ;
2018-08-03 00:13:44 +02:00
case ENDTURN_SUN :
2017-09-17 14:10:32 +02:00
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 ;
2018-08-03 00:13:44 +02:00
case ENDTURN_HAIL :
if ( gBattleWeather & WEATHER_HAIL_ANY )
2017-09-17 14:10:32 +02:00
{
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 ;
2018-08-03 00:13:44 +02:00
case ENDTURN_FIELD_COUNT :
2017-09-17 14:10:32 +02:00
effect + + ;
break ;
}
} while ( effect = = 0 ) ;
return ( gBattleMainFunc ! = BattleTurnPassed ) ;
}
2018-08-03 00:13:44 +02:00
enum
{
ENDTURN_INGRAIN ,
ENDTURN_ABILITIES ,
2018-08-03 00:24:10 +02:00
ENDTURN_ITEMS1 ,
ENDTURN_LEECH_SEED ,
ENDTURN_POISON ,
ENDTURN_BAD_POISON ,
ENDTURN_BURN ,
ENDTURN_NIGHTMARES ,
ENDTURN_CURSE ,
ENDTURN_WRAP ,
ENDTURN_UPROAR ,
ENDTURN_THRASH ,
ENDTURN_DISABLE ,
ENDTURN_ENCORE ,
ENDTURN_LOCK_ON ,
ENDTURN_CHARGE ,
ENDTURN_TAUNT ,
ENDTURN_YAWN ,
ENDTURN_ITEMS2 ,
ENDTURN_BATTLER_COUNT
2018-08-03 00:13:44 +02:00
} ;
2017-09-17 14:10:32 +02:00
2018-08-03 00:13:44 +02:00
u8 DoBattlerEndTurnEffects ( void )
2017-09-17 14:10:32 +02:00
{
u8 effect = 0 ;
gHitMarker | = ( HITMARKER_GRUDGE | HITMARKER_x20 ) ;
2018-08-03 00:13:44 +02:00
while ( gBattleStruct - > turnEffectsBattlerId < gBattlersCount & & gBattleStruct - > turnEffectsTracker < = ENDTURN_BATTLER_COUNT )
2017-09-17 14:10:32 +02:00
{
2018-06-28 21:06:32 +02:00
gActiveBattler = gBattlerAttacker = gBattlerByTurnOrder [ gBattleStruct - > turnEffectsBattlerId ] ;
2018-02-06 02:46:59 +01:00
if ( gAbsentBattlerFlags & gBitTable [ gActiveBattler ] )
2017-09-17 14:10:32 +02:00
{
2018-02-07 22:53:40 +01:00
gBattleStruct - > turnEffectsBattlerId + + ;
2017-09-17 14:10:32 +02:00
}
else
{
switch ( gBattleStruct - > turnEffectsTracker )
{
2018-08-03 00:13:44 +02:00
case ENDTURN_INGRAIN : // 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 ;
2018-08-03 00:13:44 +02:00
case ENDTURN_ABILITIES : // 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 ;
2018-08-03 00:13:44 +02:00
case ENDTURN_ITEMS1 : // item effects
2018-09-01 20:00:13 +02:00
if ( ItemBattleEffects ( 1 , gActiveBattler , FALSE ) )
2017-09-17 14:10:32 +02:00
effect + + ;
gBattleStruct - > turnEffectsTracker + + ;
break ;
2018-08-03 00:13:44 +02:00
case ENDTURN_ITEMS2 : // item effects again
2018-09-01 20:00:13 +02:00
if ( ItemBattleEffects ( 1 , gActiveBattler , TRUE ) )
2017-09-17 14:10:32 +02:00
effect + + ;
gBattleStruct - > turnEffectsTracker + + ;
break ;
2018-08-03 00:13:44 +02:00
case ENDTURN_LEECH_SEED : // leech seed
2018-02-06 02:46:59 +01:00
if ( ( gStatuses3 [ gActiveBattler ] & STATUS3_LEECHSEED )
2018-07-01 11:15:42 +02:00
& & gBattleMons [ gStatuses3 [ gActiveBattler ] & STATUS3_LEECHSEED_BATTLER ] . hp ! = 0
2018-02-06 02:46:59 +01:00
& & gBattleMons [ gActiveBattler ] . hp ! = 0 )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
gBattlerTarget = gStatuses3 [ gActiveBattler ] & STATUS3_LEECHSEED_BATTLER ; // Notice gBattlerTarget is actually the HP receiver.
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gBattleMons [ gActiveBattler ] . maxHP / 8 ;
2017-09-17 14:10:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2018-02-06 23:09:39 +01:00
gBattleScripting . animArg1 = gBattlerTarget ;
gBattleScripting . animArg2 = gBattlerAttacker ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_LeechSeedTurnDrain ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
gBattleStruct - > turnEffectsTracker + + ;
break ;
2018-08-03 00:13:44 +02:00
case ENDTURN_POISON : // 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 ;
2018-08-03 00:13:44 +02:00
case ENDTURN_BAD_POISON : // 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 ;
2020-07-17 02:12:12 +02:00
if ( ( gBattleMons [ gActiveBattler ] . status1 & STATUS1_TOXIC_COUNTER ) ! = STATUS1_TOXIC_TURN ( 15 ) ) // not 16 turns
gBattleMons [ gActiveBattler ] . status1 + = STATUS1_TOXIC_TURN ( 1 ) ;
gBattleMoveDamage * = ( gBattleMons [ gActiveBattler ] . status1 & STATUS1_TOXIC_COUNTER ) > > 8 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_PoisonTurnDmg ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
gBattleStruct - > turnEffectsTracker + + ;
break ;
2018-08-03 00:13:44 +02:00
case ENDTURN_BURN : // 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 ;
2018-08-03 00:13:44 +02:00
case ENDTURN_NIGHTMARES : // spooky nightmares
2018-02-06 02:46:59 +01:00
if ( ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_NIGHTMARE ) & & gBattleMons [ gActiveBattler ] . hp ! = 0 )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
// R/S does not perform this sleep check, which causes the nightmare effect to
// persist even after the affected Pokemon has been awakened by Shed Skin.
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . status1 & STATUS1_SLEEP )
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gBattleMons [ gActiveBattler ] . maxHP / 4 ;
2017-09-17 14:10:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_NightmareTurnDmg ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
else
{
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . status2 & = ~ STATUS2_NIGHTMARE ;
2017-09-17 14:10:32 +02:00
}
}
gBattleStruct - > turnEffectsTracker + + ;
break ;
2018-08-03 00:13:44 +02:00
case ENDTURN_CURSE : // 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 ;
2018-08-03 00:13:44 +02:00
case ENDTURN_WRAP : // 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
{
2020-07-17 02:12:12 +02:00
gBattleMons [ gActiveBattler ] . status2 - = STATUS2_WRAPPED_TURN ( 1 ) ;
2018-02-06 02:46:59 +01:00
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 ;
2018-08-03 00:13:44 +02:00
case ENDTURN_UPROAR : // 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 ;
2020-07-17 02:12:12 +02:00
gBattleMons [ gActiveBattler ] . status2 - = STATUS2_UPROAR_TURN ( 1 ) ;
2018-02-06 02:46:59 +01:00
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 ;
2018-08-03 00:13:44 +02:00
case ENDTURN_THRASH : // thrash
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_LOCK_CONFUSE )
2017-09-17 14:10:32 +02:00
{
2020-07-17 02:12:12 +02:00
gBattleMons [ gActiveBattler ] . status2 - = STATUS2_LOCK_CONFUSE_TURN ( 1 ) ;
2018-02-06 02:46:59 +01:00
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 ;
2020-03-07 23:36:09 +01:00
SetMoveEffect ( TRUE , 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 ;
2018-08-03 00:13:44 +02:00
case ENDTURN_DISABLE : // disable
2018-10-14 18:10:54 +02:00
if ( gDisableStructs [ gActiveBattler ] . disableTimer ! = 0 )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
s32 i ;
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-17 14:10:32 +02:00
{
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 ;
}
2018-12-25 18:50:15 +01:00
if ( i = = MAX_MON_MOVES ) // pokemon does not have the disabled move anymore
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
gDisableStructs [ gActiveBattler ] . disabledMove = 0 ;
2018-10-14 18:10:54 +02:00
gDisableStructs [ gActiveBattler ] . disableTimer = 0 ;
2017-09-17 14:10:32 +02:00
}
2018-10-14 18:10:54 +02:00
else if ( - - gDisableStructs [ gActiveBattler ] . disableTimer = = 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 ;
2018-08-03 00:13:44 +02:00
case ENDTURN_ENCORE : // encore
2018-10-14 18:10:54 +02:00
if ( gDisableStructs [ gActiveBattler ] . encoreTimer ! = 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 ;
2018-10-14 18:10:54 +02:00
gDisableStructs [ gActiveBattler ] . encoreTimer = 0 ;
2017-09-17 14:10:32 +02:00
}
2018-10-14 18:10:54 +02:00
else if ( - - gDisableStructs [ gActiveBattler ] . encoreTimer = = 0
2018-02-06 02:46:59 +01:00
| | 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 ;
2018-10-14 18:10:54 +02:00
gDisableStructs [ gActiveBattler ] . encoreTimer = 0 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_EncoredNoMore ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
}
gBattleStruct - > turnEffectsTracker + + ;
break ;
2018-08-03 00:13:44 +02:00
case ENDTURN_LOCK_ON : // lock-on decrement
2018-02-06 02:46:59 +01:00
if ( gStatuses3 [ gActiveBattler ] & STATUS3_ALWAYS_HITS )
2020-07-17 02:12:12 +02:00
gStatuses3 [ gActiveBattler ] - = STATUS3_ALWAYS_HITS_TURN ( 1 ) ;
2017-09-17 14:10:32 +02:00
gBattleStruct - > turnEffectsTracker + + ;
break ;
2018-08-03 00:13:44 +02:00
case ENDTURN_CHARGE : // charge
2018-10-14 18:10:54 +02:00
if ( gDisableStructs [ gActiveBattler ] . chargeTimer & & - - gDisableStructs [ gActiveBattler ] . chargeTimer = = 0 )
2018-02-06 02:46:59 +01:00
gStatuses3 [ gActiveBattler ] & = ~ STATUS3_CHARGED_UP ;
2017-09-17 14:10:32 +02:00
gBattleStruct - > turnEffectsTracker + + ;
break ;
2018-08-03 00:13:44 +02:00
case ENDTURN_TAUNT : // taunt
2018-10-14 18:10:54 +02:00
if ( gDisableStructs [ gActiveBattler ] . tauntTimer )
gDisableStructs [ gActiveBattler ] . tauntTimer - - ;
2017-09-17 14:10:32 +02:00
gBattleStruct - > turnEffectsTracker + + ;
break ;
2018-08-03 00:13:44 +02:00
case ENDTURN_YAWN : // yawn
2018-02-06 02:46:59 +01:00
if ( gStatuses3 [ gActiveBattler ] & STATUS3_YAWN )
{
2020-07-17 02:12:12 +02:00
gStatuses3 [ gActiveBattler ] - = STATUS3_YAWN_TURN ( 1 ) ;
2018-02-06 02:46:59 +01:00
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 ) ;
2020-07-17 02:12:12 +02:00
gBattleMons [ gActiveBattler ] . status1 | = STATUS1_SLEEP_TURN ( ( Random ( ) & 3 ) + 2 ) ; // 2-5 turns of sleep
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gActiveBattler ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2018-02-08 11:17:41 +01:00
gEffectBattler = gActiveBattler ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_YawnMakesAsleep ) ;
2017-09-17 14:10:32 +02:00
effect + + ;
}
}
gBattleStruct - > turnEffectsTracker + + ;
break ;
2018-08-03 00:13:44 +02:00
case ENDTURN_BATTLER_COUNT : // done
2017-09-17 14:10:32 +02:00
gBattleStruct - > turnEffectsTracker = 0 ;
2018-02-07 22:53:40 +01:00
gBattleStruct - > turnEffectsBattlerId + + ;
2017-09-17 14:10:32 +02:00
break ;
}
if ( effect ! = 0 )
return effect ;
}
}
gHitMarker & = ~ ( HITMARKER_GRUDGE | HITMARKER_x20 ) ;
return 0 ;
}
2017-12-02 14:08:55 +01:00
bool8 HandleWishPerishSongOnTurnEnd ( void )
2017-09-17 14:10:32 +02:00
{
gHitMarker | = ( HITMARKER_GRUDGE | HITMARKER_x20 ) ;
2017-12-02 14:08:55 +01:00
switch ( gBattleStruct - > wishPerishSongState )
2017-09-17 14:10:32 +02:00
{
case 0 :
2018-02-07 22:53:40 +01:00
while ( gBattleStruct - > wishPerishSongBattlerId < gBattlersCount )
2017-09-17 14:10:32 +02:00
{
2018-02-07 22:53:40 +01:00
gActiveBattler = gBattleStruct - > wishPerishSongBattlerId ;
2018-02-06 02:46:59 +01:00
if ( gAbsentBattlerFlags & gBitTable [ gActiveBattler ] )
2017-09-17 14:10:32 +02:00
{
2018-02-07 22:53:40 +01:00
gBattleStruct - > wishPerishSongBattlerId + + ;
2017-09-17 14:10:32 +02:00
continue ;
}
2018-02-07 22:53:40 +01:00
gBattleStruct - > wishPerishSongBattlerId + + ;
2018-02-06 02:46:59 +01:00
if ( gWishFutureKnock . futureSightCounter [ gActiveBattler ] ! = 0
& & - - gWishFutureKnock . futureSightCounter [ gActiveBattler ] = = 0
& & gBattleMons [ gActiveBattler ] . hp ! = 0 )
2017-09-17 14:10:32 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gWishFutureKnock . futureSightMove [ gActiveBattler ] = = MOVE_FUTURE_SIGHT )
2017-09-17 14:10:32 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
2018-02-06 02:46:59 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , gWishFutureKnock . futureSightMove [ gActiveBattler ] ) ;
2017-11-26 13:26:58 +01:00
2018-02-06 23:09:39 +01:00
gBattlerTarget = gActiveBattler ;
gBattlerAttacker = gWishFutureKnock . futureSightAttacker [ gActiveBattler ] ;
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gWishFutureKnock . futureSightDmg [ gActiveBattler ] ;
2018-02-07 22:53:40 +01:00
gSpecialStatuses [ gBattlerTarget ] . dmg = 0xFFFF ;
2017-11-26 17:26:11 +01:00
BattleScriptExecute ( BattleScript_MonTookFutureAttack ) ;
2017-09-17 14:10:32 +02:00
2018-02-06 02:46:59 +01:00
if ( gWishFutureKnock . futureSightCounter [ gActiveBattler ] = = 0
& & gWishFutureKnock . futureSightCounter [ gActiveBattler ^ BIT_FLANK ] = = 0 )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gSideStatuses [ GET_BATTLER_SIDE ( gBattlerTarget ) ] & = ~ ( SIDE_STATUS_FUTUREATTACK ) ;
2017-09-17 14:10:32 +02:00
}
2017-11-26 13:26:58 +01:00
return TRUE ;
2017-09-17 14:10:32 +02:00
}
}
// Why do I have to keep doing this to match?
{
2017-12-02 14:08:55 +01:00
u8 * state = & gBattleStruct - > wishPerishSongState ;
* state = 1 ;
2018-02-07 22:53:40 +01:00
gBattleStruct - > wishPerishSongBattlerId = 0 ;
2017-09-17 14:10:32 +02:00
}
// fall through
case 1 :
2018-02-07 22:53:40 +01:00
while ( gBattleStruct - > wishPerishSongBattlerId < gBattlersCount )
2017-09-17 14:10:32 +02:00
{
2018-06-28 21:06:32 +02:00
gActiveBattler = gBattlerAttacker = gBattlerByTurnOrder [ gBattleStruct - > wishPerishSongBattlerId ] ;
2018-02-06 02:46:59 +01:00
if ( gAbsentBattlerFlags & gBitTable [ gActiveBattler ] )
2017-09-17 14:10:32 +02:00
{
2018-02-07 22:53:40 +01:00
gBattleStruct - > wishPerishSongBattlerId + + ;
2017-09-17 14:10:32 +02:00
continue ;
}
2018-02-07 22:53:40 +01:00
gBattleStruct - > wishPerishSongBattlerId + + ;
2018-02-06 02:46:59 +01:00
if ( gStatuses3 [ gActiveBattler ] & STATUS3_PERISH_SONG )
2017-09-17 14:10:32 +02:00
{
2018-10-14 18:10:54 +02:00
PREPARE_BYTE_NUMBER_BUFFER ( gBattleTextBuff1 , 1 , gDisableStructs [ gActiveBattler ] . perishSongTimer ) ;
if ( gDisableStructs [ gActiveBattler ] . perishSongTimer = = 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-10-14 18:10:54 +02:00
gDisableStructs [ gActiveBattler ] . perishSongTimer - - ;
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 )
2018-12-07 23:50:56 +01:00
& & gBattleStruct - > arenaTurnCounter = = 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 ) ;
2018-11-11 18:33:16 +01:00
gBattlescriptCurrInstr = BattleScript_ArenaDoJudgment ;
BattleScriptExecute ( BattleScript_ArenaDoJudgment ) ;
2017-12-02 14:08:55 +01:00
gBattleStruct - > wishPerishSongState + + ;
2017-11-26 13:26:58 +01:00
return TRUE ;
2017-09-17 14:10:32 +02:00
}
break ;
}
gHitMarker & = ~ ( HITMARKER_GRUDGE | HITMARKER_x20 ) ;
2017-11-26 13:26:58 +01:00
return FALSE ;
2017-09-17 14:10:32 +02:00
}
2017-12-02 14:08:55 +01:00
# define FAINTED_ACTIONS_MAX_CASE 7
2017-09-17 14:10:32 +02:00
2017-12-02 14:08:55 +01:00
bool8 HandleFaintedMonActions ( void )
2017-09-17 14:10:32 +02:00
{
if ( gBattleTypeFlags & BATTLE_TYPE_SAFARI )
return FALSE ;
do
{
2018-07-01 11:15:42 +02:00
s32 i ;
2017-12-02 14:08:55 +01:00
switch ( gBattleStruct - > faintedActionsState )
2017-09-17 14:10:32 +02:00
{
case 0 :
2018-02-07 22:53:40 +01:00
gBattleStruct - > faintedActionsBattlerId = 0 ;
2017-12-02 14:08:55 +01:00
gBattleStruct - > faintedActionsState + + ;
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
if ( gAbsentBattlerFlags & gBitTable [ i ] & & ! HasNoMonsToSwitch ( i , 6 , 6 ) )
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags & = ~ ( gBitTable [ i ] ) ;
2017-09-17 14:10:32 +02:00
}
// fall through
case 1 :
do
{
2018-02-08 11:17:41 +01:00
gBattlerFainted = gBattlerTarget = gBattleStruct - > faintedActionsBattlerId ;
2018-02-07 22:53:40 +01:00
if ( gBattleMons [ gBattleStruct - > faintedActionsBattlerId ] . hp = = 0
2018-12-07 23:50:56 +01:00
& & ! ( gBattleStruct - > givenExpMons & gBitTable [ gBattlerPartyIndexes [ gBattleStruct - > faintedActionsBattlerId ] ] )
2018-02-07 22:53:40 +01:00
& & ! ( 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 :
2020-07-28 04:22:16 +02:00
OpponentSwitchInResetSentPokesToOpponentValue ( gBattlerFainted ) ;
2018-02-07 22:53:40 +01:00
if ( + + gBattleStruct - > faintedActionsBattlerId = = gBattlersCount )
2017-12-02 14:08:55 +01:00
gBattleStruct - > faintedActionsState = 3 ;
2017-09-17 14:10:32 +02:00
else
2017-12-02 14:08:55 +01:00
gBattleStruct - > faintedActionsState = 1 ;
2017-09-17 14:10:32 +02:00
break ;
case 3 :
2018-02-07 22:53:40 +01:00
gBattleStruct - > faintedActionsBattlerId = 0 ;
2017-12-02 14:08:55 +01:00
gBattleStruct - > faintedActionsState + + ;
2017-09-17 14:10:32 +02:00
// fall through
case 4 :
do
{
2018-02-08 11:17:41 +01:00
gBattlerFainted = gBattlerTarget = gBattleStruct - > faintedActionsBattlerId ;
2018-02-07 22:53:40 +01:00
if ( gBattleMons [ gBattleStruct - > faintedActionsBattlerId ] . hp = = 0
& & ! ( gAbsentBattlerFlags & gBitTable [ gBattleStruct - > faintedActionsBattlerId ] ) )
2017-09-17 14:10:32 +02:00
{
2017-12-02 14:08:55 +01:00
BattleScriptExecute ( BattleScript_HandleFaintedMon ) ;
gBattleStruct - > faintedActionsState = 5 ;
2017-09-17 14:10:32 +02:00
return TRUE ;
}
2018-02-07 22:53:40 +01:00
} while ( + + gBattleStruct - > faintedActionsBattlerId ! = gBattlersCount ) ;
2017-12-02 14:08:55 +01:00
gBattleStruct - > faintedActionsState = 6 ;
2017-09-17 14:10:32 +02:00
break ;
case 5 :
2018-02-07 22:53:40 +01:00
if ( + + gBattleStruct - > faintedActionsBattlerId = = gBattlersCount )
2017-12-02 14:08:55 +01:00
gBattleStruct - > faintedActionsState = 6 ;
2017-09-17 14:10:32 +02:00
else
2017-12-02 14:08:55 +01:00
gBattleStruct - > faintedActionsState = 4 ;
2017-09-17 14:10:32 +02:00
break ;
case 6 :
2018-09-01 20:00:13 +02:00
if ( AbilityBattleEffects ( ABILITYEFFECT_INTIMIDATE1 , 0 , 0 , 0 , 0 ) | | AbilityBattleEffects ( ABILITYEFFECT_TRACE , 0 , 0 , 0 , 0 ) | | ItemBattleEffects ( 1 , 0 , TRUE ) | | AbilityBattleEffects ( ABILITYEFFECT_FORECAST , 0 , 0 , 0 , 0 ) )
2017-09-17 14:10:32 +02:00
return TRUE ;
2017-12-02 14:08:55 +01:00
gBattleStruct - > faintedActionsState + + ;
2017-09-17 14:10:32 +02:00
break ;
2017-12-02 14:08:55 +01:00
case FAINTED_ACTIONS_MAX_CASE :
2017-09-17 14:10:32 +02:00
break ;
}
2017-12-02 14:08:55 +01:00
} while ( gBattleStruct - > faintedActionsState ! = FAINTED_ACTIONS_MAX_CASE ) ;
2017-09-17 14:10:32 +02:00
return FALSE ;
}
2017-10-06 00:12:01 +02:00
void TryClearRageStatuses ( void )
2017-09-17 14:10:32 +02:00
{
2018-07-01 11:15:42 +02:00
s32 i ;
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
if ( ( gBattleMons [ i ] . status2 & STATUS2_RAGE ) & & gChosenMoveByBattler [ i ] ! = MOVE_RAGE )
2017-09-17 14:10:32 +02:00
gBattleMons [ i ] . status2 & = ~ ( STATUS2_RAGE ) ;
}
}
2018-08-03 00:13:44 +02:00
enum
{
2018-08-03 00:24:10 +02:00
CANCELLER_FLAGS ,
CANCELLER_ASLEEP ,
CANCELLER_FROZEN ,
CANCELLER_TRUANT ,
CANCELLER_RECHARGE ,
CANCELLER_FLINCH ,
CANCELLER_DISABLED ,
CANCELLER_TAUNTED ,
CANCELLER_IMPRISONED ,
CANCELLER_CONFUSED ,
CANCELLER_PARALYSED ,
CANCELLER_IN_LOVE ,
CANCELLER_BIDE ,
CANCELLER_THAW ,
CANCELLER_END ,
2018-08-03 00:13:44 +02:00
} ;
2017-09-17 14:10:32 +02:00
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 )
{
2018-08-03 00:13:44 +02:00
case CANCELLER_FLAGS : // 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 ;
2018-08-03 00:13:44 +02:00
case CANCELLER_ASLEEP : // 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 ;
2018-08-03 00:13:44 +02:00
case CANCELLER_FROZEN : // 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 ;
2018-08-03 00:13:44 +02:00
case CANCELLER_TRUANT : // 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 ;
2018-08-03 00:13:44 +02:00
case CANCELLER_RECHARGE : // 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 ) ;
2018-10-14 18:10:54 +02:00
gDisableStructs [ gBattlerAttacker ] . rechargeTimer = 0 ;
2018-02-06 23:09:39 +01:00
CancelMultiTurnMoves ( gBattlerAttacker ) ;
2017-09-17 14:10:32 +02:00
gBattlescriptCurrInstr = BattleScript_MoveUsedMustRecharge ;
gHitMarker | = HITMARKER_UNABLE_TO_USE_MOVE ;
effect = 1 ;
}
gBattleStruct - > atkCancellerTracker + + ;
break ;
2018-08-03 00:13:44 +02:00
case CANCELLER_FLINCH : // 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 ;
2018-08-03 00:13:44 +02:00
case CANCELLER_DISABLED : // 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 ;
2018-08-03 00:13:44 +02:00
case CANCELLER_TAUNTED : // taunt
2018-10-14 18:10:54 +02:00
if ( gDisableStructs [ gBattlerAttacker ] . tauntTimer & & 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 ;
2018-08-03 00:13:44 +02:00
case CANCELLER_IMPRISONED : // imprisoned
2018-02-06 23:09:39 +01:00
if ( GetImprisonedMovesCount ( gBattlerAttacker , gCurrentMove ) )
2017-09-17 14:10:32 +02:00
{
2019-03-02 23:40:38 +01:00
gProtectStructs [ gBattlerAttacker ] . usedImprisonedMove = 1 ;
2018-02-06 23:09:39 +01:00
CancelMultiTurnMoves ( gBattlerAttacker ) ;
2017-09-17 14:10:32 +02:00
gBattlescriptCurrInstr = BattleScript_MoveUsedIsImprisoned ;
gHitMarker | = HITMARKER_UNABLE_TO_USE_MOVE ;
effect = 1 ;
}
gBattleStruct - > atkCancellerTracker + + ;
break ;
2018-08-03 00:13:44 +02:00
case CANCELLER_CONFUSED : // confusion
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_CONFUSION )
2017-09-17 14:10:32 +02:00
{
2020-07-17 02:12:12 +02:00
gBattleMons [ gBattlerAttacker ] . status2 - = STATUS2_CONFUSION_TURN ( 1 ) ;
2018-02-06 23:09:39 +01:00
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 ;
2018-08-03 00:13:44 +02:00
case CANCELLER_PARALYSED : // 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 ;
2018-08-03 00:13:44 +02:00
case CANCELLER_IN_LOVE : // infatuation
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_INFATUATION )
2017-09-17 14:10:32 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleScripting . battler = CountTrailingZeroBits ( ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_INFATUATION ) > > 0x10 ) ;
2017-09-17 14:10:32 +02:00
if ( Random ( ) & 1 )
2018-07-01 11:15:42 +02:00
{
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2018-07-01 11:15:42 +02:00
}
2017-09-17 14:10:32 +02:00
else
{
2019-03-05 17:06:29 +01:00
BattleScriptPush ( BattleScript_MoveUsedIsInLoveCantAttack ) ;
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 ;
2018-08-03 00:13:44 +02:00
case CANCELLER_BIDE : // bide
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_BIDE )
2017-09-17 14:10:32 +02:00
{
2020-07-17 02:12:12 +02:00
gBattleMons [ gBattlerAttacker ] . status2 - = STATUS2_BIDE_TURN ( 1 ) ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_BIDE )
2018-07-01 11:15:42 +02:00
{
2017-09-17 14:10:32 +02:00
gBattlescriptCurrInstr = BattleScript_BideStoringEnergy ;
2018-07-01 11:15:42 +02:00
}
2017-09-17 14:10:32 +02:00
else
{
// This is removed in Emerald for some reason
2018-02-06 23:09:39 +01:00
//gBattleMons[gBattlerAttacker].status2 &= ~(STATUS2_MULTIPLETURNS);
if ( gTakenDmg [ gBattlerAttacker ] )
2017-09-17 14:10:32 +02:00
{
gCurrentMove = MOVE_BIDE ;
2018-02-06 23:09:39 +01:00
* bideDmg = gTakenDmg [ gBattlerAttacker ] * 2 ;
2018-02-07 22:53:40 +01:00
gBattlerTarget = gTakenDmgByBattler [ gBattlerAttacker ] ;
2018-02-06 23:09:39 +01:00
if ( gAbsentBattlerFlags & gBitTable [ gBattlerTarget ] )
gBattlerTarget = GetMoveTarget ( MOVE_BIDE , 1 ) ;
2017-09-17 14:10:32 +02:00
gBattlescriptCurrInstr = BattleScript_BideAttack ;
}
else
2018-07-01 11:15:42 +02:00
{
2017-09-17 14:10:32 +02:00
gBattlescriptCurrInstr = BattleScript_BideNoEnergyToAttack ;
2018-07-01 11:15:42 +02:00
}
2017-09-17 14:10:32 +02:00
}
effect = 1 ;
}
gBattleStruct - > atkCancellerTracker + + ;
break ;
2018-08-03 00:13:44 +02:00
case CANCELLER_THAW : // 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 ;
2018-08-03 00:13:44 +02:00
case CANCELLER_END :
2017-09-17 14:10:32 +02:00
break ;
}
2018-08-03 00:13:44 +02:00
} while ( gBattleStruct - > atkCancellerTracker ! = CANCELLER_END & & effect = = 0 ) ;
2017-09-17 14:10:32 +02:00
if ( effect = = 2 )
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gActiveBattler ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-17 14:10:32 +02:00
}
return effect ;
}
2017-09-17 15:19:15 +02:00
2018-07-01 11:15:42 +02:00
bool8 HasNoMonsToSwitch ( u8 battler , u8 partyIdBattlerOn1 , u8 partyIdBattlerOn2 )
2017-09-17 15:19:15 +02:00
{
2018-07-01 11:15:42 +02:00
struct Pokemon * party ;
u8 id1 , id2 ;
2017-09-17 15:19:15 +02:00
s32 i ;
2018-07-01 11:15:42 +02:00
2017-09-17 15:19:15 +02:00
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE ) )
return FALSE ;
2018-07-01 11:15:42 +02:00
2017-09-17 15:19:15 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER )
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( battler ) = = B_SIDE_PLAYER )
2017-09-17 15:19:15 +02:00
party = gPlayerParty ;
else
party = gEnemyParty ;
2018-07-01 11:15:42 +02:00
id1 = ( ( battler & BIT_FLANK ) / 2 ) ;
for ( i = id1 * 3 ; i < id1 * 3 + 3 ; i + + )
2017-09-17 15:19:15 +02:00
{
if ( GetMonData ( & party [ i ] , MON_DATA_HP ) ! = 0
2018-07-01 11:15:42 +02:00
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = SPECIES_NONE
2017-09-17 15:19:15 +02:00
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = SPECIES_EGG )
break ;
}
2018-07-01 11:15:42 +02:00
return ( i = = id1 * 3 + 3 ) ;
2017-09-17 15:19:15 +02:00
}
else if ( gBattleTypeFlags & BATTLE_TYPE_MULTI )
{
2021-01-13 21:17:32 +01:00
if ( gBattleTypeFlags & BATTLE_TYPE_TOWER_LINK_MULTI )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( battler ) = = B_SIDE_PLAYER )
2017-09-17 15:19:15 +02:00
{
party = gPlayerParty ;
2018-07-01 11:15:42 +02:00
id2 = GetBattlerMultiplayerId ( battler ) ;
id1 = GetLinkTrainerFlankId ( id2 ) ;
2017-09-17 15:19:15 +02:00
}
else
{
party = gEnemyParty ;
2020-10-26 04:45:42 +01:00
if ( battler = = 1 )
2018-07-01 11:15:42 +02:00
id1 = 0 ;
else
id1 = 1 ;
2017-09-17 15:19:15 +02:00
}
}
else
{
2018-07-01 11:15:42 +02:00
id2 = GetBattlerMultiplayerId ( battler ) ;
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( battler ) = = B_SIDE_PLAYER )
2017-09-17 15:19:15 +02:00
party = gPlayerParty ;
else
party = gEnemyParty ;
2018-07-01 11:15:42 +02:00
id1 = GetLinkTrainerFlankId ( id2 ) ;
2017-09-17 15:19:15 +02:00
}
2018-07-01 11:15:42 +02:00
for ( i = id1 * 3 ; i < id1 * 3 + 3 ; i + + )
2017-09-17 15:19:15 +02:00
{
if ( GetMonData ( & party [ i ] , MON_DATA_HP ) ! = 0
2018-07-01 11:15:42 +02:00
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = SPECIES_NONE
2017-09-17 15:19:15 +02:00
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = SPECIES_EGG )
break ;
}
2018-07-01 11:15:42 +02:00
return ( i = = id1 * 3 + 3 ) ;
2017-09-17 15:19:15 +02:00
}
2018-02-06 02:46:59 +01:00
else if ( ( gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS ) & & GetBattlerSide ( battler ) = = B_SIDE_OPPONENT )
2017-09-17 15:19:15 +02:00
{
party = gEnemyParty ;
2018-02-06 02:46:59 +01:00
if ( battler = = 1 )
2018-07-01 11:15:42 +02:00
id1 = 0 ;
2017-09-17 15:19:15 +02:00
else
2018-07-01 11:15:42 +02:00
id1 = 3 ;
for ( i = id1 ; i < id1 + 3 ; i + + )
2017-09-17 15:19:15 +02:00
{
if ( GetMonData ( & party [ i ] , MON_DATA_HP ) ! = 0
2018-07-01 11:15:42 +02:00
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = SPECIES_NONE
2017-09-17 15:19:15 +02:00
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = SPECIES_EGG )
break ;
}
2018-07-01 11:15:42 +02:00
return ( i = = id1 + 3 ) ;
2017-09-17 15:19:15 +02:00
}
else
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( battler ) = = B_SIDE_OPPONENT )
2017-09-17 15:19:15 +02:00
{
2018-07-01 11:15:42 +02:00
id2 = GetBattlerAtPosition ( B_POSITION_OPPONENT_LEFT ) ;
id1 = GetBattlerAtPosition ( B_POSITION_OPPONENT_RIGHT ) ;
2017-09-17 15:19:15 +02:00
party = gEnemyParty ;
}
else
{
2018-07-01 11:15:42 +02:00
id2 = GetBattlerAtPosition ( B_POSITION_PLAYER_LEFT ) ;
id1 = GetBattlerAtPosition ( B_POSITION_PLAYER_RIGHT ) ;
2017-09-17 15:19:15 +02:00
party = gPlayerParty ;
}
2018-07-01 11:15:42 +02:00
if ( partyIdBattlerOn1 = = PARTY_SIZE )
partyIdBattlerOn1 = gBattlerPartyIndexes [ id2 ] ;
if ( partyIdBattlerOn2 = = PARTY_SIZE )
partyIdBattlerOn2 = gBattlerPartyIndexes [ id1 ] ;
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2017-09-17 15:19:15 +02:00
{
if ( GetMonData ( & party [ i ] , MON_DATA_HP ) ! = 0
2018-07-01 11:15:42 +02:00
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = SPECIES_NONE
2017-09-17 15:19:15 +02:00
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ! = SPECIES_EGG
2018-07-01 11:15:42 +02:00
& & i ! = partyIdBattlerOn1 & & i ! = partyIdBattlerOn2
& & i ! = * ( gBattleStruct - > monToSwitchIntoId + id2 ) & & i ! = id1 [ gBattleStruct - > monToSwitchIntoId ] )
2017-09-17 15:19:15 +02:00
break ;
}
2018-07-01 11:15:42 +02:00
return ( i = = PARTY_SIZE ) ;
2017-09-17 15:19:15 +02:00
}
}
enum
{
CASTFORM_NO_CHANGE , //0
CASTFORM_TO_NORMAL , //1
CASTFORM_TO_FIRE , //2
CASTFORM_TO_WATER , //3
CASTFORM_TO_ICE , //4
} ;
2018-02-06 02:46:59 +01:00
u8 CastformDataTypeChange ( u8 battler )
2017-09-17 15:19:15 +02:00
{
u8 formChange = 0 ;
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . species ! = SPECIES_CASTFORM | | gBattleMons [ battler ] . ability ! = ABILITY_FORECAST | | gBattleMons [ battler ] . hp = = 0 )
2017-09-17 15:19:15 +02:00
return CASTFORM_NO_CHANGE ;
2018-03-01 00:59:52 +01:00
if ( ! WEATHER_HAS_EFFECT & & ! IS_BATTLER_OF_TYPE ( battler , TYPE_NORMAL ) )
2017-09-17 15:19:15 +02:00
{
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE ( battler , TYPE_NORMAL ) ;
2017-09-17 15:19:15 +02:00
return CASTFORM_TO_NORMAL ;
}
if ( ! WEATHER_HAS_EFFECT )
return CASTFORM_NO_CHANGE ;
2018-03-01 00:59:52 +01:00
if ( ! ( gBattleWeather & ( WEATHER_RAIN_ANY | WEATHER_SUN_ANY | WEATHER_HAIL_ANY ) ) & & ! IS_BATTLER_OF_TYPE ( battler , TYPE_NORMAL ) )
2017-09-17 15:19:15 +02:00
{
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE ( battler , TYPE_NORMAL ) ;
2017-09-17 15:19:15 +02:00
formChange = CASTFORM_TO_NORMAL ;
}
2018-03-01 00:59:52 +01:00
if ( gBattleWeather & WEATHER_SUN_ANY & & ! IS_BATTLER_OF_TYPE ( battler , TYPE_FIRE ) )
2017-09-17 15:19:15 +02:00
{
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE ( battler , TYPE_FIRE ) ;
2017-09-17 15:19:15 +02:00
formChange = CASTFORM_TO_FIRE ;
}
2018-03-01 00:59:52 +01:00
if ( gBattleWeather & WEATHER_RAIN_ANY & & ! IS_BATTLER_OF_TYPE ( battler , TYPE_WATER ) )
2017-09-17 15:19:15 +02:00
{
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE ( battler , TYPE_WATER ) ;
2017-09-17 15:19:15 +02:00
formChange = CASTFORM_TO_WATER ;
}
2018-03-01 00:59:52 +01:00
if ( gBattleWeather & WEATHER_HAIL_ANY & & ! IS_BATTLER_OF_TYPE ( battler , TYPE_ICE ) )
2017-09-17 15:19:15 +02:00
{
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE ( battler , TYPE_ICE ) ;
2017-09-17 15:19:15 +02:00
formChange = CASTFORM_TO_ICE ;
}
return formChange ;
}
2017-10-12 17:49:24 +02:00
// The largest function in the game, but even it could not save itself from decompiling.
2018-02-06 02:46:59 +01:00
u8 AbilityBattleEffects ( u8 caseID , u8 battler , u8 ability , u8 special , u16 moveArg )
2017-09-17 15:19:15 +02:00
{
u8 effect = 0 ;
2017-10-12 17:49:24 +02:00
struct Pokemon * pokeAtk ;
struct Pokemon * pokeDef ;
2017-09-17 15:19:15 +02:00
u16 speciesAtk ;
u16 speciesDef ;
u32 pidAtk ;
u32 pidDef ;
2018-02-06 23:09:39 +01:00
if ( gBattlerAttacker > = gBattlersCount )
gBattlerAttacker = battler ;
2018-07-01 11:15:42 +02:00
2018-02-06 23:09:39 +01:00
if ( GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_PLAYER )
pokeAtk = & gPlayerParty [ gBattlerPartyIndexes [ gBattlerAttacker ] ] ;
2017-09-17 15:19:15 +02:00
else
2018-02-06 23:09:39 +01:00
pokeAtk = & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ] ] ;
2017-09-17 15:19:15 +02:00
2018-02-06 23:09:39 +01:00
if ( gBattlerTarget > = gBattlersCount )
gBattlerTarget = battler ;
2018-07-01 11:15:42 +02:00
2018-02-06 23:09:39 +01:00
if ( GetBattlerSide ( gBattlerTarget ) = = B_SIDE_PLAYER )
pokeDef = & gPlayerParty [ gBattlerPartyIndexes [ gBattlerTarget ] ] ;
2017-09-17 15:19:15 +02:00
else
2018-02-06 23:09:39 +01:00
pokeDef = & gEnemyParty [ gBattlerPartyIndexes [ gBattlerTarget ] ] ;
2017-09-17 15:19:15 +02:00
speciesAtk = GetMonData ( pokeAtk , MON_DATA_SPECIES ) ;
pidAtk = GetMonData ( pokeAtk , MON_DATA_PERSONALITY ) ;
speciesDef = GetMonData ( pokeDef , MON_DATA_SPECIES ) ;
pidDef = GetMonData ( pokeDef , MON_DATA_PERSONALITY ) ;
2018-07-01 11:15:42 +02:00
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_SAFARI ) ) // Why isn't that check done at the beginning?
2017-09-17 15:19:15 +02:00
{
2017-10-12 17:49:24 +02:00
u8 moveType ;
s32 i ;
2017-09-17 15:19:15 +02:00
u16 move ;
u8 side ;
2017-10-12 17:49:24 +02:00
u8 target1 ;
2017-09-17 15:19:15 +02:00
if ( special )
gLastUsedAbility = special ;
else
2018-02-06 02:46:59 +01:00
gLastUsedAbility = gBattleMons [ battler ] . ability ;
2017-09-17 15:19:15 +02:00
if ( moveArg )
move = moveArg ;
else
move = gCurrentMove ;
2017-11-26 13:26:58 +01:00
GET_MOVE_TYPE ( move , moveType ) ;
2017-09-17 15:19:15 +02:00
switch ( caseID )
{
case ABILITYEFFECT_ON_SWITCHIN : // 0
2018-02-06 23:09:39 +01:00
if ( gBattlerAttacker > = gBattlersCount )
gBattlerAttacker = battler ;
2017-09-17 15:19:15 +02:00
switch ( gLastUsedAbility )
2017-09-18 23:44:55 +02:00
{
2017-10-02 23:32:39 +02:00
case ABILITYEFFECT_SWITCH_IN_WEATHER :
2017-10-12 17:49:24 +02:00
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_RECORDED ) )
2017-09-18 23:44:55 +02:00
{
2018-12-08 19:05:03 +01:00
switch ( GetCurrentWeather ( ) )
2017-09-17 15:19:15 +02:00
{
2019-12-02 01:19:47 +01:00
case WEATHER_RAIN :
case WEATHER_RAIN_THUNDERSTORM :
case WEATHER_DOWNPOUR :
2017-10-12 17:49:24 +02:00
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 ;
2018-12-08 19:43:21 +01:00
case WEATHER_SANDSTORM :
2017-10-12 17:49:24 +02:00
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 ;
2018-12-08 19:43:21 +01:00
case WEATHER_DROUGHT :
2017-10-12 17:49:24 +02:00
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
{
2018-12-08 19:05:03 +01:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = GetCurrentWeather ( ) ;
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-07-16 20:47:30 +02:00
if ( ! ( gSpecialStatuses [ battler ] . intimidatedMon ) )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
gStatuses3 [ battler ] | = STATUS3_INTIMIDATE_POKES ;
2018-07-16 20:47:30 +02:00
gSpecialStatuses [ battler ] . intimidatedMon = 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 :
2020-08-05 02:33:05 +02:00
if ( gBattleMons [ battler ] . statStages [ STAT_SPEED ] < MAX_STAT_STAGE & & gDisableStructs [ battler ] . isFirstTurn ! = 2 )
2017-09-17 15:19:15 +02:00
{
2018-02-08 12:13:29 +01:00
gBattleMons [ battler ] . statStages [ STAT_SPEED ] + + ;
2017-09-17 15:19:15 +02:00
gBattleScripting . animArg1 = 0x11 ;
gBattleScripting . animArg2 = 0 ;
2017-09-28 15:34:21 +02:00
BattleScriptPushCursorAndCallback ( BattleScript_SpeedBoostActivates ) ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = battler ;
2017-09-17 15:19:15 +02:00
effect + + ;
}
break ;
case ABILITY_TRUANT :
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerAttacker ] . truantCounter ^ = 1 ;
2017-09-17 15:19:15 +02:00
break ;
}
}
break ;
case ABILITYEFFECT_MOVES_BLOCK : // 2
if ( gLastUsedAbility = = ABILITY_SOUNDPROOF )
{
2017-10-06 19:09:37 +02:00
for ( i = 0 ; sSoundMovesTable [ i ] ! = 0xFFFF ; i + + )
2017-09-17 15:19:15 +02:00
{
2017-10-06 19:09:37 +02:00
if ( sSoundMovesTable [ i ] = = move )
2017-09-17 15:19:15 +02:00
break ;
}
2017-10-06 19:09:37 +02:00
if ( sSoundMovesTable [ i ] ! = 0xFFFF )
2017-09-17 15:19:15 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_MULTIPLETURNS )
2017-09-17 15:19:15 +02:00
gHitMarker | = HITMARKER_NO_PPDEDUCT ;
gBattlescriptCurrInstr = BattleScript_SoundproofProtected ;
effect = 1 ;
}
}
break ;
case ABILITYEFFECT_ABSORBING : // 3
if ( move )
{
switch ( gLastUsedAbility )
{
case ABILITY_VOLT_ABSORB :
if ( moveType = = TYPE_ELECTRIC & & gBattleMoves [ move ] . power ! = 0 )
{
2018-02-06 23:09:39 +01:00
if ( gProtectStructs [ gBattlerAttacker ] . notFirstStrike )
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_MoveHPDrain ;
else
gBattlescriptCurrInstr = BattleScript_MoveHPDrain_PPLoss ;
2017-10-12 17:49:24 +02:00
2017-09-17 15:19:15 +02:00
effect = 1 ;
}
break ;
case ABILITY_WATER_ABSORB :
if ( moveType = = TYPE_WATER & & gBattleMoves [ move ] . power ! = 0 )
{
2018-02-06 23:09:39 +01:00
if ( gProtectStructs [ gBattlerAttacker ] . notFirstStrike )
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_MoveHPDrain ;
else
gBattlescriptCurrInstr = BattleScript_MoveHPDrain_PPLoss ;
2017-10-12 17:49:24 +02:00
2017-09-17 15:19:15 +02:00
effect = 1 ;
}
break ;
case ABILITY_FLASH_FIRE :
2018-02-06 02:46:59 +01:00
if ( moveType = = TYPE_FIRE & & ! ( gBattleMons [ battler ] . status1 & STATUS1_FREEZE ) )
2017-09-17 15:19:15 +02:00
{
2019-04-04 23:53:06 +02:00
if ( ! ( gBattleResources - > flags - > flags [ battler ] & RESOURCE_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
2019-04-04 23:53:06 +02:00
gBattleResources - > flags - > flags [ battler ] | = RESOURCE_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 ;
2019-09-27 18:27:36 +02:00
case ABILITYEFFECT_ON_DAMAGE : // Contact abilities and Color Change
2017-09-17 15:19:15 +02:00
switch ( gLastUsedAbility )
{
case ABILITY_COLOR_CHANGE :
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2017-09-17 15:19:15 +02:00
& & move ! = MOVE_STRUGGLE
& & gBattleMoves [ move ] . power ! = 0
2018-03-01 00:59:52 +01:00
& & TARGET_TURN_DAMAGED
& & ! IS_BATTLER_OF_TYPE ( battler , moveType )
2018-02-06 02:46:59 +01:00
& & gBattleMons [ battler ] . hp ! = 0 )
2017-09-17 15:19:15 +02:00
{
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE ( battler , moveType ) ;
PREPARE_TYPE_BUFFER ( gBattleTextBuff1 , moveType ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_ColorChangeActivates ;
effect + + ;
}
break ;
case ABILITY_ROUGH_SKIN :
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2018-02-06 23:09:39 +01:00
& & gBattleMons [ gBattlerAttacker ] . hp ! = 0
& & ! gProtectStructs [ gBattlerAttacker ] . confusionSelfDmg
2018-03-01 00:59:52 +01:00
& & TARGET_TURN_DAMAGED
2017-09-17 15:19:15 +02:00
& & ( gBattleMoves [ move ] . flags & FLAG_MAKES_CONTACT ) )
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . maxHP / 16 ;
2017-09-17 15:19:15 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_RoughSkinActivates ;
effect + + ;
}
break ;
case ABILITY_EFFECT_SPORE :
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2018-02-06 23:09:39 +01:00
& & gBattleMons [ gBattlerAttacker ] . hp ! = 0
& & ! gProtectStructs [ gBattlerAttacker ] . confusionSelfDmg
2018-03-01 00:59:52 +01:00
& & TARGET_TURN_DAMAGED
2017-09-17 15:19:15 +02:00
& & ( gBattleMoves [ move ] . flags & FLAG_MAKES_CONTACT )
& & ( Random ( ) % 10 ) = = 0 )
{
do
{
gBattleCommunication [ MOVE_EFFECT_BYTE ] = Random ( ) & 3 ;
} while ( gBattleCommunication [ MOVE_EFFECT_BYTE ] = = 0 ) ;
2017-10-12 17:49:24 +02:00
if ( gBattleCommunication [ MOVE_EFFECT_BYTE ] = = MOVE_EFFECT_BURN )
gBattleCommunication [ MOVE_EFFECT_BYTE ] + = 2 ; // 5 MOVE_EFFECT_PARALYSIS
gBattleCommunication [ MOVE_EFFECT_BYTE ] + = MOVE_EFFECT_AFFECTS_USER ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect ;
gHitMarker | = HITMARKER_IGNORE_SAFEGUARD ;
effect + + ;
}
break ;
case ABILITY_POISON_POINT :
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2018-02-06 23:09:39 +01:00
& & gBattleMons [ gBattlerAttacker ] . hp ! = 0
& & ! gProtectStructs [ gBattlerAttacker ] . confusionSelfDmg
2018-03-01 00:59:52 +01:00
& & TARGET_TURN_DAMAGED
2017-09-17 15:19:15 +02:00
& & ( gBattleMoves [ move ] . flags & FLAG_MAKES_CONTACT )
& & ( Random ( ) % 3 ) = = 0 )
{
2017-10-12 17:49:24 +02:00
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_POISON ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect ;
gHitMarker | = HITMARKER_IGNORE_SAFEGUARD ;
effect + + ;
}
break ;
case ABILITY_STATIC :
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2018-02-06 23:09:39 +01:00
& & gBattleMons [ gBattlerAttacker ] . hp ! = 0
& & ! gProtectStructs [ gBattlerAttacker ] . confusionSelfDmg
2018-03-01 00:59:52 +01:00
& & TARGET_TURN_DAMAGED
2017-09-17 15:19:15 +02:00
& & ( gBattleMoves [ move ] . flags & FLAG_MAKES_CONTACT )
& & ( Random ( ) % 3 ) = = 0 )
{
2017-10-12 17:49:24 +02:00
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_PARALYSIS ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect ;
gHitMarker | = HITMARKER_IGNORE_SAFEGUARD ;
effect + + ;
}
break ;
case ABILITY_FLAME_BODY :
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2018-02-06 23:09:39 +01:00
& & gBattleMons [ gBattlerAttacker ] . hp ! = 0
& & ! gProtectStructs [ gBattlerAttacker ] . confusionSelfDmg
2017-09-17 15:19:15 +02:00
& & ( gBattleMoves [ move ] . flags & FLAG_MAKES_CONTACT )
2018-03-01 00:59:52 +01:00
& & TARGET_TURN_DAMAGED
2017-09-17 15:19:15 +02:00
& & ( Random ( ) % 3 ) = = 0 )
{
2017-10-12 17:49:24 +02:00
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_BURN ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect ;
gHitMarker | = HITMARKER_IGNORE_SAFEGUARD ;
effect + + ;
}
break ;
case ABILITY_CUTE_CHARM :
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2018-02-06 23:09:39 +01:00
& & gBattleMons [ gBattlerAttacker ] . hp ! = 0
& & ! gProtectStructs [ gBattlerAttacker ] . confusionSelfDmg
2017-09-17 15:19:15 +02:00
& & ( gBattleMoves [ move ] . flags & FLAG_MAKES_CONTACT )
2018-03-01 00:59:52 +01:00
& & TARGET_TURN_DAMAGED
2018-02-06 23:09:39 +01:00
& & gBattleMons [ gBattlerTarget ] . hp ! = 0
2017-09-17 15:19:15 +02:00
& & ( Random ( ) % 3 ) = = 0
2018-02-06 23:09:39 +01:00
& & gBattleMons [ gBattlerAttacker ] . ability ! = ABILITY_OBLIVIOUS
2017-09-17 15:19:15 +02:00
& & GetGenderFromSpeciesAndPersonality ( speciesAtk , pidAtk ) ! = GetGenderFromSpeciesAndPersonality ( speciesDef , pidDef )
2018-02-06 23:09:39 +01:00
& & ! ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_INFATUATION )
2017-10-12 17:49:24 +02:00
& & GetGenderFromSpeciesAndPersonality ( speciesAtk , pidAtk ) ! = MON_GENDERLESS
& & GetGenderFromSpeciesAndPersonality ( speciesDef , pidDef ) ! = MON_GENDERLESS )
2017-09-17 15:19:15 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 | = STATUS2_INFATUATED_WITH ( gBattlerTarget ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_CuteCharmActivates ;
effect + + ;
}
break ;
}
break ;
case ABILITYEFFECT_IMMUNITY : // 5
2018-02-06 02:46:59 +01:00
for ( battler = 0 ; battler < gBattlersCount ; battler + + )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
switch ( gBattleMons [ battler ] . ability )
2017-09-17 15:19:15 +02:00
{
2017-11-26 17:15:28 +01:00
case ABILITY_IMMUNITY :
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . status1 & ( STATUS1_POISON | STATUS1_TOXIC_POISON | STATUS1_TOXIC_COUNTER ) )
2017-09-17 15:19:15 +02:00
{
2017-11-26 17:15:28 +01:00
StringCopy ( gBattleTextBuff1 , gStatusConditionString_PoisonJpn ) ;
effect = 1 ;
}
break ;
case ABILITY_OWN_TEMPO :
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . status2 & STATUS2_CONFUSION )
2017-11-26 17:15:28 +01:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_ConfusionJpn ) ;
effect = 2 ;
}
break ;
case ABILITY_LIMBER :
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . status1 & STATUS1_PARALYSIS )
2017-11-26 17:15:28 +01:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_ParalysisJpn ) ;
effect = 1 ;
}
break ;
case ABILITY_INSOMNIA :
case ABILITY_VITAL_SPIRIT :
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . status1 & STATUS1_SLEEP )
2017-11-26 17:15:28 +01:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ battler ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
2017-11-26 17:15:28 +01:00
StringCopy ( gBattleTextBuff1 , gStatusConditionString_SleepJpn ) ;
effect = 1 ;
}
break ;
case ABILITY_WATER_VEIL :
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . status1 & STATUS1_BURN )
2017-11-26 17:15:28 +01:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_BurnJpn ) ;
effect = 1 ;
}
break ;
case ABILITY_MAGMA_ARMOR :
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . status1 & STATUS1_FREEZE )
2017-11-26 17:15:28 +01:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_IceJpn ) ;
effect = 1 ;
}
break ;
case ABILITY_OBLIVIOUS :
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . status2 & STATUS2_INFATUATION )
2017-11-26 17:15:28 +01:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_LoveJpn ) ;
effect = 3 ;
}
break ;
}
if ( effect )
{
switch ( effect )
{
case 1 : // status cleared
2018-02-06 02:46:59 +01:00
gBattleMons [ battler ] . status1 = 0 ;
2017-09-17 15:19:15 +02:00
break ;
2017-11-26 17:15:28 +01:00
case 2 : // get rid of confusion
2018-02-06 02:46:59 +01:00
gBattleMons [ battler ] . status2 & = ~ ( STATUS2_CONFUSION ) ;
2017-09-17 15:19:15 +02:00
break ;
2017-11-26 17:15:28 +01:00
case 3 : // get rid of infatuation
2018-02-06 02:46:59 +01:00
gBattleMons [ battler ] . status2 & = ~ ( STATUS2_INFATUATION ) ;
2017-09-17 15:19:15 +02:00
break ;
}
2017-10-12 17:49:24 +02:00
2017-11-26 17:15:28 +01:00
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_AbilityCuredStatus ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = battler ;
gActiveBattler = battler ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gActiveBattler ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-11-26 17:15:28 +01:00
return effect ;
2017-09-17 15:19:15 +02:00
}
}
break ;
case ABILITYEFFECT_FORECAST : // 6
2018-02-06 02:46:59 +01:00
for ( battler = 0 ; battler < gBattlersCount ; battler + + )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ battler ] . ability = = ABILITY_FORECAST )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
effect = CastformDataTypeChange ( battler ) ;
2017-10-12 17:49:24 +02:00
if ( effect )
2017-09-17 15:19:15 +02:00
{
2017-10-12 17:49:24 +02:00
BattleScriptPushCursorAndCallback ( BattleScript_CastformChange ) ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = battler ;
2017-10-12 17:49:24 +02:00
* ( & gBattleStruct - > formToChangeInto ) = effect - 1 ;
return effect ;
2017-09-17 15:19:15 +02:00
}
}
}
break ;
case ABILITYEFFECT_SYNCHRONIZE : // 7
if ( gLastUsedAbility = = ABILITY_SYNCHRONIZE & & ( gHitMarker & HITMARKER_SYNCHRONISE_EFFECT ) )
{
gHitMarker & = ~ ( HITMARKER_SYNCHRONISE_EFFECT ) ;
2017-10-12 17:49:24 +02:00
gBattleStruct - > synchronizeMoveEffect & = ~ ( MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN ) ;
if ( gBattleStruct - > synchronizeMoveEffect = = MOVE_EFFECT_TOXIC )
gBattleStruct - > synchronizeMoveEffect = MOVE_EFFECT_POISON ;
gBattleCommunication [ MOVE_EFFECT_BYTE ] = gBattleStruct - > synchronizeMoveEffect + MOVE_EFFECT_AFFECTS_USER ;
2018-02-06 23:09:39 +01:00
gBattleScripting . battler = gBattlerTarget ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_SynchronizeActivates ;
gHitMarker | = HITMARKER_IGNORE_SAFEGUARD ;
effect + + ;
}
break ;
case ABILITYEFFECT_ATK_SYNCHRONIZE : // 8
if ( gLastUsedAbility = = ABILITY_SYNCHRONIZE & & ( gHitMarker & HITMARKER_SYNCHRONISE_EFFECT ) )
{
gHitMarker & = ~ ( HITMARKER_SYNCHRONISE_EFFECT ) ;
2017-10-12 17:49:24 +02:00
gBattleStruct - > synchronizeMoveEffect & = ~ ( MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN ) ;
if ( gBattleStruct - > synchronizeMoveEffect = = MOVE_EFFECT_TOXIC )
gBattleStruct - > synchronizeMoveEffect = MOVE_EFFECT_POISON ;
2017-09-17 15:19:15 +02:00
gBattleCommunication [ MOVE_EFFECT_BYTE ] = gBattleStruct - > synchronizeMoveEffect ;
2018-02-06 23:09:39 +01:00
gBattleScripting . battler = gBattlerAttacker ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 15:19:15 +02:00
gBattlescriptCurrInstr = BattleScript_SynchronizeActivates ;
gHitMarker | = HITMARKER_IGNORE_SAFEGUARD ;
effect + + ;
}
break ;
case ABILITYEFFECT_INTIMIDATE1 : // 9
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
if ( gBattleMons [ i ] . ability = = ABILITY_INTIMIDATE & & gStatuses3 [ i ] & STATUS3_INTIMIDATE_POKES )
{
gLastUsedAbility = ABILITY_INTIMIDATE ;
gStatuses3 [ i ] & = ~ ( STATUS3_INTIMIDATE_POKES ) ;
2018-09-01 20:00:13 +02:00
BattleScriptPushCursorAndCallback ( BattleScript_IntimidateActivatesEnd3 ) ;
2018-07-01 11:15:42 +02:00
gBattleStruct - > intimidateBattler = i ;
2017-09-17 15:19:15 +02:00
effect + + ;
break ;
}
}
break ;
case ABILITYEFFECT_TRACE : // 11
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
if ( gBattleMons [ i ] . ability = = ABILITY_TRACE & & ( gStatuses3 [ i ] & STATUS3_TRACE ) )
{
2017-10-12 17:49:24 +02:00
u8 target2 ;
2018-02-06 02:46:59 +01:00
side = ( GetBattlerPosition ( i ) ^ BIT_SIDE ) & BIT_SIDE ; // side of the opposing pokemon
target1 = GetBattlerAtPosition ( side ) ;
target2 = GetBattlerAtPosition ( side + BIT_FLANK ) ;
2017-09-17 15:19:15 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
{
if ( gBattleMons [ target1 ] . ability ! = 0 & & gBattleMons [ target1 ] . hp ! = 0
& & gBattleMons [ target2 ] . ability ! = 0 & & gBattleMons [ target2 ] . hp ! = 0 )
{
2018-02-06 02:46:59 +01:00
gActiveBattler = GetBattlerAtPosition ( ( ( Random ( ) & 1 ) * 2 ) | side ) ;
gBattleMons [ i ] . ability = gBattleMons [ gActiveBattler ] . ability ;
gLastUsedAbility = gBattleMons [ gActiveBattler ] . ability ;
2017-09-17 15:19:15 +02:00
effect + + ;
}
else if ( gBattleMons [ target1 ] . ability ! = 0 & & gBattleMons [ target1 ] . hp ! = 0 )
{
2018-02-06 02:46:59 +01:00
gActiveBattler = target1 ;
gBattleMons [ i ] . ability = gBattleMons [ gActiveBattler ] . ability ;
gLastUsedAbility = gBattleMons [ gActiveBattler ] . ability ;
2017-09-17 15:19:15 +02:00
effect + + ;
}
else if ( gBattleMons [ target2 ] . ability ! = 0 & & gBattleMons [ target2 ] . hp ! = 0 )
{
2018-02-06 02:46:59 +01:00
gActiveBattler = target2 ;
gBattleMons [ i ] . ability = gBattleMons [ gActiveBattler ] . ability ;
gLastUsedAbility = gBattleMons [ gActiveBattler ] . ability ;
2017-09-17 15:19:15 +02:00
effect + + ;
}
}
else
{
2018-02-06 02:46:59 +01:00
gActiveBattler = target1 ;
2017-09-17 15:19:15 +02:00
if ( gBattleMons [ target1 ] . ability & & gBattleMons [ target1 ] . hp )
{
gBattleMons [ i ] . ability = gBattleMons [ target1 ] . ability ;
gLastUsedAbility = gBattleMons [ target1 ] . ability ;
effect + + ;
}
}
if ( effect )
{
2017-09-28 15:34:21 +02:00
BattleScriptPushCursorAndCallback ( BattleScript_TraceActivates ) ;
2017-09-17 15:19:15 +02:00
gStatuses3 [ i ] & = ~ ( STATUS3_TRACE ) ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = i ;
2017-09-17 15:19:15 +02:00
2018-02-06 20:48:02 +01:00
PREPARE_MON_NICK_WITH_PREFIX_BUFFER ( gBattleTextBuff1 , gActiveBattler , gBattlerPartyIndexes [ gActiveBattler ] )
2017-10-12 17:49:24 +02:00
PREPARE_ABILITY_BUFFER ( gBattleTextBuff2 , gLastUsedAbility )
2017-09-17 15:19:15 +02:00
break ;
}
}
}
break ;
case ABILITYEFFECT_INTIMIDATE2 : // 10
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
if ( gBattleMons [ i ] . ability = = ABILITY_INTIMIDATE & & ( gStatuses3 [ i ] & STATUS3_INTIMIDATE_POKES ) )
{
gLastUsedAbility = ABILITY_INTIMIDATE ;
gStatuses3 [ i ] & = ~ ( STATUS3_INTIMIDATE_POKES ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2018-09-01 20:00:13 +02:00
gBattlescriptCurrInstr = BattleScript_IntimidateActivates ;
2018-07-01 11:15:42 +02:00
gBattleStruct - > intimidateBattler = i ;
2017-09-17 15:19:15 +02:00
effect + + ;
break ;
}
}
break ;
case ABILITYEFFECT_CHECK_OTHER_SIDE : // 12
2018-02-06 02:46:59 +01:00
side = GetBattlerSide ( battler ) ;
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( i ) ! = side & & gBattleMons [ i ] . ability = = ability )
2017-09-17 15:19:15 +02:00
{
gLastUsedAbility = ability ;
effect = i + 1 ;
}
}
break ;
2018-07-01 11:15:42 +02:00
case ABILITYEFFECT_CHECK_BATTLER_SIDE : // 13
2018-02-06 02:46:59 +01:00
side = GetBattlerSide ( battler ) ;
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( i ) = = side & & gBattleMons [ i ] . ability = = ability )
2017-09-17 15:19:15 +02:00
{
gLastUsedAbility = ability ;
effect = i + 1 ;
}
}
break ;
case ABILITYEFFECT_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 ;
2018-07-01 11:15:42 +02:00
case ABILITYEFFECT_CHECK_FIELD_EXCEPT_BATTLER : // 15
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ i ] . ability = = ability & & i ! = battler )
2017-09-17 15:19:15 +02:00
{
gLastUsedAbility = ability ;
effect = i + 1 ;
}
}
break ;
2017-09-27 23:43:45 +02:00
case ABILITYEFFECT_COUNT_OTHER_SIDE : // 16
2018-02-06 02:46:59 +01:00
side = GetBattlerSide ( battler ) ;
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( i ) ! = side & & gBattleMons [ i ] . ability = = ability )
2017-09-17 15:19:15 +02:00
{
gLastUsedAbility = ability ;
effect + + ;
}
}
break ;
2018-07-01 11:15:42 +02:00
case ABILITYEFFECT_COUNT_BATTLER_SIDE : // 17
2018-02-06 02:46:59 +01:00
side = GetBattlerSide ( battler ) ;
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( i ) = = side & & gBattleMons [ i ] . ability = = ability )
2017-09-17 15:19:15 +02:00
{
gLastUsedAbility = ability ;
effect + + ;
}
}
break ;
case ABILITYEFFECT_COUNT_ON_FIELD : // 18
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-17 15:19:15 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ i ] . ability = = ability & & i ! = battler )
2017-09-17 15:19:15 +02:00
{
gLastUsedAbility = ability ;
effect + + ;
}
}
break ;
}
2017-10-12 17:49:24 +02:00
if ( effect & & caseID < ABILITYEFFECT_CHECK_OTHER_SIDE & & gLastUsedAbility ! = 0xFF )
2018-02-06 02:46:59 +01:00
RecordAbilityBattle ( battler , gLastUsedAbility ) ;
2017-09-17 15:19:15 +02:00
}
return effect ;
}
2017-09-17 17:14:32 +02:00
2017-11-26 13:26:58 +01:00
void BattleScriptExecute ( const u8 * BS_ptr )
2017-09-17 17:14:32 +02:00
{
gBattlescriptCurrInstr = BS_ptr ;
2018-02-06 23:09:39 +01:00
gBattleResources - > battleCallbackStack - > function [ gBattleResources - > battleCallbackStack - > size + + ] = gBattleMainFunc ;
2017-10-06 00:12:01 +02:00
gBattleMainFunc = RunBattleScriptCommands_PopCallbacksStack ;
gCurrentActionFuncId = 0 ;
2017-09-17 17:14:32 +02:00
}
2017-11-26 13:26:58 +01:00
void BattleScriptPushCursorAndCallback ( const u8 * BS_ptr )
2017-09-17 17:14:32 +02:00
{
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattlescriptCurrInstr = BS_ptr ;
2018-02-06 23:09:39 +01:00
gBattleResources - > battleCallbackStack - > function [ gBattleResources - > battleCallbackStack - > size + + ] = gBattleMainFunc ;
2017-10-06 00:12:01 +02:00
gBattleMainFunc = RunBattleScriptCommands ;
2017-09-17 17:14:32 +02:00
}
enum
{
ITEM_NO_EFFECT , // 0
ITEM_STATUS_CHANGE , // 1
ITEM_EFFECT_OTHER , // 2
ITEM_PP_CHANGE , // 3
ITEM_HP_CHANGE , // 4
ITEM_STATS_CHANGE , // 5
} ;
2018-02-08 11:17:41 +01:00
u8 ItemBattleEffects ( u8 caseID , u8 battlerId , bool8 moveTurn )
2017-09-17 17:14:32 +02:00
{
int i = 0 ;
u8 effect = ITEM_NO_EFFECT ;
u8 changedPP = 0 ;
2018-07-16 20:47:30 +02:00
u8 battlerHoldEffect , atkHoldEffect , defHoldEffect ;
u8 battlerHoldEffectParam , atkHoldEffectParam , defHoldEffectParam ;
2017-09-17 17:14:32 +02:00
u16 atkItem , defItem ;
2018-02-08 11:17:41 +01:00
gLastUsedItem = gBattleMons [ battlerId ] . item ;
2017-09-17 17:14:32 +02:00
if ( gLastUsedItem = = ITEM_ENIGMA_BERRY )
{
2018-07-16 20:47:30 +02:00
battlerHoldEffect = gEnigmaBerries [ battlerId ] . holdEffect ;
battlerHoldEffectParam = gEnigmaBerries [ battlerId ] . holdEffectParam ;
2017-09-17 17:14:32 +02:00
}
else
{
2018-07-16 20:47:30 +02:00
battlerHoldEffect = ItemId_GetHoldEffect ( gLastUsedItem ) ;
battlerHoldEffectParam = ItemId_GetHoldEffectParam ( gLastUsedItem ) ;
2017-09-17 17:14:32 +02:00
}
2018-02-06 23:09:39 +01:00
atkItem = gBattleMons [ gBattlerAttacker ] . item ;
2017-09-17 17:14:32 +02:00
if ( atkItem = = ITEM_ENIGMA_BERRY )
{
2018-02-06 23:09:39 +01:00
atkHoldEffect = gEnigmaBerries [ gBattlerAttacker ] . holdEffect ;
2018-07-16 20:47:30 +02:00
atkHoldEffectParam = gEnigmaBerries [ gBattlerAttacker ] . holdEffectParam ;
2017-09-17 17:14:32 +02:00
}
else
{
atkHoldEffect = ItemId_GetHoldEffect ( atkItem ) ;
2018-07-16 20:47:30 +02:00
atkHoldEffectParam = ItemId_GetHoldEffectParam ( atkItem ) ;
2017-09-17 17:14:32 +02:00
}
// 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 ;
2018-07-16 20:47:30 +02:00
defHoldEffectParam = gEnigmaBerries [ gBattlerTarget ] . holdEffectParam ;
2017-09-17 17:14:32 +02:00
}
else
{
defHoldEffect = ItemId_GetHoldEffect ( defItem ) ;
2018-07-16 20:47:30 +02:00
defHoldEffectParam = ItemId_GetHoldEffectParam ( defItem ) ;
2017-09-17 17:14:32 +02:00
}
switch ( caseID )
{
2017-10-06 00:12:01 +02:00
case ITEMEFFECT_ON_SWITCH_IN :
2018-07-16 20:47:30 +02:00
switch ( battlerHoldEffect )
2017-09-17 17:14:32 +02:00
{
case HOLD_EFFECT_DOUBLE_PRIZE :
2018-02-08 11:17:41 +01:00
if ( GetBattlerSide ( battlerId ) = = B_SIDE_PLAYER )
2017-09-17 17:14:32 +02:00
gBattleStruct - > moneyMultiplier = 2 ;
break ;
case HOLD_EFFECT_RESTORE_STATS :
2018-11-18 20:00:36 +01:00
for ( i = 0 ; i < NUM_BATTLE_STATS ; i + + )
2017-09-17 17:14:32 +02:00
{
2020-08-05 02:33:05 +02:00
if ( gBattleMons [ battlerId ] . statStages [ i ] < DEFAULT_STAT_STAGE )
2017-09-17 17:14:32 +02:00
{
2020-08-05 02:33:05 +02:00
gBattleMons [ battlerId ] . statStages [ i ] = DEFAULT_STAT_STAGE ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATS_CHANGE ;
}
}
if ( effect )
{
2018-02-08 11:17:41 +01:00
gBattleScripting . battler = battlerId ;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = battlerId ;
2018-02-08 11:17:41 +01:00
gActiveBattler = gBattlerAttacker = battlerId ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_WhiteHerbEnd2 ) ;
2017-09-17 17:14:32 +02:00
}
break ;
}
break ;
case 1 :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp )
2017-09-17 17:14:32 +02:00
{
2018-07-16 20:47:30 +02:00
switch ( battlerHoldEffect )
2017-09-17 17:14:32 +02:00
{
case HOLD_EFFECT_RESTORE_HP :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / 2 & & ! moveTurn )
2017-09-17 17:14:32 +02:00
{
2018-07-16 20:47:30 +02:00
gBattleMoveDamage = battlerHoldEffectParam ;
if ( gBattleMons [ battlerId ] . hp + battlerHoldEffectParam > gBattleMons [ battlerId ] . maxHP )
2018-02-08 11:17:41 +01:00
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP - gBattleMons [ battlerId ] . hp ;
2017-09-17 17:14:32 +02:00
gBattleMoveDamage * = - 1 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_ItemHealHP_RemoveItem ) ;
2017-09-17 17:14:32 +02:00
effect = 4 ;
}
break ;
case HOLD_EFFECT_RESTORE_PP :
if ( ! moveTurn )
{
2017-11-26 11:55:17 +01:00
struct Pokemon * mon ;
2017-09-17 17:14:32 +02:00
u8 ppBonuses ;
u16 move ;
2018-02-08 11:17:41 +01:00
if ( GetBattlerSide ( battlerId ) = = B_SIDE_PLAYER )
mon = & gPlayerParty [ gBattlerPartyIndexes [ battlerId ] ] ;
2017-09-17 17:14:32 +02:00
else
2018-02-08 11:17:41 +01:00
mon = & gEnemyParty [ gBattlerPartyIndexes [ battlerId ] ] ;
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-17 17:14:32 +02:00
{
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 ;
}
2018-12-25 18:50:15 +01:00
if ( i ! = MAX_MON_MOVES )
2017-09-17 17:14:32 +02:00
{
u8 maxPP = CalculatePPWithBonus ( move , ppBonuses , i ) ;
2018-07-16 20:47:30 +02:00
if ( changedPP + battlerHoldEffectParam > maxPP )
2017-09-17 17:14:32 +02:00
changedPP = maxPP ;
else
2018-07-16 20:47:30 +02:00
changedPP = changedPP + battlerHoldEffectParam ;
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 :
2018-11-18 20:00:36 +01:00
for ( i = 0 ; i < NUM_BATTLE_STATS ; i + + )
2017-09-17 17:14:32 +02:00
{
2020-08-05 02:33:05 +02:00
if ( gBattleMons [ battlerId ] . statStages [ i ] < DEFAULT_STAT_STAGE )
2017-09-17 17:14:32 +02:00
{
2020-08-05 02:33:05 +02:00
gBattleMons [ battlerId ] . statStages [ i ] = DEFAULT_STAT_STAGE ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATS_CHANGE ;
}
}
if ( effect )
{
2018-02-08 11:17:41 +01:00
gBattleScripting . battler = battlerId ;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = battlerId ;
2018-02-08 11:17:41 +01:00
gActiveBattler = gBattlerAttacker = battlerId ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_WhiteHerbEnd2 ) ;
2017-09-17 17:14:32 +02:00
}
break ;
case HOLD_EFFECT_LEFTOVERS :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp < gBattleMons [ battlerId ] . maxHP & & ! moveTurn )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP / 16 ;
2017-09-17 17:14:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp + gBattleMoveDamage > gBattleMons [ battlerId ] . maxHP )
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP - gBattleMons [ battlerId ] . hp ;
2017-09-17 17:14:32 +02:00
gBattleMoveDamage * = - 1 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_ItemHealHP_End2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_HP_CHANGE ;
2018-07-16 20:47:30 +02:00
RecordItemEffectBattle ( battlerId , battlerHoldEffect ) ;
2017-09-17 17:14:32 +02:00
}
break ;
// nice copy/paste there gamefreak, making a function for confuse berries was too much eh?
case HOLD_EFFECT_CONFUSE_SPICY :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / 2 & & ! moveTurn )
2017-09-17 17:14:32 +02:00
{
2017-11-27 21:24:34 +01:00
PREPARE_FLAVOR_BUFFER ( gBattleTextBuff1 , FLAVOR_SPICY ) ;
2017-11-26 11:55:17 +01:00
2018-07-16 20:47:30 +02:00
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP / battlerHoldEffectParam ;
2017-09-17 17:14:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp + gBattleMoveDamage > gBattleMons [ battlerId ] . maxHP )
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP - gBattleMons [ battlerId ] . hp ;
2017-09-17 17:14:32 +02:00
gBattleMoveDamage * = - 1 ;
2018-02-08 11:17:41 +01:00
if ( GetFlavorRelationByPersonality ( gBattleMons [ battlerId ] . personality , FLAVOR_SPICY ) < 0 )
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryConfuseHealEnd2 ) ;
2017-09-17 17:14:32 +02:00
else
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_ItemHealHP_RemoveItem ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_HP_CHANGE ;
}
break ;
case HOLD_EFFECT_CONFUSE_DRY :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / 2 & & ! moveTurn )
2017-09-17 17:14:32 +02:00
{
2017-11-27 21:24:34 +01:00
PREPARE_FLAVOR_BUFFER ( gBattleTextBuff1 , FLAVOR_DRY ) ;
2017-11-26 11:55:17 +01:00
2018-07-16 20:47:30 +02:00
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP / battlerHoldEffectParam ;
2017-09-17 17:14:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp + gBattleMoveDamage > gBattleMons [ battlerId ] . maxHP )
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP - gBattleMons [ battlerId ] . hp ;
2017-09-17 17:14:32 +02:00
gBattleMoveDamage * = - 1 ;
2018-02-08 11:17:41 +01:00
if ( GetFlavorRelationByPersonality ( gBattleMons [ battlerId ] . personality , FLAVOR_DRY ) < 0 )
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryConfuseHealEnd2 ) ;
2017-09-17 17:14:32 +02:00
else
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_ItemHealHP_RemoveItem ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_HP_CHANGE ;
}
break ;
case HOLD_EFFECT_CONFUSE_SWEET :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / 2 & & ! moveTurn )
2017-09-17 17:14:32 +02:00
{
2017-11-27 21:24:34 +01:00
PREPARE_FLAVOR_BUFFER ( gBattleTextBuff1 , FLAVOR_SWEET ) ;
2017-11-26 11:55:17 +01:00
2018-07-16 20:47:30 +02:00
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP / battlerHoldEffectParam ;
2017-09-17 17:14:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp + gBattleMoveDamage > gBattleMons [ battlerId ] . maxHP )
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP - gBattleMons [ battlerId ] . hp ;
2017-09-17 17:14:32 +02:00
gBattleMoveDamage * = - 1 ;
2018-02-08 11:17:41 +01:00
if ( GetFlavorRelationByPersonality ( gBattleMons [ battlerId ] . personality , FLAVOR_SWEET ) < 0 )
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryConfuseHealEnd2 ) ;
2017-09-17 17:14:32 +02:00
else
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_ItemHealHP_RemoveItem ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_HP_CHANGE ;
}
break ;
case HOLD_EFFECT_CONFUSE_BITTER :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / 2 & & ! moveTurn )
2017-09-17 17:14:32 +02:00
{
2017-11-27 21:24:34 +01:00
PREPARE_FLAVOR_BUFFER ( gBattleTextBuff1 , FLAVOR_BITTER ) ;
2017-11-26 11:55:17 +01:00
2018-07-16 20:47:30 +02:00
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP / battlerHoldEffectParam ;
2017-09-17 17:14:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp + gBattleMoveDamage > gBattleMons [ battlerId ] . maxHP )
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP - gBattleMons [ battlerId ] . hp ;
2017-09-17 17:14:32 +02:00
gBattleMoveDamage * = - 1 ;
2018-02-08 11:17:41 +01:00
if ( GetFlavorRelationByPersonality ( gBattleMons [ battlerId ] . personality , FLAVOR_BITTER ) < 0 )
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryConfuseHealEnd2 ) ;
2017-09-17 17:14:32 +02:00
else
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_ItemHealHP_RemoveItem ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_HP_CHANGE ;
}
break ;
case HOLD_EFFECT_CONFUSE_SOUR :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / 2 & & ! moveTurn )
2017-09-17 17:14:32 +02:00
{
2017-11-27 21:24:34 +01:00
PREPARE_FLAVOR_BUFFER ( gBattleTextBuff1 , FLAVOR_SOUR ) ;
2017-11-26 11:55:17 +01:00
2018-07-16 20:47:30 +02:00
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP / battlerHoldEffectParam ;
2017-09-17 17:14:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . hp + gBattleMoveDamage > gBattleMons [ battlerId ] . maxHP )
gBattleMoveDamage = gBattleMons [ battlerId ] . maxHP - gBattleMons [ battlerId ] . hp ;
2017-09-17 17:14:32 +02:00
gBattleMoveDamage * = - 1 ;
2018-02-08 11:17:41 +01:00
if ( GetFlavorRelationByPersonality ( gBattleMons [ battlerId ] . personality , FLAVOR_SOUR ) < 0 )
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryConfuseHealEnd2 ) ;
2017-09-17 17:14:32 +02:00
else
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_ItemHealHP_RemoveItem ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_HP_CHANGE ;
}
break ;
// copy/paste again, smh
case HOLD_EFFECT_ATTACK_UP :
2020-08-05 02:33:05 +02:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / battlerHoldEffectParam
& & ! moveTurn & & gBattleMons [ battlerId ] . statStages [ STAT_ATK ] < MAX_STAT_STAGE )
2017-09-17 17:14:32 +02:00
{
2018-02-08 12:13:29 +01:00
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , STAT_ATK ) ;
2017-11-26 11:55:17 +01:00
PREPARE_STRING_BUFFER ( gBattleTextBuff2 , STRINGID_STATROSE ) ;
2017-09-17 17:14:32 +02:00
2018-02-08 11:17:41 +01:00
gEffectBattler = battlerId ;
2018-02-08 12:13:29 +01:00
SET_STATCHANGER ( STAT_ATK , 1 , FALSE ) ;
gBattleScripting . animArg1 = 0xE + STAT_ATK ;
2017-09-17 17:14:32 +02:00
gBattleScripting . animArg2 = 0 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryStatRaiseEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATS_CHANGE ;
}
break ;
case HOLD_EFFECT_DEFENSE_UP :
2020-08-05 02:33:05 +02:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / battlerHoldEffectParam & & ! moveTurn
& & gBattleMons [ battlerId ] . statStages [ STAT_DEF ] < MAX_STAT_STAGE )
2017-09-17 17:14:32 +02:00
{
2018-02-08 12:13:29 +01:00
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , STAT_DEF ) ;
2017-09-17 17:14:32 +02:00
2018-02-08 11:17:41 +01:00
gEffectBattler = battlerId ;
2018-02-08 12:13:29 +01:00
SET_STATCHANGER ( STAT_DEF , 1 , FALSE ) ;
gBattleScripting . animArg1 = 0xE + STAT_DEF ;
2017-09-17 17:14:32 +02:00
gBattleScripting . animArg2 = 0 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryStatRaiseEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATS_CHANGE ;
}
break ;
case HOLD_EFFECT_SPEED_UP :
2020-08-05 02:33:05 +02:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / battlerHoldEffectParam & & ! moveTurn
& & gBattleMons [ battlerId ] . statStages [ STAT_SPEED ] < MAX_STAT_STAGE )
2017-09-17 17:14:32 +02:00
{
2018-02-08 12:13:29 +01:00
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , STAT_SPEED ) ;
2017-09-17 17:14:32 +02:00
2018-02-08 11:17:41 +01:00
gEffectBattler = battlerId ;
2018-02-08 12:13:29 +01:00
SET_STATCHANGER ( STAT_SPEED , 1 , FALSE ) ;
gBattleScripting . animArg1 = 0xE + STAT_SPEED ;
2017-09-17 17:14:32 +02:00
gBattleScripting . animArg2 = 0 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryStatRaiseEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATS_CHANGE ;
}
break ;
case HOLD_EFFECT_SP_ATTACK_UP :
2020-08-05 02:33:05 +02:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / battlerHoldEffectParam & & ! moveTurn
& & gBattleMons [ battlerId ] . statStages [ STAT_SPATK ] < MAX_STAT_STAGE )
2017-09-17 17:14:32 +02:00
{
2018-02-08 12:13:29 +01:00
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , STAT_SPATK ) ;
2017-09-17 17:14:32 +02:00
2018-02-08 11:17:41 +01:00
gEffectBattler = battlerId ;
2018-02-08 12:13:29 +01:00
SET_STATCHANGER ( STAT_SPATK , 1 , FALSE ) ;
gBattleScripting . animArg1 = 0xE + STAT_SPATK ;
2017-09-17 17:14:32 +02:00
gBattleScripting . animArg2 = 0 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryStatRaiseEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATS_CHANGE ;
}
break ;
case HOLD_EFFECT_SP_DEFENSE_UP :
2020-08-05 02:33:05 +02:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / battlerHoldEffectParam & & ! moveTurn
& & gBattleMons [ battlerId ] . statStages [ STAT_SPDEF ] < MAX_STAT_STAGE )
2017-09-17 17:14:32 +02:00
{
2018-02-08 12:13:29 +01:00
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , STAT_SPDEF ) ;
2017-09-17 17:14:32 +02:00
2018-02-08 11:17:41 +01:00
gEffectBattler = battlerId ;
2018-02-08 12:13:29 +01:00
SET_STATCHANGER ( STAT_SPDEF , 1 , FALSE ) ;
gBattleScripting . animArg1 = 0xE + STAT_SPDEF ;
2017-09-17 17:14:32 +02:00
gBattleScripting . animArg2 = 0 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryStatRaiseEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATS_CHANGE ;
}
break ;
case HOLD_EFFECT_CRITICAL_UP :
2020-08-05 02:33:05 +02:00
if ( gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / battlerHoldEffectParam & & ! moveTurn
& & ! ( gBattleMons [ battlerId ] . status2 & STATUS2_FOCUS_ENERGY ) )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status2 | = STATUS2_FOCUS_ENERGY ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryFocusEnergyEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_EFFECT_OTHER ;
}
break ;
case HOLD_EFFECT_RANDOM_STAT_UP :
2018-07-16 20:47:30 +02:00
if ( ! moveTurn & & gBattleMons [ battlerId ] . hp < = gBattleMons [ battlerId ] . maxHP / battlerHoldEffectParam )
2017-09-17 17:14:32 +02:00
{
for ( i = 0 ; i < 5 ; i + + )
{
2020-08-05 02:33:05 +02:00
if ( gBattleMons [ battlerId ] . statStages [ STAT_ATK + i ] < MAX_STAT_STAGE )
2017-09-17 17:14:32 +02:00
break ;
}
if ( i ! = 5 )
{
do
{
i = Random ( ) % 5 ;
2020-08-05 02:33:05 +02:00
} while ( gBattleMons [ battlerId ] . statStages [ STAT_ATK + i ] = = MAX_STAT_STAGE ) ;
2017-09-17 17:14:32 +02:00
2017-11-26 11:55:17 +01:00
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , i + 1 ) ;
gBattleTextBuff2 [ 0 ] = B_BUFF_PLACEHOLDER_BEGIN ;
gBattleTextBuff2 [ 1 ] = B_BUFF_STRING ;
gBattleTextBuff2 [ 2 ] = STRINGID_STATSHARPLY ;
gBattleTextBuff2 [ 3 ] = STRINGID_STATSHARPLY > > 8 ;
gBattleTextBuff2 [ 4 ] = B_BUFF_STRING ;
gBattleTextBuff2 [ 5 ] = STRINGID_STATROSE ;
gBattleTextBuff2 [ 6 ] = STRINGID_STATROSE > > 8 ;
2017-09-17 17:14:32 +02:00
gBattleTextBuff2 [ 7 ] = EOS ;
2018-02-08 11:17:41 +01:00
gEffectBattler = battlerId ;
2017-11-26 11:55:17 +01:00
SET_STATCHANGER ( i + 1 , 2 , FALSE ) ;
2017-09-17 17:14:32 +02:00
gBattleScripting . animArg1 = 0x21 + i + 6 ;
gBattleScripting . animArg2 = 0 ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryStatRaiseEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATS_CHANGE ;
}
}
break ;
case HOLD_EFFECT_CURE_PAR :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_PARALYSIS )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 & = ~ ( STATUS1_PARALYSIS ) ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryCurePrlzEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_PSN :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_PSN_ANY )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 & = ~ ( STATUS1_PSN_ANY | STATUS1_TOXIC_COUNTER ) ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryCurePsnEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_BRN :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_BURN )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 & = ~ ( STATUS1_BURN ) ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryCureBrnEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_FRZ :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_FREEZE )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 & = ~ ( STATUS1_FREEZE ) ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryCureFrzEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_SLP :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_SLEEP )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 & = ~ ( STATUS1_SLEEP ) ;
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryCureSlpEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_CONFUSION :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status2 & STATUS2_CONFUSION )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_CONFUSION ) ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryCureConfusionEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_EFFECT_OTHER ;
}
break ;
case HOLD_EFFECT_CURE_STATUS :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_ANY | | gBattleMons [ battlerId ] . status2 & STATUS2_CONFUSION )
2017-09-17 17:14:32 +02:00
{
i = 0 ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_PSN_ANY )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_PoisonJpn ) ;
i + + ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_SLEEP )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
2017-09-17 17:14:32 +02:00
StringCopy ( gBattleTextBuff1 , gStatusConditionString_SleepJpn ) ;
i + + ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_PARALYSIS )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_ParalysisJpn ) ;
i + + ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_BURN )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_BurnJpn ) ;
i + + ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_FREEZE )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_IceJpn ) ;
i + + ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status2 & STATUS2_CONFUSION )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_ConfusionJpn ) ;
i + + ;
}
if ( ! ( i > 1 ) )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 = 0 ;
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_CONFUSION ) ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryCureChosenStatusEnd2 ) ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_ATTRACT :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status2 & STATUS2_INFATUATION )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_INFATUATION ) ;
2017-09-17 17:14:32 +02:00
StringCopy ( gBattleTextBuff1 , gStatusConditionString_LoveJpn ) ;
2017-09-28 15:34:21 +02:00
BattleScriptExecute ( BattleScript_BerryCureChosenStatusEnd2 ) ;
2017-09-17 17:14:32 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
effect = ITEM_EFFECT_OTHER ;
}
break ;
}
if ( effect )
{
2018-02-08 11:17:41 +01:00
gBattleScripting . battler = battlerId ;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = battlerId ;
2018-02-08 11:17:41 +01:00
gActiveBattler = gBattlerAttacker = battlerId ;
2017-09-17 17:14:32 +02:00
switch ( effect )
{
case ITEM_STATUS_CHANGE :
2018-02-08 11:17:41 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ battlerId ] . status1 ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-17 17:14:32 +02:00
break ;
case ITEM_PP_CHANGE :
2019-01-19 22:32:25 +01:00
if ( ! ( gBattleMons [ battlerId ] . status2 & STATUS2_TRANSFORMED ) & & ! ( gDisableStructs [ battlerId ] . mimickedMoves & gBitTable [ i ] ) )
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . pp [ i ] = changedPP ;
2017-09-17 17:14:32 +02:00
break ;
}
}
}
break ;
case 2 :
break ;
2018-09-01 20:00:13 +02:00
case ITEMEFFECT_MOVE_END :
2018-02-08 11:17:41 +01:00
for ( battlerId = 0 ; battlerId < gBattlersCount ; battlerId + + )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gLastUsedItem = gBattleMons [ battlerId ] . item ;
if ( gBattleMons [ battlerId ] . item = = ITEM_ENIGMA_BERRY )
2017-09-17 17:14:32 +02:00
{
2018-07-16 20:47:30 +02:00
battlerHoldEffect = gEnigmaBerries [ battlerId ] . holdEffect ;
battlerHoldEffectParam = gEnigmaBerries [ battlerId ] . holdEffectParam ;
2017-09-17 17:14:32 +02:00
}
else
{
2018-07-16 20:47:30 +02:00
battlerHoldEffect = ItemId_GetHoldEffect ( gLastUsedItem ) ;
battlerHoldEffectParam = ItemId_GetHoldEffectParam ( gLastUsedItem ) ;
2017-09-17 17:14:32 +02:00
}
2018-07-16 20:47:30 +02:00
switch ( battlerHoldEffect )
2017-09-17 17:14:32 +02:00
{
case HOLD_EFFECT_CURE_PAR :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_PARALYSIS )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 & = ~ ( STATUS1_PARALYSIS ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattlescriptCurrInstr = BattleScript_BerryCureParRet ;
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_PSN :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_PSN_ANY )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 & = ~ ( STATUS1_PSN_ANY | STATUS1_TOXIC_COUNTER ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattlescriptCurrInstr = BattleScript_BerryCurePsnRet ;
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_BRN :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_BURN )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 & = ~ ( STATUS1_BURN ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattlescriptCurrInstr = BattleScript_BerryCureBrnRet ;
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_FRZ :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_FREEZE )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 & = ~ ( STATUS1_FREEZE ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattlescriptCurrInstr = BattleScript_BerryCureFrzRet ;
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_SLP :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_SLEEP )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 & = ~ ( STATUS1_SLEEP ) ;
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattlescriptCurrInstr = BattleScript_BerryCureSlpRet ;
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_CURE_CONFUSION :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status2 & STATUS2_CONFUSION )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_CONFUSION ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattlescriptCurrInstr = BattleScript_BerryCureConfusionRet ;
effect = ITEM_EFFECT_OTHER ;
}
break ;
case HOLD_EFFECT_CURE_ATTRACT :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status2 & STATUS2_INFATUATION )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_INFATUATION ) ;
2017-09-17 17:14:32 +02:00
StringCopy ( gBattleTextBuff1 , gStatusConditionString_LoveJpn ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
gBattlescriptCurrInstr = BattleScript_BerryCureChosenStatusRet ;
effect = ITEM_EFFECT_OTHER ;
}
break ;
case HOLD_EFFECT_CURE_STATUS :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_ANY | | gBattleMons [ battlerId ] . status2 & STATUS2_CONFUSION )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_PSN_ANY )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_PoisonJpn ) ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_SLEEP )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
2017-09-17 17:14:32 +02:00
StringCopy ( gBattleTextBuff1 , gStatusConditionString_SleepJpn ) ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_PARALYSIS )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_ParalysisJpn ) ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_BURN )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_BurnJpn ) ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status1 & STATUS1_FREEZE )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_IceJpn ) ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battlerId ] . status2 & STATUS2_CONFUSION )
2017-09-17 17:14:32 +02:00
{
StringCopy ( gBattleTextBuff1 , gStatusConditionString_ConfusionJpn ) ;
}
2018-02-08 11:17:41 +01:00
gBattleMons [ battlerId ] . status1 = 0 ;
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_CONFUSION ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
gBattlescriptCurrInstr = BattleScript_BerryCureChosenStatusRet ;
effect = ITEM_STATUS_CHANGE ;
}
break ;
case HOLD_EFFECT_RESTORE_STATS :
2018-11-18 20:00:36 +01:00
for ( i = 0 ; i < NUM_BATTLE_STATS ; i + + )
2017-09-17 17:14:32 +02:00
{
2020-08-05 02:33:05 +02:00
if ( gBattleMons [ battlerId ] . statStages [ i ] < DEFAULT_STAT_STAGE )
2017-09-17 17:14:32 +02:00
{
2020-08-05 02:33:05 +02:00
gBattleMons [ battlerId ] . statStages [ i ] = DEFAULT_STAT_STAGE ;
2017-09-17 17:14:32 +02:00
effect = ITEM_STATS_CHANGE ;
}
}
if ( effect )
{
2018-02-08 11:17:41 +01:00
gBattleScripting . battler = battlerId ;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = battlerId ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattlescriptCurrInstr = BattleScript_WhiteHerbRet ;
2018-09-01 20:00:13 +02:00
return effect ;
2017-09-17 17:14:32 +02:00
}
break ;
}
if ( effect )
{
2018-02-08 11:17:41 +01:00
gBattleScripting . battler = battlerId ;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = battlerId ;
2018-02-08 11:17:41 +01:00
gActiveBattler = battlerId ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gActiveBattler ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-17 17:14:32 +02:00
break ;
}
}
break ;
2018-09-01 20:00:13 +02:00
case ITEMEFFECT_KINGSROCK_SHELLBELL :
2017-09-17 17:14:32 +02:00
if ( gBattleMoveDamage )
{
switch ( atkHoldEffect )
{
case HOLD_EFFECT_FLINCH :
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2018-03-01 00:59:52 +01:00
& & TARGET_TURN_DAMAGED
2018-07-16 20:47:30 +02:00
& & ( Random ( ) % 100 ) < atkHoldEffectParam
2020-12-12 16:09:26 +01:00
& & gBattleMoves [ gCurrentMove ] . flags & FLAG_KINGS_ROCK_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 ( ) ;
2020-03-07 23:36:09 +01:00
SetMoveEffect ( FALSE , 0 ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPop ( ) ;
2017-09-17 17:14:32 +02:00
}
break ;
case HOLD_EFFECT_SHELL_BELL :
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2018-02-07 22:53:40 +01:00
& & gSpecialStatuses [ gBattlerTarget ] . dmg ! = 0
& & gSpecialStatuses [ gBattlerTarget ] . dmg ! = 0xFFFF
2018-02-06 23:09:39 +01:00
& & gBattlerAttacker ! = gBattlerTarget
& & gBattleMons [ gBattlerAttacker ] . hp ! = gBattleMons [ gBattlerAttacker ] . maxHP
& & gBattleMons [ gBattlerAttacker ] . hp ! = 0 )
2017-09-17 17:14:32 +02:00
{
gLastUsedItem = atkItem ;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerAttacker ;
2018-02-06 23:09:39 +01:00
gBattleScripting . battler = gBattlerAttacker ;
2018-07-16 20:47:30 +02:00
gBattleMoveDamage = ( gSpecialStatuses [ gBattlerTarget ] . dmg / atkHoldEffectParam ) * - 1 ;
2017-09-17 17:14:32 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = - 1 ;
2018-02-07 22:53:40 +01:00
gSpecialStatuses [ gBattlerTarget ] . dmg = 0 ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-17 17:14:32 +02:00
gBattlescriptCurrInstr = BattleScript_ItemHealHP_Ret ;
effect + + ;
}
break ;
}
}
break ;
}
return effect ;
}
2018-02-08 11:17:41 +01:00
void ClearFuryCutterDestinyBondGrudge ( u8 battlerId )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
gDisableStructs [ battlerId ] . furyCutterCounter = 0 ;
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_DESTINY_BOND ) ;
gStatuses3 [ battlerId ] & = ~ ( STATUS3_GRUDGE ) ;
2017-09-17 17:14:32 +02:00
}
2017-10-06 17:06:45 +02:00
void HandleAction_RunBattleScript ( void ) // identical to RunBattleScriptCommands
2017-09-17 17:14:32 +02:00
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-17 17:14:32 +02:00
gBattleScriptingCommandsTable [ * gBattlescriptCurrInstr ] ( ) ;
}
2018-03-01 00:59:52 +01:00
u8 GetMoveTarget ( u16 move , u8 setTarget )
2017-09-17 17:14:32 +02:00
{
2018-07-01 11:15:42 +02:00
u8 targetBattler = 0 ;
2017-09-17 17:14:32 +02:00
u8 moveTarget ;
u8 side ;
2018-03-01 00:59:52 +01:00
if ( setTarget )
moveTarget = setTarget - 1 ;
2017-09-17 17:14:32 +02:00
else
moveTarget = gBattleMoves [ move ] . target ;
switch ( moveTarget )
{
2017-09-19 21:01:12 +02:00
case MOVE_TARGET_SELECTED :
2018-02-06 23:09:39 +01:00
side = GetBattlerSide ( gBattlerAttacker ) ^ BIT_SIDE ;
2017-09-17 17:14:32 +02:00
if ( gSideTimers [ side ] . followmeTimer & & gBattleMons [ gSideTimers [ side ] . followmeTarget ] . hp )
2018-07-01 11:15:42 +02:00
targetBattler = gSideTimers [ side ] . followmeTarget ;
2017-09-17 17:14:32 +02:00
else
{
2018-02-06 23:09:39 +01:00
side = GetBattlerSide ( gBattlerAttacker ) ;
2017-09-17 17:14:32 +02:00
do
{
2018-07-01 11:15:42 +02:00
targetBattler = Random ( ) % gBattlersCount ;
} while ( targetBattler = = gBattlerAttacker | | side = = GetBattlerSide ( targetBattler ) | | gAbsentBattlerFlags & gBitTable [ targetBattler ] ) ;
2017-09-17 17:14:32 +02:00
if ( gBattleMoves [ move ] . type = = TYPE_ELECTRIC
2018-02-06 23:09:39 +01:00
& & AbilityBattleEffects ( ABILITYEFFECT_COUNT_OTHER_SIDE , gBattlerAttacker , ABILITY_LIGHTNING_ROD , 0 , 0 )
2018-07-01 11:15:42 +02:00
& & gBattleMons [ targetBattler ] . ability ! = ABILITY_LIGHTNING_ROD )
2017-09-17 17:14:32 +02:00
{
2018-07-01 11:15:42 +02:00
targetBattler ^ = BIT_FLANK ;
RecordAbilityBattle ( targetBattler , gBattleMons [ targetBattler ] . ability ) ;
gSpecialStatuses [ targetBattler ] . lightningRodRedirected = 1 ;
2017-09-17 17:14:32 +02:00
}
}
break ;
2017-09-19 21:01:12 +02:00
case MOVE_TARGET_DEPENDS :
case MOVE_TARGET_BOTH :
case MOVE_TARGET_FOES_AND_ALLY :
case MOVE_TARGET_OPPONENTS_FIELD :
2018-07-01 11:15:42 +02:00
targetBattler = GetBattlerAtPosition ( ( GetBattlerPosition ( gBattlerAttacker ) & BIT_SIDE ) ^ BIT_SIDE ) ;
if ( gAbsentBattlerFlags & gBitTable [ targetBattler ] )
targetBattler ^ = BIT_FLANK ;
2017-09-17 17:14:32 +02:00
break ;
2017-09-19 21:01:12 +02:00
case MOVE_TARGET_RANDOM :
2018-02-06 23:09:39 +01:00
side = GetBattlerSide ( gBattlerAttacker ) ^ BIT_SIDE ;
2017-09-17 17:14:32 +02:00
if ( gSideTimers [ side ] . followmeTimer & & gBattleMons [ gSideTimers [ side ] . followmeTarget ] . hp )
2018-07-01 11:15:42 +02:00
targetBattler = gSideTimers [ side ] . followmeTarget ;
2017-09-19 21:01:12 +02:00
else if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE & & moveTarget & MOVE_TARGET_RANDOM )
2017-09-17 17:14:32 +02:00
{
2018-02-06 23:09:39 +01:00
if ( GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_PLAYER )
2017-09-17 17:14:32 +02:00
{
if ( Random ( ) & 1 )
2018-07-01 11:15:42 +02:00
targetBattler = GetBattlerAtPosition ( B_POSITION_OPPONENT_LEFT ) ;
2017-09-17 17:14:32 +02:00
else
2018-07-01 11:15:42 +02:00
targetBattler = GetBattlerAtPosition ( B_POSITION_OPPONENT_RIGHT ) ;
2017-09-17 17:14:32 +02:00
}
else
{
if ( Random ( ) & 1 )
2018-07-01 11:15:42 +02:00
targetBattler = GetBattlerAtPosition ( B_POSITION_PLAYER_LEFT ) ;
2017-09-17 17:14:32 +02:00
else
2018-07-01 11:15:42 +02:00
targetBattler = GetBattlerAtPosition ( B_POSITION_PLAYER_RIGHT ) ;
2017-09-17 17:14:32 +02:00
}
2018-07-01 11:15:42 +02:00
if ( gAbsentBattlerFlags & gBitTable [ targetBattler ] )
targetBattler ^ = BIT_FLANK ;
2017-09-17 17:14:32 +02:00
}
else
2018-07-01 11:15:42 +02:00
targetBattler = GetBattlerAtPosition ( ( GetBattlerPosition ( gBattlerAttacker ) & BIT_SIDE ) ^ BIT_SIDE ) ;
2017-09-17 17:14:32 +02:00
break ;
2018-02-26 13:24:46 +01:00
case MOVE_TARGET_USER_OR_SELECTED :
2017-09-19 21:01:12 +02:00
case MOVE_TARGET_USER :
2018-07-01 11:15:42 +02:00
targetBattler = gBattlerAttacker ;
2017-09-17 17:14:32 +02:00
break ;
}
2018-07-01 11:15:42 +02:00
* ( gBattleStruct - > moveTarget + gBattlerAttacker ) = targetBattler ;
2017-09-17 17:14:32 +02:00
2018-07-01 11:15:42 +02:00
return targetBattler ;
2017-09-17 17:14:32 +02:00
}
2021-02-15 20:54:35 +01:00
static bool32 IsNotEventLegalMewOrDeoxys ( u8 battlerId )
2017-09-17 17:14:32 +02:00
{
2018-02-08 11:17:41 +01:00
if ( GetBattlerSide ( battlerId ) = = B_SIDE_OPPONENT )
2017-09-17 17:14:32 +02:00
return TRUE ;
2018-02-08 11:17:41 +01:00
if ( GetMonData ( & gPlayerParty [ gBattlerPartyIndexes [ battlerId ] ] , MON_DATA_SPECIES , NULL ) ! = SPECIES_DEOXYS
& & GetMonData ( & gPlayerParty [ gBattlerPartyIndexes [ battlerId ] ] , MON_DATA_SPECIES , NULL ) ! = SPECIES_MEW )
2017-09-17 17:14:32 +02:00
return TRUE ;
2021-02-15 20:54:35 +01:00
return GetMonData ( & gPlayerParty [ gBattlerPartyIndexes [ battlerId ] ] , MON_DATA_EVENT_LEGAL , 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 ;
2021-01-13 21:17:32 +01:00
if ( gBattleTypeFlags & ( BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK ) )
2017-09-17 17:14:32 +02:00
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 ;
2021-02-15 20:54:35 +01:00
if ( IsNotEventLegalMewOrDeoxys ( 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
{
2018-09-01 20:00:13 +02:00
gBattlescriptCurrInstr = BattleScript_IgnoresWhileAsleep ;
2017-09-17 17:14:32 +02:00
return 1 ;
}
rnd = ( Random ( ) & 255 ) ;
2018-02-06 23:09:39 +01:00
calc = ( gBattleMons [ gBattlerAttacker ] . level + obedienceLevel ) * rnd > > 8 ;
2017-09-17 17:14:32 +02:00
if ( calc < obedienceLevel )
{
2018-02-06 23:09:39 +01:00
calc = CheckMoveLimitations ( gBattlerAttacker , gBitTable [ gCurrMovePos ] , 0xFF ) ;
2017-09-17 17:14:32 +02:00
if ( calc = = 0xF ) // all moves cannot be used
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = Random ( ) & 3 ;
gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround ;
return 1 ;
}
else // use a random move
{
do
{
2018-02-08 11:17:41 +01:00
gCurrMovePos = gChosenMovePos = Random ( ) & 3 ;
2017-09-17 17:14:32 +02:00
} while ( gBitTable [ gCurrMovePos ] & calc ) ;
2018-09-22 18:41:00 +02:00
gCalledMove = gBattleMons [ gBattlerAttacker ] . moves [ gCurrMovePos ] ;
2017-11-26 17:15:28 +01:00
gBattlescriptCurrInstr = BattleScript_IgnoresAndUsesRandomMove ;
2018-09-22 18:41:00 +02:00
gBattlerTarget = GetMoveTarget ( gCalledMove , 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 ;
2018-09-01 20:00:13 +02:00
gBattlescriptCurrInstr = BattleScript_IgnoresAndHitsItself ;
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 ;
}
}
}