2017-09-04 15:05:11 +02:00
# include "global.h"
# include "battle.h"
2017-09-08 16:46:37 +02:00
# include "battle_move_effects.h"
2017-09-19 21:01:12 +02:00
# include "battle_message.h"
2017-09-28 17:38:07 +02:00
# include "battle_ai_script_commands.h"
2017-11-25 18:42:31 +01:00
# include "battle_scripts.h"
2017-09-08 16:46:37 +02:00
# include "moves.h"
# include "abilities.h"
# include "item.h"
# include "items.h"
# include "hold_effects.h"
2017-09-19 21:01:12 +02:00
# include "util.h"
# include "pokemon.h"
# include "calculate_base_damage.h"
# include "rng.h"
2017-09-20 00:28:00 +02:00
# include "battle_controllers.h"
2017-11-11 20:01:04 +01:00
# include "battle_interface.h"
2017-09-20 00:28:00 +02:00
# include "species.h"
2017-09-20 12:56:45 +02:00
# include "songs.h"
2017-09-22 21:33:49 +02:00
# include "text.h"
# include "sound.h"
2017-09-24 00:29:52 +02:00
# include "pokedex.h"
2017-09-25 00:09:13 +02:00
# include "recorded_battle.h"
# include "window.h"
# include "reshow_battle_screen.h"
# include "main.h"
# include "palette.h"
# include "money.h"
2017-09-26 22:39:59 +02:00
# include "bg.h"
# include "string_util.h"
# include "pokemon_icon.h"
# include "pokemon_item_effects.h"
# include "m4a.h"
2017-09-27 23:43:45 +02:00
# include "mail.h"
2017-09-28 15:34:21 +02:00
# include "event_data.h"
# include "pokemon_storage_system.h"
# include "task.h"
# include "naming_screen.h"
2017-10-07 15:15:47 +02:00
# include "battle_string_ids.h"
2017-09-19 21:01:12 +02:00
// variables
extern u8 gCritMultiplier ;
extern s32 gBattleMoveDamage ;
extern u32 gStatuses3 [ BATTLE_BANKS_COUNT ] ;
extern u32 gBattleTypeFlags ;
extern struct BattleEnigmaBerry gEnigmaBerries [ BATTLE_BANKS_COUNT ] ;
extern struct BattlePokemon gBattleMons [ BATTLE_BANKS_COUNT ] ;
extern u8 gActiveBank ;
extern u32 gBattleExecBuffer ;
extern u8 gNoOfAllBanks ;
extern u16 gBattlePartyID [ BATTLE_BANKS_COUNT ] ;
2017-10-04 19:25:14 +02:00
extern u8 gBanksByTurnOrder [ BATTLE_BANKS_COUNT ] ;
extern u8 gActionsByTurnOrder [ BATTLE_BANKS_COUNT ] ;
2017-09-19 21:01:12 +02:00
extern u16 gCurrentMove ;
extern u8 gLastUsedAbility ;
extern u16 gBattleWeather ;
extern u8 gStringBank ;
extern u8 gEffectBank ;
extern u8 gAbsentBankFlags ;
extern u8 gMultiHitCounter ;
extern u16 gChosenMovesByBanks [ BATTLE_BANKS_COUNT ] ;
extern u16 gSideAffecting [ 2 ] ;
extern u16 gPauseCounterBattle ;
extern u16 gPaydayMoney ;
extern u16 gRandomTurnNumber ;
extern u8 gBattleOutcome ;
extern u8 gBattleTerrain ;
extern u8 gBankAttacker ;
extern u8 gBankTarget ;
extern const u8 * gBattlescriptCurrInstr ;
extern u8 gCurrMovePos ;
2017-10-06 00:12:01 +02:00
extern u8 gCurrentActionFuncId ;
2017-09-19 21:01:12 +02:00
extern u32 gHitMarker ;
extern u8 gBattleMoveFlags ;
extern u8 gBattleCommunication [ ] ;
2017-11-26 14:17:02 +01:00
extern u16 gLastLandedMoves [ 4 ] ;
extern u16 gLastHitByType [ 4 ] ;
2017-11-26 18:07:00 +01:00
extern u16 gLastResultingMoves [ 4 ] ;
2017-11-26 14:17:02 +01:00
extern u8 gLastHitBy [ 4 ] ;
2017-09-19 21:01:12 +02:00
extern u8 gStringBank ;
extern u16 gDynamicBasePower ;
extern u16 gLastUsedItem ;
extern u16 gBattleMovePower ;
2017-09-20 12:56:45 +02:00
extern s32 gHpDealt ;
2017-09-19 21:01:12 +02:00
extern s32 gTakenDmg [ BATTLE_BANKS_COUNT ] ;
extern u8 gTakenDmgBanks [ BATTLE_BANKS_COUNT ] ;
extern u8 gSentPokesToOpponent [ 2 ] ;
extern u8 gBank1 ;
extern u16 gExpShareExp ;
extern u8 gLeveledUpInBattle ;
extern void ( * gBattleMainFunc ) ( void ) ;
extern u8 gPlayerPartyCount ;
extern u16 gMoveToLearn ;
extern u16 gRandomMove ;
extern u8 gBankInMenu ;
2017-09-20 22:54:26 +02:00
extern u8 gActionForBanks [ BATTLE_BANKS_COUNT ] ;
2017-10-06 00:12:01 +02:00
extern u8 gCurrentTurnActionNumber ;
2017-09-20 22:54:26 +02:00
extern u8 gBattleBufferB [ BATTLE_BANKS_COUNT ] [ 0x200 ] ;
extern u16 gLockedMoves [ BATTLE_BANKS_COUNT ] ;
2017-09-22 21:33:49 +02:00
extern u16 gPartnerTrainerId ;
2017-11-26 18:07:00 +01:00
extern u16 gChosenMove ;
extern u16 gLastPrintedMoves [ BATTLE_BANKS_COUNT ] ;
extern u16 gLastMoves [ BATTLE_BANKS_COUNT ] ;
2017-09-25 00:09:13 +02:00
extern u16 gTrainerBattleOpponent_A ;
extern u16 gTrainerBattleOpponent_B ;
2017-09-27 23:43:45 +02:00
extern u8 gUnknown_020241E9 ;
2017-09-28 15:34:21 +02:00
extern u16 gBattle_BG1_X ;
extern u16 gBattle_BG1_Y ;
extern u16 gBattle_BG2_X ;
extern u16 gBattle_BG2_Y ;
extern u16 gBattle_BG3_X ;
2017-09-26 22:39:59 +02:00
extern struct MusicPlayerInfo gMPlay_BGM ;
2017-09-25 00:09:13 +02:00
struct TrainerMoney
{
u8 classId ;
u8 value ;
} ;
2017-09-19 21:01:12 +02:00
extern const struct BattleMove gBattleMoves [ ] ;
2017-09-20 22:54:26 +02:00
extern const struct BaseStats gBaseStats [ ] ;
2017-11-11 20:01:04 +01:00
extern const u8 gTypeEffectiveness [ 336 ] ;
2017-09-25 00:09:13 +02:00
extern const struct TrainerMoney gTrainerMoneyTable [ ] ;
2017-09-23 20:13:45 +02:00
extern const u8 * const gBattleScriptsForMoveEffects [ ] ;
2017-09-19 21:01:12 +02:00
// functions
2017-09-22 21:33:49 +02:00
extern void sub_81A5718 ( u8 bank ) ; // battle frontier 2
2017-09-24 00:29:52 +02:00
extern void sub_81A56B4 ( void ) ; // battle frontier 2
2017-09-25 00:09:13 +02:00
extern void sub_81BFA38 ( struct Pokemon * party , u8 monPartyId , u8 monCount , void ( * callback ) ( void ) , u16 move ) ; // pokemon summary screen
extern u8 sub_81C1B94 ( void ) ; // pokemon summary screen
extern void IncrementGameStat ( u8 statId ) ; // rom_4
2017-09-26 22:39:59 +02:00
extern void sub_81D388C ( struct Pokemon * mon , void * statStoreLocation ) ; // pokenav.s
extern void sub_81D3640 ( u8 arg0 , void * statStoreLocation1 , void * statStoreLocation2 , u8 arg3 , u8 arg4 , u8 arg5 ) ; // pokenav.s
extern void sub_81D3784 ( u8 arg0 , void * statStoreLocation1 , u8 arg2 , u8 arg3 , u8 arg4 ) ; // pokenav.s
extern u8 * GetMonNickname ( struct Pokemon * mon , u8 * dst ) ; // party_menu
extern u8 sub_81A5258 ( u8 * arg0 ) ; // battle frontier 2
extern void sub_81A5BF8 ( void ) ; // battle frontier 2
extern void sub_81A5D44 ( void ) ; // battle frontier 2
extern void sub_81B8E80 ( u8 bank , u8 , u8 ) ; // party menu
extern bool8 sub_81B1250 ( void ) ; // ?
2017-09-28 15:34:21 +02:00
extern bool8 InBattlePike ( void ) ;
extern bool8 InBattlePyramid ( void ) ;
extern u16 GetBattlePyramidPickupItemId ( void ) ;
extern u8 sav1_map_get_light_level ( void ) ;
extern u8 sub_813B21C ( void ) ;
extern u16 get_unknown_box_id ( void ) ;
2017-10-01 18:54:01 +02:00
extern void sub_80356D0 ( void ) ;
2017-09-19 21:01:12 +02:00
2017-09-25 00:09:13 +02:00
// strings
extern const u8 gText_BattleYesNoChoice [ ] ;
2017-09-19 21:01:12 +02:00
// read via orr
# define BSScriptRead32(ptr) ((ptr)[0] | (ptr)[1] << 8 | (ptr)[2] << 16 | (ptr)[3] << 24)
2017-09-28 15:34:21 +02:00
# define BSScriptRead16(ptr) ((ptr)[0] | ((ptr)[1] << 8))
2017-09-19 21:01:12 +02:00
# define BSScriptReadPtr(ptr) ((void *)BSScriptRead32(ptr))
// read via add
# define BS2ScriptRead32(ptr) ((ptr)[0] + ((ptr)[1] << 8) + ((ptr)[2] << 16) + ((ptr)[3] << 24))
# define BS2ScriptRead16(ptr) ((ptr)[0] + ((ptr)[1] << 8))
# define BS2ScriptReadPtr(ptr) ((void *)BS2ScriptRead32(ptr))
# define TARGET_PROTECT_AFFECTED ((gProtectStructs[gBankTarget].protected && gBattleMoves[gCurrentMove].flags & FLAG_PROTECT_AFFECTED))
2017-09-23 20:13:45 +02:00
# define TARGET_TURN_DAMAGED (((gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special)))
2017-09-19 21:01:12 +02:00
// this file's functions
2017-09-28 15:34:21 +02:00
static bool8 IsTwoTurnsMove ( u16 move ) ;
2017-11-25 18:42:31 +01:00
static void TrySetDestinyBondToHappen ( void ) ;
2017-09-28 15:34:21 +02:00
static u8 AttacksThisTurn ( u8 bank , u16 move ) ; // Note: returns 1 if it's a charging turn, otherwise 2.
2017-09-20 00:28:00 +02:00
static void CheckWonderGuardAndLevitate ( void ) ;
2017-09-28 15:34:21 +02:00
static u8 ChangeStatBuffs ( s8 statValue , u8 statId , u8 , const u8 * BS_ptr ) ;
static bool32 IsMonGettingExpSentOut ( void ) ;
static void sub_804F17C ( void ) ;
static bool8 sub_804F1CC ( void ) ;
static void sub_804F100 ( void ) ;
static void sub_804F144 ( void ) ;
static bool8 sub_804F344 ( void ) ;
static void PutMonIconOnLvlUpBox ( void ) ;
static void PutLevelAndGenderOnLvlUpBox ( void ) ;
2017-09-28 16:32:23 +02:00
static void SpriteCB_MonIconOnLvlUpBox ( struct Sprite * sprite ) ;
2017-09-28 15:34:21 +02:00
static void atk00_attackcanceler ( void ) ;
static void atk01_accuracycheck ( void ) ;
static void atk02_attackstring ( void ) ;
static void atk03_ppreduce ( void ) ;
static void atk04_critcalc ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk05_damagecalc ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk06_typecalc ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk07_adjustnormaldamage ( void ) ;
static void atk08_adjustnormaldamage2 ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk09_attackanimation ( void ) ;
static void atk0A_waitanimation ( void ) ;
static void atk0B_healthbarupdate ( void ) ;
static void atk0C_datahpupdate ( void ) ;
static void atk0D_critmessage ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk0E_effectivenesssound ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk0F_resultmessage ( void ) ;
static void atk10_printstring ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk11_printselectionstring ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk12_waitmessage ( void ) ;
static void atk13_printfromtable ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk14_printselectionstringfromtable ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk15_seteffectwithchance ( void ) ;
static void atk16_seteffectprimary ( void ) ;
static void atk17_seteffectsecondary ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk18_clearstatusfromeffect ( void ) ;
static void atk19_tryfaintmon ( void ) ;
static void atk1A_dofaintanimation ( void ) ;
static void atk1B_cleareffectsonfaint ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk1C_jumpifstatus ( void ) ;
static void atk1D_jumpifstatus2 ( void ) ;
static void atk1E_jumpifability ( void ) ;
static void atk1F_jumpifsideaffecting ( void ) ;
static void atk20_jumpifstat ( void ) ;
2017-11-26 11:55:17 +01:00
static void atk21_jumpifstatus3condition ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk22_jumpiftype ( void ) ;
static void atk23_getexp ( void ) ;
static void atk24 ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk25_movevaluescleanup ( void ) ;
static void atk26_setmultihit ( void ) ;
static void atk27_decrementmultihit ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk28_goto ( void ) ;
static void atk29_jumpifbyte ( void ) ;
static void atk2A_jumpifhalfword ( void ) ;
static void atk2B_jumpifword ( void ) ;
static void atk2C_jumpifarrayequal ( void ) ;
static void atk2D_jumpifarraynotequal ( void ) ;
static void atk2E_setbyte ( void ) ;
static void atk2F_addbyte ( void ) ;
static void atk30_subbyte ( void ) ;
static void atk31_copyarray ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk32_copyarraywithindex ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk33_orbyte ( void ) ;
static void atk34_orhalfword ( void ) ;
static void atk35_orword ( void ) ;
static void atk36_bicbyte ( void ) ;
static void atk37_bichalfword ( void ) ;
static void atk38_bicword ( void ) ;
static void atk39_pause ( void ) ;
static void atk3A_waitstate ( void ) ;
static void atk3B_healthbar_update ( void ) ;
static void atk3C_return ( void ) ;
static void atk3D_end ( void ) ;
static void atk3E_end2 ( void ) ;
static void atk3F_end3 ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk40_jumpifaffectedbyprotect ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk41_call ( void ) ;
static void atk42_jumpiftype2 ( void ) ;
static void atk43_jumpifabilitypresent ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk44_endselectionscript ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk45_playanimation ( void ) ;
static void atk46_playanimation2 ( void ) ;
static void atk47_setgraphicalstatchangevalues ( void ) ;
static void atk48_playstatchangeanimation ( void ) ;
static void atk49_moveend ( void ) ;
static void atk4A_typecalc2 ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk4B_returnatktoball ( void ) ;
static void atk4C_getswitchedmondata ( void ) ;
static void atk4D_switchindataupdate ( void ) ;
static void atk4E_switchinanim ( void ) ;
static void atk4F_jumpifcantswitch ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk50_openpartyscreen ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk51_switchhandleorder ( void ) ;
static void atk52_switchineffects ( void ) ;
static void atk53_trainerslidein ( void ) ;
static void atk54_playse ( void ) ;
static void atk55_fanfare ( void ) ;
static void atk56_playfaintcry ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk57 ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk58_returntoball ( void ) ;
static void atk59_handlelearnnewmove ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk5A_yesnoboxlearnmove ( void ) ;
static void atk5B_yesnoboxstoplearningmove ( void ) ;
static void atk5C_hitanimation ( void ) ;
static void atk5D_getmoneyreward ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk5E ( void ) ;
static void atk5F ( void ) ;
static void atk60_incrementgamestat ( void ) ;
static void atk61_drawpartystatussummary ( void ) ;
static void atk62 ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk63_jumptorandomattack ( void ) ;
static void atk64_statusanimation ( void ) ;
static void atk65_status2animation ( void ) ;
static void atk66_chosenstatusanimation ( void ) ;
static void atk67_yesnobox ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk68_cancelallactions ( void ) ;
static void atk69_adjustsetdamage ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk6A_removeitem ( void ) ;
static void atk6B_atknameinbuff1 ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk6C_drawlvlupbox ( void ) ;
static void atk6D_resetsentmonsvalue ( void ) ;
static void atk6E_setatktoplayer0 ( void ) ;
static void atk6F_makevisible ( void ) ;
static void atk70_recordlastability ( void ) ;
static void atk71_buffermovetolearn ( void ) ;
static void atk72_jumpifplayerran ( void ) ;
static void atk73_hpthresholds ( void ) ;
static void atk74_hpthresholds2 ( void ) ;
static void atk75_useitemonopponent ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk76_various ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk77_setprotectlike ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk78_faintifabilitynotdamp ( void ) ;
static void atk79_setatkhptozero ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk7A_jumpifnexttargetvalid ( void ) ;
static void atk7B_tryhealhalfhealth ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk7C_trymirrormove ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk7D_setrain ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk7E_setreflect ( void ) ;
static void atk7F_setseeded ( void ) ;
static void atk80_manipulatedamage ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk81_trysetrest ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk82_jumpifnotfirstturn ( void ) ;
static void atk83_nop ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk84_jumpifcantmakeasleep ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk85_stockpile ( void ) ;
static void atk86_stockpiletobasedamage ( void ) ;
static void atk87_stockpiletohpheal ( void ) ;
static void atk88_negativedamage ( void ) ;
static void atk89_statbuffchange ( void ) ;
static void atk8A_normalisebuffs ( void ) ;
static void atk8B_setbide ( void ) ;
static void atk8C_confuseifrepeatingattackends ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk8D_setmultihitcounter ( void ) ;
static void atk8E_initmultihitstring ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk8F_forcerandomswitch ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk90_tryconversiontypechange ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk91_givepaydaymoney ( void ) ;
static void atk92_setlightscreen ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk93_tryKO ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk94_damagetohalftargethp ( void ) ;
static void atk95_setsandstorm ( void ) ;
static void atk96_weatherdamage ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk97_tryinfatuating ( void ) ;
static void atk98_updatestatusicon ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk99_setmist ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk9A_setfocusenergy ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk9B_transformdataexecution ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk9C_setsubstitute ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk9D_mimicattackcopy ( void ) ;
static void atk9E_metronome ( void ) ;
static void atk9F_dmgtolevel ( void ) ;
static void atkA0_psywavedamageeffect ( void ) ;
static void atkA1_counterdamagecalculator ( void ) ;
static void atkA2_mirrorcoatdamagecalculator ( void ) ;
static void atkA3_disablelastusedattack ( void ) ;
2017-11-25 18:42:31 +01:00
static void atkA4_trysetencore ( void ) ;
2017-09-28 15:34:21 +02:00
static void atkA5_painsplitdmgcalc ( void ) ;
static void atkA6_settypetorandomresistance ( void ) ;
static void atkA7_setalwayshitflag ( void ) ;
static void atkA8_copymovepermanently ( void ) ;
2017-11-26 01:19:57 +01:00
static void atkA9_trychoosesleeptalkmove ( void ) ;
2017-11-25 18:42:31 +01:00
static void atkAA_setdestinybond ( void ) ;
static void atkAB_trysetdestinybondtohappen ( void ) ;
2017-09-28 15:34:21 +02:00
static void atkAC_remaininghptopower ( void ) ;
2017-11-25 18:42:31 +01:00
static void atkAD_tryspiteppreduce ( void ) ;
static void atkAE_healpartystatus ( void ) ;
2017-09-28 15:34:21 +02:00
static void atkAF_cursetarget ( void ) ;
2017-11-25 18:42:31 +01:00
static void atkB0_trysetspikes ( void ) ;
static void atkB1_setforesight ( void ) ;
static void atkB2_trysetperishsong ( void ) ;
2017-09-28 15:34:21 +02:00
static void atkB3_rolloutdamagecalculation ( void ) ;
static void atkB4_jumpifconfusedandstatmaxed ( void ) ;
static void atkB5_furycuttercalc ( void ) ;
static void atkB6_happinesstodamagecalculation ( void ) ;
static void atkB7_presentdamagecalculation ( void ) ;
2017-11-25 18:42:31 +01:00
static void atkB8_setsafeguard ( void ) ;
2017-09-28 15:34:21 +02:00
static void atkB9_magnitudedamagecalculation ( void ) ;
static void atkBA_jumpifnopursuitswitchdmg ( void ) ;
static void atkBB_setsunny ( void ) ;
static void atkBC_maxattackhalvehp ( void ) ;
static void atkBD_copyfoestats ( void ) ;
static void atkBE_rapidspinfree ( void ) ;
2017-11-25 18:42:31 +01:00
static void atkBF_setdefensecurlbit ( void ) ;
2017-09-28 15:34:21 +02:00
static void atkC0_recoverbasedonsunlight ( void ) ;
2017-11-25 18:42:31 +01:00
static void atkC1_hiddenpowercalc ( void ) ;
static void atkC2_selectfirstvalidtarget ( void ) ;
static void atkC3_trysetfutureattack ( void ) ;
static void atkC4_trydobeatup ( void ) ;
2017-09-28 15:34:21 +02:00
static void atkC5_setsemiinvulnerablebit ( void ) ;
static void atkC6_clearsemiinvulnerablebit ( void ) ;
static void atkC7_setminimize ( void ) ;
static void atkC8_sethail ( void ) ;
static void atkC9_jumpifattackandspecialattackcannotfall ( void ) ;
static void atkCA_setforcedtarget ( void ) ;
static void atkCB_setcharge ( void ) ;
static void atkCC_callterrainattack ( void ) ;
static void atkCD_cureifburnedparalysedorpoisoned ( void ) ;
static void atkCE_settorment ( void ) ;
static void atkCF_jumpifnodamage ( void ) ;
static void atkD0_settaunt ( void ) ;
2017-11-25 18:42:31 +01:00
static void atkD1_trysethelpinghand ( void ) ;
static void atkD2_tryswapitems ( void ) ;
static void atkD3_trycopyability ( void ) ;
static void atkD4_trywish ( void ) ;
static void atkD5_trysetroots ( void ) ;
2017-09-28 15:34:21 +02:00
static void atkD6_doubledamagedealtifdamaged ( void ) ;
static void atkD7_setyawn ( void ) ;
static void atkD8_setdamagetohealthdifference ( void ) ;
static void atkD9_scaledamagebyhealthratio ( void ) ;
2017-11-25 18:42:31 +01:00
static void atkDA_tryswapabilities ( void ) ;
static void atkDB_tryimprision ( void ) ;
static void atkDC_trysetgrudge ( void ) ;
2017-09-28 15:34:21 +02:00
static void atkDD_weightdamagecalculation ( void ) ;
static void atkDE_asistattackselect ( void ) ;
2017-11-25 18:42:31 +01:00
static void atkDF_trysetmagiccoat ( void ) ;
static void atkE0_trysetsnatch ( void ) ;
static void atkE1_trygetintimidatetarget ( void ) ;
static void atkE2_switchoutabilities ( void ) ;
2017-09-28 15:34:21 +02:00
static void atkE3_jumpifhasnohp ( void ) ;
static void atkE4_getsecretpowereffect ( void ) ;
static void atkE5_pickup ( void ) ;
2017-11-25 18:42:31 +01:00
static void atkE6_docastformchangeanimation ( void ) ;
static void atkE7_trycastformdatachange ( void ) ;
2017-09-28 15:34:21 +02:00
static void atkE8_settypebasedhalvers ( void ) ;
static void atkE9_setweatherballtype ( void ) ;
2017-11-25 18:42:31 +01:00
static void atkEA_tryrecycleitem ( void ) ;
2017-09-28 15:34:21 +02:00
static void atkEB_settypetoterrain ( void ) ;
2017-11-25 18:42:31 +01:00
static void atkEC_pursuitrelated ( void ) ;
static void atkEF_snatchsetbanks ( void ) ;
2017-09-28 15:34:21 +02:00
static void atkEE_removelightscreenreflect ( void ) ;
2017-11-26 01:19:57 +01:00
static void atkEF_handleballthrow ( void ) ;
2017-11-25 18:42:31 +01:00
static void atkF0_givecaughtmon ( void ) ;
static void atkF1_trysetcaughtmondexflags ( void ) ;
static void atkF2_displaydexinfo ( void ) ;
static void atkF3_trygivecaughtmonnick ( void ) ;
2017-09-28 15:34:21 +02:00
static void atkF4_subattackerhpbydmg ( void ) ;
static void atkF5_removeattackerstatus1 ( void ) ;
2017-11-25 18:42:31 +01:00
static void atkF6_finishaction ( void ) ;
static void atkF7_finishturn ( void ) ;
static void atkF8_trainerslideout ( void ) ;
2017-09-04 15:05:11 +02:00
void ( * const gBattleScriptingCommandsTable [ ] ) ( void ) =
{
atk00_attackcanceler ,
atk01_accuracycheck ,
atk02_attackstring ,
atk03_ppreduce ,
atk04_critcalc ,
2017-11-25 18:42:31 +01:00
atk05_damagecalc ,
2017-09-04 15:05:11 +02:00
atk06_typecalc ,
2017-11-25 18:42:31 +01:00
atk07_adjustnormaldamage ,
atk08_adjustnormaldamage2 ,
2017-09-04 15:05:11 +02:00
atk09_attackanimation ,
atk0A_waitanimation ,
atk0B_healthbarupdate ,
atk0C_datahpupdate ,
atk0D_critmessage ,
2017-11-25 18:42:31 +01:00
atk0E_effectivenesssound ,
2017-09-04 15:05:11 +02:00
atk0F_resultmessage ,
atk10_printstring ,
2017-11-25 18:42:31 +01:00
atk11_printselectionstring ,
2017-09-04 15:05:11 +02:00
atk12_waitmessage ,
atk13_printfromtable ,
2017-11-25 18:42:31 +01:00
atk14_printselectionstringfromtable ,
2017-09-27 23:43:45 +02:00
atk15_seteffectwithchance ,
2017-09-04 15:05:11 +02:00
atk16_seteffectprimary ,
atk17_seteffectsecondary ,
2017-11-25 18:42:31 +01:00
atk18_clearstatusfromeffect ,
atk19_tryfaintmon ,
atk1A_dofaintanimation ,
atk1B_cleareffectsonfaint ,
2017-09-04 15:05:11 +02:00
atk1C_jumpifstatus ,
atk1D_jumpifstatus2 ,
atk1E_jumpifability ,
atk1F_jumpifsideaffecting ,
atk20_jumpifstat ,
2017-11-26 11:55:17 +01:00
atk21_jumpifstatus3condition ,
2017-09-04 15:05:11 +02:00
atk22_jumpiftype ,
atk23_getexp ,
atk24 ,
2017-11-25 18:42:31 +01:00
atk25_movevaluescleanup ,
atk26_setmultihit ,
atk27_decrementmultihit ,
2017-09-04 15:05:11 +02:00
atk28_goto ,
atk29_jumpifbyte ,
atk2A_jumpifhalfword ,
atk2B_jumpifword ,
atk2C_jumpifarrayequal ,
atk2D_jumpifarraynotequal ,
atk2E_setbyte ,
atk2F_addbyte ,
atk30_subbyte ,
atk31_copyarray ,
2017-11-25 18:42:31 +01:00
atk32_copyarraywithindex ,
2017-09-04 15:05:11 +02:00
atk33_orbyte ,
atk34_orhalfword ,
atk35_orword ,
atk36_bicbyte ,
atk37_bichalfword ,
atk38_bicword ,
atk39_pause ,
atk3A_waitstate ,
atk3B_healthbar_update ,
atk3C_return ,
atk3D_end ,
atk3E_end2 ,
atk3F_end3 ,
2017-11-25 18:42:31 +01:00
atk40_jumpifaffectedbyprotect ,
2017-09-04 15:05:11 +02:00
atk41_call ,
atk42_jumpiftype2 ,
atk43_jumpifabilitypresent ,
2017-11-25 18:42:31 +01:00
atk44_endselectionscript ,
2017-09-04 15:05:11 +02:00
atk45_playanimation ,
atk46_playanimation2 ,
atk47_setgraphicalstatchangevalues ,
atk48_playstatchangeanimation ,
2017-09-23 20:13:45 +02:00
atk49_moveend ,
2017-09-04 15:05:11 +02:00
atk4A_typecalc2 ,
2017-11-25 18:42:31 +01:00
atk4B_returnatktoball ,
atk4C_getswitchedmondata ,
atk4D_switchindataupdate ,
atk4E_switchinanim ,
atk4F_jumpifcantswitch ,
2017-09-04 15:05:11 +02:00
atk50_openpartyscreen ,
2017-11-25 18:42:31 +01:00
atk51_switchhandleorder ,
atk52_switchineffects ,
atk53_trainerslidein ,
atk54_playse ,
atk55_fanfare ,
atk56_playfaintcry ,
2017-09-04 15:05:11 +02:00
atk57 ,
2017-11-25 18:42:31 +01:00
atk58_returntoball ,
atk59_handlelearnnewmove ,
2017-09-25 00:09:13 +02:00
atk5A_yesnoboxlearnmove ,
atk5B_yesnoboxstoplearningmove ,
2017-09-04 15:05:11 +02:00
atk5C_hitanimation ,
atk5D_getmoneyreward ,
2017-11-25 18:42:31 +01:00
atk5E ,
atk5F ,
atk60_incrementgamestat ,
atk61_drawpartystatussummary ,
atk62 ,
2017-09-04 15:05:11 +02:00
atk63_jumptorandomattack ,
atk64_statusanimation ,
atk65_status2animation ,
atk66_chosenstatusanimation ,
2017-09-25 00:09:13 +02:00
atk67_yesnobox ,
2017-11-25 18:42:31 +01:00
atk68_cancelallactions ,
atk69_adjustsetdamage ,
2017-09-04 15:05:11 +02:00
atk6A_removeitem ,
atk6B_atknameinbuff1 ,
2017-11-25 18:42:31 +01:00
atk6C_drawlvlupbox ,
atk6D_resetsentmonsvalue ,
atk6E_setatktoplayer0 ,
atk6F_makevisible ,
atk70_recordlastability ,
atk71_buffermovetolearn ,
atk72_jumpifplayerran ,
atk73_hpthresholds ,
atk74_hpthresholds2 ,
atk75_useitemonopponent ,
2017-09-04 15:05:11 +02:00
atk76_various ,
2017-11-25 18:42:31 +01:00
atk77_setprotectlike ,
2017-09-04 15:05:11 +02:00
atk78_faintifabilitynotdamp ,
atk79_setatkhptozero ,
2017-11-25 18:42:31 +01:00
atk7A_jumpifnexttargetvalid ,
atk7B_tryhealhalfhealth ,
2017-09-26 22:39:59 +02:00
atk7C_trymirrormove ,
2017-11-25 18:42:31 +01:00
atk7D_setrain ,
2017-09-04 15:05:11 +02:00
atk7E_setreflect ,
atk7F_setseeded ,
atk80_manipulatedamage ,
2017-11-25 18:42:31 +01:00
atk81_trysetrest ,
2017-09-04 15:05:11 +02:00
atk82_jumpifnotfirstturn ,
atk83_nop ,
2017-11-25 18:42:31 +01:00
atk84_jumpifcantmakeasleep ,
2017-09-04 15:05:11 +02:00
atk85_stockpile ,
atk86_stockpiletobasedamage ,
atk87_stockpiletohpheal ,
atk88_negativedamage ,
atk89_statbuffchange ,
atk8A_normalisebuffs ,
atk8B_setbide ,
atk8C_confuseifrepeatingattackends ,
2017-11-25 18:42:31 +01:00
atk8D_setmultihitcounter ,
atk8E_initmultihitstring ,
2017-09-04 15:05:11 +02:00
atk8F_forcerandomswitch ,
2017-11-25 18:42:31 +01:00
atk90_tryconversiontypechange ,
2017-09-04 15:05:11 +02:00
atk91_givepaydaymoney ,
atk92_setlightscreen ,
2017-11-25 18:42:31 +01:00
atk93_tryKO ,
2017-09-26 22:39:59 +02:00
atk94_damagetohalftargethp ,
2017-09-04 15:05:11 +02:00
atk95_setsandstorm ,
atk96_weatherdamage ,
2017-11-25 18:42:31 +01:00
atk97_tryinfatuating ,
atk98_updatestatusicon ,
2017-09-04 15:05:11 +02:00
atk99_setmist ,
2017-11-25 18:42:31 +01:00
atk9A_setfocusenergy ,
2017-09-04 15:05:11 +02:00
atk9B_transformdataexecution ,
2017-11-25 18:42:31 +01:00
atk9C_setsubstitute ,
2017-09-26 22:39:59 +02:00
atk9D_mimicattackcopy ,
2017-09-04 15:05:11 +02:00
atk9E_metronome ,
atk9F_dmgtolevel ,
atkA0_psywavedamageeffect ,
atkA1_counterdamagecalculator ,
atkA2_mirrorcoatdamagecalculator ,
atkA3_disablelastusedattack ,
2017-11-25 18:42:31 +01:00
atkA4_trysetencore ,
2017-09-04 15:05:11 +02:00
atkA5_painsplitdmgcalc ,
atkA6_settypetorandomresistance ,
atkA7_setalwayshitflag ,
atkA8_copymovepermanently ,
2017-11-26 01:19:57 +01:00
atkA9_trychoosesleeptalkmove ,
2017-11-25 18:42:31 +01:00
atkAA_setdestinybond ,
atkAB_trysetdestinybondtohappen ,
2017-09-04 15:05:11 +02:00
atkAC_remaininghptopower ,
2017-11-25 18:42:31 +01:00
atkAD_tryspiteppreduce ,
atkAE_healpartystatus ,
2017-09-04 15:05:11 +02:00
atkAF_cursetarget ,
2017-11-25 18:42:31 +01:00
atkB0_trysetspikes ,
atkB1_setforesight ,
atkB2_trysetperishsong ,
2017-09-04 15:05:11 +02:00
atkB3_rolloutdamagecalculation ,
atkB4_jumpifconfusedandstatmaxed ,
atkB5_furycuttercalc ,
atkB6_happinesstodamagecalculation ,
atkB7_presentdamagecalculation ,
2017-11-25 18:42:31 +01:00
atkB8_setsafeguard ,
2017-09-04 15:05:11 +02:00
atkB9_magnitudedamagecalculation ,
atkBA_jumpifnopursuitswitchdmg ,
atkBB_setsunny ,
atkBC_maxattackhalvehp ,
atkBD_copyfoestats ,
2017-09-27 23:43:45 +02:00
atkBE_rapidspinfree ,
2017-11-25 18:42:31 +01:00
atkBF_setdefensecurlbit ,
2017-09-04 15:05:11 +02:00
atkC0_recoverbasedonsunlight ,
2017-11-25 18:42:31 +01:00
atkC1_hiddenpowercalc ,
atkC2_selectfirstvalidtarget ,
atkC3_trysetfutureattack ,
atkC4_trydobeatup ,
2017-09-27 23:43:45 +02:00
atkC5_setsemiinvulnerablebit ,
atkC6_clearsemiinvulnerablebit ,
2017-09-04 15:05:11 +02:00
atkC7_setminimize ,
atkC8_sethail ,
atkC9_jumpifattackandspecialattackcannotfall ,
atkCA_setforcedtarget ,
atkCB_setcharge ,
atkCC_callterrainattack ,
atkCD_cureifburnedparalysedorpoisoned ,
atkCE_settorment ,
atkCF_jumpifnodamage ,
atkD0_settaunt ,
2017-11-25 18:42:31 +01:00
atkD1_trysethelpinghand ,
atkD2_tryswapitems ,
atkD3_trycopyability ,
atkD4_trywish ,
atkD5_trysetroots ,
2017-09-04 15:05:11 +02:00
atkD6_doubledamagedealtifdamaged ,
atkD7_setyawn ,
atkD8_setdamagetohealthdifference ,
atkD9_scaledamagebyhealthratio ,
2017-11-25 18:42:31 +01:00
atkDA_tryswapabilities ,
atkDB_tryimprision ,
atkDC_trysetgrudge ,
2017-09-04 15:05:11 +02:00
atkDD_weightdamagecalculation ,
atkDE_asistattackselect ,
2017-11-25 18:42:31 +01:00
atkDF_trysetmagiccoat ,
atkE0_trysetsnatch ,
atkE1_trygetintimidatetarget ,
atkE2_switchoutabilities ,
2017-09-27 23:43:45 +02:00
atkE3_jumpifhasnohp ,
2017-09-04 15:05:11 +02:00
atkE4_getsecretpowereffect ,
atkE5_pickup ,
2017-11-25 18:42:31 +01:00
atkE6_docastformchangeanimation ,
atkE7_trycastformdatachange ,
2017-09-04 15:05:11 +02:00
atkE8_settypebasedhalvers ,
atkE9_setweatherballtype ,
2017-11-25 18:42:31 +01:00
atkEA_tryrecycleitem ,
2017-09-04 15:05:11 +02:00
atkEB_settypetoterrain ,
2017-11-25 18:42:31 +01:00
atkEC_pursuitrelated ,
atkEF_snatchsetbanks ,
2017-09-04 15:05:11 +02:00
atkEE_removelightscreenreflect ,
2017-11-26 01:19:57 +01:00
atkEF_handleballthrow ,
2017-11-25 18:42:31 +01:00
atkF0_givecaughtmon ,
atkF1_trysetcaughtmondexflags ,
atkF2_displaydexinfo ,
atkF3_trygivecaughtmonnick ,
2017-09-28 15:34:21 +02:00
atkF4_subattackerhpbydmg ,
2017-09-04 15:05:11 +02:00
atkF5_removeattackerstatus1 ,
2017-11-25 18:42:31 +01:00
atkF6_finishaction ,
atkF7_finishturn ,
atkF8_trainerslideout
2017-09-04 15:05:11 +02:00
} ;
2017-09-19 21:01:12 +02:00
struct StatFractions
2017-09-04 15:05:11 +02:00
{
u8 dividend ;
u8 divisor ;
} ;
2017-09-28 16:51:24 +02:00
static const struct StatFractions sAccuracyStageRatios [ ] =
2017-09-04 15:05:11 +02:00
{
{ 33 , 100 } , // -6
{ 36 , 100 } , // -5
{ 43 , 100 } , // -4
{ 50 , 100 } , // -3
{ 60 , 100 } , // -2
{ 75 , 100 } , // -1
{ 1 , 1 } , // 0
{ 133 , 100 } , // +1
{ 166 , 100 } , // +2
{ 2 , 1 } , // +3
{ 233 , 100 } , // +4
{ 133 , 50 } , // +5
{ 3 , 1 } , // +6
} ;
// The chance is 1/N for each stage.
2017-09-28 16:51:24 +02:00
static const u16 sCriticalHitChance [ ] = { 16 , 8 , 4 , 3 , 2 } ;
2017-09-04 15:05:11 +02:00
2017-09-28 16:51:24 +02:00
static const u32 sStatusFlagsForMoveEffects [ ] =
2017-09-04 15:05:11 +02:00
{
0x00000000 ,
2017-09-20 22:54:26 +02:00
STATUS_SLEEP ,
STATUS_POISON ,
STATUS_BURN ,
STATUS_FREEZE ,
STATUS_PARALYSIS ,
STATUS_TOXIC_POISON ,
STATUS2_CONFUSION ,
STATUS2_FLINCHED ,
2017-09-04 15:05:11 +02:00
0x00000000 ,
2017-09-22 21:33:49 +02:00
STATUS2_UPROAR ,
2017-09-04 15:05:11 +02:00
0x00000000 ,
2017-09-22 21:33:49 +02:00
STATUS2_MULTIPLETURNS ,
STATUS2_WRAPPED ,
2017-09-04 15:05:11 +02:00
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
2017-09-22 21:33:49 +02:00
STATUS2_RECHARGE ,
2017-09-04 15:05:11 +02:00
0x00000000 ,
0x00000000 ,
2017-09-22 21:33:49 +02:00
STATUS2_ESCAPE_PREVENTION ,
2017-11-11 20:01:04 +01:00
STATUS2_NIGHTMARE ,
2017-09-04 15:05:11 +02:00
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
2017-09-22 21:33:49 +02:00
STATUS2_LOCK_CONFUSE ,
2017-09-04 15:05:11 +02:00
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000 ,
0x00000000
} ;
2017-09-19 21:01:12 +02:00
2017-09-28 16:51:24 +02:00
static const u8 * const sMoveEffectBS_Ptrs [ ] =
2017-09-26 22:39:59 +02:00
{
BattleScript_MoveEffectSleep , // 0
BattleScript_MoveEffectSleep , // MOVE_EFFECT_SLEEP
BattleScript_MoveEffectPoison , // MOVE_EFFECT_POISON
BattleScript_MoveEffectBurn , // MOVE_EFFECT_BURN
BattleScript_MoveEffectFreeze , // MOVE_EFFECT_FREEZE
BattleScript_MoveEffectParalysis , // MOVE_EFFECT_PARALYSIS
BattleScript_MoveEffectToxic , // MOVE_EFFECT_TOXIC
BattleScript_MoveEffectConfusion , // MOVE_EFFECT_CONFUSION
BattleScript_MoveEffectSleep , // MOVE_EFFECT_FLINCH
BattleScript_MoveEffectSleep , // MOVE_EFFECT_TRI_ATTACK
BattleScript_MoveEffectUproar , // MOVE_EFFECT_UPROAR
BattleScript_MoveEffectPayDay , // MOVE_EFFECT_PAYDAY
BattleScript_MoveEffectSleep , // MOVE_EFFECT_CHARGING
BattleScript_MoveEffectWrap , // MOVE_EFFECT_WRAP
BattleScript_MoveEffectRecoil33 , // MOVE_EFFECT_RECOIL_25
BattleScript_MoveEffectSleep , // MOVE_EFFECT_ATK_PLUS_1
BattleScript_MoveEffectSleep , // MOVE_EFFECT_DEF_PLUS_1
BattleScript_MoveEffectSleep , // MOVE_EFFECT_SPD_PLUS_1
BattleScript_MoveEffectSleep , // MOVE_EFFECT_SP_ATK_PLUS_1
BattleScript_MoveEffectSleep , // MOVE_EFFECT_SP_DEF_PLUS_1
BattleScript_MoveEffectSleep , // MOVE_EFFECT_ACC_PLUS_1
BattleScript_MoveEffectSleep , // MOVE_EFFECT_EVS_PLUS_1
BattleScript_MoveEffectSleep , // MOVE_EFFECT_ATK_MINUS_1
BattleScript_MoveEffectSleep , // MOVE_EFFECT_DEF_MINUS_1
BattleScript_MoveEffectSleep , // MOVE_EFFECT_SPD_MINUS_1
BattleScript_MoveEffectSleep , // MOVE_EFFECT_SP_ATK_MINUS_1
BattleScript_MoveEffectSleep , // MOVE_EFFECT_SP_DEF_MINUS_1
BattleScript_MoveEffectSleep , // MOVE_EFFECT_ACC_MINUS_1
BattleScript_MoveEffectSleep , // MOVE_EFFECT_EVS_MINUS_1
BattleScript_MoveEffectSleep , // MOVE_EFFECT_RECHARGE
BattleScript_MoveEffectSleep , // MOVE_EFFECT_RAGE
BattleScript_MoveEffectSleep , // MOVE_EFFECT_STEAL_ITEM
BattleScript_MoveEffectSleep , // MOVE_EFFECT_PREVENT_ESCAPE
BattleScript_MoveEffectSleep , // MOVE_EFFECT_NIGHTMARE
BattleScript_MoveEffectSleep , // MOVE_EFFECT_ALL_STATS_UP
BattleScript_MoveEffectSleep , // MOVE_EFFECT_RAPIDSPIN
BattleScript_MoveEffectSleep , // MOVE_EFFECT_REMOVE_PARALYSIS
BattleScript_MoveEffectSleep , // MOVE_EFFECT_ATK_DEF_DOWN
BattleScript_MoveEffectRecoil33 , // MOVE_EFFECT_RECOIL_33_PARALYSIS
} ;
static const struct WindowTemplate sUnusedWinTemplate = { 0 , 1 , 3 , 7 , 0xF , 0x1F , 0x3F } ;
2017-09-28 16:51:24 +02:00
static const u16 sUnknown_0831C2C8 [ ] = INCBIN_U16 ( " graphics/battle_interface/unk_battlebox.gbapal " ) ;
static const u8 sUnknown_0831C2E8 [ ] = INCBIN_U8 ( " graphics/battle_interface/unk_battlebox.4bpp.lz " ) ;
2017-09-28 16:32:23 +02:00
// unused
static const u8 sRubyLevelUpStatBoxStats [ ] =
{
MON_DATA_MAX_HP , MON_DATA_SPATK , MON_DATA_ATK ,
2017-10-24 03:43:26 +02:00
MON_DATA_SPDEF , MON_DATA_DEF , MON_DATA_SPEED
2017-09-28 16:32:23 +02:00
} ;
# define MON_ICON_LVLUP_BOX_TAG 0xD75A
2017-09-28 16:51:24 +02:00
static const struct OamData sOamData_MonIconOnLvlUpBox =
2017-09-28 16:32:23 +02:00
{
. y = 0 ,
. affineMode = 0 ,
. objMode = 0 ,
. mosaic = 0 ,
. bpp = 0 ,
. shape = 0 ,
. x = 0 ,
. matrixNum = 0 ,
. size = 2 ,
. tileNum = 0 ,
. priority = 0 ,
. paletteNum = 0 ,
. affineParam = 0 ,
} ;
2017-09-28 16:51:24 +02:00
static const struct SpriteTemplate sSpriteTemplate_MonIconOnLvlUpBox =
2017-09-28 16:32:23 +02:00
{
. tileTag = MON_ICON_LVLUP_BOX_TAG ,
. paletteTag = MON_ICON_LVLUP_BOX_TAG ,
2017-09-28 16:51:24 +02:00
. oam = & sOamData_MonIconOnLvlUpBox ,
2017-09-28 16:32:23 +02:00
. anims = gDummySpriteAnimTable ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
. callback = SpriteCB_MonIconOnLvlUpBox
} ;
2017-09-28 16:51:24 +02:00
static const u16 sProtectSuccessRates [ ] = { USHRT_MAX , USHRT_MAX / 2 , USHRT_MAX / 4 , USHRT_MAX / 8 } ;
2017-09-28 15:34:21 +02:00
# define MIMIC_FORBIDDEN_END 0xFFFE
# define METRONOME_FORBIDDEN_END 0xFFFF
# define ASSIST_FORBIDDEN_END 0xFFFF
2017-09-20 22:54:26 +02:00
2017-09-28 16:51:24 +02:00
static const u16 sMovesForbiddenToCopy [ ] =
2017-09-28 16:32:23 +02:00
{
MOVE_METRONOME ,
MOVE_STRUGGLE ,
MOVE_SKETCH ,
MOVE_MIMIC ,
MIMIC_FORBIDDEN_END ,
MOVE_COUNTER ,
MOVE_MIRROR_COAT ,
MOVE_PROTECT ,
MOVE_DETECT ,
MOVE_ENDURE ,
MOVE_DESTINY_BOND ,
MOVE_SLEEP_TALK ,
MOVE_THIEF ,
MOVE_FOLLOW_ME ,
MOVE_SNATCH ,
MOVE_HELPING_HAND ,
MOVE_COVET ,
MOVE_TRICK ,
MOVE_FOCUS_PUNCH ,
METRONOME_FORBIDDEN_END
} ;
static const u8 sFlailHpScaleToPowerTable [ ] =
{
1 , 200 ,
4 , 150 ,
9 , 100 ,
16 , 80 ,
32 , 40 ,
48 , 20
} ;
static const u16 sNaturePowerMoves [ ] =
{
MOVE_STUN_SPORE ,
MOVE_RAZOR_LEAF ,
MOVE_EARTHQUAKE ,
MOVE_HYDRO_PUMP ,
MOVE_SURF ,
MOVE_BUBBLE_BEAM ,
MOVE_ROCK_SLIDE ,
MOVE_SHADOW_BALL ,
MOVE_SWIFT ,
MOVE_SWIFT
} ;
// format: min. weight (hectograms), base power
static const u16 sWeightToDamageTable [ ] =
{
100 , 20 ,
250 , 40 ,
500 , 60 ,
1000 , 80 ,
2000 , 100 ,
0xFFFF , 0xFFFF
} ;
2017-09-28 16:51:24 +02:00
static const u16 sPickupItems [ ] =
2017-09-28 16:32:23 +02:00
{
ITEM_POTION ,
ITEM_ANTIDOTE ,
ITEM_SUPER_POTION ,
ITEM_GREAT_BALL ,
ITEM_REPEL ,
ITEM_ESCAPE_ROPE ,
ITEM_X_ATTACK ,
ITEM_FULL_HEAL ,
ITEM_ULTRA_BALL ,
ITEM_HYPER_POTION ,
ITEM_RARE_CANDY ,
ITEM_PROTEIN ,
ITEM_REVIVE ,
ITEM_HP_UP ,
ITEM_FULL_RESTORE ,
ITEM_MAX_REVIVE ,
ITEM_PP_UP ,
ITEM_MAX_ELIXIR ,
} ;
2017-09-28 16:51:24 +02:00
static const u16 sRarePickupItems [ ] =
2017-09-28 16:32:23 +02:00
{
ITEM_HYPER_POTION ,
ITEM_NUGGET ,
ITEM_KINGS_ROCK ,
ITEM_FULL_RESTORE ,
ITEM_ETHER ,
ITEM_WHITE_HERB ,
ITEM_TM44 ,
ITEM_ELIXIR ,
ITEM_TM01 ,
ITEM_LEFTOVERS ,
ITEM_TM26 ,
} ;
2017-09-28 16:51:24 +02:00
static const u8 sPickupProbabilities [ ] =
2017-09-28 16:32:23 +02:00
{
30 , 40 , 50 , 60 , 70 , 80 , 90 , 94 , 98
} ;
static const u8 sTerrainToType [ ] =
{
TYPE_GRASS , // tall grass
TYPE_GRASS , // long grass
TYPE_GROUND , // sand
TYPE_WATER , // underwater
TYPE_WATER , // water
TYPE_WATER , // pond water
2017-09-28 16:51:24 +02:00
TYPE_ROCK , // rock
TYPE_ROCK , // cave
2017-09-28 16:32:23 +02:00
TYPE_NORMAL , // building
TYPE_NORMAL , // plain
} ;
static const u8 sBallCatchBonuses [ ] =
{
20 , 15 , 10 , 15 // Ultra, Great, Poke, Safari
} ;
2017-11-04 16:11:13 +01:00
const ALIGNED ( 4 ) u8 gUnknown_0831C494 [ ] [ 4 ] =
{
{ 0x3d , 0x44 , 0x3d , 0x44 } ,
{ 0x14 , 0x2d , 0x54 , 0x5c } ,
{ 0x46 , 0x55 , 0x20 , 0x5c } ,
{ 0x26 , 0x45 , 0x46 , 0x55 } ,
{ 0x14 , 0x5a , 0x46 , 0x5c } ,
{ 0x1e , 0x32 , 0x20 , 0x5a } ,
{ 0x38 , 0x4e , 0x38 , 0x4e } ,
{ 0x19 , 0x28 , 0x4b , 0x5a } ,
{ 0x45 , 0x4b , 0x1c , 0x53 } ,
{ 0x23 , 0x2d , 0x1d , 0x23 } ,
{ 0x3e , 0x48 , 0x1e , 0x32 } ,
{ 0x3a , 0x5f , 0x58 , 0x5e } ,
{ 0x22 , 0x2d , 0x1d , 0x28 } ,
{ 0x23 , 0x28 , 0x23 , 0x5f } ,
{ 0x38 , 0x4e , 0x38 , 0x4e } ,
{ 0x23 , 0x50 , 0x22 , 0x5e } ,
{ 0x2c , 0x5e , 0x22 , 0x28 } ,
{ 0x38 , 0x4e , 0x38 , 0x4e } ,
{ 0x1e , 0x58 , 0x1e , 0x58 } ,
{ 0x1e , 0x2b , 0x1b , 0x21 } ,
{ 0x28 , 0x5a , 0x19 , 0x57 } ,
{ 0x12 , 0x58 , 0x5a , 0x5f } ,
{ 0x58 , 0x5e , 0x16 , 0x2a } ,
{ 0x2a , 0x5c , 0x2a , 0x2f } ,
{ 0x38 , 0x4e , 0x38 , 0x4e }
2017-09-28 16:51:24 +02:00
} ;
static const u8 sUnknown_0831C4F8 [ ] =
{
0x03 , 0x00 , 0x01 , 0x00 , 0x00 , 0x01 , 0x03 , 0x00 ,
0x01 , 0x02 , 0x02 , 0x00 , 0x03 , 0x01 , 0x03 , 0x01 ,
0x02 , 0x03 , 0x03 , 0x02 , 0x01 , 0x00 , 0x02 , 0x02 ,
0x03 , 0x00 , 0x00 , 0x00
} ;
2017-09-28 16:32:23 +02:00
2017-09-28 15:34:21 +02:00
static void atk00_attackcanceler ( void )
2017-09-19 21:01:12 +02:00
{
s32 i ;
2017-10-06 00:12:01 +02:00
if ( gBattleOutcome ! = 0 )
2017-09-19 21:01:12 +02:00
{
2017-10-06 00:12:01 +02:00
gCurrentActionFuncId = ACTION_FINISHED ;
2017-09-19 21:01:12 +02:00
return ;
}
if ( gBattleMons [ gBankAttacker ] . hp = = 0 & & ! ( gHitMarker & HITMARKER_NO_ATTACKSTRING ) )
{
gHitMarker | = HITMARKER_UNABLE_TO_USE_MOVE ;
gBattlescriptCurrInstr = BattleScript_MoveEnd ;
return ;
}
if ( AtkCanceller_UnableToUseMove ( ) )
return ;
if ( AbilityBattleEffects ( ABILITYEFFECT_MOVES_BLOCK , gBankTarget , 0 , 0 , 0 ) )
return ;
if ( ! gBattleMons [ gBankAttacker ] . pp [ gCurrMovePos ] & & gCurrentMove ! = MOVE_STRUGGLE & & ! ( gHitMarker & 0x800200 )
& & ! ( gBattleMons [ gBankAttacker ] . status2 & STATUS2_MULTIPLETURNS ) )
{
gBattlescriptCurrInstr = BattleScript_NoPPForMove ;
gBattleMoveFlags | = MOVESTATUS_MISSED ;
return ;
}
gHitMarker & = ~ ( HITMARKER_x800000 ) ;
if ( ! ( gHitMarker & HITMARKER_OBEYS ) & & ! ( gBattleMons [ gBankAttacker ] . status2 & STATUS2_MULTIPLETURNS ) )
{
i = IsPokeDisobedient ( ) ; // why use the 'i' variable...?
switch ( i )
{
case 0 :
break ;
case 2 :
gHitMarker | = HITMARKER_OBEYS ;
return ;
default :
gBattleMoveFlags | = MOVESTATUS_MISSED ;
return ;
}
}
gHitMarker | = HITMARKER_OBEYS ;
if ( gProtectStructs [ gBankTarget ] . bounceMove & & gBattleMoves [ gCurrentMove ] . flags & FLAG_MAGICCOAT_AFFECTED )
{
PressurePPLose ( gBankAttacker , gBankTarget , MOVE_MAGIC_COAT ) ;
gProtectStructs [ gBankTarget ] . bounceMove = 0 ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-19 21:01:12 +02:00
gBattlescriptCurrInstr = BattleScript_MagicCoatBounce ;
return ;
}
for ( i = 0 ; i < gNoOfAllBanks ; i + + )
{
2017-10-04 19:25:14 +02:00
if ( ( gProtectStructs [ gBanksByTurnOrder [ i ] ] . stealMove ) & & gBattleMoves [ gCurrentMove ] . flags & FLAG_SNATCH_AFFECTED )
2017-09-19 21:01:12 +02:00
{
2017-10-04 19:25:14 +02:00
PressurePPLose ( gBankAttacker , gBanksByTurnOrder [ i ] , MOVE_SNATCH ) ;
gProtectStructs [ gBanksByTurnOrder [ i ] ] . stealMove = 0 ;
gBattleScripting . bank = gBanksByTurnOrder [ i ] ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-19 21:01:12 +02:00
gBattlescriptCurrInstr = BattleScript_SnatchedMove ;
return ;
}
}
if ( gSpecialStatuses [ gBankTarget ] . lightningRodRedirected )
{
gSpecialStatuses [ gBankTarget ] . lightningRodRedirected = 0 ;
gLastUsedAbility = ABILITY_LIGHTNING_ROD ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-19 21:01:12 +02:00
gBattlescriptCurrInstr = BattleScript_TookAttack ;
RecordAbilityBattle ( gBankTarget , gLastUsedAbility ) ;
}
else if ( TARGET_PROTECT_AFFECTED
& & ( gCurrentMove ! = MOVE_CURSE | | ( gBattleMons [ gBankAttacker ] . type1 = = TYPE_GHOST | | gBattleMons [ gBankAttacker ] . type2 = = TYPE_GHOST ) )
& & ( ( ! IsTwoTurnsMove ( gCurrentMove ) | | ( gBattleMons [ gBankAttacker ] . status2 & STATUS2_MULTIPLETURNS ) ) ) )
{
CancelMultiTurnMoves ( gBankAttacker ) ;
gBattleMoveFlags | = MOVESTATUS_MISSED ;
2017-11-26 14:17:02 +01:00
gLastLandedMoves [ gBankTarget ] = 0 ;
gLastHitByType [ gBankTarget ] = 0 ;
2017-09-19 21:01:12 +02:00
gBattleCommunication [ 6 ] = 1 ;
gBattlescriptCurrInstr + + ;
}
else
{
gBattlescriptCurrInstr + + ;
}
}
2017-09-28 15:34:21 +02:00
static void JumpIfMoveFailed ( u8 adder , u16 move )
2017-09-19 21:01:12 +02:00
{
2017-11-26 14:17:02 +01:00
const u8 * BS_ptr = gBattlescriptCurrInstr + adder ;
2017-09-19 21:01:12 +02:00
if ( gBattleMoveFlags & MOVESTATUS_NOEFFECT )
{
2017-11-26 14:17:02 +01:00
gLastLandedMoves [ gBankTarget ] = 0 ;
gLastHitByType [ gBankTarget ] = 0 ;
2017-09-19 21:01:12 +02:00
BS_ptr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
2017-11-25 18:42:31 +01:00
TrySetDestinyBondToHappen ( ) ;
2017-09-19 21:01:12 +02:00
if ( AbilityBattleEffects ( ABILITYEFFECT_ABSORBING , gBankTarget , 0 , 0 , move ) )
return ;
}
gBattlescriptCurrInstr = BS_ptr ;
}
2017-11-25 18:42:31 +01:00
static void atk40_jumpifaffectedbyprotect ( void )
2017-09-19 21:01:12 +02:00
{
if ( TARGET_PROTECT_AFFECTED )
{
gBattleMoveFlags | = MOVESTATUS_MISSED ;
JumpIfMoveFailed ( 5 , 0 ) ;
gBattleCommunication [ 6 ] = 1 ;
}
else
{
gBattlescriptCurrInstr + = 5 ;
}
}
bool8 JumpIfMoveAffectedByProtect ( u16 move )
{
bool8 affected = FALSE ;
if ( TARGET_PROTECT_AFFECTED )
{
gBattleMoveFlags | = MOVESTATUS_MISSED ;
JumpIfMoveFailed ( 7 , move ) ;
gBattleCommunication [ 6 ] = 1 ;
affected = TRUE ;
}
return affected ;
}
2017-11-11 20:01:04 +01:00
static bool8 AccuracyCalcHelper ( u16 move )
2017-09-19 21:01:12 +02:00
{
if ( gStatuses3 [ gBankTarget ] & STATUS3_ALWAYS_HITS & & gDisableStructs [ gBankTarget ] . bankWithSureHit = = gBankAttacker )
{
JumpIfMoveFailed ( 7 , move ) ;
return TRUE ;
}
if ( ! ( gHitMarker & HITMARKER_IGNORE_ON_AIR ) & & gStatuses3 [ gBankTarget ] & STATUS3_ON_AIR )
{
gBattleMoveFlags | = MOVESTATUS_MISSED ;
JumpIfMoveFailed ( 7 , move ) ;
return TRUE ;
}
gHitMarker & = ~ HITMARKER_IGNORE_ON_AIR ;
if ( ! ( gHitMarker & HITMARKER_IGNORE_UNDERGROUND ) & & gStatuses3 [ gBankTarget ] & STATUS3_UNDERGROUND )
{
gBattleMoveFlags | = MOVESTATUS_MISSED ;
JumpIfMoveFailed ( 7 , move ) ;
return TRUE ;
}
gHitMarker & = ~ HITMARKER_IGNORE_UNDERGROUND ;
if ( ! ( gHitMarker & HITMARKER_IGNORE_UNDERWATER ) & & gStatuses3 [ gBankTarget ] & STATUS3_UNDERWATER )
{
gBattleMoveFlags | = MOVESTATUS_MISSED ;
JumpIfMoveFailed ( 7 , move ) ;
return TRUE ;
}
gHitMarker & = ~ HITMARKER_IGNORE_UNDERWATER ;
if ( ( WEATHER_HAS_EFFECT & & ( gBattleWeather & WEATHER_RAIN_ANY ) & & gBattleMoves [ move ] . effect = = EFFECT_THUNDER )
| | ( gBattleMoves [ move ] . effect = = EFFECT_ALWAYS_HIT | | gBattleMoves [ move ] . effect = = EFFECT_VITAL_THROW ) )
{
JumpIfMoveFailed ( 7 , move ) ;
return TRUE ;
}
return FALSE ;
}
2017-09-28 15:34:21 +02:00
static void atk01_accuracycheck ( void )
2017-09-19 21:01:12 +02:00
{
u16 move = BS2ScriptRead16 ( gBattlescriptCurrInstr + 5 ) ;
if ( move = = 0xFFFE | | move = = 0xFFFF )
{
if ( gStatuses3 [ gBankTarget ] & STATUS3_ALWAYS_HITS & & move = = 0xFFFF & & gDisableStructs [ gBankTarget ] . bankWithSureHit = = gBankAttacker )
gBattlescriptCurrInstr + = 7 ;
else if ( gStatuses3 [ gBankTarget ] & ( STATUS3_ON_AIR | STATUS3_UNDERGROUND | STATUS3_UNDERWATER ) )
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
else if ( ! JumpIfMoveAffectedByProtect ( 0 ) )
gBattlescriptCurrInstr + = 7 ;
}
else
{
u8 type , moveAcc , holdEffect , quality ;
s8 buff ;
u16 calc ;
if ( move = = 0 )
move = gCurrentMove ;
GET_MOVE_TYPE ( move , type ) ;
if ( JumpIfMoveAffectedByProtect ( move ) )
return ;
if ( AccuracyCalcHelper ( move ) )
return ;
if ( gBattleMons [ gBankTarget ] . status2 & STATUS2_FORESIGHT )
{
u8 acc = gBattleMons [ gBankAttacker ] . statStages [ STAT_STAGE_ACC ] ;
buff = acc ;
}
else
{
u8 acc = gBattleMons [ gBankAttacker ] . statStages [ STAT_STAGE_ACC ] ;
buff = acc + 6 - gBattleMons [ gBankTarget ] . statStages [ STAT_STAGE_EVASION ] ;
}
if ( buff < 0 )
buff = 0 ;
if ( buff > 0xC )
buff = 0xC ;
moveAcc = gBattleMoves [ move ] . accuracy ;
// check Thunder on sunny weather
if ( WEATHER_HAS_EFFECT & & gBattleWeather & WEATHER_SUN_ANY & & gBattleMoves [ move ] . effect = = EFFECT_THUNDER )
moveAcc = 50 ;
2017-09-28 16:51:24 +02:00
calc = sAccuracyStageRatios [ buff ] . dividend * moveAcc ;
calc / = sAccuracyStageRatios [ buff ] . divisor ;
2017-09-19 21:01:12 +02:00
if ( gBattleMons [ gBankAttacker ] . ability = = ABILITY_COMPOUND_EYES )
calc = ( calc * 130 ) / 100 ; // 1.3 compound eyes boost
if ( WEATHER_HAS_EFFECT & & gBattleMons [ gBankTarget ] . ability = = ABILITY_SAND_VEIL & & gBattleWeather & WEATHER_SANDSTORM_ANY )
calc = ( calc * 80 ) / 100 ; // 1.2 sand veil loss
if ( gBattleMons [ gBankAttacker ] . ability = = ABILITY_HUSTLE & & type < 9 )
calc = ( calc * 80 ) / 100 ; // 1.2 hustle loss
if ( gBattleMons [ gBankTarget ] . item = = ITEM_ENIGMA_BERRY )
{
holdEffect = gEnigmaBerries [ gBankTarget ] . holdEffect ;
quality = gEnigmaBerries [ gBankTarget ] . holdEffectParam ;
}
else
{
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ gBankTarget ] . item ) ;
quality = ItemId_GetHoldEffectParam ( gBattleMons [ gBankTarget ] . item ) ;
}
gStringBank = gBankTarget ;
if ( holdEffect = = HOLD_EFFECT_EVASION_UP )
calc = ( calc * ( 100 - quality ) ) / 100 ;
// final calculation
if ( ( Random ( ) % 100 + 1 ) > calc )
{
gBattleMoveFlags | = MOVESTATUS_MISSED ;
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE & &
( gBattleMoves [ move ] . target = = MOVE_TARGET_BOTH | | gBattleMoves [ move ] . target = = MOVE_TARGET_FOES_AND_ALLY ) )
gBattleCommunication [ 6 ] = 2 ;
else
gBattleCommunication [ 6 ] = 0 ;
2017-09-20 00:28:00 +02:00
CheckWonderGuardAndLevitate ( ) ;
2017-09-19 21:01:12 +02:00
}
JumpIfMoveFailed ( 7 , move ) ;
}
}
2017-09-28 15:34:21 +02:00
static void atk02_attackstring ( void )
2017-09-19 21:01:12 +02:00
{
if ( gBattleExecBuffer )
return ;
if ( ! ( gHitMarker & ( HITMARKER_NO_ATTACKSTRING | HITMARKER_ATTACKSTRING_PRINTED ) ) )
{
2017-10-07 15:15:47 +02:00
PrepareStringBattle ( STRINGID_USEDMOVE , gBankAttacker ) ;
2017-09-19 21:01:12 +02:00
gHitMarker | = HITMARKER_ATTACKSTRING_PRINTED ;
}
gBattlescriptCurrInstr + + ;
gBattleCommunication [ MSG_DISPLAY ] = 0 ;
}
2017-09-20 00:28:00 +02:00
2017-09-28 15:34:21 +02:00
static void atk03_ppreduce ( void )
2017-09-20 00:28:00 +02:00
{
2017-09-27 23:43:45 +02:00
s32 ppToDeduct = 1 ;
2017-09-20 00:28:00 +02:00
if ( gBattleExecBuffer )
return ;
if ( ! gSpecialStatuses [ gBankAttacker ] . flag20 )
{
switch ( gBattleMoves [ gCurrentMove ] . target )
{
case MOVE_TARGET_FOES_AND_ALLY :
2017-09-27 23:43:45 +02:00
ppToDeduct + = AbilityBattleEffects ( ABILITYEFFECT_COUNT_ON_FIELD , gBankAttacker , ABILITY_PRESSURE , 0 , 0 ) ;
2017-09-20 00:28:00 +02:00
break ;
case MOVE_TARGET_BOTH :
case MOVE_TARGET_OPPONENTS_FIELD :
2017-09-27 23:43:45 +02:00
ppToDeduct + = AbilityBattleEffects ( ABILITYEFFECT_COUNT_OTHER_SIDE , gBankAttacker , ABILITY_PRESSURE , 0 , 0 ) ;
2017-09-20 00:28:00 +02:00
break ;
default :
if ( gBankAttacker ! = gBankTarget & & gBattleMons [ gBankTarget ] . ability = = ABILITY_PRESSURE )
2017-09-27 23:43:45 +02:00
ppToDeduct + + ;
2017-09-20 00:28:00 +02:00
break ;
}
}
if ( ! ( gHitMarker & ( HITMARKER_NO_PPDEDUCT | HITMARKER_NO_ATTACKSTRING ) ) & & gBattleMons [ gBankAttacker ] . pp [ gCurrMovePos ] )
{
gProtectStructs [ gBankAttacker ] . notFirstStrike = 1 ;
2017-09-27 23:43:45 +02:00
if ( gBattleMons [ gBankAttacker ] . pp [ gCurrMovePos ] > ppToDeduct )
gBattleMons [ gBankAttacker ] . pp [ gCurrMovePos ] - = ppToDeduct ;
2017-09-20 00:28:00 +02:00
else
gBattleMons [ gBankAttacker ] . pp [ gCurrMovePos ] = 0 ;
if ( ! ( gBattleMons [ gBankAttacker ] . status2 & STATUS2_TRANSFORMED )
& & ! ( ( gDisableStructs [ gBankAttacker ] . unk18_b ) & gBitTable [ gCurrMovePos ] ) )
{
gActiveBank = gBankAttacker ;
2017-09-26 22:39:59 +02:00
EmitSetMonData ( 0 , REQUEST_PPMOVE1_BATTLE + gCurrMovePos , 0 , 1 , & gBattleMons [ gBankAttacker ] . pp [ gCurrMovePos ] ) ;
2017-09-20 00:28:00 +02:00
MarkBufferBankForExecution ( gBankAttacker ) ;
}
}
gHitMarker & = ~ ( HITMARKER_NO_PPDEDUCT ) ;
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk04_critcalc ( void )
2017-09-20 00:28:00 +02:00
{
u8 holdEffect ;
u16 item , critChance ;
item = gBattleMons [ gBankAttacker ] . item ;
if ( item = = ITEM_ENIGMA_BERRY )
holdEffect = gEnigmaBerries [ gBankAttacker ] . holdEffect ;
else
holdEffect = ItemId_GetHoldEffect ( item ) ;
gStringBank = gBankAttacker ;
critChance = 2 * ( ( gBattleMons [ gBankAttacker ] . status2 & STATUS2_FOCUS_ENERGY ) ! = 0 )
+ ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_HIGH_CRITICAL )
+ ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_SKY_ATTACK )
+ ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_BLAZE_KICK )
+ ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_POISON_TAIL )
+ ( holdEffect = = HOLD_EFFECT_SCOPE_LENS )
+ 2 * ( holdEffect = = HOLD_EFFECT_LUCKY_PUNCH & & gBattleMons [ gBankAttacker ] . species = = SPECIES_CHANSEY )
+ 2 * ( holdEffect = = HOLD_EFFECT_STICK & & gBattleMons [ gBankAttacker ] . species = = SPECIES_FARFETCHD ) ;
if ( critChance > 4 )
critChance = 4 ;
if ( ( gBattleMons [ gBankTarget ] . ability ! = ABILITY_BATTLE_ARMOR & & gBattleMons [ gBankTarget ] . ability ! = ABILITY_SHELL_ARMOR )
& & ! ( gStatuses3 [ gBankAttacker ] & STATUS3_CANT_SCORE_A_CRIT )
& & ! ( gBattleTypeFlags & ( BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_FIRST_BATTLE ) )
2017-09-28 16:51:24 +02:00
& & ! ( Random ( ) % sCriticalHitChance [ critChance ] ) )
2017-09-20 00:28:00 +02:00
gCritMultiplier = 2 ;
else
gCritMultiplier = 1 ;
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atk05_damagecalc ( void )
2017-09-20 00:28:00 +02:00
{
u16 sideStatus = gSideAffecting [ GET_BANK_SIDE ( gBankTarget ) ] ;
gBattleMoveDamage = CalculateBaseDamage ( & gBattleMons [ gBankAttacker ] , & gBattleMons [ gBankTarget ] , gCurrentMove ,
sideStatus , gDynamicBasePower ,
gBattleStruct - > dynamicMoveType , gBankAttacker , gBankTarget ) ;
gBattleMoveDamage = gBattleMoveDamage * gCritMultiplier * gBattleScripting . dmgMultiplier ;
if ( gStatuses3 [ gBankAttacker ] & STATUS3_CHARGED_UP & & gBattleMoves [ gCurrentMove ] . type = = TYPE_ELECTRIC )
gBattleMoveDamage * = 2 ;
if ( gProtectStructs [ gBankAttacker ] . helpingHand )
gBattleMoveDamage = gBattleMoveDamage * 15 / 10 ;
gBattlescriptCurrInstr + + ;
}
void AI_CalcDmg ( u8 bankAtk , u8 bankDef )
{
u16 sideStatus = gSideAffecting [ GET_BANK_SIDE ( bankDef ) ] ;
gBattleMoveDamage = CalculateBaseDamage ( & gBattleMons [ bankAtk ] , & gBattleMons [ bankDef ] , gCurrentMove ,
sideStatus , gDynamicBasePower ,
gBattleStruct - > dynamicMoveType , bankAtk , bankDef ) ;
gDynamicBasePower = 0 ;
gBattleMoveDamage = gBattleMoveDamage * gCritMultiplier * gBattleScripting . dmgMultiplier ;
if ( gStatuses3 [ bankAtk ] & STATUS3_CHARGED_UP & & gBattleMoves [ gCurrentMove ] . type = = TYPE_ELECTRIC )
gBattleMoveDamage * = 2 ;
if ( gProtectStructs [ bankAtk ] . helpingHand )
gBattleMoveDamage = gBattleMoveDamage * 15 / 10 ;
}
2017-09-28 15:34:21 +02:00
static void ModulateDmgByType ( u8 multiplier )
2017-09-20 00:28:00 +02:00
{
gBattleMoveDamage = gBattleMoveDamage * multiplier / 10 ;
if ( gBattleMoveDamage = = 0 & & multiplier ! = 0 )
gBattleMoveDamage = 1 ;
switch ( multiplier )
{
case TYPE_MUL_NO_EFFECT :
gBattleMoveFlags | = MOVESTATUS_NOTAFFECTED ;
gBattleMoveFlags & = ~ MOVESTATUS_NOTVERYEFFECTIVE ;
gBattleMoveFlags & = ~ MOVESTATUS_SUPEREFFECTIVE ;
break ;
case TYPE_MUL_NOT_EFFECTIVE :
if ( gBattleMoves [ gCurrentMove ] . power & & ! ( gBattleMoveFlags & MOVESTATUS_NOEFFECT ) )
{
if ( gBattleMoveFlags & MOVESTATUS_SUPEREFFECTIVE )
gBattleMoveFlags & = ~ MOVESTATUS_SUPEREFFECTIVE ;
else
gBattleMoveFlags | = MOVESTATUS_NOTVERYEFFECTIVE ;
}
break ;
case TYPE_MUL_SUPER_EFFECTIVE :
if ( gBattleMoves [ gCurrentMove ] . power & & ! ( gBattleMoveFlags & MOVESTATUS_NOEFFECT ) )
{
if ( gBattleMoveFlags & MOVESTATUS_NOTVERYEFFECTIVE )
gBattleMoveFlags & = ~ MOVESTATUS_NOTVERYEFFECTIVE ;
else
gBattleMoveFlags | = MOVESTATUS_SUPEREFFECTIVE ;
}
break ;
}
}
2017-09-28 15:34:21 +02:00
static void atk06_typecalc ( void )
2017-09-20 00:28:00 +02:00
{
s32 i = 0 ;
u8 moveType ;
if ( gCurrentMove = = MOVE_STRUGGLE )
{
gBattlescriptCurrInstr + + ;
return ;
}
GET_MOVE_TYPE ( gCurrentMove , moveType ) ;
// check stab
if ( gBattleMons [ gBankAttacker ] . type1 = = moveType | | gBattleMons [ gBankAttacker ] . type2 = = moveType )
{
gBattleMoveDamage = gBattleMoveDamage * 15 ;
gBattleMoveDamage = gBattleMoveDamage / 10 ;
}
if ( gBattleMons [ gBankTarget ] . ability = = ABILITY_LEVITATE & & moveType = = TYPE_GROUND )
{
gLastUsedAbility = gBattleMons [ gBankTarget ] . ability ;
gBattleMoveFlags | = ( MOVESTATUS_MISSED | MOVESTATUS_NOTAFFECTED ) ;
2017-11-26 14:17:02 +01:00
gLastLandedMoves [ gBankTarget ] = 0 ;
gLastHitByType [ gBankTarget ] = 0 ;
2017-09-20 00:28:00 +02:00
gBattleCommunication [ 6 ] = moveType ;
RecordAbilityBattle ( gBankTarget , gLastUsedAbility ) ;
}
else
{
2017-11-11 20:01:04 +01:00
while ( TYPE_EFFECT_ATK_TYPE ( i ) ! = TYPE_ENDTABLE )
2017-09-20 00:28:00 +02:00
{
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( i ) = = TYPE_FORESIGHT )
2017-09-20 00:28:00 +02:00
{
if ( gBattleMons [ gBankTarget ] . status2 & STATUS2_FORESIGHT )
break ;
i + = 3 ;
continue ;
}
2017-11-11 20:01:04 +01:00
else if ( TYPE_EFFECT_ATK_TYPE ( i ) = = moveType )
2017-09-20 00:28:00 +02:00
{
// check type1
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBankTarget ] . type1 )
ModulateDmgByType ( TYPE_EFFECT_MULTIPLIER ( i ) ) ;
2017-09-20 00:28:00 +02:00
// check type2
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBankTarget ] . type2 & &
2017-09-20 00:28:00 +02:00
gBattleMons [ gBankTarget ] . type1 ! = gBattleMons [ gBankTarget ] . type2 )
2017-11-11 20:01:04 +01:00
ModulateDmgByType ( TYPE_EFFECT_MULTIPLIER ( i ) ) ;
2017-09-20 00:28:00 +02:00
}
i + = 3 ;
}
}
if ( gBattleMons [ gBankTarget ] . ability = = ABILITY_WONDER_GUARD & & AttacksThisTurn ( gBankAttacker , gCurrentMove ) = = 2
& & ( ! ( gBattleMoveFlags & MOVESTATUS_SUPEREFFECTIVE ) | | ( ( gBattleMoveFlags & ( MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE ) ) = = ( MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE ) ) )
& & gBattleMoves [ gCurrentMove ] . power )
{
gLastUsedAbility = ABILITY_WONDER_GUARD ;
gBattleMoveFlags | = MOVESTATUS_MISSED ;
2017-11-26 14:17:02 +01:00
gLastLandedMoves [ gBankTarget ] = 0 ;
gLastHitByType [ gBankTarget ] = 0 ;
2017-09-20 00:28:00 +02:00
gBattleCommunication [ 6 ] = 3 ;
RecordAbilityBattle ( gBankTarget , gLastUsedAbility ) ;
}
if ( gBattleMoveFlags & MOVESTATUS_NOTAFFECTED )
2017-10-06 17:06:45 +02:00
gProtectStructs [ gBankAttacker ] . targetNotAffected = 1 ;
2017-09-20 00:28:00 +02:00
gBattlescriptCurrInstr + + ;
}
static void CheckWonderGuardAndLevitate ( void )
{
u8 flags = 0 ;
s32 i = 0 ;
u8 moveType ;
if ( gCurrentMove = = MOVE_STRUGGLE | | ! gBattleMoves [ gCurrentMove ] . power )
return ;
GET_MOVE_TYPE ( gCurrentMove , moveType ) ;
if ( gBattleMons [ gBankTarget ] . ability = = ABILITY_LEVITATE & & moveType = = TYPE_GROUND )
{
gLastUsedAbility = ABILITY_LEVITATE ;
gBattleCommunication [ 6 ] = moveType ;
RecordAbilityBattle ( gBankTarget , ABILITY_LEVITATE ) ;
return ;
}
2017-11-11 20:01:04 +01:00
while ( TYPE_EFFECT_ATK_TYPE ( i ) ! = TYPE_ENDTABLE )
2017-09-20 00:28:00 +02:00
{
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( i ) = = TYPE_FORESIGHT )
2017-09-20 00:28:00 +02:00
{
if ( gBattleMons [ gBankTarget ] . status2 & STATUS2_FORESIGHT )
break ;
i + = 3 ;
continue ;
}
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( i ) = = moveType )
2017-09-20 00:28:00 +02:00
{
// check no effect
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBankTarget ] . type1
& & TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_NO_EFFECT )
2017-09-20 00:28:00 +02:00
{
gBattleMoveFlags | = MOVESTATUS_NOTAFFECTED ;
2017-10-06 17:06:45 +02:00
gProtectStructs [ gBankAttacker ] . targetNotAffected = 1 ;
2017-09-20 00:28:00 +02:00
}
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBankTarget ] . type2 & &
2017-09-20 00:28:00 +02:00
gBattleMons [ gBankTarget ] . type1 ! = gBattleMons [ gBankTarget ] . type2 & &
2017-11-11 20:01:04 +01:00
TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_NO_EFFECT )
2017-09-20 00:28:00 +02:00
{
gBattleMoveFlags | = MOVESTATUS_NOTAFFECTED ;
2017-10-06 17:06:45 +02:00
gProtectStructs [ gBankAttacker ] . targetNotAffected = 1 ;
2017-09-20 00:28:00 +02:00
}
// check super effective
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBankTarget ] . type1 & & TYPE_EFFECT_MULTIPLIER ( i ) = = 20 )
2017-09-20 00:28:00 +02:00
flags | = 1 ;
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBankTarget ] . type2
2017-09-20 00:28:00 +02:00
& & gBattleMons [ gBankTarget ] . type1 ! = gBattleMons [ gBankTarget ] . type2
2017-11-11 20:01:04 +01:00
& & TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_SUPER_EFFECTIVE )
2017-09-20 00:28:00 +02:00
flags | = 1 ;
// check not very effective
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBankTarget ] . type1 & & TYPE_EFFECT_MULTIPLIER ( i ) = = 5 )
2017-09-20 00:28:00 +02:00
flags | = 2 ;
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBankTarget ] . type2
2017-09-20 00:28:00 +02:00
& & gBattleMons [ gBankTarget ] . type1 ! = gBattleMons [ gBankTarget ] . type2
2017-11-11 20:01:04 +01:00
& & TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_NOT_EFFECTIVE )
2017-09-20 00:28:00 +02:00
flags | = 2 ;
}
i + = 3 ;
}
if ( gBattleMons [ gBankTarget ] . ability = = ABILITY_WONDER_GUARD & & AttacksThisTurn ( gBankAttacker , gCurrentMove ) = = 2 )
{
if ( ( ( flags & 2 ) | | ! ( flags & 1 ) ) & & gBattleMoves [ gCurrentMove ] . power )
{
gLastUsedAbility = ABILITY_WONDER_GUARD ;
gBattleCommunication [ 6 ] = 3 ;
RecordAbilityBattle ( gBankTarget , ABILITY_WONDER_GUARD ) ;
}
}
}
2017-09-28 15:34:21 +02:00
static void ModulateDmgByType2 ( u8 multiplier , u16 move , u8 * flags ) // same as ModulateDmgByType except different arguments
2017-09-20 00:28:00 +02:00
{
gBattleMoveDamage = gBattleMoveDamage * multiplier / 10 ;
if ( gBattleMoveDamage = = 0 & & multiplier ! = 0 )
gBattleMoveDamage = 1 ;
switch ( multiplier )
{
case TYPE_MUL_NO_EFFECT :
* flags | = MOVESTATUS_NOTAFFECTED ;
* flags & = ~ MOVESTATUS_NOTVERYEFFECTIVE ;
* flags & = ~ MOVESTATUS_SUPEREFFECTIVE ;
break ;
case TYPE_MUL_NOT_EFFECTIVE :
if ( gBattleMoves [ move ] . power & & ! ( * flags & MOVESTATUS_NOEFFECT ) )
{
if ( * flags & MOVESTATUS_SUPEREFFECTIVE )
* flags & = ~ MOVESTATUS_SUPEREFFECTIVE ;
else
* flags | = MOVESTATUS_NOTVERYEFFECTIVE ;
}
break ;
case TYPE_MUL_SUPER_EFFECTIVE :
if ( gBattleMoves [ move ] . power & & ! ( * flags & MOVESTATUS_NOEFFECT ) )
{
if ( * flags & MOVESTATUS_NOTVERYEFFECTIVE )
* flags & = ~ MOVESTATUS_NOTVERYEFFECTIVE ;
else
* flags | = MOVESTATUS_SUPEREFFECTIVE ;
}
break ;
}
}
u8 TypeCalc ( u16 move , u8 bankAtk , u8 bankDef )
{
s32 i = 0 ;
u8 flags = 0 ;
u8 moveType ;
if ( move = = MOVE_STRUGGLE )
return 0 ;
moveType = gBattleMoves [ move ] . type ;
// check stab
if ( gBattleMons [ bankAtk ] . type1 = = moveType | | gBattleMons [ bankAtk ] . type2 = = moveType )
{
gBattleMoveDamage = gBattleMoveDamage * 15 ;
gBattleMoveDamage = gBattleMoveDamage / 10 ;
}
if ( gBattleMons [ bankDef ] . ability = = ABILITY_LEVITATE & & moveType = = TYPE_GROUND )
{
flags | = ( MOVESTATUS_MISSED | MOVESTATUS_NOTAFFECTED ) ;
}
else
{
2017-11-11 20:01:04 +01:00
while ( TYPE_EFFECT_ATK_TYPE ( i ) ! = TYPE_ENDTABLE )
2017-09-20 00:28:00 +02:00
{
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( i ) = = TYPE_FORESIGHT )
2017-09-20 00:28:00 +02:00
{
if ( gBattleMons [ bankDef ] . status2 & STATUS2_FORESIGHT )
break ;
i + = 3 ;
continue ;
}
2017-11-11 20:01:04 +01:00
else if ( TYPE_EFFECT_ATK_TYPE ( i ) = = moveType )
2017-09-20 00:28:00 +02:00
{
// check type1
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ bankDef ] . type1 )
ModulateDmgByType2 ( TYPE_EFFECT_MULTIPLIER ( i ) , move , & flags ) ;
2017-09-20 00:28:00 +02:00
// check type2
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ bankDef ] . type2 & &
2017-09-20 00:28:00 +02:00
gBattleMons [ bankDef ] . type1 ! = gBattleMons [ bankDef ] . type2 )
2017-11-11 20:01:04 +01:00
ModulateDmgByType2 ( TYPE_EFFECT_MULTIPLIER ( i ) , move , & flags ) ;
2017-09-20 00:28:00 +02:00
}
i + = 3 ;
}
}
if ( gBattleMons [ bankDef ] . ability = = ABILITY_WONDER_GUARD & & ! ( flags & MOVESTATUS_MISSED )
& & AttacksThisTurn ( bankAtk , move ) = = 2
& & ( ! ( flags & MOVESTATUS_SUPEREFFECTIVE ) | | ( ( flags & ( MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE ) ) = = ( MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE ) ) )
& & gBattleMoves [ move ] . power )
{
flags | = MOVESTATUS_MISSED ;
}
return flags ;
}
2017-10-10 18:01:45 +02:00
u8 AI_TypeCalc ( u16 move , u16 targetSpecies , u8 targetAbility )
2017-09-20 00:28:00 +02:00
{
s32 i = 0 ;
u8 flags = 0 ;
2017-10-10 18:01:45 +02:00
u8 type1 = gBaseStats [ targetSpecies ] . type1 , type2 = gBaseStats [ targetSpecies ] . type2 ;
2017-09-20 00:28:00 +02:00
u8 moveType ;
if ( move = = MOVE_STRUGGLE )
return 0 ;
moveType = gBattleMoves [ move ] . type ;
2017-10-10 18:01:45 +02:00
if ( targetAbility = = ABILITY_LEVITATE & & moveType = = TYPE_GROUND )
2017-09-20 00:28:00 +02:00
{
flags = MOVESTATUS_MISSED | MOVESTATUS_NOTAFFECTED ;
}
else
{
2017-11-11 20:01:04 +01:00
while ( TYPE_EFFECT_ATK_TYPE ( i ) ! = TYPE_ENDTABLE )
2017-09-20 00:28:00 +02:00
{
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( i ) = = TYPE_FORESIGHT )
2017-09-20 00:28:00 +02:00
{
i + = 3 ;
continue ;
}
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( i ) = = moveType )
2017-09-20 00:28:00 +02:00
{
// check type1
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = type1 )
ModulateDmgByType2 ( TYPE_EFFECT_MULTIPLIER ( i ) , move , & flags ) ;
2017-09-20 00:28:00 +02:00
// check type2
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = type2 & & type1 ! = type2 )
ModulateDmgByType2 ( TYPE_EFFECT_MULTIPLIER ( i ) , move , & flags ) ;
2017-09-20 00:28:00 +02:00
}
i + = 3 ;
}
}
2017-10-10 18:01:45 +02:00
if ( targetAbility = = ABILITY_WONDER_GUARD
2017-09-20 00:28:00 +02:00
& & ( ! ( flags & MOVESTATUS_SUPEREFFECTIVE ) | | ( ( flags & ( MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE ) ) = = ( MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE ) ) )
& & gBattleMoves [ move ] . power )
flags | = MOVESTATUS_NOTAFFECTED ;
return flags ;
}
// Multiplies the damage by a random factor between 85% to 100% inclusive
static inline void ApplyRandomDmgMultiplier ( void )
{
u16 rand = Random ( ) ;
u16 randPercent = 100 - ( rand % 16 ) ;
if ( gBattleMoveDamage ! = 0 )
{
gBattleMoveDamage * = randPercent ;
gBattleMoveDamage / = 100 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
}
}
2017-09-28 15:34:21 +02:00
static void Unused_ApplyRandomDmgMultiplier ( void )
2017-09-20 00:28:00 +02:00
{
ApplyRandomDmgMultiplier ( ) ;
}
2017-11-25 18:42:31 +01:00
static void atk07_adjustnormaldamage ( void )
2017-09-20 00:28:00 +02:00
{
u8 holdEffect , quality ;
ApplyRandomDmgMultiplier ( ) ;
if ( gBattleMons [ gBankTarget ] . item = = ITEM_ENIGMA_BERRY )
{
holdEffect = gEnigmaBerries [ gBankTarget ] . holdEffect , quality = gEnigmaBerries [ gBankTarget ] . holdEffectParam ;
}
else
{
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ gBankTarget ] . item ) ;
quality = ItemId_GetHoldEffectParam ( gBattleMons [ gBankTarget ] . item ) ;
}
gStringBank = gBankTarget ;
if ( holdEffect = = HOLD_EFFECT_FOCUS_BAND & & ( Random ( ) % 100 ) < quality )
{
RecordItemEffectBattle ( gBankTarget , holdEffect ) ;
gSpecialStatuses [ gBankTarget ] . focusBanded = 1 ;
}
if ( gBattleMons [ gBankTarget ] . status2 & STATUS2_SUBSTITUTE )
goto END ;
if ( gBattleMoves [ gCurrentMove ] . effect ! = EFFECT_FALSE_SWIPE & & ! gProtectStructs [ gBankTarget ] . endured
& & ! gSpecialStatuses [ gBankTarget ] . focusBanded )
goto END ;
if ( gBattleMons [ gBankTarget ] . hp > gBattleMoveDamage )
goto END ;
gBattleMoveDamage = gBattleMons [ gBankTarget ] . hp - 1 ;
if ( gProtectStructs [ gBankTarget ] . endured )
{
gBattleMoveFlags | = MOVESTATUS_ENDURED ;
}
else if ( gSpecialStatuses [ gBankTarget ] . focusBanded )
{
gBattleMoveFlags | = MOVESTATUS_HUNGON ;
gLastUsedItem = gBattleMons [ gBankTarget ] . item ;
}
END :
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atk08_adjustnormaldamage2 ( void ) // The same as 0x7 except it doesn't check for false swipe move effect.
2017-09-20 00:28:00 +02:00
{
u8 holdEffect , quality ;
ApplyRandomDmgMultiplier ( ) ;
if ( gBattleMons [ gBankTarget ] . item = = ITEM_ENIGMA_BERRY )
{
holdEffect = gEnigmaBerries [ gBankTarget ] . holdEffect , quality = gEnigmaBerries [ gBankTarget ] . holdEffectParam ;
}
else
{
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ gBankTarget ] . item ) ;
quality = ItemId_GetHoldEffectParam ( gBattleMons [ gBankTarget ] . item ) ;
}
gStringBank = gBankTarget ;
if ( holdEffect = = HOLD_EFFECT_FOCUS_BAND & & ( Random ( ) % 100 ) < quality )
{
RecordItemEffectBattle ( gBankTarget , holdEffect ) ;
gSpecialStatuses [ gBankTarget ] . focusBanded = 1 ;
}
if ( gBattleMons [ gBankTarget ] . status2 & STATUS2_SUBSTITUTE )
goto END ;
if ( ! gProtectStructs [ gBankTarget ] . endured & & ! gSpecialStatuses [ gBankTarget ] . focusBanded )
goto END ;
if ( gBattleMons [ gBankTarget ] . hp > gBattleMoveDamage )
goto END ;
gBattleMoveDamage = gBattleMons [ gBankTarget ] . hp - 1 ;
if ( gProtectStructs [ gBankTarget ] . endured )
{
gBattleMoveFlags | = MOVESTATUS_ENDURED ;
}
else if ( gSpecialStatuses [ gBankTarget ] . focusBanded )
{
gBattleMoveFlags | = MOVESTATUS_HUNGON ;
gLastUsedItem = gBattleMons [ gBankTarget ] . item ;
}
END :
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk09_attackanimation ( void )
2017-09-20 00:28:00 +02:00
{
if ( gBattleExecBuffer )
return ;
if ( ( gHitMarker & HITMARKER_NO_ANIMATIONS ) & & ( gCurrentMove ! = MOVE_TRANSFORM & & gCurrentMove ! = MOVE_SUBSTITUTE ) )
{
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 00:28:00 +02:00
gBattlescriptCurrInstr = BattleScript_Pausex20 ;
gBattleScripting . animTurn + + ;
gBattleScripting . animTargetsHit + + ;
}
else
{
if ( ( gBattleMoves [ gCurrentMove ] . target & MOVE_TARGET_BOTH
| | gBattleMoves [ gCurrentMove ] . target & MOVE_TARGET_FOES_AND_ALLY
| | gBattleMoves [ gCurrentMove ] . target & MOVE_TARGET_DEPENDS )
& & gBattleScripting . animTargetsHit )
{
gBattlescriptCurrInstr + + ;
return ;
}
if ( ! ( gBattleMoveFlags & MOVESTATUS_NOEFFECT ) )
{
u8 multihit ;
gActiveBank = gBankAttacker ;
if ( gBattleMons [ gBankTarget ] . status2 & STATUS2_SUBSTITUTE )
multihit = gMultiHitCounter ;
else if ( gMultiHitCounter ! = 0 & & gMultiHitCounter ! = 1 )
{
if ( gBattleMons [ gBankTarget ] . hp < = gBattleMoveDamage )
multihit = 1 ;
else
multihit = gMultiHitCounter ;
}
else
multihit = gMultiHitCounter ;
EmitMoveAnimation ( 0 , gCurrentMove , gBattleScripting . animTurn , gBattleMovePower , gBattleMoveDamage , gBattleMons [ gBankAttacker ] . friendship , & gDisableStructs [ gBankAttacker ] , multihit ) ;
gBattleScripting . animTurn + = 1 ;
gBattleScripting . animTargetsHit + = 1 ;
MarkBufferBankForExecution ( gBankAttacker ) ;
gBattlescriptCurrInstr + + ;
}
else
{
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 00:28:00 +02:00
gBattlescriptCurrInstr = BattleScript_Pausex20 ;
}
}
}
2017-09-28 15:34:21 +02:00
static void atk0A_waitanimation ( void )
2017-09-20 00:28:00 +02:00
{
if ( gBattleExecBuffer = = 0 )
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk0B_healthbarupdate ( void )
2017-09-20 00:28:00 +02:00
{
2017-09-20 12:56:45 +02:00
if ( gBattleExecBuffer )
return ;
if ( ! ( gBattleMoveFlags & MOVESTATUS_NOEFFECT ) )
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-20 12:56:45 +02:00
if ( gBattleMons [ gActiveBank ] . status2 & STATUS2_SUBSTITUTE & & gDisableStructs [ gActiveBank ] . substituteHP & & ! ( gHitMarker & HITMARKER_IGNORE_SUBSTITUTE ) )
{
2017-10-07 15:15:47 +02:00
PrepareStringBattle ( STRINGID_SUBSTITUTEDAMAGED , gActiveBank ) ;
2017-09-20 12:56:45 +02:00
}
else
{
s16 healthValue ;
s32 currDmg = gBattleMoveDamage ;
s32 maxPossibleDmgValue = 10000 ; // not present in R/S, ensures that huge damage values don't change sign
if ( currDmg < = maxPossibleDmgValue )
healthValue = currDmg ;
else
healthValue = maxPossibleDmgValue ;
EmitHealthBarUpdate ( 0 , healthValue ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
if ( GetBankSide ( gActiveBank ) = = SIDE_PLAYER & & gBattleMoveDamage > 0 )
gBattleResults . unk5_0 = 1 ;
}
}
gBattlescriptCurrInstr + = 2 ;
}
2017-09-28 15:34:21 +02:00
static void atk0C_datahpupdate ( void )
2017-09-20 12:56:45 +02:00
{
u32 moveType ;
2017-09-20 00:28:00 +02:00
if ( gBattleExecBuffer )
return ;
2017-09-20 12:56:45 +02:00
if ( gBattleStruct - > dynamicMoveType = = 0 )
moveType = gBattleMoves [ gCurrentMove ] . type ;
else if ( ! ( gBattleStruct - > dynamicMoveType & 0x40 ) )
moveType = gBattleStruct - > dynamicMoveType & 0x3F ;
else
moveType = gBattleMoves [ gCurrentMove ] . type ;
2017-09-20 00:28:00 +02:00
2017-09-20 12:56:45 +02:00
if ( ! ( gBattleMoveFlags & MOVESTATUS_NOEFFECT ) )
2017-09-20 00:28:00 +02:00
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-20 12:56:45 +02:00
if ( gBattleMons [ gActiveBank ] . status2 & STATUS2_SUBSTITUTE & & gDisableStructs [ gActiveBank ] . substituteHP & & ! ( gHitMarker & HITMARKER_IGNORE_SUBSTITUTE ) )
{
if ( gDisableStructs [ gActiveBank ] . substituteHP > = gBattleMoveDamage )
{
if ( gSpecialStatuses [ gActiveBank ] . moveturnLostHP = = 0 )
gSpecialStatuses [ gActiveBank ] . moveturnLostHP = gBattleMoveDamage ;
gDisableStructs [ gActiveBank ] . substituteHP - = gBattleMoveDamage ;
gHpDealt = gBattleMoveDamage ;
}
else
{
if ( gSpecialStatuses [ gActiveBank ] . moveturnLostHP = = 0 )
gSpecialStatuses [ gActiveBank ] . moveturnLostHP = gDisableStructs [ gActiveBank ] . substituteHP ;
gHpDealt = gDisableStructs [ gActiveBank ] . substituteHP ;
gDisableStructs [ gActiveBank ] . substituteHP = 0 ;
}
// check substitute fading
if ( gDisableStructs [ gActiveBank ] . substituteHP = = 0 )
{
gBattlescriptCurrInstr + = 2 ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr = BattleScript_SubstituteFade ;
return ;
}
}
else
{
gHitMarker & = ~ ( HITMARKER_IGNORE_SUBSTITUTE ) ;
if ( gBattleMoveDamage < 0 ) // hp goes up
{
gBattleMons [ gActiveBank ] . hp - = gBattleMoveDamage ;
if ( gBattleMons [ gActiveBank ] . hp > gBattleMons [ gActiveBank ] . maxHP )
gBattleMons [ gActiveBank ] . hp = gBattleMons [ gActiveBank ] . maxHP ;
}
else // hp goes down
{
if ( gHitMarker & HITMARKER_x20 )
{
gHitMarker & = ~ ( HITMARKER_x20 ) ;
}
else
{
gTakenDmg [ gActiveBank ] + = gBattleMoveDamage ;
2017-09-28 15:34:21 +02:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_GET_TARGET )
2017-09-20 12:56:45 +02:00
gTakenDmgBanks [ gActiveBank ] = gBankAttacker ;
else
gTakenDmgBanks [ gActiveBank ] = gBankTarget ;
}
if ( gBattleMons [ gActiveBank ] . hp > gBattleMoveDamage )
{
gBattleMons [ gActiveBank ] . hp - = gBattleMoveDamage ;
gHpDealt = gBattleMoveDamage ;
}
else
{
gHpDealt = gBattleMons [ gActiveBank ] . hp ;
gBattleMons [ gActiveBank ] . hp = 0 ;
}
if ( ! gSpecialStatuses [ gActiveBank ] . moveturnLostHP & & ! ( gHitMarker & HITMARKER_x100000 ) )
gSpecialStatuses [ gActiveBank ] . moveturnLostHP = gHpDealt ;
if ( moveType < = 8 & & ! ( gHitMarker & HITMARKER_x100000 ) & & gCurrentMove ! = MOVE_PAIN_SPLIT )
{
gProtectStructs [ gActiveBank ] . physicalDmg = gHpDealt ;
gSpecialStatuses [ gActiveBank ] . moveturnLostHP_physical = gHpDealt ;
2017-09-28 15:34:21 +02:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_GET_TARGET )
2017-09-20 12:56:45 +02:00
{
gProtectStructs [ gActiveBank ] . physicalBank = gBankAttacker ;
gSpecialStatuses [ gActiveBank ] . moveturnPhysicalBank = gBankAttacker ;
}
else
{
gProtectStructs [ gActiveBank ] . physicalBank = gBankTarget ;
gSpecialStatuses [ gActiveBank ] . moveturnPhysicalBank = gBankTarget ;
}
}
else if ( moveType > 8 & & ! ( gHitMarker & HITMARKER_x100000 ) )
{
gProtectStructs [ gActiveBank ] . specialDmg = gHpDealt ;
gSpecialStatuses [ gActiveBank ] . moveturnLostHP_special = gHpDealt ;
2017-09-28 15:34:21 +02:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_GET_TARGET )
2017-09-20 12:56:45 +02:00
{
gProtectStructs [ gActiveBank ] . specialBank = gBankAttacker ;
gSpecialStatuses [ gActiveBank ] . moveturnSpecialBank = gBankAttacker ;
}
else
{
gProtectStructs [ gActiveBank ] . specialBank = gBankTarget ;
gSpecialStatuses [ gActiveBank ] . moveturnSpecialBank = gBankTarget ;
}
}
}
gHitMarker & = ~ ( HITMARKER_x100000 ) ;
2017-09-26 22:39:59 +02:00
EmitSetMonData ( 0 , REQUEST_HP_BATTLE , 0 , 2 , & gBattleMons [ gActiveBank ] . hp ) ;
2017-09-20 12:56:45 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
}
}
else
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-20 12:56:45 +02:00
if ( gSpecialStatuses [ gActiveBank ] . moveturnLostHP = = 0 )
gSpecialStatuses [ gActiveBank ] . moveturnLostHP = 0xFFFF ;
}
gBattlescriptCurrInstr + = 2 ;
}
2017-09-28 15:34:21 +02:00
static void atk0D_critmessage ( void )
2017-09-20 12:56:45 +02:00
{
if ( gBattleExecBuffer = = 0 )
{
if ( gCritMultiplier = = 2 & & ! ( gBattleMoveFlags & MOVESTATUS_NOEFFECT ) )
{
2017-10-07 15:15:47 +02:00
PrepareStringBattle ( STRINGID_CRITICALHIT , gBankAttacker ) ;
2017-09-20 12:56:45 +02:00
gBattleCommunication [ MSG_DISPLAY ] = 1 ;
}
gBattlescriptCurrInstr + + ;
}
}
2017-11-25 18:42:31 +01:00
static void atk0E_effectivenesssound ( void )
2017-09-20 12:56:45 +02:00
{
if ( gBattleExecBuffer )
return ;
gActiveBank = gBankTarget ;
if ( ! ( gBattleMoveFlags & MOVESTATUS_MISSED ) )
{
switch ( gBattleMoveFlags & ( u8 ) ( ~ ( MOVESTATUS_MISSED ) ) )
{
case MOVESTATUS_SUPEREFFECTIVE :
2017-11-25 18:42:31 +01:00
EmitPlaySE ( 0 , SE_KOUKA_H ) ;
2017-09-20 12:56:45 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
break ;
case MOVESTATUS_NOTVERYEFFECTIVE :
2017-11-25 18:42:31 +01:00
EmitPlaySE ( 0 , SE_KOUKA_L ) ;
2017-09-20 12:56:45 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
break ;
case MOVESTATUS_NOTAFFECTED :
case MOVESTATUS_FAILED :
// no sound
break ;
case MOVESTATUS_ENDURED :
case MOVESTATUS_ONEHITKO :
case MOVESTATUS_HUNGON :
default :
if ( gBattleMoveFlags & MOVESTATUS_SUPEREFFECTIVE )
{
2017-11-25 18:42:31 +01:00
EmitPlaySE ( 0 , SE_KOUKA_H ) ;
2017-09-20 12:56:45 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
}
else if ( gBattleMoveFlags & MOVESTATUS_NOTVERYEFFECTIVE )
{
2017-11-25 18:42:31 +01:00
EmitPlaySE ( 0 , SE_KOUKA_L ) ;
2017-09-20 12:56:45 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
}
else if ( ! ( gBattleMoveFlags & ( MOVESTATUS_NOTAFFECTED | MOVESTATUS_FAILED ) ) )
{
2017-11-25 18:42:31 +01:00
EmitPlaySE ( 0 , SE_KOUKA_M ) ;
2017-09-20 12:56:45 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
}
break ;
}
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk0F_resultmessage ( void )
2017-09-20 12:56:45 +02:00
{
u32 stringId = 0 ;
if ( gBattleExecBuffer )
return ;
if ( gBattleMoveFlags & MOVESTATUS_MISSED & & ( ! ( gBattleMoveFlags & MOVESTATUS_NOTAFFECTED ) | | gBattleCommunication [ 6 ] > 2 ) )
{
stringId = gMissStringIds [ gBattleCommunication [ 6 ] ] ;
gBattleCommunication [ MSG_DISPLAY ] = 1 ;
}
else
{
gBattleCommunication [ MSG_DISPLAY ] = 1 ;
switch ( gBattleMoveFlags & ( u8 ) ( ~ ( MOVESTATUS_MISSED ) ) )
{
case MOVESTATUS_SUPEREFFECTIVE :
2017-10-07 15:15:47 +02:00
stringId = STRINGID_SUPEREFFECTIVE ;
2017-09-20 12:56:45 +02:00
break ;
case MOVESTATUS_NOTVERYEFFECTIVE :
2017-10-07 15:15:47 +02:00
stringId = STRINGID_NOTVERYEFFECTIVE ;
2017-09-20 12:56:45 +02:00
break ;
case MOVESTATUS_ONEHITKO :
2017-10-07 15:15:47 +02:00
stringId = STRINGID_ONEHITKO ;
2017-09-20 12:56:45 +02:00
break ;
case MOVESTATUS_ENDURED :
2017-10-07 15:15:47 +02:00
stringId = STRINGID_PKMNENDUREDHIT ;
2017-09-20 12:56:45 +02:00
break ;
case MOVESTATUS_FAILED :
2017-10-07 15:15:47 +02:00
stringId = STRINGID_BUTITFAILED ;
2017-09-20 12:56:45 +02:00
break ;
case MOVESTATUS_NOTAFFECTED :
2017-10-07 15:15:47 +02:00
stringId = STRINGID_ITDOESNTAFFECT ;
2017-09-20 12:56:45 +02:00
break ;
case MOVESTATUS_HUNGON :
gLastUsedItem = gBattleMons [ gBankTarget ] . item ;
gStringBank = gBankTarget ;
gBattleMoveFlags & = ~ ( MOVESTATUS_ENDURED | MOVESTATUS_HUNGON ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr = BattleScript_HangedOnMsg ;
return ;
default :
if ( gBattleMoveFlags & MOVESTATUS_NOTAFFECTED )
{
2017-10-07 15:15:47 +02:00
stringId = STRINGID_ITDOESNTAFFECT ;
2017-09-20 12:56:45 +02:00
}
else if ( gBattleMoveFlags & MOVESTATUS_ONEHITKO )
{
gBattleMoveFlags & = ~ ( MOVESTATUS_ONEHITKO ) ;
gBattleMoveFlags & = ~ ( MOVESTATUS_SUPEREFFECTIVE ) ;
gBattleMoveFlags & = ~ ( MOVESTATUS_NOTVERYEFFECTIVE ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr = BattleScript_OneHitKOMsg ;
return ;
}
else if ( gBattleMoveFlags & MOVESTATUS_ENDURED )
{
gBattleMoveFlags & = ~ ( MOVESTATUS_ENDURED | MOVESTATUS_HUNGON ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr = BattleScript_EnduredMsg ;
return ;
}
else if ( gBattleMoveFlags & MOVESTATUS_HUNGON )
{
gLastUsedItem = gBattleMons [ gBankTarget ] . item ;
gStringBank = gBankTarget ;
gBattleMoveFlags & = ~ ( MOVESTATUS_ENDURED | MOVESTATUS_HUNGON ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr = BattleScript_HangedOnMsg ;
return ;
}
else if ( gBattleMoveFlags & MOVESTATUS_FAILED )
{
2017-10-07 15:15:47 +02:00
stringId = STRINGID_BUTITFAILED ;
2017-09-20 12:56:45 +02:00
}
else
{
gBattleCommunication [ MSG_DISPLAY ] = 0 ;
}
}
}
if ( stringId )
PrepareStringBattle ( stringId , gBankAttacker ) ;
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk10_printstring ( void )
2017-09-20 12:56:45 +02:00
{
if ( gBattleExecBuffer = = 0 )
{
u16 var = BS2ScriptRead16 ( gBattlescriptCurrInstr + 1 ) ;
PrepareStringBattle ( var , gBankAttacker ) ;
gBattlescriptCurrInstr + = 3 ;
gBattleCommunication [ MSG_DISPLAY ] = 1 ;
2017-09-20 00:28:00 +02:00
}
2017-09-20 12:56:45 +02:00
}
2017-09-20 00:28:00 +02:00
2017-11-25 18:42:31 +01:00
static void atk11_printselectionstring ( void )
2017-09-20 12:56:45 +02:00
{
gActiveBank = gBankAttacker ;
2017-09-20 00:28:00 +02:00
2017-11-25 18:42:31 +01:00
EmitPrintSelectionString ( 0 , BS2ScriptRead16 ( gBattlescriptCurrInstr + 1 ) ) ;
2017-09-20 00:28:00 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr + = 3 ;
gBattleCommunication [ MSG_DISPLAY ] = 1 ;
}
2017-09-20 00:28:00 +02:00
2017-09-28 15:34:21 +02:00
static void atk12_waitmessage ( void )
2017-09-20 12:56:45 +02:00
{
if ( gBattleExecBuffer = = 0 )
{
if ( ! gBattleCommunication [ MSG_DISPLAY ] )
{
gBattlescriptCurrInstr + = 3 ;
}
else
{
u16 toWait = BS2ScriptRead16 ( gBattlescriptCurrInstr + 1 ) ;
if ( + + gPauseCounterBattle > = toWait )
{
gPauseCounterBattle = 0 ;
gBattlescriptCurrInstr + = 3 ;
gBattleCommunication [ MSG_DISPLAY ] = 0 ;
}
}
}
}
2017-09-28 15:34:21 +02:00
static void atk13_printfromtable ( void )
2017-09-20 12:56:45 +02:00
{
if ( gBattleExecBuffer = = 0 )
{
2017-09-27 23:43:45 +02:00
const u16 * ptr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 12:56:45 +02:00
ptr + = gBattleCommunication [ MULTISTRING_CHOOSER ] ;
2017-09-27 23:43:45 +02:00
PrepareStringBattle ( * ptr , gBankAttacker ) ;
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr + = 5 ;
gBattleCommunication [ MSG_DISPLAY ] = 1 ;
}
}
2017-11-25 18:42:31 +01:00
static void atk14_printselectionstringfromtable ( void )
2017-09-20 12:56:45 +02:00
{
if ( gBattleExecBuffer = = 0 )
{
2017-09-27 23:43:45 +02:00
const u16 * ptr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 12:56:45 +02:00
ptr + = gBattleCommunication [ MULTISTRING_CHOOSER ] ;
gActiveBank = gBankAttacker ;
2017-11-25 18:42:31 +01:00
EmitPrintSelectionString ( 0 , * ptr ) ;
2017-09-20 12:56:45 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 5 ;
gBattleCommunication [ MSG_DISPLAY ] = 1 ;
}
}
u8 BankGetTurnOrder ( u8 bank )
{
s32 i ;
for ( i = 0 ; i < gNoOfAllBanks ; i + + )
{
2017-10-04 19:25:14 +02:00
if ( gBanksByTurnOrder [ i ] = = bank )
2017-09-20 12:56:45 +02:00
break ;
}
return i ;
2017-09-20 00:28:00 +02:00
}
2017-09-20 22:54:26 +02:00
# define INCREMENT_RESET_RETURN \
{ \
gBattlescriptCurrInstr + + ; \
gBattleCommunication [ MOVE_EFFECT_BYTE ] = 0 ; \
return ; \
}
# define RESET_RETURN \
{ \
gBattleCommunication [ MOVE_EFFECT_BYTE ] = 0 ; \
return ; \
}
void SetMoveEffect ( bool8 primary , u8 certain )
{
bool32 statusChanged = FALSE ;
u8 affectsUser = 0 ; // 0x40 otherwise
bool32 noSunCanFreeze = TRUE ;
if ( gBattleCommunication [ MOVE_EFFECT_BYTE ] & MOVE_EFFECT_AFFECTS_USER )
{
gEffectBank = gBankAttacker ; // bank that effects get applied on
gBattleCommunication [ MOVE_EFFECT_BYTE ] & = ~ ( MOVE_EFFECT_AFFECTS_USER ) ;
affectsUser = MOVE_EFFECT_AFFECTS_USER ;
gBattleScripting . bank = gBankTarget ; // theoretically the attacker
}
else
{
gEffectBank = gBankTarget ;
gBattleScripting . bank = gBankAttacker ;
}
if ( gBattleMons [ gEffectBank ] . ability = = ABILITY_SHIELD_DUST & & ! ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
& & ! primary & & gBattleCommunication [ MOVE_EFFECT_BYTE ] < = 9 )
INCREMENT_RESET_RETURN
if ( gSideAffecting [ GET_BANK_SIDE ( gEffectBank ) ] & SIDE_STATUS_SAFEGUARD & & ! ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
& & ! primary & & gBattleCommunication [ MOVE_EFFECT_BYTE ] < = 7 )
INCREMENT_RESET_RETURN
if ( gBattleMons [ gEffectBank ] . hp = = 0
& & gBattleCommunication [ MOVE_EFFECT_BYTE ] ! = MOVE_EFFECT_PAYDAY
& & gBattleCommunication [ MOVE_EFFECT_BYTE ] ! = MOVE_EFFECT_STEAL_ITEM )
INCREMENT_RESET_RETURN
if ( gBattleMons [ gEffectBank ] . status2 & STATUS2_SUBSTITUTE & & affectsUser ! = MOVE_EFFECT_AFFECTS_USER )
INCREMENT_RESET_RETURN
if ( gBattleCommunication [ MOVE_EFFECT_BYTE ] < = 6 ) // status change
{
2017-09-28 16:51:24 +02:00
switch ( sStatusFlagsForMoveEffects [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] )
2017-09-20 22:54:26 +02:00
{
case STATUS_SLEEP :
// check active uproar
if ( gBattleMons [ gEffectBank ] . ability ! = ABILITY_SOUNDPROOF )
{
for ( gActiveBank = 0 ;
gActiveBank < gNoOfAllBanks & & ! ( gBattleMons [ gActiveBank ] . status2 & STATUS2_UPROAR ) ;
gActiveBank + + )
{ }
}
else
gActiveBank = gNoOfAllBanks ;
if ( gBattleMons [ gEffectBank ] . status1 )
break ;
if ( gActiveBank ! = gNoOfAllBanks )
break ;
if ( gBattleMons [ gEffectBank ] . ability = = ABILITY_VITAL_SPIRIT )
break ;
if ( gBattleMons [ gEffectBank ] . ability = = ABILITY_INSOMNIA )
break ;
CancelMultiTurnMoves ( gEffectBank ) ;
statusChanged = TRUE ;
break ;
case STATUS_POISON :
if ( gBattleMons [ gEffectBank ] . ability = = ABILITY_IMMUNITY
2017-09-22 21:33:49 +02:00
& & ( primary = = TRUE | | certain = = MOVE_EFFECT_CERTAIN ) )
2017-09-20 22:54:26 +02:00
{
gLastUsedAbility = ABILITY_IMMUNITY ;
RecordAbilityBattle ( gEffectBank , ABILITY_IMMUNITY ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_PSNPrevention ;
if ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
gHitMarker & = ~ ( HITMARKER_IGNORE_SAFEGUARD ) ;
}
else
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
RESET_RETURN
}
if ( ( gBattleMons [ gEffectBank ] . type1 = = TYPE_POISON | | gBattleMons [ gEffectBank ] . type2 = = TYPE_POISON
| | gBattleMons [ gEffectBank ] . type1 = = TYPE_STEEL | | gBattleMons [ gEffectBank ] . type2 = = TYPE_STEEL )
& & ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
2017-09-22 21:33:49 +02:00
& & ( primary = = TRUE | | certain = = MOVE_EFFECT_CERTAIN ) )
2017-09-20 22:54:26 +02:00
{
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_PSNPrevention ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
RESET_RETURN
}
if ( gBattleMons [ gEffectBank ] . type1 = = TYPE_POISON )
break ;
if ( gBattleMons [ gEffectBank ] . type2 = = TYPE_POISON )
break ;
if ( gBattleMons [ gEffectBank ] . type1 = = TYPE_STEEL )
break ;
if ( gBattleMons [ gEffectBank ] . type2 = = TYPE_STEEL )
break ;
if ( gBattleMons [ gEffectBank ] . status1 )
break ;
if ( gBattleMons [ gEffectBank ] . ability = = ABILITY_IMMUNITY )
break ;
statusChanged = TRUE ;
break ;
case STATUS_BURN :
if ( gBattleMons [ gEffectBank ] . ability = = ABILITY_WATER_VEIL
2017-09-22 21:33:49 +02:00
& & ( primary = = TRUE | | certain = = MOVE_EFFECT_CERTAIN ) )
2017-09-20 22:54:26 +02:00
{
gLastUsedAbility = ABILITY_WATER_VEIL ;
RecordAbilityBattle ( gEffectBank , ABILITY_WATER_VEIL ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_BRNPrevention ;
if ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
gHitMarker & = ~ ( HITMARKER_IGNORE_SAFEGUARD ) ;
}
else
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
RESET_RETURN
}
if ( ( gBattleMons [ gEffectBank ] . type1 = = TYPE_FIRE
| | gBattleMons [ gEffectBank ] . type2 = = TYPE_FIRE )
& & ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
2017-09-22 21:33:49 +02:00
& & ( primary = = TRUE | | certain = = MOVE_EFFECT_CERTAIN ) )
2017-09-20 22:54:26 +02:00
{
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_BRNPrevention ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
RESET_RETURN
}
if ( gBattleMons [ gEffectBank ] . type1 = = TYPE_FIRE )
break ;
if ( gBattleMons [ gEffectBank ] . type2 = = TYPE_FIRE )
break ;
if ( gBattleMons [ gEffectBank ] . ability = = ABILITY_WATER_VEIL )
break ;
if ( gBattleMons [ gEffectBank ] . status1 )
break ;
statusChanged = TRUE ;
break ;
case STATUS_FREEZE :
if ( WEATHER_HAS_EFFECT & & gBattleWeather & WEATHER_SUN_ANY )
noSunCanFreeze = FALSE ;
if ( gBattleMons [ gEffectBank ] . type1 = = TYPE_ICE )
break ;
if ( gBattleMons [ gEffectBank ] . type2 = = TYPE_ICE )
break ;
if ( gBattleMons [ gEffectBank ] . status1 )
break ;
if ( noSunCanFreeze = = 0 )
break ;
if ( gBattleMons [ gEffectBank ] . ability = = ABILITY_MAGMA_ARMOR )
break ;
CancelMultiTurnMoves ( gEffectBank ) ;
statusChanged = TRUE ;
break ;
case STATUS_PARALYSIS :
if ( gBattleMons [ gEffectBank ] . ability = = ABILITY_LIMBER )
{
2017-09-22 21:33:49 +02:00
if ( primary = = TRUE | | certain = = MOVE_EFFECT_CERTAIN )
2017-09-20 22:54:26 +02:00
{
gLastUsedAbility = ABILITY_LIMBER ;
RecordAbilityBattle ( gEffectBank , ABILITY_LIMBER ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_PRLZPrevention ;
if ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
gHitMarker & = ~ ( HITMARKER_IGNORE_SAFEGUARD ) ;
}
else
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
RESET_RETURN
}
else
break ;
}
if ( gBattleMons [ gEffectBank ] . status1 )
break ;
statusChanged = TRUE ;
break ;
case STATUS_TOXIC_POISON :
2017-09-22 21:33:49 +02:00
if ( gBattleMons [ gEffectBank ] . ability = = ABILITY_IMMUNITY & & ( primary = = TRUE | | certain = = MOVE_EFFECT_CERTAIN ) )
2017-09-20 22:54:26 +02:00
{
gLastUsedAbility = ABILITY_IMMUNITY ;
RecordAbilityBattle ( gEffectBank , ABILITY_IMMUNITY ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_PSNPrevention ;
if ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
gHitMarker & = ~ ( HITMARKER_IGNORE_SAFEGUARD ) ;
}
else
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
RESET_RETURN
}
if ( ( gBattleMons [ gEffectBank ] . type1 = = TYPE_POISON | | gBattleMons [ gEffectBank ] . type2 = = TYPE_POISON
| | gBattleMons [ gEffectBank ] . type1 = = TYPE_STEEL | | gBattleMons [ gEffectBank ] . type2 = = TYPE_STEEL )
& & ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
2017-09-22 21:33:49 +02:00
& & ( primary = = TRUE | | certain = = MOVE_EFFECT_CERTAIN ) )
2017-09-20 22:54:26 +02:00
{
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_PSNPrevention ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
RESET_RETURN
}
if ( gBattleMons [ gEffectBank ] . status1 )
break ;
if ( gBattleMons [ gEffectBank ] . type1 ! = TYPE_POISON
& & gBattleMons [ gEffectBank ] . type2 ! = TYPE_POISON
& & gBattleMons [ gEffectBank ] . type1 ! = TYPE_STEEL
& & gBattleMons [ gEffectBank ] . type2 ! = TYPE_STEEL )
{
if ( gBattleMons [ gEffectBank ] . ability = = ABILITY_IMMUNITY )
break ;
// It's redundant, because at this point we know the status1 value is 0.
gBattleMons [ gEffectBank ] . status1 & = ~ ( STATUS_TOXIC_POISON ) ;
gBattleMons [ gEffectBank ] . status1 & = ~ ( STATUS_POISON ) ;
statusChanged = TRUE ;
break ;
}
else
{
gBattleMoveFlags | = MOVESTATUS_NOTAFFECTED ;
}
break ;
}
if ( statusChanged = = TRUE )
{
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
2017-09-28 16:51:24 +02:00
if ( sStatusFlagsForMoveEffects [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] = = STATUS_SLEEP )
2017-09-20 22:54:26 +02:00
gBattleMons [ gEffectBank ] . status1 | = ( ( Random ( ) & 3 ) + 2 ) ;
else
2017-09-28 16:51:24 +02:00
gBattleMons [ gEffectBank ] . status1 | = sStatusFlagsForMoveEffects [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ;
2017-09-20 22:54:26 +02:00
2017-09-28 16:51:24 +02:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ;
2017-09-20 22:54:26 +02:00
gActiveBank = gEffectBank ;
2017-09-26 22:39:59 +02:00
EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gEffectBank ] . status1 ) ;
2017-09-20 22:54:26 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
if ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
gHitMarker & = ~ ( HITMARKER_IGNORE_SAFEGUARD ) ;
}
else
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
// for synchronize
if ( gBattleCommunication [ MOVE_EFFECT_BYTE ] = = MOVE_EFFECT_POISON
| | gBattleCommunication [ MOVE_EFFECT_BYTE ] = = MOVE_EFFECT_TOXIC
| | gBattleCommunication [ MOVE_EFFECT_BYTE ] = = MOVE_EFFECT_PARALYSIS
| | gBattleCommunication [ MOVE_EFFECT_BYTE ] = = MOVE_EFFECT_BURN )
{
u8 * synchronizeEffect = & gBattleStruct - > synchronizeMoveEffect ;
* synchronizeEffect = gBattleCommunication [ MOVE_EFFECT_BYTE ] ;
gHitMarker | = HITMARKER_SYNCHRONISE_EFFECT ;
}
return ;
}
else if ( statusChanged = = FALSE )
{
gBattleCommunication [ MOVE_EFFECT_BYTE ] = 0 ;
gBattlescriptCurrInstr + + ;
return ;
}
2017-09-22 21:33:49 +02:00
return ;
2017-09-20 22:54:26 +02:00
}
else
{
2017-09-28 16:51:24 +02:00
if ( gBattleMons [ gEffectBank ] . status2 & sStatusFlagsForMoveEffects [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
u8 side ;
2017-09-22 21:33:49 +02:00
switch ( gBattleCommunication [ MOVE_EFFECT_BYTE ] )
2017-09-20 22:54:26 +02:00
{
case MOVE_EFFECT_CONFUSION :
if ( gBattleMons [ gEffectBank ] . ability = = ABILITY_OWN_TEMPO
| | gBattleMons [ gEffectBank ] . status2 & STATUS2_CONFUSION )
{
gBattlescriptCurrInstr + + ;
}
else
{
gBattleMons [ gEffectBank ] . status2 | = ( ( ( Random ( ) ) % 0x4 ) ) + 2 ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 16:51:24 +02:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ;
2017-09-20 22:54:26 +02:00
}
break ;
case MOVE_EFFECT_FLINCH :
if ( gBattleMons [ gEffectBank ] . ability = = ABILITY_INNER_FOCUS )
{
2017-09-22 21:33:49 +02:00
if ( primary = = TRUE | | certain = = MOVE_EFFECT_CERTAIN )
2017-09-20 22:54:26 +02:00
{
gLastUsedAbility = ABILITY_INNER_FOCUS ;
RecordAbilityBattle ( gEffectBank , ABILITY_INNER_FOCUS ) ;
gBattlescriptCurrInstr = BattleScript_FlinchPrevention ;
}
else
{
gBattlescriptCurrInstr + + ;
}
}
else
{
2017-10-06 00:12:01 +02:00
if ( BankGetTurnOrder ( gEffectBank ) > gCurrentTurnActionNumber )
2017-09-28 16:51:24 +02:00
gBattleMons [ gEffectBank ] . status2 | = sStatusFlagsForMoveEffects [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr + + ;
2017-09-20 22:54:26 +02:00
}
break ;
case MOVE_EFFECT_UPROAR :
2017-09-22 21:33:49 +02:00
if ( ! ( gBattleMons [ gEffectBank ] . status2 & STATUS2_UPROAR ) )
2017-09-20 22:54:26 +02:00
{
2017-09-22 21:33:49 +02:00
2017-09-20 22:54:26 +02:00
gBattleMons [ gEffectBank ] . status2 | = STATUS2_MULTIPLETURNS ;
gLockedMoves [ gEffectBank ] = gCurrentMove ;
gBattleMons [ gEffectBank ] . status2 | = ( ( Random ( ) & 3 ) + 2 ) < < 4 ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 16:51:24 +02:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ;
2017-09-20 22:54:26 +02:00
}
2017-09-22 21:33:49 +02:00
else
{
gBattlescriptCurrInstr + + ;
}
2017-09-20 22:54:26 +02:00
break ;
case MOVE_EFFECT_PAYDAY :
if ( GET_BANK_SIDE ( gBankAttacker ) = = SIDE_PLAYER )
{
u16 PayDay = gPaydayMoney ;
gPaydayMoney + = ( gBattleMons [ gBankAttacker ] . level * 5 ) ;
if ( PayDay > gPaydayMoney )
gPaydayMoney = 0xFFFF ;
}
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 16:51:24 +02:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ;
2017-09-20 22:54:26 +02:00
break ;
case MOVE_EFFECT_TRI_ATTACK :
if ( gBattleMons [ gEffectBank ] . status1 )
{
gBattlescriptCurrInstr + + ;
}
else
{
gBattleCommunication [ MOVE_EFFECT_BYTE ] = Random ( ) % 3 + 3 ;
SetMoveEffect ( FALSE , 0 ) ;
}
break ;
case MOVE_EFFECT_CHARGING :
gBattleMons [ gEffectBank ] . status2 | = STATUS2_MULTIPLETURNS ;
gLockedMoves [ gEffectBank ] = gCurrentMove ;
gProtectStructs [ gEffectBank ] . chargingTurn = 1 ;
gBattlescriptCurrInstr + + ;
break ;
case MOVE_EFFECT_WRAP :
if ( gBattleMons [ gEffectBank ] . status2 & STATUS2_WRAPPED )
{
gBattlescriptCurrInstr + + ;
}
else
{
2017-09-22 21:33:49 +02:00
gBattleMons [ gEffectBank ] . status2 | = ( ( Random ( ) & 3 ) + 3 ) < < 0xD ;
2017-09-20 22:54:26 +02:00
* ( gBattleStruct - > wrappedMove + gEffectBank * 2 + 0 ) = gCurrentMove ;
* ( gBattleStruct - > wrappedMove + gEffectBank * 2 + 1 ) = gCurrentMove > > 8 ;
* ( gBattleStruct - > wrappedBy + gEffectBank ) = gBankAttacker ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 16:51:24 +02:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ;
2017-09-20 22:54:26 +02:00
2017-09-22 21:33:49 +02:00
for ( gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ; ; gBattleCommunication [ MULTISTRING_CHOOSER ] + + )
2017-09-20 22:54:26 +02:00
{
2017-09-22 21:33:49 +02:00
if ( gBattleCommunication [ MULTISTRING_CHOOSER ] > 4 )
break ;
if ( gTrappingMoves [ gBattleCommunication [ MULTISTRING_CHOOSER ] ] = = gCurrentMove )
2017-09-20 22:54:26 +02:00
break ;
}
}
break ;
case MOVE_EFFECT_RECOIL_25 : // 25% recoil
gBattleMoveDamage = ( gHpDealt ) / 4 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 16:51:24 +02:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ;
2017-09-20 22:54:26 +02:00
break ;
2017-09-22 21:33:49 +02:00
case MOVE_EFFECT_ATK_PLUS_1 :
case MOVE_EFFECT_DEF_PLUS_1 :
case MOVE_EFFECT_SPD_PLUS_1 :
case MOVE_EFFECT_SP_ATK_PLUS_1 :
case MOVE_EFFECT_SP_DEF_PLUS_1 :
case MOVE_EFFECT_ACC_PLUS_1 :
case MOVE_EFFECT_EVS_PLUS_1 :
if ( ChangeStatBuffs ( SET_STAT_BUFF_VALUE ( 1 ) ,
gBattleCommunication [ MOVE_EFFECT_BYTE ] - MOVE_EFFECT_ATK_PLUS_1 + 1 ,
affectsUser , 0 ) )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2017-09-22 21:33:49 +02:00
gBattleScripting . animArg1 = gBattleCommunication [ MOVE_EFFECT_BYTE ] & ~ ( MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN ) ;
2017-09-20 22:54:26 +02:00
gBattleScripting . animArg2 = 0 ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_StatUp ;
}
break ;
2017-09-22 21:33:49 +02:00
case MOVE_EFFECT_ATK_MINUS_1 :
case MOVE_EFFECT_DEF_MINUS_1 :
case MOVE_EFFECT_SPD_MINUS_1 :
case MOVE_EFFECT_SP_ATK_MINUS_1 :
case MOVE_EFFECT_SP_DEF_MINUS_1 :
case MOVE_EFFECT_ACC_MINUS_1 :
case MOVE_EFFECT_EVS_MINUS_1 :
if ( ChangeStatBuffs ( SET_STAT_BUFF_VALUE ( 1 ) | STAT_BUFF_NEGATIVE ,
gBattleCommunication [ MOVE_EFFECT_BYTE ] - MOVE_EFFECT_ATK_MINUS_1 + 1 ,
affectsUser , 0 ) )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2017-09-22 21:33:49 +02:00
gBattleScripting . animArg1 = gBattleCommunication [ MOVE_EFFECT_BYTE ] & ~ ( MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN ) ;
2017-09-20 22:54:26 +02:00
gBattleScripting . animArg2 = 0 ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_StatDown ;
}
break ;
2017-09-22 21:33:49 +02:00
case MOVE_EFFECT_ATK_PLUS_2 :
case MOVE_EFFECT_DEF_PLUS_2 :
case MOVE_EFFECT_SPD_PLUS_2 :
case MOVE_EFFECT_SP_ATK_PLUS_2 :
case MOVE_EFFECT_SP_DEF_PLUS_2 :
case MOVE_EFFECT_ACC_PLUS_2 :
case MOVE_EFFECT_EVS_PLUS_2 :
if ( ChangeStatBuffs ( SET_STAT_BUFF_VALUE ( 2 ) ,
gBattleCommunication [ MOVE_EFFECT_BYTE ] - MOVE_EFFECT_ATK_PLUS_2 + 1 ,
affectsUser , 0 ) )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2017-09-22 21:33:49 +02:00
gBattleScripting . animArg1 = gBattleCommunication [ MOVE_EFFECT_BYTE ] & ~ ( MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN ) ;
2017-09-20 22:54:26 +02:00
gBattleScripting . animArg2 = 0 ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_StatUp ;
}
break ;
2017-09-22 21:33:49 +02:00
case MOVE_EFFECT_ATK_MINUS_2 :
case MOVE_EFFECT_DEF_MINUS_2 :
case MOVE_EFFECT_SPD_MINUS_2 :
case MOVE_EFFECT_SP_ATK_MINUS_2 :
case MOVE_EFFECT_SP_DEF_MINUS_2 :
case MOVE_EFFECT_ACC_MINUS_2 :
case MOVE_EFFECT_EVS_MINUS_2 :
if ( ChangeStatBuffs ( SET_STAT_BUFF_VALUE ( 2 ) | STAT_BUFF_NEGATIVE ,
gBattleCommunication [ MOVE_EFFECT_BYTE ] - MOVE_EFFECT_ATK_MINUS_2 + 1 ,
affectsUser , 0 ) )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2017-09-22 21:33:49 +02:00
gBattleScripting . animArg1 = gBattleCommunication [ MOVE_EFFECT_BYTE ] & ~ ( MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN ) ;
2017-09-20 22:54:26 +02:00
gBattleScripting . animArg2 = 0 ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_StatDown ;
}
break ;
case MOVE_EFFECT_RECHARGE :
gBattleMons [ gEffectBank ] . status2 | = STATUS2_RECHARGE ;
gDisableStructs [ gEffectBank ] . rechargeCounter = 2 ;
gLockedMoves [ gEffectBank ] = gCurrentMove ;
gBattlescriptCurrInstr + + ;
break ;
case MOVE_EFFECT_RAGE :
gBattleMons [ gBankAttacker ] . status2 | = STATUS2_RAGE ;
gBattlescriptCurrInstr + + ;
break ;
case MOVE_EFFECT_STEAL_ITEM :
{
if ( gBattleTypeFlags & BATTLE_TYPE_x4000000 )
{
gBattlescriptCurrInstr + + ;
break ;
}
side = GetBankSide ( gBankAttacker ) ;
if ( GetBankSide ( gBankAttacker ) = = SIDE_OPPONENT
& & ! ( gBattleTypeFlags &
( BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_FRONTIER
| BATTLE_TYPE_LINK
| BATTLE_TYPE_x2000000
| BATTLE_TYPE_SECRET_BASE ) ) )
{
gBattlescriptCurrInstr + + ;
}
2017-09-22 21:33:49 +02:00
else if ( ! ( gBattleTypeFlags &
2017-09-20 22:54:26 +02:00
( BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_FRONTIER
| BATTLE_TYPE_LINK
| BATTLE_TYPE_x2000000
| BATTLE_TYPE_SECRET_BASE ) )
& & ( gWishFutureKnock . knockedOffPokes [ side ] & gBitTable [ gBattlePartyID [ gBankAttacker ] ] ) )
{
gBattlescriptCurrInstr + + ;
}
2017-09-22 21:33:49 +02:00
else if ( gBattleMons [ gBankTarget ] . item
2017-09-20 22:54:26 +02:00
& & gBattleMons [ gBankTarget ] . ability = = ABILITY_STICKY_HOLD )
{
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_NoItemSteal ;
gLastUsedAbility = gBattleMons [ gBankTarget ] . ability ;
RecordAbilityBattle ( gBankTarget , gLastUsedAbility ) ;
}
2017-09-27 23:43:45 +02:00
else if ( gBattleMons [ gBankAttacker ] . item ! = 0
2017-09-22 21:33:49 +02:00
| | gBattleMons [ gBankTarget ] . item = = ITEM_ENIGMA_BERRY
2017-09-27 23:43:45 +02:00
| | IS_ITEM_MAIL ( gBattleMons [ gBankTarget ] . item )
2017-09-22 21:33:49 +02:00
| | gBattleMons [ gBankTarget ] . item = = 0 )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
2017-09-22 21:33:49 +02:00
else
2017-09-20 22:54:26 +02:00
{
2017-09-27 23:43:45 +02:00
u16 * changedItem = & gBattleStruct - > changedItems [ gBankAttacker ] ;
2017-09-23 20:13:45 +02:00
gLastUsedItem = * changedItem = gBattleMons [ gBankTarget ] . item ;
2017-09-22 21:33:49 +02:00
gBattleMons [ gBankTarget ] . item = 0 ;
2017-09-20 22:54:26 +02:00
2017-09-22 21:33:49 +02:00
gActiveBank = gBankAttacker ;
2017-09-26 22:39:59 +02:00
EmitSetMonData ( 0 , REQUEST_HELDITEM_BATTLE , 0 , 2 , & gLastUsedItem ) ;
2017-09-22 21:33:49 +02:00
MarkBufferBankForExecution ( gBankAttacker ) ;
2017-09-20 22:54:26 +02:00
2017-09-22 21:33:49 +02:00
gActiveBank = gBankTarget ;
2017-09-26 22:39:59 +02:00
EmitSetMonData ( 0 , REQUEST_HELDITEM_BATTLE , 0 , 2 , & gBattleMons [ gBankTarget ] . item ) ;
2017-09-22 21:33:49 +02:00
MarkBufferBankForExecution ( gBankTarget ) ;
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
gBattlescriptCurrInstr = BattleScript_ItemSteal ;
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gBankTarget ] ) + 0 ) = 0 ;
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gBankTarget ] ) + 1 ) = 0 ;
}
2017-09-20 22:54:26 +02:00
}
break ;
case MOVE_EFFECT_PREVENT_ESCAPE :
gBattleMons [ gBankTarget ] . status2 | = STATUS2_ESCAPE_PREVENTION ;
gDisableStructs [ gBankTarget ] . bankPreventingEscape = gBankAttacker ;
gBattlescriptCurrInstr + + ;
break ;
case MOVE_EFFECT_NIGHTMARE :
gBattleMons [ gBankTarget ] . status2 | = STATUS2_NIGHTMARE ;
gBattlescriptCurrInstr + + ;
break ;
case MOVE_EFFECT_ALL_STATS_UP :
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_AllStatsUp ;
break ;
case MOVE_EFFECT_RAPIDSPIN :
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_RapidSpinAway ;
break ;
case MOVE_EFFECT_REMOVE_PARALYSIS : // Smelling salts
if ( ! ( gBattleMons [ gBankTarget ] . status1 & STATUS_PARALYSIS ) )
{
gBattlescriptCurrInstr + + ;
}
else
{
gBattleMons [ gBankTarget ] . status1 & = ~ ( STATUS_PARALYSIS ) ;
gActiveBank = gBankTarget ;
2017-09-26 22:39:59 +02:00
EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gActiveBank ] . status1 ) ;
2017-09-20 22:54:26 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_TargetPRLZHeal ;
}
break ;
case MOVE_EFFECT_ATK_DEF_DOWN : // SuperPower
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_AtkDefDown ;
break ;
case MOVE_EFFECT_RECOIL_33_PARALYSIS : // Volt Tackle
gBattleMoveDamage = gHpDealt / 3 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 16:51:24 +02:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ;
2017-09-20 22:54:26 +02:00
break ;
case MOVE_EFFECT_THRASH :
if ( gBattleMons [ gEffectBank ] . status2 & STATUS2_LOCK_CONFUSE )
{
gBattlescriptCurrInstr + + ;
}
else
{
gBattleMons [ gEffectBank ] . status2 | = STATUS2_MULTIPLETURNS ;
gLockedMoves [ gEffectBank ] = gCurrentMove ;
gBattleMons [ gEffectBank ] . status2 | = ( ( ( Random ( ) & 1 ) + 2 ) < < 0xA ) ;
}
break ;
case MOVE_EFFECT_KNOCK_OFF :
if ( gBattleMons [ gEffectBank ] . ability = = ABILITY_STICKY_HOLD )
{
if ( gBattleMons [ gEffectBank ] . item = = 0 )
{
gBattlescriptCurrInstr + + ;
}
else
{
gLastUsedAbility = ABILITY_STICKY_HOLD ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr = BattleScript_StickyHoldActivates ;
2017-09-20 22:54:26 +02:00
RecordAbilityBattle ( gEffectBank , ABILITY_STICKY_HOLD ) ;
}
break ;
}
2017-09-22 21:33:49 +02:00
if ( gBattleMons [ gEffectBank ] . item )
2017-09-20 22:54:26 +02:00
{
side = GetBankSide ( gEffectBank ) ;
gLastUsedItem = gBattleMons [ gEffectBank ] . item ;
gBattleMons [ gEffectBank ] . item = 0 ;
gWishFutureKnock . knockedOffPokes [ side ] | = gBitTable [ gBattlePartyID [ gEffectBank ] ] ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_KnockedOff ;
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gEffectBank ] ) + 0 ) = 0 ;
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gEffectBank ] ) + 1 ) = 0 ;
}
2017-09-22 21:33:49 +02:00
else
{
gBattlescriptCurrInstr + + ;
}
2017-09-20 22:54:26 +02:00
break ;
case MOVE_EFFECT_SP_ATK_TWO_DOWN : // Overheat
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_SAtkDown2 ;
break ;
}
}
}
gBattleCommunication [ MOVE_EFFECT_BYTE ] = 0 ;
}
2017-09-22 21:33:49 +02:00
2017-09-28 15:34:21 +02:00
static void atk15_seteffectwithchance ( void )
2017-09-22 21:33:49 +02:00
{
u32 percentChance ;
if ( gBattleMons [ gBankAttacker ] . ability = = ABILITY_SERENE_GRACE )
percentChance = gBattleMoves [ gCurrentMove ] . secondaryEffectChance * 2 ;
else
percentChance = gBattleMoves [ gCurrentMove ] . secondaryEffectChance ;
if ( gBattleCommunication [ MOVE_EFFECT_BYTE ] & MOVE_EFFECT_CERTAIN
& & ! ( gBattleMoveFlags & MOVESTATUS_NOEFFECT ) )
{
gBattleCommunication [ MOVE_EFFECT_BYTE ] & = ~ ( MOVE_EFFECT_CERTAIN ) ;
SetMoveEffect ( 0 , MOVE_EFFECT_CERTAIN ) ;
}
else if ( Random ( ) % 100 < percentChance
& & gBattleCommunication [ MOVE_EFFECT_BYTE ]
& & ! ( gBattleMoveFlags & MOVESTATUS_NOEFFECT ) )
{
if ( percentChance > = 100 )
SetMoveEffect ( 0 , MOVE_EFFECT_CERTAIN ) ;
else
SetMoveEffect ( 0 , 0 ) ;
}
else
{
gBattlescriptCurrInstr + + ;
}
gBattleCommunication [ MOVE_EFFECT_BYTE ] = 0 ;
gBattleScripting . field_16 = 0 ;
}
2017-09-28 15:34:21 +02:00
static void atk16_seteffectprimary ( void )
2017-09-22 21:33:49 +02:00
{
SetMoveEffect ( TRUE , 0 ) ;
}
2017-09-28 15:34:21 +02:00
static void atk17_seteffectsecondary ( void )
2017-09-22 21:33:49 +02:00
{
SetMoveEffect ( FALSE , 0 ) ;
}
2017-11-25 18:42:31 +01:00
static void atk18_clearstatusfromeffect ( void )
2017-09-22 21:33:49 +02:00
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-22 21:33:49 +02:00
if ( gBattleCommunication [ MOVE_EFFECT_BYTE ] < = MOVE_EFFECT_TOXIC )
2017-09-28 16:51:24 +02:00
gBattleMons [ gActiveBank ] . status1 & = ( ~ sStatusFlagsForMoveEffects [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ) ;
2017-09-22 21:33:49 +02:00
else
2017-09-28 16:51:24 +02:00
gBattleMons [ gActiveBank ] . status2 & = ( ~ sStatusFlagsForMoveEffects [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ) ;
2017-09-22 21:33:49 +02:00
gBattleCommunication [ MOVE_EFFECT_BYTE ] = 0 ;
gBattlescriptCurrInstr + = 2 ;
gBattleScripting . field_16 = 0 ;
}
2017-11-25 18:42:31 +01:00
static void atk19_tryfaintmon ( void )
2017-09-22 21:33:49 +02:00
{
const u8 * BS_ptr ;
if ( gBattlescriptCurrInstr [ 2 ] ! = 0 )
{
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
if ( gHitMarker & HITMARKER_FAINTED ( gActiveBank ) )
{
BS_ptr = BSScriptReadPtr ( gBattlescriptCurrInstr + 3 ) ;
BattleScriptPop ( ) ;
gBattlescriptCurrInstr = BS_ptr ;
gSideAffecting [ GetBankSide ( gActiveBank ) ] & = ~ ( SIDE_STATUS_SPIKES_DAMAGED ) ;
}
else
{
gBattlescriptCurrInstr + = 7 ;
}
}
else
{
u8 bank ;
if ( gBattlescriptCurrInstr [ 1 ] = = BS_GET_ATTACKER )
{
gActiveBank = gBankAttacker ;
bank = gBankTarget ;
BS_ptr = BattleScript_FaintAttacker ;
}
else
{
gActiveBank = gBankTarget ;
bank = gBankAttacker ;
BS_ptr = BattleScript_FaintTarget ;
}
if ( ! ( gAbsentBankFlags & gBitTable [ gActiveBank ] )
& & gBattleMons [ gActiveBank ] . hp = = 0 )
{
gHitMarker | = HITMARKER_FAINTED ( gActiveBank ) ;
BattleScriptPush ( gBattlescriptCurrInstr + 7 ) ;
gBattlescriptCurrInstr = BS_ptr ;
if ( GetBankSide ( gActiveBank ) = = SIDE_PLAYER )
{
gHitMarker | = HITMARKER_x400000 ;
if ( gBattleResults . playerFaintCounter < 0xFF )
gBattleResults . playerFaintCounter + + ;
AdjustFriendshipOnBattleFaint ( gActiveBank ) ;
}
else
{
if ( gBattleResults . opponentFaintCounter < 0xFF )
gBattleResults . opponentFaintCounter + + ;
gBattleResults . lastOpponentSpecies = GetMonData ( & gEnemyParty [ gBattlePartyID [ gActiveBank ] ] , MON_DATA_SPECIES , NULL ) ;
}
if ( ( gHitMarker & HITMARKER_DESTINYBOND ) & & gBattleMons [ gBankAttacker ] . hp ! = 0 )
{
gHitMarker & = ~ ( HITMARKER_DESTINYBOND ) ;
BattleScriptPush ( gBattlescriptCurrInstr ) ;
gBattleMoveDamage = gBattleMons [ bank ] . hp ;
gBattlescriptCurrInstr = BattleScript_DestinyBondTakesLife ;
}
if ( ( gStatuses3 [ gBankTarget ] & STATUS3_GRUDGE )
& & ! ( gHitMarker & HITMARKER_GRUDGE )
& & GetBankSide ( gBankAttacker ) ! = GetBankSide ( gBankTarget )
& & gBattleMons [ gBankAttacker ] . hp ! = 0
& & gCurrentMove ! = MOVE_STRUGGLE )
{
2017-10-06 00:12:01 +02:00
u8 moveIndex = * ( gBattleStruct - > chosenMovePositions + gBankAttacker ) ;
2017-09-22 21:33:49 +02:00
gBattleMons [ gBankAttacker ] . pp [ moveIndex ] = 0 ;
BattleScriptPush ( gBattlescriptCurrInstr ) ;
gBattlescriptCurrInstr = BattleScript_GrudgeTakesPp ;
gActiveBank = gBankAttacker ;
2017-09-26 22:39:59 +02:00
EmitSetMonData ( 0 , moveIndex + REQUEST_PPMOVE1_BATTLE , 0 , 1 , & gBattleMons [ gActiveBank ] . pp [ moveIndex ] ) ;
2017-09-22 21:33:49 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
2017-09-25 00:09:13 +02:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , gBattleMons [ gBankAttacker ] . moves [ moveIndex ] )
2017-09-22 21:33:49 +02:00
}
}
else
{
gBattlescriptCurrInstr + = 7 ;
}
}
}
2017-11-25 18:42:31 +01:00
static void atk1A_dofaintanimation ( void )
2017-09-22 21:33:49 +02:00
{
if ( gBattleExecBuffer = = 0 )
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-22 21:33:49 +02:00
EmitFaintAnimation ( 0 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 2 ;
}
}
2017-11-25 18:42:31 +01:00
static void atk1B_cleareffectsonfaint ( void )
2017-09-22 21:33:49 +02:00
{
if ( gBattleExecBuffer = = 0 )
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-22 21:33:49 +02:00
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_ARENA ) | | gBattleMons [ gActiveBank ] . hp = = 0 )
{
gBattleMons [ gActiveBank ] . status1 = 0 ;
2017-09-26 22:39:59 +02:00
EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 0x4 , & gBattleMons [ gActiveBank ] . status1 ) ;
2017-09-22 21:33:49 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
}
2017-10-02 23:32:39 +02:00
FaintClearSetData ( ) ; // Effects like attractions, trapping, etc.
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr + = 2 ;
}
}
2017-09-28 15:34:21 +02:00
static void atk1C_jumpifstatus ( void )
2017-09-22 21:33:49 +02:00
{
2017-09-28 15:34:21 +02:00
u8 bank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-22 21:33:49 +02:00
u32 flags = BS2ScriptRead32 ( gBattlescriptCurrInstr + 2 ) ;
const u8 * jumpPtr = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 6 ) ;
if ( gBattleMons [ bank ] . status1 & flags & & gBattleMons [ bank ] . hp )
gBattlescriptCurrInstr = jumpPtr ;
else
gBattlescriptCurrInstr + = 10 ;
}
2017-09-28 15:34:21 +02:00
static void atk1D_jumpifstatus2 ( void )
2017-09-22 21:33:49 +02:00
{
2017-09-28 15:34:21 +02:00
u8 bank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-22 21:33:49 +02:00
u32 flags = BS2ScriptRead32 ( gBattlescriptCurrInstr + 2 ) ;
const u8 * jumpPtr = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 6 ) ;
if ( gBattleMons [ bank ] . status2 & flags & & gBattleMons [ bank ] . hp )
gBattlescriptCurrInstr = jumpPtr ;
else
gBattlescriptCurrInstr + = 10 ;
}
2017-09-28 15:34:21 +02:00
static void atk1E_jumpifability ( void )
2017-09-22 21:33:49 +02:00
{
u8 bank ;
2017-09-28 15:34:21 +02:00
u8 ability = gBattlescriptCurrInstr [ 2 ] ;
2017-09-22 21:33:49 +02:00
const u8 * jumpPtr = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 3 ) ;
2017-09-28 15:34:21 +02:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_GET_ATTACKER_SIDE )
2017-09-22 21:33:49 +02:00
{
bank = AbilityBattleEffects ( ABILITYEFFECT_CHECK_BANK_SIDE , gBankAttacker , ability , 0 , 0 ) ;
if ( bank )
{
gLastUsedAbility = ability ;
gBattlescriptCurrInstr = jumpPtr ;
RecordAbilityBattle ( bank - 1 , gLastUsedAbility ) ;
gBattleScripting . field_15 = bank - 1 ;
}
else
gBattlescriptCurrInstr + = 7 ;
}
2017-09-28 15:34:21 +02:00
else if ( gBattlescriptCurrInstr [ 1 ] = = BS_GET_NOT_ATTACKER_SIDE )
2017-09-22 21:33:49 +02:00
{
bank = AbilityBattleEffects ( ABILITYEFFECT_CHECK_OTHER_SIDE , gBankAttacker , ability , 0 , 0 ) ;
if ( bank )
{
gLastUsedAbility = ability ;
gBattlescriptCurrInstr = jumpPtr ;
RecordAbilityBattle ( bank - 1 , gLastUsedAbility ) ;
gBattleScripting . field_15 = bank - 1 ;
}
else
gBattlescriptCurrInstr + = 7 ;
}
else
{
2017-09-28 15:34:21 +02:00
bank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-22 21:33:49 +02:00
if ( gBattleMons [ bank ] . ability = = ability )
{
gLastUsedAbility = ability ;
gBattlescriptCurrInstr = jumpPtr ;
RecordAbilityBattle ( bank , gLastUsedAbility ) ;
gBattleScripting . field_15 = bank ;
}
else
gBattlescriptCurrInstr + = 7 ;
}
}
2017-09-28 15:34:21 +02:00
static void atk1F_jumpifsideaffecting ( void )
2017-09-22 21:33:49 +02:00
{
u8 side ;
u16 flags ;
const u8 * jumpPtr ;
2017-09-28 15:34:21 +02:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_GET_ATTACKER )
2017-09-22 21:33:49 +02:00
side = GET_BANK_SIDE ( gBankAttacker ) ;
else
side = GET_BANK_SIDE ( gBankTarget ) ;
flags = BS2ScriptRead16 ( gBattlescriptCurrInstr + 2 ) ;
jumpPtr = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 4 ) ;
if ( gSideAffecting [ side ] & flags )
gBattlescriptCurrInstr = jumpPtr ;
else
gBattlescriptCurrInstr + = 8 ;
}
2017-09-28 15:34:21 +02:00
static void atk20_jumpifstat ( void )
2017-09-22 21:33:49 +02:00
{
u8 ret = 0 ;
2017-09-28 15:34:21 +02:00
u8 bank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
u8 value = gBattleMons [ bank ] . statStages [ gBattlescriptCurrInstr [ 3 ] ] ;
2017-09-22 21:33:49 +02:00
2017-09-28 15:34:21 +02:00
switch ( gBattlescriptCurrInstr [ 2 ] )
2017-09-22 21:33:49 +02:00
{
case CMP_EQUAL :
2017-09-28 15:34:21 +02:00
if ( value = = gBattlescriptCurrInstr [ 4 ] )
2017-09-22 21:33:49 +02:00
ret + + ;
break ;
case CMP_NOT_EQUAL :
2017-09-28 15:34:21 +02:00
if ( value ! = gBattlescriptCurrInstr [ 4 ] )
2017-09-22 21:33:49 +02:00
ret + + ;
break ;
case CMP_GREATER_THAN :
2017-09-28 15:34:21 +02:00
if ( value > gBattlescriptCurrInstr [ 4 ] )
2017-09-22 21:33:49 +02:00
ret + + ;
break ;
case CMP_LESS_THAN :
2017-09-28 15:34:21 +02:00
if ( value < gBattlescriptCurrInstr [ 4 ] )
2017-09-22 21:33:49 +02:00
ret + + ;
break ;
case CMP_COMMON_BITS :
2017-09-28 15:34:21 +02:00
if ( value & gBattlescriptCurrInstr [ 4 ] )
2017-09-22 21:33:49 +02:00
ret + + ;
break ;
case CMP_NO_COMMON_BITS :
2017-09-28 15:34:21 +02:00
if ( ! ( value & gBattlescriptCurrInstr [ 4 ] ) )
2017-09-22 21:33:49 +02:00
ret + + ;
break ;
}
if ( ret )
gBattlescriptCurrInstr = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 5 ) ;
else
gBattlescriptCurrInstr + = 9 ;
}
2017-11-26 11:55:17 +01:00
static void atk21_jumpifstatus3condition ( void )
2017-09-22 21:33:49 +02:00
{
u32 flags ;
2017-11-26 11:55:17 +01:00
const u8 * jumpPtr ;
2017-09-22 21:33:49 +02:00
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-22 21:33:49 +02:00
flags = BS2ScriptRead32 ( gBattlescriptCurrInstr + 2 ) ;
jumpPtr = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 7 ) ;
2017-09-28 15:34:21 +02:00
if ( gBattlescriptCurrInstr [ 6 ] )
2017-09-22 21:33:49 +02:00
{
if ( ( gStatuses3 [ gActiveBank ] & flags ) ! = 0 )
gBattlescriptCurrInstr + = 11 ;
else
gBattlescriptCurrInstr = jumpPtr ;
}
else
{
if ( ( gStatuses3 [ gActiveBank ] & flags ) ! = 0 )
gBattlescriptCurrInstr = jumpPtr ;
else
gBattlescriptCurrInstr + = 11 ;
}
}
2017-09-28 15:34:21 +02:00
static void atk22_jumpiftype ( void )
2017-09-22 21:33:49 +02:00
{
2017-09-28 15:34:21 +02:00
u8 bank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
u8 type = gBattlescriptCurrInstr [ 2 ] ;
2017-09-22 21:33:49 +02:00
const u8 * jumpPtr = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 3 ) ;
if ( gBattleMons [ bank ] . type1 = = type | | gBattleMons [ bank ] . type2 = = type )
gBattlescriptCurrInstr = jumpPtr ;
else
gBattlescriptCurrInstr + = 7 ;
}
2017-09-28 15:34:21 +02:00
static void atk23_getexp ( void )
2017-09-22 21:33:49 +02:00
{
u16 item ;
s32 i ; // also used as stringId
u8 holdEffect ;
s32 sentIn ;
s32 viaExpShare = 0 ;
u16 * exp = & gBattleStruct - > expValue ;
2017-09-28 15:34:21 +02:00
gBank1 = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-22 21:33:49 +02:00
sentIn = gSentPokesToOpponent [ ( gBank1 & 2 ) > > 1 ] ;
switch ( gBattleScripting . atk23_state )
{
case 0 : // check if should receive exp at all
if ( GetBankSide ( gBank1 ) ! = SIDE_OPPONENT | | ( gBattleTypeFlags &
( BATTLE_TYPE_LINK
| BATTLE_TYPE_x2000000
| BATTLE_TYPE_x4000000
| BATTLE_TYPE_FRONTIER
| BATTLE_TYPE_SAFARI
| BATTLE_TYPE_BATTLE_TOWER
| BATTLE_TYPE_EREADER_TRAINER ) ) )
{
gBattleScripting . atk23_state = 6 ; // goto last case
}
else
{
gBattleScripting . atk23_state + + ;
gBattleStruct - > field_DF | = gBitTable [ gBattlePartyID [ gBank1 ] ] ;
}
break ;
case 1 : // calculate experience points to redistribute
{
u16 calculatedExp ;
s32 viaSentIn ;
for ( viaSentIn = 0 , i = 0 ; i < 6 ; i + + )
{
if ( GetMonData ( & gPlayerParty [ i ] , MON_DATA_SPECIES ) = = SPECIES_NONE | | GetMonData ( & gPlayerParty [ i ] , MON_DATA_HP ) = = 0 )
continue ;
if ( gBitTable [ i ] & sentIn )
viaSentIn + + ;
item = GetMonData ( & gPlayerParty [ i ] , MON_DATA_HELD_ITEM ) ;
if ( item = = ITEM_ENIGMA_BERRY )
holdEffect = gSaveBlock1Ptr - > enigmaBerry . holdEffect ;
else
holdEffect = ItemId_GetHoldEffect ( item ) ;
if ( holdEffect = = HOLD_EFFECT_EXP_SHARE )
viaExpShare + + ;
}
calculatedExp = gBaseStats [ gBattleMons [ gBank1 ] . species ] . expYield * gBattleMons [ gBank1 ] . level / 7 ;
if ( viaExpShare ) // at least one mon is getting exp via exp share
{
* exp = calculatedExp / 2 / viaSentIn ;
if ( * exp = = 0 )
* exp = 1 ;
gExpShareExp = calculatedExp / 2 / viaExpShare ;
if ( gExpShareExp = = 0 )
gExpShareExp = 1 ;
}
else
{
* exp = calculatedExp / viaSentIn ;
if ( * exp = = 0 )
* exp = 1 ;
gExpShareExp = 0 ;
}
gBattleScripting . atk23_state + + ;
gBattleStruct - > expGetterId = 0 ;
gBattleStruct - > sentInPokes = sentIn ;
}
// fall through
case 2 : // set exp value to the poke in expgetter_id and print message
if ( gBattleExecBuffer = = 0 )
{
item = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_HELD_ITEM ) ;
if ( item = = ITEM_ENIGMA_BERRY )
holdEffect = gSaveBlock1Ptr - > enigmaBerry . holdEffect ;
else
holdEffect = ItemId_GetHoldEffect ( item ) ;
if ( holdEffect ! = HOLD_EFFECT_EXP_SHARE & & ! ( gBattleStruct - > sentInPokes & 1 ) )
{
* ( & gBattleStruct - > sentInPokes ) > > = 1 ;
gBattleScripting . atk23_state = 5 ;
gBattleMoveDamage = 0 ; // used for exp
}
else if ( GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_LEVEL ) = = MAX_MON_LEVEL )
{
* ( & gBattleStruct - > sentInPokes ) > > = 1 ;
gBattleScripting . atk23_state = 5 ;
gBattleMoveDamage = 0 ; // used for exp
}
else
{
// music change in wild battle after fainting a poke
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_TRAINER ) & & gBattleMons [ 0 ] . hp & & ! gBattleStruct - > wildVictorySong )
{
2017-11-04 16:11:13 +01:00
BattleStopLowHpSound ( ) ;
2017-09-22 21:33:49 +02:00
PlayBGM ( 0x161 ) ;
gBattleStruct - > wildVictorySong + + ;
}
if ( GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_HP ) )
{
if ( gBattleStruct - > sentInPokes & 1 )
gBattleMoveDamage = * exp ;
else
gBattleMoveDamage = 0 ;
if ( holdEffect = = HOLD_EFFECT_EXP_SHARE )
gBattleMoveDamage + = gExpShareExp ;
if ( holdEffect = = HOLD_EFFECT_LUCKY_EGG )
gBattleMoveDamage = ( gBattleMoveDamage * 150 ) / 100 ;
if ( gBattleTypeFlags & BATTLE_TYPE_TRAINER )
gBattleMoveDamage = ( gBattleMoveDamage * 150 ) / 100 ;
if ( IsTradedMon ( & gPlayerParty [ gBattleStruct - > expGetterId ] ) )
{
// check if the pokemon doesn't belong to the player
if ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER & & gBattleStruct - > expGetterId > = 3 )
{
i = 0x149 ;
}
else
{
gBattleMoveDamage = ( gBattleMoveDamage * 150 ) / 100 ;
i = 0x14A ;
}
}
else
{
2017-09-27 23:43:45 +02:00
i = 0x149 ;
}
2017-09-22 21:33:49 +02:00
// get exp getter bank
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
{
if ( ! ( gBattlePartyID [ 2 ] ! = gBattleStruct - > expGetterId ) & & ! ( gAbsentBankFlags & gBitTable [ 2 ] ) )
gBattleStruct - > expGetterBank = 2 ;
else
{
if ( ! ( gAbsentBankFlags & gBitTable [ 0 ] ) )
gBattleStruct - > expGetterBank = 0 ;
else
gBattleStruct - > expGetterBank = 2 ;
}
}
else
gBattleStruct - > expGetterBank = 0 ;
2017-09-25 00:09:13 +02:00
PREPARE_MON_NICK_WITH_PREFIX_BUFFER ( gBattleTextBuff1 , gBattleStruct - > expGetterBank , gBattleStruct - > expGetterId )
2017-09-22 21:33:49 +02:00
// buffer 'gained' or 'gained a boosted'
2017-09-25 00:09:13 +02:00
PREPARE_STRING_BUFFER ( gBattleTextBuff2 , i )
PREPARE_WORD_NUMBER_BUFFER ( gBattleTextBuff3 , 5 , gBattleMoveDamage )
2017-09-22 21:33:49 +02:00
2017-10-07 15:15:47 +02:00
PrepareStringBattle ( STRINGID_PKMNGAINEDEXP , gBattleStruct - > expGetterBank ) ;
2017-09-22 21:33:49 +02:00
MonGainEVs ( & gPlayerParty [ gBattleStruct - > expGetterId ] , gBattleMons [ gBank1 ] . species ) ;
}
gBattleStruct - > sentInPokes > > = 1 ;
gBattleScripting . atk23_state + + ;
}
}
break ;
case 3 : // Set stats and give exp
if ( gBattleExecBuffer = = 0 )
{
gBattleBufferB [ gBattleStruct - > expGetterBank ] [ 0 ] = 0 ;
if ( GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_HP ) & & GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_LEVEL ) ! = MAX_MON_LEVEL )
{
BATTLE_LVLUP_STATS - > hp = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_MAX_HP ) ;
BATTLE_LVLUP_STATS - > atk = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_ATK ) ;
BATTLE_LVLUP_STATS - > def = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_DEF ) ;
2017-10-24 03:43:26 +02:00
BATTLE_LVLUP_STATS - > spd = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_SPEED ) ;
2017-09-22 21:33:49 +02:00
BATTLE_LVLUP_STATS - > spAtk = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_SPATK ) ;
BATTLE_LVLUP_STATS - > spDef = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_SPDEF ) ;
gActiveBank = gBattleStruct - > expGetterBank ;
EmitExpUpdate ( 0 , gBattleStruct - > expGetterId , gBattleMoveDamage ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
}
gBattleScripting . atk23_state + + ;
}
break ;
case 4 : // lvl up if necessary
if ( gBattleExecBuffer = = 0 )
{
gActiveBank = gBattleStruct - > expGetterBank ;
2017-10-22 18:43:15 +02:00
if ( gBattleBufferB [ gActiveBank ] [ 0 ] = = CONTROLLER_TWORETURNVALUES & & gBattleBufferB [ gActiveBank ] [ 1 ] = = RET_VALUE_LEVELLED_UP )
2017-09-22 21:33:49 +02:00
{
if ( gBattleTypeFlags & BATTLE_TYPE_TRAINER & & gBattlePartyID [ gActiveBank ] = = gBattleStruct - > expGetterId )
2017-11-04 16:11:13 +01:00
HandleLowHpMusicChange ( & gPlayerParty [ gBattlePartyID [ gActiveBank ] ] , gActiveBank ) ;
2017-09-22 21:33:49 +02:00
2017-09-25 00:09:13 +02:00
PREPARE_MON_NICK_WITH_PREFIX_BUFFER ( gBattleTextBuff1 , gActiveBank , gBattleStruct - > expGetterId )
PREPARE_BYTE_NUMBER_BUFFER ( gBattleTextBuff2 , 3 , GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_LEVEL ) )
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
gLeveledUpInBattle | = gBitTable [ gBattleStruct - > expGetterId ] ;
gBattlescriptCurrInstr = BattleScript_LevelUp ;
gBattleMoveDamage = ( gBattleBufferB [ gActiveBank ] [ 2 ] | ( gBattleBufferB [ gActiveBank ] [ 3 ] < < 8 ) ) ;
AdjustFriendship ( & gPlayerParty [ gBattleStruct - > expGetterId ] , 0 ) ;
// update battle mon structure after level up
if ( gBattlePartyID [ 0 ] = = gBattleStruct - > expGetterId & & gBattleMons [ 0 ] . hp )
{
gBattleMons [ 0 ] . level = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_LEVEL ) ;
gBattleMons [ 0 ] . hp = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_HP ) ;
gBattleMons [ 0 ] . maxHP = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_MAX_HP ) ;
gBattleMons [ 0 ] . attack = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_ATK ) ;
gBattleMons [ 0 ] . defense = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_DEF ) ;
// Why is this duplicated?
2017-10-24 03:43:26 +02:00
gBattleMons [ 0 ] . speed = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_SPEED ) ;
gBattleMons [ 0 ] . speed = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_SPEED ) ;
2017-09-22 21:33:49 +02:00
gBattleMons [ 0 ] . spAttack = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_SPATK ) ;
gBattleMons [ 0 ] . spDefense = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_SPDEF ) ;
}
// What is else if?
if ( gBattlePartyID [ 2 ] = = gBattleStruct - > expGetterId & & gBattleMons [ 2 ] . hp & & ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE ) )
{
gBattleMons [ 2 ] . level = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_LEVEL ) ;
gBattleMons [ 2 ] . hp = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_HP ) ;
gBattleMons [ 2 ] . maxHP = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_MAX_HP ) ;
gBattleMons [ 2 ] . attack = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_ATK ) ;
gBattleMons [ 2 ] . defense = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_DEF ) ;
// Duplicated again, but this time there's no Sp Defense
2017-10-24 03:43:26 +02:00
gBattleMons [ 2 ] . speed = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_SPEED ) ;
gBattleMons [ 2 ] . speed = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_SPEED ) ;
2017-09-22 21:33:49 +02:00
gBattleMons [ 2 ] . spAttack = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_SPATK ) ;
}
gBattleScripting . atk23_state = 5 ;
}
else
{
gBattleMoveDamage = 0 ;
gBattleScripting . atk23_state = 5 ;
}
}
break ;
case 5 : // looper increment
if ( gBattleMoveDamage ) // there is exp to give, goto case 3 that gives exp
gBattleScripting . atk23_state = 3 ;
else
{
gBattleStruct - > expGetterId + + ;
if ( gBattleStruct - > expGetterId < = 5 )
gBattleScripting . atk23_state = 2 ; // loop again
else
gBattleScripting . atk23_state = 6 ; // we're done
}
break ;
case 6 : // increment instruction
if ( gBattleExecBuffer = = 0 )
{
// not sure why gf clears the item and ability here
gBattleMons [ gBank1 ] . item = 0 ;
gBattleMons [ gBank1 ] . ability = 0 ;
gBattlescriptCurrInstr + = 2 ;
}
break ;
}
}
# ifdef NONMATCHING
2017-09-28 15:34:21 +02:00
static void atk24 ( void )
2017-09-22 21:33:49 +02:00
{
u16 HP_count = 0 ;
s32 i ;
if ( gBattleExecBuffer )
return ;
if ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER & & gPartnerTrainerId = = STEVEN_PARTNER_ID )
{
for ( i = 0 ; i < 3 ; i + + )
{
if ( GetMonData ( & gPlayerParty [ i ] , MON_DATA_SPECIES ) & & ! GetMonData ( & gPlayerParty [ i ] , MON_DATA_IS_EGG ) )
HP_count + = GetMonData ( & gPlayerParty [ i ] , MON_DATA_HP ) ;
}
}
else
{
for ( i = 0 ; i < 6 ; i + + )
{
if ( GetMonData ( & gPlayerParty [ i ] , MON_DATA_SPECIES ) & & ! GetMonData ( & gPlayerParty [ i ] , MON_DATA_IS_EGG )
& & ( ! ( gBattleTypeFlags & BATTLE_TYPE_ARENA ) | | ! ( gBattleStruct - > field_2A0 & gBitTable [ i ] ) ) )
{
HP_count + = GetMonData ( & gPlayerParty [ i ] , MON_DATA_HP ) ;
}
}
}
if ( HP_count = = 0 )
gBattleOutcome | = BATTLE_LOST ;
for ( HP_count = 0 , i = 0 ; i < 6 ; i + + )
{
if ( GetMonData ( & gEnemyParty [ i ] , MON_DATA_SPECIES ) & & ! GetMonData ( & gEnemyParty [ i ] , MON_DATA_IS_EGG )
& & ( ! ( gBattleTypeFlags & BATTLE_TYPE_ARENA ) | | ! ( gBattleStruct - > field_2A1 & gBitTable [ i ] ) ) )
{
HP_count + = GetMonData ( & gEnemyParty [ i ] , MON_DATA_HP ) ;
}
}
if ( HP_count = = 0 )
gBattleOutcome | = BATTLE_WON ;
if ( gBattleOutcome = = 0 & & ( gBattleTypeFlags & ( BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000 ) ) )
{
s32 foundPlayer ;
s32 foundOpponent ;
// Impossible to decompile loops.
for ( foundPlayer = 0 , i = 0 ; i < gNoOfAllBanks ; i + = 2 )
{
if ( HITMARKER_UNK ( i ) & gHitMarker & & ! gSpecialStatuses [ i ] . flag40 )
foundPlayer + + ;
}
for ( foundOpponent = 0 , i = 1 ; i < gNoOfAllBanks ; i + = 2 )
{
if ( HITMARKER_UNK ( i ) & gHitMarker & & ! gSpecialStatuses [ i ] . flag40 )
foundOpponent + + ;
}
if ( gBattleTypeFlags & BATTLE_TYPE_MULTI )
{
if ( foundOpponent + foundPlayer > 1 )
gBattlescriptCurrInstr = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
else
gBattlescriptCurrInstr + = 5 ;
}
else
{
if ( foundOpponent ! = 0 & & foundPlayer ! = 0 )
gBattlescriptCurrInstr = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
else
gBattlescriptCurrInstr + = 5 ;
}
}
else
{
gBattlescriptCurrInstr + = 5 ;
}
}
# else
__attribute__ ( ( naked ) )
2017-09-28 15:34:21 +02:00
static void atk24 ( void )
2017-09-22 21:33:49 +02:00
{
asm ( " \n \
. syntax unified \ n \
push { r4 - r7 , lr } \ n \
mov r7 , r8 \ n \
push { r7 } \ n \
movs r6 , 0 \ n \
ldr r0 , = gBattleExecBuffer \ n \
ldr r0 , [ r0 ] \ n \
cmp r0 , 0 \ n \
beq _0804ACE2 \ n \
b _0804AF22 \ n \
_0804ACE2 : \ n \
ldr r0 , = gBattleTypeFlags \ n \
ldr r0 , [ r0 ] \ n \
movs r1 , 0x80 \ n \
lsls r1 , 15 \ n \
ands r0 , r1 \ n \
cmp r0 , 0 \ n \
beq _0804AD48 \ n \
ldr r0 , = gPartnerTrainerId \ n \
ldrh r1 , [ r0 ] \ n \
ldr r0 , = 0x00000c03 \ n \
cmp r1 , r0 \ n \
bne _0804AD48 \ n \
movs r5 , 0 \ n \
_0804ACFC : \ n \
movs r0 , 0x64 \ n \
adds r1 , r5 , 0 \ n \
muls r1 , r0 \ n \
ldr r0 , = gPlayerParty \ n \
adds r4 , r1 , r0 \ n \
adds r0 , r4 , 0 \ n \
movs r1 , 0xB \ n \
bl GetMonData \ n \
cmp r0 , 0 \ n \
beq _0804AD2C \ n \
adds r0 , r4 , 0 \ n \
movs r1 , 0x2D \ n \
bl GetMonData \ n \
cmp r0 , 0 \ n \
bne _0804AD2C \ n \
adds r0 , r4 , 0 \ n \
movs r1 , 0x39 \ n \
bl GetMonData \ n \
adds r0 , r6 , r0 \ n \
lsls r0 , 16 \ n \
lsrs r6 , r0 , 16 \ n \
_0804AD2C : \ n \
adds r5 , 0x1 \ n \
cmp r5 , 0x2 \ n \
ble _0804ACFC \ n \
b _0804ADA8 \ n \
. pool \ n \
_0804AD48 : \ n \
movs r5 , 0 \ n \
_0804AD4A : \ n \
movs r0 , 0x64 \ n \
adds r1 , r5 , 0 \ n \
muls r1 , r0 \ n \
ldr r0 , = gPlayerParty \ n \
adds r4 , r1 , r0 \ n \
adds r0 , r4 , 0 \ n \
movs r1 , 0xB \ n \
bl GetMonData \ n \
cmp r0 , 0 \ n \
beq _0804ADA2 \ n \
adds r0 , r4 , 0 \ n \
movs r1 , 0x2D \ n \
bl GetMonData \ n \
cmp r0 , 0 \ n \
bne _0804ADA2 \ n \
ldr r0 , = gBattleTypeFlags \ n \
ldr r0 , [ r0 ] \ n \
movs r1 , 0x80 \ n \
lsls r1 , 11 \ n \
ands r0 , r1 \ n \
cmp r0 , 0 \ n \
beq _0804AD94 \ n \
ldr r0 , = gBattleStruct \ n \
ldr r0 , [ r0 ] \ n \
movs r1 , 0xA8 \ n \
lsls r1 , 2 \ n \
adds r0 , r1 \ n \
ldrb r1 , [ r0 ] \ n \
ldr r2 , = gBitTable \ n \
lsls r0 , r5 , 2 \ n \
adds r0 , r2 \ n \
ldr r0 , [ r0 ] \ n \
ands r1 , r0 \ n \
cmp r1 , 0 \ n \
bne _0804ADA2 \ n \
_0804AD94 : \ n \
adds r0 , r4 , 0 \ n \
movs r1 , 0x39 \ n \
bl GetMonData \ n \
adds r0 , r6 , r0 \ n \
lsls r0 , 16 \ n \
lsrs r6 , r0 , 16 \ n \
_0804ADA2 : \ n \
adds r5 , 0x1 \ n \
cmp r5 , 0x5 \ n \
ble _0804AD4A \ n \
_0804ADA8 : \ n \
cmp r6 , 0 \ n \
bne _0804ADB6 \ n \
ldr r0 , = gBattleOutcome \ n \
ldrb r1 , [ r0 ] \ n \
movs r2 , 0x2 \ n \
orrs r1 , r2 \ n \
strb r1 , [ r0 ] \ n \
_0804ADB6 : \ n \
movs r6 , 0 \ n \
movs r5 , 0 \ n \
_0804ADBA : \ n \
movs r0 , 0x64 \ n \
adds r1 , r5 , 0 \ n \
muls r1 , r0 \ n \
ldr r0 , = gEnemyParty \ n \
adds r4 , r1 , r0 \ n \
adds r0 , r4 , 0 \ n \
movs r1 , 0xB \ n \
bl GetMonData \ n \
cmp r0 , 0 \ n \
beq _0804AE10 \ n \
adds r0 , r4 , 0 \ n \
movs r1 , 0x2D \ n \
bl GetMonData \ n \
cmp r0 , 0 \ n \
bne _0804AE10 \ n \
ldr r0 , = gBattleTypeFlags \ n \
ldr r0 , [ r0 ] \ n \
movs r1 , 0x80 \ n \
lsls r1 , 11 \ n \
ands r0 , r1 \ n \
cmp r0 , 0 \ n \
beq _0804AE02 \ n \
ldr r0 , = gBattleStruct \ n \
ldr r0 , [ r0 ] \ n \
ldr r1 , = 0x000002a1 \ n \
adds r0 , r1 \ n \
ldrb r1 , [ r0 ] \ n \
ldr r2 , = gBitTable \ n \
lsls r0 , r5 , 2 \ n \
adds r0 , r2 \ n \
ldr r0 , [ r0 ] \ n \
ands r1 , r0 \ n \
cmp r1 , 0 \ n \
bne _0804AE10 \ n \
_0804AE02 : \ n \
adds r0 , r4 , 0 \ n \
movs r1 , 0x39 \ n \
bl GetMonData \ n \
adds r0 , r6 , r0 \ n \
lsls r0 , 16 \ n \
lsrs r6 , r0 , 16 \ n \
_0804AE10 : \ n \
adds r5 , 0x1 \ n \
cmp r5 , 0x5 \ n \
ble _0804ADBA \ n \
ldr r2 , = gBattleOutcome \ n \
cmp r6 , 0 \ n \
bne _0804AE24 \ n \
ldrb r0 , [ r2 ] \ n \
movs r1 , 0x1 \ n \
orrs r0 , r1 \ n \
strb r0 , [ r2 ] \ n \
_0804AE24 : \ n \
ldrb r0 , [ r2 ] \ n \
cmp r0 , 0 \ n \
bne _0804AF1A \ n \
ldr r0 , = gBattleTypeFlags \ n \
ldr r1 , [ r0 ] \ n \
ldr r2 , = 0x02000002 \ n \
ands r1 , r2 \ n \
mov r8 , r0 \ n \
cmp r1 , 0 \ n \
beq _0804AF1A \ n \
movs r3 , 0 \ n \
movs r5 , 0 \ n \
ldr r0 , = gNoOfAllBanks \ n \
ldrb r1 , [ r0 ] \ n \
mov r12 , r0 \ n \
ldr r7 , = gBattlescriptCurrInstr \ n \
cmp r3 , r1 \ n \
bge _0804AE70 \ n \
ldr r0 , = gHitMarker \ n \
movs r6 , 0x80 \ n \
lsls r6 , 21 \ n \
ldr r4 , [ r0 ] \ n \
adds r2 , r1 , 0 \ n \
ldr r1 , = gSpecialStatuses \ n \
_0804AE54 : \ n \
adds r0 , r6 , 0 \ n \
lsls r0 , r5 \ n \
ands r0 , r4 \ n \
cmp r0 , 0 \ n \
beq _0804AE68 \ n \
ldrb r0 , [ r1 ] \ n \
lsls r0 , 25 \ n \
cmp r0 , 0 \ n \
blt _0804AE68 \ n \
adds r3 , 0x1 \ n \
_0804AE68 : \ n \
adds r1 , 0x28 \ n \
adds r5 , 0x2 \ n \
cmp r5 , r2 \ n \
blt _0804AE54 \ n \
_0804AE70 : \ n \
movs r2 , 0 \ n \
movs r5 , 0x1 \ n \
mov r4 , r12 \ n \
ldrb r1 , [ r4 ] \ n \
cmp r5 , r1 \ n \
bge _0804AEAA \ n \
ldr r0 , = gHitMarker \ n \
movs r4 , 0x80 \ n \
lsls r4 , 21 \ n \
mov r12 , r4 \ n \
ldr r6 , [ r0 ] \ n \
ldr r0 , = gSpecialStatuses \ n \
adds r4 , r1 , 0 \ n \
adds r1 , r0 , 0 \ n \
adds r1 , 0x14 \ n \
_0804AE8E : \ n \
mov r0 , r12 \ n \
lsls r0 , r5 \ n \
ands r0 , r6 \ n \
cmp r0 , 0 \ n \
beq _0804AEA2 \ n \
ldrb r0 , [ r1 ] \ n \
lsls r0 , 25 \ n \
cmp r0 , 0 \ n \
blt _0804AEA2 \ n \
adds r2 , 0x1 \ n \
_0804AEA2 : \ n \
adds r1 , 0x28 \ n \
adds r5 , 0x2 \ n \
cmp r5 , r4 \ n \
blt _0804AE8E \ n \
_0804AEAA : \ n \
mov r1 , r8 \ n \
ldr r0 , [ r1 ] \ n \
movs r1 , 0x40 \ n \
ands r0 , r1 \ n \
cmp r0 , 0 \ n \
beq _0804AEF0 \ n \
adds r0 , r2 , r3 \ n \
cmp r0 , 0x1 \ n \
bgt _0804AEF8 \ n \
b _0804AF12 \ n \
. pool \ n \
_0804AEF0 : \ n \
cmp r2 , 0 \ n \
beq _0804AF12 \ n \
cmp r3 , 0 \ n \
beq _0804AF12 \ n \
_0804AEF8 : \ n \
ldr r2 , [ r7 ] \ n \
ldrb r1 , [ r2 , 0x1 ] \ n \
ldrb r0 , [ r2 , 0x2 ] \ n \
lsls r0 , 8 \ n \
adds r1 , r0 \ n \
ldrb r0 , [ r2 , 0x3 ] \ n \
lsls r0 , 16 \ n \
adds r1 , r0 \ n \
ldrb r0 , [ r2 , 0x4 ] \ n \
lsls r0 , 24 \ n \
adds r1 , r0 \ n \
str r1 , [ r7 ] \ n \
b _0804AF22 \ n \
_0804AF12 : \ n \
ldr r0 , [ r7 ] \ n \
adds r0 , 0x5 \ n \
str r0 , [ r7 ] \ n \
b _0804AF22 \ n \
_0804AF1A : \ n \
ldr r1 , = gBattlescriptCurrInstr \ n \
ldr r0 , [ r1 ] \ n \
adds r0 , 0x5 \ n \
str r0 , [ r1 ] \ n \
_0804AF22 : \ n \
pop { r3 } \ n \
mov r8 , r3 \ n \
pop { r4 - r7 } \ n \
pop { r0 } \ n \
bx r0 \ n \
. pool \ n \
. syntax divided " );
}
# endif // NONMATCHING
2017-09-28 15:34:21 +02:00
static void MoveValuesCleanUp ( void )
2017-09-22 21:33:49 +02:00
{
gBattleMoveFlags = 0 ;
gBattleScripting . dmgMultiplier = 1 ;
gCritMultiplier = 1 ;
gBattleCommunication [ MOVE_EFFECT_BYTE ] = 0 ;
gBattleCommunication [ 6 ] = 0 ;
gHitMarker & = ~ ( HITMARKER_DESTINYBOND ) ;
gHitMarker & = ~ ( HITMARKER_SYNCHRONISE_EFFECT ) ;
}
2017-11-25 18:42:31 +01:00
static void atk25_movevaluescleanup ( void )
2017-09-22 21:33:49 +02:00
{
MoveValuesCleanUp ( ) ;
gBattlescriptCurrInstr + = 1 ;
}
2017-11-25 18:42:31 +01:00
static void atk26_setmultihit ( void )
2017-09-22 21:33:49 +02:00
{
2017-09-28 15:34:21 +02:00
gMultiHitCounter = gBattlescriptCurrInstr [ 1 ] ;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr + = 2 ;
}
2017-11-25 18:42:31 +01:00
static void atk27_decrementmultihit ( void )
2017-09-22 21:33:49 +02:00
{
if ( - - gMultiHitCounter = = 0 )
gBattlescriptCurrInstr + = 5 ;
else
gBattlescriptCurrInstr = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
2017-09-28 15:34:21 +02:00
static void atk28_goto ( void )
2017-09-22 21:33:49 +02:00
{
gBattlescriptCurrInstr = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
2017-09-28 15:34:21 +02:00
static void atk29_jumpifbyte ( void )
2017-09-22 21:33:49 +02:00
{
2017-09-28 15:34:21 +02:00
u8 caseID = gBattlescriptCurrInstr [ 1 ] ;
2017-09-22 21:33:49 +02:00
const u8 * memByte = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 2 ) ;
2017-09-28 15:34:21 +02:00
u8 value = gBattlescriptCurrInstr [ 6 ] ;
2017-09-22 21:33:49 +02:00
const u8 * jumpPtr = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 7 ) ;
gBattlescriptCurrInstr + = 11 ;
switch ( caseID )
{
case CMP_EQUAL :
if ( * memByte = = value )
gBattlescriptCurrInstr = jumpPtr ;
break ;
case CMP_NOT_EQUAL :
if ( * memByte ! = value )
gBattlescriptCurrInstr = jumpPtr ;
break ;
case CMP_GREATER_THAN :
if ( * memByte > value )
gBattlescriptCurrInstr = jumpPtr ;
break ;
case CMP_LESS_THAN :
if ( * memByte < value )
gBattlescriptCurrInstr = jumpPtr ;
break ;
case CMP_COMMON_BITS :
if ( * memByte & value )
gBattlescriptCurrInstr = jumpPtr ;
break ;
case CMP_NO_COMMON_BITS :
if ( ! ( * memByte & value ) )
gBattlescriptCurrInstr = jumpPtr ;
break ;
}
}
2017-09-28 15:34:21 +02:00
static void atk2A_jumpifhalfword ( void )
2017-09-22 21:33:49 +02:00
{
2017-09-28 15:34:21 +02:00
u8 caseID = gBattlescriptCurrInstr [ 1 ] ;
2017-09-22 21:33:49 +02:00
const u16 * memHword = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 2 ) ;
u16 value = BS2ScriptRead16 ( gBattlescriptCurrInstr + 6 ) ;
const u8 * jumpPtr = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 8 ) ;
gBattlescriptCurrInstr + = 12 ;
switch ( caseID )
{
case CMP_EQUAL :
if ( * memHword = = value )
gBattlescriptCurrInstr = jumpPtr ;
break ;
case CMP_NOT_EQUAL :
if ( * memHword ! = value )
gBattlescriptCurrInstr = jumpPtr ;
break ;
case CMP_GREATER_THAN :
if ( * memHword > value )
gBattlescriptCurrInstr = jumpPtr ;
break ;
case CMP_LESS_THAN :
if ( * memHword < value )
gBattlescriptCurrInstr = jumpPtr ;
break ;
case CMP_COMMON_BITS :
if ( * memHword & value )
gBattlescriptCurrInstr = jumpPtr ;
break ;
case CMP_NO_COMMON_BITS :
if ( ! ( * memHword & value ) )
gBattlescriptCurrInstr = jumpPtr ;
break ;
}
}
2017-09-28 15:34:21 +02:00
static void atk2B_jumpifword ( void )
2017-09-22 21:33:49 +02:00
{
2017-09-28 15:34:21 +02:00
u8 caseID = gBattlescriptCurrInstr [ 1 ] ;
2017-09-22 21:33:49 +02:00
const u32 * memWord = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 2 ) ;
u32 value = BSScriptRead32 ( gBattlescriptCurrInstr + 6 ) ;
const u8 * jumpPtr = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 10 ) ;
gBattlescriptCurrInstr + = 14 ;
switch ( caseID )
{
case CMP_EQUAL :
if ( * memWord = = value )
gBattlescriptCurrInstr = jumpPtr ;
break ;
case CMP_NOT_EQUAL :
if ( * memWord ! = value )
gBattlescriptCurrInstr = jumpPtr ;
break ;
case CMP_GREATER_THAN :
if ( * memWord > value )
gBattlescriptCurrInstr = jumpPtr ;
break ;
case CMP_LESS_THAN :
if ( * memWord < value )
gBattlescriptCurrInstr = jumpPtr ;
break ;
case CMP_COMMON_BITS :
if ( * memWord & value )
gBattlescriptCurrInstr = jumpPtr ;
break ;
case CMP_NO_COMMON_BITS :
if ( ! ( * memWord & value ) )
gBattlescriptCurrInstr = jumpPtr ;
break ;
}
}
2017-09-28 15:34:21 +02:00
static void atk2C_jumpifarrayequal ( void )
2017-09-22 21:33:49 +02:00
{
const u8 * mem1 = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
const u8 * mem2 = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 5 ) ;
2017-09-28 15:34:21 +02:00
u32 size = gBattlescriptCurrInstr [ 9 ] ;
2017-09-22 21:33:49 +02:00
const u8 * jumpPtr = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 10 ) ;
u8 i ;
for ( i = 0 ; i < size ; i + + )
{
if ( * mem1 ! = * mem2 )
{
gBattlescriptCurrInstr + = 14 ;
break ;
}
mem1 + + , mem2 + + ;
}
if ( i = = size )
gBattlescriptCurrInstr = jumpPtr ;
}
2017-09-28 15:34:21 +02:00
static void atk2D_jumpifarraynotequal ( void )
2017-09-22 21:33:49 +02:00
{
u8 equalBytes = 0 ;
const u8 * mem1 = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
const u8 * mem2 = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 5 ) ;
2017-09-28 15:34:21 +02:00
u32 size = gBattlescriptCurrInstr [ 9 ] ;
2017-09-22 21:33:49 +02:00
const u8 * jumpPtr = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 10 ) ;
u8 i ;
for ( i = 0 ; i < size ; i + + )
{
if ( * mem1 = = * mem2 )
{
equalBytes + + ;
}
mem1 + + , mem2 + + ;
}
if ( equalBytes ! = size )
gBattlescriptCurrInstr = jumpPtr ;
else
gBattlescriptCurrInstr + = 14 ;
}
2017-09-28 15:34:21 +02:00
static void atk2E_setbyte ( void )
2017-09-22 21:33:49 +02:00
{
u8 * memByte = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 15:34:21 +02:00
* memByte = gBattlescriptCurrInstr [ 5 ] ;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr + = 6 ;
}
2017-09-28 15:34:21 +02:00
static void atk2F_addbyte ( void )
2017-09-22 21:33:49 +02:00
{
u8 * memByte = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 15:34:21 +02:00
* memByte + = gBattlescriptCurrInstr [ 5 ] ;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr + = 6 ;
}
2017-09-28 15:34:21 +02:00
static void atk30_subbyte ( void )
2017-09-22 21:33:49 +02:00
{
u8 * memByte = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 15:34:21 +02:00
* memByte - = gBattlescriptCurrInstr [ 5 ] ;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr + = 6 ;
}
2017-09-28 15:34:21 +02:00
static void atk31_copyarray ( void )
2017-09-22 21:33:49 +02:00
{
u8 * dest = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
const u8 * src = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 5 ) ;
2017-09-28 15:34:21 +02:00
s32 size = gBattlescriptCurrInstr [ 9 ] ;
2017-09-22 21:33:49 +02:00
s32 i ;
for ( i = 0 ; i < size ; i + + )
{
dest [ i ] = src [ i ] ;
}
gBattlescriptCurrInstr + = 10 ;
}
2017-11-25 18:42:31 +01:00
static void atk32_copyarraywithindex ( void )
2017-09-22 21:33:49 +02:00
{
u8 * dest = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
const u8 * src = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 5 ) ;
const u8 * index = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 9 ) ;
2017-09-28 15:34:21 +02:00
s32 size = gBattlescriptCurrInstr [ 13 ] ;
2017-09-22 21:33:49 +02:00
s32 i ;
for ( i = 0 ; i < size ; i + + )
{
dest [ i ] = src [ i + * index ] ;
}
gBattlescriptCurrInstr + = 14 ;
}
2017-09-28 15:34:21 +02:00
static void atk33_orbyte ( void )
2017-09-22 21:33:49 +02:00
{
u8 * memByte = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 15:34:21 +02:00
* memByte | = gBattlescriptCurrInstr [ 5 ] ;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr + = 6 ;
}
2017-09-28 15:34:21 +02:00
static void atk34_orhalfword ( void )
2017-09-22 21:33:49 +02:00
{
u16 * memHword = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
u16 val = BS2ScriptRead16 ( gBattlescriptCurrInstr + 5 ) ;
* memHword | = val ;
gBattlescriptCurrInstr + = 7 ;
}
2017-09-28 15:34:21 +02:00
static void atk35_orword ( void )
2017-09-22 21:33:49 +02:00
{
u32 * memWord = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
u32 val = BS2ScriptRead32 ( gBattlescriptCurrInstr + 5 ) ;
* memWord | = val ;
gBattlescriptCurrInstr + = 9 ;
}
2017-09-28 15:34:21 +02:00
static void atk36_bicbyte ( void )
2017-09-22 21:33:49 +02:00
{
u8 * memByte = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 15:34:21 +02:00
* memByte & = ~ ( gBattlescriptCurrInstr [ 5 ] ) ;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr + = 6 ;
}
2017-09-28 15:34:21 +02:00
static void atk37_bichalfword ( void )
2017-09-22 21:33:49 +02:00
{
u16 * memHword = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
u16 val = BS2ScriptRead16 ( gBattlescriptCurrInstr + 5 ) ;
* memHword & = ~ val ;
gBattlescriptCurrInstr + = 7 ;
}
2017-09-28 15:34:21 +02:00
static void atk38_bicword ( void )
2017-09-22 21:33:49 +02:00
{
u32 * memWord = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
u32 val = BS2ScriptRead32 ( gBattlescriptCurrInstr + 5 ) ;
* memWord & = ~ val ;
gBattlescriptCurrInstr + = 9 ;
}
2017-09-28 15:34:21 +02:00
static void atk39_pause ( void )
2017-09-22 21:33:49 +02:00
{
if ( gBattleExecBuffer = = 0 )
{
u16 value = BS2ScriptRead16 ( gBattlescriptCurrInstr + 1 ) ;
if ( + + gPauseCounterBattle > = value )
{
gPauseCounterBattle = 0 ;
gBattlescriptCurrInstr + = 3 ;
}
}
}
2017-09-28 15:34:21 +02:00
static void atk3A_waitstate ( void )
2017-09-22 21:33:49 +02:00
{
if ( gBattleExecBuffer = = 0 )
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk3B_healthbar_update ( void )
2017-09-22 21:33:49 +02:00
{
2017-09-28 15:34:21 +02:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_GET_TARGET )
2017-09-22 21:33:49 +02:00
gActiveBank = gBankTarget ;
else
gActiveBank = gBankAttacker ;
EmitHealthBarUpdate ( 0 , gBattleMoveDamage ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 2 ;
}
2017-09-28 15:34:21 +02:00
static void atk3C_return ( void )
2017-09-22 21:33:49 +02:00
{
BattleScriptPop ( ) ;
}
2017-09-28 15:34:21 +02:00
static void atk3D_end ( void )
2017-09-22 21:33:49 +02:00
{
if ( gBattleTypeFlags & BATTLE_TYPE_ARENA )
sub_81A5718 ( gBankAttacker ) ;
gBattleMoveFlags = 0 ;
gActiveBank = 0 ;
2017-10-06 00:12:01 +02:00
gCurrentActionFuncId = 0xB ;
2017-09-22 21:33:49 +02:00
}
2017-09-28 15:34:21 +02:00
static void atk3E_end2 ( void )
2017-09-22 21:33:49 +02:00
{
gActiveBank = 0 ;
2017-10-06 00:12:01 +02:00
gCurrentActionFuncId = 0xB ;
2017-09-22 21:33:49 +02:00
}
2017-09-28 15:34:21 +02:00
static void atk3F_end3 ( void ) // pops the main function stack
2017-09-22 21:33:49 +02:00
{
BattleScriptPop ( ) ;
if ( BATTLE_CALLBACKS_STACK - > size )
BATTLE_CALLBACKS_STACK - > size - - ;
gBattleMainFunc = BATTLE_CALLBACKS_STACK - > function [ BATTLE_CALLBACKS_STACK - > size ] ;
}
2017-09-28 15:34:21 +02:00
static void atk41_call ( void )
2017-09-22 21:33:49 +02:00
{
BattleScriptPush ( gBattlescriptCurrInstr + 5 ) ;
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
2017-09-28 15:34:21 +02:00
static void atk42_jumpiftype2 ( void )
2017-09-22 21:33:49 +02:00
{
2017-09-28 15:34:21 +02:00
u8 bank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-22 21:33:49 +02:00
2017-09-28 15:34:21 +02:00
if ( gBattlescriptCurrInstr [ 2 ] = = gBattleMons [ bank ] . type1 | | gBattlescriptCurrInstr [ 2 ] = = gBattleMons [ bank ] . type2 )
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 3 ) ;
else
gBattlescriptCurrInstr + = 7 ;
}
2017-09-28 15:34:21 +02:00
static void atk43_jumpifabilitypresent ( void )
2017-09-22 21:33:49 +02:00
{
2017-09-28 15:34:21 +02:00
if ( AbilityBattleEffects ( ABILITYEFFECT_CHECK_ON_FIELD , 0 , gBattlescriptCurrInstr [ 1 ] , 0 , 0 ) )
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 2 ) ;
else
gBattlescriptCurrInstr + = 6 ;
}
2017-11-25 18:42:31 +01:00
static void atk44_endselectionscript ( void )
2017-09-22 21:33:49 +02:00
{
2017-10-04 19:25:14 +02:00
* ( gBankAttacker + gBattleStruct - > selectionScriptFinished ) = TRUE ;
2017-09-22 21:33:49 +02:00
}
2017-09-28 15:34:21 +02:00
static void atk45_playanimation ( void )
2017-09-22 21:33:49 +02:00
{
const u16 * argumentPtr ;
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-22 21:33:49 +02:00
argumentPtr = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 3 ) ;
if ( gBattlescriptCurrInstr [ 2 ] = = B_ANIM_STATS_CHANGE
| | gBattlescriptCurrInstr [ 2 ] = = B_ANIM_SNATCH_MOVE
| | gBattlescriptCurrInstr [ 2 ] = = B_ANIM_SUBSTITUTE_FADE )
{
EmitBattleAnimation ( 0 , gBattlescriptCurrInstr [ 2 ] , * argumentPtr ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 7 ;
}
else if ( gHitMarker & HITMARKER_NO_ANIMATIONS )
{
BattleScriptPush ( gBattlescriptCurrInstr + 7 ) ;
gBattlescriptCurrInstr = BattleScript_Pausex20 ;
}
else if ( gBattlescriptCurrInstr [ 2 ] = = B_ANIM_RAIN_CONTINUES
| | gBattlescriptCurrInstr [ 2 ] = = B_ANIM_SUN_CONTINUES
| | gBattlescriptCurrInstr [ 2 ] = = B_ANIM_SANDSTORM_CONTINUES
| | gBattlescriptCurrInstr [ 2 ] = = B_ANIM_HAIL_CONTINUES )
{
EmitBattleAnimation ( 0 , gBattlescriptCurrInstr [ 2 ] , * argumentPtr ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 7 ;
}
else if ( gStatuses3 [ gActiveBank ] & STATUS3_SEMI_INVULNERABLE )
{
gBattlescriptCurrInstr + = 7 ;
}
else
{
EmitBattleAnimation ( 0 , gBattlescriptCurrInstr [ 2 ] , * argumentPtr ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 7 ;
}
}
2017-09-28 15:34:21 +02:00
static void atk46_playanimation2 ( void ) // animation Id is stored in the first pointer
2017-09-22 21:33:49 +02:00
{
const u16 * argumentPtr ;
const u8 * animationIdPtr ;
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-22 21:33:49 +02:00
animationIdPtr = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 2 ) ;
argumentPtr = BS2ScriptReadPtr ( gBattlescriptCurrInstr + 6 ) ;
if ( * animationIdPtr = = B_ANIM_STATS_CHANGE
| | * animationIdPtr = = B_ANIM_SNATCH_MOVE
| | * animationIdPtr = = B_ANIM_SUBSTITUTE_FADE )
{
EmitBattleAnimation ( 0 , * animationIdPtr , * argumentPtr ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 10 ;
}
else if ( gHitMarker & HITMARKER_NO_ANIMATIONS )
{
gBattlescriptCurrInstr + = 10 ;
}
else if ( * animationIdPtr = = B_ANIM_RAIN_CONTINUES
| | * animationIdPtr = = B_ANIM_SUN_CONTINUES
| | * animationIdPtr = = B_ANIM_SANDSTORM_CONTINUES
| | * animationIdPtr = = B_ANIM_HAIL_CONTINUES )
{
EmitBattleAnimation ( 0 , * animationIdPtr , * argumentPtr ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 10 ;
}
else if ( gStatuses3 [ gActiveBank ] & STATUS3_SEMI_INVULNERABLE )
{
gBattlescriptCurrInstr + = 10 ;
}
else
{
EmitBattleAnimation ( 0 , * animationIdPtr , * argumentPtr ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 10 ;
}
}
2017-09-28 15:34:21 +02:00
static void atk47_setgraphicalstatchangevalues ( void )
2017-09-22 21:33:49 +02:00
{
u8 value = 0 ;
switch ( gBattleScripting . statChanger & 0xF0 )
{
case 0x10 : // +1
value = 0xF ;
break ;
case 0x20 : // +2
value = 0x27 ;
break ;
case 0x90 : // -1
value = 0x16 ;
break ;
case 0xA0 : // -2
value = 0x2E ;
break ;
}
gBattleScripting . animArg1 = ( gBattleScripting . statChanger & 0xF ) + value - 1 ;
gBattleScripting . animArg2 = 0 ;
gBattlescriptCurrInstr + + ;
}
2017-09-23 20:13:45 +02:00
# ifdef NONMATCHING
2017-09-28 15:34:21 +02:00
static void atk48_playstatchangeanimation ( void )
2017-09-22 21:33:49 +02:00
{
2017-09-23 00:06:52 +02:00
u32 currStat = 0 ;
2017-09-22 21:33:49 +02:00
s16 statAnimId = 0 ;
2017-09-23 00:06:52 +02:00
s16 checkingStatAnimId = 0 ;
2017-09-22 21:33:49 +02:00
s32 changeableStats = 0 ;
u32 statsToCheck = 0 ;
2017-09-23 00:06:52 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
statsToCheck = gBattlescriptCurrInstr [ 2 ] ;
2017-09-22 21:33:49 +02:00
2017-09-23 00:06:52 +02:00
if ( gBattlescriptCurrInstr [ 3 ] & ATK48_STAT_NEGATIVE ) // goes down
2017-09-22 21:33:49 +02:00
{
2017-09-23 00:06:52 +02:00
checkingStatAnimId = ( gBattlescriptCurrInstr [ 3 ] & ATK48_STAT_BY_TWO ) ? 0x2D : 0x15 ;
while ( statsToCheck ! = 0 )
2017-09-22 21:33:49 +02:00
{
2017-09-23 00:06:52 +02:00
if ( statsToCheck & 1 )
2017-09-22 21:33:49 +02:00
{
2017-09-23 00:06:52 +02:00
if ( ! ( gBattlescriptCurrInstr [ 3 ] & ATK48_LOWER_FAIL_CHECK ) )
2017-09-22 21:33:49 +02:00
{
2017-09-23 00:06:52 +02:00
if ( gBattleMons [ gActiveBank ] . statStages [ currStat ] > 0 )
{
statAnimId = checkingStatAnimId ;
changeableStats + + ;
}
2017-09-22 21:33:49 +02:00
}
2017-09-23 00:06:52 +02:00
else if ( ! gSideTimers [ GET_BANK_SIDE ( gActiveBank ) ] . mistTimer
& & gBattleMons [ gActiveBank ] . ability ! = ABILITY_CLEAR_BODY
& & gBattleMons [ gActiveBank ] . ability ! = ABILITY_WHITE_SMOKE
& & ! ( gBattleMons [ gActiveBank ] . ability = = ABILITY_KEEN_EYE & & currStat = = STAT_STAGE_ACC )
& & ! ( gBattleMons [ gActiveBank ] . ability = = ABILITY_HYPER_CUTTER & & currStat = = STAT_STAGE_ATK ) )
2017-09-22 21:33:49 +02:00
{
2017-09-23 00:06:52 +02:00
if ( gBattleMons [ gActiveBank ] . statStages [ currStat ] > 0 )
{
statAnimId = checkingStatAnimId ;
changeableStats + + ;
}
2017-09-22 21:33:49 +02:00
}
}
2017-09-23 00:06:52 +02:00
statsToCheck > > = 1 , checkingStatAnimId + + , currStat + + ;
2017-09-22 21:33:49 +02:00
}
if ( changeableStats > 1 ) // more than one stat, so the color is gray
{
2017-09-23 00:06:52 +02:00
if ( gBattlescriptCurrInstr [ 3 ] & ATK48_STAT_BY_TWO )
2017-09-22 21:33:49 +02:00
statAnimId = 0x3A ;
else
statAnimId = 0x39 ;
}
}
else // goes up
{
2017-09-23 00:06:52 +02:00
checkingStatAnimId = ( gBattlescriptCurrInstr [ 3 ] & ATK48_STAT_BY_TWO ) ? 0x26 : 0xE ;
while ( statsToCheck ! = 0 )
2017-09-22 21:33:49 +02:00
{
if ( statsToCheck & 1 & & gBattleMons [ gActiveBank ] . statStages [ currStat ] < 0xC )
{
statAnimId = checkingStatAnimId ;
changeableStats + + ;
}
2017-09-23 00:06:52 +02:00
statsToCheck > > = 1 , checkingStatAnimId + = 1 , currStat + + ;
2017-09-22 21:33:49 +02:00
}
if ( changeableStats > 1 ) // more than one stat, so the color is gray
{
2017-09-23 00:06:52 +02:00
if ( gBattlescriptCurrInstr [ 3 ] & ATK48_STAT_BY_TWO )
2017-09-22 21:33:49 +02:00
statAnimId = 0x38 ;
else
statAnimId = 0x37 ;
}
}
2017-09-23 00:06:52 +02:00
if ( gBattlescriptCurrInstr [ 3 ] & ATK48_BIT_x4 & & changeableStats < 2 )
2017-09-22 21:33:49 +02:00
{
gBattlescriptCurrInstr + = 4 ;
}
else if ( changeableStats ! = 0 & & gBattleScripting . field_1B = = 0 )
{
EmitBattleAnimation ( 0 , B_ANIM_STATS_CHANGE , statAnimId ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
2017-09-23 00:06:52 +02:00
if ( gBattlescriptCurrInstr [ 3 ] & ATK48_BIT_x4 & & changeableStats > 1 )
2017-09-22 21:33:49 +02:00
gBattleScripting . field_1B = 1 ;
gBattlescriptCurrInstr + = 4 ;
}
else
{
gBattlescriptCurrInstr + = 4 ;
}
}
2017-09-23 20:13:45 +02:00
# else
__attribute__ ( ( naked ) )
2017-09-28 15:34:21 +02:00
static void atk48_playstatchangeanimation ( void )
2017-09-23 20:13:45 +02:00
{
asm ( " \n \
. syntax unified \ n \
push { r4 - r7 , lr } \ n \
mov r7 , r10 \ n \
mov r6 , r9 \ n \
mov r5 , r8 \ n \
push { r5 - r7 } \ n \
sub sp , 0x4 \ n \
movs r7 , 0 \ n \
movs r0 , 0 \ n \
mov r8 , r0 \ n \
movs r3 , 0 \ n \
ldr r5 , = gBattlescriptCurrInstr \ n \
ldr r0 , [ r5 ] \ n \
ldrb r0 , [ r0 , 0x1 ] \ n \
str r3 , [ sp ] \ n \
bl GetBattleBank \ n \
ldr r2 , = gActiveBank \ n \
strb r0 , [ r2 ] \ n \
ldr r0 , [ r5 ] \ n \
ldrb r4 , [ r0 , 0x2 ] \ n \
ldrb r1 , [ r0 , 0x3 ] \ n \
movs r0 , 0x1 \ n \
ands r0 , r1 \ n \
ldr r3 , [ sp ] \ n \
cmp r0 , 0 \ n \
beq _0804BAEC \ n \
movs r0 , 0x2 \ n \
ands r0 , r1 \ n \
movs r1 , 0x15 \ n \
cmp r0 , 0 \ n \
beq _0804BA18 \ n \
movs r1 , 0x2D \ n \
_0804BA18 : \ n \
cmp r4 , 0 \ n \
beq _0804BAC0 \ n \
movs r0 , 0x1 \ n \
mov r10 , r0 \ n \
ldr r0 , = gBattleMons + 0x18 \ n \
mov r9 , r0 \ n \
lsls r5 , r1 , 16 \ n \
_0804BA26 : \ n \
adds r0 , r4 , 0 \ n \
mov r1 , r10 \ n \
ands r0 , r1 \ n \
cmp r0 , 0 \ n \
beq _0804BAB2 \ n \
ldr r0 , = gBattlescriptCurrInstr \ n \
ldr r0 , [ r0 ] \ n \
ldrb r1 , [ r0 , 0x3 ] \ n \
movs r0 , 0x8 \ n \
ands r0 , r1 \ n \
cmp r0 , 0 \ n \
beq _0804BA58 \ n \
ldr r0 , = gActiveBank \ n \
ldrb r1 , [ r0 ] \ n \
movs r0 , 0x58 \ n \
muls r0 , r1 \ n \
adds r0 , r7 , r0 \ n \
b _0804BAA0 \ n \
. pool \ n \
_0804BA58 : \ n \
ldr r6 , = gActiveBank \ n \
ldrb r0 , [ r6 ] \ n \
str r3 , [ sp ] \ n \
bl GetBankIdentity \ n \
mov r1 , r10 \ n \
ands r1 , r0 \ n \
lsls r0 , r1 , 1 \ n \
adds r0 , r1 \ n \
lsls r0 , 2 \ n \
ldr r1 , = gSideTimers \ n \
adds r0 , r1 \ n \
ldrb r0 , [ r0 , 0x4 ] \ n \
ldr r3 , [ sp ] \ n \
cmp r0 , 0 \ n \
bne _0804BAB2 \ n \
ldr r0 , = gBattleMons \ n \
ldrb r2 , [ r6 ] \ n \
movs r1 , 0x58 \ n \
muls r2 , r1 \ n \
adds r0 , r2 , r0 \ n \
adds r0 , 0x20 \ n \
ldrb r0 , [ r0 ] \ n \
cmp r0 , 0x1D \ n \
beq _0804BAB2 \ n \
cmp r0 , 0x49 \ n \
beq _0804BAB2 \ n \
cmp r0 , 0x33 \ n \
bne _0804BA96 \ n \
cmp r7 , 0x6 \ n \
beq _0804BAB2 \ n \
_0804BA96 : \ n \
cmp r0 , 0x34 \ n \
bne _0804BA9E \ n \
cmp r7 , 0x1 \ n \
beq _0804BAB2 \ n \
_0804BA9E : \ n \
adds r0 , r7 , r2 \ n \
_0804BAA0 : \ n \
add r0 , r9 \ n \
ldrb r0 , [ r0 ] \ n \
lsls r0 , 24 \ n \
asrs r0 , 24 \ n \
cmp r0 , 0 \ n \
ble _0804BAB2 \ n \
lsrs r0 , r5 , 16 \ n \
mov r8 , r0 \ n \
adds r3 , 0x1 \ n \
_0804BAB2 : \ n \
lsrs r4 , 1 \ n \
movs r1 , 0x80 \ n \
lsls r1 , 9 \ n \
adds r5 , r1 \ n \
adds r7 , 0x1 \ n \
cmp r4 , 0 \ n \
bne _0804BA26 \ n \
_0804BAC0 : \ n \
ldr r0 , = gBattlescriptCurrInstr \ n \
mov r9 , r0 \ n \
cmp r3 , 0x1 \ n \
ble _0804BB4E \ n \
ldr r0 , [ r0 ] \ n \
ldrb r1 , [ r0 , 0x3 ] \ n \
movs r0 , 0x2 \ n \
ands r0 , r1 \ n \
movs r1 , 0x39 \ n \
mov r8 , r1 \ n \
cmp r0 , 0 \ n \
beq _0804BB4E \ n \
movs r0 , 0x3A \ n \
b _0804BB4C \ n \
. pool \ n \
_0804BAEC : \ n \
movs r0 , 0x2 \ n \
ands r0 , r1 \ n \
movs r1 , 0xE \ n \
cmp r0 , 0 \ n \
beq _0804BAF8 \ n \
movs r1 , 0x26 \ n \
_0804BAF8 : \ n \
mov r9 , r5 \ n \
cmp r4 , 0 \ n \
beq _0804BB34 \ n \
ldr r6 , = gBattleMons + 0x18 \ n \
adds r5 , r2 , 0 \ n \
lsls r2 , r1 , 16 \ n \
_0804BB04 : \ n \
movs r0 , 0x1 \ n \
ands r0 , r4 \ n \
cmp r0 , 0 \ n \
beq _0804BB26 \ n \
ldrb r1 , [ r5 ] \ n \
movs r0 , 0x58 \ n \
muls r0 , r1 \ n \
adds r0 , r7 , r0 \ n \
adds r0 , r6 \ n \
ldrb r0 , [ r0 ] \ n \
lsls r0 , 24 \ n \
asrs r0 , 24 \ n \
cmp r0 , 0xB \ n \
bgt _0804BB26 \ n \
lsrs r1 , r2 , 16 \ n \
mov r8 , r1 \ n \
adds r3 , 0x1 \ n \
_0804BB26 : \ n \
lsrs r4 , 1 \ n \
movs r0 , 0x80 \ n \
lsls r0 , 9 \ n \
adds r2 , r0 \ n \
adds r7 , 0x1 \ n \
cmp r4 , 0 \ n \
bne _0804BB04 \ n \
_0804BB34 : \ n \
cmp r3 , 0x1 \ n \
ble _0804BB4E \ n \
mov r1 , r9 \ n \
ldr r0 , [ r1 ] \ n \
ldrb r1 , [ r0 , 0x3 ] \ n \
movs r0 , 0x2 \ n \
ands r0 , r1 \ n \
movs r1 , 0x37 \ n \
mov r8 , r1 \ n \
cmp r0 , 0 \ n \
beq _0804BB4E \ n \
movs r0 , 0x38 \ n \
_0804BB4C : \ n \
mov r8 , r0 \ n \
_0804BB4E : \ n \
mov r1 , r9 \ n \
ldr r2 , [ r1 ] \ n \
ldrb r1 , [ r2 , 0x3 ] \ n \
movs r0 , 0x4 \ n \
ands r0 , r1 \ n \
cmp r0 , 0 \ n \
beq _0804BB6C \ n \
cmp r3 , 0x1 \ n \
bgt _0804BB6C \ n \
adds r0 , r2 , 0x4 \ n \
mov r1 , r9 \ n \
b _0804BBBA \ n \
. pool \ n \
_0804BB6C : \ n \
cmp r3 , 0 \ n \
beq _0804BBB4 \ n \
ldr r4 , = gBattleScripting \ n \
ldrb r0 , [ r4 , 0x1B ] \ n \
cmp r0 , 0 \ n \
bne _0804BBB4 \ n \
movs r0 , 0 \ n \
movs r1 , 0x1 \ n \
mov r2 , r8 \ n \
str r3 , [ sp ] \ n \
bl EmitBattleAnimation \ n \
ldr r0 , = gActiveBank \ n \
ldrb r0 , [ r0 ] \ n \
bl MarkBufferBankForExecution \ n \
ldr r0 , = gBattlescriptCurrInstr \ n \
ldr r0 , [ r0 ] \ n \
ldrb r1 , [ r0 , 0x3 ] \ n \
movs r0 , 0x4 \ n \
ands r0 , r1 \ n \
ldr r3 , [ sp ] \ n \
cmp r0 , 0 \ n \
beq _0804BBA4 \ n \
cmp r3 , 0x1 \ n \
ble _0804BBA4 \ n \
movs r0 , 0x1 \ n \
strb r0 , [ r4 , 0x1B ] \ n \
_0804BBA4 : \ n \
ldr r1 , = gBattlescriptCurrInstr \ n \
b _0804BBB6 \ n \
. pool \ n \
_0804BBB4 : \ n \
mov r1 , r9 \ n \
_0804BBB6 : \ n \
ldr r0 , [ r1 ] \ n \
adds r0 , 0x4 \ n \
_0804BBBA : \ n \
str r0 , [ r1 ] \ n \
add sp , 0x4 \ n \
pop { r3 - r5 } \ n \
mov r8 , r3 \ n \
mov r9 , r4 \ n \
mov r10 , r5 \ n \
pop { r4 - r7 } \ n \
pop { r0 } \ n \
bx r0 \ n \
. syntax divided " );
}
# endif // NONMATCHING
# define ATK49_LAST_CASE 17
2017-09-28 15:34:21 +02:00
static void atk49_moveend ( void )
2017-09-23 20:13:45 +02:00
{
s32 i ;
bool32 effect ;
u8 moveType ;
u8 holdEffectAtk ;
u16 * choicedMoveAtk ;
u8 arg1 , arg2 ;
2017-11-26 14:17:02 +01:00
u16 originallyUsedMove ;
2017-09-23 20:13:45 +02:00
effect = FALSE ;
2017-11-26 18:07:00 +01:00
if ( gChosenMove = = 0xFFFF )
2017-11-26 14:17:02 +01:00
originallyUsedMove = 0 ;
2017-09-23 20:13:45 +02:00
else
2017-11-26 18:07:00 +01:00
originallyUsedMove = gChosenMove ;
2017-09-23 20:13:45 +02:00
arg1 = gBattlescriptCurrInstr [ 1 ] ;
arg2 = gBattlescriptCurrInstr [ 2 ] ;
if ( gBattleMons [ gBankAttacker ] . item = = ITEM_ENIGMA_BERRY )
holdEffectAtk = gEnigmaBerries [ gBankAttacker ] . holdEffect ;
else
holdEffectAtk = ItemId_GetHoldEffect ( gBattleMons [ gBankAttacker ] . item ) ;
choicedMoveAtk = & gBattleStruct - > choicedMove [ gBankAttacker ] ;
GET_MOVE_TYPE ( gCurrentMove , moveType ) ;
do
{
switch ( gBattleScripting . atk49_state )
{
case 0 : // rage check
if ( gBattleMons [ gBankTarget ] . status2 & STATUS2_RAGE
& & gBattleMons [ gBankTarget ] . hp ! = 0 & & gBankAttacker ! = gBankTarget
& & GetBankSide ( gBankAttacker ) ! = GetBankSide ( gBankTarget )
& & ! ( gBattleMoveFlags & MOVESTATUS_NOEFFECT ) & & TARGET_TURN_DAMAGED
& & gBattleMoves [ gCurrentMove ] . power & & gBattleMons [ gBankTarget ] . statStages [ STAT_STAGE_ATK ] < = 0xB )
{
gBattleMons [ gBankTarget ] . statStages [ STAT_STAGE_ATK ] + + ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_RageIsBuilding ;
effect = TRUE ;
}
gBattleScripting . atk49_state + + ;
break ;
case 1 : // defrosting check
if ( gBattleMons [ gBankTarget ] . status1 & STATUS_FREEZE
& & gBattleMons [ gBankTarget ] . hp ! = 0 & & gBankAttacker ! = gBankTarget
& & gSpecialStatuses [ gBankTarget ] . moveturnLostHP_special
& & ! ( gBattleMoveFlags & MOVESTATUS_NOEFFECT ) & & moveType = = TYPE_FIRE )
{
gBattleMons [ gBankTarget ] . status1 & = ~ ( STATUS_FREEZE ) ;
gActiveBank = gBankTarget ;
2017-09-26 22:39:59 +02:00
EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gBankTarget ] . status1 ) ;
2017-09-23 20:13:45 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_DefrostedViaFireMove ;
effect = TRUE ;
}
gBattleScripting . atk49_state + + ;
break ;
case 2 : // target synchronize
if ( AbilityBattleEffects ( ABILITYEFFECT_SYNCHRONIZE , gBankTarget , 0 , 0 , 0 ) )
effect = TRUE ;
gBattleScripting . atk49_state + + ;
break ;
case 3 : // contact abilities
if ( AbilityBattleEffects ( ABILITYEFFECT_CONTACT , gBankTarget , 0 , 0 , 0 ) )
effect = TRUE ;
gBattleScripting . atk49_state + + ;
break ;
case 4 : // status immunities
if ( AbilityBattleEffects ( ABILITYEFFECT_IMMUNITY , 0 , 0 , 0 , 0 ) )
effect = TRUE ; // it loops through all banks, so we increment after its done with all banks
else
gBattleScripting . atk49_state + + ;
break ;
case 5 : // attacker synchronize
if ( AbilityBattleEffects ( ABILITYEFFECT_ATK_SYNCHRONIZE , gBankAttacker , 0 , 0 , 0 ) )
effect = TRUE ;
gBattleScripting . atk49_state + + ;
break ;
case 6 : // update choice band move
if ( ! ( gHitMarker & HITMARKER_OBEYS ) | | holdEffectAtk ! = HOLD_EFFECT_CHOICE_BAND
2017-11-26 18:07:00 +01:00
| | gChosenMove = = MOVE_STRUGGLE | | ( * choicedMoveAtk ! = 0 & & * choicedMoveAtk ! = 0xFFFF ) )
2017-09-23 20:13:45 +02:00
goto LOOP ;
2017-11-26 18:07:00 +01:00
if ( gChosenMove = = MOVE_BATON_PASS & & ! ( gBattleMoveFlags & MOVESTATUS_FAILED ) )
2017-09-23 20:13:45 +02:00
{
gBattleScripting . atk49_state + + ;
break ;
}
2017-11-26 18:07:00 +01:00
* choicedMoveAtk = gChosenMove ;
2017-09-23 20:13:45 +02:00
LOOP :
{
for ( i = 0 ; i < 4 ; i + + )
{
if ( gBattleMons [ gBankAttacker ] . moves [ i ] = = * choicedMoveAtk )
break ;
}
if ( i = = 4 )
* choicedMoveAtk = 0 ;
gBattleScripting . atk49_state + + ;
}
break ;
case 7 : // changed held items
for ( i = 0 ; i < gNoOfAllBanks ; i + + )
{
2017-09-27 23:43:45 +02:00
u16 * changedItem = & gBattleStruct - > changedItems [ i ] ;
2017-09-23 20:13:45 +02:00
if ( * changedItem ! = 0 )
{
gBattleMons [ i ] . item = * changedItem ;
* changedItem = 0 ;
}
}
gBattleScripting . atk49_state + + ;
break ;
case 11 : // item effects for all banks
if ( ItemBattleEffects ( 3 , 0 , FALSE ) )
effect = TRUE ;
else
gBattleScripting . atk49_state + + ;
break ;
case 12 : // king's rock and shell bell
if ( ItemBattleEffects ( 4 , 0 , FALSE ) )
effect = TRUE ;
gBattleScripting . atk49_state + + ;
break ;
case 8 : // make attacker sprite invisible
if ( gStatuses3 [ gBankAttacker ] & ( STATUS3_SEMI_INVULNERABLE )
& & gHitMarker & HITMARKER_NO_ANIMATIONS )
{
gActiveBank = gBankAttacker ;
EmitSpriteInvisibility ( 0 , TRUE ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattleScripting . atk49_state + + ;
return ;
}
gBattleScripting . atk49_state + + ;
break ;
case 9 : // make attacker sprite visible
if ( gBattleMoveFlags & MOVESTATUS_NOEFFECT
| | ! ( gStatuses3 [ gBankAttacker ] & ( STATUS3_SEMI_INVULNERABLE ) )
2017-10-06 17:06:45 +02:00
| | WasUnableToUseMove ( gBankAttacker ) )
2017-09-23 20:13:45 +02:00
{
gActiveBank = gBankAttacker ;
EmitSpriteInvisibility ( 0 , FALSE ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gStatuses3 [ gBankAttacker ] & = ~ ( STATUS3_SEMI_INVULNERABLE ) ;
gSpecialStatuses [ gBankAttacker ] . restoredBankSprite = 1 ;
gBattleScripting . atk49_state + + ;
return ;
}
gBattleScripting . atk49_state + + ;
break ;
case 10 : // make target sprite visible
if ( ! gSpecialStatuses [ gBankTarget ] . restoredBankSprite & & gBankTarget < gNoOfAllBanks
& & ! ( gStatuses3 [ gBankTarget ] & STATUS3_SEMI_INVULNERABLE ) )
{
gActiveBank = gBankTarget ;
EmitSpriteInvisibility ( 0 , FALSE ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gStatuses3 [ gBankTarget ] & = ~ ( STATUS3_SEMI_INVULNERABLE ) ;
gBattleScripting . atk49_state + + ;
return ;
}
gBattleScripting . atk49_state + + ;
break ;
case 13 : // update substitute
for ( i = 0 ; i < gNoOfAllBanks ; i + + )
{
if ( gDisableStructs [ i ] . substituteHP = = 0 )
gBattleMons [ i ] . status2 & = ~ ( STATUS2_SUBSTITUTE ) ;
}
gBattleScripting . atk49_state + + ;
break ;
case 14 : // This case looks interesting, although I am not certain what it does. Probably fine tunes edge cases.
if ( gHitMarker & HITMARKER_PURSUIT_TRAP )
{
gActiveBank = gBankAttacker ;
gBankAttacker = gBankTarget ;
gBankTarget = gActiveBank ;
gHitMarker & = ~ ( HITMARKER_PURSUIT_TRAP ) ;
}
if ( gHitMarker & HITMARKER_ATTACKSTRING_PRINTED )
{
2017-11-26 18:07:00 +01:00
gLastPrintedMoves [ gBankAttacker ] = gChosenMove ;
2017-09-23 20:13:45 +02:00
}
if ( ! ( gAbsentBankFlags & gBitTable [ gBankAttacker ] )
& & ! ( gBattleStruct - > field_91 & gBitTable [ gBankAttacker ] )
2017-11-26 14:17:02 +01:00
& & gBattleMoves [ originallyUsedMove ] . effect ! = EFFECT_BATON_PASS )
2017-09-23 20:13:45 +02:00
{
if ( gHitMarker & HITMARKER_OBEYS )
{
2017-11-26 18:07:00 +01:00
gLastMoves [ gBankAttacker ] = gChosenMove ;
gLastResultingMoves [ gBankAttacker ] = gCurrentMove ;
2017-09-23 20:13:45 +02:00
}
else
{
2017-11-26 14:17:02 +01:00
gLastMoves [ gBankAttacker ] = 0xFFFF ;
2017-11-26 18:07:00 +01:00
gLastResultingMoves [ gBankAttacker ] = 0xFFFF ;
2017-09-23 20:13:45 +02:00
}
if ( ! ( gHitMarker & HITMARKER_FAINTED ( gBankTarget ) ) )
2017-11-26 14:17:02 +01:00
gLastHitBy [ gBankTarget ] = gBankAttacker ;
2017-09-23 20:13:45 +02:00
if ( gHitMarker & HITMARKER_OBEYS & & ! ( gBattleMoveFlags & MOVESTATUS_NOEFFECT ) )
{
2017-11-26 18:07:00 +01:00
if ( gChosenMove = = 0xFFFF )
2017-09-23 20:13:45 +02:00
{
2017-11-26 18:07:00 +01:00
gLastLandedMoves [ gBankTarget ] = gChosenMove ;
2017-09-23 20:13:45 +02:00
}
else
{
2017-11-26 14:17:02 +01:00
gLastLandedMoves [ gBankTarget ] = gCurrentMove ;
GET_MOVE_TYPE ( gCurrentMove , gLastHitByType [ gBankTarget ] ) ;
2017-09-23 20:13:45 +02:00
}
}
else
{
2017-11-26 14:17:02 +01:00
gLastLandedMoves [ gBankTarget ] = 0xFFFF ;
2017-09-23 20:13:45 +02:00
}
}
gBattleScripting . atk49_state + + ;
break ;
case 15 : // mirror move
if ( ! ( gAbsentBankFlags & gBitTable [ gBankAttacker ] ) & & ! ( gBattleStruct - > field_91 & gBitTable [ gBankAttacker ] )
2017-11-26 14:17:02 +01:00
& & gBattleMoves [ originallyUsedMove ] . flags & FLAG_MIRROR_MOVE_AFFECTED & & gHitMarker & HITMARKER_OBEYS
2017-09-23 20:13:45 +02:00
& & gBankAttacker ! = gBankTarget & & ! ( gHitMarker & HITMARKER_FAINTED ( gBankTarget ) )
& & ! ( gBattleMoveFlags & MOVESTATUS_NOEFFECT ) )
{
u8 target , attacker ;
2017-11-26 18:07:00 +01:00
* ( gBattleStruct - > mirrorMoves + gBankTarget * 2 + 0 ) = gChosenMove ;
* ( gBattleStruct - > mirrorMoves + gBankTarget * 2 + 1 ) = gChosenMove > > 8 ;
2017-09-23 20:13:45 +02:00
target = gBankTarget ;
attacker = gBankAttacker ;
2017-11-26 18:07:00 +01:00
* ( attacker * 2 + target * 8 + ( u8 * ) ( gBattleStruct - > mirrorMoveArrays ) + 0 ) = gChosenMove ;
2017-09-23 20:13:45 +02:00
target = gBankTarget ;
attacker = gBankAttacker ;
2017-11-26 18:07:00 +01:00
* ( attacker * 2 + target * 8 + ( u8 * ) ( gBattleStruct - > mirrorMoveArrays ) + 1 ) = gChosenMove > > 8 ;
2017-09-23 20:13:45 +02:00
}
gBattleScripting . atk49_state + + ;
break ;
case 16 : //
if ( ! ( gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE ) & & gBattleTypeFlags & BATTLE_TYPE_DOUBLE
& & ! gProtectStructs [ gBankAttacker ] . chargingTurn & & gBattleMoves [ gCurrentMove ] . target = = MOVE_TARGET_BOTH
& & ! ( gHitMarker & HITMARKER_NO_ATTACKSTRING ) )
{
2017-09-26 22:39:59 +02:00
u8 bank = GetBankByIdentity ( GetBankIdentity ( gBankTarget ) ^ BIT_MON ) ;
2017-09-23 20:13:45 +02:00
if ( gBattleMons [ bank ] . hp ! = 0 )
{
gBankTarget = bank ;
gHitMarker | = HITMARKER_NO_ATTACKSTRING ;
gBattleScripting . atk49_state = 0 ;
MoveValuesCleanUp ( ) ;
BattleScriptPush ( gBattleScriptsForMoveEffects [ gBattleMoves [ gCurrentMove ] . effect ] ) ;
2017-11-25 18:42:31 +01:00
gBattlescriptCurrInstr = BattleScript_82DB87D ;
2017-09-23 20:13:45 +02:00
return ;
}
else
{
gHitMarker | = HITMARKER_NO_ATTACKSTRING ;
}
}
gBattleScripting . atk49_state + + ;
break ;
case ATK49_LAST_CASE :
break ;
}
if ( arg1 = = 1 & & effect = = FALSE )
gBattleScripting . atk49_state = ATK49_LAST_CASE ;
if ( arg1 = = 2 & & arg2 = = gBattleScripting . atk49_state )
gBattleScripting . atk49_state = ATK49_LAST_CASE ;
} while ( gBattleScripting . atk49_state ! = ATK49_LAST_CASE & & effect = = FALSE ) ;
if ( gBattleScripting . atk49_state = = ATK49_LAST_CASE & & effect = = FALSE )
gBattlescriptCurrInstr + = 3 ;
}
2017-09-28 15:34:21 +02:00
static void atk4A_typecalc2 ( void )
2017-09-24 00:29:52 +02:00
{
u8 flags = 0 ;
s32 i = 0 ;
u8 moveType = gBattleMoves [ gCurrentMove ] . type ;
if ( gBattleMons [ gBankTarget ] . ability = = ABILITY_LEVITATE & & moveType = = TYPE_GROUND )
{
gLastUsedAbility = gBattleMons [ gBankTarget ] . ability ;
gBattleMoveFlags | = ( MOVESTATUS_MISSED | MOVESTATUS_NOTAFFECTED ) ;
2017-11-26 14:17:02 +01:00
gLastLandedMoves [ gBankTarget ] = 0 ;
2017-09-24 00:29:52 +02:00
gBattleCommunication [ 6 ] = moveType ;
RecordAbilityBattle ( gBankTarget , gLastUsedAbility ) ;
}
else
{
2017-11-11 20:01:04 +01:00
while ( TYPE_EFFECT_ATK_TYPE ( i ) ! = TYPE_ENDTABLE )
2017-09-24 00:29:52 +02:00
{
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( i ) = = TYPE_FORESIGHT )
2017-09-24 00:29:52 +02:00
{
if ( gBattleMons [ gBankTarget ] . status2 & STATUS2_FORESIGHT )
{
break ;
}
else
{
i + = 3 ;
continue ;
}
}
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( i ) = = moveType )
2017-09-24 00:29:52 +02:00
{
// check type1
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBankTarget ] . type1 )
2017-09-24 00:29:52 +02:00
{
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_NO_EFFECT )
2017-09-24 00:29:52 +02:00
{
gBattleMoveFlags | = MOVESTATUS_NOTAFFECTED ;
break ;
}
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_NOT_EFFECTIVE )
2017-09-24 00:29:52 +02:00
{
flags | = MOVESTATUS_NOTVERYEFFECTIVE ;
}
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_SUPER_EFFECTIVE )
2017-09-24 00:29:52 +02:00
{
flags | = MOVESTATUS_SUPEREFFECTIVE ;
}
}
// check type2
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBankTarget ] . type2 )
2017-09-24 00:29:52 +02:00
{
if ( gBattleMons [ gBankTarget ] . type1 ! = gBattleMons [ gBankTarget ] . type2
2017-11-11 20:01:04 +01:00
& & TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_NO_EFFECT )
2017-09-24 00:29:52 +02:00
{
gBattleMoveFlags | = MOVESTATUS_NOTAFFECTED ;
break ;
}
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBankTarget ] . type2
2017-09-24 00:29:52 +02:00
& & gBattleMons [ gBankTarget ] . type1 ! = gBattleMons [ gBankTarget ] . type2
2017-11-11 20:01:04 +01:00
& & TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_NOT_EFFECTIVE )
2017-09-24 00:29:52 +02:00
{
flags | = MOVESTATUS_NOTVERYEFFECTIVE ;
}
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBankTarget ] . type2
2017-09-24 00:29:52 +02:00
& & gBattleMons [ gBankTarget ] . type1 ! = gBattleMons [ gBankTarget ] . type2
2017-11-11 20:01:04 +01:00
& & TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_SUPER_EFFECTIVE )
2017-09-24 00:29:52 +02:00
{
flags | = MOVESTATUS_SUPEREFFECTIVE ;
}
}
}
i + = 3 ;
}
}
if ( gBattleMons [ gBankTarget ] . ability = = ABILITY_WONDER_GUARD
& & ! ( flags & MOVESTATUS_NOEFFECT )
& & AttacksThisTurn ( gBankAttacker , gCurrentMove ) = = 2
& & ( ! ( flags & MOVESTATUS_SUPEREFFECTIVE ) | | ( ( flags & ( MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE ) ) = = ( MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE ) ) )
& & gBattleMoves [ gCurrentMove ] . power )
{
gLastUsedAbility = ABILITY_WONDER_GUARD ;
gBattleMoveFlags | = MOVESTATUS_MISSED ;
2017-11-26 14:17:02 +01:00
gLastLandedMoves [ gBankTarget ] = 0 ;
2017-09-24 00:29:52 +02:00
gBattleCommunication [ 6 ] = 3 ;
RecordAbilityBattle ( gBankTarget , gLastUsedAbility ) ;
}
if ( gBattleMoveFlags & MOVESTATUS_NOTAFFECTED )
2017-10-06 17:06:45 +02:00
gProtectStructs [ gBankAttacker ] . targetNotAffected = 1 ;
2017-09-24 00:29:52 +02:00
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atk4B_returnatktoball ( void )
2017-09-24 00:29:52 +02:00
{
gActiveBank = gBankAttacker ;
if ( ! ( gHitMarker & HITMARKER_FAINTED ( gActiveBank ) ) )
{
2017-10-14 11:34:26 +02:00
EmitReturnMonToBall ( 0 , 0 ) ;
2017-09-24 00:29:52 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
}
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atk4C_getswitchedmondata ( void )
2017-09-24 00:29:52 +02:00
{
if ( gBattleExecBuffer )
return ;
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-24 00:29:52 +02:00
2017-11-12 17:06:31 +01:00
gBattlePartyID [ gActiveBank ] = * ( gBattleStruct - > monToSwitchIntoId + gActiveBank ) ;
2017-09-24 00:29:52 +02:00
2017-11-11 20:01:04 +01:00
EmitGetMonData ( 0 , REQUEST_ALL_BATTLE , gBitTable [ gBattlePartyID [ gActiveBank ] ] ) ;
2017-09-24 00:29:52 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 2 ;
}
2017-11-25 18:42:31 +01:00
static void atk4D_switchindataupdate ( void )
2017-09-24 00:29:52 +02:00
{
struct BattlePokemon oldData ;
s32 i ;
u8 * monData ;
if ( gBattleExecBuffer )
return ;
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-24 00:29:52 +02:00
oldData = gBattleMons [ gActiveBank ] ;
monData = ( u8 * ) ( & gBattleMons [ gActiveBank ] ) ;
for ( i = 0 ; i < sizeof ( struct BattlePokemon ) ; i + + )
{
monData [ i ] = gBattleBufferB [ gActiveBank ] [ 4 + i ] ;
}
gBattleMons [ gActiveBank ] . type1 = gBaseStats [ gBattleMons [ gActiveBank ] . species ] . type1 ;
gBattleMons [ gActiveBank ] . type2 = gBaseStats [ gBattleMons [ gActiveBank ] . species ] . type2 ;
gBattleMons [ gActiveBank ] . ability = GetAbilityBySpecies ( gBattleMons [ gActiveBank ] . species , gBattleMons [ gActiveBank ] . altAbility ) ;
// check knocked off item
i = GetBankSide ( gActiveBank ) ;
if ( gWishFutureKnock . knockedOffPokes [ i ] & gBitTable [ gBattlePartyID [ gActiveBank ] ] )
{
gBattleMons [ gActiveBank ] . item = 0 ;
}
if ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_BATON_PASS )
{
2017-11-11 20:01:04 +01:00
for ( i = 0 ; i < BATTLE_STATS_NO ; i + + )
2017-09-24 00:29:52 +02:00
{
gBattleMons [ gActiveBank ] . statStages [ i ] = oldData . statStages [ i ] ;
}
gBattleMons [ gActiveBank ] . status2 = oldData . status2 ;
}
2017-10-02 23:32:39 +02:00
SwitchInClearSetData ( ) ;
2017-09-24 00:29:52 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_PALACE & & gBattleMons [ gActiveBank ] . maxHP / 2 > = gBattleMons [ gActiveBank ] . hp
& & gBattleMons [ gActiveBank ] . hp ! = 0 & & ! ( gBattleMons [ gActiveBank ] . status1 & STATUS_SLEEP ) )
{
gBattleStruct - > field_92 | = gBitTable [ gActiveBank ] ;
}
gBattleScripting . bank = gActiveBank ;
2017-11-11 20:01:04 +01:00
PREPARE_MON_NICK_BUFFER ( gBattleTextBuff1 , gActiveBank , gBattlePartyID [ gActiveBank ] ) ;
2017-09-24 00:29:52 +02:00
gBattlescriptCurrInstr + = 2 ;
}
2017-11-25 18:42:31 +01:00
static void atk4E_switchinanim ( void )
2017-09-24 00:29:52 +02:00
{
if ( gBattleExecBuffer )
return ;
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-24 00:29:52 +02:00
if ( GetBankSide ( gActiveBank ) = = SIDE_OPPONENT
& & ! ( gBattleTypeFlags & ( BATTLE_TYPE_LINK
| BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_x2000000
| BATTLE_TYPE_x4000000
| BATTLE_TYPE_FRONTIER ) ) )
HandleSetPokedexFlag ( SpeciesToNationalPokedexNum ( gBattleMons [ gActiveBank ] . species ) , FLAG_SET_SEEN , gBattleMons [ gActiveBank ] . personality ) ;
gAbsentBankFlags & = ~ ( gBitTable [ gActiveBank ] ) ;
EmitSwitchInAnim ( 0 , gBattlePartyID [ gActiveBank ] , gBattlescriptCurrInstr [ 2 ] ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 3 ;
if ( gBattleTypeFlags & BATTLE_TYPE_ARENA )
sub_81A56B4 ( ) ;
}
2017-11-25 18:42:31 +01:00
static void atk4F_jumpifcantswitch ( void )
2017-09-24 00:29:52 +02:00
{
s32 val = 0 ;
s32 compareVar = 0 ;
struct Pokemon * party = NULL ;
s32 r7 = 0 ;
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] & ~ ( ATK4F_DONT_CHECK_STATUSES ) ) ;
if ( ! ( gBattlescriptCurrInstr [ 1 ] & ATK4F_DONT_CHECK_STATUSES )
& & ( ( gBattleMons [ gActiveBank ] . status2 & ( STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION ) )
| | ( gStatuses3 [ gActiveBank ] & STATUS3_ROOTED ) ) )
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 2 ) ;
}
else if ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER )
{
# ifndef NONMATCHING
asm ( " " : : : " r5 " ) ;
# endif // NONMATCHING
if ( GetBankSide ( gActiveBank ) = = SIDE_OPPONENT )
party = gEnemyParty ;
else
party = gPlayerParty ;
val = 0 ;
if ( 2 & gActiveBank )
val = 3 ;
for ( compareVar = val + 3 ; val < compareVar ; val + + )
{
if ( GetMonData ( & party [ val ] , MON_DATA_SPECIES ) ! = SPECIES_NONE
& & ! GetMonData ( & party [ val ] , MON_DATA_IS_EGG )
& & GetMonData ( & party [ val ] , MON_DATA_HP ) ! = 0
& & gBattlePartyID [ gActiveBank ] ! = val )
break ;
}
if ( val = = compareVar )
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 2 ) ;
else
gBattlescriptCurrInstr + = 6 ;
}
else if ( gBattleTypeFlags & BATTLE_TYPE_MULTI )
{
if ( gBattleTypeFlags & BATTLE_TYPE_x800000 )
{
if ( GetBankSide ( gActiveBank ) = = SIDE_PLAYER )
{
party = gPlayerParty ;
val = 0 ;
2017-10-23 16:38:11 +02:00
if ( sub_806D82C ( GetBankMultiplayerId ( gActiveBank ) ) = = TRUE )
2017-09-24 00:29:52 +02:00
val = 3 ;
}
else
{
party = gEnemyParty ;
if ( gActiveBank = = 1 )
val = 0 ;
else
val = 3 ;
}
}
else
{
if ( GetBankSide ( gActiveBank ) = = SIDE_OPPONENT )
party = gEnemyParty ;
else
party = gPlayerParty ;
val = 0 ;
2017-10-23 16:38:11 +02:00
if ( sub_806D82C ( GetBankMultiplayerId ( gActiveBank ) ) = = TRUE )
2017-09-24 00:29:52 +02:00
val = 3 ;
}
for ( compareVar = val + 3 ; val < compareVar ; val + + )
{
if ( GetMonData ( & party [ val ] , MON_DATA_SPECIES ) ! = SPECIES_NONE
& & ! GetMonData ( & party [ val ] , MON_DATA_IS_EGG )
& & GetMonData ( & party [ val ] , MON_DATA_HP ) ! = 0
& & gBattlePartyID [ gActiveBank ] ! = val )
break ;
}
if ( val = = compareVar )
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 2 ) ;
else
gBattlescriptCurrInstr + = 6 ;
}
else if ( gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS & & GetBankSide ( gActiveBank ) = = SIDE_OPPONENT )
{
party = gEnemyParty ;
val = 0 ;
if ( gActiveBank = = 3 )
val = 3 ;
for ( compareVar = val + 3 ; val < compareVar ; val + + )
{
if ( GetMonData ( & party [ val ] , MON_DATA_SPECIES ) ! = SPECIES_NONE
& & ! GetMonData ( & party [ val ] , MON_DATA_IS_EGG )
& & GetMonData ( & party [ val ] , MON_DATA_HP ) ! = 0
& & gBattlePartyID [ gActiveBank ] ! = val )
break ;
}
if ( val = = compareVar )
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 2 ) ;
else
gBattlescriptCurrInstr + = 6 ;
}
else
{
if ( GetBankSide ( gActiveBank ) = = SIDE_OPPONENT )
{
2017-11-26 13:26:58 +01:00
r7 = GetBankByIdentity ( IDENTITY_OPPONENT_MON1 ) ;
2017-09-24 00:29:52 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
2017-11-26 13:26:58 +01:00
compareVar = GetBankByIdentity ( IDENTITY_OPPONENT_MON2 ) ;
2017-09-24 00:29:52 +02:00
else
compareVar = r7 ;
party = gEnemyParty ;
}
else
{
2017-11-26 13:26:58 +01:00
r7 = GetBankByIdentity ( IDENTITY_PLAYER_MON1 ) ;
2017-09-24 00:29:52 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
2017-11-26 13:26:58 +01:00
compareVar = GetBankByIdentity ( IDENTITY_PLAYER_MON2 ) ;
2017-09-24 00:29:52 +02:00
else
compareVar = r7 ;
party = gPlayerParty ;
}
for ( val = 0 ; val < 6 ; val + + )
{
if ( GetMonData ( & party [ val ] , MON_DATA_HP ) ! = 0
& & GetMonData ( & party [ val ] , MON_DATA_SPECIES ) ! = SPECIES_NONE
& & ! GetMonData ( & party [ val ] , MON_DATA_IS_EGG )
& & val ! = gBattlePartyID [ r7 ] & & val ! = gBattlePartyID [ compareVar ] )
break ;
}
if ( val = = 6 )
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 2 ) ;
else
gBattlescriptCurrInstr + = 6 ;
}
}
2017-09-28 15:34:21 +02:00
static void sub_804CF10 ( u8 arg0 )
2017-09-24 00:29:52 +02:00
{
* ( gBattleStruct - > field_58 + gActiveBank ) = gBattlePartyID [ gActiveBank ] ;
2017-11-12 17:06:31 +01:00
* ( gBattleStruct - > monToSwitchIntoId + gActiveBank ) = 6 ;
2017-09-24 00:29:52 +02:00
gBattleStruct - > field_93 & = ~ ( gBitTable [ gActiveBank ] ) ;
EmitChoosePokemon ( 0 , 1 , arg0 , 0 , gBattleStruct - > field_60 [ gActiveBank ] ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
}
2017-09-25 00:09:13 +02:00
2017-09-28 15:34:21 +02:00
static void atk50_openpartyscreen ( void )
2017-09-25 00:09:13 +02:00
{
u32 flags ;
u8 hitmarkerFaintBits ;
u8 bank ;
const u8 * jumpPtr ;
bank = 0 ;
flags = 0 ;
jumpPtr = BSScriptReadPtr ( gBattlescriptCurrInstr + 2 ) ;
if ( gBattlescriptCurrInstr [ 1 ] = = 5 )
{
if ( ( gBattleTypeFlags & ( BATTLE_TYPE_DOUBLE | BATTLE_TYPE_MULTI ) ) ! = BATTLE_TYPE_DOUBLE )
{
for ( gActiveBank = 0 ; gActiveBank < gNoOfAllBanks ; gActiveBank + + )
{
if ( gHitMarker & HITMARKER_FAINTED ( gActiveBank ) )
{
if ( sub_80423F4 ( gActiveBank , 6 , 6 ) )
{
gAbsentBankFlags | = gBitTable [ gActiveBank ] ;
gHitMarker & = ~ ( HITMARKER_FAINTED ( gActiveBank ) ) ;
EmitLinkStandbyMsg ( 0 , 2 , 0 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
}
else if ( ! gSpecialStatuses [ gActiveBank ] . flag40 )
{
sub_804CF10 ( 6 ) ;
gSpecialStatuses [ gActiveBank ] . flag40 = 1 ;
}
}
else
{
EmitLinkStandbyMsg ( 0 , 2 , 0 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
}
}
}
else if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
{
u8 flag40_0 , flag40_1 , flag40_2 , flag40_3 ;
hitmarkerFaintBits = gHitMarker > > 0x1C ;
if ( gBitTable [ 0 ] & hitmarkerFaintBits )
{
gActiveBank = 0 ;
if ( sub_80423F4 ( 0 , 6 , 6 ) )
{
gAbsentBankFlags | = gBitTable [ gActiveBank ] ;
gHitMarker & = ~ ( HITMARKER_FAINTED ( gActiveBank ) ) ;
2017-10-14 11:34:26 +02:00
EmitCmd42 ( 0 ) ;
2017-09-25 00:09:13 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
}
else if ( ! gSpecialStatuses [ gActiveBank ] . flag40 )
{
2017-11-12 17:06:31 +01:00
sub_804CF10 ( gBattleStruct - > monToSwitchIntoId [ 2 ] ) ;
2017-09-25 00:09:13 +02:00
gSpecialStatuses [ gActiveBank ] . flag40 = 1 ;
}
else
{
EmitLinkStandbyMsg ( 0 , 2 , 0 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
flags | = 1 ;
}
}
if ( gBitTable [ 2 ] & hitmarkerFaintBits & & ! ( gBitTable [ 0 ] & hitmarkerFaintBits ) )
{
gActiveBank = 2 ;
if ( sub_80423F4 ( 2 , 6 , 6 ) )
{
gAbsentBankFlags | = gBitTable [ gActiveBank ] ;
gHitMarker & = ~ ( HITMARKER_FAINTED ( gActiveBank ) ) ;
2017-10-14 11:34:26 +02:00
EmitCmd42 ( 0 ) ;
2017-09-25 00:09:13 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
}
else if ( ! gSpecialStatuses [ gActiveBank ] . flag40 )
{
2017-11-12 17:06:31 +01:00
sub_804CF10 ( gBattleStruct - > monToSwitchIntoId [ 0 ] ) ;
2017-09-25 00:09:13 +02:00
gSpecialStatuses [ gActiveBank ] . flag40 = 1 ;
}
else if ( ! ( flags & 1 ) )
{
EmitLinkStandbyMsg ( 0 , 2 , 0 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
}
}
if ( gBitTable [ 1 ] & hitmarkerFaintBits )
{
gActiveBank = 1 ;
if ( sub_80423F4 ( 1 , 6 , 6 ) )
{
gAbsentBankFlags | = gBitTable [ gActiveBank ] ;
gHitMarker & = ~ ( HITMARKER_FAINTED ( gActiveBank ) ) ;
2017-10-14 11:34:26 +02:00
EmitCmd42 ( 0 ) ;
2017-09-25 00:09:13 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
}
else if ( ! gSpecialStatuses [ gActiveBank ] . flag40 )
{
2017-11-12 17:06:31 +01:00
sub_804CF10 ( gBattleStruct - > monToSwitchIntoId [ 3 ] ) ;
2017-09-25 00:09:13 +02:00
gSpecialStatuses [ gActiveBank ] . flag40 = 1 ;
}
else
{
EmitLinkStandbyMsg ( 0 , 2 , 0 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
flags | = 2 ;
}
}
if ( gBitTable [ 3 ] & hitmarkerFaintBits & & ! ( gBitTable [ 1 ] & hitmarkerFaintBits ) )
{
gActiveBank = 3 ;
if ( sub_80423F4 ( 3 , 6 , 6 ) )
{
gAbsentBankFlags | = gBitTable [ gActiveBank ] ;
gHitMarker & = ~ ( HITMARKER_FAINTED ( gActiveBank ) ) ;
2017-10-14 11:34:26 +02:00
EmitCmd42 ( 0 ) ;
2017-09-25 00:09:13 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
}
else if ( ! gSpecialStatuses [ gActiveBank ] . flag40 )
{
2017-11-12 17:06:31 +01:00
sub_804CF10 ( gBattleStruct - > monToSwitchIntoId [ 1 ] ) ;
2017-09-25 00:09:13 +02:00
gSpecialStatuses [ gActiveBank ] . flag40 = 1 ;
}
else if ( ! ( flags & 2 ) )
{
EmitLinkStandbyMsg ( 0 , 2 , 0 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
}
}
flag40_0 = gSpecialStatuses [ 0 ] . flag40 ;
if ( ! flag40_0 )
{
flag40_2 = gSpecialStatuses [ 2 ] . flag40 ;
if ( ! flag40_2 & & hitmarkerFaintBits ! = 0 )
{
if ( gAbsentBankFlags & gBitTable [ 0 ] )
gActiveBank = 2 ;
else
gActiveBank = 0 ;
EmitLinkStandbyMsg ( 0 , 2 , 0 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
}
}
flag40_1 = gSpecialStatuses [ 1 ] . flag40 ;
if ( ! flag40_1 )
{
flag40_3 = gSpecialStatuses [ 3 ] . flag40 ;
if ( ! flag40_3 & & hitmarkerFaintBits ! = 0 )
{
if ( gAbsentBankFlags & gBitTable [ 1 ] )
gActiveBank = 3 ;
else
gActiveBank = 1 ;
EmitLinkStandbyMsg ( 0 , 2 , 0 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
}
}
}
gBattlescriptCurrInstr + = 6 ;
}
else if ( gBattlescriptCurrInstr [ 1 ] = = 6 )
{
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_MULTI ) )
{
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
{
hitmarkerFaintBits = gHitMarker > > 0x1C ;
if ( gBitTable [ 2 ] & hitmarkerFaintBits & & gBitTable [ 0 ] & hitmarkerFaintBits )
{
gActiveBank = 2 ;
if ( sub_80423F4 ( 2 , gBattleBufferB [ 0 ] [ 1 ] , 6 ) )
{
gAbsentBankFlags | = gBitTable [ gActiveBank ] ;
gHitMarker & = ~ ( HITMARKER_FAINTED ( gActiveBank ) ) ;
2017-10-14 11:34:26 +02:00
EmitCmd42 ( 0 ) ;
2017-09-25 00:09:13 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
}
else if ( ! gSpecialStatuses [ gActiveBank ] . flag40 )
{
2017-11-12 17:06:31 +01:00
sub_804CF10 ( gBattleStruct - > monToSwitchIntoId [ 0 ] ) ;
2017-09-25 00:09:13 +02:00
gSpecialStatuses [ gActiveBank ] . flag40 = 1 ;
}
}
if ( gBitTable [ 3 ] & hitmarkerFaintBits & & hitmarkerFaintBits & gBitTable [ 1 ] )
{
gActiveBank = 3 ;
if ( sub_80423F4 ( 3 , gBattleBufferB [ 1 ] [ 1 ] , 6 ) )
{
gAbsentBankFlags | = gBitTable [ gActiveBank ] ;
gHitMarker & = ~ ( HITMARKER_FAINTED ( gActiveBank ) ) ;
2017-10-14 11:34:26 +02:00
EmitCmd42 ( 0 ) ;
2017-09-25 00:09:13 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
}
else if ( ! gSpecialStatuses [ gActiveBank ] . flag40 )
{
2017-11-12 17:06:31 +01:00
sub_804CF10 ( gBattleStruct - > monToSwitchIntoId [ 1 ] ) ;
2017-09-25 00:09:13 +02:00
gSpecialStatuses [ gActiveBank ] . flag40 = 1 ;
}
}
gBattlescriptCurrInstr + = 6 ;
}
else
{
gBattlescriptCurrInstr + = 6 ;
}
}
else
{
gBattlescriptCurrInstr + = 6 ;
}
hitmarkerFaintBits = gHitMarker > > 0x1C ;
gBank1 = 0 ;
while ( 1 )
{
if ( gBitTable [ gBank1 ] & hitmarkerFaintBits )
break ;
if ( gBank1 > = gNoOfAllBanks )
break ;
gBank1 + + ;
}
if ( gBank1 = = gNoOfAllBanks )
gBattlescriptCurrInstr = jumpPtr ;
}
else
{
if ( gBattlescriptCurrInstr [ 1 ] & 0x80 )
hitmarkerFaintBits = 0 ; // used here as the caseId for the EmitChoose function
else
hitmarkerFaintBits = 1 ;
bank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] & ~ ( 0x80 ) ) ;
if ( gSpecialStatuses [ bank ] . flag40 )
{
gBattlescriptCurrInstr + = 6 ;
}
else if ( sub_80423F4 ( bank , 6 , 6 ) )
{
gActiveBank = bank ;
gAbsentBankFlags | = gBitTable [ gActiveBank ] ;
gHitMarker & = ~ ( HITMARKER_FAINTED ( gActiveBank ) ) ;
gBattlescriptCurrInstr = jumpPtr ;
}
else
{
gActiveBank = bank ;
* ( gBattleStruct - > field_58 + gActiveBank ) = gBattlePartyID [ gActiveBank ] ;
2017-11-12 17:06:31 +01:00
* ( gBattleStruct - > monToSwitchIntoId + gActiveBank ) = 6 ;
2017-09-25 00:09:13 +02:00
gBattleStruct - > field_93 & = ~ ( gBitTable [ gActiveBank ] ) ;
2017-11-12 17:06:31 +01:00
EmitChoosePokemon ( 0 , hitmarkerFaintBits , * ( gBattleStruct - > monToSwitchIntoId + ( gActiveBank ^ 2 ) ) , 0 , gBattleStruct - > field_60 [ gActiveBank ] ) ;
2017-09-25 00:09:13 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 6 ;
if ( GetBankIdentity ( gActiveBank ) = = 0 & & gBattleResults . playerSwitchesCounter < 0xFF )
gBattleResults . playerSwitchesCounter + + ;
if ( gBattleTypeFlags & BATTLE_TYPE_MULTI )
{
for ( gActiveBank = 0 ; gActiveBank < gNoOfAllBanks ; gActiveBank + + )
{
if ( gActiveBank ! = bank )
{
EmitLinkStandbyMsg ( 0 , 2 , 0 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
}
}
}
else
{
2017-09-26 22:39:59 +02:00
gActiveBank = GetBankByIdentity ( GetBankIdentity ( bank ) ^ BIT_SIDE ) ;
2017-09-25 00:09:13 +02:00
if ( gAbsentBankFlags & gBitTable [ gActiveBank ] )
2017-09-26 22:39:59 +02:00
gActiveBank ^ = BIT_MON ;
2017-09-25 00:09:13 +02:00
EmitLinkStandbyMsg ( 0 , 2 , 0 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
}
}
}
}
2017-11-25 18:42:31 +01:00
static void atk51_switchhandleorder ( void )
2017-09-25 00:09:13 +02:00
{
s32 i ;
if ( gBattleExecBuffer )
return ;
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-25 00:09:13 +02:00
2017-09-28 15:34:21 +02:00
switch ( gBattlescriptCurrInstr [ 2 ] )
2017-09-25 00:09:13 +02:00
{
case 0 :
for ( i = 0 ; i < gNoOfAllBanks ; i + + )
{
if ( gBattleBufferB [ i ] [ 0 ] = = 0x22 )
{
2017-11-12 17:06:31 +01:00
* ( gBattleStruct - > monToSwitchIntoId + i ) = gBattleBufferB [ i ] [ 1 ] ;
2017-09-25 00:09:13 +02:00
if ( ! ( gBattleStruct - > field_93 & gBitTable [ i ] ) )
{
RecordedBattle_SetBankAction ( i , gBattleBufferB [ i ] [ 1 ] ) ;
gBattleStruct - > field_93 | = gBitTable [ i ] ;
}
}
}
break ;
case 1 :
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_MULTI ) )
sub_803BDA0 ( gActiveBank ) ;
break ;
case 2 :
if ( ! ( gBattleStruct - > field_93 & gBitTable [ gActiveBank ] ) )
{
RecordedBattle_SetBankAction ( gActiveBank , gBattleBufferB [ gActiveBank ] [ 1 ] ) ;
gBattleStruct - > field_93 | = gBitTable [ gActiveBank ] ;
}
// fall through
case 3 :
gBattleCommunication [ 0 ] = gBattleBufferB [ gActiveBank ] [ 1 ] ;
2017-11-12 17:06:31 +01:00
* ( gBattleStruct - > monToSwitchIntoId + gActiveBank ) = gBattleBufferB [ gActiveBank ] [ 1 ] ;
2017-09-25 00:09:13 +02:00
2017-10-04 19:25:14 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_LINK & & gBattleTypeFlags & BATTLE_TYPE_MULTI )
2017-09-25 00:09:13 +02:00
{
* ( gActiveBank * 3 + ( u8 * ) ( gBattleStruct - > field_60 ) + 0 ) & = 0xF ;
* ( gActiveBank * 3 + ( u8 * ) ( gBattleStruct - > field_60 ) + 0 ) | = ( gBattleBufferB [ gActiveBank ] [ 2 ] & 0xF0 ) ;
* ( gActiveBank * 3 + ( u8 * ) ( gBattleStruct - > field_60 ) + 1 ) = gBattleBufferB [ gActiveBank ] [ 3 ] ;
2017-10-04 19:25:14 +02:00
* ( ( gActiveBank ^ BIT_MON ) * 3 + ( u8 * ) ( gBattleStruct - > field_60 ) + 0 ) & = ( 0xF0 ) ;
* ( ( gActiveBank ^ BIT_MON ) * 3 + ( u8 * ) ( gBattleStruct - > field_60 ) + 0 ) | = ( gBattleBufferB [ gActiveBank ] [ 2 ] & 0xF0 ) > > 4 ;
* ( ( gActiveBank ^ BIT_MON ) * 3 + ( u8 * ) ( gBattleStruct - > field_60 ) + 2 ) = gBattleBufferB [ gActiveBank ] [ 3 ] ;
2017-09-25 00:09:13 +02:00
}
else if ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER )
{
2017-11-12 17:06:31 +01:00
sub_80571DC ( gActiveBank , * ( gBattleStruct - > monToSwitchIntoId + gActiveBank ) ) ;
2017-09-25 00:09:13 +02:00
}
else
{
sub_803BDA0 ( gActiveBank ) ;
}
PREPARE_SPECIES_BUFFER ( gBattleTextBuff1 , gBattleMons [ gBankAttacker ] . species )
PREPARE_MON_NICK_BUFFER ( gBattleTextBuff2 , gActiveBank , gBattleBufferB [ gActiveBank ] [ 1 ] )
break ;
}
gBattlescriptCurrInstr + = 3 ;
}
2017-11-25 18:42:31 +01:00
static void atk52_switchineffects ( void )
2017-09-25 00:09:13 +02:00
{
s32 i ;
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-25 00:09:13 +02:00
sub_803FA70 ( gActiveBank ) ;
gHitMarker & = ~ ( HITMARKER_FAINTED ( gActiveBank ) ) ;
gSpecialStatuses [ gActiveBank ] . flag40 = 0 ;
if ( ! ( gSideAffecting [ GetBankSide ( gActiveBank ) ] & SIDE_STATUS_SPIKES_DAMAGED )
& & ( gSideAffecting [ GetBankSide ( gActiveBank ) ] & SIDE_STATUS_SPIKES )
& & gBattleMons [ gActiveBank ] . type1 ! = TYPE_FLYING
& & gBattleMons [ gActiveBank ] . type2 ! = TYPE_FLYING
& & gBattleMons [ gActiveBank ] . ability ! = ABILITY_LEVITATE )
{
u8 spikesDmg ;
gSideAffecting [ GetBankSide ( gActiveBank ) ] | = SIDE_STATUS_SPIKES_DAMAGED ;
gBattleMons [ gActiveBank ] . status2 & = ~ ( STATUS2_DESTINY_BOND ) ;
gHitMarker & = ~ ( HITMARKER_DESTINYBOND ) ;
spikesDmg = ( 5 - gSideTimers [ GetBankSide ( gActiveBank ) ] . spikesAmount ) * 2 ;
gBattleMoveDamage = gBattleMons [ gActiveBank ] . maxHP / ( spikesDmg ) ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleScripting . bank = gActiveBank ;
BattleScriptPushCursor ( ) ;
2017-11-25 18:42:31 +01:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_GET_TARGET )
gBattlescriptCurrInstr = BattleScript_SpikesOnTarget ;
else if ( gBattlescriptCurrInstr [ 1 ] = = BS_GET_ATTACKER )
gBattlescriptCurrInstr = BattleScript_SpikesOnAttacker ;
2017-09-25 00:09:13 +02:00
else
2017-11-25 18:42:31 +01:00
gBattlescriptCurrInstr = BattleScript_SpikesOngBank1 ;
2017-09-25 00:09:13 +02:00
}
else
{
if ( gBattleMons [ gActiveBank ] . ability = = ABILITY_TRUANT & & ! gDisableStructs [ gActiveBank ] . truantUnknownBit )
gDisableStructs [ gActiveBank ] . truantCounter = 1 ;
gDisableStructs [ gActiveBank ] . truantUnknownBit = 0 ;
if ( AbilityBattleEffects ( ABILITYEFFECT_ON_SWITCHIN , gActiveBank , 0 , 0 , 0 ) = = 0 & &
ItemBattleEffects ( 0 , gActiveBank , 0 ) = = 0 )
{
gSideAffecting [ GetBankSide ( gActiveBank ) ] & = ~ ( SIDE_STATUS_SPIKES_DAMAGED ) ;
for ( i = 0 ; i < gNoOfAllBanks ; i + + )
{
2017-10-04 19:25:14 +02:00
if ( gBanksByTurnOrder [ i ] = = gActiveBank )
gActionsByTurnOrder [ i ] = ACTION_CANCEL_PARTNER ;
2017-09-25 00:09:13 +02:00
}
for ( i = 0 ; i < gNoOfAllBanks ; i + + )
{
2017-09-27 23:43:45 +02:00
u16 * hpOnSwitchout = & gBattleStruct - > hpOnSwitchout [ GetBankSide ( i ) ] ;
2017-09-25 00:09:13 +02:00
* hpOnSwitchout = gBattleMons [ i ] . hp ;
}
2017-09-28 15:34:21 +02:00
if ( gBattlescriptCurrInstr [ 1 ] = = 5 )
2017-09-25 00:09:13 +02:00
{
u32 hitmarkerFaintBits = gHitMarker > > 0x1C ;
gBank1 + + ;
while ( 1 )
{
if ( hitmarkerFaintBits & gBitTable [ gBank1 ] & & ! ( gAbsentBankFlags & gBitTable [ gBank1 ] ) )
break ;
if ( gBank1 > = gNoOfAllBanks )
break ;
gBank1 + + ;
}
}
gBattlescriptCurrInstr + = 2 ;
}
}
}
2017-11-25 18:42:31 +01:00
static void atk53_trainerslidein ( void )
2017-09-25 00:09:13 +02:00
{
2017-09-26 22:39:59 +02:00
gActiveBank = GetBankByIdentity ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-25 00:09:13 +02:00
EmitTrainerSlide ( 0 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 2 ;
}
2017-11-25 18:42:31 +01:00
static void atk54_playse ( void )
2017-09-25 00:09:13 +02:00
{
gActiveBank = gBankAttacker ;
2017-11-25 18:42:31 +01:00
EmitPlaySE ( 0 , BS2ScriptRead16 ( gBattlescriptCurrInstr + 1 ) ) ;
2017-09-25 00:09:13 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 3 ;
}
2017-11-25 18:42:31 +01:00
static void atk55_fanfare ( void )
2017-09-25 00:09:13 +02:00
{
gActiveBank = gBankAttacker ;
2017-10-14 11:34:26 +02:00
EmitPlayFanfareOrBGM ( 0 , BS2ScriptRead16 ( gBattlescriptCurrInstr + 1 ) , FALSE ) ;
2017-09-25 00:09:13 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 3 ;
}
2017-11-25 18:42:31 +01:00
static void atk56_playfaintcry ( void )
2017-09-25 00:09:13 +02:00
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-25 00:09:13 +02:00
EmitFaintingCry ( 0 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 2 ;
}
2017-09-28 15:34:21 +02:00
static void atk57 ( void )
2017-09-25 00:09:13 +02:00
{
2017-11-25 18:42:31 +01:00
gActiveBank = GetBankByIdentity ( IDENTITY_PLAYER_MON1 ) ;
2017-10-14 11:34:26 +02:00
EmitCmd55 ( 0 , gBattleOutcome ) ;
2017-09-25 00:09:13 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 1 ;
}
2017-11-25 18:42:31 +01:00
static void atk58_returntoball ( void )
2017-09-25 00:09:13 +02:00
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-10-14 11:34:26 +02:00
EmitReturnMonToBall ( 0 , 1 ) ;
2017-09-25 00:09:13 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 2 ;
}
2017-11-25 18:42:31 +01:00
static void atk59_handlelearnnewmove ( void )
2017-09-25 00:09:13 +02:00
{
2017-11-26 21:04:00 +01:00
const u8 * jumpPtr1 = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
const u8 * jumpPtr2 = BSScriptReadPtr ( gBattlescriptCurrInstr + 5 ) ;
2017-09-25 00:09:13 +02:00
2017-09-28 15:34:21 +02:00
u16 ret = MonTryLearningNewMove ( & gPlayerParty [ gBattleStruct - > expGetterId ] , gBattlescriptCurrInstr [ 9 ] ) ;
2017-09-25 00:09:13 +02:00
while ( ret = = 0xFFFE )
ret = MonTryLearningNewMove ( & gPlayerParty [ gBattleStruct - > expGetterId ] , 0 ) ;
if ( ret = = 0 )
{
gBattlescriptCurrInstr = jumpPtr2 ;
}
else if ( ret = = 0xFFFF )
{
gBattlescriptCurrInstr + = 10 ;
}
else
{
2017-11-26 13:26:58 +01:00
gActiveBank = GetBankByIdentity ( IDENTITY_PLAYER_MON1 ) ;
2017-09-25 00:09:13 +02:00
if ( gBattlePartyID [ gActiveBank ] = = gBattleStruct - > expGetterId
& & ! ( gBattleMons [ gActiveBank ] . status2 & STATUS2_TRANSFORMED ) )
{
GiveMoveToBattleMon ( & gBattleMons [ gActiveBank ] , ret ) ;
}
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
{
2017-11-26 13:26:58 +01:00
gActiveBank = GetBankByIdentity ( IDENTITY_PLAYER_MON2 ) ;
2017-09-25 00:09:13 +02:00
if ( gBattlePartyID [ gActiveBank ] = = gBattleStruct - > expGetterId
& & ! ( gBattleMons [ gActiveBank ] . status2 & STATUS2_TRANSFORMED ) )
{
GiveMoveToBattleMon ( & gBattleMons [ gActiveBank ] , ret ) ;
}
}
gBattlescriptCurrInstr = jumpPtr1 ;
}
}
2017-09-28 15:34:21 +02:00
static void atk5A_yesnoboxlearnmove ( void )
2017-09-25 00:09:13 +02:00
{
gActiveBank = 0 ;
switch ( gBattleScripting . learnMoveState )
{
case 0 :
2017-10-22 01:04:02 +02:00
HandleBattleWindow ( 0x18 , 8 , 0x1D , 0xD , 0 ) ;
BattleHandleAddTextPrinter ( gText_BattleYesNoChoice , 0xC ) ;
2017-09-25 00:09:13 +02:00
gBattleScripting . learnMoveState + + ;
gBattleCommunication [ CURSOR_POSITION ] = 0 ;
2017-10-21 17:32:35 +02:00
BattleCreateYesNoCursorAt ( 0 ) ;
2017-09-25 00:09:13 +02:00
break ;
case 1 :
if ( gMain . newKeys & DPAD_UP & & gBattleCommunication [ CURSOR_POSITION ] ! = 0 )
{
PlaySE ( SE_SELECT ) ;
2017-10-21 17:32:35 +02:00
BattleDestroyYesNoCursorAt ( gBattleCommunication [ CURSOR_POSITION ] ) ;
2017-09-25 00:09:13 +02:00
gBattleCommunication [ CURSOR_POSITION ] = 0 ;
2017-10-21 17:32:35 +02:00
BattleCreateYesNoCursorAt ( 0 ) ;
2017-09-25 00:09:13 +02:00
}
if ( gMain . newKeys & DPAD_DOWN & & gBattleCommunication [ CURSOR_POSITION ] = = 0 )
{
PlaySE ( SE_SELECT ) ;
2017-10-21 17:32:35 +02:00
BattleDestroyYesNoCursorAt ( gBattleCommunication [ CURSOR_POSITION ] ) ;
2017-09-25 00:09:13 +02:00
gBattleCommunication [ CURSOR_POSITION ] = 1 ;
2017-10-21 17:32:35 +02:00
BattleCreateYesNoCursorAt ( 1 ) ;
2017-09-25 00:09:13 +02:00
}
if ( gMain . newKeys & A_BUTTON )
{
PlaySE ( SE_SELECT ) ;
if ( gBattleCommunication [ 1 ] = = 0 )
{
2017-10-22 01:04:02 +02:00
HandleBattleWindow ( 0x18 , 0x8 , 0x1D , 0xD , WINDOW_CLEAR ) ;
2017-09-25 00:09:13 +02:00
BeginNormalPaletteFade ( - 1 , 0 , 0 , 0x10 , 0 ) ;
gBattleScripting . learnMoveState + + ;
}
else
{
gBattleScripting . learnMoveState = 5 ;
}
}
else if ( gMain . newKeys & B_BUTTON )
{
PlaySE ( SE_SELECT ) ;
gBattleScripting . learnMoveState = 5 ;
}
break ;
case 2 :
if ( ! gPaletteFade . active )
{
FreeAllWindowBuffers ( ) ;
sub_81BFA38 ( gPlayerParty , gBattleStruct - > expGetterId , gPlayerPartyCount - 1 , ReshowBattleScreenAfterMenu , gMoveToLearn ) ;
gBattleScripting . learnMoveState + + ;
}
break ;
case 3 :
if ( ! gPaletteFade . active & & gMain . callback2 = = BattleMainCB2 )
{
gBattleScripting . learnMoveState + + ;
}
break ;
case 4 :
if ( ! gPaletteFade . active & & gMain . callback2 = = BattleMainCB2 )
{
u8 movePosition = sub_81C1B94 ( ) ;
if ( movePosition = = 4 )
{
gBattleScripting . learnMoveState = 5 ;
}
else
{
u16 moveId = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_MOVE1 + movePosition ) ;
if ( IsHMMove2 ( moveId ) )
{
2017-10-07 15:15:47 +02:00
PrepareStringBattle ( STRINGID_HMMOVESCANTBEFORGOTTEN , gActiveBank ) ;
2017-09-25 00:09:13 +02:00
gBattleScripting . learnMoveState = 6 ;
}
else
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
PREPARE_MOVE_BUFFER ( gBattleTextBuff2 , moveId )
RemoveMonPPBonus ( & gPlayerParty [ gBattleStruct - > expGetterId ] , movePosition ) ;
SetMonMoveSlot ( & gPlayerParty [ gBattleStruct - > expGetterId ] , gMoveToLearn , movePosition ) ;
if ( gBattlePartyID [ 0 ] = = gBattleStruct - > expGetterId
& & ! ( gBattleMons [ 0 ] . status2 & STATUS2_TRANSFORMED )
& & ! ( gDisableStructs [ 0 ] . unk18_b & gBitTable [ movePosition ] ) )
{
RemoveBattleMonPPBonus ( & gBattleMons [ 0 ] , movePosition ) ;
SetBattleMonMoveSlot ( & gBattleMons [ 0 ] , gMoveToLearn , movePosition ) ;
}
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE
& & gBattlePartyID [ 2 ] = = gBattleStruct - > expGetterId
& & ! ( gBattleMons [ 2 ] . status2 & STATUS2_TRANSFORMED )
& & ! ( gDisableStructs [ 2 ] . unk18_b & gBitTable [ movePosition ] ) )
{
RemoveBattleMonPPBonus ( & gBattleMons [ 2 ] , movePosition ) ;
SetBattleMonMoveSlot ( & gBattleMons [ 2 ] , gMoveToLearn , movePosition ) ;
}
}
}
}
break ;
case 5 :
2017-10-22 01:04:02 +02:00
HandleBattleWindow ( 0x18 , 8 , 0x1D , 0xD , WINDOW_CLEAR ) ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + = 5 ;
break ;
case 6 :
if ( gBattleExecBuffer = = 0 )
{
gBattleScripting . learnMoveState = 2 ;
}
break ;
}
}
2017-09-28 15:34:21 +02:00
static void atk5B_yesnoboxstoplearningmove ( void )
2017-09-25 00:09:13 +02:00
{
switch ( gBattleScripting . learnMoveState )
{
case 0 :
2017-10-22 01:04:02 +02:00
HandleBattleWindow ( 0x18 , 8 , 0x1D , 0xD , 0 ) ;
BattleHandleAddTextPrinter ( gText_BattleYesNoChoice , 0xC ) ;
2017-09-25 00:09:13 +02:00
gBattleScripting . learnMoveState + + ;
gBattleCommunication [ CURSOR_POSITION ] = 0 ;
2017-10-21 17:32:35 +02:00
BattleCreateYesNoCursorAt ( 0 ) ;
2017-09-25 00:09:13 +02:00
break ;
case 1 :
if ( gMain . newKeys & DPAD_UP & & gBattleCommunication [ CURSOR_POSITION ] ! = 0 )
{
PlaySE ( SE_SELECT ) ;
2017-10-21 17:32:35 +02:00
BattleDestroyYesNoCursorAt ( gBattleCommunication [ CURSOR_POSITION ] ) ;
2017-09-25 00:09:13 +02:00
gBattleCommunication [ CURSOR_POSITION ] = 0 ;
2017-10-21 17:32:35 +02:00
BattleCreateYesNoCursorAt ( 0 ) ;
2017-09-25 00:09:13 +02:00
}
if ( gMain . newKeys & DPAD_DOWN & & gBattleCommunication [ CURSOR_POSITION ] = = 0 )
{
PlaySE ( SE_SELECT ) ;
2017-10-21 17:32:35 +02:00
BattleDestroyYesNoCursorAt ( gBattleCommunication [ CURSOR_POSITION ] ) ;
2017-09-25 00:09:13 +02:00
gBattleCommunication [ CURSOR_POSITION ] = 1 ;
2017-10-21 17:32:35 +02:00
BattleCreateYesNoCursorAt ( 1 ) ;
2017-09-25 00:09:13 +02:00
}
if ( gMain . newKeys & A_BUTTON )
{
PlaySE ( SE_SELECT ) ;
if ( gBattleCommunication [ 1 ] ! = 0 )
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
else
gBattlescriptCurrInstr + = 5 ;
2017-10-22 01:04:02 +02:00
HandleBattleWindow ( 0x18 , 0x8 , 0x1D , 0xD , WINDOW_CLEAR ) ;
2017-09-25 00:09:13 +02:00
}
else if ( gMain . newKeys & B_BUTTON )
{
PlaySE ( SE_SELECT ) ;
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
2017-10-22 01:04:02 +02:00
HandleBattleWindow ( 0x18 , 0x8 , 0x1D , 0xD , WINDOW_CLEAR ) ;
2017-09-25 00:09:13 +02:00
}
break ;
}
}
2017-09-28 15:34:21 +02:00
static void atk5C_hitanimation ( void )
2017-09-25 00:09:13 +02:00
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-25 00:09:13 +02:00
if ( gBattleMoveFlags & MOVESTATUS_NOEFFECT )
{
gBattlescriptCurrInstr + = 2 ;
}
else if ( ! ( gHitMarker & HITMARKER_IGNORE_SUBSTITUTE ) | | ! ( gBattleMons [ gActiveBank ] . status2 & STATUS2_SUBSTITUTE ) | | gDisableStructs [ gActiveBank ] . substituteHP = = 0 )
{
EmitHitAnimation ( 0 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 2 ;
}
else
{
gBattlescriptCurrInstr + = 2 ;
}
}
static u32 GetTrainerMoneyToGive ( u16 trainerId )
{
u32 i = 0 ;
u32 lastMonLevel = 0 ;
u32 moneyReward = 0 ;
if ( trainerId = = SECRET_BASE_OPPONENT )
{
moneyReward = 20 * gBattleResources - > secretBase - > partyLevels [ 0 ] * gBattleStruct - > moneyMultiplier ;
}
else
{
switch ( gTrainers [ trainerId ] . partyFlags )
{
case 0 :
{
const struct TrainerMonNoItemDefaultMoves * party = gTrainers [ trainerId ] . party . NoItemDefaultMoves ;
lastMonLevel = party [ gTrainers [ trainerId ] . partySize - 1 ] . lvl ;
}
break ;
case PARTY_FLAG_CUSTOM_MOVES :
{
const struct TrainerMonNoItemCustomMoves * party = gTrainers [ trainerId ] . party . NoItemCustomMoves ;
lastMonLevel = party [ gTrainers [ trainerId ] . partySize - 1 ] . lvl ;
}
break ;
case PARTY_FLAG_HAS_ITEM :
{
const struct TrainerMonItemDefaultMoves * party = gTrainers [ trainerId ] . party . ItemDefaultMoves ;
lastMonLevel = party [ gTrainers [ trainerId ] . partySize - 1 ] . lvl ;
}
break ;
case PARTY_FLAG_CUSTOM_MOVES | PARTY_FLAG_HAS_ITEM :
{
const struct TrainerMonItemCustomMoves * party = gTrainers [ trainerId ] . party . ItemCustomMoves ;
lastMonLevel = party [ gTrainers [ trainerId ] . partySize - 1 ] . lvl ;
}
break ;
}
for ( ; gTrainerMoneyTable [ i ] . classId ! = 0xFF ; i + + )
{
if ( gTrainerMoneyTable [ i ] . classId = = gTrainers [ trainerId ] . trainerClass )
break ;
}
if ( gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS )
moneyReward = 4 * lastMonLevel * gBattleStruct - > moneyMultiplier * gTrainerMoneyTable [ i ] . value ;
else if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
moneyReward = 4 * lastMonLevel * gBattleStruct - > moneyMultiplier * 2 * gTrainerMoneyTable [ i ] . value ;
else
moneyReward = 4 * lastMonLevel * gBattleStruct - > moneyMultiplier * gTrainerMoneyTable [ i ] . value ;
}
return moneyReward ;
}
2017-09-28 15:34:21 +02:00
static void atk5D_getmoneyreward ( void )
2017-09-25 00:09:13 +02:00
{
u32 moneyReward = GetTrainerMoneyToGive ( gTrainerBattleOpponent_A ) ;
if ( gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS )
moneyReward + = GetTrainerMoneyToGive ( gTrainerBattleOpponent_B ) ;
AddMoney ( & gSaveBlock1Ptr - > money , moneyReward ) ;
PREPARE_WORD_NUMBER_BUFFER ( gBattleTextBuff1 , 5 , moneyReward )
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atk5E ( void )
2017-09-25 00:09:13 +02:00
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-25 00:09:13 +02:00
switch ( gBattleCommunication [ 0 ] )
{
case 0 :
2017-09-26 22:39:59 +02:00
EmitGetMonData ( 0 , REQUEST_ALL_BATTLE , 0 ) ;
2017-09-25 00:09:13 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
gBattleCommunication [ 0 ] + + ;
break ;
case 1 :
if ( gBattleExecBuffer = = 0 )
{
s32 i ;
struct BattlePokemon * bufferPoke = ( struct BattlePokemon * ) & gBattleBufferB [ gActiveBank ] [ 4 ] ;
for ( i = 0 ; i < 4 ; i + + )
{
gBattleMons [ gActiveBank ] . moves [ i ] = bufferPoke - > moves [ i ] ;
gBattleMons [ gActiveBank ] . pp [ i ] = bufferPoke - > pp [ i ] ;
}
gBattlescriptCurrInstr + = 2 ;
}
break ;
}
}
2017-11-25 18:42:31 +01:00
static void atk5F ( void )
2017-09-25 00:09:13 +02:00
{
gActiveBank = gBankAttacker ;
gBankAttacker = gBankTarget ;
gBankTarget = gActiveBank ;
if ( gHitMarker & HITMARKER_PURSUIT_TRAP )
gHitMarker & = ~ ( HITMARKER_PURSUIT_TRAP ) ;
else
gHitMarker | = HITMARKER_PURSUIT_TRAP ;
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atk60_incrementgamestat ( void )
2017-09-25 00:09:13 +02:00
{
if ( GetBankSide ( gBankAttacker ) = = SIDE_PLAYER )
2017-09-28 15:34:21 +02:00
IncrementGameStat ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + = 2 ;
}
2017-11-25 18:42:31 +01:00
static void atk61_drawpartystatussummary ( void )
2017-09-25 00:09:13 +02:00
{
s32 i ;
struct Pokemon * party ;
struct HpAndStatus hpStatuses [ 6 ] ;
if ( gBattleExecBuffer )
return ;
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-25 00:09:13 +02:00
if ( GetBankSide ( gActiveBank ) = = SIDE_PLAYER )
party = gPlayerParty ;
else
party = gEnemyParty ;
for ( i = 0 ; i < 6 ; i + + )
{
if ( GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) = = SPECIES_NONE
| | GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) = = SPECIES_EGG )
{
hpStatuses [ i ] . hp = 0xFFFF ;
hpStatuses [ i ] . status = 0 ;
}
else
{
hpStatuses [ i ] . hp = GetMonData ( & party [ i ] , MON_DATA_HP ) ;
hpStatuses [ i ] . status = GetMonData ( & party [ i ] , MON_DATA_STATUS ) ;
}
}
2017-10-02 23:32:39 +02:00
EmitDrawPartyStatusSummary ( 0 , hpStatuses , 1 ) ;
2017-09-25 00:09:13 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 2 ;
}
2017-11-25 18:42:31 +01:00
static void atk62 ( void )
2017-09-25 00:09:13 +02:00
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-25 00:09:13 +02:00
EmitCmd49 ( 0 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 2 ;
}
2017-09-28 15:34:21 +02:00
static void atk63_jumptorandomattack ( void )
2017-09-25 00:09:13 +02:00
{
2017-12-02 00:03:46 +01:00
if ( gBattlescriptCurrInstr [ 1 ] )
2017-09-25 00:09:13 +02:00
gCurrentMove = gRandomMove ;
else
2017-11-26 18:07:00 +01:00
gChosenMove = gCurrentMove = gRandomMove ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr = gBattleScriptsForMoveEffects [ gBattleMoves [ gCurrentMove ] . effect ] ;
}
2017-09-28 15:34:21 +02:00
static void atk64_statusanimation ( void )
2017-09-25 00:09:13 +02:00
{
if ( gBattleExecBuffer = = 0 )
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-25 00:09:13 +02:00
if ( ! ( gStatuses3 [ gActiveBank ] & STATUS3_SEMI_INVULNERABLE )
& & gDisableStructs [ gActiveBank ] . substituteHP = = 0
& & ! ( gHitMarker & HITMARKER_NO_ANIMATIONS ) )
{
EmitStatusAnimation ( 0 , FALSE , gBattleMons [ gActiveBank ] . status1 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
}
gBattlescriptCurrInstr + = 2 ;
}
}
2017-09-28 15:34:21 +02:00
static void atk65_status2animation ( void )
2017-09-25 00:09:13 +02:00
{
u32 wantedToAnimate ;
if ( gBattleExecBuffer = = 0 )
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-25 00:09:13 +02:00
wantedToAnimate = BSScriptRead32 ( gBattlescriptCurrInstr + 2 ) ;
if ( ! ( gStatuses3 [ gActiveBank ] & STATUS3_SEMI_INVULNERABLE )
& & gDisableStructs [ gActiveBank ] . substituteHP = = 0
& & ! ( gHitMarker & HITMARKER_NO_ANIMATIONS ) )
{
EmitStatusAnimation ( 0 , TRUE , gBattleMons [ gActiveBank ] . status2 & wantedToAnimate ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
}
gBattlescriptCurrInstr + = 6 ;
}
}
2017-09-28 15:34:21 +02:00
static void atk66_chosenstatusanimation ( void )
2017-09-25 00:09:13 +02:00
{
u32 wantedStatus ;
if ( gBattleExecBuffer = = 0 )
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-25 00:09:13 +02:00
wantedStatus = BSScriptRead32 ( gBattlescriptCurrInstr + 3 ) ;
if ( ! ( gStatuses3 [ gActiveBank ] & STATUS3_SEMI_INVULNERABLE )
& & gDisableStructs [ gActiveBank ] . substituteHP = = 0
& & ! ( gHitMarker & HITMARKER_NO_ANIMATIONS ) )
{
2017-09-28 15:34:21 +02:00
EmitStatusAnimation ( 0 , gBattlescriptCurrInstr [ 2 ] , wantedStatus ) ;
2017-09-25 00:09:13 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
}
gBattlescriptCurrInstr + = 7 ;
}
}
2017-09-28 15:34:21 +02:00
static void atk67_yesnobox ( void )
2017-09-25 00:09:13 +02:00
{
switch ( gBattleCommunication [ 0 ] )
{
case 0 :
2017-10-22 01:04:02 +02:00
HandleBattleWindow ( 0x18 , 8 , 0x1D , 0xD , 0 ) ;
BattleHandleAddTextPrinter ( gText_BattleYesNoChoice , 0xC ) ;
2017-09-25 00:09:13 +02:00
gBattleCommunication [ 0 ] + + ;
gBattleCommunication [ CURSOR_POSITION ] = 0 ;
2017-10-21 17:32:35 +02:00
BattleCreateYesNoCursorAt ( 0 ) ;
2017-09-25 00:09:13 +02:00
break ;
case 1 :
if ( gMain . newKeys & DPAD_UP & & gBattleCommunication [ CURSOR_POSITION ] ! = 0 )
{
PlaySE ( SE_SELECT ) ;
2017-10-21 17:32:35 +02:00
BattleDestroyYesNoCursorAt ( gBattleCommunication [ CURSOR_POSITION ] ) ;
2017-09-25 00:09:13 +02:00
gBattleCommunication [ CURSOR_POSITION ] = 0 ;
2017-10-21 17:32:35 +02:00
BattleCreateYesNoCursorAt ( 0 ) ;
2017-09-25 00:09:13 +02:00
}
if ( gMain . newKeys & DPAD_DOWN & & gBattleCommunication [ CURSOR_POSITION ] = = 0 )
{
PlaySE ( SE_SELECT ) ;
2017-10-21 17:32:35 +02:00
BattleDestroyYesNoCursorAt ( gBattleCommunication [ CURSOR_POSITION ] ) ;
2017-09-25 00:09:13 +02:00
gBattleCommunication [ CURSOR_POSITION ] = 1 ;
2017-10-21 17:32:35 +02:00
BattleCreateYesNoCursorAt ( 1 ) ;
2017-09-25 00:09:13 +02:00
}
if ( gMain . newKeys & B_BUTTON )
{
gBattleCommunication [ CURSOR_POSITION ] = 1 ;
PlaySE ( SE_SELECT ) ;
2017-10-22 01:04:02 +02:00
HandleBattleWindow ( 0x18 , 8 , 0x1D , 0xD , WINDOW_CLEAR ) ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + + ;
}
else if ( gMain . newKeys & A_BUTTON )
{
PlaySE ( SE_SELECT ) ;
2017-10-22 01:04:02 +02:00
HandleBattleWindow ( 0x18 , 8 , 0x1D , 0xD , WINDOW_CLEAR ) ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + + ;
}
break ;
}
}
2017-11-25 18:42:31 +01:00
static void atk68_cancelallactions ( void )
2017-09-25 00:09:13 +02:00
{
s32 i ;
for ( i = 0 ; i < gNoOfAllBanks ; i + + )
2017-10-04 19:25:14 +02:00
gActionsByTurnOrder [ i ] = ACTION_CANCEL_PARTNER ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atk69_adjustsetdamage ( void ) // The same as 0x7, except there's no random damage multiplier.
2017-09-25 00:09:13 +02:00
{
u8 holdEffect , quality ;
if ( gBattleMons [ gBankTarget ] . item = = ITEM_ENIGMA_BERRY )
{
holdEffect = gEnigmaBerries [ gBankTarget ] . holdEffect , quality = gEnigmaBerries [ gBankTarget ] . holdEffectParam ;
}
else
{
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ gBankTarget ] . item ) ;
quality = ItemId_GetHoldEffectParam ( gBattleMons [ gBankTarget ] . item ) ;
}
gStringBank = gBankTarget ;
if ( holdEffect = = HOLD_EFFECT_FOCUS_BAND & & ( Random ( ) % 100 ) < quality )
{
RecordItemEffectBattle ( gBankTarget , holdEffect ) ;
gSpecialStatuses [ gBankTarget ] . focusBanded = 1 ;
}
if ( gBattleMons [ gBankTarget ] . status2 & STATUS2_SUBSTITUTE )
goto END ;
if ( gBattleMoves [ gCurrentMove ] . effect ! = EFFECT_FALSE_SWIPE & & ! gProtectStructs [ gBankTarget ] . endured
& & ! gSpecialStatuses [ gBankTarget ] . focusBanded )
goto END ;
if ( gBattleMons [ gBankTarget ] . hp > gBattleMoveDamage )
goto END ;
gBattleMoveDamage = gBattleMons [ gBankTarget ] . hp - 1 ;
if ( gProtectStructs [ gBankTarget ] . endured )
{
gBattleMoveFlags | = MOVESTATUS_ENDURED ;
}
else if ( gSpecialStatuses [ gBankTarget ] . focusBanded )
{
gBattleMoveFlags | = MOVESTATUS_HUNGON ;
gLastUsedItem = gBattleMons [ gBankTarget ] . item ;
}
END :
gBattlescriptCurrInstr + + ;
}
2017-09-26 22:39:59 +02:00
2017-09-28 15:34:21 +02:00
static void atk6A_removeitem ( void )
2017-09-26 22:39:59 +02:00
{
u16 * usedHeldItem ;
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-26 22:39:59 +02:00
2017-09-27 23:43:45 +02:00
usedHeldItem = & gBattleStruct - > usedHeldItems [ gActiveBank ] ;
2017-09-26 22:39:59 +02:00
* usedHeldItem = gBattleMons [ gActiveBank ] . item ;
gBattleMons [ gActiveBank ] . item = 0 ;
EmitSetMonData ( 0 , REQUEST_HELDITEM_BATTLE , 0 , 2 , & gBattleMons [ gActiveBank ] . item ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 2 ;
}
2017-09-28 15:34:21 +02:00
static void atk6B_atknameinbuff1 ( void )
2017-09-26 22:39:59 +02:00
{
PREPARE_MON_NICK_BUFFER ( gBattleTextBuff1 , gBankAttacker , gBattlePartyID [ gBankAttacker ] )
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atk6C_drawlvlupbox ( void )
2017-09-26 22:39:59 +02:00
{
if ( gBattleScripting . atk6C_state = = 0 )
{
if ( IsMonGettingExpSentOut ( ) )
gBattleScripting . atk6C_state = 3 ;
else
gBattleScripting . atk6C_state = 1 ;
}
switch ( gBattleScripting . atk6C_state )
{
case 1 :
gBattle_BG2_Y = 0x60 ;
SetBgAttribute ( 2 , BG_CTRL_ATTR_MOSAIC , 0 ) ;
ShowBg ( 2 ) ;
sub_804F17C ( ) ;
gBattleScripting . atk6C_state = 2 ;
break ;
case 2 :
if ( ! sub_804F1CC ( ) )
gBattleScripting . atk6C_state = 3 ;
break ;
case 3 :
gBattle_BG1_X = 0 ;
gBattle_BG1_Y = 0x100 ;
SetBgAttribute ( 0 , BG_CTRL_ATTR_MOSAIC , 1 ) ;
SetBgAttribute ( 1 , BG_CTRL_ATTR_MOSAIC , 0 ) ;
ShowBg ( 0 ) ;
ShowBg ( 1 ) ;
2017-10-22 01:04:02 +02:00
HandleBattleWindow ( 0x12 , 7 , 0x1D , 0x13 , WINDOW_x80 ) ;
2017-09-26 22:39:59 +02:00
gBattleScripting . atk6C_state = 4 ;
break ;
case 4 :
sub_804F100 ( ) ;
PutWindowTilemap ( 13 ) ;
CopyWindowToVram ( 13 , 3 ) ;
gBattleScripting . atk6C_state + + ;
break ;
case 5 :
case 7 :
if ( ! IsDma3ManagerBusyWithBgCopy ( ) )
{
gBattle_BG1_Y = 0 ;
gBattleScripting . atk6C_state + + ;
}
break ;
case 6 :
if ( gMain . newKeys ! = 0 )
{
PlaySE ( SE_SELECT ) ;
sub_804F144 ( ) ;
CopyWindowToVram ( 13 , 2 ) ;
gBattleScripting . atk6C_state + + ;
}
break ;
case 8 :
if ( gMain . newKeys ! = 0 )
{
PlaySE ( SE_SELECT ) ;
2017-10-22 01:04:02 +02:00
HandleBattleWindow ( 0x12 , 7 , 0x1D , 0x13 , WINDOW_x80 | WINDOW_CLEAR ) ;
2017-09-26 22:39:59 +02:00
gBattleScripting . atk6C_state + + ;
}
break ;
case 9 :
if ( ! sub_804F344 ( ) )
{
ClearWindowTilemap ( 14 ) ;
CopyWindowToVram ( 14 , 1 ) ;
ClearWindowTilemap ( 13 ) ;
CopyWindowToVram ( 13 , 1 ) ;
SetBgAttribute ( 2 , BG_CTRL_ATTR_MOSAIC , 2 ) ;
ShowBg ( 2 ) ;
gBattleScripting . atk6C_state = 10 ;
}
break ;
case 10 :
if ( ! IsDma3ManagerBusyWithBgCopy ( ) )
{
SetBgAttribute ( 0 , BG_CTRL_ATTR_MOSAIC , 0 ) ;
SetBgAttribute ( 1 , BG_CTRL_ATTR_MOSAIC , 1 ) ;
ShowBg ( 0 ) ;
ShowBg ( 1 ) ;
gBattlescriptCurrInstr + + ;
}
break ;
}
}
2017-09-28 15:34:21 +02:00
static void sub_804F100 ( void )
2017-09-26 22:39:59 +02:00
{
struct StatsArray currentStats ;
sub_81D388C ( & gPlayerParty [ gBattleStruct - > expGetterId ] , & currentStats ) ;
sub_81D3640 ( 0xD , gBattleResources - > statsBeforeLvlUp , & currentStats , 0xE , 0xD , 0xF ) ;
}
2017-09-28 15:34:21 +02:00
static void sub_804F144 ( void )
2017-09-26 22:39:59 +02:00
{
struct StatsArray currentStats ;
sub_81D388C ( & gPlayerParty [ gBattleStruct - > expGetterId ] , & currentStats ) ;
sub_81D3784 ( 0xD , & currentStats , 0xE , 0xD , 0xF ) ;
}
2017-09-28 15:34:21 +02:00
static void sub_804F17C ( void )
2017-09-26 22:39:59 +02:00
{
gBattle_BG2_Y = 0 ;
gBattle_BG2_X = 0x1A0 ;
2017-09-28 16:51:24 +02:00
LoadPalette ( sUnknown_0831C2C8 , 0x60 , 0x20 ) ;
CopyToWindowPixelBuffer ( 14 , sUnknown_0831C2E8 , 0 , 0 ) ;
2017-09-26 22:39:59 +02:00
PutWindowTilemap ( 14 ) ;
CopyWindowToVram ( 14 , 3 ) ;
PutMonIconOnLvlUpBox ( ) ;
}
2017-09-28 15:34:21 +02:00
static bool8 sub_804F1CC ( void )
2017-09-26 22:39:59 +02:00
{
if ( IsDma3ManagerBusyWithBgCopy ( ) )
return TRUE ;
if ( gBattle_BG2_X = = 0x200 )
return FALSE ;
if ( gBattle_BG2_X = = 0x1A0 )
PutLevelAndGenderOnLvlUpBox ( ) ;
gBattle_BG2_X + = 8 ;
if ( gBattle_BG2_X > = 0x200 )
gBattle_BG2_X = 0x200 ;
return ( gBattle_BG2_X ! = 0x200 ) ;
}
2017-09-28 15:34:21 +02:00
static void PutLevelAndGenderOnLvlUpBox ( void )
2017-09-26 22:39:59 +02:00
{
u16 monLevel ;
u8 monGender ;
struct TextSubPrinter subPrinter ;
u8 * txtPtr ;
u32 var ;
monLevel = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_LEVEL ) ;
monGender = GetMonGender ( & gPlayerParty [ gBattleStruct - > expGetterId ] ) ;
GetMonNickname ( & gPlayerParty [ gBattleStruct - > expGetterId ] , gStringVar4 ) ;
subPrinter . current_text_offset = gStringVar4 ;
subPrinter . windowId = 14 ;
subPrinter . fontId = 0 ;
subPrinter . x = 32 ;
subPrinter . y = 0 ;
subPrinter . currentX = 32 ;
subPrinter . currentY = 0 ;
subPrinter . letterSpacing = 0 ;
subPrinter . lineSpacing = 0 ;
subPrinter . fontColor_l = TEXT_COLOR_TRANSPARENT ;
subPrinter . fontColor_h = TEXT_COLOR_WHITE ;
subPrinter . bgColor = TEXT_COLOR_TRANSPARENT ;
subPrinter . shadowColor = TEXT_COLOR_DARK_GREY ;
AddTextPrinter ( & subPrinter , 0xFF , NULL ) ;
txtPtr = gStringVar4 ;
gStringVar4 [ 0 ] = CHAR_SPECIAL_F9 ;
txtPtr + + ;
txtPtr [ 0 ] = 5 ;
txtPtr + + ;
var = ( u32 ) ( txtPtr ) ;
txtPtr = ConvertIntToDecimalStringN ( txtPtr , monLevel , STR_CONV_MODE_LEFT_ALIGN , 3 ) ;
var = ( u32 ) ( txtPtr ) - var ;
txtPtr = StringFill ( txtPtr , 0x77 , 4 - var ) ;
if ( monGender ! = MON_GENDERLESS )
{
if ( monGender = = MON_MALE )
{
txtPtr = WriteColorChangeControlCode ( txtPtr , 0 , 0xC ) ;
txtPtr = WriteColorChangeControlCode ( txtPtr , 1 , 0xD ) ;
* ( txtPtr + + ) = CHAR_MALE ;
}
else
{
txtPtr = WriteColorChangeControlCode ( txtPtr , 0 , 0xE ) ;
txtPtr = WriteColorChangeControlCode ( txtPtr , 1 , 0xF ) ;
* ( txtPtr + + ) = CHAR_FEMALE ;
}
* ( txtPtr + + ) = EOS ;
}
subPrinter . y = 10 ;
subPrinter . currentY = 10 ;
AddTextPrinter ( & subPrinter , 0xFF , NULL ) ;
CopyWindowToVram ( 14 , 2 ) ;
}
2017-09-28 15:34:21 +02:00
static bool8 sub_804F344 ( void )
2017-09-26 22:39:59 +02:00
{
if ( gBattle_BG2_X = = 0x1A0 )
return FALSE ;
if ( gBattle_BG2_X - 16 < 0x1A0 )
gBattle_BG2_X = 0x1A0 ;
else
gBattle_BG2_X - = 16 ;
return ( gBattle_BG2_X ! = 0x1A0 ) ;
}
# define sDestroy data0
# define sSavedLvlUpBoxXPosition data1
2017-09-28 15:34:21 +02:00
static void PutMonIconOnLvlUpBox ( void )
2017-09-26 22:39:59 +02:00
{
u8 spriteId ;
const u16 * iconPal ;
struct SpriteSheet iconSheet ;
struct SpritePalette iconPalSheet ;
u16 species = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_SPECIES ) ;
u32 personality = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterId ] , MON_DATA_PERSONALITY ) ;
const u8 * iconPtr = GetMonIconPtr ( species , personality , 1 ) ;
iconSheet . data = iconPtr ;
iconSheet . size = 0x200 ;
iconSheet . tag = MON_ICON_LVLUP_BOX_TAG ;
iconPal = GetValidMonIconPalettePtr ( species ) ;
iconPalSheet . data = iconPal ;
iconPalSheet . tag = MON_ICON_LVLUP_BOX_TAG ;
LoadSpriteSheet ( & iconSheet ) ;
LoadSpritePalette ( & iconPalSheet ) ;
2017-09-28 16:51:24 +02:00
spriteId = CreateSprite ( & sSpriteTemplate_MonIconOnLvlUpBox , 256 , 10 , 0 ) ;
2017-09-26 22:39:59 +02:00
gSprites [ spriteId ] . sDestroy = FALSE ;
gSprites [ spriteId ] . sSavedLvlUpBoxXPosition = gBattle_BG2_X ;
}
2017-09-28 16:32:23 +02:00
static void SpriteCB_MonIconOnLvlUpBox ( struct Sprite * sprite )
2017-09-26 22:39:59 +02:00
{
sprite - > pos2 . x = sprite - > sSavedLvlUpBoxXPosition - gBattle_BG2_X ;
if ( sprite - > pos2 . x ! = 0 )
{
sprite - > sDestroy = TRUE ;
}
else if ( sprite - > sDestroy )
{
DestroySprite ( sprite ) ;
FreeSpriteTilesByTag ( MON_ICON_LVLUP_BOX_TAG ) ;
FreeSpritePaletteByTag ( MON_ICON_LVLUP_BOX_TAG ) ;
}
}
# undef sDestroy
# undef sSavedLvlUpBoxXPosition
2017-09-28 15:34:21 +02:00
static bool32 IsMonGettingExpSentOut ( void )
2017-09-26 22:39:59 +02:00
{
if ( gBattlePartyID [ 0 ] = = gBattleStruct - > expGetterId )
return TRUE ;
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE & & gBattlePartyID [ 2 ] = = gBattleStruct - > expGetterId )
return TRUE ;
return FALSE ;
}
2017-11-25 18:42:31 +01:00
static void atk6D_resetsentmonsvalue ( void )
2017-09-26 22:39:59 +02:00
{
ResetSentPokesToOpponentValue ( ) ;
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atk6E_setatktoplayer0 ( void )
2017-09-26 22:39:59 +02:00
{
2017-11-26 13:26:58 +01:00
gBankAttacker = GetBankByIdentity ( IDENTITY_PLAYER_MON1 ) ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atk6F_makevisible ( void )
2017-09-26 22:39:59 +02:00
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-26 22:39:59 +02:00
EmitSpriteInvisibility ( 0 , FALSE ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 2 ;
}
2017-11-25 18:42:31 +01:00
static void atk70_recordlastability ( void )
2017-09-26 22:39:59 +02:00
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-26 22:39:59 +02:00
RecordAbilityBattle ( gActiveBank , gLastUsedAbility ) ;
gBattlescriptCurrInstr + = 1 ; // UB: Should be + 2, one byte for command and one byte for bank argument.
}
void BufferMoveToLearnIntoBattleTextBuff2 ( void )
{
PREPARE_MOVE_BUFFER ( gBattleTextBuff2 , gMoveToLearn ) ;
}
2017-11-25 18:42:31 +01:00
static void atk71_buffermovetolearn ( void )
2017-09-26 22:39:59 +02:00
{
BufferMoveToLearnIntoBattleTextBuff2 ( ) ;
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atk72_jumpifplayerran ( void )
2017-09-26 22:39:59 +02:00
{
2017-10-06 00:12:01 +02:00
if ( TryRunFromBattle ( gBank1 ) )
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
else
gBattlescriptCurrInstr + = 5 ;
}
2017-11-25 18:42:31 +01:00
static void atk73_hpthresholds ( void )
2017-09-26 22:39:59 +02:00
{
u8 opposingBank ;
s32 result ;
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE ) )
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-26 22:39:59 +02:00
opposingBank = gActiveBank ^ BIT_SIDE ;
result = gBattleMons [ opposingBank ] . hp * 100 / gBattleMons [ opposingBank ] . maxHP ;
if ( result = = 0 )
result = 1 ;
if ( result > 69 | | ! gBattleMons [ opposingBank ] . hp )
gBattleStruct - > hpScale = 0 ;
else if ( result > 39 )
gBattleStruct - > hpScale = 1 ;
else if ( result > 9 )
gBattleStruct - > hpScale = 2 ;
else
gBattleStruct - > hpScale = 3 ;
}
gBattlescriptCurrInstr + = 2 ;
}
2017-11-25 18:42:31 +01:00
static void atk74_hpthresholds2 ( void )
2017-09-26 22:39:59 +02:00
{
u8 opposingBank ;
s32 result ;
u8 hpSwitchout ;
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE ) )
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-26 22:39:59 +02:00
opposingBank = gActiveBank ^ BIT_SIDE ;
hpSwitchout = * ( gBattleStruct - > hpOnSwitchout + GetBankSide ( opposingBank ) ) ;
result = ( hpSwitchout - gBattleMons [ opposingBank ] . hp ) * 100 / hpSwitchout ;
if ( gBattleMons [ opposingBank ] . hp > = hpSwitchout )
gBattleStruct - > hpScale = 0 ;
else if ( result < = 29 )
gBattleStruct - > hpScale = 1 ;
else if ( result < = 69 )
gBattleStruct - > hpScale = 2 ;
else
gBattleStruct - > hpScale = 3 ;
}
gBattlescriptCurrInstr + = 2 ;
}
2017-11-25 18:42:31 +01:00
static void atk75_useitemonopponent ( void )
2017-09-26 22:39:59 +02:00
{
gBankInMenu = gBankAttacker ;
ExecuteTableBasedItemEffect ( & gEnemyParty [ gBattlePartyID [ gBankAttacker ] ] , gLastUsedItem , gBattlePartyID [ gBankAttacker ] , 0 , 1 ) ;
gBattlescriptCurrInstr + = 1 ;
}
2017-09-28 15:34:21 +02:00
static void atk76_various ( void )
2017-09-26 22:39:59 +02:00
{
u8 side ;
s32 i ;
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
switch ( gBattlescriptCurrInstr [ 2 ] )
{
case VARIOUS_CANCEL_MULTI_TURN_MOVES :
CancelMultiTurnMoves ( gActiveBank ) ;
break ;
case VARIOUS_SET_MAGIC_COAT_TARGET :
gBankAttacker = gBankTarget ;
2017-11-25 18:42:31 +01:00
side = GetBankSide ( gBankAttacker ) ^ BIT_SIDE ;
2017-09-26 22:39:59 +02:00
if ( gSideTimers [ side ] . followmeTimer ! = 0 & & gBattleMons [ gSideTimers [ side ] . followmeTarget ] . hp ! = 0 )
gBankTarget = gSideTimers [ side ] . followmeTarget ;
else
gBankTarget = gActiveBank ;
break ;
2017-11-25 18:42:31 +01:00
case VARIOUS_IS_RUNNING_IMPOSSIBLE :
2017-09-26 22:39:59 +02:00
gBattleCommunication [ 0 ] = IsRunningFromBattleImpossible ( ) ;
break ;
case VARIOUS_GET_MOVE_TARGET :
gBankTarget = GetMoveTarget ( gCurrentMove , 0 ) ;
break ;
case 4 :
if ( gHitMarker & HITMARKER_FAINTED ( gActiveBank ) )
gBattleCommunication [ 0 ] = 1 ;
else
gBattleCommunication [ 0 ] = 0 ;
break ;
case VARIOUS_RESET_INTIMIDATE_TRACE_BITS :
gSpecialStatuses [ gActiveBank ] . intimidatedPoke = 0 ;
gSpecialStatuses [ gActiveBank ] . traced = 0 ;
break ;
case VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP :
if ( gBattlePartyID [ 0 ] = = gBattleStruct - > expGetterId | | gBattlePartyID [ 2 ] = = gBattleStruct - > expGetterId )
{
u16 * choicedMove ;
if ( gBattlePartyID [ 0 ] = = gBattleStruct - > expGetterId )
gActiveBank = 0 ;
else
gActiveBank = 2 ;
choicedMove = & gBattleStruct - > choicedMove [ gActiveBank ] ;
for ( i = 0 ; i < 4 ; i + + )
{
if ( gBattleMons [ gActiveBank ] . moves [ i ] = = * choicedMove )
break ;
}
if ( i = = 4 )
* choicedMove = 0 ;
}
break ;
case 7 :
if ( ! ( gBattleTypeFlags & ( BATTLE_TYPE_LINK | BATTLE_TYPE_DOUBLE ) )
& & gBattleTypeFlags & BATTLE_TYPE_TRAINER
& & gBattleMons [ 0 ] . hp ! = 0
& & gBattleMons [ 1 ] . hp ! = 0 )
{
gHitMarker & = ~ ( HITMARKER_x400000 ) ;
}
break ;
case 8 :
gBattleCommunication [ 0 ] = 0 ;
gBattleScripting . bank = gActiveBank = gBattleCommunication [ 1 ] ;
if ( ! ( gBattleStruct - > field_92 & gBitTable [ gActiveBank ] )
& & gBattleMons [ gActiveBank ] . maxHP / 2 > = gBattleMons [ gActiveBank ] . hp
& & gBattleMons [ gActiveBank ] . hp ! = 0
& & ! ( gBattleMons [ gActiveBank ] . status1 & STATUS_SLEEP ) )
{
gBattleStruct - > field_92 | = gBitTable [ gActiveBank ] ;
gBattleCommunication [ 0 ] = 1 ;
2017-09-28 16:51:24 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = sUnknown_0831C4F8 [ GetNatureFromPersonality ( gBattleMons [ gActiveBank ] . personality ) ] ;
2017-09-26 22:39:59 +02:00
}
break ;
case 9 :
i = sub_81A5258 ( gBattleCommunication ) ;
if ( i = = 0 )
return ;
gBattleCommunication [ 1 ] = i ;
break ;
case 10 :
gBattleMons [ 1 ] . hp = 0 ;
gHitMarker | = HITMARKER_FAINTED ( 1 ) ;
gBattleStruct - > field_2A1 | = gBitTable [ gBattlePartyID [ 1 ] ] ;
gDisableStructs [ 1 ] . truantUnknownBit = 1 ;
break ;
case 11 :
gBattleMons [ 0 ] . hp = 0 ;
gHitMarker | = HITMARKER_FAINTED ( 0 ) ;
gHitMarker | = HITMARKER_x400000 ;
gBattleStruct - > field_2A0 | = gBitTable [ gBattlePartyID [ 0 ] ] ;
gDisableStructs [ 0 ] . truantUnknownBit = 1 ;
break ;
case 12 :
gBattleMons [ 0 ] . hp = 0 ;
gBattleMons [ 1 ] . hp = 0 ;
gHitMarker | = HITMARKER_FAINTED ( 0 ) ;
gHitMarker | = HITMARKER_FAINTED ( 1 ) ;
gHitMarker | = HITMARKER_x400000 ;
gBattleStruct - > field_2A0 | = gBitTable [ gBattlePartyID [ 0 ] ] ;
gBattleStruct - > field_2A1 | = gBitTable [ gBattlePartyID [ 1 ] ] ;
gDisableStructs [ 0 ] . truantUnknownBit = 1 ;
gDisableStructs [ 1 ] . truantUnknownBit = 1 ;
break ;
2017-10-22 01:04:02 +02:00
case VARIOUS_EMIT_YESNOBOX :
2017-10-22 18:43:15 +02:00
EmitUnknownYesNoBox ( 0 ) ;
2017-09-26 22:39:59 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
break ;
case 14 :
sub_81A5BF8 ( ) ;
break ;
case 15 :
sub_81A5D44 ( ) ;
break ;
case 16 :
BattleStringExpandPlaceholdersToDisplayedString ( gRefereeStringsTable [ gBattlescriptCurrInstr [ 1 ] ] ) ;
2017-10-22 01:04:02 +02:00
BattleHandleAddTextPrinter ( gDisplayedStringBattle , 0x16 ) ;
2017-09-26 22:39:59 +02:00
break ;
case 17 :
if ( IsTextPrinterActive ( 0x16 ) )
return ;
break ;
case VARIOUS_WAIT_CRY :
if ( ! IsCryFinished ( ) )
return ;
break ;
case VARIOUS_RETURN_OPPONENT_MON1 :
gActiveBank = 1 ;
if ( gBattleMons [ gActiveBank ] . hp ! = 0 )
{
2017-10-14 11:34:26 +02:00
EmitReturnMonToBall ( 0 , 0 ) ;
2017-09-26 22:39:59 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
}
break ;
case VARIOUS_RETURN_OPPONENT_MON2 :
if ( gNoOfAllBanks > 3 )
{
gActiveBank = 3 ;
if ( gBattleMons [ gActiveBank ] . hp ! = 0 )
{
2017-10-14 11:34:26 +02:00
EmitReturnMonToBall ( 0 , 0 ) ;
2017-09-26 22:39:59 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
}
}
break ;
case 21 :
m4aMPlayVolumeControl ( & gMPlay_BGM , 0xFFFF , 0x55 ) ;
break ;
case 22 :
m4aMPlayVolumeControl ( & gMPlay_BGM , 0xFFFF , 0x100 ) ;
break ;
case 23 :
gBattleStruct - > field_2A2 | = gBitTable [ gActiveBank ] ;
break ;
case 24 :
if ( sub_805725C ( gActiveBank ) )
return ;
break ;
case VARIOUS_SET_TELEPORT_OUTCOME :
if ( GetBankSide ( gActiveBank ) = = SIDE_PLAYER )
gBattleOutcome = BATTLE_PLAYER_TELEPORTED ;
else
gBattleOutcome = BATTLE_OPPONENT_TELEPORTED ;
break ;
case VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC :
2017-10-14 11:34:26 +02:00
EmitPlayFanfareOrBGM ( 0 , BGM_KACHI1 , TRUE ) ;
2017-09-26 22:39:59 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
break ;
}
gBattlescriptCurrInstr + = 3 ;
}
2017-11-25 18:42:31 +01:00
static void atk77_setprotectlike ( void ) // protect and endure
2017-09-26 22:39:59 +02:00
{
bool8 notLastTurn = TRUE ;
2017-11-26 18:07:00 +01:00
u16 lastMove = gLastResultingMoves [ gBankAttacker ] ;
2017-09-26 22:39:59 +02:00
if ( lastMove ! = MOVE_PROTECT & & lastMove ! = MOVE_DETECT & & lastMove ! = MOVE_ENDURE )
gDisableStructs [ gBankAttacker ] . protectUses = 0 ;
2017-10-06 00:12:01 +02:00
if ( gCurrentTurnActionNumber = = ( gNoOfAllBanks - 1 ) )
2017-09-26 22:39:59 +02:00
notLastTurn = FALSE ;
if ( sProtectSuccessRates [ gDisableStructs [ gBankAttacker ] . protectUses ] > = Random ( ) & & notLastTurn )
{
if ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_PROTECT )
{
gProtectStructs [ gBankAttacker ] . protected = 1 ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
if ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_ENDURE )
{
gProtectStructs [ gBankAttacker ] . endured = 1 ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
gDisableStructs [ gBankAttacker ] . protectUses + + ;
}
else
{
gDisableStructs [ gBankAttacker ] . protectUses = 0 ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
gBattleMoveFlags | = MOVESTATUS_MISSED ;
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk78_faintifabilitynotdamp ( void )
2017-09-26 22:39:59 +02:00
{
if ( gBattleExecBuffer )
return ;
for ( gBankTarget = 0 ; gBankTarget < gNoOfAllBanks ; gBankTarget + + )
{
if ( gBattleMons [ gBankTarget ] . ability = = ABILITY_DAMP )
break ;
}
if ( gBankTarget = = gNoOfAllBanks )
{
gActiveBank = gBankAttacker ;
gBattleMoveDamage = gBattleMons [ gActiveBank ] . hp ;
2017-10-22 18:43:15 +02:00
EmitHealthBarUpdate ( 0 , INSTANT_HP_BAR_DROP ) ;
2017-09-26 22:39:59 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + + ;
for ( gBankTarget = 0 ; gBankTarget < gNoOfAllBanks ; gBankTarget + + )
{
if ( gBankTarget = = gBankAttacker )
continue ;
if ( ! ( gAbsentBankFlags & gBitTable [ gBankTarget ] ) )
break ;
}
}
else
{
gLastUsedAbility = ABILITY_DAMP ;
RecordAbilityBattle ( gBankTarget , gBattleMons [ gBankTarget ] . ability ) ;
gBattlescriptCurrInstr = BattleScript_DampStopsExplosion ;
}
}
2017-09-28 15:34:21 +02:00
static void atk79_setatkhptozero ( void )
2017-09-26 22:39:59 +02:00
{
if ( gBattleExecBuffer )
return ;
gActiveBank = gBankAttacker ;
gBattleMons [ gActiveBank ] . hp = 0 ;
EmitSetMonData ( 0 , REQUEST_HP_BATTLE , 0 , 2 , & gBattleMons [ gActiveBank ] . hp ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atk7A_jumpifnexttargetvalid ( void )
2017-09-26 22:39:59 +02:00
{
2017-11-25 18:42:31 +01:00
const u8 * jumpPtr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
{
for ( gBankTarget + + ; ; gBankTarget + + )
{
if ( gBankTarget = = gBankAttacker )
continue ;
if ( ! ( gAbsentBankFlags & gBitTable [ gBankTarget ] ) )
break ;
}
if ( gBankTarget > = gNoOfAllBanks )
gBattlescriptCurrInstr + = 5 ;
else
gBattlescriptCurrInstr = jumpPtr ;
}
else
2017-11-25 18:42:31 +01:00
{
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
2017-11-25 18:42:31 +01:00
}
2017-09-26 22:39:59 +02:00
}
2017-11-25 18:42:31 +01:00
static void atk7B_tryhealhalfhealth ( void )
2017-09-26 22:39:59 +02:00
{
const u8 * failPtr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 15:34:21 +02:00
if ( gBattlescriptCurrInstr [ 5 ] = = BS_GET_ATTACKER )
2017-09-26 22:39:59 +02:00
gBankTarget = gBankAttacker ;
gBattleMoveDamage = gBattleMons [ gBankTarget ] . maxHP / 2 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleMoveDamage * = - 1 ;
if ( gBattleMons [ gBankTarget ] . hp = = gBattleMons [ gBankTarget ] . maxHP )
gBattlescriptCurrInstr = failPtr ;
else
gBattlescriptCurrInstr + = 6 ;
}
2017-09-28 15:34:21 +02:00
static void atk7C_trymirrormove ( void )
2017-09-26 22:39:59 +02:00
{
s32 validMovesCount ;
s32 i ;
u16 move ;
u16 movesArray [ 4 ] ;
for ( i = 0 ; i < 3 ; i + + )
movesArray [ i ] = 0 ;
for ( validMovesCount = 0 , i = 0 ; i < gNoOfAllBanks ; i + + )
{
if ( i ! = gBankAttacker )
{
move = * ( i * 2 + gBankAttacker * 8 + ( u8 * ) ( gBattleStruct - > mirrorMoveArrays ) + 0 )
| ( * ( i * 2 + gBankAttacker * 8 + ( u8 * ) ( gBattleStruct - > mirrorMoveArrays ) + 1 ) < < 8 ) ;
if ( move ! = 0 & & move ! = 0xFFFF )
{
movesArray [ validMovesCount ] = move ;
validMovesCount + + ;
}
}
}
move = * ( gBattleStruct - > mirrorMoves + gBankAttacker * 2 + 0 )
| ( * ( gBattleStruct - > mirrorMoves + gBankAttacker * 2 + 1 ) < < 8 ) ;
if ( move ! = 0 & & move ! = 0xFFFF )
{
gHitMarker & = ~ ( HITMARKER_ATTACKSTRING_PRINTED ) ;
gCurrentMove = move ;
gBankTarget = GetMoveTarget ( gCurrentMove , 0 ) ;
gBattlescriptCurrInstr = gBattleScriptsForMoveEffects [ gBattleMoves [ gCurrentMove ] . effect ] ;
}
else if ( validMovesCount )
{
gHitMarker & = ~ ( HITMARKER_ATTACKSTRING_PRINTED ) ;
i = Random ( ) % validMovesCount ;
gCurrentMove = movesArray [ i ] ;
gBankTarget = GetMoveTarget ( gCurrentMove , 0 ) ;
gBattlescriptCurrInstr = gBattleScriptsForMoveEffects [ gBattleMoves [ gCurrentMove ] . effect ] ;
}
else
{
gSpecialStatuses [ gBankAttacker ] . flag20 = 1 ;
gBattlescriptCurrInstr + + ;
}
}
2017-11-25 18:42:31 +01:00
static void atk7D_setrain ( void )
2017-09-26 22:39:59 +02:00
{
if ( gBattleWeather & WEATHER_RAIN_ANY )
{
gBattleMoveFlags | = MOVESTATUS_MISSED ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
}
else
{
gBattleWeather = WEATHER_RAIN_TEMPORARY ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
gWishFutureKnock . weatherDuration = 5 ;
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk7E_setreflect ( void )
2017-09-26 22:39:59 +02:00
{
if ( gSideAffecting [ GET_BANK_SIDE ( gBankAttacker ) ] & SIDE_STATUS_REFLECT )
{
gBattleMoveFlags | = MOVESTATUS_MISSED ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
else
{
gSideAffecting [ GET_BANK_SIDE ( gBankAttacker ) ] | = SIDE_STATUS_REFLECT ;
gSideTimers [ GET_BANK_SIDE ( gBankAttacker ) ] . reflectTimer = 5 ;
gSideTimers [ GET_BANK_SIDE ( gBankAttacker ) ] . reflectBank = gBankAttacker ;
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE & & CountAliveMonsInBattle ( BATTLE_ALIVE_ATK_SIDE ) = = 2 )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk7F_setseeded ( void )
2017-09-26 22:39:59 +02:00
{
if ( gBattleMoveFlags & MOVESTATUS_NOEFFECT | | gStatuses3 [ gBankTarget ] & STATUS3_LEECHSEED )
{
gBattleMoveFlags | = MOVESTATUS_MISSED ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
else if ( gBattleMons [ gBankTarget ] . type1 = = TYPE_GRASS | | gBattleMons [ gBankTarget ] . type2 = = TYPE_GRASS )
{
gBattleMoveFlags | = MOVESTATUS_MISSED ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
}
else
{
gStatuses3 [ gBankTarget ] | = gBankAttacker ;
gStatuses3 [ gBankTarget ] | = STATUS3_LEECHSEED ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk80_manipulatedamage ( void )
2017-09-26 22:39:59 +02:00
{
2017-09-28 15:34:21 +02:00
switch ( gBattlescriptCurrInstr [ 1 ] )
2017-09-26 22:39:59 +02:00
{
case ATK80_DMG_CHANGE_SIGN :
gBattleMoveDamage * = - 1 ;
break ;
case ATK80_DMG_HALF_BY_TWO_NOT_MORE_THAN_HALF_MAX_HP :
gBattleMoveDamage / = 2 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
if ( ( gBattleMons [ gBankTarget ] . maxHP / 2 ) < gBattleMoveDamage )
gBattleMoveDamage = gBattleMons [ gBankTarget ] . maxHP / 2 ;
break ;
case ATK80_DMG_DOUBLED :
gBattleMoveDamage * = 2 ;
break ;
}
gBattlescriptCurrInstr + = 2 ;
}
2017-11-25 18:42:31 +01:00
static void atk81_trysetrest ( void )
2017-09-26 22:39:59 +02:00
{
2017-11-25 18:42:31 +01:00
const u8 * failJump = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
gActiveBank = gBankTarget = gBankAttacker ;
gBattleMoveDamage = gBattleMons [ gBankTarget ] . maxHP * ( - 1 ) ;
if ( gBattleMons [ gBankTarget ] . hp = = gBattleMons [ gBankTarget ] . maxHP )
{
gBattlescriptCurrInstr = failJump ;
}
else
{
if ( gBattleMons [ gBankTarget ] . status1 & ( ( u8 ) ( ~ STATUS_SLEEP ) ) )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
gBattleMons [ gBankTarget ] . status1 = 3 ;
EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gActiveBank ] . status1 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 5 ;
}
}
2017-09-28 15:34:21 +02:00
static void atk82_jumpifnotfirstturn ( void )
2017-09-26 22:39:59 +02:00
{
const u8 * failJump = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
if ( gDisableStructs [ gBankAttacker ] . isFirstTurn )
gBattlescriptCurrInstr + = 5 ;
else
gBattlescriptCurrInstr = failJump ;
}
2017-09-28 15:34:21 +02:00
static void atk83_nop ( void )
2017-09-26 22:39:59 +02:00
{
gBattlescriptCurrInstr + + ;
}
bool8 UproarWakeUpCheck ( u8 bank )
{
s32 i ;
for ( i = 0 ; i < gNoOfAllBanks ; i + + )
{
if ( ! ( gBattleMons [ i ] . status2 & STATUS2_UPROAR ) | | gBattleMons [ bank ] . ability = = ABILITY_SOUNDPROOF )
continue ;
gBattleScripting . bank = i ;
if ( gBankTarget = = 0xFF )
gBankTarget = i ;
else if ( gBankTarget = = i )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
break ;
}
if ( i = = gNoOfAllBanks )
return FALSE ;
else
return TRUE ;
}
2017-11-25 18:42:31 +01:00
static void atk84_jumpifcantmakeasleep ( void )
2017-09-26 22:39:59 +02:00
{
2017-11-25 18:42:31 +01:00
const u8 * jumpPtr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
if ( UproarWakeUpCheck ( gBankTarget ) )
{
gBattlescriptCurrInstr = jumpPtr ;
}
else if ( gBattleMons [ gBankTarget ] . ability = = ABILITY_INSOMNIA
| | gBattleMons [ gBankTarget ] . ability = = ABILITY_VITAL_SPIRIT )
{
gLastUsedAbility = gBattleMons [ gBankTarget ] . ability ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
gBattlescriptCurrInstr = jumpPtr ;
RecordAbilityBattle ( gBankTarget , gLastUsedAbility ) ;
}
else
{
gBattlescriptCurrInstr + = 5 ;
}
}
2017-09-28 15:34:21 +02:00
static void atk85_stockpile ( void )
2017-09-26 22:39:59 +02:00
{
if ( gDisableStructs [ gBankAttacker ] . stockpileCounter = = 3 )
{
gBattleMoveFlags | = MOVESTATUS_MISSED ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
else
{
gDisableStructs [ gBankAttacker ] . stockpileCounter + + ;
PREPARE_BYTE_NUMBER_BUFFER ( gBattleTextBuff1 , 1 , gDisableStructs [ gBankAttacker ] . stockpileCounter )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk86_stockpiletobasedamage ( void )
2017-09-26 22:39:59 +02:00
{
const u8 * jumpPtr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
if ( gDisableStructs [ gBankAttacker ] . stockpileCounter = = 0 )
{
gBattlescriptCurrInstr = jumpPtr ;
}
else
{
if ( gBattleCommunication [ 6 ] ! = 1 )
{
gBattleMoveDamage = CalculateBaseDamage ( & gBattleMons [ gBankAttacker ] , & gBattleMons [ gBankTarget ] , gCurrentMove ,
gSideAffecting [ GET_BANK_SIDE ( gBankTarget ) ] , 0 ,
0 , gBankAttacker , gBankTarget )
* gDisableStructs [ gBankAttacker ] . stockpileCounter ;
gBattleScripting . animTurn = gDisableStructs [ gBankAttacker ] . stockpileCounter ;
if ( gProtectStructs [ gBankAttacker ] . helpingHand )
gBattleMoveDamage = gBattleMoveDamage * 15 / 10 ;
}
gDisableStructs [ gBankAttacker ] . stockpileCounter = 0 ;
gBattlescriptCurrInstr + = 5 ;
}
}
2017-09-28 15:34:21 +02:00
static void atk87_stockpiletohpheal ( void )
2017-09-26 22:39:59 +02:00
{
const u8 * jumpPtr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
if ( gDisableStructs [ gBankAttacker ] . stockpileCounter = = 0 )
{
gBattlescriptCurrInstr = jumpPtr ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
else if ( gBattleMons [ gBankAttacker ] . maxHP = = gBattleMons [ gBankAttacker ] . hp )
{
gDisableStructs [ gBankAttacker ] . stockpileCounter = 0 ;
gBattlescriptCurrInstr = jumpPtr ;
gBankTarget = gBankAttacker ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
else
{
gBattleMoveDamage = gBattleMons [ gBankAttacker ] . maxHP / ( 1 < < ( 3 - gDisableStructs [ gBankAttacker ] . stockpileCounter ) ) ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleMoveDamage * = - 1 ;
gBattleScripting . animTurn = gDisableStructs [ gBankAttacker ] . stockpileCounter ;
gDisableStructs [ gBankAttacker ] . stockpileCounter = 0 ;
gBattlescriptCurrInstr + = 5 ;
gBankTarget = gBankAttacker ;
}
}
2017-09-28 15:34:21 +02:00
static void atk88_negativedamage ( void )
2017-09-26 22:39:59 +02:00
{
gBattleMoveDamage = - ( gHpDealt / 2 ) ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = - 1 ;
gBattlescriptCurrInstr + + ;
}
2017-11-26 11:55:17 +01:00
static u8 ChangeStatBuffs ( s8 statValue , u8 statId , u8 flags , const u8 * BS_ptr )
2017-09-26 22:39:59 +02:00
{
2017-11-26 11:55:17 +01:00
bool8 certain = FALSE ;
2017-09-26 22:39:59 +02:00
bool8 notProtectAffected = FALSE ;
u32 index ;
if ( flags & MOVE_EFFECT_AFFECTS_USER )
gActiveBank = gBankAttacker ;
else
gActiveBank = gBankTarget ;
flags & = ~ ( MOVE_EFFECT_AFFECTS_USER ) ;
if ( flags & MOVE_EFFECT_CERTAIN )
certain + + ;
flags & = ~ ( MOVE_EFFECT_CERTAIN ) ;
if ( flags & STAT_CHANGE_NOT_PROTECT_AFFECTED )
notProtectAffected + + ;
flags & = ~ ( STAT_CHANGE_NOT_PROTECT_AFFECTED ) ;
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , statId )
if ( ( statValue < < 0x18 ) < 0 ) // stat decrease
{
if ( gSideTimers [ GET_BANK_SIDE ( gActiveBank ) ] . mistTimer
& & ! certain & & gCurrentMove ! = MOVE_CURSE )
{
if ( flags = = STAT_CHANGE_BS_PTR )
{
if ( gSpecialStatuses [ gActiveBank ] . statLowered )
{
gBattlescriptCurrInstr = BS_ptr ;
}
else
{
BattleScriptPush ( BS_ptr ) ;
gBattleScripting . bank = gActiveBank ;
gBattlescriptCurrInstr = BattleScript_MistProtected ;
gSpecialStatuses [ gActiveBank ] . statLowered = 1 ;
}
}
return STAT_CHANGE_DIDNT_WORK ;
}
else if ( gCurrentMove ! = MOVE_CURSE
& & notProtectAffected ! = TRUE & & JumpIfMoveAffectedByProtect ( 0 ) )
{
gBattlescriptCurrInstr = BattleScript_ButItFailed ;
return STAT_CHANGE_DIDNT_WORK ;
}
else if ( ( gBattleMons [ gActiveBank ] . ability = = ABILITY_CLEAR_BODY
| | gBattleMons [ gActiveBank ] . ability = = ABILITY_WHITE_SMOKE )
& & ! certain & & gCurrentMove ! = MOVE_CURSE )
{
if ( flags = = STAT_CHANGE_BS_PTR )
{
if ( gSpecialStatuses [ gActiveBank ] . statLowered )
{
gBattlescriptCurrInstr = BS_ptr ;
}
else
{
BattleScriptPush ( BS_ptr ) ;
gBattleScripting . bank = gActiveBank ;
gBattlescriptCurrInstr = BattleScript_AbilityNoStatLoss ;
gLastUsedAbility = gBattleMons [ gActiveBank ] . ability ;
RecordAbilityBattle ( gActiveBank , gLastUsedAbility ) ;
gSpecialStatuses [ gActiveBank ] . statLowered = 1 ;
}
}
return STAT_CHANGE_DIDNT_WORK ;
}
else if ( gBattleMons [ gActiveBank ] . ability = = ABILITY_KEEN_EYE
& & ! certain & & statId = = STAT_STAGE_ACC )
{
if ( flags = = STAT_CHANGE_BS_PTR )
{
BattleScriptPush ( BS_ptr ) ;
gBattleScripting . bank = gActiveBank ;
gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss ;
gLastUsedAbility = gBattleMons [ gActiveBank ] . ability ;
RecordAbilityBattle ( gActiveBank , gLastUsedAbility ) ;
}
return STAT_CHANGE_DIDNT_WORK ;
}
else if ( gBattleMons [ gActiveBank ] . ability = = ABILITY_HYPER_CUTTER
& & ! certain & & statId = = STAT_STAGE_ATK )
{
if ( flags = = STAT_CHANGE_BS_PTR )
{
BattleScriptPush ( BS_ptr ) ;
gBattleScripting . bank = gActiveBank ;
gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss ;
gLastUsedAbility = gBattleMons [ gActiveBank ] . ability ;
RecordAbilityBattle ( gActiveBank , gLastUsedAbility ) ;
}
return STAT_CHANGE_DIDNT_WORK ;
}
else if ( gBattleMons [ gActiveBank ] . ability = = ABILITY_SHIELD_DUST & & flags = = 0 )
{
return STAT_CHANGE_DIDNT_WORK ;
}
else // try to decrease
{
statValue = - GET_STAT_BUFF_VALUE ( statValue ) ;
gBattleTextBuff2 [ 0 ] = B_BUFF_PLACEHOLDER_BEGIN ;
index = 1 ;
if ( statValue = = - 2 )
{
gBattleTextBuff2 [ 1 ] = B_BUFF_STRING ;
2017-11-26 11:55:17 +01:00
gBattleTextBuff2 [ 2 ] = STRINGID_STATHARSHLY ;
gBattleTextBuff2 [ 3 ] = STRINGID_STATHARSHLY > > 8 ;
2017-09-26 22:39:59 +02:00
index = 4 ;
}
gBattleTextBuff2 [ index ] = B_BUFF_STRING ;
index + + ;
2017-11-26 11:55:17 +01:00
gBattleTextBuff2 [ index ] = STRINGID_STATFELL ;
2017-09-26 22:39:59 +02:00
index + + ;
2017-11-26 11:55:17 +01:00
gBattleTextBuff2 [ index ] = STRINGID_STATFELL > > 8 ;
2017-09-26 22:39:59 +02:00
index + + ;
gBattleTextBuff2 [ index ] = B_BUFF_EOS ;
if ( gBattleMons [ gActiveBank ] . statStages [ statId ] = = 0 )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = ( gBankTarget = = gActiveBank ) ;
}
}
else // stat increase
{
statValue = GET_STAT_BUFF_VALUE ( statValue ) ;
gBattleTextBuff2 [ 0 ] = B_BUFF_PLACEHOLDER_BEGIN ;
index = 1 ;
if ( statValue = = 2 )
{
gBattleTextBuff2 [ 1 ] = B_BUFF_STRING ;
2017-11-26 11:55:17 +01:00
gBattleTextBuff2 [ 2 ] = STRINGID_STATSHARPLY ;
gBattleTextBuff2 [ 3 ] = STRINGID_STATSHARPLY > > 8 ;
2017-09-26 22:39:59 +02:00
index = 4 ;
}
gBattleTextBuff2 [ index ] = B_BUFF_STRING ;
index + + ;
2017-11-26 11:55:17 +01:00
gBattleTextBuff2 [ index ] = STRINGID_STATROSE ;
2017-09-26 22:39:59 +02:00
index + + ;
2017-11-26 11:55:17 +01:00
gBattleTextBuff2 [ index ] = STRINGID_STATROSE > > 8 ;
2017-09-26 22:39:59 +02:00
index + + ;
gBattleTextBuff2 [ index ] = B_BUFF_EOS ;
if ( gBattleMons [ gActiveBank ] . statStages [ statId ] = = 0xC )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = ( gBankTarget = = gActiveBank ) ;
}
gBattleMons [ gActiveBank ] . statStages [ statId ] + = statValue ;
if ( gBattleMons [ gActiveBank ] . statStages [ statId ] < 0 )
gBattleMons [ gActiveBank ] . statStages [ statId ] = 0 ;
if ( gBattleMons [ gActiveBank ] . statStages [ statId ] > 0xC )
gBattleMons [ gActiveBank ] . statStages [ statId ] = 0xC ;
if ( gBattleCommunication [ MULTISTRING_CHOOSER ] = = 2 & & flags & STAT_CHANGE_BS_PTR )
gBattleMoveFlags | = MOVESTATUS_MISSED ;
if ( gBattleCommunication [ MULTISTRING_CHOOSER ] = = 2 & & ! ( flags & STAT_CHANGE_BS_PTR ) )
return STAT_CHANGE_DIDNT_WORK ;
return STAT_CHANGE_WORKED ;
}
2017-09-28 15:34:21 +02:00
static void atk89_statbuffchange ( void )
2017-09-26 22:39:59 +02:00
{
const u8 * jumpPtr = BSScriptReadPtr ( gBattlescriptCurrInstr + 2 ) ;
2017-09-28 15:34:21 +02:00
if ( ChangeStatBuffs ( gBattleScripting . statChanger & 0xF0 , GET_STAT_BUFF_ID ( gBattleScripting . statChanger ) , gBattlescriptCurrInstr [ 1 ] , jumpPtr ) = = STAT_CHANGE_WORKED )
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 6 ;
}
2017-09-28 15:34:21 +02:00
static void atk8A_normalisebuffs ( void ) // haze
2017-09-26 22:39:59 +02:00
{
s32 i , j ;
for ( i = 0 ; i < gNoOfAllBanks ; i + + )
{
for ( j = 0 ; j < BATTLE_STATS_NO ; j + + )
gBattleMons [ i ] . statStages [ j ] = 6 ;
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk8B_setbide ( void )
2017-09-26 22:39:59 +02:00
{
gBattleMons [ gBankAttacker ] . status2 | = STATUS2_MULTIPLETURNS ;
gLockedMoves [ gBankAttacker ] = gCurrentMove ;
gTakenDmg [ gBankAttacker ] = 0 ;
gBattleMons [ gBankAttacker ] . status2 | = ( STATUS2_BIDE - 0x100 ) ; // 2 turns
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk8C_confuseifrepeatingattackends ( void )
2017-09-26 22:39:59 +02:00
{
if ( ! ( gBattleMons [ gBankAttacker ] . status2 & STATUS2_LOCK_CONFUSE ) )
gBattleCommunication [ MOVE_EFFECT_BYTE ] = ( MOVE_EFFECT_THRASH | MOVE_EFFECT_AFFECTS_USER ) ;
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atk8D_setmultihitcounter ( void )
2017-09-26 22:39:59 +02:00
{
2017-09-28 15:34:21 +02:00
if ( gBattlescriptCurrInstr [ 1 ] )
2017-09-26 22:39:59 +02:00
{
2017-09-28 15:34:21 +02:00
gMultiHitCounter = gBattlescriptCurrInstr [ 1 ] ;
2017-09-26 22:39:59 +02:00
}
else
{
gMultiHitCounter = Random ( ) & 3 ;
if ( gMultiHitCounter > 1 )
gMultiHitCounter = ( Random ( ) & 3 ) + 2 ;
else
gMultiHitCounter + = 2 ;
}
gBattlescriptCurrInstr + = 2 ;
}
2017-11-25 18:42:31 +01:00
static void atk8E_initmultihitstring ( void )
2017-09-26 22:39:59 +02:00
{
PREPARE_BYTE_NUMBER_BUFFER ( gBattleScripting . multihitString , 1 , 0 )
gBattlescriptCurrInstr + + ;
}
2017-12-02 00:03:46 +01:00
static bool8 TryDoForceSwitchOut ( void )
2017-09-26 22:39:59 +02:00
{
if ( gBattleMons [ gBankAttacker ] . level > = gBattleMons [ gBankTarget ] . level )
{
* ( gBattleStruct - > field_58 + gBankTarget ) = gBattlePartyID [ gBankTarget ] ;
}
else
{
u16 random = Random ( ) & 0xFF ;
if ( ( u32 ) ( ( random * ( gBattleMons [ gBankAttacker ] . level + gBattleMons [ gBankTarget ] . level ) > > 8 ) + 1 ) < = ( gBattleMons [ gBankTarget ] . level / 4 ) )
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
return FALSE ;
}
* ( gBattleStruct - > field_58 + gBankTarget ) = gBattlePartyID [ gBankTarget ] ;
}
2017-12-02 00:03:46 +01:00
gBattlescriptCurrInstr = BattleScript_SuccessForceOut ;
2017-09-26 22:39:59 +02:00
return TRUE ;
}
2017-09-28 15:34:21 +02:00
static void atk8F_forcerandomswitch ( void )
2017-09-26 22:39:59 +02:00
{
s32 i ;
s32 bank1PartyId = 0 ;
s32 bank2PartyId = 0 ;
# ifdef NONMATCHING
s32 lastMonId = 0 ; // + 1
# else
register s32 lastMonId asm ( " r8 " ) = 0 ; // + 1
# endif // NONMATCHING
s32 firstMonId = 0 ;
s32 monsCount = 0 ;
struct Pokemon * party = NULL ;
s32 validMons = 0 ;
s32 minNeeded = 0 ;
if ( ( gBattleTypeFlags & BATTLE_TYPE_TRAINER ) )
{
if ( GetBankSide ( gBankTarget ) = = SIDE_PLAYER )
party = gPlayerParty ;
else
party = gEnemyParty ;
if ( ( gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER & & gBattleTypeFlags & BATTLE_TYPE_LINK )
| | ( gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER & & gBattleTypeFlags & BATTLE_TYPE_x2000000 )
| | ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER ) )
{
if ( ( gBankTarget & BIT_MON ) ! = 0 )
{
firstMonId = 3 ;
lastMonId = 6 ;
}
else
{
firstMonId = 0 ;
lastMonId = 3 ;
}
monsCount = 3 ;
minNeeded = 1 ;
bank2PartyId = gBattlePartyID [ gBankTarget ] ;
bank1PartyId = gBattlePartyID [ gBankTarget ^ BIT_MON ] ;
}
else if ( ( gBattleTypeFlags & BATTLE_TYPE_MULTI & & gBattleTypeFlags & BATTLE_TYPE_LINK )
| | ( gBattleTypeFlags & BATTLE_TYPE_MULTI & & gBattleTypeFlags & BATTLE_TYPE_x2000000 ) )
{
2017-10-23 16:38:11 +02:00
if ( sub_806D82C ( GetBankMultiplayerId ( gBankTarget ) ) = = 1 )
2017-09-26 22:39:59 +02:00
{
firstMonId = 3 ;
lastMonId = 6 ;
}
else
{
firstMonId = 0 ;
lastMonId = 3 ;
}
monsCount = 3 ;
minNeeded = 1 ;
bank2PartyId = gBattlePartyID [ gBankTarget ] ;
bank1PartyId = gBattlePartyID [ gBankTarget ^ BIT_MON ] ;
}
else if ( gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS )
{
if ( GetBankSide ( gBankTarget ) = = SIDE_PLAYER )
{
firstMonId = 0 ;
lastMonId = 6 ;
monsCount = 6 ;
minNeeded = 2 ; // since there are two opponents, it has to be a double battle
}
else
{
if ( ( gBankTarget & BIT_MON ) ! = 0 )
{
firstMonId = 3 ;
lastMonId = 6 ;
}
else
{
firstMonId = 0 ;
lastMonId = 3 ;
}
monsCount = 3 ;
minNeeded = 1 ;
}
bank2PartyId = gBattlePartyID [ gBankTarget ] ;
bank1PartyId = gBattlePartyID [ gBankTarget ^ BIT_MON ] ;
}
else if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
{
firstMonId = 0 ;
lastMonId = 6 ;
monsCount = 6 ;
minNeeded = 2 ;
bank2PartyId = gBattlePartyID [ gBankTarget ] ;
bank1PartyId = gBattlePartyID [ gBankTarget ^ BIT_MON ] ;
}
else
{
firstMonId = 0 ;
lastMonId = 6 ;
monsCount = 6 ;
minNeeded = 1 ;
bank2PartyId = gBattlePartyID [ gBankTarget ] ; // there is only one pokemon out in single battles
bank1PartyId = gBattlePartyID [ gBankTarget ] ;
}
for ( i = firstMonId ; i < lastMonId ; i + + )
{
if ( GetMonData ( & party [ i ] , MON_DATA_SPECIES ) ! = SPECIES_NONE
& & ! GetMonData ( & party [ i ] , MON_DATA_IS_EGG )
& & GetMonData ( & party [ i ] , MON_DATA_HP ) ! = 0 )
{
validMons + + ;
}
}
if ( validMons < = minNeeded )
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
2017-12-02 00:03:46 +01:00
if ( TryDoForceSwitchOut ( ) )
2017-09-26 22:39:59 +02:00
{
do
{
i = Random ( ) % monsCount ;
i + = firstMonId ;
}
while ( i = = bank2PartyId
| | i = = bank1PartyId
| | GetMonData ( & party [ i ] , MON_DATA_SPECIES ) = = SPECIES_NONE
| | GetMonData ( & party [ i ] , MON_DATA_IS_EGG ) = = TRUE
| | GetMonData ( & party [ i ] , MON_DATA_HP ) = = 0 ) ;
}
2017-11-12 17:06:31 +01:00
* ( gBattleStruct - > monToSwitchIntoId + gBankTarget ) = i ;
2017-09-26 22:39:59 +02:00
if ( ! sub_81B1250 ( ) )
sub_803BDA0 ( gBankTarget ) ;
if ( ( gBattleTypeFlags & BATTLE_TYPE_LINK & & gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER )
| | ( gBattleTypeFlags & BATTLE_TYPE_LINK & & gBattleTypeFlags & BATTLE_TYPE_MULTI )
| | ( gBattleTypeFlags & BATTLE_TYPE_x2000000 & & gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER )
| | ( gBattleTypeFlags & BATTLE_TYPE_x2000000 & & gBattleTypeFlags & BATTLE_TYPE_MULTI ) )
{
sub_81B8E80 ( gBankTarget , i , 0 ) ;
sub_81B8E80 ( gBankTarget ^ BIT_MON , i , 1 ) ;
}
if ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER )
sub_80571DC ( gBankTarget , i ) ;
}
}
else
{
2017-12-02 00:03:46 +01:00
TryDoForceSwitchOut ( ) ;
2017-09-26 22:39:59 +02:00
}
}
2017-11-25 18:42:31 +01:00
static void atk90_tryconversiontypechange ( void ) // randomly changes user's type to one of its moves' type
2017-09-26 22:39:59 +02:00
{
u8 validMoves = 0 ;
u8 moveChecked ;
u8 moveType ;
while ( validMoves < 4 )
{
if ( gBattleMons [ gBankAttacker ] . moves [ validMoves ] = = 0 )
break ;
validMoves + + ;
}
for ( moveChecked = 0 ; moveChecked < validMoves ; moveChecked + + )
{
moveType = gBattleMoves [ gBattleMons [ gBankAttacker ] . moves [ moveChecked ] ] . type ;
if ( moveType = = TYPE_MYSTERY )
{
if ( gBattleMons [ gBankAttacker ] . type1 = = TYPE_GHOST | | gBattleMons [ gBankAttacker ] . type2 = = TYPE_GHOST )
moveType = TYPE_GHOST ;
else
moveType = TYPE_NORMAL ;
}
if ( moveType ! = gBattleMons [ gBankAttacker ] . type1
& & moveType ! = gBattleMons [ gBankAttacker ] . type2 )
{
break ;
}
}
if ( moveChecked = = validMoves )
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
do
{
while ( ( moveChecked = Random ( ) & 3 ) > = validMoves ) ;
moveType = gBattleMoves [ gBattleMons [ gBankAttacker ] . moves [ moveChecked ] ] . type ;
if ( moveType = = TYPE_MYSTERY )
{
if ( gBattleMons [ gBankAttacker ] . type1 = = TYPE_GHOST | | gBattleMons [ gBankAttacker ] . type2 = = TYPE_GHOST )
moveType = TYPE_GHOST ;
else
moveType = TYPE_NORMAL ;
}
}
while ( moveType = = gBattleMons [ gBankAttacker ] . type1 | | moveType = = gBattleMons [ gBankAttacker ] . type2 ) ;
gBattleMons [ gBankAttacker ] . type1 = moveType ;
gBattleMons [ gBankAttacker ] . type2 = moveType ;
PREPARE_TYPE_BUFFER ( gBattleTextBuff1 , moveType )
gBattlescriptCurrInstr + = 5 ;
}
}
2017-09-28 15:34:21 +02:00
static void atk91_givepaydaymoney ( void )
2017-09-26 22:39:59 +02:00
{
if ( ! ( gBattleTypeFlags & ( BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000 ) ) & & gPaydayMoney ! = 0 )
{
u32 bonusMoney = gPaydayMoney * gBattleStruct - > moneyMultiplier ;
AddMoney ( & gSaveBlock1Ptr - > money , bonusMoney ) ;
PREPARE_HWORD_NUMBER_BUFFER ( gBattleTextBuff1 , 5 , bonusMoney )
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
gBattlescriptCurrInstr = BattleScript_PrintPayDayMoneyString ;
}
else
{
gBattlescriptCurrInstr + + ;
}
}
2017-09-28 15:34:21 +02:00
static void atk92_setlightscreen ( void )
2017-09-26 22:39:59 +02:00
{
if ( gSideAffecting [ GET_BANK_SIDE ( gBankAttacker ) ] & SIDE_STATUS_LIGHTSCREEN )
{
gBattleMoveFlags | = MOVESTATUS_MISSED ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
else
{
gSideAffecting [ GET_BANK_SIDE ( gBankAttacker ) ] | = SIDE_STATUS_LIGHTSCREEN ;
gSideTimers [ GET_BANK_SIDE ( gBankAttacker ) ] . lightscreenTimer = 5 ;
gSideTimers [ GET_BANK_SIDE ( gBankAttacker ) ] . lightscreenBank = gBankAttacker ;
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE & & CountAliveMonsInBattle ( BATTLE_ALIVE_ATK_SIDE ) = = 2 )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 4 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 3 ;
}
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atk93_tryKO ( void )
2017-09-26 22:39:59 +02:00
{
u8 holdEffect , param ;
if ( gBattleMons [ gBankTarget ] . item = = ITEM_ENIGMA_BERRY )
{
holdEffect = gEnigmaBerries [ gBankTarget ] . holdEffect ;
param = gEnigmaBerries [ gBankTarget ] . holdEffectParam ;
}
else
{
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ gBankTarget ] . item ) ;
param = ItemId_GetHoldEffectParam ( gBattleMons [ gBankTarget ] . item ) ;
}
gStringBank = gBankTarget ;
if ( holdEffect = = HOLD_EFFECT_FOCUS_BAND & & ( Random ( ) % 100 ) < param )
{
RecordItemEffectBattle ( gBankTarget , HOLD_EFFECT_FOCUS_BAND ) ;
gSpecialStatuses [ gBankTarget ] . focusBanded = 1 ;
}
if ( gBattleMons [ gBankTarget ] . ability = = ABILITY_STURDY )
{
gBattleMoveFlags | = MOVESTATUS_MISSED ;
gLastUsedAbility = ABILITY_STURDY ;
gBattlescriptCurrInstr = BattleScript_SturdyPreventsOHKO ;
RecordAbilityBattle ( gBankTarget , ABILITY_STURDY ) ;
}
else
{
u16 chance ;
if ( ! ( gStatuses3 [ gBankTarget ] & STATUS3_ALWAYS_HITS ) )
{
chance = gBattleMoves [ gCurrentMove ] . accuracy + ( gBattleMons [ gBankAttacker ] . level - gBattleMons [ gBankTarget ] . level ) ;
if ( Random ( ) % 100 + 1 < chance & & gBattleMons [ gBankAttacker ] . level > = gBattleMons [ gBankTarget ] . level )
chance = TRUE ;
else
chance = FALSE ;
}
else if ( gDisableStructs [ gBankTarget ] . bankWithSureHit = = gBankAttacker
& & gBattleMons [ gBankAttacker ] . level > = gBattleMons [ gBankTarget ] . level )
{
chance = TRUE ;
}
else
{
chance = gBattleMoves [ gCurrentMove ] . accuracy + ( gBattleMons [ gBankAttacker ] . level - gBattleMons [ gBankTarget ] . level ) ;
if ( Random ( ) % 100 + 1 < chance & & gBattleMons [ gBankAttacker ] . level > = gBattleMons [ gBankTarget ] . level )
chance = TRUE ;
else
chance = FALSE ;
}
if ( chance )
{
if ( gProtectStructs [ gBankTarget ] . endured )
{
gBattleMoveDamage = gBattleMons [ gBankTarget ] . hp - 1 ;
gBattleMoveFlags | = MOVESTATUS_ENDURED ;
}
else if ( gSpecialStatuses [ gBankTarget ] . focusBanded )
{
gBattleMoveDamage = gBattleMons [ gBankTarget ] . hp - 1 ;
gBattleMoveFlags | = MOVESTATUS_HUNGON ;
gLastUsedItem = gBattleMons [ gBankTarget ] . item ;
}
else
{
gBattleMoveDamage = gBattleMons [ gBankTarget ] . hp ;
gBattleMoveFlags | = MOVESTATUS_ONEHITKO ;
}
gBattlescriptCurrInstr + = 5 ;
}
else
{
gBattleMoveFlags | = MOVESTATUS_MISSED ;
if ( gBattleMons [ gBankAttacker ] . level > = gBattleMons [ gBankTarget ] . level )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
}
2017-09-28 15:34:21 +02:00
static void atk94_damagetohalftargethp ( void ) // super fang
2017-09-26 22:39:59 +02:00
{
gBattleMoveDamage = gBattleMons [ gBankTarget ] . hp / 2 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk95_setsandstorm ( void )
2017-09-26 22:39:59 +02:00
{
if ( gBattleWeather & WEATHER_SANDSTORM_ANY )
{
gBattleMoveFlags | = MOVESTATUS_MISSED ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
}
else
{
gBattleWeather = WEATHER_SANDSTORM_TEMPORARY ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 3 ;
gWishFutureKnock . weatherDuration = 5 ;
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk96_weatherdamage ( void )
2017-09-26 22:39:59 +02:00
{
if ( WEATHER_HAS_EFFECT )
{
if ( gBattleWeather & WEATHER_SANDSTORM_ANY )
{
if ( gBattleMons [ gBankAttacker ] . type1 ! = TYPE_ROCK
& & gBattleMons [ gBankAttacker ] . type1 ! = TYPE_STEEL
& & gBattleMons [ gBankAttacker ] . type1 ! = TYPE_GROUND
& & gBattleMons [ gBankAttacker ] . type2 ! = TYPE_ROCK
& & gBattleMons [ gBankAttacker ] . type2 ! = TYPE_STEEL
& & gBattleMons [ gBankAttacker ] . type2 ! = TYPE_GROUND
& & gBattleMons [ gBankAttacker ] . ability ! = ABILITY_SAND_VEIL
& & ! ( gStatuses3 [ gBankAttacker ] & STATUS3_UNDERGROUND )
& & ! ( gStatuses3 [ gBankAttacker ] & STATUS3_UNDERWATER ) )
{
gBattleMoveDamage = gBattleMons [ gBankAttacker ] . maxHP / 16 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
}
else
{
gBattleMoveDamage = 0 ;
}
}
if ( gBattleWeather & WEATHER_HAIL )
{
if ( gBattleMons [ gBankAttacker ] . type1 ! = TYPE_ICE
& & gBattleMons [ gBankAttacker ] . type2 ! = TYPE_ICE
& & ! ( gStatuses3 [ gBankAttacker ] & STATUS3_UNDERGROUND )
& & ! ( gStatuses3 [ gBankAttacker ] & STATUS3_UNDERWATER ) )
{
gBattleMoveDamage = gBattleMons [ gBankAttacker ] . maxHP / 16 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
}
else
{
gBattleMoveDamage = 0 ;
}
}
}
else
{
gBattleMoveDamage = 0 ;
}
if ( gAbsentBankFlags & gBitTable [ gBankAttacker ] )
gBattleMoveDamage = 0 ;
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atk97_tryinfatuating ( void )
2017-09-26 22:39:59 +02:00
{
struct Pokemon * monAttacker , * monTarget ;
u16 speciesAttacker , speciesTarget ;
u32 personalityAttacker , personalityTarget ;
if ( GetBankSide ( gBankAttacker ) = = SIDE_PLAYER )
monAttacker = & gPlayerParty [ gBattlePartyID [ gBankAttacker ] ] ;
else
monAttacker = & gEnemyParty [ gBattlePartyID [ gBankAttacker ] ] ;
if ( GetBankSide ( gBankTarget ) = = SIDE_PLAYER )
monTarget = & gPlayerParty [ gBattlePartyID [ gBankTarget ] ] ;
else
monTarget = & gEnemyParty [ gBattlePartyID [ gBankTarget ] ] ;
speciesAttacker = GetMonData ( monAttacker , MON_DATA_SPECIES ) ;
personalityAttacker = GetMonData ( monAttacker , MON_DATA_PERSONALITY ) ;
speciesTarget = GetMonData ( monTarget , MON_DATA_SPECIES ) ;
personalityTarget = GetMonData ( monTarget , MON_DATA_PERSONALITY ) ;
if ( gBattleMons [ gBankTarget ] . ability = = ABILITY_OBLIVIOUS )
{
gBattlescriptCurrInstr = BattleScript_ObliviousPreventsAttraction ;
gLastUsedAbility = ABILITY_OBLIVIOUS ;
RecordAbilityBattle ( gBankTarget , ABILITY_OBLIVIOUS ) ;
}
else
{
if ( GetGenderFromSpeciesAndPersonality ( speciesAttacker , personalityAttacker ) = = GetGenderFromSpeciesAndPersonality ( speciesTarget , personalityTarget )
| | gBattleMons [ gBankTarget ] . status2 & STATUS2_INFATUATION
| | GetGenderFromSpeciesAndPersonality ( speciesAttacker , personalityAttacker ) = = MON_GENDERLESS
| | GetGenderFromSpeciesAndPersonality ( speciesTarget , personalityTarget ) = = MON_GENDERLESS )
2017-09-27 23:43:45 +02:00
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
2017-09-26 22:39:59 +02:00
else
{
gBattleMons [ gBankTarget ] . status2 | = STATUS2_INFATUATED_WITH ( gBankAttacker ) ;
gBattlescriptCurrInstr + = 5 ;
}
}
}
2017-11-25 18:42:31 +01:00
static void atk98_updatestatusicon ( void )
2017-09-26 22:39:59 +02:00
{
if ( gBattleExecBuffer )
return ;
2017-09-28 15:34:21 +02:00
if ( gBattlescriptCurrInstr [ 1 ] ! = BS_ATTACKER_WITH_PARTNER )
2017-09-26 22:39:59 +02:00
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-26 22:39:59 +02:00
EmitStatusIconUpdate ( 0 , gBattleMons [ gActiveBank ] . status1 , gBattleMons [ gActiveBank ] . status2 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 2 ;
}
else
{
gActiveBank = gBankAttacker ;
if ( ! ( gAbsentBankFlags & gBitTable [ gActiveBank ] ) )
{
EmitStatusIconUpdate ( 0 , gBattleMons [ gActiveBank ] . status1 , gBattleMons [ gActiveBank ] . status2 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
}
if ( ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE ) )
{
gActiveBank = GetBankByIdentity ( GetBankIdentity ( gBankAttacker ) ^ BIT_MON ) ;
if ( ! ( gAbsentBankFlags & gBitTable [ gActiveBank ] ) )
{
EmitStatusIconUpdate ( 0 , gBattleMons [ gActiveBank ] . status1 , gBattleMons [ gActiveBank ] . status2 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
}
}
gBattlescriptCurrInstr + = 2 ;
}
}
2017-09-28 15:34:21 +02:00
static void atk99_setmist ( void )
2017-09-26 22:39:59 +02:00
{
if ( gSideTimers [ GET_BANK_SIDE ( gBankAttacker ) ] . mistTimer )
{
gBattleMoveFlags | = MOVESTATUS_FAILED ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
else
{
gSideTimers [ GET_BANK_SIDE ( gBankAttacker ) ] . mistTimer = 5 ;
gSideTimers [ GET_BANK_SIDE ( gBankAttacker ) ] . mistBank = gBankAttacker ;
gSideAffecting [ GET_BANK_SIDE ( gBankAttacker ) ] | = SIDE_STATUS_MIST ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atk9A_setfocusenergy ( void )
2017-09-26 22:39:59 +02:00
{
if ( gBattleMons [ gBankAttacker ] . status2 & STATUS2_FOCUS_ENERGY )
{
gBattleMoveFlags | = MOVESTATUS_FAILED ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
else
{
gBattleMons [ gBankAttacker ] . status2 | = STATUS2_FOCUS_ENERGY ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk9B_transformdataexecution ( void )
2017-09-26 22:39:59 +02:00
{
2017-11-26 18:07:00 +01:00
gChosenMove = 0xFFFF ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + + ;
if ( gBattleMons [ gBankTarget ] . status2 & STATUS2_TRANSFORMED
| | gStatuses3 [ gBankTarget ] & STATUS3_SEMI_INVULNERABLE )
{
gBattleMoveFlags | = MOVESTATUS_FAILED ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
else
{
s32 i ;
u8 * battleMonAttacker , * battleMonTarget ;
gBattleMons [ gBankAttacker ] . status2 | = STATUS2_TRANSFORMED ;
gDisableStructs [ gBankAttacker ] . disabledMove = 0 ;
gDisableStructs [ gBankAttacker ] . disableTimer1 = 0 ;
2017-10-22 01:04:02 +02:00
gDisableStructs [ gBankAttacker ] . transformedMonPersonality = gBattleMons [ gBankTarget ] . personality ;
2017-09-26 22:39:59 +02:00
gDisableStructs [ gBankAttacker ] . unk18_b = 0 ;
PREPARE_SPECIES_BUFFER ( gBattleTextBuff1 , gBattleMons [ gBankTarget ] . species )
battleMonAttacker = ( u8 * ) ( & gBattleMons [ gBankAttacker ] ) ;
battleMonTarget = ( u8 * ) ( & gBattleMons [ gBankTarget ] ) ;
for ( i = 0 ; i < offsetof ( struct BattlePokemon , pp ) ; i + + )
battleMonAttacker [ i ] = battleMonTarget [ i ] ;
for ( i = 0 ; i < 4 ; i + + )
{
if ( gBattleMoves [ gBattleMons [ gBankAttacker ] . moves [ i ] ] . pp < 5 )
gBattleMons [ gBankAttacker ] . pp [ i ] = gBattleMoves [ gBattleMons [ gBankAttacker ] . moves [ i ] ] . pp ;
else
gBattleMons [ gBankAttacker ] . pp [ i ] = 5 ;
}
gActiveBank = gBankAttacker ;
EmitResetActionMoveSelection ( 0 , RESET_MOVE_SELECTION ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
}
2017-11-25 18:42:31 +01:00
static void atk9C_setsubstitute ( void )
2017-09-26 22:39:59 +02:00
{
u32 hp = gBattleMons [ gBankAttacker ] . maxHP / 4 ;
if ( gBattleMons [ gBankAttacker ] . maxHP / 4 = = 0 )
hp = 1 ;
if ( gBattleMons [ gBankAttacker ] . hp < = hp )
{
gBattleMoveDamage = 0 ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
else
{
gBattleMoveDamage = gBattleMons [ gBankAttacker ] . maxHP / 4 ; // one bit value will only work for pokemon which max hp can go to 1020(which is more than possible in games)
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleMons [ gBankAttacker ] . status2 | = STATUS2_SUBSTITUTE ;
gBattleMons [ gBankAttacker ] . status2 & = ~ ( STATUS2_WRAPPED ) ;
gDisableStructs [ gBankAttacker ] . substituteHP = gBattleMoveDamage ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
gHitMarker | = HITMARKER_IGNORE_SUBSTITUTE ;
}
gBattlescriptCurrInstr + + ;
}
static bool8 IsMoveUncopyableByMimic ( u16 move )
{
s32 i ;
2017-09-28 16:51:24 +02:00
for ( i = 0 ; sMovesForbiddenToCopy [ i ] ! = MIMIC_FORBIDDEN_END
& & sMovesForbiddenToCopy [ i ] ! = move ; i + + ) ;
2017-09-26 22:39:59 +02:00
2017-09-28 16:51:24 +02:00
return ( sMovesForbiddenToCopy [ i ] ! = MIMIC_FORBIDDEN_END ) ;
2017-09-26 22:39:59 +02:00
}
2017-09-28 15:34:21 +02:00
static void atk9D_mimicattackcopy ( void )
2017-09-26 22:39:59 +02:00
{
2017-11-26 18:07:00 +01:00
gChosenMove = 0xFFFF ;
2017-09-26 22:39:59 +02:00
2017-11-26 18:07:00 +01:00
if ( IsMoveUncopyableByMimic ( gLastMoves [ gBankTarget ] )
2017-09-26 22:39:59 +02:00
| | gBattleMons [ gBankAttacker ] . status2 & STATUS2_TRANSFORMED
2017-11-26 18:07:00 +01:00
| | gLastMoves [ gBankTarget ] = = 0
| | gLastMoves [ gBankTarget ] = = 0xFFFF )
2017-09-26 22:39:59 +02:00
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
s32 i ;
for ( i = 0 ; i < 4 ; i + + )
{
2017-11-26 18:07:00 +01:00
if ( gBattleMons [ gBankAttacker ] . moves [ i ] = = gLastMoves [ gBankTarget ] )
2017-09-26 22:39:59 +02:00
break ;
}
if ( i = = 4 )
{
2017-11-26 18:07:00 +01:00
gBattleMons [ gBankAttacker ] . moves [ gCurrMovePos ] = gLastMoves [ gBankTarget ] ;
if ( gBattleMoves [ gLastMoves [ gBankTarget ] ] . pp < 5 )
gBattleMons [ gBankAttacker ] . pp [ gCurrMovePos ] = gBattleMoves [ gLastMoves [ gBankTarget ] ] . pp ;
2017-09-26 22:39:59 +02:00
else
gBattleMons [ gBankAttacker ] . pp [ gCurrMovePos ] = 5 ;
2017-11-26 18:07:00 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , gLastMoves [ gBankTarget ] )
2017-09-26 22:39:59 +02:00
gDisableStructs [ gBankAttacker ] . unk18_b | = gBitTable [ gCurrMovePos ] ;
gBattlescriptCurrInstr + = 5 ;
}
else
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
}
2017-09-28 15:34:21 +02:00
static void atk9E_metronome ( void )
2017-09-26 22:39:59 +02:00
{
while ( 1 )
{
2017-11-11 22:58:23 +01:00
s32 i ;
2017-09-26 22:39:59 +02:00
gCurrentMove = ( Random ( ) & 0x1FF ) + 1 ;
if ( gCurrentMove > LAST_MOVE_INDEX )
continue ;
for ( i = 0 ; i < 4 ; i + + ) ; // ?
2017-11-11 22:58:23 +01:00
i = - 1 ;
while ( 1 )
2017-09-26 22:39:59 +02:00
{
2017-11-11 22:58:23 +01:00
i + + ;
if ( sMovesForbiddenToCopy [ i ] = = gCurrentMove )
2017-09-26 22:39:59 +02:00
break ;
2017-11-11 22:58:23 +01:00
if ( sMovesForbiddenToCopy [ i ] = = METRONOME_FORBIDDEN_END )
2017-09-26 22:39:59 +02:00
break ;
}
2017-11-11 22:58:23 +01:00
if ( sMovesForbiddenToCopy [ i ] = = METRONOME_FORBIDDEN_END )
{
gHitMarker & = ~ ( HITMARKER_ATTACKSTRING_PRINTED ) ;
gBattlescriptCurrInstr = gBattleScriptsForMoveEffects [ gBattleMoves [ gCurrentMove ] . effect ] ;
gBankTarget = GetMoveTarget ( gCurrentMove , 0 ) ;
return ;
}
2017-09-26 22:39:59 +02:00
}
}
2017-09-28 15:34:21 +02:00
static void atk9F_dmgtolevel ( void )
2017-09-26 22:39:59 +02:00
{
gBattleMoveDamage = gBattleMons [ gBankAttacker ] . level ;
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkA0_psywavedamageeffect ( void )
2017-09-26 22:39:59 +02:00
{
s32 randDamage ;
while ( ( randDamage = ( Random ( ) & 0xF ) ) > 10 ) ;
randDamage * = 10 ;
gBattleMoveDamage = gBattleMons [ gBankAttacker ] . level * ( randDamage + 50 ) / 100 ;
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkA1_counterdamagecalculator ( void )
2017-09-26 22:39:59 +02:00
{
u8 sideAttacker = GetBankSide ( gBankAttacker ) ;
u8 sideTarget = GetBankSide ( gProtectStructs [ gBankAttacker ] . physicalBank ) ;
if ( gProtectStructs [ gBankAttacker ] . physicalDmg
& & sideAttacker ! = sideTarget
& & gBattleMons [ gProtectStructs [ gBankAttacker ] . physicalBank ] . hp )
{
gBattleMoveDamage = gProtectStructs [ gBankAttacker ] . physicalDmg * 2 ;
if ( gSideTimers [ sideTarget ] . followmeTimer & & gBattleMons [ gSideTimers [ sideTarget ] . followmeTarget ] . hp )
gBankTarget = gSideTimers [ sideTarget ] . followmeTarget ;
else
gBankTarget = gProtectStructs [ gBankAttacker ] . physicalBank ;
gBattlescriptCurrInstr + = 5 ;
}
else
{
gSpecialStatuses [ gBankAttacker ] . flag20 = 1 ;
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
2017-09-28 15:34:21 +02:00
static void atkA2_mirrorcoatdamagecalculator ( void ) // a copy of atkA1 with the physical -> special field changes
2017-09-26 22:39:59 +02:00
{
u8 sideAttacker = GetBankSide ( gBankAttacker ) ;
u8 sideTarget = GetBankSide ( gProtectStructs [ gBankAttacker ] . specialBank ) ;
if ( gProtectStructs [ gBankAttacker ] . specialDmg & & sideAttacker ! = sideTarget & & gBattleMons [ gProtectStructs [ gBankAttacker ] . specialBank ] . hp )
{
gBattleMoveDamage = gProtectStructs [ gBankAttacker ] . specialDmg * 2 ;
if ( gSideTimers [ sideTarget ] . followmeTimer & & gBattleMons [ gSideTimers [ sideTarget ] . followmeTarget ] . hp )
gBankTarget = gSideTimers [ sideTarget ] . followmeTarget ;
else
gBankTarget = gProtectStructs [ gBankAttacker ] . specialBank ;
gBattlescriptCurrInstr + = 5 ;
}
else
{
gSpecialStatuses [ gBankAttacker ] . flag20 = 1 ;
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
2017-09-28 15:34:21 +02:00
static void atkA3_disablelastusedattack ( void )
2017-09-26 22:39:59 +02:00
{
s32 i ;
for ( i = 0 ; i < 4 ; i + + )
{
2017-11-26 18:07:00 +01:00
if ( gBattleMons [ gBankTarget ] . moves [ i ] = = gLastMoves [ gBankTarget ] )
2017-09-26 22:39:59 +02:00
break ;
}
if ( gDisableStructs [ gBankTarget ] . disabledMove = = 0
& & i ! = 4 & & gBattleMons [ gBankTarget ] . pp [ i ] ! = 0 )
{
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , gBattleMons [ gBankTarget ] . moves [ i ] )
gDisableStructs [ gBankTarget ] . disabledMove = gBattleMons [ gBankTarget ] . moves [ i ] ;
gDisableStructs [ gBankTarget ] . disableTimer1 = ( Random ( ) & 3 ) + 2 ;
gDisableStructs [ gBankTarget ] . disableTimer2 = gDisableStructs [ gBankTarget ] . disableTimer1 ; // used to save the random amount of turns?
gBattlescriptCurrInstr + = 5 ;
}
else
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
2017-11-25 18:42:31 +01:00
static void atkA4_trysetencore ( void )
2017-09-26 22:39:59 +02:00
{
s32 i ;
for ( i = 0 ; i < 4 ; i + + )
{
2017-11-26 18:07:00 +01:00
if ( gBattleMons [ gBankTarget ] . moves [ i ] = = gLastMoves [ gBankTarget ] )
2017-09-26 22:39:59 +02:00
break ;
}
2017-11-26 18:07:00 +01:00
if ( gLastMoves [ gBankTarget ] = = MOVE_STRUGGLE
| | gLastMoves [ gBankTarget ] = = MOVE_ENCORE
| | gLastMoves [ gBankTarget ] = = MOVE_MIRROR_MOVE )
2017-09-26 22:39:59 +02:00
{
i = 4 ;
}
if ( gDisableStructs [ gBankTarget ] . encoredMove = = 0
& & i ! = 4 & & gBattleMons [ gBankTarget ] . pp [ i ] ! = 0 )
{
gDisableStructs [ gBankTarget ] . encoredMove = gBattleMons [ gBankTarget ] . moves [ i ] ;
gDisableStructs [ gBankTarget ] . encoredMovePos = i ;
gDisableStructs [ gBankTarget ] . encoreTimer1 = ( Random ( ) & 3 ) + 3 ;
gDisableStructs [ gBankTarget ] . encoreTimer2 = gDisableStructs [ gBankTarget ] . encoreTimer1 ;
gBattlescriptCurrInstr + = 5 ;
}
else
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
2017-09-28 15:34:21 +02:00
static void atkA5_painsplitdmgcalc ( void )
2017-09-26 22:39:59 +02:00
{
if ( ! ( gBattleMons [ gBankTarget ] . status2 & STATUS2_SUBSTITUTE ) )
{
s32 hpDiff = ( gBattleMons [ gBankAttacker ] . hp + gBattleMons [ gBankTarget ] . hp ) / 2 ;
s32 painSplitHp = gBattleMoveDamage = gBattleMons [ gBankTarget ] . hp - hpDiff ;
u8 * storeLoc = ( void * ) ( & gBattleScripting . painSplitHp ) ;
storeLoc [ 0 ] = ( painSplitHp ) ;
storeLoc [ 1 ] = ( painSplitHp & 0x0000FF00 ) > > 8 ;
storeLoc [ 2 ] = ( painSplitHp & 0x00FF0000 ) > > 16 ;
storeLoc [ 3 ] = ( painSplitHp & 0xFF000000 ) > > 24 ;
gBattleMoveDamage = gBattleMons [ gBankAttacker ] . hp - hpDiff ;
gSpecialStatuses [ gBankTarget ] . moveturnLostHP = 0xFFFF ;
gBattlescriptCurrInstr + = 5 ;
}
else
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
2017-09-28 15:34:21 +02:00
static void atkA6_settypetorandomresistance ( void ) // conversion 2
2017-09-26 22:39:59 +02:00
{
2017-11-26 14:17:02 +01:00
if ( gLastLandedMoves [ gBankAttacker ] = = 0
| | gLastLandedMoves [ gBankAttacker ] = = 0xFFFF )
2017-09-26 22:39:59 +02:00
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
2017-11-26 14:17:02 +01:00
else if ( IsTwoTurnsMove ( gLastLandedMoves [ gBankAttacker ] )
& & gBattleMons [ gLastHitBy [ gBankAttacker ] ] . status2 & STATUS2_MULTIPLETURNS )
2017-09-26 22:39:59 +02:00
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
2017-11-11 20:01:04 +01:00
s32 i , j , rands ;
for ( rands = 0 ; rands < 1000 ; rands + + )
2017-09-26 22:39:59 +02:00
{
2017-11-11 20:01:04 +01:00
while ( ( ( i = ( Random ( ) & 0x7F ) ) > sizeof ( gTypeEffectiveness ) / 3 ) ) ;
2017-09-26 22:39:59 +02:00
2017-11-11 20:01:04 +01:00
i * = 3 ;
2017-09-26 22:39:59 +02:00
2017-11-26 14:17:02 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( i ) = = gLastHitByType [ gBankAttacker ]
2017-11-11 20:01:04 +01:00
& & TYPE_EFFECT_MULTIPLIER ( i ) < = TYPE_MUL_NOT_EFFECTIVE
& & gBattleMons [ gBankAttacker ] . type1 ! = TYPE_EFFECT_DEF_TYPE ( i )
& & gBattleMons [ gBankAttacker ] . type2 ! = TYPE_EFFECT_DEF_TYPE ( i ) )
2017-09-26 22:39:59 +02:00
{
2017-11-11 20:01:04 +01:00
gBattleMons [ gBankAttacker ] . type1 = TYPE_EFFECT_DEF_TYPE ( i ) ;
gBattleMons [ gBankAttacker ] . type2 = TYPE_EFFECT_DEF_TYPE ( i ) ;
2017-09-26 22:39:59 +02:00
2017-11-11 20:01:04 +01:00
PREPARE_TYPE_BUFFER ( gBattleTextBuff1 , TYPE_EFFECT_DEF_TYPE ( i ) )
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
return ;
}
2017-11-11 20:01:04 +01:00
}
2017-09-26 22:39:59 +02:00
2017-11-11 20:01:04 +01:00
for ( j = 0 , rands = 0 ; rands < sizeof ( gTypeEffectiveness ) ; j + = 3 , rands + = 3 )
2017-09-26 22:39:59 +02:00
{
2017-11-11 20:01:04 +01:00
switch ( TYPE_EFFECT_ATK_TYPE ( j ) )
2017-09-26 22:39:59 +02:00
{
2017-11-11 20:01:04 +01:00
case TYPE_ENDTABLE :
case TYPE_FORESIGHT :
break ;
default :
2017-11-26 14:17:02 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( j ) = = gLastHitByType [ gBankAttacker ]
2017-11-11 20:01:04 +01:00
& & TYPE_EFFECT_MULTIPLIER ( j ) < = 5
& & gBattleMons [ gBankAttacker ] . type1 ! = TYPE_EFFECT_DEF_TYPE ( i )
& & gBattleMons [ gBankAttacker ] . type2 ! = TYPE_EFFECT_DEF_TYPE ( i ) )
2017-09-26 22:39:59 +02:00
{
2017-11-11 20:01:04 +01:00
gBattleMons [ gBankAttacker ] . type1 = TYPE_EFFECT_DEF_TYPE ( rands ) ;
gBattleMons [ gBankAttacker ] . type2 = TYPE_EFFECT_DEF_TYPE ( rands ) ;
2017-09-26 22:39:59 +02:00
2017-11-11 20:01:04 +01:00
PREPARE_TYPE_BUFFER ( gBattleTextBuff1 , TYPE_EFFECT_DEF_TYPE ( rands ) )
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
return ;
}
2017-11-11 20:01:04 +01:00
break ;
2017-09-26 22:39:59 +02:00
}
2017-11-11 20:01:04 +01:00
}
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
2017-09-28 15:34:21 +02:00
static void atkA7_setalwayshitflag ( void )
2017-09-26 22:39:59 +02:00
{
gStatuses3 [ gBankTarget ] & = ~ ( STATUS3_ALWAYS_HITS ) ;
gStatuses3 [ gBankTarget ] | = 0x10 ;
gDisableStructs [ gBankTarget ] . bankWithSureHit = gBankAttacker ;
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkA8_copymovepermanently ( void ) // sketch
2017-09-26 22:39:59 +02:00
{
2017-11-26 18:07:00 +01:00
gChosenMove = 0xFFFF ;
2017-09-26 22:39:59 +02:00
if ( ! ( gBattleMons [ gBankAttacker ] . status2 & STATUS2_TRANSFORMED )
2017-11-26 18:07:00 +01:00
& & gLastPrintedMoves [ gBankTarget ] ! = MOVE_STRUGGLE
& & gLastPrintedMoves [ gBankTarget ] ! = 0
& & gLastPrintedMoves [ gBankTarget ] ! = 0xFFFF
& & gLastPrintedMoves [ gBankTarget ] ! = MOVE_SKETCH )
2017-09-26 22:39:59 +02:00
{
s32 i ;
for ( i = 0 ; i < 4 ; i + + )
{
if ( gBattleMons [ gBankAttacker ] . moves [ i ] = = MOVE_SKETCH )
continue ;
2017-11-26 18:07:00 +01:00
if ( gBattleMons [ gBankAttacker ] . moves [ i ] = = gLastPrintedMoves [ gBankTarget ] )
2017-09-26 22:39:59 +02:00
break ;
}
if ( i ! = 4 )
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else // sketch worked
{
struct MovePpInfo movePpData ;
2017-11-26 18:07:00 +01:00
gBattleMons [ gBankAttacker ] . moves [ gCurrMovePos ] = gLastPrintedMoves [ gBankTarget ] ;
gBattleMons [ gBankAttacker ] . pp [ gCurrMovePos ] = gBattleMoves [ gLastPrintedMoves [ gBankTarget ] ] . pp ;
2017-09-26 22:39:59 +02:00
gActiveBank = gBankAttacker ;
for ( i = 0 ; i < 4 ; i + + )
{
2017-10-22 01:04:02 +02:00
movePpData . moves [ i ] = gBattleMons [ gBankAttacker ] . moves [ i ] ;
2017-09-26 22:39:59 +02:00
movePpData . pp [ i ] = gBattleMons [ gBankAttacker ] . pp [ i ] ;
}
movePpData . ppBonuses = gBattleMons [ gBankAttacker ] . ppBonuses ;
EmitSetMonData ( 0 , REQUEST_MOVES_PP_BATTLE , 0 , sizeof ( struct MovePpInfo ) , & movePpData ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
2017-11-26 18:07:00 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , gLastPrintedMoves [ gBankTarget ] )
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
}
}
else
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
2017-09-28 15:34:21 +02:00
static bool8 IsTwoTurnsMove ( u16 move )
2017-09-27 23:43:45 +02:00
{
if ( gBattleMoves [ move ] . effect = = EFFECT_SKULL_BASH
| | gBattleMoves [ move ] . effect = = EFFECT_RAZOR_WIND
| | gBattleMoves [ move ] . effect = = EFFECT_SKY_ATTACK
| | gBattleMoves [ move ] . effect = = EFFECT_SOLARBEAM
2017-11-26 00:33:40 +01:00
| | gBattleMoves [ move ] . effect = = EFFECT_SEMI_INVULNERABLE
2017-09-27 23:43:45 +02:00
| | gBattleMoves [ move ] . effect = = EFFECT_BIDE )
return TRUE ;
else
return FALSE ;
}
static bool8 IsInvalidForSleepTalkOrAssist ( u16 move )
{
if ( move = = 0 | | move = = MOVE_SLEEP_TALK | | move = = MOVE_ASSIST
| | move = = MOVE_MIRROR_MOVE | | move = = MOVE_METRONOME )
return TRUE ;
else
return FALSE ;
}
2017-09-28 15:34:21 +02:00
static u8 AttacksThisTurn ( u8 bank , u16 move ) // Note: returns 1 if it's a charging turn, otherwise 2
2017-09-27 23:43:45 +02:00
{
// first argument is unused
if ( gBattleMoves [ move ] . effect = = EFFECT_SOLARBEAM
& & ( gBattleWeather & WEATHER_SUN_ANY ) )
return 2 ;
if ( gBattleMoves [ move ] . effect = = EFFECT_SKULL_BASH
| | gBattleMoves [ move ] . effect = = EFFECT_RAZOR_WIND
| | gBattleMoves [ move ] . effect = = EFFECT_SKY_ATTACK
| | gBattleMoves [ move ] . effect = = EFFECT_SOLARBEAM
2017-11-26 00:33:40 +01:00
| | gBattleMoves [ move ] . effect = = EFFECT_SEMI_INVULNERABLE
2017-09-27 23:43:45 +02:00
| | gBattleMoves [ move ] . effect = = EFFECT_BIDE )
{
if ( ( gHitMarker & HITMARKER_x8000000 ) )
return 1 ;
}
return 2 ;
}
2017-11-26 01:19:57 +01:00
static void atkA9_trychoosesleeptalkmove ( void )
2017-09-27 23:43:45 +02:00
{
s32 i ;
u8 unusableMovesBits = 0 ;
for ( i = 0 ; i < 4 ; i + + )
{
if ( IsInvalidForSleepTalkOrAssist ( gBattleMons [ gBankAttacker ] . moves [ i ] )
| | gBattleMons [ gBankAttacker ] . moves [ i ] = = MOVE_FOCUS_PUNCH
| | gBattleMons [ gBankAttacker ] . moves [ i ] = = MOVE_UPROAR
| | IsTwoTurnsMove ( gBattleMons [ gBankAttacker ] . moves [ i ] ) )
{
unusableMovesBits | = gBitTable [ i ] ;
}
}
unusableMovesBits = CheckMoveLimitations ( gBankAttacker , unusableMovesBits , ~ ( MOVE_LIMITATION_PP ) ) ;
if ( unusableMovesBits = = 0xF ) // all 4 moves cannot be chosen
{
gBattlescriptCurrInstr + = 5 ;
}
else // at least one move can be chosen
{
u32 movePosition ;
do
{
movePosition = Random ( ) & 3 ;
} while ( ( gBitTable [ movePosition ] & unusableMovesBits ) ) ;
gRandomMove = gBattleMons [ gBankAttacker ] . moves [ movePosition ] ;
gCurrMovePos = movePosition ;
gHitMarker & = ~ ( HITMARKER_ATTACKSTRING_PRINTED ) ;
gBankTarget = GetMoveTarget ( gRandomMove , 0 ) ;
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
2017-11-25 18:42:31 +01:00
static void atkAA_setdestinybond ( void )
2017-09-27 23:43:45 +02:00
{
gBattleMons [ gBankAttacker ] . status2 | = STATUS2_DESTINY_BOND ;
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void TrySetDestinyBondToHappen ( void )
2017-09-27 23:43:45 +02:00
{
u8 sideAttacker = GetBankSide ( gBankAttacker ) ;
u8 sideTarget = GetBankSide ( gBankTarget ) ;
if ( gBattleMons [ gBankTarget ] . status2 & STATUS2_DESTINY_BOND
& & sideAttacker ! = sideTarget
& & ! ( gHitMarker & HITMARKER_GRUDGE ) )
{
gHitMarker | = HITMARKER_DESTINYBOND ;
}
}
2017-11-25 18:42:31 +01:00
static void atkAB_trysetdestinybondtohappen ( void )
2017-09-27 23:43:45 +02:00
{
2017-11-25 18:42:31 +01:00
TrySetDestinyBondToHappen ( ) ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkAC_remaininghptopower ( void )
2017-09-27 23:43:45 +02:00
{
s32 i ;
s32 hpFraction = GetScaledHPFraction ( gBattleMons [ gBankAttacker ] . hp , gBattleMons [ gBankAttacker ] . maxHP , 48 ) ;
for ( i = 0 ; i < ( s32 ) sizeof ( sFlailHpScaleToPowerTable ) ; i + = 2 )
{
if ( hpFraction < = sFlailHpScaleToPowerTable [ i ] )
break ;
}
gDynamicBasePower = sFlailHpScaleToPowerTable [ i + 1 ] ;
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atkAD_tryspiteppreduce ( void )
2017-09-27 23:43:45 +02:00
{
2017-11-26 18:07:00 +01:00
if ( gLastMoves [ gBankTarget ] ! = 0
& & gLastMoves [ gBankTarget ] ! = 0xFFFF )
2017-09-27 23:43:45 +02:00
{
s32 i ;
for ( i = 0 ; i < 4 ; i + + )
{
2017-11-26 18:07:00 +01:00
if ( gLastMoves [ gBankTarget ] = = gBattleMons [ gBankTarget ] . moves [ i ] )
2017-09-27 23:43:45 +02:00
break ;
}
if ( i ! = 4 & & gBattleMons [ gBankTarget ] . pp [ i ] > 1 )
{
s32 ppToDeduct = ( Random ( ) & 3 ) + 2 ;
if ( gBattleMons [ gBankTarget ] . pp [ i ] < ppToDeduct )
ppToDeduct = gBattleMons [ gBankTarget ] . pp [ i ] ;
2017-11-26 18:07:00 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , gLastMoves [ gBankTarget ] )
2017-09-27 23:43:45 +02:00
ConvertIntToDecimalStringN ( gBattleTextBuff2 , ppToDeduct , 0 , 1 ) ;
PREPARE_BYTE_NUMBER_BUFFER ( gBattleTextBuff2 , 1 , ppToDeduct )
gBattleMons [ gBankTarget ] . pp [ i ] - = ppToDeduct ;
gActiveBank = gBankTarget ;
if ( ! ( gDisableStructs [ gActiveBank ] . unk18_b & gBitTable [ i ] )
& & ! ( gBattleMons [ gActiveBank ] . status2 & STATUS2_TRANSFORMED ) )
{
EmitSetMonData ( 0 , REQUEST_PPMOVE1_BATTLE + i , 0 , 1 , & gBattleMons [ gActiveBank ] . pp [ i ] ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
}
gBattlescriptCurrInstr + = 5 ;
if ( gBattleMons [ gBankTarget ] . pp [ i ] = = 0 )
CancelMultiTurnMoves ( gBankTarget ) ;
}
else
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
else
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
2017-11-25 18:42:31 +01:00
static void atkAE_healpartystatus ( void )
2017-09-27 23:43:45 +02:00
{
u32 zero = 0 ;
u8 toHeal = 0 ;
if ( gCurrentMove = = MOVE_HEAL_BELL )
{
struct Pokemon * party ;
s32 i ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
if ( GetBankSide ( gBankAttacker ) = = SIDE_PLAYER )
party = gPlayerParty ;
else
party = gEnemyParty ;
if ( gBattleMons [ gBankAttacker ] . ability ! = ABILITY_SOUNDPROOF )
{
gBattleMons [ gBankAttacker ] . status1 = 0 ;
gBattleMons [ gBankAttacker ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
}
else
{
RecordAbilityBattle ( gBankAttacker , gBattleMons [ gBankAttacker ] . ability ) ;
gBattleCommunication [ MULTISTRING_CHOOSER ] | = 1 ;
}
gActiveBank = gBattleScripting . bank = GetBankByIdentity ( GetBankIdentity ( gBankAttacker ) ^ BIT_MON ) ;
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE
& & ! ( gAbsentBankFlags & gBitTable [ gActiveBank ] ) )
{
if ( gBattleMons [ gActiveBank ] . ability ! = ABILITY_SOUNDPROOF )
{
gBattleMons [ gActiveBank ] . status1 = 0 ;
gBattleMons [ gActiveBank ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
}
else
{
RecordAbilityBattle ( gActiveBank , gBattleMons [ gActiveBank ] . ability ) ;
gBattleCommunication [ MULTISTRING_CHOOSER ] | = 2 ;
}
}
for ( i = 0 ; i < 6 ; i + + )
{
u16 species = GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ;
u8 abilityBit = GetMonData ( & party [ i ] , MON_DATA_ALT_ABILITY ) ;
if ( species ! = 0 & & species ! = SPECIES_EGG )
{
u8 ability ;
if ( gBattlePartyID [ gBankAttacker ] = = i )
ability = gBattleMons [ gBankAttacker ] . ability ;
else if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE
& & gBattlePartyID [ gActiveBank ] = = i
& & ! ( gAbsentBankFlags & gBitTable [ gActiveBank ] ) )
ability = gBattleMons [ gActiveBank ] . ability ;
else
ability = GetAbilityBySpecies ( species , abilityBit ) ;
if ( ability ! = ABILITY_SOUNDPROOF )
toHeal | = ( 1 < < i ) ;
}
}
}
else // Aromatherapy
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 4 ;
toHeal = 0x3F ;
gBattleMons [ gBankAttacker ] . status1 = 0 ;
gBattleMons [ gBankAttacker ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
2017-11-26 13:26:58 +01:00
gActiveBank = GetBankByIdentity ( GetBankIdentity ( gBankAttacker ) ^ BIT_MON ) ;
2017-09-27 23:43:45 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE
& & ! ( gAbsentBankFlags & gBitTable [ gActiveBank ] ) )
{
gBattleMons [ gActiveBank ] . status1 = 0 ;
gBattleMons [ gActiveBank ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
}
}
if ( toHeal )
{
gActiveBank = gBankAttacker ;
EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , toHeal , 4 , & zero ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkAF_cursetarget ( void )
2017-09-27 23:43:45 +02:00
{
if ( gBattleMons [ gBankTarget ] . status2 & STATUS2_CURSED )
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
gBattleMons [ gBankTarget ] . status2 | = STATUS2_CURSED ;
gBattleMoveDamage = gBattleMons [ gBankAttacker ] . maxHP / 2 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattlescriptCurrInstr + = 5 ;
}
}
2017-11-25 18:42:31 +01:00
static void atkB0_trysetspikes ( void )
2017-09-27 23:43:45 +02:00
{
u8 targetSide = GetBankSide ( gBankAttacker ) ^ BIT_SIDE ;
if ( gSideTimers [ targetSide ] . spikesAmount = = 3 )
{
gSpecialStatuses [ gBankAttacker ] . flag20 = 1 ;
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
gSideAffecting [ targetSide ] | = SIDE_STATUS_SPIKES ;
gSideTimers [ targetSide ] . spikesAmount + + ;
gBattlescriptCurrInstr + = 5 ;
}
}
2017-11-25 18:42:31 +01:00
static void atkB1_setforesight ( void )
2017-09-27 23:43:45 +02:00
{
gBattleMons [ gBankTarget ] . status2 | = STATUS2_FORESIGHT ;
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atkB2_trysetperishsong ( void )
2017-09-27 23:43:45 +02:00
{
s32 i ;
s32 notAffectedCount = 0 ;
for ( i = 0 ; i < gNoOfAllBanks ; i + + )
{
if ( gStatuses3 [ i ] & STATUS3_PERISH_SONG
| | gBattleMons [ i ] . ability = = ABILITY_SOUNDPROOF )
{
notAffectedCount + + ;
}
else
{
gStatuses3 [ i ] | = STATUS3_PERISH_SONG ;
2017-11-12 17:11:06 +01:00
gDisableStructs [ i ] . perishSongTimer1 = 3 ;
gDisableStructs [ i ] . perishSongTimer2 = 3 ;
2017-09-27 23:43:45 +02:00
}
}
PressurePPLoseOnUsingPerishSong ( gBankAttacker ) ;
if ( notAffectedCount = = gNoOfAllBanks )
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
else
gBattlescriptCurrInstr + = 5 ;
}
2017-09-28 15:34:21 +02:00
static void atkB3_rolloutdamagecalculation ( void )
2017-09-27 23:43:45 +02:00
{
if ( gBattleMoveFlags & MOVESTATUS_NOEFFECT )
{
CancelMultiTurnMoves ( gBankAttacker ) ;
2017-11-25 18:42:31 +01:00
gBattlescriptCurrInstr = BattleScript_MoveMissedPause ;
2017-09-27 23:43:45 +02:00
}
else
{
s32 i ;
if ( ! ( gBattleMons [ gBankAttacker ] . status2 & STATUS2_MULTIPLETURNS ) ) // first hit
{
2017-10-06 17:06:45 +02:00
gDisableStructs [ gBankAttacker ] . rolloutCounter1 = 5 ;
gDisableStructs [ gBankAttacker ] . rolloutCounter2 = 5 ;
2017-09-27 23:43:45 +02:00
gBattleMons [ gBankAttacker ] . status2 | = STATUS2_MULTIPLETURNS ;
gLockedMoves [ gBankAttacker ] = gCurrentMove ;
}
2017-10-06 17:06:45 +02:00
if ( - - gDisableStructs [ gBankAttacker ] . rolloutCounter1 = = 0 ) // last hit
2017-09-27 23:43:45 +02:00
{
gBattleMons [ gBankAttacker ] . status2 & = ~ ( STATUS2_MULTIPLETURNS ) ;
}
gDynamicBasePower = gBattleMoves [ gCurrentMove ] . power ;
2017-10-06 17:06:45 +02:00
for ( i = 1 ; i < ( 5 - gDisableStructs [ gBankAttacker ] . rolloutCounter1 ) ; i + + )
2017-09-27 23:43:45 +02:00
gDynamicBasePower * = 2 ;
if ( gBattleMons [ gBankAttacker ] . status2 & STATUS2_DEFENSE_CURL )
gDynamicBasePower * = 2 ;
gBattlescriptCurrInstr + + ;
}
}
2017-09-28 15:34:21 +02:00
static void atkB4_jumpifconfusedandstatmaxed ( void )
2017-09-27 23:43:45 +02:00
{
if ( gBattleMons [ gBankTarget ] . status2 & STATUS2_CONFUSION
& & gBattleMons [ gBankTarget ] . statStages [ gBattlescriptCurrInstr [ 1 ] ] = = 0xC )
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 2 ) ;
else
gBattlescriptCurrInstr + = 6 ;
}
2017-09-28 15:34:21 +02:00
static void atkB5_furycuttercalc ( void )
2017-09-27 23:43:45 +02:00
{
if ( gBattleMoveFlags & MOVESTATUS_NOEFFECT )
{
gDisableStructs [ gBankAttacker ] . furyCutterCounter = 0 ;
2017-11-25 18:42:31 +01:00
gBattlescriptCurrInstr = BattleScript_MoveMissedPause ;
2017-09-27 23:43:45 +02:00
}
else
{
s32 i ;
if ( gDisableStructs [ gBankAttacker ] . furyCutterCounter ! = 5 )
gDisableStructs [ gBankAttacker ] . furyCutterCounter + + ;
gDynamicBasePower = gBattleMoves [ gCurrentMove ] . power ;
for ( i = 1 ; i < gDisableStructs [ gBankAttacker ] . furyCutterCounter ; i + + )
gDynamicBasePower * = 2 ;
gBattlescriptCurrInstr + + ;
}
}
2017-09-28 15:34:21 +02:00
static void atkB6_happinesstodamagecalculation ( void )
2017-09-27 23:43:45 +02:00
{
if ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_RETURN )
gDynamicBasePower = 10 * ( gBattleMons [ gBankAttacker ] . friendship ) / 25 ;
else // EFFECT_FRUSTRATION
gDynamicBasePower = 10 * ( 255 - gBattleMons [ gBankAttacker ] . friendship ) / 25 ;
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkB7_presentdamagecalculation ( void )
2017-09-27 23:43:45 +02:00
{
s32 rand = Random ( ) & 0xFF ;
if ( rand < 102 )
gDynamicBasePower = 40 ;
else if ( rand < 178 )
gDynamicBasePower = 80 ;
else if ( rand < 204 )
gDynamicBasePower = 120 ;
else
{
gBattleMoveDamage = gBattleMons [ gBankTarget ] . maxHP / 4 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleMoveDamage * = - 1 ;
}
if ( rand < 204 )
2017-11-25 18:42:31 +01:00
gBattlescriptCurrInstr = BattleScript_HitFromCritCalc ;
2017-09-27 23:43:45 +02:00
else if ( gBattleMons [ gBankTarget ] . maxHP = = gBattleMons [ gBankTarget ] . hp )
gBattlescriptCurrInstr = BattleScript_AlreadyAtFullHp ;
else
{
gBattleMoveFlags & = ~ ( MOVESTATUS_NOTAFFECTED ) ;
gBattlescriptCurrInstr = BattleScript_PresentHealTarget ;
}
}
2017-11-25 18:42:31 +01:00
static void atkB8_setsafeguard ( void )
2017-09-27 23:43:45 +02:00
{
if ( gSideAffecting [ GET_BANK_SIDE ( gBankAttacker ) ] & SIDE_STATUS_SAFEGUARD )
{
gBattleMoveFlags | = MOVESTATUS_MISSED ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
else
{
gSideAffecting [ GET_BANK_SIDE ( gBankAttacker ) ] | = SIDE_STATUS_SAFEGUARD ;
gSideTimers [ GET_BANK_SIDE ( gBankAttacker ) ] . safeguardTimer = 5 ;
gSideTimers [ GET_BANK_SIDE ( gBankAttacker ) ] . safeguardBank = gBankAttacker ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 5 ;
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkB9_magnitudedamagecalculation ( void )
2017-09-27 23:43:45 +02:00
{
s32 magnitude = Random ( ) % 100 ;
if ( magnitude < 5 )
{
gDynamicBasePower = 10 ;
magnitude = 4 ;
}
else if ( magnitude < 15 )
{
gDynamicBasePower = 30 ;
magnitude = 5 ;
}
else if ( magnitude < 35 )
{
gDynamicBasePower = 50 ;
magnitude = 6 ;
}
else if ( magnitude < 65 )
{
gDynamicBasePower = 70 ;
magnitude = 7 ;
}
else if ( magnitude < 85 )
{
gDynamicBasePower = 90 ;
magnitude = 8 ;
}
else if ( magnitude < 95 )
{
gDynamicBasePower = 110 ;
magnitude = 9 ;
}
else
{
gDynamicBasePower = 150 ;
magnitude = 10 ;
}
PREPARE_BYTE_NUMBER_BUFFER ( gBattleTextBuff1 , 2 , magnitude )
for ( gBankTarget = 0 ; gBankTarget < gNoOfAllBanks ; gBankTarget + + )
{
if ( gBankTarget = = gBankAttacker )
continue ;
if ( ! ( gAbsentBankFlags & gBitTable [ gBankTarget ] ) ) // a valid target was found
break ;
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkBA_jumpifnopursuitswitchdmg ( void )
2017-09-27 23:43:45 +02:00
{
if ( gMultiHitCounter = = 1 )
{
if ( GetBankSide ( gBankAttacker ) = = SIDE_PLAYER )
gBankTarget = GetBankByIdentity ( IDENTITY_OPPONENT_MON1 ) ;
else
gBankTarget = GetBankByIdentity ( IDENTITY_PLAYER_MON1 ) ;
}
else
{
if ( GetBankSide ( gBankAttacker ) = = SIDE_PLAYER )
gBankTarget = GetBankByIdentity ( IDENTITY_OPPONENT_MON2 ) ;
else
gBankTarget = GetBankByIdentity ( IDENTITY_PLAYER_MON2 ) ;
}
2017-12-02 00:03:46 +01:00
if ( gActionForBanks [ gBankTarget ] = = ACTION_USE_MOVE
2017-09-27 23:43:45 +02:00
& & gBankAttacker = = * ( gBattleStruct - > moveTarget + gBankTarget )
& & ! ( gBattleMons [ gBankTarget ] . status1 & ( STATUS_SLEEP | STATUS_FREEZE ) )
& & gBattleMons [ gBankAttacker ] . hp
& & ! gDisableStructs [ gBankTarget ] . truantCounter
& & gChosenMovesByBanks [ gBankTarget ] = = MOVE_PURSUIT )
{
s32 i ;
for ( i = 0 ; i < gNoOfAllBanks ; i + + )
{
2017-10-04 19:25:14 +02:00
if ( gBanksByTurnOrder [ i ] = = gBankTarget )
gActionsByTurnOrder [ i ] = 11 ;
2017-09-27 23:43:45 +02:00
}
gCurrentMove = MOVE_PURSUIT ;
2017-10-06 00:12:01 +02:00
gCurrMovePos = gUnknown_020241E9 = * ( gBattleStruct - > chosenMovePositions + gBankTarget ) ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 5 ;
gBattleScripting . animTurn = 1 ;
gHitMarker & = ~ ( HITMARKER_ATTACKSTRING_PRINTED ) ;
}
else
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
2017-09-28 15:34:21 +02:00
static void atkBB_setsunny ( void )
2017-09-27 23:43:45 +02:00
{
if ( gBattleWeather & WEATHER_SUN_ANY )
{
gBattleMoveFlags | = MOVESTATUS_MISSED ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
}
else
{
gBattleWeather = WEATHER_SUN_TEMPORARY ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 4 ;
gWishFutureKnock . weatherDuration = 5 ;
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkBC_maxattackhalvehp ( void ) // belly drum
2017-09-27 23:43:45 +02:00
{
u32 halfHp = gBattleMons [ gBankAttacker ] . maxHP / 2 ;
if ( ! ( gBattleMons [ gBankAttacker ] . maxHP / 2 ) )
halfHp = 1 ;
if ( gBattleMons [ gBankAttacker ] . statStages [ STAT_STAGE_ATK ] < 12
& & gBattleMons [ gBankAttacker ] . hp > halfHp )
{
gBattleMons [ gBankAttacker ] . statStages [ STAT_STAGE_ATK ] = 12 ;
gBattleMoveDamage = gBattleMons [ gBankAttacker ] . maxHP / 2 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattlescriptCurrInstr + = 5 ;
}
else
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
2017-09-28 15:34:21 +02:00
static void atkBD_copyfoestats ( void ) // psych up
2017-09-27 23:43:45 +02:00
{
s32 i ;
for ( i = 0 ; i < BATTLE_STATS_NO ; i + + )
{
gBattleMons [ gBankAttacker ] . statStages [ i ] = gBattleMons [ gBankTarget ] . statStages [ i ] ;
}
gBattlescriptCurrInstr + = 5 ; // Has an unused jump ptr(possibly for a failed attempt) parameter.
}
2017-09-28 15:34:21 +02:00
static void atkBE_rapidspinfree ( void )
2017-09-27 23:43:45 +02:00
{
if ( gBattleMons [ gBankAttacker ] . status2 & STATUS2_WRAPPED )
{
gBattleScripting . bank = gBankTarget ;
gBattleMons [ gBankAttacker ] . status2 & = ~ ( STATUS2_WRAPPED ) ;
gBankTarget = * ( gBattleStruct - > wrappedBy + gBankAttacker ) ;
gBattleTextBuff1 [ 0 ] = B_BUFF_PLACEHOLDER_BEGIN ;
gBattleTextBuff1 [ 1 ] = B_BUFF_MOVE ;
gBattleTextBuff1 [ 2 ] = * ( gBattleStruct - > wrappedMove + gBankAttacker * 2 + 0 ) ;
gBattleTextBuff1 [ 3 ] = * ( gBattleStruct - > wrappedMove + gBankAttacker * 2 + 1 ) ;
gBattleTextBuff1 [ 4 ] = B_BUFF_EOS ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_WrapFree ;
}
else if ( gStatuses3 [ gBankAttacker ] & STATUS3_LEECHSEED )
{
gStatuses3 [ gBankAttacker ] & = ~ ( STATUS3_LEECHSEED ) ;
gStatuses3 [ gBankAttacker ] & = ~ ( STATUS3_LEECHSEED_BANK ) ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_LeechSeedFree ;
}
else if ( gSideAffecting [ GetBankSide ( gBankAttacker ) ] & SIDE_STATUS_SPIKES )
{
gSideAffecting [ GetBankSide ( gBankAttacker ) ] & = ~ ( SIDE_STATUS_SPIKES ) ;
gSideTimers [ GetBankSide ( gBankAttacker ) ] . spikesAmount = 0 ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_SpikesFree ;
}
else
{
gBattlescriptCurrInstr + + ;
}
}
2017-11-25 18:42:31 +01:00
static void atkBF_setdefensecurlbit ( void )
2017-09-27 23:43:45 +02:00
{
gBattleMons [ gBankAttacker ] . status2 | = STATUS2_DEFENSE_CURL ;
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkC0_recoverbasedonsunlight ( void )
2017-09-27 23:43:45 +02:00
{
gBankTarget = gBankAttacker ;
if ( gBattleMons [ gBankAttacker ] . hp ! = gBattleMons [ gBankAttacker ] . maxHP )
{
if ( gBattleWeather = = 0 | | ! WEATHER_HAS_EFFECT )
gBattleMoveDamage = gBattleMons [ gBankAttacker ] . maxHP / 2 ;
else if ( gBattleWeather & WEATHER_SUN_ANY )
gBattleMoveDamage = 20 * gBattleMons [ gBankAttacker ] . maxHP / 30 ;
else // not sunny weather
gBattleMoveDamage = gBattleMons [ gBankAttacker ] . maxHP / 4 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleMoveDamage * = - 1 ;
gBattlescriptCurrInstr + = 5 ;
}
else
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
# ifdef NONMATCHING
2017-11-25 18:42:31 +01:00
static void atkC1_hiddenpowercalc ( void )
2017-09-27 23:43:45 +02:00
{
2017-11-12 00:16:46 +01:00
u32 powerBits = 0 ;
u32 typeBits = 0 ;
2017-09-27 23:43:45 +02:00
2017-11-12 00:16:46 +01:00
powerBits | = ( ( gBattleMons [ gBankAttacker ] . hpIV & 2 ) > > 1 ) ;
powerBits | = ( ( gBattleMons [ gBankAttacker ] . attackIV & 2 ) < < 0 ) ;
powerBits | = ( ( gBattleMons [ gBankAttacker ] . defenseIV & 2 ) < < 1 ) ;
powerBits | = ( ( gBattleMons [ gBankAttacker ] . speedIV & 2 ) < < 2 ) ;
powerBits | = ( ( gBattleMons [ gBankAttacker ] . spAttackIV & 2 ) < < 3 ) ;
powerBits | = ( ( gBattleMons [ gBankAttacker ] . spDefenseIV & 2 ) < < 4 ) ;
2017-09-27 23:43:45 +02:00
2017-11-12 00:16:46 +01:00
typeBits | = ( ( gBattleMons [ gBankAttacker ] . hpIV & 1 ) < < 0 ) ;
typeBits | = ( ( gBattleMons [ gBankAttacker ] . attackIV & 1 ) < < 1 ) ;
typeBits | = ( ( gBattleMons [ gBankAttacker ] . defenseIV & 1 ) < < 2 ) ;
typeBits | = ( ( gBattleMons [ gBankAttacker ] . speedIV & 1 ) < < 3 ) ;
typeBits | = ( ( gBattleMons [ gBankAttacker ] . spAttackIV & 1 ) < < 4 ) ;
typeBits | = ( ( gBattleMons [ gBankAttacker ] . spDefenseIV & 1 ) < < 5 ) ;
2017-09-27 23:43:45 +02:00
gDynamicBasePower = ( 40 * powerBits ) / 63 + 30 ;
gBattleStruct - > dynamicMoveType = ( 15 * typeBits ) / 63 + 1 ;
if ( gBattleStruct - > dynamicMoveType > 8 )
gBattleStruct - > dynamicMoveType + + ;
gBattleStruct - > dynamicMoveType | = 0xC0 ;
gBattlescriptCurrInstr + + ;
}
# else
__attribute__ ( ( naked ) )
2017-11-25 18:42:31 +01:00
static void atkC1_hiddenpowercalc ( void )
2017-09-27 23:43:45 +02:00
{
asm ( " .syntax unified \n \
push { r4 - r7 , lr } \ n \
mov r7 , r10 \ n \
mov r6 , r9 \ n \
mov r5 , r8 \ n \
push { r5 - r7 } \ n \
ldr r2 , = gBattleMons \ n \
ldr r0 , = gBankAttacker \ n \
ldrb r1 , [ r0 ] \ n \
movs r0 , 0x58 \ n \
adds r4 , r1 , 0 \ n \
muls r4 , r0 \ n \
adds r4 , r2 \ n \
ldrb r0 , [ r4 , 0x14 ] \ n \
mov r10 , r0 \ n \
mov r7 , r10 \ n \
lsls r7 , 27 \ n \
adds r0 , r7 , 0 \ n \
lsrs r0 , 27 \ n \
mov r10 , r0 \ n \
movs r1 , 0x2 \ n \
mov r2 , r10 \ n \
ands r2 , r1 \ n \
asrs r2 , 1 \ n \
ldrh r7 , [ r4 , 0x14 ] \ n \
mov r9 , r7 \ n \
mov r0 , r9 \ n \
lsls r0 , 22 \ n \
mov r9 , r0 \ n \
lsrs r3 , r0 , 27 \ n \
adds r0 , r1 , 0 \ n \
ands r0 , r3 \ n \
orrs r2 , r0 \ n \
ldrb r7 , [ r4 , 0x15 ] \ n \
mov r8 , r7 \ n \
mov r0 , r8 \ n \
lsls r0 , 25 \ n \
mov r8 , r0 \ n \
lsrs r3 , r0 , 27 \ n \
adds r0 , r1 , 0 \ n \
ands r0 , r3 \ n \
lsls r0 , 1 \ n \
orrs r2 , r0 \ n \
ldr r6 , [ r4 , 0x14 ] \ n \
lsls r6 , 12 \ n \
lsrs r3 , r6 , 27 \ n \
adds r0 , r1 , 0 \ n \
ands r0 , r3 \ n \
lsls r0 , 2 \ n \
orrs r2 , r0 \ n \
ldrh r5 , [ r4 , 0x16 ] \ n \
lsls r5 , 23 \ n \
lsrs r3 , r5 , 27 \ n \
adds r0 , r1 , 0 \ n \
ands r0 , r3 \ n \
lsls r0 , 3 \ n \
orrs r2 , r0 \ n \
ldrb r3 , [ r4 , 0x17 ] \ n \
lsls r3 , 26 \ n \
lsrs r0 , r3 , 27 \ n \
ands r1 , r0 \ n \
lsls r1 , 4 \ n \
orrs r2 , r1 \ n \
movs r1 , 0x1 \ n \
adds r4 , r1 , 0 \ n \
mov r7 , r10 \ n \
ands r4 , r7 \ n \
mov r0 , r9 \ n \
lsrs r0 , 27 \ n \
mov r9 , r0 \ n \
adds r0 , r1 , 0 \ n \
mov r7 , r9 \ n \
ands r0 , r7 \ n \
lsls r0 , 1 \ n \
orrs r4 , r0 \ n \
mov r0 , r8 \ n \
lsrs r0 , 27 \ n \
mov r8 , r0 \ n \
adds r0 , r1 , 0 \ n \
mov r7 , r8 \ n \
ands r0 , r7 \ n \
lsls r0 , 2 \ n \
orrs r4 , r0 \ n \
lsrs r6 , 27 \ n \
adds r0 , r1 , 0 \ n \
ands r0 , r6 \ n \
lsls r0 , 3 \ n \
orrs r4 , r0 \ n \
lsrs r5 , 27 \ n \
adds r0 , r1 , 0 \ n \
ands r0 , r5 \ n \
lsls r0 , 4 \ n \
orrs r4 , r0 \ n \
lsrs r3 , 27 \ n \
ands r1 , r3 \ n \
lsls r1 , 5 \ n \
orrs r4 , r1 \ n \
ldr r5 , = gDynamicBasePower \ n \
lsls r0 , r2 , 2 \ n \
adds r0 , r2 \ n \
lsls r0 , 3 \ n \
movs r1 , 0x3F \ n \
bl __divsi3 \ n \
adds r0 , 0x1E \ n \
strh r0 , [ r5 ] \ n \
ldr r6 , = gBattleStruct \ n \
ldr r5 , [ r6 ] \ n \
lsls r0 , r4 , 4 \ n \
subs r0 , r4 \ n \
movs r1 , 0x3F \ n \
bl __divsi3 \ n \
adds r0 , 0x1 \ n \
strb r0 , [ r5 , 0x13 ] \ n \
ldr r1 , [ r6 ] \ n \
ldrb r0 , [ r1 , 0x13 ] \ n \
cmp r0 , 0x8 \ n \
bls _080544F0 \ n \
adds r0 , 0x1 \ n \
strb r0 , [ r1 , 0x13 ] \ n \
_080544F0 : \ n \
ldr r2 , [ r6 ] \ n \
ldrb r0 , [ r2 , 0x13 ] \ n \
movs r1 , 0xC0 \ n \
orrs r0 , r1 \ n \
strb r0 , [ r2 , 0x13 ] \ n \
ldr r1 , = gBattlescriptCurrInstr \ n \
ldr r0 , [ r1 ] \ n \
adds r0 , 0x1 \ n \
str r0 , [ r1 ] \ n \
pop { r3 - r5 } \ n \
mov r8 , r3 \ n \
mov r9 , r4 \ n \
mov r10 , r5 \ n \
pop { r4 - r7 } \ n \
pop { r0 } \ n \
bx r0 \ n \
. pool \ n \
. syntax divided " );
}
# endif // NONMATCHING
2017-11-25 18:42:31 +01:00
static void atkC2_selectfirstvalidtarget ( void )
2017-09-27 23:43:45 +02:00
{
for ( gBankTarget = 0 ; gBankTarget < gNoOfAllBanks ; gBankTarget + + )
{
if ( gBankTarget = = gBankAttacker )
continue ;
if ( ! ( gAbsentBankFlags & gBitTable [ gBankTarget ] ) )
break ;
}
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atkC3_trysetfutureattack ( void )
2017-09-27 23:43:45 +02:00
{
if ( gWishFutureKnock . futureSightCounter [ gBankTarget ] ! = 0 )
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
gSideAffecting [ GET_BANK_SIDE ( gBankTarget ) ] | = SIDE_STATUS_FUTUREATTACK ;
gWishFutureKnock . futureSightMove [ gBankTarget ] = gCurrentMove ;
gWishFutureKnock . futureSightAttacker [ gBankTarget ] = gBankAttacker ;
gWishFutureKnock . futureSightCounter [ gBankTarget ] = 3 ;
gWishFutureKnock . futureSightDmg [ gBankTarget ] = CalculateBaseDamage ( & gBattleMons [ gBankAttacker ] , & gBattleMons [ gBankTarget ] , gCurrentMove ,
gSideAffecting [ GET_BANK_SIDE ( gBankTarget ) ] , 0 ,
0 , gBankAttacker , gBankTarget ) ;
if ( gProtectStructs [ gBankAttacker ] . helpingHand )
gWishFutureKnock . futureSightDmg [ gBankTarget ] = gWishFutureKnock . futureSightDmg [ gBankTarget ] * 15 / 10 ;
if ( gCurrentMove = = MOVE_DOOM_DESIRE )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
gBattlescriptCurrInstr + = 5 ;
}
}
2017-11-25 18:42:31 +01:00
static void atkC4_trydobeatup ( void )
2017-09-27 23:43:45 +02:00
{
2017-11-25 18:42:31 +01:00
struct Pokemon * party ;
2017-09-27 23:43:45 +02:00
if ( GetBankSide ( gBankAttacker ) = = SIDE_PLAYER )
party = gPlayerParty ;
else
party = gEnemyParty ;
if ( gBattleMons [ gBankTarget ] . hp = = 0 )
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
u8 beforeLoop = gBattleCommunication [ 0 ] ;
for ( ; gBattleCommunication [ 0 ] < 6 ; gBattleCommunication [ 0 ] + + )
{
if ( GetMonData ( & party [ gBattleCommunication [ 0 ] ] , MON_DATA_HP )
& & GetMonData ( & party [ gBattleCommunication [ 0 ] ] , MON_DATA_SPECIES2 )
& & GetMonData ( & party [ gBattleCommunication [ 0 ] ] , MON_DATA_SPECIES2 ) ! = SPECIES_EGG
& & ! GetMonData ( & party [ gBattleCommunication [ 0 ] ] , MON_DATA_STATUS ) )
break ;
}
if ( gBattleCommunication [ 0 ] < 6 )
{
PREPARE_MON_NICK_WITH_PREFIX_BUFFER ( gBattleTextBuff1 , gBankAttacker , gBattleCommunication [ 0 ] )
gBattlescriptCurrInstr + = 9 ;
gBattleMoveDamage = gBaseStats [ GetMonData ( & party [ gBattleCommunication [ 0 ] ] , MON_DATA_SPECIES ) ] . baseAttack ;
gBattleMoveDamage * = gBattleMoves [ gCurrentMove ] . power ;
gBattleMoveDamage * = ( GetMonData ( & party [ gBattleCommunication [ 0 ] ] , MON_DATA_LEVEL ) * 2 / 5 + 2 ) ;
gBattleMoveDamage / = gBaseStats [ gBattleMons [ gBankTarget ] . species ] . baseDefense ;
gBattleMoveDamage = ( gBattleMoveDamage / 50 ) + 2 ;
if ( gProtectStructs [ gBankAttacker ] . helpingHand )
gBattleMoveDamage = gBattleMoveDamage * 15 / 10 ;
gBattleCommunication [ 0 ] + + ;
}
else if ( beforeLoop ! = 0 )
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
else
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 5 ) ;
}
}
2017-09-28 15:34:21 +02:00
static void atkC5_setsemiinvulnerablebit ( void )
2017-09-27 23:43:45 +02:00
{
switch ( gCurrentMove )
{
case MOVE_FLY :
case MOVE_BOUNCE :
gStatuses3 [ gBankAttacker ] | = STATUS3_ON_AIR ;
break ;
case MOVE_DIG :
gStatuses3 [ gBankAttacker ] | = STATUS3_UNDERGROUND ;
break ;
case MOVE_DIVE :
gStatuses3 [ gBankAttacker ] | = STATUS3_UNDERWATER ;
break ;
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkC6_clearsemiinvulnerablebit ( void )
2017-09-27 23:43:45 +02:00
{
switch ( gCurrentMove )
{
case MOVE_FLY :
case MOVE_BOUNCE :
gStatuses3 [ gBankAttacker ] & = ~ STATUS3_ON_AIR ;
break ;
case MOVE_DIG :
gStatuses3 [ gBankAttacker ] & = ~ STATUS3_UNDERGROUND ;
break ;
case MOVE_DIVE :
gStatuses3 [ gBankAttacker ] & = ~ STATUS3_UNDERWATER ;
break ;
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkC7_setminimize ( void )
2017-09-27 23:43:45 +02:00
{
if ( gHitMarker & HITMARKER_OBEYS )
gStatuses3 [ gBankAttacker ] | = STATUS3_MINIMIZED ;
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkC8_sethail ( void )
2017-09-27 23:43:45 +02:00
{
if ( gBattleWeather & WEATHER_HAIL_ANY )
{
gBattleMoveFlags | = MOVESTATUS_MISSED ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
}
else
{
gBattleWeather = WEATHER_HAIL ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 5 ;
gWishFutureKnock . weatherDuration = 5 ;
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkC9_jumpifattackandspecialattackcannotfall ( void ) // memento
2017-09-27 23:43:45 +02:00
{
if ( gBattleMons [ gBankTarget ] . statStages [ STAT_STAGE_ATK ] = = 0
& & gBattleMons [ gBankTarget ] . statStages [ STAT_STAGE_SPATK ] = = 0
& & gBattleCommunication [ 6 ] ! = 1 )
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
gActiveBank = gBankAttacker ;
gBattleMoveDamage = gBattleMons [ gActiveBank ] . hp ;
2017-10-22 18:43:15 +02:00
EmitHealthBarUpdate ( 0 , INSTANT_HP_BAR_DROP ) ;
2017-09-27 23:43:45 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 5 ;
}
}
2017-09-28 15:34:21 +02:00
static void atkCA_setforcedtarget ( void ) // follow me
2017-09-27 23:43:45 +02:00
{
gSideTimers [ GetBankSide ( gBankAttacker ) ] . followmeTimer = 1 ;
gSideTimers [ GetBankSide ( gBankAttacker ) ] . followmeTarget = gBankAttacker ;
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkCB_setcharge ( void )
2017-09-27 23:43:45 +02:00
{
gStatuses3 [ gBankAttacker ] | = STATUS3_CHARGED_UP ;
gDisableStructs [ gBankAttacker ] . chargeTimer1 = 2 ;
gDisableStructs [ gBankAttacker ] . chargeTimer2 = 2 ;
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkCC_callterrainattack ( void ) // nature power
2017-09-27 23:43:45 +02:00
{
gHitMarker & = ~ ( HITMARKER_ATTACKSTRING_PRINTED ) ;
gCurrentMove = sNaturePowerMoves [ gBattleTerrain ] ;
gBankTarget = GetMoveTarget ( gCurrentMove , 0 ) ;
BattleScriptPush ( gBattleScriptsForMoveEffects [ gBattleMoves [ gCurrentMove ] . effect ] ) ;
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkCD_cureifburnedparalysedorpoisoned ( void ) // refresh
2017-09-27 23:43:45 +02:00
{
if ( gBattleMons [ gBankAttacker ] . status1 & ( STATUS_POISON | STATUS_BURN | STATUS_PARALYSIS | STATUS_TOXIC_POISON ) )
{
gBattleMons [ gBankAttacker ] . status1 = 0 ;
gBattlescriptCurrInstr + = 5 ;
gActiveBank = gBankAttacker ;
EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gActiveBank ] . status1 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
}
else
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
2017-09-28 15:34:21 +02:00
static void atkCE_settorment ( void )
2017-09-27 23:43:45 +02:00
{
if ( gBattleMons [ gBankTarget ] . status2 & STATUS2_TORMENT )
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
gBattleMons [ gBankTarget ] . status2 | = STATUS2_TORMENT ;
gBattlescriptCurrInstr + = 5 ;
}
}
2017-09-28 15:34:21 +02:00
static void atkCF_jumpifnodamage ( void )
2017-09-27 23:43:45 +02:00
{
if ( gProtectStructs [ gBankAttacker ] . physicalDmg | | gProtectStructs [ gBankAttacker ] . specialDmg )
gBattlescriptCurrInstr + = 5 ;
else
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
2017-09-28 15:34:21 +02:00
static void atkD0_settaunt ( void )
2017-09-27 23:43:45 +02:00
{
if ( gDisableStructs [ gBankTarget ] . tauntTimer1 = = 0 )
{
gDisableStructs [ gBankTarget ] . tauntTimer1 = 2 ;
gDisableStructs [ gBankTarget ] . tauntTimer2 = 2 ;
gBattlescriptCurrInstr + = 5 ;
}
else
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
2017-11-25 18:42:31 +01:00
static void atkD1_trysethelpinghand ( void )
2017-09-27 23:43:45 +02:00
{
gBankTarget = GetBankByIdentity ( GetBankIdentity ( gBankAttacker ) ^ BIT_MON ) ;
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE
& & ! ( gAbsentBankFlags & gBitTable [ gBankTarget ] )
& & ! gProtectStructs [ gBankAttacker ] . helpingHand
& & ! gProtectStructs [ gBankTarget ] . helpingHand )
{
gProtectStructs [ gBankTarget ] . helpingHand = 1 ;
gBattlescriptCurrInstr + = 5 ;
}
else
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
2017-11-25 18:42:31 +01:00
static void atkD2_tryswapitems ( void ) // trick
2017-09-27 23:43:45 +02:00
{
// opponent can't swap items with player in regular battles
if ( gBattleTypeFlags & BATTLE_TYPE_x4000000
| | ( GetBankSide ( gBankAttacker ) = = SIDE_OPPONENT
& & ! ( gBattleTypeFlags & ( BATTLE_TYPE_LINK
| BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_FRONTIER
| BATTLE_TYPE_SECRET_BASE
| BATTLE_TYPE_x2000000 ) ) ) )
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
u8 sideAttacker = GetBankSide ( gBankAttacker ) ;
u8 sideTarget = GetBankSide ( gBankTarget ) ;
// you can't swap items if they were knocked off in regular battles
if ( ! ( gBattleTypeFlags & ( BATTLE_TYPE_LINK
| BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_FRONTIER
| BATTLE_TYPE_SECRET_BASE
| BATTLE_TYPE_x2000000 ) )
& & ( gWishFutureKnock . knockedOffPokes [ sideAttacker ] & gBitTable [ gBattlePartyID [ gBankAttacker ] ]
| | gWishFutureKnock . knockedOffPokes [ sideTarget ] & gBitTable [ gBattlePartyID [ gBankTarget ] ] ) )
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
// can't swap if two pokemon don't have an item
// or if either of them is an enigma berry or a mail
else if ( ( gBattleMons [ gBankAttacker ] . item = = 0 & & gBattleMons [ gBankTarget ] . item = = 0 )
| | gBattleMons [ gBankAttacker ] . item = = ITEM_ENIGMA_BERRY
| | gBattleMons [ gBankTarget ] . item = = ITEM_ENIGMA_BERRY
| | IS_ITEM_MAIL ( gBattleMons [ gBankAttacker ] . item )
| | IS_ITEM_MAIL ( gBattleMons [ gBankTarget ] . item ) )
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
// check if ability prevents swapping
else if ( gBattleMons [ gBankTarget ] . ability = = ABILITY_STICKY_HOLD )
{
gBattlescriptCurrInstr = BattleScript_StickyHoldActivates ;
gLastUsedAbility = gBattleMons [ gBankTarget ] . ability ;
RecordAbilityBattle ( gBankTarget , gLastUsedAbility ) ;
}
// took a while, but all checks passed and items can be safely swapped
else
{
u16 oldItemAtk , * newItemAtk ;
newItemAtk = & gBattleStruct - > changedItems [ gBankAttacker ] ;
oldItemAtk = gBattleMons [ gBankAttacker ] . item ;
* newItemAtk = gBattleMons [ gBankTarget ] . item ;
gBattleMons [ gBankAttacker ] . item = 0 ;
gBattleMons [ gBankTarget ] . item = oldItemAtk ;
gActiveBank = gBankAttacker ;
EmitSetMonData ( 0 , REQUEST_HELDITEM_BATTLE , 0 , 2 , newItemAtk ) ;
MarkBufferBankForExecution ( gBankAttacker ) ;
gActiveBank = gBankTarget ;
EmitSetMonData ( 0 , REQUEST_HELDITEM_BATTLE , 0 , 2 , & gBattleMons [ gBankTarget ] . item ) ;
MarkBufferBankForExecution ( gBankTarget ) ;
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gBankTarget ] ) + 0 ) = 0 ;
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gBankTarget ] ) + 1 ) = 0 ;
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gBankAttacker ] ) + 0 ) = 0 ;
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gBankAttacker ] ) + 1 ) = 0 ;
gBattlescriptCurrInstr + = 5 ;
PREPARE_ITEM_BUFFER ( gBattleTextBuff1 , * newItemAtk )
PREPARE_ITEM_BUFFER ( gBattleTextBuff2 , oldItemAtk )
if ( oldItemAtk ! = 0 & & * newItemAtk ! = 0 )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ; // attacker's item -> <- target's item
else if ( oldItemAtk = = 0 & & * newItemAtk ! = 0 )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ; // nothing -> <- target's item
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ; // attacker's item -> <- nothing
}
}
}
2017-11-25 18:42:31 +01:00
static void atkD3_trycopyability ( void ) // role play
2017-09-27 23:43:45 +02:00
{
if ( gBattleMons [ gBankTarget ] . ability ! = 0
& & gBattleMons [ gBankTarget ] . ability ! = ABILITY_WONDER_GUARD )
{
gBattleMons [ gBankAttacker ] . ability = gBattleMons [ gBankTarget ] . ability ;
gLastUsedAbility = gBattleMons [ gBankTarget ] . ability ;
gBattlescriptCurrInstr + = 5 ;
}
else
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
2017-11-25 18:42:31 +01:00
static void atkD4_trywish ( void )
2017-09-27 23:43:45 +02:00
{
2017-09-28 15:34:21 +02:00
switch ( gBattlescriptCurrInstr [ 1 ] )
2017-09-27 23:43:45 +02:00
{
case 0 : // use wish
if ( gWishFutureKnock . wishCounter [ gBankAttacker ] = = 0 )
{
gWishFutureKnock . wishCounter [ gBankAttacker ] = 2 ;
gWishFutureKnock . wishUserID [ gBankAttacker ] = gBattlePartyID [ gBankAttacker ] ;
gBattlescriptCurrInstr + = 6 ;
}
else
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 2 ) ;
}
break ;
case 1 : // heal effect
PREPARE_MON_NICK_WITH_PREFIX_BUFFER ( gBattleTextBuff1 , gBankTarget , gWishFutureKnock . wishUserID [ gBankTarget ] )
gBattleMoveDamage = gBattleMons [ gBankTarget ] . maxHP / 2 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleMoveDamage * = - 1 ;
if ( gBattleMons [ gBankTarget ] . hp = = gBattleMons [ gBankTarget ] . maxHP )
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 2 ) ;
else
gBattlescriptCurrInstr + = 6 ;
break ;
}
}
2017-11-25 18:42:31 +01:00
static void atkD5_trysetroots ( void ) // ingrain
2017-09-27 23:43:45 +02:00
{
if ( gStatuses3 [ gBankAttacker ] & STATUS3_ROOTED )
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
gStatuses3 [ gBankAttacker ] | = STATUS3_ROOTED ;
gBattlescriptCurrInstr + = 5 ;
}
}
2017-09-28 15:34:21 +02:00
static void atkD6_doubledamagedealtifdamaged ( void )
2017-09-27 23:43:45 +02:00
{
if ( ( gProtectStructs [ gBankAttacker ] . physicalDmg
& & gProtectStructs [ gBankAttacker ] . physicalBank = = gBankTarget )
| | ( gProtectStructs [ gBankAttacker ] . specialDmg
& & gProtectStructs [ gBankAttacker ] . specialBank = = gBankTarget ) )
{
gBattleScripting . dmgMultiplier = 2 ;
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkD7_setyawn ( void )
2017-09-27 23:43:45 +02:00
{
if ( gStatuses3 [ gBankTarget ] & STATUS3_YAWN
| | gBattleMons [ gBankTarget ] . status1 & STATUS_ANY )
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
gStatuses3 [ gBankTarget ] | = 0x1000 ;
gBattlescriptCurrInstr + = 5 ;
}
}
2017-09-28 15:34:21 +02:00
static void atkD8_setdamagetohealthdifference ( void )
2017-09-27 23:43:45 +02:00
{
if ( gBattleMons [ gBankTarget ] . hp < = gBattleMons [ gBankAttacker ] . hp )
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
gBattleMoveDamage = gBattleMons [ gBankTarget ] . hp - gBattleMons [ gBankAttacker ] . hp ;
gBattlescriptCurrInstr + = 5 ;
}
}
2017-09-28 15:34:21 +02:00
static void atkD9_scaledamagebyhealthratio ( void )
2017-09-27 23:43:45 +02:00
{
if ( gDynamicBasePower = = 0 )
{
u8 power = gBattleMoves [ gCurrentMove ] . power ;
gDynamicBasePower = gBattleMons [ gBankAttacker ] . hp * power / gBattleMons [ gBankAttacker ] . maxHP ;
if ( gDynamicBasePower = = 0 )
gDynamicBasePower = 1 ;
}
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atkDA_tryswapabilities ( void ) // skill swap
2017-09-27 23:43:45 +02:00
{
if ( ( gBattleMons [ gBankAttacker ] . ability = = 0
& & gBattleMons [ gBankTarget ] . ability = = 0 )
| | gBattleMons [ gBankAttacker ] . ability = = ABILITY_WONDER_GUARD
| | gBattleMons [ gBankTarget ] . ability = = ABILITY_WONDER_GUARD
| | gBattleMoveFlags & MOVESTATUS_NOEFFECT )
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
u8 abilityAtk = gBattleMons [ gBankAttacker ] . ability ;
gBattleMons [ gBankAttacker ] . ability = gBattleMons [ gBankTarget ] . ability ;
gBattleMons [ gBankTarget ] . ability = abilityAtk ;
gBattlescriptCurrInstr + = 5 ;
}
}
2017-11-25 18:42:31 +01:00
static void atkDB_tryimprision ( void )
2017-09-27 23:43:45 +02:00
{
if ( ( gStatuses3 [ gBankAttacker ] & STATUS3_IMPRISONED_OTHERS ) )
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
u8 bank , sideAttacker ;
sideAttacker = GetBankSide ( gBankAttacker ) ;
PressurePPLoseOnUsingImprision ( gBankAttacker ) ;
for ( bank = 0 ; bank < gNoOfAllBanks ; bank + + )
{
if ( sideAttacker ! = GetBankSide ( bank ) )
{
s32 attackerMoveId ;
for ( attackerMoveId = 0 ; attackerMoveId < 4 ; attackerMoveId + + )
{
s32 i ;
for ( i = 0 ; i < 4 ; i + + )
{
if ( gBattleMons [ gBankAttacker ] . moves [ attackerMoveId ] = = gBattleMons [ bank ] . moves [ i ]
& & gBattleMons [ gBankAttacker ] . moves [ attackerMoveId ] ! = MOVE_NONE )
break ;
}
if ( i ! = 4 )
break ;
}
if ( attackerMoveId ! = 4 )
{
gStatuses3 [ gBankAttacker ] | = STATUS3_IMPRISONED_OTHERS ;
gBattlescriptCurrInstr + = 5 ;
break ;
}
}
}
if ( bank = = gNoOfAllBanks ) // In Generation 3 games, Imprison fails if the user doesn't share any moves with any of the foes
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
2017-11-25 18:42:31 +01:00
static void atkDC_trysetgrudge ( void )
2017-09-27 23:43:45 +02:00
{
if ( gStatuses3 [ gBankAttacker ] & STATUS3_GRUDGE )
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
gStatuses3 [ gBankAttacker ] | = STATUS3_GRUDGE ;
gBattlescriptCurrInstr + = 5 ;
}
}
2017-09-28 15:34:21 +02:00
static void atkDD_weightdamagecalculation ( void )
2017-09-27 23:43:45 +02:00
{
s32 i ;
for ( i = 0 ; sWeightToDamageTable [ i ] ! = 0xFFFF ; i + = 2 )
{
if ( sWeightToDamageTable [ i ] > GetPokedexHeightWeight ( SpeciesToNationalPokedexNum ( gBattleMons [ gBankTarget ] . species ) , 1 ) )
break ;
}
if ( sWeightToDamageTable [ i ] ! = 0xFFFF )
gDynamicBasePower = sWeightToDamageTable [ i + 1 ] ;
else
gDynamicBasePower = 120 ;
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkDE_asistattackselect ( void )
2017-09-27 23:43:45 +02:00
{
s32 chooseableMovesNo = 0 ;
struct Pokemon * party ;
s32 monId , moveId ;
u16 * movesArray = gBattleStruct - > assistPossibleMoves ;
if ( GET_BANK_SIDE ( gBankAttacker ) ! = SIDE_PLAYER )
party = gEnemyParty ;
else
party = gPlayerParty ;
for ( monId = 0 ; monId < 6 ; monId + + )
{
if ( monId = = gBattlePartyID [ gBankAttacker ] )
continue ;
if ( GetMonData ( & party [ monId ] , MON_DATA_SPECIES2 ) = = SPECIES_NONE )
continue ;
if ( GetMonData ( & party [ monId ] , MON_DATA_SPECIES2 ) = = SPECIES_EGG )
continue ;
for ( moveId = 0 ; moveId < 4 ; moveId + + )
{
s32 i = 0 ;
u16 move = GetMonData ( & party [ monId ] , MON_DATA_MOVE1 + moveId ) ;
if ( IsInvalidForSleepTalkOrAssist ( move ) )
continue ;
2017-09-28 16:51:24 +02:00
for ( ; sMovesForbiddenToCopy [ i ] ! = ASSIST_FORBIDDEN_END & & move ! = sMovesForbiddenToCopy [ i ] ; i + + ) ;
2017-09-27 23:43:45 +02:00
2017-09-28 16:51:24 +02:00
if ( sMovesForbiddenToCopy [ i ] ! = ASSIST_FORBIDDEN_END )
2017-09-27 23:43:45 +02:00
continue ;
if ( move = = MOVE_NONE )
continue ;
movesArray [ chooseableMovesNo ] = move ;
chooseableMovesNo + + ;
}
}
if ( chooseableMovesNo )
{
gHitMarker & = ~ ( HITMARKER_ATTACKSTRING_PRINTED ) ;
gRandomMove = movesArray [ ( ( Random ( ) & 0xFF ) * chooseableMovesNo ) > > 8 ] ;
gBankTarget = GetMoveTarget ( gRandomMove , 0 ) ;
gBattlescriptCurrInstr + = 5 ;
}
else
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
2017-11-25 18:42:31 +01:00
static void atkDF_trysetmagiccoat ( void )
2017-09-27 23:43:45 +02:00
{
gBankTarget = gBankAttacker ;
gSpecialStatuses [ gBankAttacker ] . flag20 = 1 ;
2017-10-06 00:12:01 +02:00
if ( gCurrentTurnActionNumber = = gNoOfAllBanks - 1 ) // moves last turn
2017-09-27 23:43:45 +02:00
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
gProtectStructs [ gBankAttacker ] . bounceMove = 1 ;
gBattlescriptCurrInstr + = 5 ;
}
}
2017-11-25 18:42:31 +01:00
static void atkE0_trysetsnatch ( void ) // snatch
2017-09-27 23:43:45 +02:00
{
gSpecialStatuses [ gBankAttacker ] . flag20 = 1 ;
2017-10-06 00:12:01 +02:00
if ( gCurrentTurnActionNumber = = gNoOfAllBanks - 1 ) // moves last turn
2017-09-27 23:43:45 +02:00
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
gProtectStructs [ gBankAttacker ] . stealMove = 1 ;
gBattlescriptCurrInstr + = 5 ;
}
}
2017-11-25 18:42:31 +01:00
static void atkE1_trygetintimidatetarget ( void )
2017-09-27 23:43:45 +02:00
{
u8 side ;
gBattleScripting . bank = gBattleStruct - > intimidateBank ;
side = GetBankSide ( gBattleScripting . bank ) ;
PREPARE_ABILITY_BUFFER ( gBattleTextBuff1 , gBattleMons [ gBattleScripting . bank ] . ability )
for ( ; gBankTarget < gNoOfAllBanks ; gBankTarget + + )
{
if ( GetBankSide ( gBankTarget ) = = side )
continue ;
if ( ! ( gAbsentBankFlags & gBitTable [ gBankTarget ] ) )
break ;
}
if ( gBankTarget > = gNoOfAllBanks )
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
else
gBattlescriptCurrInstr + = 5 ;
}
2017-11-25 18:42:31 +01:00
static void atkE2_switchoutabilities ( void )
2017-09-27 23:43:45 +02:00
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-27 23:43:45 +02:00
switch ( gBattleMons [ gActiveBank ] . ability )
{
case ABILITY_NATURAL_CURE :
gBattleMons [ gActiveBank ] . status1 = 0 ;
EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , gBitTable [ * ( gBattleStruct - > field_58 + gActiveBank ) ] , 4 , & gBattleMons [ gActiveBank ] . status1 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
break ;
}
gBattlescriptCurrInstr + = 2 ;
}
2017-09-28 15:34:21 +02:00
static void atkE3_jumpifhasnohp ( void )
2017-09-27 23:43:45 +02:00
{
2017-09-28 15:34:21 +02:00
gActiveBank = GetBattleBank ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-27 23:43:45 +02:00
if ( gBattleMons [ gActiveBank ] . hp = = 0 )
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 2 ) ;
else
gBattlescriptCurrInstr + = 6 ;
}
2017-09-28 15:34:21 +02:00
static void atkE4_getsecretpowereffect ( void )
2017-09-27 23:43:45 +02:00
{
switch ( gBattleTerrain )
{
case BATTLE_TERRAIN_GRASS :
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_POISON ;
break ;
case BATTLE_TERRAIN_LONG_GRASS :
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_SLEEP ;
break ;
case BATTLE_TERRAIN_SAND :
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_ACC_MINUS_1 ;
break ;
case BATTLE_TERRAIN_UNDERWATER :
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_DEF_MINUS_1 ;
break ;
case BATTLE_TERRAIN_WATER :
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_ATK_MINUS_1 ;
break ;
case BATTLE_TERRAIN_POND :
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_SPD_MINUS_1 ;
break ;
case BATTLE_TERRAIN_ROCK :
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_CONFUSION ;
break ;
case BATTLE_TERRAIN_CAVE :
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_FLINCH ;
break ;
default :
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_PARALYSIS ;
break ;
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkE5_pickup ( void )
2017-09-27 23:43:45 +02:00
{
if ( ! InBattlePike ( ) )
{
s32 i ;
u16 species , heldItem ;
u8 ability ;
if ( InBattlePyramid ( ) )
{
for ( i = 0 ; i < 6 ; i + + )
{
species = GetMonData ( & gPlayerParty [ i ] , MON_DATA_SPECIES2 ) ;
heldItem = GetMonData ( & gPlayerParty [ i ] , MON_DATA_HELD_ITEM ) ;
if ( GetMonData ( & gPlayerParty [ i ] , MON_DATA_ALT_ABILITY ) )
ability = gBaseStats [ species ] . ability2 ;
else
ability = gBaseStats [ species ] . ability1 ;
if ( ability = = ABILITY_PICKUP
& & species ! = 0
& & species ! = SPECIES_EGG
& & heldItem = = ITEM_NONE
& & ( Random ( ) % 10 ) = = 0 )
{
heldItem = GetBattlePyramidPickupItemId ( ) ;
SetMonData ( & gPlayerParty [ i ] , MON_DATA_HELD_ITEM , & heldItem ) ;
}
}
}
else
{
for ( i = 0 ; i < 6 ; i + + )
{
species = GetMonData ( & gPlayerParty [ i ] , MON_DATA_SPECIES2 ) ;
heldItem = GetMonData ( & gPlayerParty [ i ] , MON_DATA_HELD_ITEM ) ;
if ( GetMonData ( & gPlayerParty [ i ] , MON_DATA_ALT_ABILITY ) )
ability = gBaseStats [ species ] . ability2 ;
else
ability = gBaseStats [ species ] . ability1 ;
if ( ability = = ABILITY_PICKUP
& & species ! = 0
& & species ! = SPECIES_EGG
& & heldItem = = ITEM_NONE
& & ( Random ( ) % 10 ) = = 0 )
{
s32 j ;
s32 rand = Random ( ) % 100 ;
u8 lvlDivBy10 = ( GetMonData ( & gPlayerParty [ i ] , MON_DATA_LEVEL ) - 1 ) / 10 ;
if ( lvlDivBy10 > 9 )
lvlDivBy10 = 9 ;
for ( j = 0 ; j < 9 ; j + + )
{
2017-09-28 16:51:24 +02:00
if ( sPickupProbabilities [ j ] > rand )
2017-09-27 23:43:45 +02:00
{
2017-09-28 16:51:24 +02:00
SetMonData ( & gPlayerParty [ i ] , MON_DATA_HELD_ITEM , & sPickupItems [ lvlDivBy10 + j ] ) ;
2017-09-27 23:43:45 +02:00
break ;
}
else if ( rand = = 99 | | rand = = 98 )
{
2017-09-28 16:51:24 +02:00
SetMonData ( & gPlayerParty [ i ] , MON_DATA_HELD_ITEM , & sRarePickupItems [ lvlDivBy10 + ( 99 - rand ) ] ) ;
2017-09-27 23:43:45 +02:00
break ;
}
}
}
}
}
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
2017-11-25 18:42:31 +01:00
static void atkE6_docastformchangeanimation ( void )
2017-09-28 15:34:21 +02:00
{
gActiveBank = gBattleScripting . bank ;
if ( gBattleMons [ gActiveBank ] . status2 & STATUS2_SUBSTITUTE )
* ( & gBattleStruct - > formToChangeInto ) | = 0x80 ;
EmitBattleAnimation ( 0 , B_ANIM_CASTFORM_CHANGE , gBattleStruct - > formToChangeInto ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atkE7_trycastformdatachange ( void )
2017-09-28 15:34:21 +02:00
{
u8 form ;
gBattlescriptCurrInstr + + ;
form = CastformDataTypeChange ( gBattleScripting . bank ) ;
if ( form )
{
BattleScriptPushCursorAndCallback ( BattleScript_CastformChange ) ;
* ( & gBattleStruct - > formToChangeInto ) = form - 1 ;
}
}
static void atkE8_settypebasedhalvers ( void ) // water and mud sport
{
bool8 worked = FALSE ;
if ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_MUD_SPORT )
{
if ( ! ( gStatuses3 [ gBankAttacker ] & STATUS3_MUDSPORT ) )
{
gStatuses3 [ gBankAttacker ] | = STATUS3_MUDSPORT ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
worked = TRUE ;
}
}
else // water sport
{
if ( ! ( gStatuses3 [ gBankAttacker ] & STATUS3_WATERSPORT ) )
{
gStatuses3 [ gBankAttacker ] | = STATUS3_WATERSPORT ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
worked = TRUE ;
}
}
if ( worked )
gBattlescriptCurrInstr + = 5 ;
else
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
static void atkE9_setweatherballtype ( void )
{
if ( WEATHER_HAS_EFFECT )
{
if ( gBattleWeather & WEATHER_ANY )
gBattleScripting . dmgMultiplier = 2 ;
if ( gBattleWeather & WEATHER_RAIN_ANY )
* ( & gBattleStruct - > dynamicMoveType ) = TYPE_WATER | 0x80 ;
else if ( gBattleWeather & WEATHER_SANDSTORM_ANY )
* ( & gBattleStruct - > dynamicMoveType ) = TYPE_ROCK | 0x80 ;
else if ( gBattleWeather & WEATHER_SUN_ANY )
* ( & gBattleStruct - > dynamicMoveType ) = TYPE_FIRE | 0x80 ;
else if ( gBattleWeather & WEATHER_HAIL_ANY )
* ( & gBattleStruct - > dynamicMoveType ) = TYPE_ICE | 0x80 ;
else
* ( & gBattleStruct - > dynamicMoveType ) = TYPE_NORMAL | 0x80 ;
}
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atkEA_tryrecycleitem ( void )
2017-09-28 15:34:21 +02:00
{
u16 * usedHeldItem ;
gActiveBank = gBankAttacker ;
usedHeldItem = & gBattleStruct - > usedHeldItems [ gActiveBank ] ;
if ( * usedHeldItem ! = 0 & & gBattleMons [ gActiveBank ] . item = = 0 )
{
gLastUsedItem = * usedHeldItem ;
* usedHeldItem = 0 ;
gBattleMons [ gActiveBank ] . item = gLastUsedItem ;
EmitSetMonData ( 0 , REQUEST_HELDITEM_BATTLE , 0 , 2 , & gBattleMons [ gActiveBank ] . item ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 5 ;
}
else
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
static void atkEB_settypetoterrain ( void )
{
if ( gBattleMons [ gBankAttacker ] . type1 ! = sTerrainToType [ gBattleTerrain ]
& & gBattleMons [ gBankAttacker ] . type2 ! = sTerrainToType [ gBattleTerrain ] )
{
gBattleMons [ gBankAttacker ] . type1 = sTerrainToType [ gBattleTerrain ] ;
gBattleMons [ gBankAttacker ] . type2 = sTerrainToType [ gBattleTerrain ] ;
PREPARE_TYPE_BUFFER ( gBattleTextBuff1 , sTerrainToType [ gBattleTerrain ] )
gBattlescriptCurrInstr + = 5 ;
}
else
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
2017-11-25 18:42:31 +01:00
static void atkEC_pursuitrelated ( void )
2017-09-28 15:34:21 +02:00
{
gActiveBank = GetBankByIdentity ( GetBankIdentity ( gBankAttacker ) ^ BIT_MON ) ;
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE
& & ! ( gAbsentBankFlags & gBitTable [ gActiveBank ] )
& & gActionForBanks [ gActiveBank ] = = 0
& & gChosenMovesByBanks [ gActiveBank ] = = MOVE_PURSUIT )
{
2017-10-04 19:25:14 +02:00
gActionsByTurnOrder [ gActiveBank ] = 11 ;
2017-09-28 15:34:21 +02:00
gCurrentMove = MOVE_PURSUIT ;
gBattlescriptCurrInstr + = 5 ;
gBattleScripting . animTurn = 1 ;
gBattleScripting . field_20 = gBankAttacker ;
gBankAttacker = gActiveBank ;
}
else
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
}
2017-11-25 18:42:31 +01:00
static void atkEF_snatchsetbanks ( void )
2017-09-28 15:34:21 +02:00
{
gEffectBank = gBankAttacker ;
if ( gBankAttacker = = gBankTarget )
gBankAttacker = gBankTarget = gBattleScripting . bank ;
else
gBankTarget = gBattleScripting . bank ;
gBattleScripting . bank = gEffectBank ;
gBattlescriptCurrInstr + + ;
}
static void atkEE_removelightscreenreflect ( void ) // brick break
{
u8 opposingSide = GetBankSide ( gBankAttacker ) ^ BIT_SIDE ;
if ( gSideTimers [ opposingSide ] . reflectTimer | | gSideTimers [ opposingSide ] . lightscreenTimer )
{
gSideAffecting [ opposingSide ] & = ~ ( SIDE_STATUS_REFLECT ) ;
gSideAffecting [ opposingSide ] & = ~ ( SIDE_STATUS_LIGHTSCREEN ) ;
gSideTimers [ opposingSide ] . reflectTimer = 0 ;
gSideTimers [ opposingSide ] . lightscreenTimer = 0 ;
gBattleScripting . animTurn = 1 ;
gBattleScripting . animTargetsHit = 1 ;
}
else
{
gBattleScripting . animTurn = 0 ;
gBattleScripting . animTargetsHit = 0 ;
}
gBattlescriptCurrInstr + + ;
}
2017-11-26 01:19:57 +01:00
static void atkEF_handleballthrow ( void )
2017-09-28 15:34:21 +02:00
{
u8 ballMultiplier = 0 ;
if ( gBattleExecBuffer )
return ;
gActiveBank = gBankAttacker ;
gBankTarget = gBankAttacker ^ BIT_SIDE ;
if ( gBattleTypeFlags & BATTLE_TYPE_TRAINER )
{
2017-10-22 18:43:15 +02:00
EmitBallThrowAnim ( 0 , BALL_TRAINER_BLOCK ) ;
2017-09-28 15:34:21 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr = BattleScript_TrainerBallBlock ;
}
else if ( gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL )
{
2017-10-22 18:43:15 +02:00
EmitBallThrowAnim ( 0 , BALL_3_SHAKES_SUCCESS ) ;
2017-09-28 15:34:21 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr = BattleScript_WallyBallThrow ;
}
else
{
u32 odds ;
u8 catchRate ;
if ( gLastUsedItem = = ITEM_SAFARI_BALL )
catchRate = gBattleStruct - > field_7C * 1275 / 100 ;
else
catchRate = gBaseStats [ gBattleMons [ gBankTarget ] . species ] . catchRate ;
if ( gLastUsedItem > ITEM_SAFARI_BALL )
{
switch ( gLastUsedItem )
{
case ITEM_NET_BALL :
if ( gBattleMons [ gBankTarget ] . type1 = = TYPE_WATER
| | gBattleMons [ gBankTarget ] . type2 = = TYPE_WATER
| | gBattleMons [ gBankTarget ] . type1 = = TYPE_BUG
| | gBattleMons [ gBankTarget ] . type2 = = TYPE_BUG )
ballMultiplier = 30 ;
else
ballMultiplier = 10 ;
break ;
case ITEM_DIVE_BALL :
if ( sav1_map_get_light_level ( ) = = 5 )
ballMultiplier = 35 ;
else
ballMultiplier = 10 ;
break ;
case ITEM_NEST_BALL :
2017-09-28 19:34:13 +02:00
if ( gBattleMons [ gBankTarget ] . level < 40 )
2017-09-28 15:34:21 +02:00
{
ballMultiplier = 40 - gBattleMons [ gBankTarget ] . level ;
if ( ballMultiplier < = 9 )
ballMultiplier = 10 ;
}
else
{
ballMultiplier = 10 ;
}
break ;
case ITEM_REPEAT_BALL :
if ( GetSetPokedexFlag ( SpeciesToNationalPokedexNum ( gBattleMons [ gBankTarget ] . species ) , FLAG_GET_CAUGHT ) )
ballMultiplier = 30 ;
else
ballMultiplier = 10 ;
break ;
case ITEM_TIMER_BALL :
ballMultiplier = gBattleResults . battleTurnCounter + 10 ;
if ( ballMultiplier > 40 )
ballMultiplier = 40 ;
break ;
case ITEM_LUXURY_BALL :
case ITEM_PREMIER_BALL :
ballMultiplier = 10 ;
break ;
}
}
else
ballMultiplier = sBallCatchBonuses [ gLastUsedItem - 2 ] ;
odds = ( catchRate * ballMultiplier / 10 )
* ( gBattleMons [ gBankTarget ] . maxHP * 3 - gBattleMons [ gBankTarget ] . hp * 2 )
/ ( 3 * gBattleMons [ gBankTarget ] . maxHP ) ;
if ( gBattleMons [ gBankTarget ] . status1 & ( STATUS_SLEEP | STATUS_FREEZE ) )
odds * = 2 ;
if ( gBattleMons [ gBankTarget ] . status1 & ( STATUS_POISON | STATUS_BURN | STATUS_PARALYSIS | STATUS_TOXIC_POISON ) )
odds = ( odds * 15 ) / 10 ;
if ( gLastUsedItem ! = ITEM_SAFARI_BALL )
{
if ( gLastUsedItem = = ITEM_MASTER_BALL )
{
2017-10-13 17:09:36 +02:00
gBattleResults . usedMasterBall = TRUE ;
2017-09-28 15:34:21 +02:00
}
else
{
if ( gBattleResults . catchAttempts [ gLastUsedItem - ITEM_ULTRA_BALL ] < 0xFF )
gBattleResults . catchAttempts [ gLastUsedItem - ITEM_ULTRA_BALL ] + + ;
}
}
if ( odds > 254 ) // mon caught
{
2017-10-22 18:43:15 +02:00
EmitBallThrowAnim ( 0 , BALL_3_SHAKES_SUCCESS ) ;
2017-09-28 15:34:21 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr = BattleScript_SuccessBallThrow ;
SetMonData ( & gEnemyParty [ gBattlePartyID [ gBankTarget ] ] , MON_DATA_POKEBALL , & gLastUsedItem ) ;
if ( CalculatePlayerPartyCount ( ) = = 6 )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
else // mon may be caught, calculate shakes
{
u8 shakes ;
odds = Sqrt ( Sqrt ( 16711680 / odds ) ) ;
odds = 1048560 / odds ;
for ( shakes = 0 ; shakes < 4 & & Random ( ) < odds ; shakes + + ) ;
if ( gLastUsedItem = = ITEM_MASTER_BALL )
shakes = BALL_3_SHAKES_SUCCESS ; // why calculate the shakes before that check?
2017-10-22 18:43:15 +02:00
EmitBallThrowAnim ( 0 , shakes ) ;
2017-09-28 15:34:21 +02:00
MarkBufferBankForExecution ( gActiveBank ) ;
if ( shakes = = BALL_3_SHAKES_SUCCESS ) // mon caught, copy of the code above
{
gBattlescriptCurrInstr = BattleScript_SuccessBallThrow ;
SetMonData ( & gEnemyParty [ gBattlePartyID [ gBankTarget ] ] , MON_DATA_POKEBALL , & gLastUsedItem ) ;
if ( CalculatePlayerPartyCount ( ) = = 6 )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
else // not caught
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = shakes ;
gBattlescriptCurrInstr = BattleScript_ShakeBallThrow ;
}
}
}
}
2017-11-25 18:42:31 +01:00
static void atkF0_givecaughtmon ( void )
2017-09-28 15:34:21 +02:00
{
if ( GiveMonToPlayer ( & gEnemyParty [ gBattlePartyID [ gBankAttacker ^ BIT_SIDE ] ] ) ! = MON_GIVEN_TO_PARTY )
{
if ( ! sub_813B21C ( ) )
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
StringCopy ( gStringVar1 , GetBoxNamePtr ( VarGet ( VAR_STORAGE_UNKNOWN ) ) ) ;
GetMonData ( & gEnemyParty [ gBattlePartyID [ gBankAttacker ^ BIT_SIDE ] ] , MON_DATA_NICKNAME , gStringVar2 ) ;
}
else
{
StringCopy ( gStringVar1 , GetBoxNamePtr ( VarGet ( VAR_STORAGE_UNKNOWN ) ) ) ;
GetMonData ( & gEnemyParty [ gBattlePartyID [ gBankAttacker ^ BIT_SIDE ] ] , MON_DATA_NICKNAME , gStringVar2 ) ;
StringCopy ( gStringVar3 , GetBoxNamePtr ( get_unknown_box_id ( ) ) ) ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
}
2017-11-08 22:20:10 +01:00
if ( FlagGet ( FLAG_SYS_PC_LANETTE ) )
2017-09-28 15:34:21 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] + + ;
}
gBattleResults . caughtMonSpecies = GetMonData ( & gEnemyParty [ gBattlePartyID [ gBankAttacker ^ BIT_SIDE ] ] , MON_DATA_SPECIES , NULL ) ;
GetMonData ( & gEnemyParty [ gBattlePartyID [ gBankAttacker ^ BIT_SIDE ] ] , MON_DATA_NICKNAME , gBattleResults . caughtMonNick ) ;
gBattleResults . caughtMonBall = GetMonData ( & gEnemyParty [ gBattlePartyID [ gBankAttacker ^ BIT_SIDE ] ] , MON_DATA_POKEBALL , NULL ) ;
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atkF1_trysetcaughtmondexflags ( void )
2017-09-28 15:34:21 +02:00
{
u16 species = GetMonData ( & gEnemyParty [ 0 ] , MON_DATA_SPECIES , NULL ) ;
u32 personality = GetMonData ( & gEnemyParty [ 0 ] , MON_DATA_PERSONALITY , NULL ) ;
if ( GetSetPokedexFlag ( SpeciesToNationalPokedexNum ( species ) , FLAG_GET_CAUGHT ) )
{
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
HandleSetPokedexFlag ( SpeciesToNationalPokedexNum ( species ) , FLAG_SET_CAUGHT , personality ) ;
gBattlescriptCurrInstr + = 5 ;
}
}
2017-11-25 18:42:31 +01:00
static void atkF2_displaydexinfo ( void )
2017-09-28 15:34:21 +02:00
{
u16 species = GetMonData ( & gEnemyParty [ 0 ] , MON_DATA_SPECIES , NULL ) ;
switch ( gBattleCommunication [ 0 ] )
{
case 0 :
BeginNormalPaletteFade ( - 1 , 0 , 0 , 0x10 , 0 ) ;
gBattleCommunication [ 0 ] + + ;
break ;
case 1 :
if ( ! gPaletteFade . active )
{
FreeAllWindowBuffers ( ) ;
gBattleCommunication [ TASK_ID ] = CreateDexDisplayMonDataTask ( SpeciesToNationalPokedexNum ( species ) ,
gBattleMons [ gBankTarget ] . otId ,
gBattleMons [ gBankTarget ] . personality ) ;
gBattleCommunication [ 0 ] + + ;
}
break ;
case 2 :
if ( ! gPaletteFade . active
& & gMain . callback2 = = BattleMainCB2
& & ! gTasks [ gBattleCommunication [ TASK_ID ] ] . isActive )
{
SetVBlankCallback ( VBlankCB_Battle ) ;
gBattleCommunication [ 0 ] + + ;
}
break ;
case 3 :
2017-10-01 18:54:01 +02:00
sub_80356D0 ( ) ;
2017-10-01 01:12:42 +02:00
LoadBattleTextboxAndBackground ( ) ;
2017-09-28 15:34:21 +02:00
gBattle_BG3_X = 0x100 ;
gBattleCommunication [ 0 ] + + ;
break ;
case 4 :
if ( ! IsDma3ManagerBusyWithBgCopy ( ) )
{
BeginNormalPaletteFade ( 0xFFFF , 0 , 0x10 , 0 , 0 ) ;
ShowBg ( 0 ) ;
ShowBg ( 3 ) ;
gBattleCommunication [ 0 ] + + ;
}
break ;
case 5 :
if ( ! gPaletteFade . active )
gBattlescriptCurrInstr + + ;
break ;
}
}
2017-10-22 01:04:02 +02:00
void HandleBattleWindow ( u8 xStart , u8 yStart , u8 xEnd , u8 yEnd , u8 flags )
2017-09-28 15:34:21 +02:00
{
s32 destY , destX ;
u16 var = 0 ;
for ( destY = yStart ; destY < = yEnd ; destY + + )
{
for ( destX = xStart ; destX < = xEnd ; destX + + )
{
if ( destY = = yStart )
{
if ( destX = = xStart )
var = 0x1022 ;
else if ( destX = = xEnd )
var = 0x1024 ;
else
var = 0x1023 ;
}
else if ( destY = = yEnd )
{
if ( destX = = xStart )
var = 0x1028 ;
else if ( destX = = xEnd )
var = 0x102A ;
else
var = 0x1029 ;
}
else
{
if ( destX = = xStart )
var = 0x1025 ;
else if ( destX = = xEnd )
var = 0x1027 ;
else
var = 0x1026 ;
}
2017-10-22 01:04:02 +02:00
if ( flags & WINDOW_CLEAR )
2017-09-28 15:34:21 +02:00
var = 0 ;
2017-10-22 01:04:02 +02:00
if ( flags & WINDOW_x80 )
2017-09-28 15:34:21 +02:00
CopyToBgTilemapBufferRect_ChangePalette ( 1 , & var , destX , destY , 1 , 1 , 0x11 ) ;
else
CopyToBgTilemapBufferRect_ChangePalette ( 0 , & var , destX , destY , 1 , 1 , 0x11 ) ;
}
}
}
2017-10-21 17:32:35 +02:00
void BattleCreateYesNoCursorAt ( u8 cursorPosition )
2017-09-28 15:34:21 +02:00
{
u16 src [ 2 ] ;
src [ 0 ] = 1 ;
src [ 1 ] = 2 ;
CopyToBgTilemapBufferRect_ChangePalette ( 0 , src , 0x19 , 9 + ( 2 * cursorPosition ) , 1 , 2 , 0x11 ) ;
CopyBgTilemapBufferToVram ( 0 ) ;
}
2017-10-21 17:32:35 +02:00
void BattleDestroyYesNoCursorAt ( u8 cursorPosition )
2017-09-28 15:34:21 +02:00
{
u16 src [ 2 ] ;
src [ 0 ] = 0x1016 ;
src [ 1 ] = 0x1016 ;
CopyToBgTilemapBufferRect_ChangePalette ( 0 , src , 0x19 , 9 + ( 2 * cursorPosition ) , 1 , 2 , 0x11 ) ;
CopyBgTilemapBufferToVram ( 0 ) ;
}
2017-11-25 18:42:31 +01:00
static void atkF3_trygivecaughtmonnick ( void )
2017-09-28 15:34:21 +02:00
{
switch ( gBattleCommunication [ MULTIUSE_STATE ] )
{
case 0 :
2017-10-22 01:04:02 +02:00
HandleBattleWindow ( 0x18 , 8 , 0x1D , 0xD , 0 ) ;
BattleHandleAddTextPrinter ( gText_BattleYesNoChoice , 0xC ) ;
2017-09-28 15:34:21 +02:00
gBattleCommunication [ MULTIUSE_STATE ] + + ;
gBattleCommunication [ CURSOR_POSITION ] = 0 ;
2017-10-21 17:32:35 +02:00
BattleCreateYesNoCursorAt ( 0 ) ;
2017-09-28 15:34:21 +02:00
break ;
case 1 :
if ( gMain . newKeys & DPAD_UP & & gBattleCommunication [ CURSOR_POSITION ] ! = 0 )
{
PlaySE ( SE_SELECT ) ;
2017-10-21 17:32:35 +02:00
BattleDestroyYesNoCursorAt ( gBattleCommunication [ CURSOR_POSITION ] ) ;
2017-09-28 15:34:21 +02:00
gBattleCommunication [ CURSOR_POSITION ] = 0 ;
2017-10-21 17:32:35 +02:00
BattleCreateYesNoCursorAt ( 0 ) ;
2017-09-28 15:34:21 +02:00
}
if ( gMain . newKeys & DPAD_DOWN & & gBattleCommunication [ CURSOR_POSITION ] = = 0 )
{
PlaySE ( SE_SELECT ) ;
2017-10-21 17:32:35 +02:00
BattleDestroyYesNoCursorAt ( gBattleCommunication [ CURSOR_POSITION ] ) ;
2017-09-28 15:34:21 +02:00
gBattleCommunication [ CURSOR_POSITION ] = 1 ;
2017-10-21 17:32:35 +02:00
BattleCreateYesNoCursorAt ( 1 ) ;
2017-09-28 15:34:21 +02:00
}
if ( gMain . newKeys & A_BUTTON )
{
PlaySE ( SE_SELECT ) ;
if ( gBattleCommunication [ CURSOR_POSITION ] = = 0 )
{
gBattleCommunication [ MULTIUSE_STATE ] + + ;
BeginFastPaletteFade ( 3 ) ;
}
else
{
gBattleCommunication [ MULTIUSE_STATE ] = 4 ;
}
}
else if ( gMain . newKeys & B_BUTTON )
{
PlaySE ( SE_SELECT ) ;
gBattleCommunication [ MULTIUSE_STATE ] = 4 ;
}
break ;
case 2 :
if ( ! gPaletteFade . active )
{
GetMonData ( & gEnemyParty [ gBattlePartyID [ gBankAttacker ^ BIT_SIDE ] ] , MON_DATA_NICKNAME , gBattleStruct - > caughtMonNick ) ;
FreeAllWindowBuffers ( ) ;
DoNamingScreen ( NAMING_SCREEN_CAUGHT_MON , gBattleStruct - > caughtMonNick ,
GetMonData ( & gEnemyParty [ gBattlePartyID [ gBankAttacker ^ BIT_SIDE ] ] , MON_DATA_SPECIES ) ,
GetMonGender ( & gEnemyParty [ gBattlePartyID [ gBankAttacker ^ BIT_SIDE ] ] ) ,
GetMonData ( & gEnemyParty [ gBattlePartyID [ gBankAttacker ^ BIT_SIDE ] ] , MON_DATA_PERSONALITY , NULL ) ,
BattleMainCB2 ) ;
gBattleCommunication [ MULTIUSE_STATE ] + + ;
}
break ;
case 3 :
if ( gMain . callback2 = = BattleMainCB2 & & ! gPaletteFade . active )
{
SetMonData ( & gEnemyParty [ gBattlePartyID [ gBankAttacker ^ BIT_SIDE ] ] , MON_DATA_NICKNAME , gBattleStruct - > caughtMonNick ) ;
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
}
break ;
case 4 :
if ( CalculatePlayerPartyCount ( ) = = 6 )
gBattlescriptCurrInstr + = 5 ;
else
gBattlescriptCurrInstr = BSScriptReadPtr ( gBattlescriptCurrInstr + 1 ) ;
break ;
}
}
static void atkF4_subattackerhpbydmg ( void )
{
gBattleMons [ gBankAttacker ] . hp - = gBattleMoveDamage ;
gBattlescriptCurrInstr + + ;
}
static void atkF5_removeattackerstatus1 ( void )
{
gBattleMons [ gBankAttacker ] . status1 = 0 ;
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atkF6_finishaction ( void )
2017-09-28 15:34:21 +02:00
{
2017-10-06 00:12:01 +02:00
gCurrentActionFuncId = ACTION_FINISHED ;
2017-09-28 15:34:21 +02:00
}
2017-11-25 18:42:31 +01:00
static void atkF7_finishturn ( void )
2017-09-28 15:34:21 +02:00
{
2017-10-06 00:12:01 +02:00
gCurrentActionFuncId = ACTION_FINISHED ;
gCurrentTurnActionNumber = gNoOfAllBanks ;
2017-09-28 15:34:21 +02:00
}
2017-11-25 18:42:31 +01:00
static void atkF8_trainerslideout ( void )
2017-09-28 15:34:21 +02:00
{
gActiveBank = GetBankByIdentity ( gBattlescriptCurrInstr [ 1 ] ) ;
EmitTrainerSlideBack ( 0 ) ;
MarkBufferBankForExecution ( gActiveBank ) ;
gBattlescriptCurrInstr + = 2 ;
}