2017-09-04 15:05:11 +02:00
# include "global.h"
# include "battle.h"
2017-12-05 18:55:48 +01:00
# include "constants/battle_move_effects.h"
2018-02-08 11:17:41 +01:00
# include "constants/battle_script_commands.h"
2017-09-19 21:01:12 +02:00
# include "battle_message.h"
2018-10-07 15:39:46 +02:00
# include "battle_anim.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-12-11 19:27:51 +01:00
# include "constants/moves.h"
2017-12-05 18:55:48 +01:00
# include "constants/abilities.h"
2017-09-08 16:46:37 +02:00
# include "item.h"
2017-12-05 18:55:48 +01:00
# include "constants/items.h"
# include "constants/hold_effects.h"
2017-09-19 21:01:12 +02:00
# include "util.h"
# include "pokemon.h"
2017-12-05 19:27:33 +01:00
# include "random.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-12-11 19:27:51 +01:00
# include "constants/species.h"
# include "constants/songs.h"
2017-12-17 21:19:08 +01:00
# include "constants/trainers.h"
2017-12-31 16:28:57 +01:00
# include "constants/battle_anim.h"
2018-07-16 20:23:05 +02:00
# include "constants/map_types.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 "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"
2018-02-08 00:35:13 +01:00
# include "constants/battle_string_ids.h"
2018-02-07 23:21:51 +01:00
# include "battle_setup.h"
# include "overworld.h"
2018-07-07 19:57:09 +02:00
# include "party_menu.h"
2018-11-11 18:33:16 +01:00
# include "battle_arena.h"
2018-11-12 14:35:56 +01:00
# include "battle_pike.h"
2018-11-18 17:52:22 +01:00
# include "battle_pyramid.h"
2018-12-24 00:02:29 +01:00
# include "field_specials.h"
# include "pokemon_summary_screen.h"
2019-03-02 04:32:50 +01:00
# include "pokenav.h"
2019-03-17 23:20:40 +01:00
# include "menu_specialized.h"
2019-04-04 23:05:46 +02:00
# include "constants/rgb.h"
2019-04-05 00:05:51 +02:00
# include "data.h"
2017-09-19 21:01:12 +02:00
2018-01-10 04:30:54 +01:00
extern struct MusicPlayerInfo gMPlayInfo_BGM ;
2017-09-25 00:09:13 +02:00
2017-09-23 20:13:45 +02:00
extern const u8 * const gBattleScriptsForMoveEffects [ ] ;
2017-09-19 21:01:12 +02:00
2018-02-06 23:09:39 +01:00
# define DEFENDER_IS_PROTECTED ((gProtectStructs[gBattlerTarget].protected) && (gBattleMoves[gCurrentMove].flags & FLAG_PROTECT_AFFECTED))
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 ) ;
2018-02-08 12:13:29 +01:00
static u8 AttacksThisTurn ( u8 battlerId , 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 ) ;
2019-04-04 21:24:21 +02:00
static void DrawLevelUpWindow1 ( void ) ;
static void DrawLevelUpWindow2 ( void ) ;
2017-09-28 15:34:21 +02:00
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 ) ;
2018-06-30 14:12:17 +02:00
static void atk5F_swapattackerwithtarget ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk60_incrementgamestat ( void ) ;
static void atk61_drawpartystatussummary ( void ) ;
2018-06-28 21:06:32 +02:00
static void atk62_hidepartystatussummary ( void ) ;
2018-09-22 19:08:41 +02:00
static void atk63_jumptocalledmove ( void ) ;
2017-09-28 15:34:21 +02:00
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 ) ;
2019-03-02 23:40:38 +01:00
static void atkDB_tryimprison ( void ) ;
2017-11-25 18:42:31 +01:00
static void atkDC_trysetgrudge ( void ) ;
2017-09-28 15:34:21 +02:00
static void atkDD_weightdamagecalculation ( void ) ;
2019-04-03 16:36:50 +02:00
static void atkDE_assistattackselect ( 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 ) ;
2018-06-30 14:12:17 +02:00
static void atkEF_snatchsetbattlers ( 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 ,
2018-06-30 14:12:17 +02:00
atk5F_swapattackerwithtarget ,
2017-11-25 18:42:31 +01:00
atk60_incrementgamestat ,
atk61_drawpartystatussummary ,
2018-06-28 21:06:32 +02:00
atk62_hidepartystatussummary ,
2018-09-22 19:08:41 +02:00
atk63_jumptocalledmove ,
2017-09-04 15:05:11 +02:00
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 ,
2019-03-02 23:40:38 +01:00
atkDB_tryimprison ,
2017-11-25 18:42:31 +01:00
atkDC_trysetgrudge ,
2017-09-04 15:05:11 +02:00
atkDD_weightdamagecalculation ,
2019-04-03 16:36:50 +02:00
atkDE_assistattackselect ,
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 ,
2018-06-30 14:12:17 +02:00
atkEF_snatchsetbattlers ,
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 ,
2018-01-16 22:12:38 +01:00
STATUS1_SLEEP ,
STATUS1_POISON ,
STATUS1_BURN ,
STATUS1_FREEZE ,
STATUS1_PARALYSIS ,
STATUS1_TOXIC_POISON ,
2017-09-20 22:54:26 +02:00
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
{
2018-12-08 04:33:41 +01:00
[ 0 ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_SLEEP ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_POISON ] = BattleScript_MoveEffectPoison ,
[ MOVE_EFFECT_BURN ] = BattleScript_MoveEffectBurn ,
[ MOVE_EFFECT_FREEZE ] = BattleScript_MoveEffectFreeze ,
[ MOVE_EFFECT_PARALYSIS ] = BattleScript_MoveEffectParalysis ,
[ MOVE_EFFECT_TOXIC ] = BattleScript_MoveEffectToxic ,
[ MOVE_EFFECT_CONFUSION ] = BattleScript_MoveEffectConfusion ,
[ MOVE_EFFECT_FLINCH ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_TRI_ATTACK ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_UPROAR ] = BattleScript_MoveEffectUproar ,
[ MOVE_EFFECT_PAYDAY ] = BattleScript_MoveEffectPayDay ,
[ MOVE_EFFECT_CHARGING ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_WRAP ] = BattleScript_MoveEffectWrap ,
[ MOVE_EFFECT_RECOIL_25 ] = BattleScript_MoveEffectRecoil ,
[ 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_MoveEffectSleep ,
[ MOVE_EFFECT_RECOIL_33 ] = BattleScript_MoveEffectRecoil ,
2017-09-26 22:39:59 +02:00
} ;
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 " ) ;
2018-10-21 09:24:57 +02:00
static const u32 sUnknown_0831C2E8 [ ] = INCBIN_U32 ( " 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 ,
2019-03-11 08:12:15 +01:00
. shape = SPRITE_SHAPE ( 32 x32 ) ,
2017-09-28 16:32:23 +02:00
. x = 0 ,
. matrixNum = 0 ,
2019-03-11 08:12:15 +01:00
. size = SPRITE_SIZE ( 32 x32 ) ,
2017-09-28 16:32:23 +02:00
. 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
2018-12-05 15:31:01 +01:00
# 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
{
2018-12-08 04:33:41 +01: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
2017-09-28 16:32:23 +02:00
} ;
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 ,
2018-12-05 15:31:01 +01:00
0xFFFF , 0xFFFF
2017-09-28 16:32:23 +02:00
} ;
2017-09-28 16:51:24 +02:00
static const u16 sPickupItems [ ] =
2017-09-28 16:32:23 +02:00
{
ITEM_POTION ,
2018-12-05 15:31:01 +01:00
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:32:23 +02:00
} ;
2017-09-28 16:51:24 +02:00
static const u16 sRarePickupItems [ ] =
2017-09-28 16:32:23 +02:00
{
ITEM_HYPER_POTION ,
2018-12-05 15:31:01 +01:00
ITEM_NUGGET ,
ITEM_KINGS_ROCK ,
ITEM_FULL_RESTORE ,
ITEM_ETHER ,
ITEM_WHITE_HERB ,
ITEM_TM44_REST ,
ITEM_ELIXIR ,
ITEM_TM01_FOCUS_PUNCH ,
ITEM_LEFTOVERS ,
ITEM_TM26_EARTHQUAKE ,
2017-09-28 16:32:23 +02:00
} ;
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 [ ] =
{
2018-12-05 15:31:01 +01:00
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:51:24 +02:00
} ;
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
{
2018-02-06 23:09:39 +01:00
gCurrentActionFuncId = B_ACTION_FINISHED ;
2017-09-19 21:01:12 +02:00
return ;
}
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . hp = = 0 & & ! ( gHitMarker & HITMARKER_NO_ATTACKSTRING ) )
2017-09-19 21:01:12 +02:00
{
gHitMarker | = HITMARKER_UNABLE_TO_USE_MOVE ;
gBattlescriptCurrInstr = BattleScript_MoveEnd ;
return ;
}
if ( AtkCanceller_UnableToUseMove ( ) )
return ;
2018-02-06 23:09:39 +01:00
if ( AbilityBattleEffects ( ABILITYEFFECT_MOVES_BLOCK , gBattlerTarget , 0 , 0 , 0 ) )
2017-09-19 21:01:12 +02:00
return ;
2018-11-30 23:16:15 +01:00
if ( ! gBattleMons [ gBattlerAttacker ] . pp [ gCurrMovePos ] & & gCurrentMove ! = MOVE_STRUGGLE & & ! ( gHitMarker & ( HITMARKER_x800000 | HITMARKER_NO_ATTACKSTRING ) )
2018-02-06 23:09:39 +01:00
& & ! ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_MULTIPLETURNS ) )
2017-09-19 21:01:12 +02:00
{
gBattlescriptCurrInstr = BattleScript_NoPPForMove ;
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-19 21:01:12 +02:00
return ;
}
gHitMarker & = ~ ( HITMARKER_x800000 ) ;
2018-02-06 23:09:39 +01:00
if ( ! ( gHitMarker & HITMARKER_OBEYS ) & & ! ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_MULTIPLETURNS ) )
2017-09-19 21:01:12 +02:00
{
2017-12-02 14:08:55 +01:00
i = IsMonDisobedient ( ) ; // why use the 'i' variable...?
2017-09-19 21:01:12 +02:00
switch ( i )
{
case 0 :
break ;
case 2 :
gHitMarker | = HITMARKER_OBEYS ;
return ;
default :
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-19 21:01:12 +02:00
return ;
}
}
gHitMarker | = HITMARKER_OBEYS ;
2018-02-06 23:09:39 +01:00
if ( gProtectStructs [ gBattlerTarget ] . bounceMove & & gBattleMoves [ gCurrentMove ] . flags & FLAG_MAGICCOAT_AFFECTED )
2017-09-19 21:01:12 +02:00
{
2018-02-06 23:09:39 +01:00
PressurePPLose ( gBattlerAttacker , gBattlerTarget , MOVE_MAGIC_COAT ) ;
gProtectStructs [ gBattlerTarget ] . bounceMove = 0 ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-19 21:01:12 +02:00
gBattlescriptCurrInstr = BattleScript_MagicCoatBounce ;
return ;
}
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-19 21:01:12 +02:00
{
2018-06-28 21:06:32 +02:00
if ( ( gProtectStructs [ gBattlerByTurnOrder [ i ] ] . stealMove ) & & gBattleMoves [ gCurrentMove ] . flags & FLAG_SNATCH_AFFECTED )
2017-09-19 21:01:12 +02:00
{
2018-06-28 21:06:32 +02:00
PressurePPLose ( gBattlerAttacker , gBattlerByTurnOrder [ i ] , MOVE_SNATCH ) ;
gProtectStructs [ gBattlerByTurnOrder [ i ] ] . stealMove = 0 ;
gBattleScripting . battler = gBattlerByTurnOrder [ i ] ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-19 21:01:12 +02:00
gBattlescriptCurrInstr = BattleScript_SnatchedMove ;
return ;
}
}
2018-02-06 23:09:39 +01:00
if ( gSpecialStatuses [ gBattlerTarget ] . lightningRodRedirected )
2017-09-19 21:01:12 +02:00
{
2018-02-06 23:09:39 +01:00
gSpecialStatuses [ gBattlerTarget ] . lightningRodRedirected = 0 ;
2017-09-19 21:01:12 +02:00
gLastUsedAbility = ABILITY_LIGHTNING_ROD ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-19 21:01:12 +02:00
gBattlescriptCurrInstr = BattleScript_TookAttack ;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle ( gBattlerTarget , gLastUsedAbility ) ;
2017-09-19 21:01:12 +02:00
}
2018-01-16 22:12:38 +01:00
else if ( DEFENDER_IS_PROTECTED
2018-03-01 00:59:52 +01:00
& & ( gCurrentMove ! = MOVE_CURSE | | IS_BATTLER_OF_TYPE ( gBattlerAttacker , TYPE_GHOST ) )
2018-02-06 23:09:39 +01:00
& & ( ( ! IsTwoTurnsMove ( gCurrentMove ) | | ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_MULTIPLETURNS ) ) ) )
2017-09-19 21:01:12 +02:00
{
2018-02-06 23:09:39 +01:00
CancelMultiTurnMoves ( gBattlerAttacker ) ;
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2018-02-06 23:09:39 +01:00
gLastLandedMoves [ gBattlerTarget ] = 0 ;
gLastHitByType [ gBattlerTarget ] = 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 ;
2018-01-16 22:12:38 +01:00
if ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2017-09-19 21:01:12 +02:00
{
2018-02-06 23:09:39 +01:00
gLastLandedMoves [ gBattlerTarget ] = 0 ;
gLastHitByType [ gBattlerTarget ] = 0 ;
2018-03-01 00:59:52 +01:00
BS_ptr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-19 21:01:12 +02:00
}
else
{
2017-11-25 18:42:31 +01:00
TrySetDestinyBondToHappen ( ) ;
2018-02-06 23:09:39 +01:00
if ( AbilityBattleEffects ( ABILITYEFFECT_ABSORBING , gBattlerTarget , 0 , 0 , move ) )
2017-09-19 21:01:12 +02:00
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
{
2018-01-16 22:12:38 +01:00
if ( DEFENDER_IS_PROTECTED )
2017-09-19 21:01:12 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-19 21:01:12 +02:00
JumpIfMoveFailed ( 5 , 0 ) ;
gBattleCommunication [ 6 ] = 1 ;
}
else
{
gBattlescriptCurrInstr + = 5 ;
}
}
bool8 JumpIfMoveAffectedByProtect ( u16 move )
{
bool8 affected = FALSE ;
2018-01-16 22:12:38 +01:00
if ( DEFENDER_IS_PROTECTED )
2017-09-19 21:01:12 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-19 21:01:12 +02:00
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
{
2018-02-06 23:09:39 +01:00
if ( gStatuses3 [ gBattlerTarget ] & STATUS3_ALWAYS_HITS & & gDisableStructs [ gBattlerTarget ] . battlerWithSureHit = = gBattlerAttacker )
2017-09-19 21:01:12 +02:00
{
JumpIfMoveFailed ( 7 , move ) ;
return TRUE ;
}
2018-02-06 23:09:39 +01:00
if ( ! ( gHitMarker & HITMARKER_IGNORE_ON_AIR ) & & gStatuses3 [ gBattlerTarget ] & STATUS3_ON_AIR )
2017-09-19 21:01:12 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-19 21:01:12 +02:00
JumpIfMoveFailed ( 7 , move ) ;
return TRUE ;
}
gHitMarker & = ~ HITMARKER_IGNORE_ON_AIR ;
2018-02-06 23:09:39 +01:00
if ( ! ( gHitMarker & HITMARKER_IGNORE_UNDERGROUND ) & & gStatuses3 [ gBattlerTarget ] & STATUS3_UNDERGROUND )
2017-09-19 21:01:12 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-19 21:01:12 +02:00
JumpIfMoveFailed ( 7 , move ) ;
return TRUE ;
}
gHitMarker & = ~ HITMARKER_IGNORE_UNDERGROUND ;
2018-02-06 23:09:39 +01:00
if ( ! ( gHitMarker & HITMARKER_IGNORE_UNDERWATER ) & & gStatuses3 [ gBattlerTarget ] & STATUS3_UNDERWATER )
2017-09-19 21:01:12 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-19 21:01:12 +02:00
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
{
2018-03-01 00:59:52 +01:00
u16 move = T2_READ_16 ( gBattlescriptCurrInstr + 5 ) ;
2017-09-19 21:01:12 +02:00
2018-08-03 00:13:44 +02:00
if ( move = = NO_ACC_CALC | | move = = NO_ACC_CALC_CHECK_LOCK_ON )
2017-09-19 21:01:12 +02:00
{
2018-08-03 00:13:44 +02:00
if ( gStatuses3 [ gBattlerTarget ] & STATUS3_ALWAYS_HITS & & move = = NO_ACC_CALC_CHECK_LOCK_ON & & gDisableStructs [ gBattlerTarget ] . battlerWithSureHit = = gBattlerAttacker )
2017-09-19 21:01:12 +02:00
gBattlescriptCurrInstr + = 7 ;
2018-02-06 23:09:39 +01:00
else if ( gStatuses3 [ gBattlerTarget ] & ( STATUS3_ON_AIR | STATUS3_UNDERGROUND | STATUS3_UNDERWATER ) )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-19 21:01:12 +02:00
else if ( ! JumpIfMoveAffectedByProtect ( 0 ) )
gBattlescriptCurrInstr + = 7 ;
}
else
{
2018-02-08 11:17:41 +01:00
u8 type , moveAcc , holdEffect , param ;
2017-09-19 21:01:12 +02:00
s8 buff ;
u16 calc ;
if ( move = = 0 )
move = gCurrentMove ;
GET_MOVE_TYPE ( move , type ) ;
if ( JumpIfMoveAffectedByProtect ( move ) )
return ;
if ( AccuracyCalcHelper ( move ) )
return ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_FORESIGHT )
2017-09-19 21:01:12 +02:00
{
2018-02-08 12:13:29 +01:00
u8 acc = gBattleMons [ gBattlerAttacker ] . statStages [ STAT_ACC ] ;
2017-09-19 21:01:12 +02:00
buff = acc ;
}
else
{
2018-02-08 12:13:29 +01:00
u8 acc = gBattleMons [ gBattlerAttacker ] . statStages [ STAT_ACC ] ;
buff = acc + 6 - gBattleMons [ gBattlerTarget ] . statStages [ STAT_EVASION ] ;
2017-09-19 21:01:12 +02:00
}
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
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . ability = = ABILITY_COMPOUND_EYES )
2017-09-19 21:01:12 +02:00
calc = ( calc * 130 ) / 100 ; // 1.3 compound eyes boost
2018-02-06 23:09:39 +01:00
if ( WEATHER_HAS_EFFECT & & gBattleMons [ gBattlerTarget ] . ability = = ABILITY_SAND_VEIL & & gBattleWeather & WEATHER_SANDSTORM_ANY )
2017-09-19 21:01:12 +02:00
calc = ( calc * 80 ) / 100 ; // 1.2 sand veil loss
2018-07-16 22:00:27 +02:00
if ( gBattleMons [ gBattlerAttacker ] . ability = = ABILITY_HUSTLE & & IS_TYPE_PHYSICAL ( type ) )
2017-09-19 21:01:12 +02:00
calc = ( calc * 80 ) / 100 ; // 1.2 hustle loss
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . item = = ITEM_ENIGMA_BERRY )
2017-09-19 21:01:12 +02:00
{
2018-02-06 23:09:39 +01:00
holdEffect = gEnigmaBerries [ gBattlerTarget ] . holdEffect ;
2018-02-08 11:17:41 +01:00
param = gEnigmaBerries [ gBattlerTarget ] . holdEffectParam ;
2017-09-19 21:01:12 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ gBattlerTarget ] . item ) ;
2018-02-08 11:17:41 +01:00
param = ItemId_GetHoldEffectParam ( gBattleMons [ gBattlerTarget ] . item ) ;
2017-09-19 21:01:12 +02:00
}
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerTarget ;
2017-09-19 21:01:12 +02:00
if ( holdEffect = = HOLD_EFFECT_EVASION_UP )
2018-02-08 11:17:41 +01:00
calc = ( calc * ( 100 - param ) ) / 100 ;
2017-09-19 21:01:12 +02:00
// final calculation
if ( ( Random ( ) % 100 + 1 ) > calc )
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-19 21:01:12 +02:00
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
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-09-19 21:01:12 +02:00
return ;
if ( ! ( gHitMarker & ( HITMARKER_NO_ATTACKSTRING | HITMARKER_ATTACKSTRING_PRINTED ) ) )
{
2018-02-06 23:09:39 +01:00
PrepareStringBattle ( STRINGID_USEDMOVE , gBattlerAttacker ) ;
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
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-09-20 00:28:00 +02:00
return ;
2018-10-14 18:10:54 +02:00
if ( ! gSpecialStatuses [ gBattlerAttacker ] . ppNotAffectedByPressure )
2017-09-20 00:28:00 +02:00
{
switch ( gBattleMoves [ gCurrentMove ] . target )
{
case MOVE_TARGET_FOES_AND_ALLY :
2018-02-06 23:09:39 +01:00
ppToDeduct + = AbilityBattleEffects ( ABILITYEFFECT_COUNT_ON_FIELD , gBattlerAttacker , ABILITY_PRESSURE , 0 , 0 ) ;
2017-09-20 00:28:00 +02:00
break ;
case MOVE_TARGET_BOTH :
case MOVE_TARGET_OPPONENTS_FIELD :
2018-02-06 23:09:39 +01:00
ppToDeduct + = AbilityBattleEffects ( ABILITYEFFECT_COUNT_OTHER_SIDE , gBattlerAttacker , ABILITY_PRESSURE , 0 , 0 ) ;
2017-09-20 00:28:00 +02:00
break ;
default :
2018-02-06 23:09:39 +01:00
if ( gBattlerAttacker ! = gBattlerTarget & & gBattleMons [ gBattlerTarget ] . ability = = ABILITY_PRESSURE )
2017-09-27 23:43:45 +02:00
ppToDeduct + + ;
2017-09-20 00:28:00 +02:00
break ;
}
}
2018-02-06 23:09:39 +01:00
if ( ! ( gHitMarker & ( HITMARKER_NO_PPDEDUCT | HITMARKER_NO_ATTACKSTRING ) ) & & gBattleMons [ gBattlerAttacker ] . pp [ gCurrMovePos ] )
2017-09-20 00:28:00 +02:00
{
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . notFirstStrike = 1 ;
2017-09-20 00:28:00 +02:00
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . pp [ gCurrMovePos ] > ppToDeduct )
gBattleMons [ gBattlerAttacker ] . pp [ gCurrMovePos ] - = ppToDeduct ;
2017-09-20 00:28:00 +02:00
else
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . pp [ gCurrMovePos ] = 0 ;
2017-09-20 00:28:00 +02:00
2018-02-06 23:09:39 +01:00
if ( ! ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_TRANSFORMED )
2019-01-19 22:32:25 +01:00
& & ! ( ( gDisableStructs [ gBattlerAttacker ] . mimickedMoves ) & gBitTable [ gCurrMovePos ] ) )
2017-09-20 00:28:00 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
BtlController_EmitSetMonData ( 0 , REQUEST_PPMOVE1_BATTLE + gCurrMovePos , 0 , 1 , & gBattleMons [ gBattlerAttacker ] . pp [ gCurrMovePos ] ) ;
MarkBattlerForControllerExec ( gBattlerAttacker ) ;
2017-09-20 00:28:00 +02:00
}
}
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 ;
2018-02-06 23:09:39 +01:00
item = gBattleMons [ gBattlerAttacker ] . item ;
2017-09-20 00:28:00 +02:00
if ( item = = ITEM_ENIGMA_BERRY )
2018-02-06 23:09:39 +01:00
holdEffect = gEnigmaBerries [ gBattlerAttacker ] . holdEffect ;
2017-09-20 00:28:00 +02:00
else
holdEffect = ItemId_GetHoldEffect ( item ) ;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerAttacker ;
2017-09-20 00:28:00 +02:00
2018-02-06 23:09:39 +01:00
critChance = 2 * ( ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_FOCUS_ENERGY ) ! = 0 )
2017-09-20 00:28:00 +02:00
+ ( 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 )
2018-02-06 23:09:39 +01:00
+ 2 * ( holdEffect = = HOLD_EFFECT_LUCKY_PUNCH & & gBattleMons [ gBattlerAttacker ] . species = = SPECIES_CHANSEY )
+ 2 * ( holdEffect = = HOLD_EFFECT_STICK & & gBattleMons [ gBattlerAttacker ] . species = = SPECIES_FARFETCHD ) ;
2017-09-20 00:28:00 +02:00
if ( critChance > 4 )
critChance = 4 ;
2018-02-06 23:09:39 +01:00
if ( ( gBattleMons [ gBattlerTarget ] . ability ! = ABILITY_BATTLE_ARMOR & & gBattleMons [ gBattlerTarget ] . ability ! = ABILITY_SHELL_ARMOR )
& & ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_CANT_SCORE_A_CRIT )
2017-09-20 00:28:00 +02:00
& & ! ( 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
{
2018-02-06 23:09:39 +01:00
u16 sideStatus = gSideStatuses [ GET_BATTLER_SIDE ( gBattlerTarget ) ] ;
gBattleMoveDamage = CalculateBaseDamage ( & gBattleMons [ gBattlerAttacker ] , & gBattleMons [ gBattlerTarget ] , gCurrentMove ,
2017-09-20 00:28:00 +02:00
sideStatus , gDynamicBasePower ,
2018-02-06 23:09:39 +01:00
gBattleStruct - > dynamicMoveType , gBattlerAttacker , gBattlerTarget ) ;
2017-09-20 00:28:00 +02:00
gBattleMoveDamage = gBattleMoveDamage * gCritMultiplier * gBattleScripting . dmgMultiplier ;
2018-02-06 23:09:39 +01:00
if ( gStatuses3 [ gBattlerAttacker ] & STATUS3_CHARGED_UP & & gBattleMoves [ gCurrentMove ] . type = = TYPE_ELECTRIC )
2017-09-20 00:28:00 +02:00
gBattleMoveDamage * = 2 ;
2018-02-06 23:09:39 +01:00
if ( gProtectStructs [ gBattlerAttacker ] . helpingHand )
2017-09-20 00:28:00 +02:00
gBattleMoveDamage = gBattleMoveDamage * 15 / 10 ;
gBattlescriptCurrInstr + + ;
}
2018-02-06 02:46:59 +01:00
void AI_CalcDmg ( u8 attacker , u8 defender )
2017-09-20 00:28:00 +02:00
{
2018-02-06 02:46:59 +01:00
u16 sideStatus = gSideStatuses [ GET_BATTLER_SIDE ( defender ) ] ;
gBattleMoveDamage = CalculateBaseDamage ( & gBattleMons [ attacker ] , & gBattleMons [ defender ] , gCurrentMove ,
2017-09-20 00:28:00 +02:00
sideStatus , gDynamicBasePower ,
2018-02-06 02:46:59 +01:00
gBattleStruct - > dynamicMoveType , attacker , defender ) ;
2017-09-20 00:28:00 +02:00
gDynamicBasePower = 0 ;
gBattleMoveDamage = gBattleMoveDamage * gCritMultiplier * gBattleScripting . dmgMultiplier ;
2018-02-06 02:46:59 +01:00
if ( gStatuses3 [ attacker ] & STATUS3_CHARGED_UP & & gBattleMoves [ gCurrentMove ] . type = = TYPE_ELECTRIC )
2017-09-20 00:28:00 +02:00
gBattleMoveDamage * = 2 ;
2018-02-06 02:46:59 +01:00
if ( gProtectStructs [ attacker ] . helpingHand )
2017-09-20 00:28:00 +02:00
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 :
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_DOESNT_AFFECT_FOE ;
gMoveResultFlags & = ~ MOVE_RESULT_NOT_VERY_EFFECTIVE ;
gMoveResultFlags & = ~ MOVE_RESULT_SUPER_EFFECTIVE ;
2017-09-20 00:28:00 +02:00
break ;
case TYPE_MUL_NOT_EFFECTIVE :
2018-01-16 22:12:38 +01:00
if ( gBattleMoves [ gCurrentMove ] . power & & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
2017-09-20 00:28:00 +02:00
{
2018-01-16 22:12:38 +01:00
if ( gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE )
gMoveResultFlags & = ~ MOVE_RESULT_SUPER_EFFECTIVE ;
2017-09-20 00:28:00 +02:00
else
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_NOT_VERY_EFFECTIVE ;
2017-09-20 00:28:00 +02:00
}
break ;
case TYPE_MUL_SUPER_EFFECTIVE :
2018-01-16 22:12:38 +01:00
if ( gBattleMoves [ gCurrentMove ] . power & & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
2017-09-20 00:28:00 +02:00
{
2018-01-16 22:12:38 +01:00
if ( gMoveResultFlags & MOVE_RESULT_NOT_VERY_EFFECTIVE )
gMoveResultFlags & = ~ MOVE_RESULT_NOT_VERY_EFFECTIVE ;
2017-09-20 00:28:00 +02:00
else
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_SUPER_EFFECTIVE ;
2017-09-20 00:28:00 +02:00
}
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
2018-03-01 00:59:52 +01:00
if ( IS_BATTLER_OF_TYPE ( gBattlerAttacker , moveType ) )
2017-09-20 00:28:00 +02:00
{
gBattleMoveDamage = gBattleMoveDamage * 15 ;
gBattleMoveDamage = gBattleMoveDamage / 10 ;
}
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . ability = = ABILITY_LEVITATE & & moveType = = TYPE_GROUND )
2017-09-20 00:28:00 +02:00
{
2018-02-06 23:09:39 +01:00
gLastUsedAbility = gBattleMons [ gBattlerTarget ] . ability ;
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = ( MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE ) ;
2018-02-06 23:09:39 +01:00
gLastLandedMoves [ gBattlerTarget ] = 0 ;
gLastHitByType [ gBattlerTarget ] = 0 ;
2017-09-20 00:28:00 +02:00
gBattleCommunication [ 6 ] = moveType ;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle ( gBattlerTarget , gLastUsedAbility ) ;
2017-09-20 00:28:00 +02:00
}
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
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_FORESIGHT )
2017-09-20 00:28:00 +02:00
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
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type1 )
2017-11-11 20:01:04 +01:00
ModulateDmgByType ( TYPE_EFFECT_MULTIPLIER ( i ) ) ;
2017-09-20 00:28:00 +02:00
// check type2
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type2 & &
gBattleMons [ gBattlerTarget ] . type1 ! = gBattleMons [ gBattlerTarget ] . type2 )
2017-11-11 20:01:04 +01:00
ModulateDmgByType ( TYPE_EFFECT_MULTIPLIER ( i ) ) ;
2017-09-20 00:28:00 +02:00
}
i + = 3 ;
}
}
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . ability = = ABILITY_WONDER_GUARD & & AttacksThisTurn ( gBattlerAttacker , gCurrentMove ) = = 2
2018-01-16 22:12:38 +01:00
& & ( ! ( gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE ) | | ( ( gMoveResultFlags & ( MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE ) ) = = ( MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE ) ) )
2017-09-20 00:28:00 +02:00
& & gBattleMoves [ gCurrentMove ] . power )
{
gLastUsedAbility = ABILITY_WONDER_GUARD ;
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2018-02-06 23:09:39 +01:00
gLastLandedMoves [ gBattlerTarget ] = 0 ;
gLastHitByType [ gBattlerTarget ] = 0 ;
2017-09-20 00:28:00 +02:00
gBattleCommunication [ 6 ] = 3 ;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle ( gBattlerTarget , gLastUsedAbility ) ;
2017-09-20 00:28:00 +02:00
}
2018-01-16 22:12:38 +01:00
if ( gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE )
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . 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 ) ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . ability = = ABILITY_LEVITATE & & moveType = = TYPE_GROUND )
2017-09-20 00:28:00 +02:00
{
gLastUsedAbility = ABILITY_LEVITATE ;
gBattleCommunication [ 6 ] = moveType ;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle ( gBattlerTarget , ABILITY_LEVITATE ) ;
2017-09-20 00:28:00 +02:00
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
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_FORESIGHT )
2017-09-20 00:28:00 +02:00
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
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type1
2017-11-11 20:01:04 +01:00
& & TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_NO_EFFECT )
2017-09-20 00:28:00 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_DOESNT_AFFECT_FOE ;
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . targetNotAffected = 1 ;
2017-09-20 00:28:00 +02:00
}
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type2 & &
gBattleMons [ gBattlerTarget ] . type1 ! = gBattleMons [ gBattlerTarget ] . 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
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_DOESNT_AFFECT_FOE ;
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . targetNotAffected = 1 ;
2017-09-20 00:28:00 +02:00
}
// check super effective
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type1 & & TYPE_EFFECT_MULTIPLIER ( i ) = = 20 )
2017-09-20 00:28:00 +02:00
flags | = 1 ;
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type2
& & gBattleMons [ gBattlerTarget ] . type1 ! = gBattleMons [ gBattlerTarget ] . 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
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type1 & & TYPE_EFFECT_MULTIPLIER ( i ) = = 5 )
2017-09-20 00:28:00 +02:00
flags | = 2 ;
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type2
& & gBattleMons [ gBattlerTarget ] . type1 ! = gBattleMons [ gBattlerTarget ] . 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 ;
}
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . ability = = ABILITY_WONDER_GUARD & & AttacksThisTurn ( gBattlerAttacker , gCurrentMove ) = = 2 )
2017-09-20 00:28:00 +02:00
{
if ( ( ( flags & 2 ) | | ! ( flags & 1 ) ) & & gBattleMoves [ gCurrentMove ] . power )
{
gLastUsedAbility = ABILITY_WONDER_GUARD ;
gBattleCommunication [ 6 ] = 3 ;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle ( gBattlerTarget , ABILITY_WONDER_GUARD ) ;
2017-09-20 00:28:00 +02:00
}
}
}
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 :
2018-01-16 22:12:38 +01:00
* flags | = MOVE_RESULT_DOESNT_AFFECT_FOE ;
* flags & = ~ MOVE_RESULT_NOT_VERY_EFFECTIVE ;
* flags & = ~ MOVE_RESULT_SUPER_EFFECTIVE ;
2017-09-20 00:28:00 +02:00
break ;
case TYPE_MUL_NOT_EFFECTIVE :
2018-01-16 22:12:38 +01:00
if ( gBattleMoves [ move ] . power & & ! ( * flags & MOVE_RESULT_NO_EFFECT ) )
2017-09-20 00:28:00 +02:00
{
2018-01-16 22:12:38 +01:00
if ( * flags & MOVE_RESULT_SUPER_EFFECTIVE )
* flags & = ~ MOVE_RESULT_SUPER_EFFECTIVE ;
2017-09-20 00:28:00 +02:00
else
2018-01-16 22:12:38 +01:00
* flags | = MOVE_RESULT_NOT_VERY_EFFECTIVE ;
2017-09-20 00:28:00 +02:00
}
break ;
case TYPE_MUL_SUPER_EFFECTIVE :
2018-01-16 22:12:38 +01:00
if ( gBattleMoves [ move ] . power & & ! ( * flags & MOVE_RESULT_NO_EFFECT ) )
2017-09-20 00:28:00 +02:00
{
2018-01-16 22:12:38 +01:00
if ( * flags & MOVE_RESULT_NOT_VERY_EFFECTIVE )
* flags & = ~ MOVE_RESULT_NOT_VERY_EFFECTIVE ;
2017-09-20 00:28:00 +02:00
else
2018-01-16 22:12:38 +01:00
* flags | = MOVE_RESULT_SUPER_EFFECTIVE ;
2017-09-20 00:28:00 +02:00
}
break ;
}
}
2018-02-06 02:46:59 +01:00
u8 TypeCalc ( u16 move , u8 attacker , u8 defender )
2017-09-20 00:28:00 +02:00
{
s32 i = 0 ;
u8 flags = 0 ;
u8 moveType ;
if ( move = = MOVE_STRUGGLE )
return 0 ;
moveType = gBattleMoves [ move ] . type ;
// check stab
2018-03-01 00:59:52 +01:00
if ( IS_BATTLER_OF_TYPE ( attacker , moveType ) )
2017-09-20 00:28:00 +02:00
{
gBattleMoveDamage = gBattleMoveDamage * 15 ;
gBattleMoveDamage = gBattleMoveDamage / 10 ;
}
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ defender ] . ability = = ABILITY_LEVITATE & & moveType = = TYPE_GROUND )
2017-09-20 00:28:00 +02:00
{
2018-01-16 22:12:38 +01:00
flags | = ( MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE ) ;
2017-09-20 00:28:00 +02:00
}
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
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ defender ] . status2 & STATUS2_FORESIGHT )
2017-09-20 00:28:00 +02:00
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
2018-02-06 02:46:59 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ defender ] . type1 )
2017-11-11 20:01:04 +01:00
ModulateDmgByType2 ( TYPE_EFFECT_MULTIPLIER ( i ) , move , & flags ) ;
2017-09-20 00:28:00 +02:00
// check type2
2018-02-06 02:46:59 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ defender ] . type2 & &
gBattleMons [ defender ] . type1 ! = gBattleMons [ defender ] . 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 ;
}
}
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ defender ] . ability = = ABILITY_WONDER_GUARD & & ! ( flags & MOVE_RESULT_MISSED )
& & AttacksThisTurn ( attacker , move ) = = 2
2018-01-16 22:12:38 +01:00
& & ( ! ( flags & MOVE_RESULT_SUPER_EFFECTIVE ) | | ( ( flags & ( MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE ) ) = = ( MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE ) ) )
2017-09-20 00:28:00 +02:00
& & gBattleMoves [ move ] . power )
{
2018-01-16 22:12:38 +01:00
flags | = MOVE_RESULT_MISSED ;
2017-09-20 00:28:00 +02:00
}
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
{
2018-01-16 22:12:38 +01:00
flags = MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE ;
2017-09-20 00:28:00 +02:00
}
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
2018-01-16 22:12:38 +01:00
& & ( ! ( flags & MOVE_RESULT_SUPER_EFFECTIVE ) | | ( ( flags & ( MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE ) ) = = ( MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE ) ) )
2017-09-20 00:28:00 +02:00
& & gBattleMoves [ move ] . power )
2018-01-16 22:12:38 +01:00
flags | = MOVE_RESULT_DOESNT_AFFECT_FOE ;
2017-09-20 00:28:00 +02:00
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
{
2018-02-08 11:17:41 +01:00
u8 holdEffect , param ;
2017-09-20 00:28:00 +02:00
ApplyRandomDmgMultiplier ( ) ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . item = = ITEM_ENIGMA_BERRY )
2017-09-20 00:28:00 +02:00
{
2018-02-08 11:17:41 +01:00
holdEffect = gEnigmaBerries [ gBattlerTarget ] . holdEffect ;
param = gEnigmaBerries [ gBattlerTarget ] . holdEffectParam ;
2017-09-20 00:28:00 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ gBattlerTarget ] . item ) ;
2018-02-08 11:17:41 +01:00
param = ItemId_GetHoldEffectParam ( gBattleMons [ gBattlerTarget ] . item ) ;
2017-09-20 00:28:00 +02:00
}
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerTarget ;
2017-09-20 00:28:00 +02:00
2018-02-08 11:17:41 +01:00
if ( holdEffect = = HOLD_EFFECT_FOCUS_BAND & & ( Random ( ) % 100 ) < param )
2017-09-20 00:28:00 +02:00
{
2018-02-06 23:09:39 +01:00
RecordItemEffectBattle ( gBattlerTarget , holdEffect ) ;
gSpecialStatuses [ gBattlerTarget ] . focusBanded = 1 ;
2017-09-20 00:28:00 +02:00
}
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_SUBSTITUTE )
2017-09-20 00:28:00 +02:00
goto END ;
2018-02-06 23:09:39 +01:00
if ( gBattleMoves [ gCurrentMove ] . effect ! = EFFECT_FALSE_SWIPE & & ! gProtectStructs [ gBattlerTarget ] . endured
& & ! gSpecialStatuses [ gBattlerTarget ] . focusBanded )
2017-09-20 00:28:00 +02:00
goto END ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . hp > gBattleMoveDamage )
2017-09-20 00:28:00 +02:00
goto END ;
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . hp - 1 ;
2017-09-20 00:28:00 +02:00
2018-02-06 23:09:39 +01:00
if ( gProtectStructs [ gBattlerTarget ] . endured )
2017-09-20 00:28:00 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_FOE_ENDURED ;
2017-09-20 00:28:00 +02:00
}
2018-02-06 23:09:39 +01:00
else if ( gSpecialStatuses [ gBattlerTarget ] . focusBanded )
2017-09-20 00:28:00 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_FOE_HUNG_ON ;
2018-02-06 23:09:39 +01:00
gLastUsedItem = gBattleMons [ gBattlerTarget ] . item ;
2017-09-20 00:28:00 +02:00
}
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
{
2018-02-08 11:17:41 +01:00
u8 holdEffect , param ;
2017-09-20 00:28:00 +02:00
ApplyRandomDmgMultiplier ( ) ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . item = = ITEM_ENIGMA_BERRY )
2017-09-20 00:28:00 +02:00
{
2018-02-08 11:17:41 +01:00
holdEffect = gEnigmaBerries [ gBattlerTarget ] . holdEffect ;
param = gEnigmaBerries [ gBattlerTarget ] . holdEffectParam ;
2017-09-20 00:28:00 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ gBattlerTarget ] . item ) ;
2018-02-08 11:17:41 +01:00
param = ItemId_GetHoldEffectParam ( gBattleMons [ gBattlerTarget ] . item ) ;
2017-09-20 00:28:00 +02:00
}
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerTarget ;
2017-09-20 00:28:00 +02:00
2018-02-08 11:17:41 +01:00
if ( holdEffect = = HOLD_EFFECT_FOCUS_BAND & & ( Random ( ) % 100 ) < param )
2017-09-20 00:28:00 +02:00
{
2018-02-06 23:09:39 +01:00
RecordItemEffectBattle ( gBattlerTarget , holdEffect ) ;
gSpecialStatuses [ gBattlerTarget ] . focusBanded = 1 ;
2017-09-20 00:28:00 +02:00
}
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_SUBSTITUTE )
2017-09-20 00:28:00 +02:00
goto END ;
2018-02-06 23:09:39 +01:00
if ( ! gProtectStructs [ gBattlerTarget ] . endured & & ! gSpecialStatuses [ gBattlerTarget ] . focusBanded )
2017-09-20 00:28:00 +02:00
goto END ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . hp > gBattleMoveDamage )
2017-09-20 00:28:00 +02:00
goto END ;
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . hp - 1 ;
2017-09-20 00:28:00 +02:00
2018-02-06 23:09:39 +01:00
if ( gProtectStructs [ gBattlerTarget ] . endured )
2017-09-20 00:28:00 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_FOE_ENDURED ;
2017-09-20 00:28:00 +02:00
}
2018-02-06 23:09:39 +01:00
else if ( gSpecialStatuses [ gBattlerTarget ] . focusBanded )
2017-09-20 00:28:00 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_FOE_HUNG_ON ;
2018-02-06 23:09:39 +01:00
gLastUsedItem = gBattleMons [ gBattlerTarget ] . item ;
2017-09-20 00:28:00 +02:00
}
END :
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk09_attackanimation ( void )
2017-09-20 00:28:00 +02:00
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-09-20 00:28:00 +02:00
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 ;
}
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
2017-09-20 00:28:00 +02:00
{
u8 multihit ;
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2017-09-20 00:28:00 +02:00
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_SUBSTITUTE )
2017-09-20 00:28:00 +02:00
multihit = gMultiHitCounter ;
else if ( gMultiHitCounter ! = 0 & & gMultiHitCounter ! = 1 )
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . hp < = gBattleMoveDamage )
2017-09-20 00:28:00 +02:00
multihit = 1 ;
else
multihit = gMultiHitCounter ;
}
else
multihit = gMultiHitCounter ;
2018-02-06 23:09:39 +01:00
BtlController_EmitMoveAnimation ( 0 , gCurrentMove , gBattleScripting . animTurn , gBattleMovePower , gBattleMoveDamage , gBattleMons [ gBattlerAttacker ] . friendship , & gDisableStructs [ gBattlerAttacker ] , multihit ) ;
2017-09-20 00:28:00 +02:00
gBattleScripting . animTurn + = 1 ;
gBattleScripting . animTargetsHit + = 1 ;
2018-02-06 23:09:39 +01:00
MarkBattlerForControllerExec ( gBattlerAttacker ) ;
2017-09-20 00:28:00 +02:00
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
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-20 00:28:00 +02:00
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk0B_healthbarupdate ( void )
2017-09-20 00:28:00 +02:00
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-09-20 12:56:45 +02:00
return ;
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
2017-09-20 12:56:45 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-20 12:56:45 +02:00
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_SUBSTITUTE & & gDisableStructs [ gActiveBattler ] . substituteHP & & ! ( gHitMarker & HITMARKER_IGNORE_SUBSTITUTE ) )
2017-09-20 12:56:45 +02:00
{
2018-02-06 02:46:59 +01:00
PrepareStringBattle ( STRINGID_SUBSTITUTEDAMAGED , gActiveBattler ) ;
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 ;
2018-02-06 20:48:02 +01:00
BtlController_EmitHealthBarUpdate ( 0 , healthValue ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-20 12:56:45 +02:00
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_PLAYER & & gBattleMoveDamage > 0 )
2018-10-14 18:37:52 +02:00
gBattleResults . playerMonWasDamaged = TRUE ;
2017-09-20 12:56:45 +02:00
}
}
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
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-09-20 00:28:00 +02:00
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
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
2017-09-20 00:28:00 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_SUBSTITUTE & & gDisableStructs [ gActiveBattler ] . substituteHP & & ! ( gHitMarker & HITMARKER_IGNORE_SUBSTITUTE ) )
2017-09-20 12:56:45 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gDisableStructs [ gActiveBattler ] . substituteHP > = gBattleMoveDamage )
2017-09-20 12:56:45 +02:00
{
2018-02-07 22:53:40 +01:00
if ( gSpecialStatuses [ gActiveBattler ] . dmg = = 0 )
gSpecialStatuses [ gActiveBattler ] . dmg = gBattleMoveDamage ;
2018-02-06 02:46:59 +01:00
gDisableStructs [ gActiveBattler ] . substituteHP - = gBattleMoveDamage ;
2017-09-20 12:56:45 +02:00
gHpDealt = gBattleMoveDamage ;
}
else
{
2018-02-07 22:53:40 +01:00
if ( gSpecialStatuses [ gActiveBattler ] . dmg = = 0 )
gSpecialStatuses [ gActiveBattler ] . dmg = gDisableStructs [ gActiveBattler ] . substituteHP ;
2018-02-06 02:46:59 +01:00
gHpDealt = gDisableStructs [ gActiveBattler ] . substituteHP ;
gDisableStructs [ gActiveBattler ] . substituteHP = 0 ;
2017-09-20 12:56:45 +02:00
}
// check substitute fading
2018-02-06 02:46:59 +01:00
if ( gDisableStructs [ gActiveBattler ] . substituteHP = = 0 )
2017-09-20 12:56:45 +02:00
{
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
{
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . hp - = gBattleMoveDamage ;
if ( gBattleMons [ gActiveBattler ] . hp > gBattleMons [ gActiveBattler ] . maxHP )
gBattleMons [ gActiveBattler ] . hp = gBattleMons [ gActiveBattler ] . maxHP ;
2017-09-20 12:56:45 +02:00
}
else // hp goes down
{
if ( gHitMarker & HITMARKER_x20 )
{
gHitMarker & = ~ ( HITMARKER_x20 ) ;
}
else
{
2018-02-06 02:46:59 +01:00
gTakenDmg [ gActiveBattler ] + = gBattleMoveDamage ;
2018-02-08 11:17:41 +01:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_TARGET )
2018-02-07 22:53:40 +01:00
gTakenDmgByBattler [ gActiveBattler ] = gBattlerAttacker ;
2017-09-20 12:56:45 +02:00
else
2018-02-07 22:53:40 +01:00
gTakenDmgByBattler [ gActiveBattler ] = gBattlerTarget ;
2017-09-20 12:56:45 +02:00
}
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . hp > gBattleMoveDamage )
2017-09-20 12:56:45 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . hp - = gBattleMoveDamage ;
2017-09-20 12:56:45 +02:00
gHpDealt = gBattleMoveDamage ;
}
else
{
2018-02-06 02:46:59 +01:00
gHpDealt = gBattleMons [ gActiveBattler ] . hp ;
gBattleMons [ gActiveBattler ] . hp = 0 ;
2017-09-20 12:56:45 +02:00
}
2018-02-07 22:53:40 +01:00
if ( ! gSpecialStatuses [ gActiveBattler ] . dmg & & ! ( gHitMarker & HITMARKER_x100000 ) )
gSpecialStatuses [ gActiveBattler ] . dmg = gHpDealt ;
2017-09-20 12:56:45 +02:00
2018-07-16 22:00:27 +02:00
if ( IS_TYPE_PHYSICAL ( moveType ) & & ! ( gHitMarker & HITMARKER_x100000 ) & & gCurrentMove ! = MOVE_PAIN_SPLIT )
2017-09-20 12:56:45 +02:00
{
2018-02-06 02:46:59 +01:00
gProtectStructs [ gActiveBattler ] . physicalDmg = gHpDealt ;
2018-02-07 22:53:40 +01:00
gSpecialStatuses [ gActiveBattler ] . physicalDmg = gHpDealt ;
2018-02-08 11:17:41 +01:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_TARGET )
2017-09-20 12:56:45 +02:00
{
2018-02-07 22:53:40 +01:00
gProtectStructs [ gActiveBattler ] . physicalBattlerId = gBattlerAttacker ;
gSpecialStatuses [ gActiveBattler ] . physicalBattlerId = gBattlerAttacker ;
2017-09-20 12:56:45 +02:00
}
else
{
2018-02-07 22:53:40 +01:00
gProtectStructs [ gActiveBattler ] . physicalBattlerId = gBattlerTarget ;
gSpecialStatuses [ gActiveBattler ] . physicalBattlerId = gBattlerTarget ;
2017-09-20 12:56:45 +02:00
}
}
2018-07-16 22:00:27 +02:00
else if ( ! IS_TYPE_PHYSICAL ( moveType ) & & ! ( gHitMarker & HITMARKER_x100000 ) )
2017-09-20 12:56:45 +02:00
{
2018-02-06 02:46:59 +01:00
gProtectStructs [ gActiveBattler ] . specialDmg = gHpDealt ;
2018-02-07 22:53:40 +01:00
gSpecialStatuses [ gActiveBattler ] . specialDmg = gHpDealt ;
2018-02-08 11:17:41 +01:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_TARGET )
2017-09-20 12:56:45 +02:00
{
2018-02-07 22:53:40 +01:00
gProtectStructs [ gActiveBattler ] . specialBattlerId = gBattlerAttacker ;
gSpecialStatuses [ gActiveBattler ] . specialBattlerId = gBattlerAttacker ;
2017-09-20 12:56:45 +02:00
}
else
{
2018-02-07 22:53:40 +01:00
gProtectStructs [ gActiveBattler ] . specialBattlerId = gBattlerTarget ;
gSpecialStatuses [ gActiveBattler ] . specialBattlerId = gBattlerTarget ;
2017-09-20 12:56:45 +02:00
}
}
}
gHitMarker & = ~ ( HITMARKER_x100000 ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_HP_BATTLE , 0 , 2 , & gBattleMons [ gActiveBattler ] . hp ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-20 12:56:45 +02:00
}
}
else
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-02-07 22:53:40 +01:00
if ( gSpecialStatuses [ gActiveBattler ] . dmg = = 0 )
2018-12-05 15:31:01 +01:00
gSpecialStatuses [ gActiveBattler ] . dmg = 0xFFFF ;
2017-09-20 12:56:45 +02:00
}
gBattlescriptCurrInstr + = 2 ;
}
2017-09-28 15:34:21 +02:00
static void atk0D_critmessage ( void )
2017-09-20 12:56:45 +02:00
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-20 12:56:45 +02:00
{
2018-01-16 22:12:38 +01:00
if ( gCritMultiplier = = 2 & & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
2017-09-20 12:56:45 +02:00
{
2018-02-06 23:09:39 +01:00
PrepareStringBattle ( STRINGID_CRITICALHIT , gBattlerAttacker ) ;
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
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-09-20 12:56:45 +02:00
return ;
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget ;
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_MISSED ) )
2017-09-20 12:56:45 +02:00
{
2018-01-16 22:12:38 +01:00
switch ( gMoveResultFlags & ( u8 ) ( ~ ( MOVE_RESULT_MISSED ) ) )
2017-09-20 12:56:45 +02:00
{
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_SUPER_EFFECTIVE :
2018-02-06 20:48:02 +01:00
BtlController_EmitPlaySE ( 0 , SE_KOUKA_H ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-20 12:56:45 +02:00
break ;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_NOT_VERY_EFFECTIVE :
2018-02-06 20:48:02 +01:00
BtlController_EmitPlaySE ( 0 , SE_KOUKA_L ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-20 12:56:45 +02:00
break ;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_DOESNT_AFFECT_FOE :
case MOVE_RESULT_FAILED :
2017-09-20 12:56:45 +02:00
// no sound
break ;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_FOE_ENDURED :
case MOVE_RESULT_ONE_HIT_KO :
case MOVE_RESULT_FOE_HUNG_ON :
2017-09-20 12:56:45 +02:00
default :
2018-01-16 22:12:38 +01:00
if ( gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE )
2017-09-20 12:56:45 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitPlaySE ( 0 , SE_KOUKA_H ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-20 12:56:45 +02:00
}
2018-01-16 22:12:38 +01:00
else if ( gMoveResultFlags & MOVE_RESULT_NOT_VERY_EFFECTIVE )
2017-09-20 12:56:45 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitPlaySE ( 0 , SE_KOUKA_L ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-20 12:56:45 +02:00
}
2018-01-16 22:12:38 +01:00
else if ( ! ( gMoveResultFlags & ( MOVE_RESULT_DOESNT_AFFECT_FOE | MOVE_RESULT_FAILED ) ) )
2017-09-20 12:56:45 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitPlaySE ( 0 , SE_KOUKA_M ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-20 12:56:45 +02:00
}
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 ;
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-09-20 12:56:45 +02:00
return ;
2018-01-16 22:12:38 +01:00
if ( gMoveResultFlags & MOVE_RESULT_MISSED & & ( ! ( gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE ) | | gBattleCommunication [ 6 ] > 2 ) )
2017-09-20 12:56:45 +02:00
{
stringId = gMissStringIds [ gBattleCommunication [ 6 ] ] ;
gBattleCommunication [ MSG_DISPLAY ] = 1 ;
}
else
{
gBattleCommunication [ MSG_DISPLAY ] = 1 ;
2018-01-16 22:12:38 +01:00
switch ( gMoveResultFlags & ( u8 ) ( ~ ( MOVE_RESULT_MISSED ) ) )
2017-09-20 12:56:45 +02:00
{
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_SUPER_EFFECTIVE :
2017-10-07 15:15:47 +02:00
stringId = STRINGID_SUPEREFFECTIVE ;
2017-09-20 12:56:45 +02:00
break ;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_NOT_VERY_EFFECTIVE :
2017-10-07 15:15:47 +02:00
stringId = STRINGID_NOTVERYEFFECTIVE ;
2017-09-20 12:56:45 +02:00
break ;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_ONE_HIT_KO :
2017-10-07 15:15:47 +02:00
stringId = STRINGID_ONEHITKO ;
2017-09-20 12:56:45 +02:00
break ;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_FOE_ENDURED :
2017-10-07 15:15:47 +02:00
stringId = STRINGID_PKMNENDUREDHIT ;
2017-09-20 12:56:45 +02:00
break ;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_FAILED :
2017-10-07 15:15:47 +02:00
stringId = STRINGID_BUTITFAILED ;
2017-09-20 12:56:45 +02:00
break ;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_DOESNT_AFFECT_FOE :
2017-10-07 15:15:47 +02:00
stringId = STRINGID_ITDOESNTAFFECT ;
2017-09-20 12:56:45 +02:00
break ;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_FOE_HUNG_ON :
2018-02-06 23:09:39 +01:00
gLastUsedItem = gBattleMons [ gBattlerTarget ] . item ;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerTarget ;
2018-01-16 22:12:38 +01:00
gMoveResultFlags & = ~ ( MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr = BattleScript_HangedOnMsg ;
return ;
default :
2018-01-16 22:12:38 +01:00
if ( gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE )
2017-09-20 12:56:45 +02:00
{
2017-10-07 15:15:47 +02:00
stringId = STRINGID_ITDOESNTAFFECT ;
2017-09-20 12:56:45 +02:00
}
2018-01-16 22:12:38 +01:00
else if ( gMoveResultFlags & MOVE_RESULT_ONE_HIT_KO )
2017-09-20 12:56:45 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags & = ~ ( MOVE_RESULT_ONE_HIT_KO ) ;
gMoveResultFlags & = ~ ( MOVE_RESULT_SUPER_EFFECTIVE ) ;
gMoveResultFlags & = ~ ( MOVE_RESULT_NOT_VERY_EFFECTIVE ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr = BattleScript_OneHitKOMsg ;
return ;
}
2018-01-16 22:12:38 +01:00
else if ( gMoveResultFlags & MOVE_RESULT_FOE_ENDURED )
2017-09-20 12:56:45 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags & = ~ ( MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr = BattleScript_EnduredMsg ;
return ;
}
2018-01-16 22:12:38 +01:00
else if ( gMoveResultFlags & MOVE_RESULT_FOE_HUNG_ON )
2017-09-20 12:56:45 +02:00
{
2018-02-06 23:09:39 +01:00
gLastUsedItem = gBattleMons [ gBattlerTarget ] . item ;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerTarget ;
2018-01-16 22:12:38 +01:00
gMoveResultFlags & = ~ ( MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr = BattleScript_HangedOnMsg ;
return ;
}
2018-01-16 22:12:38 +01:00
else if ( gMoveResultFlags & MOVE_RESULT_FAILED )
2017-09-20 12:56:45 +02:00
{
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 )
2018-02-06 23:09:39 +01:00
PrepareStringBattle ( stringId , gBattlerAttacker ) ;
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk10_printstring ( void )
2017-09-20 12:56:45 +02:00
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-20 12:56:45 +02:00
{
2018-03-01 00:59:52 +01:00
u16 var = T2_READ_16 ( gBattlescriptCurrInstr + 1 ) ;
2018-02-06 23:09:39 +01:00
PrepareStringBattle ( var , gBattlerAttacker ) ;
2017-09-20 12:56:45 +02:00
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
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2017-09-20 00:28:00 +02:00
2018-03-01 00:59:52 +01:00
BtlController_EmitPrintSelectionString ( 0 , T2_READ_16 ( gBattlescriptCurrInstr + 1 ) ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-20 00:28:00 +02:00
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
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-20 12:56:45 +02:00
{
if ( ! gBattleCommunication [ MSG_DISPLAY ] )
{
gBattlescriptCurrInstr + = 3 ;
}
else
{
2018-03-01 00:59:52 +01:00
u16 toWait = T2_READ_16 ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 12:56:45 +02:00
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
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-20 12:56:45 +02:00
{
2018-03-01 00:59:52 +01:00
const u16 * ptr = ( const u16 * ) T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 12:56:45 +02:00
ptr + = gBattleCommunication [ MULTISTRING_CHOOSER ] ;
2018-02-06 23:09:39 +01:00
PrepareStringBattle ( * ptr , gBattlerAttacker ) ;
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
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-20 12:56:45 +02:00
{
2018-03-01 00:59:52 +01:00
const u16 * ptr = ( const u16 * ) T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 12:56:45 +02:00
ptr + = gBattleCommunication [ MULTISTRING_CHOOSER ] ;
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-02-06 20:48:02 +01:00
BtlController_EmitPrintSelectionString ( 0 , * ptr ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr + = 5 ;
gBattleCommunication [ MSG_DISPLAY ] = 1 ;
}
}
2018-02-08 12:13:29 +01:00
u8 GetBattlerTurnOrderNum ( u8 battlerId )
2017-09-20 12:56:45 +02:00
{
s32 i ;
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-20 12:56:45 +02:00
{
2018-06-28 21:06:32 +02:00
if ( gBattlerByTurnOrder [ i ] = = battlerId )
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 )
{
2018-02-08 12:13:29 +01:00
gEffectBattler = gBattlerAttacker ; // battlerId that effects get applied on
2017-09-20 22:54:26 +02:00
gBattleCommunication [ MOVE_EFFECT_BYTE ] & = ~ ( MOVE_EFFECT_AFFECTS_USER ) ;
affectsUser = MOVE_EFFECT_AFFECTS_USER ;
2018-02-06 23:09:39 +01:00
gBattleScripting . battler = gBattlerTarget ; // theoretically the attacker
2017-09-20 22:54:26 +02:00
}
else
{
2018-02-08 11:17:41 +01:00
gEffectBattler = gBattlerTarget ;
2018-02-06 23:09:39 +01:00
gBattleScripting . battler = gBattlerAttacker ;
2017-09-20 22:54:26 +02:00
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_SHIELD_DUST & & ! ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
2017-09-20 22:54:26 +02:00
& & ! primary & & gBattleCommunication [ MOVE_EFFECT_BYTE ] < = 9 )
INCREMENT_RESET_RETURN
2018-02-08 11:17:41 +01:00
if ( gSideStatuses [ GET_BATTLER_SIDE ( gEffectBattler ) ] & SIDE_STATUS_SAFEGUARD & & ! ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
2017-09-20 22:54:26 +02:00
& & ! primary & & gBattleCommunication [ MOVE_EFFECT_BYTE ] < = 7 )
INCREMENT_RESET_RETURN
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . hp = = 0
2017-09-20 22:54:26 +02:00
& & gBattleCommunication [ MOVE_EFFECT_BYTE ] ! = MOVE_EFFECT_PAYDAY
& & gBattleCommunication [ MOVE_EFFECT_BYTE ] ! = MOVE_EFFECT_STEAL_ITEM )
INCREMENT_RESET_RETURN
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status2 & STATUS2_SUBSTITUTE & & affectsUser ! = MOVE_EFFECT_AFFECTS_USER )
2017-09-20 22:54:26 +02:00
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
{
2018-01-16 22:12:38 +01:00
case STATUS1_SLEEP :
2017-09-20 22:54:26 +02:00
// check active uproar
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability ! = ABILITY_SOUNDPROOF )
2017-09-20 22:54:26 +02:00
{
2018-02-06 02:46:59 +01:00
for ( gActiveBattler = 0 ;
gActiveBattler < gBattlersCount & & ! ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_UPROAR ) ;
gActiveBattler + + )
2017-09-20 22:54:26 +02:00
{ }
}
else
2018-02-06 02:46:59 +01:00
gActiveBattler = gBattlersCount ;
2017-09-20 22:54:26 +02:00
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status1 )
2017-09-20 22:54:26 +02:00
break ;
2018-02-06 02:46:59 +01:00
if ( gActiveBattler ! = gBattlersCount )
2017-09-20 22:54:26 +02:00
break ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_VITAL_SPIRIT )
2017-09-20 22:54:26 +02:00
break ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_INSOMNIA )
2017-09-20 22:54:26 +02:00
break ;
2018-02-08 11:17:41 +01:00
CancelMultiTurnMoves ( gEffectBattler ) ;
2017-09-20 22:54:26 +02:00
statusChanged = TRUE ;
break ;
2018-01-16 22:12:38 +01:00
case STATUS1_POISON :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . 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 ;
2018-02-08 11:17:41 +01:00
RecordAbilityBattle ( gEffectBattler , ABILITY_IMMUNITY ) ;
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 ;
if ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
gHitMarker & = ~ ( HITMARKER_IGNORE_SAFEGUARD ) ;
}
else
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
RESET_RETURN
}
2018-03-01 00:59:52 +01:00
if ( ( IS_BATTLER_OF_TYPE ( gEffectBattler , TYPE_POISON ) | | IS_BATTLER_OF_TYPE ( gEffectBattler , TYPE_STEEL ) )
2017-09-20 22:54:26 +02:00
& & ( 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
}
2018-03-01 00:59:52 +01:00
if ( IS_BATTLER_OF_TYPE ( gEffectBattler , TYPE_POISON ) )
2017-09-20 22:54:26 +02:00
break ;
2018-03-01 00:59:52 +01:00
if ( IS_BATTLER_OF_TYPE ( gEffectBattler , TYPE_STEEL ) )
2017-09-20 22:54:26 +02:00
break ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status1 )
2017-09-20 22:54:26 +02:00
break ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_IMMUNITY )
2017-09-20 22:54:26 +02:00
break ;
statusChanged = TRUE ;
break ;
2018-01-16 22:12:38 +01:00
case STATUS1_BURN :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . 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 ;
2018-02-08 11:17:41 +01:00
RecordAbilityBattle ( gEffectBattler , ABILITY_WATER_VEIL ) ;
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 ;
if ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
gHitMarker & = ~ ( HITMARKER_IGNORE_SAFEGUARD ) ;
}
else
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
RESET_RETURN
}
2018-03-01 00:59:52 +01:00
if ( IS_BATTLER_OF_TYPE ( gEffectBattler , TYPE_FIRE )
2017-09-20 22:54:26 +02:00
& & ( 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
}
2018-03-01 00:59:52 +01:00
if ( IS_BATTLER_OF_TYPE ( gEffectBattler , TYPE_FIRE ) )
2017-09-20 22:54:26 +02:00
break ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_WATER_VEIL )
2017-09-20 22:54:26 +02:00
break ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status1 )
2017-09-20 22:54:26 +02:00
break ;
statusChanged = TRUE ;
break ;
2018-01-16 22:12:38 +01:00
case STATUS1_FREEZE :
2017-09-20 22:54:26 +02:00
if ( WEATHER_HAS_EFFECT & & gBattleWeather & WEATHER_SUN_ANY )
noSunCanFreeze = FALSE ;
2018-03-01 00:59:52 +01:00
if ( IS_BATTLER_OF_TYPE ( gEffectBattler , TYPE_ICE ) )
2017-09-20 22:54:26 +02:00
break ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status1 )
2017-09-20 22:54:26 +02:00
break ;
if ( noSunCanFreeze = = 0 )
break ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_MAGMA_ARMOR )
2017-09-20 22:54:26 +02:00
break ;
2018-02-08 11:17:41 +01:00
CancelMultiTurnMoves ( gEffectBattler ) ;
2017-09-20 22:54:26 +02:00
statusChanged = TRUE ;
break ;
2018-01-16 22:12:38 +01:00
case STATUS1_PARALYSIS :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_LIMBER )
2017-09-20 22:54:26 +02:00
{
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 ;
2018-02-08 11:17:41 +01:00
RecordAbilityBattle ( gEffectBattler , ABILITY_LIMBER ) ;
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_PRLZPrevention ;
if ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
gHitMarker & = ~ ( HITMARKER_IGNORE_SAFEGUARD ) ;
}
else
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
RESET_RETURN
}
else
break ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status1 )
2017-09-20 22:54:26 +02:00
break ;
statusChanged = TRUE ;
break ;
2018-01-16 22:12:38 +01:00
case STATUS1_TOXIC_POISON :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_IMMUNITY & & ( primary = = TRUE | | certain = = MOVE_EFFECT_CERTAIN ) )
2017-09-20 22:54:26 +02:00
{
gLastUsedAbility = ABILITY_IMMUNITY ;
2018-02-08 11:17:41 +01:00
RecordAbilityBattle ( gEffectBattler , ABILITY_IMMUNITY ) ;
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 ;
if ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
gHitMarker & = ~ ( HITMARKER_IGNORE_SAFEGUARD ) ;
}
else
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
RESET_RETURN
}
2018-03-01 00:59:52 +01:00
if ( ( IS_BATTLER_OF_TYPE ( gEffectBattler , TYPE_POISON ) | | IS_BATTLER_OF_TYPE ( gEffectBattler , TYPE_STEEL ) )
2017-09-20 22:54:26 +02:00
& & ( 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
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status1 )
2017-09-20 22:54:26 +02:00
break ;
2018-03-01 00:59:52 +01:00
if ( ! IS_BATTLER_OF_TYPE ( gEffectBattler , TYPE_POISON ) & & ! IS_BATTLER_OF_TYPE ( gEffectBattler , TYPE_STEEL ) )
2017-09-20 22:54:26 +02:00
{
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_IMMUNITY )
2017-09-20 22:54:26 +02:00
break ;
// It's redundant, because at this point we know the status1 value is 0.
2018-02-08 11:17:41 +01:00
gBattleMons [ gEffectBattler ] . status1 & = ~ ( STATUS1_TOXIC_POISON ) ;
gBattleMons [ gEffectBattler ] . status1 & = ~ ( STATUS1_POISON ) ;
2017-09-20 22:54:26 +02:00
statusChanged = TRUE ;
break ;
}
else
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_DOESNT_AFFECT_FOE ;
2017-09-20 22:54:26 +02:00
}
break ;
}
if ( statusChanged = = TRUE )
{
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
2018-01-16 22:12:38 +01:00
if ( sStatusFlagsForMoveEffects [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] = = STATUS1_SLEEP )
2018-02-08 11:17:41 +01:00
gBattleMons [ gEffectBattler ] . status1 | = ( ( Random ( ) & 3 ) + 2 ) ;
2017-09-20 22:54:26 +02:00
else
2018-02-08 11:17:41 +01:00
gBattleMons [ gEffectBattler ] . 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
2018-02-08 11:17:41 +01:00
gActiveBattler = gEffectBattler ;
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gEffectBattler ] . status1 ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-20 22:54:26 +02:00
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
{
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . 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 :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_OWN_TEMPO
| | gBattleMons [ gEffectBattler ] . status2 & STATUS2_CONFUSION )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2018-02-08 11:17:41 +01:00
gBattleMons [ gEffectBattler ] . status2 | = ( ( ( Random ( ) ) % 0x4 ) ) + 2 ;
2017-09-20 22:54:26 +02:00
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 :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_INNER_FOCUS )
2017-09-20 22:54:26 +02:00
{
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 ;
2018-02-08 11:17:41 +01:00
RecordAbilityBattle ( gEffectBattler , ABILITY_INNER_FOCUS ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_FlinchPrevention ;
}
else
{
gBattlescriptCurrInstr + + ;
}
}
else
{
2018-02-08 11:17:41 +01:00
if ( GetBattlerTurnOrderNum ( gEffectBattler ) > gCurrentTurnActionNumber )
gBattleMons [ gEffectBattler ] . 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 :
2018-02-08 11:17:41 +01:00
if ( ! ( gBattleMons [ gEffectBattler ] . status2 & STATUS2_UPROAR ) )
2017-09-20 22:54:26 +02:00
{
2017-09-22 21:33:49 +02:00
2018-02-08 11:17:41 +01:00
gBattleMons [ gEffectBattler ] . status2 | = STATUS2_MULTIPLETURNS ;
gLockedMoves [ gEffectBattler ] = gCurrentMove ;
gBattleMons [ gEffectBattler ] . status2 | = ( ( Random ( ) & 3 ) + 2 ) < < 4 ;
2017-09-20 22:54:26 +02:00
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 :
2018-02-06 23:09:39 +01:00
if ( GET_BATTLER_SIDE ( gBattlerAttacker ) = = B_SIDE_PLAYER )
2017-09-20 22:54:26 +02:00
{
u16 PayDay = gPaydayMoney ;
2018-02-06 23:09:39 +01:00
gPaydayMoney + = ( gBattleMons [ gBattlerAttacker ] . level * 5 ) ;
2017-09-20 22:54:26 +02:00
if ( PayDay > gPaydayMoney )
2018-12-05 15:31:01 +01:00
gPaydayMoney = 0xFFFF ;
2017-09-20 22:54:26 +02:00
}
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 :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status1 )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
gBattleCommunication [ MOVE_EFFECT_BYTE ] = Random ( ) % 3 + 3 ;
SetMoveEffect ( FALSE , 0 ) ;
}
break ;
case MOVE_EFFECT_CHARGING :
2018-02-08 11:17:41 +01:00
gBattleMons [ gEffectBattler ] . status2 | = STATUS2_MULTIPLETURNS ;
gLockedMoves [ gEffectBattler ] = gCurrentMove ;
gProtectStructs [ gEffectBattler ] . chargingTurn = 1 ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr + + ;
break ;
case MOVE_EFFECT_WRAP :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status2 & STATUS2_WRAPPED )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2018-02-08 11:17:41 +01:00
gBattleMons [ gEffectBattler ] . status2 | = ( ( Random ( ) & 3 ) + 3 ) < < 0xD ;
2017-09-20 22:54:26 +02:00
2018-02-08 11:17:41 +01:00
* ( gBattleStruct - > wrappedMove + gEffectBattler * 2 + 0 ) = gCurrentMove ;
* ( gBattleStruct - > wrappedMove + gEffectBattler * 2 + 1 ) = gCurrentMove > > 8 ;
* ( gBattleStruct - > wrappedBy + gEffectBattler ) = gBattlerAttacker ;
2017-09-20 22:54:26 +02:00
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 :
2018-02-08 11:17:41 +01:00
gBattleMons [ gEffectBattler ] . status2 | = STATUS2_RECHARGE ;
2018-10-14 18:10:54 +02:00
gDisableStructs [ gEffectBattler ] . rechargeTimer = 2 ;
2018-02-08 11:17:41 +01:00
gLockedMoves [ gEffectBattler ] = gCurrentMove ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr + + ;
break ;
case MOVE_EFFECT_RAGE :
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 | = STATUS2_RAGE ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr + + ;
break ;
case MOVE_EFFECT_STEAL_ITEM :
{
2018-09-20 22:00:00 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_TRAINER_HILL )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
break ;
}
2018-02-06 23:09:39 +01:00
side = GetBattlerSide ( gBattlerAttacker ) ;
if ( GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_OPPONENT
2017-09-20 22:54:26 +02:00
& & ! ( 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 ) )
2018-10-14 18:37:52 +02:00
& & ( gWishFutureKnock . knockedOffMons [ side ] & gBitTable [ gBattlerPartyIndexes [ gBattlerAttacker ] ] ) )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
2018-02-06 23:09:39 +01:00
else if ( gBattleMons [ gBattlerTarget ] . item
& & gBattleMons [ gBattlerTarget ] . ability = = ABILITY_STICKY_HOLD )
2017-09-20 22:54:26 +02:00
{
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_NoItemSteal ;
2018-02-06 23:09:39 +01:00
gLastUsedAbility = gBattleMons [ gBattlerTarget ] . ability ;
RecordAbilityBattle ( gBattlerTarget , gLastUsedAbility ) ;
2017-09-20 22:54:26 +02:00
}
2018-02-06 23:09:39 +01:00
else if ( gBattleMons [ gBattlerAttacker ] . item ! = 0
| | gBattleMons [ gBattlerTarget ] . item = = ITEM_ENIGMA_BERRY
| | IS_ITEM_MAIL ( gBattleMons [ gBattlerTarget ] . item )
| | gBattleMons [ gBattlerTarget ] . 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
{
2018-02-06 23:09:39 +01:00
u16 * changedItem = & gBattleStruct - > changedItems [ gBattlerAttacker ] ;
gLastUsedItem = * changedItem = gBattleMons [ gBattlerTarget ] . item ;
gBattleMons [ gBattlerTarget ] . item = 0 ;
2017-09-20 22:54:26 +02:00
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_HELDITEM_BATTLE , 0 , 2 , & gLastUsedItem ) ;
2018-02-06 23:09:39 +01:00
MarkBattlerForControllerExec ( gBattlerAttacker ) ;
2017-09-20 22:54:26 +02:00
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget ;
BtlController_EmitSetMonData ( 0 , REQUEST_HELDITEM_BATTLE , 0 , 2 , & gBattleMons [ gBattlerTarget ] . item ) ;
MarkBattlerForControllerExec ( gBattlerTarget ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
gBattlescriptCurrInstr = BattleScript_ItemSteal ;
2018-02-06 23:09:39 +01:00
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gBattlerTarget ] ) + 0 ) = 0 ;
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gBattlerTarget ] ) + 1 ) = 0 ;
2017-09-22 21:33:49 +02:00
}
2017-09-20 22:54:26 +02:00
}
break ;
case MOVE_EFFECT_PREVENT_ESCAPE :
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerTarget ] . status2 | = STATUS2_ESCAPE_PREVENTION ;
gDisableStructs [ gBattlerTarget ] . battlerPreventingEscape = gBattlerAttacker ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr + + ;
break ;
case MOVE_EFFECT_NIGHTMARE :
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerTarget ] . status2 | = STATUS2_NIGHTMARE ;
2017-09-20 22:54:26 +02:00
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
2018-02-06 23:09:39 +01:00
if ( ! ( gBattleMons [ gBattlerTarget ] . status1 & STATUS1_PARALYSIS ) )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerTarget ] . status1 & = ~ ( STATUS1_PARALYSIS ) ;
2017-09-20 22:54:26 +02:00
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gActiveBattler ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
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_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 ;
2018-09-01 20:00:13 +02:00
case MOVE_EFFECT_RECOIL_33 : // Double Edge
2017-09-20 22:54:26 +02:00
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 :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status2 & STATUS2_LOCK_CONFUSE )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2018-02-08 11:17:41 +01:00
gBattleMons [ gEffectBattler ] . status2 | = STATUS2_MULTIPLETURNS ;
gLockedMoves [ gEffectBattler ] = gCurrentMove ;
gBattleMons [ gEffectBattler ] . status2 | = ( ( ( Random ( ) & 1 ) + 2 ) < < 0xA ) ;
2017-09-20 22:54:26 +02:00
}
break ;
case MOVE_EFFECT_KNOCK_OFF :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_STICKY_HOLD )
2017-09-20 22:54:26 +02:00
{
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . item = = 0 )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
gLastUsedAbility = ABILITY_STICKY_HOLD ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr = BattleScript_StickyHoldActivates ;
2018-02-08 11:17:41 +01:00
RecordAbilityBattle ( gEffectBattler , ABILITY_STICKY_HOLD ) ;
2017-09-20 22:54:26 +02:00
}
break ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . item )
2017-09-20 22:54:26 +02:00
{
2018-02-08 11:17:41 +01:00
side = GetBattlerSide ( gEffectBattler ) ;
2017-09-20 22:54:26 +02:00
2018-02-08 11:17:41 +01:00
gLastUsedItem = gBattleMons [ gEffectBattler ] . item ;
gBattleMons [ gEffectBattler ] . item = 0 ;
2018-10-14 18:37:52 +02:00
gWishFutureKnock . knockedOffMons [ side ] | = gBitTable [ gBattlerPartyIndexes [ gEffectBattler ] ] ;
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_KnockedOff ;
2018-02-08 11:17:41 +01:00
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gEffectBattler ] ) + 0 ) = 0 ;
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gEffectBattler ] ) + 1 ) = 0 ;
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_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 ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . ability = = ABILITY_SERENE_GRACE )
2017-09-22 21:33:49 +02:00
percentChance = gBattleMoves [ gCurrentMove ] . secondaryEffectChance * 2 ;
else
percentChance = gBattleMoves [ gCurrentMove ] . secondaryEffectChance ;
if ( gBattleCommunication [ MOVE_EFFECT_BYTE ] & MOVE_EFFECT_CERTAIN
2018-01-16 22:12:38 +01:00
& & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
2017-09-22 21:33:49 +02:00
{
gBattleCommunication [ MOVE_EFFECT_BYTE ] & = ~ ( MOVE_EFFECT_CERTAIN ) ;
SetMoveEffect ( 0 , MOVE_EFFECT_CERTAIN ) ;
}
else if ( Random ( ) % 100 < percentChance
& & gBattleCommunication [ MOVE_EFFECT_BYTE ]
2018-01-16 22:12:38 +01:00
& & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
2017-09-22 21:33:49 +02:00
{
if ( percentChance > = 100 )
SetMoveEffect ( 0 , MOVE_EFFECT_CERTAIN ) ;
else
SetMoveEffect ( 0 , 0 ) ;
}
else
{
gBattlescriptCurrInstr + + ;
}
gBattleCommunication [ MOVE_EFFECT_BYTE ] = 0 ;
2017-12-02 23:31:58 +01:00
gBattleScripting . multihitMoveEffect = 0 ;
2017-09-22 21:33:49 +02:00
}
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
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-22 21:33:49 +02:00
if ( gBattleCommunication [ MOVE_EFFECT_BYTE ] < = MOVE_EFFECT_TOXIC )
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . status1 & = ( ~ sStatusFlagsForMoveEffects [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ) ;
2017-09-22 21:33:49 +02:00
else
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . status2 & = ( ~ sStatusFlagsForMoveEffects [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ) ;
2017-09-22 21:33:49 +02:00
gBattleCommunication [ MOVE_EFFECT_BYTE ] = 0 ;
gBattlescriptCurrInstr + = 2 ;
2017-12-02 23:31:58 +01:00
gBattleScripting . multihitMoveEffect = 0 ;
2017-09-22 21:33:49 +02:00
}
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 )
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-02-06 02:46:59 +01:00
if ( gHitMarker & HITMARKER_FAINTED ( gActiveBattler ) )
2017-09-22 21:33:49 +02:00
{
2018-03-01 00:59:52 +01:00
BS_ptr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPop ( ) ;
gBattlescriptCurrInstr = BS_ptr ;
2018-02-06 02:46:59 +01:00
gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] & = ~ ( SIDE_STATUS_SPIKES_DAMAGED ) ;
2017-09-22 21:33:49 +02:00
}
else
{
gBattlescriptCurrInstr + = 7 ;
}
}
else
{
2018-02-08 12:13:29 +01:00
u8 battlerId ;
2017-09-22 21:33:49 +02:00
2018-02-08 11:17:41 +01:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_ATTACKER )
2017-09-22 21:33:49 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-02-08 12:13:29 +01:00
battlerId = gBattlerTarget ;
2017-09-22 21:33:49 +02:00
BS_ptr = BattleScript_FaintAttacker ;
}
else
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget ;
2018-02-08 12:13:29 +01:00
battlerId = gBattlerAttacker ;
2017-09-22 21:33:49 +02:00
BS_ptr = BattleScript_FaintTarget ;
}
2018-02-06 02:46:59 +01:00
if ( ! ( gAbsentBattlerFlags & gBitTable [ gActiveBattler ] )
& & gBattleMons [ gActiveBattler ] . hp = = 0 )
2017-09-22 21:33:49 +02:00
{
2018-02-06 02:46:59 +01:00
gHitMarker | = HITMARKER_FAINTED ( gActiveBattler ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 7 ) ;
gBattlescriptCurrInstr = BS_ptr ;
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_PLAYER )
2017-09-22 21:33:49 +02:00
{
gHitMarker | = HITMARKER_x400000 ;
if ( gBattleResults . playerFaintCounter < 0xFF )
gBattleResults . playerFaintCounter + + ;
2018-02-06 02:46:59 +01:00
AdjustFriendshipOnBattleFaint ( gActiveBattler ) ;
2017-09-22 21:33:49 +02:00
}
else
{
if ( gBattleResults . opponentFaintCounter < 0xFF )
gBattleResults . opponentFaintCounter + + ;
2018-02-06 20:48:02 +01:00
gBattleResults . lastOpponentSpecies = GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gActiveBattler ] ] , MON_DATA_SPECIES , NULL ) ;
2017-09-22 21:33:49 +02:00
}
2018-02-06 23:09:39 +01:00
if ( ( gHitMarker & HITMARKER_DESTINYBOND ) & & gBattleMons [ gBattlerAttacker ] . hp ! = 0 )
2017-09-22 21:33:49 +02:00
{
gHitMarker & = ~ ( HITMARKER_DESTINYBOND ) ;
BattleScriptPush ( gBattlescriptCurrInstr ) ;
2018-02-08 12:13:29 +01:00
gBattleMoveDamage = gBattleMons [ battlerId ] . hp ;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr = BattleScript_DestinyBondTakesLife ;
}
2018-02-06 23:09:39 +01:00
if ( ( gStatuses3 [ gBattlerTarget ] & STATUS3_GRUDGE )
2017-09-22 21:33:49 +02:00
& & ! ( gHitMarker & HITMARKER_GRUDGE )
2018-02-06 23:09:39 +01:00
& & GetBattlerSide ( gBattlerAttacker ) ! = GetBattlerSide ( gBattlerTarget )
& & gBattleMons [ gBattlerAttacker ] . hp ! = 0
2017-09-22 21:33:49 +02:00
& & gCurrentMove ! = MOVE_STRUGGLE )
{
2018-02-06 23:09:39 +01:00
u8 moveIndex = * ( gBattleStruct - > chosenMovePositions + gBattlerAttacker ) ;
2017-09-22 21:33:49 +02:00
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . pp [ moveIndex ] = 0 ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr ) ;
gBattlescriptCurrInstr = BattleScript_GrudgeTakesPp ;
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , moveIndex + REQUEST_PPMOVE1_BATTLE , 0 , 1 , & gBattleMons [ gActiveBattler ] . pp [ moveIndex ] ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-22 21:33:49 +02:00
2018-02-06 23:09:39 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , gBattleMons [ gBattlerAttacker ] . 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
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-22 21:33:49 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitFaintAnimation ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr + = 2 ;
}
}
2017-11-25 18:42:31 +01:00
static void atk1B_cleareffectsonfaint ( void )
2017-09-22 21:33:49 +02:00
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-22 21:33:49 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-22 21:33:49 +02:00
2018-02-06 02:46:59 +01:00
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_ARENA ) | | gBattleMons [ gActiveBattler ] . hp = = 0 )
2017-09-22 21:33:49 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . status1 = 0 ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 0x4 , & gBattleMons [ gActiveBattler ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-22 21:33:49 +02:00
}
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
{
2018-02-08 12:13:29 +01:00
u8 battlerId = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-03-01 00:59:52 +01:00
u32 flags = T2_READ_32 ( gBattlescriptCurrInstr + 2 ) ;
const u8 * jumpPtr = T2_READ_PTR ( gBattlescriptCurrInstr + 6 ) ;
2017-09-22 21:33:49 +02:00
2018-02-08 12:13:29 +01:00
if ( gBattleMons [ battlerId ] . status1 & flags & & gBattleMons [ battlerId ] . hp )
2017-09-22 21:33:49 +02:00
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
{
2018-02-08 12:13:29 +01:00
u8 battlerId = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-03-01 00:59:52 +01:00
u32 flags = T2_READ_32 ( gBattlescriptCurrInstr + 2 ) ;
const u8 * jumpPtr = T2_READ_PTR ( gBattlescriptCurrInstr + 6 ) ;
2017-09-22 21:33:49 +02:00
2018-02-08 12:13:29 +01:00
if ( gBattleMons [ battlerId ] . status2 & flags & & gBattleMons [ battlerId ] . hp )
2017-09-22 21:33:49 +02:00
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
{
2018-02-08 12:13:29 +01:00
u8 battlerId ;
2017-09-28 15:34:21 +02:00
u8 ability = gBattlescriptCurrInstr [ 2 ] ;
2018-03-01 00:59:52 +01:00
const u8 * jumpPtr = T2_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
2017-09-22 21:33:49 +02:00
2018-02-08 11:17:41 +01:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_ATTACKER_SIDE )
2017-09-22 21:33:49 +02:00
{
2018-07-01 11:15:42 +02:00
battlerId = AbilityBattleEffects ( ABILITYEFFECT_CHECK_BATTLER_SIDE , gBattlerAttacker , ability , 0 , 0 ) ;
2018-02-08 12:13:29 +01:00
if ( battlerId )
2017-09-22 21:33:49 +02:00
{
gLastUsedAbility = ability ;
gBattlescriptCurrInstr = jumpPtr ;
2018-02-08 12:13:29 +01:00
RecordAbilityBattle ( battlerId - 1 , gLastUsedAbility ) ;
gBattleScripting . battlerWithAbility = battlerId - 1 ;
2017-09-22 21:33:49 +02:00
}
else
gBattlescriptCurrInstr + = 7 ;
}
2018-02-08 11:17:41 +01:00
else if ( gBattlescriptCurrInstr [ 1 ] = = BS_NOT_ATTACKER_SIDE )
2017-09-22 21:33:49 +02:00
{
2018-02-08 12:13:29 +01:00
battlerId = AbilityBattleEffects ( ABILITYEFFECT_CHECK_OTHER_SIDE , gBattlerAttacker , ability , 0 , 0 ) ;
if ( battlerId )
2017-09-22 21:33:49 +02:00
{
gLastUsedAbility = ability ;
gBattlescriptCurrInstr = jumpPtr ;
2018-02-08 12:13:29 +01:00
RecordAbilityBattle ( battlerId - 1 , gLastUsedAbility ) ;
gBattleScripting . battlerWithAbility = battlerId - 1 ;
2017-09-22 21:33:49 +02:00
}
else
gBattlescriptCurrInstr + = 7 ;
}
else
{
2018-02-08 12:13:29 +01:00
battlerId = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
if ( gBattleMons [ battlerId ] . ability = = ability )
2017-09-22 21:33:49 +02:00
{
gLastUsedAbility = ability ;
gBattlescriptCurrInstr = jumpPtr ;
2018-02-08 12:13:29 +01:00
RecordAbilityBattle ( battlerId , gLastUsedAbility ) ;
gBattleScripting . battlerWithAbility = battlerId ;
2017-09-22 21:33:49 +02:00
}
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 ;
2018-02-08 11:17:41 +01:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_ATTACKER )
2018-02-06 23:09:39 +01:00
side = GET_BATTLER_SIDE ( gBattlerAttacker ) ;
2017-09-22 21:33:49 +02:00
else
2018-02-06 23:09:39 +01:00
side = GET_BATTLER_SIDE ( gBattlerTarget ) ;
2017-09-22 21:33:49 +02:00
2018-03-01 00:59:52 +01:00
flags = T2_READ_16 ( gBattlescriptCurrInstr + 2 ) ;
jumpPtr = T2_READ_PTR ( gBattlescriptCurrInstr + 4 ) ;
2017-09-22 21:33:49 +02:00
2018-01-16 22:12:38 +01:00
if ( gSideStatuses [ side ] & flags )
2017-09-22 21:33:49 +02:00
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 ;
2018-02-08 12:13:29 +01:00
u8 battlerId = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
u8 value = gBattleMons [ battlerId ] . 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 )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T2_READ_PTR ( gBattlescriptCurrInstr + 5 ) ;
2017-09-22 21:33:49 +02:00
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
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-03-01 00:59:52 +01:00
flags = T2_READ_32 ( gBattlescriptCurrInstr + 2 ) ;
jumpPtr = T2_READ_PTR ( gBattlescriptCurrInstr + 7 ) ;
2017-09-22 21:33:49 +02:00
2017-09-28 15:34:21 +02:00
if ( gBattlescriptCurrInstr [ 6 ] )
2017-09-22 21:33:49 +02:00
{
2018-02-06 02:46:59 +01:00
if ( ( gStatuses3 [ gActiveBattler ] & flags ) ! = 0 )
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr + = 11 ;
else
gBattlescriptCurrInstr = jumpPtr ;
}
else
{
2018-02-06 02:46:59 +01:00
if ( ( gStatuses3 [ gActiveBattler ] & flags ) ! = 0 )
2017-09-22 21:33:49 +02:00
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
{
2018-02-08 12:13:29 +01:00
u8 battlerId = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-28 15:34:21 +02:00
u8 type = gBattlescriptCurrInstr [ 2 ] ;
2018-03-01 00:59:52 +01:00
const u8 * jumpPtr = T2_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
2017-09-22 21:33:49 +02:00
2018-03-01 00:59:52 +01:00
if ( IS_BATTLER_OF_TYPE ( battlerId , type ) )
2017-09-22 21:33:49 +02:00
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 ;
2019-04-04 21:24:21 +02:00
u16 * exp = & gBattleStruct - > expValue ;
2017-09-22 21:33:49 +02:00
2018-02-08 11:17:41 +01:00
gBattlerFainted = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
sentIn = gSentPokesToOpponent [ ( gBattlerFainted & 2 ) > > 1 ] ;
2017-09-22 21:33:49 +02:00
switch ( gBattleScripting . atk23_state )
{
case 0 : // check if should receive exp at all
2018-02-08 11:17:41 +01:00
if ( GetBattlerSide ( gBattlerFainted ) ! = B_SIDE_OPPONENT | | ( gBattleTypeFlags &
2017-09-22 21:33:49 +02:00
( BATTLE_TYPE_LINK
| BATTLE_TYPE_x2000000
2018-09-20 22:00:00 +02:00
| BATTLE_TYPE_TRAINER_HILL
2017-09-22 21:33:49 +02:00
| 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 + + ;
2018-12-07 23:50:56 +01:00
gBattleStruct - > givenExpMons | = gBitTable [ gBattlerPartyIndexes [ gBattlerFainted ] ] ;
2017-09-22 21:33:49 +02:00
}
break ;
case 1 : // calculate experience points to redistribute
{
u16 calculatedExp ;
s32 viaSentIn ;
2018-11-18 20:00:36 +01:00
for ( viaSentIn = 0 , i = 0 ; i < PARTY_SIZE ; i + + )
2017-09-22 21:33:49 +02:00
{
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 + + ;
}
2018-02-08 11:17:41 +01:00
calculatedExp = gBaseStats [ gBattleMons [ gBattlerFainted ] . species ] . expYield * gBattleMons [ gBattlerFainted ] . level / 7 ;
2017-09-22 21:33:49 +02:00
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 + + ;
2018-02-07 22:53:40 +01:00
gBattleStruct - > expGetterMonId = 0 ;
2017-09-22 21:33:49 +02:00
gBattleStruct - > sentInPokes = sentIn ;
}
// fall through
case 2 : // set exp value to the poke in expgetter_id and print message
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-22 21:33:49 +02:00
{
2018-02-07 22:53:40 +01:00
item = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_HELD_ITEM ) ;
2017-09-22 21:33:49 +02:00
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
}
2018-10-17 04:47:08 +02:00
else if ( GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_LEVEL ) = = MAX_LEVEL )
2017-09-22 21:33:49 +02:00
{
* ( & 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 ( ) ;
2018-05-11 07:33:32 +02:00
PlayBGM ( MUS_KACHI2 ) ;
2017-09-22 21:33:49 +02:00
gBattleStruct - > wildVictorySong + + ;
}
2018-02-07 22:53:40 +01:00
if ( GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_HP ) )
2017-09-22 21:33:49 +02:00
{
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 ;
2018-02-07 22:53:40 +01:00
if ( IsTradedMon ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] ) )
2017-09-22 21:33:49 +02:00
{
// check if the pokemon doesn't belong to the player
2018-02-07 22:53:40 +01:00
if ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER & & gBattleStruct - > expGetterMonId > = 3 )
2017-09-22 21:33:49 +02:00
{
2018-10-16 22:34:53 +02:00
i = STRINGID_EMPTYSTRING4 ;
2017-09-22 21:33:49 +02:00
}
else
{
gBattleMoveDamage = ( gBattleMoveDamage * 150 ) / 100 ;
2018-10-16 22:34:53 +02:00
i = STRINGID_ABOOSTED ;
2017-09-22 21:33:49 +02:00
}
}
else
{
2018-10-16 22:34:53 +02:00
i = STRINGID_EMPTYSTRING4 ;
2017-09-27 23:43:45 +02:00
}
2017-09-22 21:33:49 +02:00
2018-02-08 12:13:29 +01:00
// get exp getter battlerId
2017-09-22 21:33:49 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
{
2018-02-07 22:53:40 +01:00
if ( ! ( gBattlerPartyIndexes [ 2 ] ! = gBattleStruct - > expGetterMonId ) & & ! ( gAbsentBattlerFlags & gBitTable [ 2 ] ) )
gBattleStruct - > expGetterBattlerId = 2 ;
2017-09-22 21:33:49 +02:00
else
{
2018-02-06 02:46:59 +01:00
if ( ! ( gAbsentBattlerFlags & gBitTable [ 0 ] ) )
2018-02-07 22:53:40 +01:00
gBattleStruct - > expGetterBattlerId = 0 ;
2017-09-22 21:33:49 +02:00
else
2018-02-07 22:53:40 +01:00
gBattleStruct - > expGetterBattlerId = 2 ;
2017-09-22 21:33:49 +02:00
}
}
else
2019-04-04 21:24:21 +02:00
{
2018-02-07 22:53:40 +01:00
gBattleStruct - > expGetterBattlerId = 0 ;
2019-04-04 21:24:21 +02:00
}
2017-09-22 21:33:49 +02:00
2019-04-04 21:24:21 +02:00
PREPARE_MON_NICK_WITH_PREFIX_BUFFER ( gBattleTextBuff1 , gBattleStruct - > expGetterBattlerId , gBattleStruct - > expGetterMonId ) ;
2018-12-05 15:31:01 +01:00
// buffer 'gained' or 'gained a boosted'
2019-04-04 21:24:21 +02:00
PREPARE_STRING_BUFFER ( gBattleTextBuff2 , i ) ;
PREPARE_WORD_NUMBER_BUFFER ( gBattleTextBuff3 , 5 , gBattleMoveDamage ) ;
2017-09-22 21:33:49 +02:00
2018-02-07 22:53:40 +01:00
PrepareStringBattle ( STRINGID_PKMNGAINEDEXP , gBattleStruct - > expGetterBattlerId ) ;
2018-02-08 11:17:41 +01:00
MonGainEVs ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , gBattleMons [ gBattlerFainted ] . species ) ;
2017-09-22 21:33:49 +02:00
}
gBattleStruct - > sentInPokes > > = 1 ;
gBattleScripting . atk23_state + + ;
}
}
break ;
case 3 : // Set stats and give exp
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-22 21:33:49 +02:00
{
2018-02-07 22:53:40 +01:00
gBattleBufferB [ gBattleStruct - > expGetterBattlerId ] [ 0 ] = 0 ;
2018-10-17 04:47:08 +02:00
if ( GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_HP ) & & GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_LEVEL ) ! = MAX_LEVEL )
2017-09-22 21:33:49 +02:00
{
2019-04-04 21:24:21 +02:00
gBattleResources - > beforeLvlUp - > stats [ STAT_HP ] = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_MAX_HP ) ;
gBattleResources - > beforeLvlUp - > stats [ STAT_ATK ] = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_ATK ) ;
gBattleResources - > beforeLvlUp - > stats [ STAT_DEF ] = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_DEF ) ;
gBattleResources - > beforeLvlUp - > stats [ STAT_SPEED ] = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPEED ) ;
gBattleResources - > beforeLvlUp - > stats [ STAT_SPATK ] = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPATK ) ;
gBattleResources - > beforeLvlUp - > stats [ STAT_SPDEF ] = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPDEF ) ;
2017-09-22 21:33:49 +02:00
2018-02-07 22:53:40 +01:00
gActiveBattler = gBattleStruct - > expGetterBattlerId ;
BtlController_EmitExpUpdate ( 0 , gBattleStruct - > expGetterMonId , gBattleMoveDamage ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-22 21:33:49 +02:00
}
gBattleScripting . atk23_state + + ;
}
break ;
case 4 : // lvl up if necessary
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-22 21:33:49 +02:00
{
2018-02-07 22:53:40 +01:00
gActiveBattler = gBattleStruct - > expGetterBattlerId ;
2018-07-16 20:47:30 +02:00
if ( gBattleBufferB [ gActiveBattler ] [ 0 ] = = CONTROLLER_TWORETURNVALUES & & gBattleBufferB [ gActiveBattler ] [ 1 ] = = RET_VALUE_LEVELED_UP )
2017-09-22 21:33:49 +02:00
{
2018-02-07 22:53:40 +01:00
if ( gBattleTypeFlags & BATTLE_TYPE_TRAINER & & gBattlerPartyIndexes [ gActiveBattler ] = = gBattleStruct - > expGetterMonId )
2018-02-06 20:48:02 +01:00
HandleLowHpMusicChange ( & gPlayerParty [ gBattlerPartyIndexes [ gActiveBattler ] ] , gActiveBattler ) ;
2017-09-22 21:33:49 +02:00
2019-04-04 21:24:21 +02:00
PREPARE_MON_NICK_WITH_PREFIX_BUFFER ( gBattleTextBuff1 , gActiveBattler , gBattleStruct - > expGetterMonId ) ;
PREPARE_BYTE_NUMBER_BUFFER ( gBattleTextBuff2 , 3 , GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_LEVEL ) ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2018-02-07 22:53:40 +01:00
gLeveledUpInBattle | = gBitTable [ gBattleStruct - > expGetterMonId ] ;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr = BattleScript_LevelUp ;
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = ( gBattleBufferB [ gActiveBattler ] [ 2 ] | ( gBattleBufferB [ gActiveBattler ] [ 3 ] < < 8 ) ) ;
2018-02-07 22:53:40 +01:00
AdjustFriendship ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , 0 ) ;
2017-09-22 21:33:49 +02:00
// update battle mon structure after level up
2018-02-07 22:53:40 +01:00
if ( gBattlerPartyIndexes [ 0 ] = = gBattleStruct - > expGetterMonId & & gBattleMons [ 0 ] . hp )
2017-09-22 21:33:49 +02:00
{
2018-02-07 22:53:40 +01:00
gBattleMons [ 0 ] . level = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_LEVEL ) ;
gBattleMons [ 0 ] . hp = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_HP ) ;
gBattleMons [ 0 ] . maxHP = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_MAX_HP ) ;
gBattleMons [ 0 ] . attack = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_ATK ) ;
gBattleMons [ 0 ] . defense = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_DEF ) ;
2017-09-22 21:33:49 +02:00
// Why is this duplicated?
2018-02-07 22:53:40 +01:00
gBattleMons [ 0 ] . speed = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPEED ) ;
gBattleMons [ 0 ] . speed = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPEED ) ;
2017-09-22 21:33:49 +02:00
2018-02-07 22:53:40 +01:00
gBattleMons [ 0 ] . spAttack = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPATK ) ;
gBattleMons [ 0 ] . spDefense = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPDEF ) ;
2017-09-22 21:33:49 +02:00
}
// What is else if?
2018-02-07 22:53:40 +01:00
if ( gBattlerPartyIndexes [ 2 ] = = gBattleStruct - > expGetterMonId & & gBattleMons [ 2 ] . hp & & ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE ) )
2017-09-22 21:33:49 +02:00
{
2018-02-07 22:53:40 +01:00
gBattleMons [ 2 ] . level = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_LEVEL ) ;
gBattleMons [ 2 ] . hp = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_HP ) ;
gBattleMons [ 2 ] . maxHP = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_MAX_HP ) ;
gBattleMons [ 2 ] . attack = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_ATK ) ;
gBattleMons [ 2 ] . defense = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_DEF ) ;
2017-09-22 21:33:49 +02:00
// Duplicated again, but this time there's no Sp Defense
2018-02-07 22:53:40 +01:00
gBattleMons [ 2 ] . speed = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPEED ) ;
gBattleMons [ 2 ] . speed = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPEED ) ;
2017-09-22 21:33:49 +02:00
2018-02-07 22:53:40 +01:00
gBattleMons [ 2 ] . spAttack = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPATK ) ;
2017-09-22 21:33:49 +02:00
}
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
2019-04-04 21:24:21 +02:00
{
2017-09-22 21:33:49 +02:00
gBattleScripting . atk23_state = 3 ;
2019-04-04 21:24:21 +02:00
}
2017-09-22 21:33:49 +02:00
else
{
2018-02-07 22:53:40 +01:00
gBattleStruct - > expGetterMonId + + ;
if ( gBattleStruct - > expGetterMonId < = 5 )
2017-09-22 21:33:49 +02:00
gBattleScripting . atk23_state = 2 ; // loop again
else
gBattleScripting . atk23_state = 6 ; // we're done
}
break ;
case 6 : // increment instruction
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-22 21:33:49 +02:00
{
// not sure why gf clears the item and ability here
2018-02-08 11:17:41 +01:00
gBattleMons [ gBattlerFainted ] . item = 0 ;
gBattleMons [ gBattlerFainted ] . ability = 0 ;
2017-09-22 21:33:49 +02:00
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 ;
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-09-22 21:33:49 +02:00
return ;
2018-06-30 18:55:34 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER & & gPartnerTrainerId = = TRAINER_STEVEN_PARTNER )
2017-09-22 21:33:49 +02:00
{
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
{
2018-11-18 20:00:36 +01:00
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2017-09-22 21:33:49 +02:00
{
if ( GetMonData ( & gPlayerParty [ i ] , MON_DATA_SPECIES ) & & ! GetMonData ( & gPlayerParty [ i ] , MON_DATA_IS_EGG )
2018-11-11 18:33:16 +01:00
& & ( ! ( gBattleTypeFlags & BATTLE_TYPE_ARENA ) | | ! ( gBattleStruct - > arenaLostPlayerMons & gBitTable [ i ] ) ) )
2017-09-22 21:33:49 +02:00
{
HP_count + = GetMonData ( & gPlayerParty [ i ] , MON_DATA_HP ) ;
}
}
}
if ( HP_count = = 0 )
2018-01-16 22:12:38 +01:00
gBattleOutcome | = B_OUTCOME_LOST ;
2017-09-22 21:33:49 +02:00
2018-11-18 20:00:36 +01:00
for ( HP_count = 0 , i = 0 ; i < PARTY_SIZE ; i + + )
2017-09-22 21:33:49 +02:00
{
if ( GetMonData ( & gEnemyParty [ i ] , MON_DATA_SPECIES ) & & ! GetMonData ( & gEnemyParty [ i ] , MON_DATA_IS_EGG )
2018-11-11 18:33:16 +01:00
& & ( ! ( gBattleTypeFlags & BATTLE_TYPE_ARENA ) | | ! ( gBattleStruct - > arenaLostOpponentMons & gBitTable [ i ] ) ) )
2017-09-22 21:33:49 +02:00
{
HP_count + = GetMonData ( & gEnemyParty [ i ] , MON_DATA_HP ) ;
}
}
if ( HP_count = = 0 )
2018-01-16 22:12:38 +01:00
gBattleOutcome | = B_OUTCOME_WON ;
2017-09-22 21:33:49 +02:00
if ( gBattleOutcome = = 0 & & ( gBattleTypeFlags & ( BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000 ) ) )
{
s32 foundPlayer ;
s32 foundOpponent ;
// Impossible to decompile loops.
2018-02-06 02:46:59 +01:00
for ( foundPlayer = 0 , i = 0 ; i < gBattlersCount ; i + = 2 )
2017-09-22 21:33:49 +02:00
{
if ( HITMARKER_UNK ( i ) & gHitMarker & & ! gSpecialStatuses [ i ] . flag40 )
foundPlayer + + ;
}
2018-02-06 02:46:59 +01:00
for ( foundOpponent = 0 , i = 1 ; i < gBattlersCount ; i + = 2 )
2017-09-22 21:33:49 +02:00
{
if ( HITMARKER_UNK ( i ) & gHitMarker & & ! gSpecialStatuses [ i ] . flag40 )
foundOpponent + + ;
}
if ( gBattleTypeFlags & BATTLE_TYPE_MULTI )
{
if ( foundOpponent + foundPlayer > 1 )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T2_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-22 21:33:49 +02:00
else
gBattlescriptCurrInstr + = 5 ;
}
else
{
if ( foundOpponent ! = 0 & & foundPlayer ! = 0 )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T2_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-22 21:33:49 +02:00
else
gBattlescriptCurrInstr + = 5 ;
}
}
else
{
gBattlescriptCurrInstr + = 5 ;
}
}
# else
2018-05-12 00:24:32 +02:00
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 \
2018-02-06 20:48:02 +01:00
ldr r0 , = gBattleControllerExecFlags \ n \
2017-09-22 21:33:49 +02:00
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 \
2018-02-06 02:46:59 +01:00
ldr r0 , = gBattlersCount \ n \
2017-09-22 21:33:49 +02:00
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
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags = 0 ;
2017-09-22 21:33:49 +02:00
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
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T2_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-22 21:33:49 +02:00
}
2017-09-28 15:34:21 +02:00
static void atk28_goto ( void )
2017-09-22 21:33:49 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T2_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-22 21:33:49 +02:00
}
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 ] ;
2018-03-01 00:59:52 +01:00
const u8 * memByte = T2_READ_PTR ( gBattlescriptCurrInstr + 2 ) ;
2017-09-28 15:34:21 +02:00
u8 value = gBattlescriptCurrInstr [ 6 ] ;
2018-03-01 00:59:52 +01:00
const u8 * jumpPtr = T2_READ_PTR ( gBattlescriptCurrInstr + 7 ) ;
2017-09-22 21:33:49 +02:00
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 ] ;
2018-03-01 00:59:52 +01:00
const u16 * memHword = T2_READ_PTR ( gBattlescriptCurrInstr + 2 ) ;
u16 value = T2_READ_16 ( gBattlescriptCurrInstr + 6 ) ;
const u8 * jumpPtr = T2_READ_PTR ( gBattlescriptCurrInstr + 8 ) ;
2017-09-22 21:33:49 +02:00
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 ] ;
2018-03-01 00:59:52 +01:00
const u32 * memWord = T2_READ_PTR ( gBattlescriptCurrInstr + 2 ) ;
u32 value = T1_READ_32 ( gBattlescriptCurrInstr + 6 ) ;
const u8 * jumpPtr = T2_READ_PTR ( gBattlescriptCurrInstr + 10 ) ;
2017-09-22 21:33:49 +02:00
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
{
2018-03-01 00:59:52 +01:00
const u8 * mem1 = T2_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
const u8 * mem2 = T2_READ_PTR ( gBattlescriptCurrInstr + 5 ) ;
2017-09-28 15:34:21 +02:00
u32 size = gBattlescriptCurrInstr [ 9 ] ;
2018-03-01 00:59:52 +01:00
const u8 * jumpPtr = T2_READ_PTR ( gBattlescriptCurrInstr + 10 ) ;
2017-09-22 21:33:49 +02:00
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 ;
2018-03-01 00:59:52 +01:00
const u8 * mem1 = T2_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
const u8 * mem2 = T2_READ_PTR ( gBattlescriptCurrInstr + 5 ) ;
2017-09-28 15:34:21 +02:00
u32 size = gBattlescriptCurrInstr [ 9 ] ;
2018-03-01 00:59:52 +01:00
const u8 * jumpPtr = T2_READ_PTR ( gBattlescriptCurrInstr + 10 ) ;
2017-09-22 21:33:49 +02:00
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
{
2018-03-01 00:59:52 +01:00
u8 * memByte = T2_READ_PTR ( 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
{
2018-03-01 00:59:52 +01:00
u8 * memByte = T2_READ_PTR ( 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
{
2018-03-01 00:59:52 +01:00
u8 * memByte = T2_READ_PTR ( 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
{
2018-03-01 00:59:52 +01:00
u8 * dest = T2_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
const u8 * src = T2_READ_PTR ( 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
{
2018-03-01 00:59:52 +01:00
u8 * dest = T2_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
const u8 * src = T2_READ_PTR ( gBattlescriptCurrInstr + 5 ) ;
const u8 * index = T2_READ_PTR ( 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
{
2018-03-01 00:59:52 +01:00
u8 * memByte = T2_READ_PTR ( 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
{
2018-03-01 00:59:52 +01:00
u16 * memHword = T2_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
u16 val = T2_READ_16 ( gBattlescriptCurrInstr + 5 ) ;
2017-09-22 21:33:49 +02:00
* 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
{
2018-03-01 00:59:52 +01:00
u32 * memWord = T2_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
u32 val = T2_READ_32 ( gBattlescriptCurrInstr + 5 ) ;
2017-09-22 21:33:49 +02:00
* 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
{
2018-03-01 00:59:52 +01:00
u8 * memByte = T2_READ_PTR ( 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
{
2018-03-01 00:59:52 +01:00
u16 * memHword = T2_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
u16 val = T2_READ_16 ( gBattlescriptCurrInstr + 5 ) ;
2017-09-22 21:33:49 +02:00
* 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
{
2018-03-01 00:59:52 +01:00
u32 * memWord = T2_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
u32 val = T2_READ_32 ( gBattlescriptCurrInstr + 5 ) ;
2017-09-22 21:33:49 +02:00
* 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
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-22 21:33:49 +02:00
{
2018-03-01 00:59:52 +01:00
u16 value = T2_READ_16 ( gBattlescriptCurrInstr + 1 ) ;
2017-09-22 21:33:49 +02:00
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
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk3B_healthbar_update ( void )
2017-09-22 21:33:49 +02:00
{
2018-02-08 11:17:41 +01:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_TARGET )
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget ;
2017-09-22 21:33:49 +02:00
else
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2017-09-22 21:33:49 +02:00
2018-02-06 20:48:02 +01:00
BtlController_EmitHealthBarUpdate ( 0 , gBattleMoveDamage ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-22 21:33:49 +02:00
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 )
2018-11-11 18:33:16 +01:00
BattleArena_AddSkillPoints ( gBattlerAttacker ) ;
2017-09-22 21:33:49 +02:00
2018-01-16 22:12:38 +01:00
gMoveResultFlags = 0 ;
2018-02-06 02:46:59 +01:00
gActiveBattler = 0 ;
2019-02-02 11:32:00 +01:00
gCurrentActionFuncId = B_ACTION_TRY_FINISH ;
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
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 0 ;
2019-02-02 11:32:00 +01:00
gCurrentActionFuncId = B_ACTION_TRY_FINISH ;
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 ( ) ;
2018-02-06 23:09:39 +01:00
if ( gBattleResources - > battleCallbackStack - > size ! = 0 )
gBattleResources - > battleCallbackStack - > size - - ;
gBattleMainFunc = gBattleResources - > battleCallbackStack - > function [ gBattleResources - > battleCallbackStack - > size ] ;
2017-09-22 21:33:49 +02:00
}
2017-09-28 15:34:21 +02:00
static void atk41_call ( void )
2017-09-22 21:33:49 +02:00
{
BattleScriptPush ( gBattlescriptCurrInstr + 5 ) ;
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-22 21:33:49 +02:00
}
2017-09-28 15:34:21 +02:00
static void atk42_jumpiftype2 ( void )
2017-09-22 21:33:49 +02:00
{
2018-02-08 12:13:29 +01:00
u8 battlerId = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-22 21:33:49 +02:00
2018-02-08 12:13:29 +01:00
if ( gBattlescriptCurrInstr [ 2 ] = = gBattleMons [ battlerId ] . type1 | | gBattlescriptCurrInstr [ 2 ] = = gBattleMons [ battlerId ] . type2 )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
2017-09-22 21:33:49 +02:00
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 ) )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 2 ) ;
2017-09-22 21:33:49 +02:00
else
gBattlescriptCurrInstr + = 6 ;
}
2017-11-25 18:42:31 +01:00
static void atk44_endselectionscript ( void )
2017-09-22 21:33:49 +02:00
{
2018-02-06 23:09:39 +01:00
* ( gBattlerAttacker + 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 ;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-03-01 00:59:52 +01:00
argumentPtr = T2_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
2017-09-22 21:33:49 +02:00
if ( gBattlescriptCurrInstr [ 2 ] = = B_ANIM_STATS_CHANGE
| | gBattlescriptCurrInstr [ 2 ] = = B_ANIM_SNATCH_MOVE
| | gBattlescriptCurrInstr [ 2 ] = = B_ANIM_SUBSTITUTE_FADE )
{
2018-02-06 20:48:02 +01:00
BtlController_EmitBattleAnimation ( 0 , gBattlescriptCurrInstr [ 2 ] , * argumentPtr ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-22 21:33:49 +02:00
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 )
{
2018-02-06 20:48:02 +01:00
BtlController_EmitBattleAnimation ( 0 , gBattlescriptCurrInstr [ 2 ] , * argumentPtr ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr + = 7 ;
}
2018-02-06 02:46:59 +01:00
else if ( gStatuses3 [ gActiveBattler ] & STATUS3_SEMI_INVULNERABLE )
2017-09-22 21:33:49 +02:00
{
gBattlescriptCurrInstr + = 7 ;
}
else
{
2018-02-06 20:48:02 +01:00
BtlController_EmitBattleAnimation ( 0 , gBattlescriptCurrInstr [ 2 ] , * argumentPtr ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-22 21:33:49 +02:00
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 ;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-03-01 00:59:52 +01:00
animationIdPtr = T2_READ_PTR ( gBattlescriptCurrInstr + 2 ) ;
argumentPtr = T2_READ_PTR ( gBattlescriptCurrInstr + 6 ) ;
2017-09-22 21:33:49 +02:00
if ( * animationIdPtr = = B_ANIM_STATS_CHANGE
| | * animationIdPtr = = B_ANIM_SNATCH_MOVE
| | * animationIdPtr = = B_ANIM_SUBSTITUTE_FADE )
{
2018-02-06 20:48:02 +01:00
BtlController_EmitBattleAnimation ( 0 , * animationIdPtr , * argumentPtr ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-22 21:33:49 +02:00
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 )
{
2018-02-06 20:48:02 +01:00
BtlController_EmitBattleAnimation ( 0 , * animationIdPtr , * argumentPtr ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr + = 10 ;
}
2018-02-06 02:46:59 +01:00
else if ( gStatuses3 [ gActiveBattler ] & STATUS3_SEMI_INVULNERABLE )
2017-09-22 21:33:49 +02:00
{
gBattlescriptCurrInstr + = 10 ;
}
else
{
2018-02-06 20:48:02 +01:00
BtlController_EmitBattleAnimation ( 0 , * animationIdPtr , * argumentPtr ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-22 21:33:49 +02:00
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 ;
2018-07-29 15:51:08 +02:00
switch ( GET_STAT_BUFF_VALUE2 ( gBattleScripting . statChanger ) )
2017-09-22 21:33:49 +02:00
{
2018-07-29 15:51:08 +02:00
case SET_STAT_BUFF_VALUE ( 1 ) : // +1
2018-10-07 15:39:46 +02:00
value = STAT_ANIM_PLUS1 ;
2017-09-22 21:33:49 +02:00
break ;
2018-07-29 15:51:08 +02:00
case SET_STAT_BUFF_VALUE ( 2 ) : // +2
2018-10-07 15:39:46 +02:00
value = STAT_ANIM_PLUS2 ;
2017-09-22 21:33:49 +02:00
break ;
2018-07-29 15:51:08 +02:00
case SET_STAT_BUFF_VALUE ( 1 ) | STAT_BUFF_NEGATIVE : // -1
2018-10-07 15:39:46 +02:00
value = STAT_ANIM_MINUS1 ;
2017-09-22 21:33:49 +02:00
break ;
2018-07-29 15:51:08 +02:00
case SET_STAT_BUFF_VALUE ( 2 ) | STAT_BUFF_NEGATIVE : // -2
2018-10-07 15:39:46 +02:00
value = STAT_ANIM_MINUS2 ;
2017-09-22 21:33:49 +02:00
break ;
}
2018-07-29 15:51:08 +02:00
gBattleScripting . animArg1 = GET_STAT_BUFF_ID ( gBattleScripting . statChanger ) + value - 1 ;
2017-09-22 21:33:49 +02:00
gBattleScripting . animArg2 = 0 ;
gBattlescriptCurrInstr + + ;
}
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 ;
2018-02-28 19:37:48 +01:00
u16 statAnimId = 0 ;
s32 changeableStatsCount = 0 ;
u8 statsToCheck = 0 ;
2017-09-22 21:33:49 +02:00
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-23 00:06:52 +02:00
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
{
2018-02-28 19:37:48 +01:00
s16 startingStatAnimId ;
if ( gBattlescriptCurrInstr [ 3 ] & ATK48_STAT_BY_TWO )
2018-10-07 15:39:46 +02:00
startingStatAnimId = STAT_ANIM_MINUS2 - 1 ;
2018-02-28 19:37:48 +01:00
else
2018-10-07 15:39:46 +02:00
startingStatAnimId = STAT_ANIM_MINUS1 - 1 ;
2018-02-28 19:37:48 +01:00
2017-09-23 00:06:52 +02:00
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
{
2018-02-28 19:37:48 +01:00
if ( gBattlescriptCurrInstr [ 3 ] & ATK48_DONT_CHECK_LOWER )
2017-09-22 21:33:49 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . statStages [ currStat ] > 0 )
2017-09-23 00:06:52 +02:00
{
2018-02-28 19:37:48 +01:00
statAnimId = startingStatAnimId + currStat ;
changeableStatsCount + + ;
2017-09-23 00:06:52 +02:00
}
2017-09-22 21:33:49 +02:00
}
2018-02-06 02:46:59 +01:00
else if ( ! gSideTimers [ GET_BATTLER_SIDE ( gActiveBattler ) ] . mistTimer
& & gBattleMons [ gActiveBattler ] . ability ! = ABILITY_CLEAR_BODY
& & gBattleMons [ gActiveBattler ] . ability ! = ABILITY_WHITE_SMOKE
2018-02-08 12:13:29 +01:00
& & ! ( gBattleMons [ gActiveBattler ] . ability = = ABILITY_KEEN_EYE & & currStat = = STAT_ACC )
& & ! ( gBattleMons [ gActiveBattler ] . ability = = ABILITY_HYPER_CUTTER & & currStat = = STAT_ATK ) )
2017-09-22 21:33:49 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . statStages [ currStat ] > 0 )
2017-09-23 00:06:52 +02:00
{
2018-02-28 19:37:48 +01:00
statAnimId = startingStatAnimId + currStat ;
changeableStatsCount + + ;
2017-09-23 00:06:52 +02:00
}
2017-09-22 21:33:49 +02:00
}
}
2018-02-28 19:37:48 +01:00
statsToCheck > > = 1 , currStat + + ;
2017-09-22 21:33:49 +02:00
}
2018-02-28 19:37:48 +01:00
if ( changeableStatsCount > 1 ) // more than one stat, so the color is gray
2017-09-22 21:33:49 +02:00
{
2017-09-23 00:06:52 +02:00
if ( gBattlescriptCurrInstr [ 3 ] & ATK48_STAT_BY_TWO )
2018-10-07 15:39:46 +02:00
statAnimId = STAT_ANIM_MULTIPLE_MINUS2 ;
2017-09-22 21:33:49 +02:00
else
2018-10-07 15:39:46 +02:00
statAnimId = STAT_ANIM_MULTIPLE_MINUS1 ;
2017-09-22 21:33:49 +02:00
}
}
else // goes up
{
2018-02-28 19:37:48 +01:00
s16 startingStatAnimId ;
if ( gBattlescriptCurrInstr [ 3 ] & ATK48_STAT_BY_TWO )
2018-10-07 15:39:46 +02:00
startingStatAnimId = STAT_ANIM_PLUS2 - 1 ;
2018-02-28 19:37:48 +01:00
else
2018-10-07 15:39:46 +02:00
startingStatAnimId = STAT_ANIM_PLUS1 - 1 ;
2018-02-28 19:37:48 +01:00
2017-09-23 00:06:52 +02:00
while ( statsToCheck ! = 0 )
2017-09-22 21:33:49 +02:00
{
2018-02-06 02:46:59 +01:00
if ( statsToCheck & 1 & & gBattleMons [ gActiveBattler ] . statStages [ currStat ] < 0xC )
2017-09-22 21:33:49 +02:00
{
2018-02-28 19:37:48 +01:00
statAnimId = startingStatAnimId + currStat ;
changeableStatsCount + + ;
2017-09-22 21:33:49 +02:00
}
2018-02-28 19:37:48 +01:00
statsToCheck > > = 1 , currStat + + ;
2017-09-22 21:33:49 +02:00
}
2018-02-28 19:37:48 +01:00
if ( changeableStatsCount > 1 ) // more than one stat, so the color is gray
2017-09-22 21:33:49 +02:00
{
2017-09-23 00:06:52 +02:00
if ( gBattlescriptCurrInstr [ 3 ] & ATK48_STAT_BY_TWO )
2018-10-07 15:39:46 +02:00
statAnimId = STAT_ANIM_MULTIPLE_PLUS2 ;
2017-09-22 21:33:49 +02:00
else
2018-10-07 15:39:46 +02:00
statAnimId = STAT_ANIM_MULTIPLE_PLUS1 ;
2017-09-22 21:33:49 +02:00
}
}
2018-07-29 15:33:16 +02:00
if ( gBattlescriptCurrInstr [ 3 ] & ATK48_ONLY_MULTIPLE & & changeableStatsCount < 2 )
2017-09-22 21:33:49 +02:00
{
gBattlescriptCurrInstr + = 4 ;
}
2018-07-29 15:33:16 +02:00
else if ( changeableStatsCount ! = 0 & & ! gBattleScripting . statAnimPlayed )
2017-09-22 21:33:49 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitBattleAnimation ( 0 , B_ANIM_STATS_CHANGE , statAnimId ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2018-07-29 15:33:16 +02:00
if ( gBattlescriptCurrInstr [ 3 ] & ATK48_ONLY_MULTIPLE & & changeableStatsCount > 1 )
gBattleScripting . statAnimPlayed = TRUE ;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr + = 4 ;
}
else
{
gBattlescriptCurrInstr + = 4 ;
}
}
2017-09-23 20:13:45 +02:00
2017-09-28 15:34:21 +02:00
static void atk49_moveend ( void )
2017-09-23 20:13:45 +02:00
{
s32 i ;
2018-09-01 20:00:13 +02:00
bool32 effect = FALSE ;
u8 moveType = 0 ;
u8 holdEffectAtk = 0 ;
u16 * choicedMoveAtk = NULL ;
2017-09-23 20:13:45 +02:00
u8 arg1 , arg2 ;
2017-11-26 14:17:02 +01:00
u16 originallyUsedMove ;
2017-09-23 20:13:45 +02:00
2018-12-05 15:31:01 +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 ] ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . item = = ITEM_ENIGMA_BERRY )
holdEffectAtk = gEnigmaBerries [ gBattlerAttacker ] . holdEffect ;
2017-09-23 20:13:45 +02:00
else
2018-02-06 23:09:39 +01:00
holdEffectAtk = ItemId_GetHoldEffect ( gBattleMons [ gBattlerAttacker ] . item ) ;
2017-09-23 20:13:45 +02:00
2018-02-06 23:09:39 +01:00
choicedMoveAtk = & gBattleStruct - > choicedMove [ gBattlerAttacker ] ;
2017-09-23 20:13:45 +02:00
GET_MOVE_TYPE ( gCurrentMove , moveType ) ;
do
{
switch ( gBattleScripting . atk49_state )
{
2018-09-01 20:00:13 +02:00
case ATK49_RAGE : // rage check
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_RAGE
& & gBattleMons [ gBattlerTarget ] . hp ! = 0 & & gBattlerAttacker ! = gBattlerTarget
& & GetBattlerSide ( gBattlerAttacker ) ! = GetBattlerSide ( gBattlerTarget )
2018-01-16 22:12:38 +01:00
& & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) & & TARGET_TURN_DAMAGED
2018-02-08 12:13:29 +01:00
& & gBattleMoves [ gCurrentMove ] . power & & gBattleMons [ gBattlerTarget ] . statStages [ STAT_ATK ] < = 0xB )
2017-09-23 20:13:45 +02:00
{
2018-02-08 12:13:29 +01:00
gBattleMons [ gBattlerTarget ] . statStages [ STAT_ATK ] + + ;
2017-09-23 20:13:45 +02:00
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_RageIsBuilding ;
effect = TRUE ;
}
gBattleScripting . atk49_state + + ;
break ;
2018-09-01 20:00:13 +02:00
case ATK49_DEFROST : // defrosting check
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status1 & STATUS1_FREEZE
& & gBattleMons [ gBattlerTarget ] . hp ! = 0 & & gBattlerAttacker ! = gBattlerTarget
2018-02-07 22:53:40 +01:00
& & gSpecialStatuses [ gBattlerTarget ] . specialDmg
2018-01-16 22:12:38 +01:00
& & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) & & moveType = = TYPE_FIRE )
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerTarget ] . status1 & = ~ ( STATUS1_FREEZE ) ;
gActiveBattler = gBattlerTarget ;
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gBattlerTarget ] . status1 ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-23 20:13:45 +02:00
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_DefrostedViaFireMove ;
effect = TRUE ;
}
gBattleScripting . atk49_state + + ;
break ;
2018-09-01 20:00:13 +02:00
case ATK49_SYNCHRONIZE_TARGET : // target synchronize
2018-02-06 23:09:39 +01:00
if ( AbilityBattleEffects ( ABILITYEFFECT_SYNCHRONIZE , gBattlerTarget , 0 , 0 , 0 ) )
2017-09-23 20:13:45 +02:00
effect = TRUE ;
gBattleScripting . atk49_state + + ;
break ;
2018-09-01 20:00:13 +02:00
case ATK49_MOVE_END_ABILITIES : // Such as abilities activating on contact(Poison Spore, Rough Skin, etc.).
if ( AbilityBattleEffects ( ABILITYEFFECT_MOVE_END , gBattlerTarget , 0 , 0 , 0 ) )
2017-09-23 20:13:45 +02:00
effect = TRUE ;
gBattleScripting . atk49_state + + ;
break ;
2018-09-01 20:00:13 +02:00
case ATK49_STATUS_IMMUNITY_ABILITIES : // status immunities
2017-09-23 20:13:45 +02:00
if ( AbilityBattleEffects ( ABILITYEFFECT_IMMUNITY , 0 , 0 , 0 , 0 ) )
2018-02-08 12:13:29 +01:00
effect = TRUE ; // it loops through all battlers, so we increment after its done with all battlers
2017-09-23 20:13:45 +02:00
else
gBattleScripting . atk49_state + + ;
break ;
2018-09-01 20:00:13 +02:00
case ATK49_SYNCHRONIZE_ATTACKER : // attacker synchronize
2018-02-06 23:09:39 +01:00
if ( AbilityBattleEffects ( ABILITYEFFECT_ATK_SYNCHRONIZE , gBattlerAttacker , 0 , 0 , 0 ) )
2017-09-23 20:13:45 +02:00
effect = TRUE ;
gBattleScripting . atk49_state + + ;
break ;
2018-09-01 20:00:13 +02:00
case ATK49_CHOICE_MOVE : // update choice band move
2017-09-23 20:13:45 +02:00
if ( ! ( gHitMarker & HITMARKER_OBEYS ) | | holdEffectAtk ! = HOLD_EFFECT_CHOICE_BAND
2018-12-05 15:31:01 +01:00
| | gChosenMove = = MOVE_STRUGGLE | | ( * choicedMoveAtk ! = 0 & & * choicedMoveAtk ! = 0xFFFF ) )
2017-09-23 20:13:45 +02:00
goto LOOP ;
2018-01-16 22:12:38 +01:00
if ( gChosenMove = = MOVE_BATON_PASS & & ! ( gMoveResultFlags & MOVE_RESULT_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 :
{
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-23 20:13:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . moves [ i ] = = * choicedMoveAtk )
2017-09-23 20:13:45 +02:00
break ;
}
2018-12-25 18:50:15 +01:00
if ( i = = MAX_MON_MOVES )
2017-09-23 20:13:45 +02:00
* choicedMoveAtk = 0 ;
gBattleScripting . atk49_state + + ;
}
break ;
2018-09-01 20:00:13 +02:00
case ATK49_CHANGED_ITEMS : // changed held items
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-23 20:13:45 +02:00
{
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 ;
2018-09-01 20:00:13 +02:00
case ATK49_ITEM_EFFECTS_ALL : // item effects for all battlers
if ( ItemBattleEffects ( ITEMEFFECT_MOVE_END , 0 , FALSE ) )
2017-09-23 20:13:45 +02:00
effect = TRUE ;
else
gBattleScripting . atk49_state + + ;
break ;
2018-09-01 20:00:13 +02:00
case ATK49_KINGSROCK_SHELLBELL : // king's rock and shell bell
if ( ItemBattleEffects ( ITEMEFFECT_KINGSROCK_SHELLBELL , 0 , FALSE ) )
2017-09-23 20:13:45 +02:00
effect = TRUE ;
gBattleScripting . atk49_state + + ;
break ;
2018-09-01 20:00:13 +02:00
case ATK49_ATTACKER_INVISIBLE : // make attacker sprite invisible
2018-02-06 23:09:39 +01:00
if ( gStatuses3 [ gBattlerAttacker ] & ( STATUS3_SEMI_INVULNERABLE )
2017-09-23 20:13:45 +02:00
& & gHitMarker & HITMARKER_NO_ANIMATIONS )
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSpriteInvisibility ( 0 , TRUE ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-23 20:13:45 +02:00
gBattleScripting . atk49_state + + ;
return ;
}
gBattleScripting . atk49_state + + ;
break ;
2018-09-01 20:00:13 +02:00
case ATK49_ATTACKER_VISIBLE : // make attacker sprite visible
2018-01-16 22:12:38 +01:00
if ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT
2018-02-06 23:09:39 +01:00
| | ! ( gStatuses3 [ gBattlerAttacker ] & ( STATUS3_SEMI_INVULNERABLE ) )
| | WasUnableToUseMove ( gBattlerAttacker ) )
2018-02-06 20:48:02 +01:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSpriteInvisibility ( 0 , FALSE ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] & = ~ ( STATUS3_SEMI_INVULNERABLE ) ;
2018-07-16 20:47:30 +02:00
gSpecialStatuses [ gBattlerAttacker ] . restoredBattlerSprite = 1 ;
2017-09-23 20:13:45 +02:00
gBattleScripting . atk49_state + + ;
return ;
}
gBattleScripting . atk49_state + + ;
break ;
2018-09-01 20:00:13 +02:00
case ATK49_TARGET_VISIBLE : // make target sprite visible
2018-07-16 20:47:30 +02:00
if ( ! gSpecialStatuses [ gBattlerTarget ] . restoredBattlerSprite & & gBattlerTarget < gBattlersCount
2018-02-06 23:09:39 +01:00
& & ! ( gStatuses3 [ gBattlerTarget ] & STATUS3_SEMI_INVULNERABLE ) )
2017-09-23 20:13:45 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSpriteInvisibility ( 0 , FALSE ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerTarget ] & = ~ ( STATUS3_SEMI_INVULNERABLE ) ;
2017-09-23 20:13:45 +02:00
gBattleScripting . atk49_state + + ;
return ;
}
gBattleScripting . atk49_state + + ;
break ;
2018-09-01 20:00:13 +02:00
case ATK49_SUBSTITUTE : // update substitute
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-23 20:13:45 +02:00
{
if ( gDisableStructs [ i ] . substituteHP = = 0 )
gBattleMons [ i ] . status2 & = ~ ( STATUS2_SUBSTITUTE ) ;
}
gBattleScripting . atk49_state + + ;
break ;
2018-09-01 20:00:13 +02:00
case ATK49_UPDATE_LAST_MOVES :
2018-06-30 14:12:17 +02:00
if ( gHitMarker & HITMARKER_SWAP_ATTACKER_TARGET )
2017-09-23 20:13:45 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
gBattlerAttacker = gBattlerTarget ;
gBattlerTarget = gActiveBattler ;
2018-06-30 14:12:17 +02:00
gHitMarker & = ~ ( HITMARKER_SWAP_ATTACKER_TARGET ) ;
2017-09-23 20:13:45 +02:00
}
if ( gHitMarker & HITMARKER_ATTACKSTRING_PRINTED )
{
2018-02-06 23:09:39 +01:00
gLastPrintedMoves [ gBattlerAttacker ] = gChosenMove ;
2017-09-23 20:13:45 +02:00
}
2018-02-06 23:09:39 +01:00
if ( ! ( gAbsentBattlerFlags & gBitTable [ gBattlerAttacker ] )
& & ! ( gBattleStruct - > field_91 & gBitTable [ gBattlerAttacker ] )
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 )
{
2018-02-06 23:09:39 +01:00
gLastMoves [ gBattlerAttacker ] = gChosenMove ;
gLastResultingMoves [ gBattlerAttacker ] = gCurrentMove ;
2017-09-23 20:13:45 +02:00
}
else
{
2018-12-05 15:31:01 +01:00
gLastMoves [ gBattlerAttacker ] = 0xFFFF ;
gLastResultingMoves [ gBattlerAttacker ] = 0xFFFF ;
2017-09-23 20:13:45 +02:00
}
2018-02-06 23:09:39 +01:00
if ( ! ( gHitMarker & HITMARKER_FAINTED ( gBattlerTarget ) ) )
gLastHitBy [ gBattlerTarget ] = gBattlerAttacker ;
2017-09-23 20:13:45 +02:00
2018-01-16 22:12:38 +01:00
if ( gHitMarker & HITMARKER_OBEYS & & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
2017-09-23 20:13:45 +02:00
{
2018-12-05 15:31:01 +01:00
if ( gChosenMove = = 0xFFFF )
2017-09-23 20:13:45 +02:00
{
2018-02-06 23:09:39 +01:00
gLastLandedMoves [ gBattlerTarget ] = gChosenMove ;
2017-09-23 20:13:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gLastLandedMoves [ gBattlerTarget ] = gCurrentMove ;
GET_MOVE_TYPE ( gCurrentMove , gLastHitByType [ gBattlerTarget ] ) ;
2017-09-23 20:13:45 +02:00
}
}
else
{
2018-12-05 15:31:01 +01:00
gLastLandedMoves [ gBattlerTarget ] = 0xFFFF ;
2017-09-23 20:13:45 +02:00
}
}
gBattleScripting . atk49_state + + ;
break ;
2018-09-01 20:00:13 +02:00
case ATK49_MIRROR_MOVE : // mirror move
2018-02-06 23:09:39 +01:00
if ( ! ( gAbsentBattlerFlags & gBitTable [ gBattlerAttacker ] ) & & ! ( gBattleStruct - > field_91 & gBitTable [ gBattlerAttacker ] )
2017-11-26 14:17:02 +01:00
& & gBattleMoves [ originallyUsedMove ] . flags & FLAG_MIRROR_MOVE_AFFECTED & & gHitMarker & HITMARKER_OBEYS
2018-02-06 23:09:39 +01:00
& & gBattlerAttacker ! = gBattlerTarget & & ! ( gHitMarker & HITMARKER_FAINTED ( gBattlerTarget ) )
2018-01-16 22:12:38 +01:00
& & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
2017-09-23 20:13:45 +02:00
{
u8 target , attacker ;
2018-10-14 18:10:54 +02:00
* ( gBattleStruct - > lastTakenMove + gBattlerTarget * 2 + 0 ) = gChosenMove ;
* ( gBattleStruct - > lastTakenMove + gBattlerTarget * 2 + 1 ) = gChosenMove > > 8 ;
2017-09-23 20:13:45 +02:00
2018-02-06 23:09:39 +01:00
target = gBattlerTarget ;
attacker = gBattlerAttacker ;
2018-10-14 18:10:54 +02:00
* ( attacker * 2 + target * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 0 ) = gChosenMove ;
2017-09-23 20:13:45 +02:00
2018-02-06 23:09:39 +01:00
target = gBattlerTarget ;
attacker = gBattlerAttacker ;
2018-10-14 18:10:54 +02:00
* ( attacker * 2 + target * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 1 ) = gChosenMove > > 8 ;
2017-09-23 20:13:45 +02:00
}
gBattleScripting . atk49_state + + ;
break ;
2018-09-01 20:00:13 +02:00
case ATK49_NEXT_TARGET : // For moves hitting two opposing Pokemon.
2017-09-23 20:13:45 +02:00
if ( ! ( gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE ) & & gBattleTypeFlags & BATTLE_TYPE_DOUBLE
2018-02-06 23:09:39 +01:00
& & ! gProtectStructs [ gBattlerAttacker ] . chargingTurn & & gBattleMoves [ gCurrentMove ] . target = = MOVE_TARGET_BOTH
2017-09-23 20:13:45 +02:00
& & ! ( gHitMarker & HITMARKER_NO_ATTACKSTRING ) )
{
2018-02-08 12:13:29 +01:00
u8 battlerId = GetBattlerAtPosition ( BATTLE_PARTNER ( GetBattlerPosition ( gBattlerTarget ) ) ) ;
if ( gBattleMons [ battlerId ] . hp ! = 0 )
2017-09-23 20:13:45 +02:00
{
2018-02-08 12:13:29 +01:00
gBattlerTarget = battlerId ;
2017-09-23 20:13:45 +02:00
gHitMarker | = HITMARKER_NO_ATTACKSTRING ;
gBattleScripting . atk49_state = 0 ;
MoveValuesCleanUp ( ) ;
BattleScriptPush ( gBattleScriptsForMoveEffects [ gBattleMoves [ gCurrentMove ] . effect ] ) ;
2018-09-01 20:00:13 +02:00
gBattlescriptCurrInstr = BattleScript_FlushMessageBox ;
2017-09-23 20:13:45 +02:00
return ;
}
else
{
gHitMarker | = HITMARKER_NO_ATTACKSTRING ;
}
}
gBattleScripting . atk49_state + + ;
break ;
2018-09-01 20:00:13 +02:00
case ATK49_COUNT :
2017-09-23 20:13:45 +02:00
break ;
}
if ( arg1 = = 1 & & effect = = FALSE )
2018-09-01 20:00:13 +02:00
gBattleScripting . atk49_state = ATK49_COUNT ;
2017-09-23 20:13:45 +02:00
if ( arg1 = = 2 & & arg2 = = gBattleScripting . atk49_state )
2018-09-01 20:00:13 +02:00
gBattleScripting . atk49_state = ATK49_COUNT ;
2017-09-23 20:13:45 +02:00
2018-09-01 20:00:13 +02:00
} while ( gBattleScripting . atk49_state ! = ATK49_COUNT & & effect = = FALSE ) ;
2017-09-23 20:13:45 +02:00
2018-09-01 20:00:13 +02:00
if ( gBattleScripting . atk49_state = = ATK49_COUNT & & effect = = FALSE )
2017-09-23 20:13:45 +02:00
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 ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . ability = = ABILITY_LEVITATE & & moveType = = TYPE_GROUND )
2017-09-24 00:29:52 +02:00
{
2018-02-06 23:09:39 +01:00
gLastUsedAbility = gBattleMons [ gBattlerTarget ] . ability ;
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = ( MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE ) ;
2018-02-06 23:09:39 +01:00
gLastLandedMoves [ gBattlerTarget ] = 0 ;
2017-09-24 00:29:52 +02:00
gBattleCommunication [ 6 ] = moveType ;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle ( gBattlerTarget , gLastUsedAbility ) ;
2017-09-24 00:29:52 +02:00
}
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
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_FORESIGHT )
2017-09-24 00:29:52 +02:00
{
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
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . 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
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_DOESNT_AFFECT_FOE ;
2017-09-24 00:29:52 +02:00
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
{
2018-01-16 22:12:38 +01:00
flags | = MOVE_RESULT_NOT_VERY_EFFECTIVE ;
2017-09-24 00:29:52 +02:00
}
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
{
2018-01-16 22:12:38 +01:00
flags | = MOVE_RESULT_SUPER_EFFECTIVE ;
2017-09-24 00:29:52 +02:00
}
}
// check type2
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type2 )
2017-09-24 00:29:52 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . type1 ! = gBattleMons [ gBattlerTarget ] . 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
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_DOESNT_AFFECT_FOE ;
2017-09-24 00:29:52 +02:00
break ;
}
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type2
& & gBattleMons [ gBattlerTarget ] . type1 ! = gBattleMons [ gBattlerTarget ] . 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
{
2018-01-16 22:12:38 +01:00
flags | = MOVE_RESULT_NOT_VERY_EFFECTIVE ;
2017-09-24 00:29:52 +02:00
}
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type2
& & gBattleMons [ gBattlerTarget ] . type1 ! = gBattleMons [ gBattlerTarget ] . 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
{
2018-01-16 22:12:38 +01:00
flags | = MOVE_RESULT_SUPER_EFFECTIVE ;
2017-09-24 00:29:52 +02:00
}
}
}
i + = 3 ;
}
}
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . ability = = ABILITY_WONDER_GUARD
2018-01-16 22:12:38 +01:00
& & ! ( flags & MOVE_RESULT_NO_EFFECT )
2018-02-06 23:09:39 +01:00
& & AttacksThisTurn ( gBattlerAttacker , gCurrentMove ) = = 2
2018-01-16 22:12:38 +01:00
& & ( ! ( flags & MOVE_RESULT_SUPER_EFFECTIVE ) | | ( ( flags & ( MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE ) ) = = ( MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE ) ) )
2017-09-24 00:29:52 +02:00
& & gBattleMoves [ gCurrentMove ] . power )
{
gLastUsedAbility = ABILITY_WONDER_GUARD ;
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2018-02-06 23:09:39 +01:00
gLastLandedMoves [ gBattlerTarget ] = 0 ;
2017-09-24 00:29:52 +02:00
gBattleCommunication [ 6 ] = 3 ;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle ( gBattlerTarget , gLastUsedAbility ) ;
2017-09-24 00:29:52 +02:00
}
2018-01-16 22:12:38 +01:00
if ( gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE )
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . 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
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-02-06 02:46:59 +01:00
if ( ! ( gHitMarker & HITMARKER_FAINTED ( gActiveBattler ) ) )
2017-09-24 00:29:52 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitReturnMonToBall ( 0 , 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-24 00:29:52 +02:00
}
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atk4C_getswitchedmondata ( void )
2017-09-24 00:29:52 +02:00
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-09-24 00:29:52 +02:00
return ;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-24 00:29:52 +02:00
2018-02-06 20:48:02 +01:00
gBattlerPartyIndexes [ gActiveBattler ] = * ( gBattleStruct - > monToSwitchIntoId + gActiveBattler ) ;
2017-09-24 00:29:52 +02:00
2018-02-06 20:48:02 +01:00
BtlController_EmitGetMonData ( 0 , REQUEST_ALL_BATTLE , gBitTable [ gBattlerPartyIndexes [ gActiveBattler ] ] ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-24 00:29:52 +02:00
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 ;
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-09-24 00:29:52 +02:00
return ;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-02-06 02:46:59 +01:00
oldData = gBattleMons [ gActiveBattler ] ;
monData = ( u8 * ) ( & gBattleMons [ gActiveBattler ] ) ;
2017-09-24 00:29:52 +02:00
for ( i = 0 ; i < sizeof ( struct BattlePokemon ) ; i + + )
{
2018-02-06 02:46:59 +01:00
monData [ i ] = gBattleBufferB [ gActiveBattler ] [ 4 + i ] ;
2017-09-24 00:29:52 +02:00
}
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . type1 = gBaseStats [ gBattleMons [ gActiveBattler ] . species ] . type1 ;
gBattleMons [ gActiveBattler ] . type2 = gBaseStats [ gBattleMons [ gActiveBattler ] . species ] . type2 ;
gBattleMons [ gActiveBattler ] . ability = GetAbilityBySpecies ( gBattleMons [ gActiveBattler ] . species , gBattleMons [ gActiveBattler ] . altAbility ) ;
2017-09-24 00:29:52 +02:00
// check knocked off item
2018-02-06 02:46:59 +01:00
i = GetBattlerSide ( gActiveBattler ) ;
2018-10-14 18:37:52 +02:00
if ( gWishFutureKnock . knockedOffMons [ i ] & gBitTable [ gBattlerPartyIndexes [ gActiveBattler ] ] )
2017-09-24 00:29:52 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . item = 0 ;
2017-09-24 00:29:52 +02:00
}
if ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_BATON_PASS )
{
2018-11-18 20:00:36 +01:00
for ( i = 0 ; i < NUM_BATTLE_STATS ; i + + )
2017-09-24 00:29:52 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . statStages [ i ] = oldData . statStages [ i ] ;
2017-09-24 00:29:52 +02:00
}
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . status2 = oldData . status2 ;
2017-09-24 00:29:52 +02:00
}
2017-10-02 23:32:39 +02:00
SwitchInClearSetData ( ) ;
2017-09-24 00:29:52 +02:00
2018-02-06 02:46:59 +01:00
if ( gBattleTypeFlags & BATTLE_TYPE_PALACE & & gBattleMons [ gActiveBattler ] . maxHP / 2 > = gBattleMons [ gActiveBattler ] . hp
& & gBattleMons [ gActiveBattler ] . hp ! = 0 & & ! ( gBattleMons [ gActiveBattler ] . status1 & STATUS1_SLEEP ) )
2017-09-24 00:29:52 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleStruct - > field_92 | = gBitTable [ gActiveBattler ] ;
2017-09-24 00:29:52 +02:00
}
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = gActiveBattler ;
2017-11-11 20:01:04 +01:00
2018-02-06 20:48:02 +01:00
PREPARE_MON_NICK_BUFFER ( gBattleTextBuff1 , gActiveBattler , gBattlerPartyIndexes [ gActiveBattler ] ) ;
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
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-09-24 00:29:52 +02:00
return ;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-24 00:29:52 +02:00
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_OPPONENT
2017-09-24 00:29:52 +02:00
& & ! ( gBattleTypeFlags & ( BATTLE_TYPE_LINK
| BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_x2000000
2018-09-20 22:00:00 +02:00
| BATTLE_TYPE_TRAINER_HILL
2017-09-24 00:29:52 +02:00
| BATTLE_TYPE_FRONTIER ) ) )
2018-02-06 02:46:59 +01:00
HandleSetPokedexFlag ( SpeciesToNationalPokedexNum ( gBattleMons [ gActiveBattler ] . species ) , FLAG_SET_SEEN , gBattleMons [ gActiveBattler ] . personality ) ;
2017-09-24 00:29:52 +02:00
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags & = ~ ( gBitTable [ gActiveBattler ] ) ;
2017-09-24 00:29:52 +02:00
2018-02-06 20:48:02 +01:00
BtlController_EmitSwitchInAnim ( 0 , gBattlerPartyIndexes [ gActiveBattler ] , gBattlescriptCurrInstr [ 2 ] ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-24 00:29:52 +02:00
gBattlescriptCurrInstr + = 3 ;
if ( gBattleTypeFlags & BATTLE_TYPE_ARENA )
2018-11-11 18:33:16 +01:00
BattleArena_InitPoints ( ) ;
2017-09-24 00:29:52 +02:00
}
2017-11-25 18:42:31 +01:00
static void atk4F_jumpifcantswitch ( void )
2017-09-24 00:29:52 +02:00
{
2018-02-28 19:37:48 +01:00
s32 i ;
s32 lastMonId ;
struct Pokemon * party ;
2017-09-24 00:29:52 +02:00
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] & ~ ( ATK4F_DONT_CHECK_STATUSES ) ) ;
2017-09-24 00:29:52 +02:00
if ( ! ( gBattlescriptCurrInstr [ 1 ] & ATK4F_DONT_CHECK_STATUSES )
2018-02-06 02:46:59 +01:00
& & ( ( gBattleMons [ gActiveBattler ] . status2 & ( STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION ) )
| | ( gStatuses3 [ gActiveBattler ] & STATUS3_ROOTED ) ) )
2017-09-24 00:29:52 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 2 ) ;
2017-09-24 00:29:52 +02:00
}
else if ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER )
{
# ifndef NONMATCHING
asm ( " " : : : " r5 " ) ;
# endif // NONMATCHING
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_OPPONENT )
2017-09-24 00:29:52 +02:00
party = gEnemyParty ;
else
party = gPlayerParty ;
2018-02-28 19:37:48 +01:00
i = 0 ;
if ( gActiveBattler & 2 )
i = 3 ;
2017-09-24 00:29:52 +02:00
2018-02-28 19:37:48 +01:00
for ( lastMonId = i + 3 ; i < lastMonId ; i + + )
2017-09-24 00:29:52 +02:00
{
2018-02-28 19:37:48 +01:00
if ( GetMonData ( & party [ i ] , MON_DATA_SPECIES ) ! = SPECIES_NONE
& & ! GetMonData ( & party [ i ] , MON_DATA_IS_EGG )
& & GetMonData ( & party [ i ] , MON_DATA_HP ) ! = 0
& & gBattlerPartyIndexes [ gActiveBattler ] ! = i )
2017-09-24 00:29:52 +02:00
break ;
}
2018-02-28 19:37:48 +01:00
if ( i = = lastMonId )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 2 ) ;
2017-09-24 00:29:52 +02:00
else
gBattlescriptCurrInstr + = 6 ;
}
else if ( gBattleTypeFlags & BATTLE_TYPE_MULTI )
{
if ( gBattleTypeFlags & BATTLE_TYPE_x800000 )
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_PLAYER )
2017-09-24 00:29:52 +02:00
{
party = gPlayerParty ;
2018-02-28 19:37:48 +01:00
i = 0 ;
2018-07-01 11:15:42 +02:00
if ( GetLinkTrainerFlankId ( GetBattlerMultiplayerId ( gActiveBattler ) ) = = TRUE )
2018-02-28 19:37:48 +01:00
i = 3 ;
2017-09-24 00:29:52 +02:00
}
else
{
party = gEnemyParty ;
2018-02-06 02:46:59 +01:00
if ( gActiveBattler = = 1 )
2018-02-28 19:37:48 +01:00
i = 0 ;
2017-09-24 00:29:52 +02:00
else
2018-02-28 19:37:48 +01:00
i = 3 ;
2017-09-24 00:29:52 +02:00
}
}
else
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_OPPONENT )
2017-09-24 00:29:52 +02:00
party = gEnemyParty ;
else
party = gPlayerParty ;
2018-02-28 19:37:48 +01:00
i = 0 ;
2018-07-01 11:15:42 +02:00
if ( GetLinkTrainerFlankId ( GetBattlerMultiplayerId ( gActiveBattler ) ) = = TRUE )
2018-02-28 19:37:48 +01:00
i = 3 ;
2017-09-24 00:29:52 +02:00
}
2018-02-28 19:37:48 +01:00
for ( lastMonId = i + 3 ; i < lastMonId ; i + + )
2017-09-24 00:29:52 +02:00
{
2018-02-28 19:37:48 +01:00
if ( GetMonData ( & party [ i ] , MON_DATA_SPECIES ) ! = SPECIES_NONE
& & ! GetMonData ( & party [ i ] , MON_DATA_IS_EGG )
& & GetMonData ( & party [ i ] , MON_DATA_HP ) ! = 0
& & gBattlerPartyIndexes [ gActiveBattler ] ! = i )
2017-09-24 00:29:52 +02:00
break ;
}
2018-02-28 19:37:48 +01:00
if ( i = = lastMonId )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 2 ) ;
2017-09-24 00:29:52 +02:00
else
gBattlescriptCurrInstr + = 6 ;
}
2018-02-06 02:46:59 +01:00
else if ( gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS & & GetBattlerSide ( gActiveBattler ) = = B_SIDE_OPPONENT )
2017-09-24 00:29:52 +02:00
{
party = gEnemyParty ;
2018-02-28 19:37:48 +01:00
i = 0 ;
if ( gActiveBattler = = B_POSITION_OPPONENT_RIGHT )
i = 3 ;
2017-09-24 00:29:52 +02:00
2018-02-28 19:37:48 +01:00
for ( lastMonId = i + 3 ; i < lastMonId ; i + + )
2017-09-24 00:29:52 +02:00
{
2018-02-28 19:37:48 +01:00
if ( GetMonData ( & party [ i ] , MON_DATA_SPECIES ) ! = SPECIES_NONE
& & ! GetMonData ( & party [ i ] , MON_DATA_IS_EGG )
& & GetMonData ( & party [ i ] , MON_DATA_HP ) ! = 0
& & gBattlerPartyIndexes [ gActiveBattler ] ! = i )
2017-09-24 00:29:52 +02:00
break ;
}
2018-02-28 19:37:48 +01:00
if ( i = = lastMonId )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 2 ) ;
2017-09-24 00:29:52 +02:00
else
gBattlescriptCurrInstr + = 6 ;
}
else
{
2018-02-28 19:37:48 +01:00
u8 battlerIn1 , battlerIn2 ;
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_OPPONENT )
2017-09-24 00:29:52 +02:00
{
2018-02-28 19:37:48 +01:00
battlerIn1 = GetBattlerAtPosition ( B_POSITION_OPPONENT_LEFT ) ;
2017-09-24 00:29:52 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
2018-02-28 19:37:48 +01:00
battlerIn2 = GetBattlerAtPosition ( B_POSITION_OPPONENT_RIGHT ) ;
2017-09-24 00:29:52 +02:00
else
2018-02-28 19:37:48 +01:00
battlerIn2 = battlerIn1 ;
2017-09-24 00:29:52 +02:00
party = gEnemyParty ;
}
else
{
2018-02-28 19:37:48 +01:00
battlerIn1 = GetBattlerAtPosition ( B_POSITION_PLAYER_LEFT ) ;
2017-09-24 00:29:52 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
2018-02-28 19:37:48 +01:00
battlerIn2 = GetBattlerAtPosition ( B_POSITION_PLAYER_RIGHT ) ;
2017-09-24 00:29:52 +02:00
else
2018-02-28 19:37:48 +01:00
battlerIn2 = battlerIn1 ;
2017-09-24 00:29:52 +02:00
party = gPlayerParty ;
}
2018-02-28 19:37:48 +01:00
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2017-09-24 00:29:52 +02:00
{
2018-02-28 19:37:48 +01:00
if ( GetMonData ( & party [ i ] , MON_DATA_HP ) ! = 0
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES ) ! = SPECIES_NONE
& & ! GetMonData ( & party [ i ] , MON_DATA_IS_EGG )
& & i ! = gBattlerPartyIndexes [ battlerIn1 ] & & i ! = gBattlerPartyIndexes [ battlerIn2 ] )
2017-09-24 00:29:52 +02:00
break ;
}
2018-02-28 19:37:48 +01:00
if ( i = = 6 )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 2 ) ;
2017-09-24 00:29:52 +02:00
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
{
2018-02-06 20:48:02 +01:00
* ( gBattleStruct - > field_58 + gActiveBattler ) = gBattlerPartyIndexes [ gActiveBattler ] ;
2018-02-06 02:46:59 +01:00
* ( gBattleStruct - > monToSwitchIntoId + gActiveBattler ) = 6 ;
gBattleStruct - > field_93 & = ~ ( gBitTable [ gActiveBattler ] ) ;
2017-09-24 00:29:52 +02:00
2018-07-07 19:57:09 +02:00
BtlController_EmitChoosePokemon ( 0 , PARTY_MUST_CHOOSE_MON , arg0 , 0 , gBattleStruct - > field_60 [ gActiveBattler ] ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-24 00:29:52 +02:00
}
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 ;
2018-02-08 12:13:29 +01:00
u8 battlerId ;
2017-09-25 00:09:13 +02:00
const u8 * jumpPtr ;
2018-02-08 12:13:29 +01:00
battlerId = 0 ;
2017-09-25 00:09:13 +02:00
flags = 0 ;
2018-03-01 00:59:52 +01:00
jumpPtr = T1_READ_PTR ( gBattlescriptCurrInstr + 2 ) ;
2017-09-25 00:09:13 +02:00
if ( gBattlescriptCurrInstr [ 1 ] = = 5 )
{
if ( ( gBattleTypeFlags & ( BATTLE_TYPE_DOUBLE | BATTLE_TYPE_MULTI ) ) ! = BATTLE_TYPE_DOUBLE )
{
2018-02-06 02:46:59 +01:00
for ( gActiveBattler = 0 ; gActiveBattler < gBattlersCount ; gActiveBattler + + )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gHitMarker & HITMARKER_FAINTED ( gActiveBattler ) )
2017-09-25 00:09:13 +02:00
{
2018-07-01 11:15:42 +02:00
if ( HasNoMonsToSwitch ( gActiveBattler , 6 , 6 ) )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags | = gBitTable [ gActiveBattler ] ;
gHitMarker & = ~ ( HITMARKER_FAINTED ( gActiveBattler ) ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitLinkStandbyMsg ( 0 , 2 , 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
2018-02-06 02:46:59 +01:00
else if ( ! gSpecialStatuses [ gActiveBattler ] . flag40 )
2017-09-25 00:09:13 +02:00
{
sub_804CF10 ( 6 ) ;
2018-02-06 02:46:59 +01:00
gSpecialStatuses [ gActiveBattler ] . flag40 = 1 ;
2017-09-25 00:09:13 +02:00
}
}
else
{
2018-02-06 20:48:02 +01:00
BtlController_EmitLinkStandbyMsg ( 0 , 2 , 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
}
}
else if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
{
u8 flag40_0 , flag40_1 , flag40_2 , flag40_3 ;
hitmarkerFaintBits = gHitMarker > > 0x1C ;
if ( gBitTable [ 0 ] & hitmarkerFaintBits )
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 0 ;
2018-07-01 11:15:42 +02:00
if ( HasNoMonsToSwitch ( 0 , 6 , 6 ) )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags | = gBitTable [ gActiveBattler ] ;
gHitMarker & = ~ ( HITMARKER_FAINTED ( gActiveBattler ) ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitCmd42 ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
2018-02-06 02:46:59 +01:00
else if ( ! gSpecialStatuses [ gActiveBattler ] . flag40 )
2017-09-25 00:09:13 +02:00
{
2017-11-12 17:06:31 +01:00
sub_804CF10 ( gBattleStruct - > monToSwitchIntoId [ 2 ] ) ;
2018-02-06 02:46:59 +01:00
gSpecialStatuses [ gActiveBattler ] . flag40 = 1 ;
2017-09-25 00:09:13 +02:00
}
else
{
2018-02-06 20:48:02 +01:00
BtlController_EmitLinkStandbyMsg ( 0 , 2 , 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
flags | = 1 ;
}
}
if ( gBitTable [ 2 ] & hitmarkerFaintBits & & ! ( gBitTable [ 0 ] & hitmarkerFaintBits ) )
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 2 ;
2018-07-01 11:15:42 +02:00
if ( HasNoMonsToSwitch ( 2 , 6 , 6 ) )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags | = gBitTable [ gActiveBattler ] ;
gHitMarker & = ~ ( HITMARKER_FAINTED ( gActiveBattler ) ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitCmd42 ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
2018-02-06 02:46:59 +01:00
else if ( ! gSpecialStatuses [ gActiveBattler ] . flag40 )
2017-09-25 00:09:13 +02:00
{
2017-11-12 17:06:31 +01:00
sub_804CF10 ( gBattleStruct - > monToSwitchIntoId [ 0 ] ) ;
2018-02-06 02:46:59 +01:00
gSpecialStatuses [ gActiveBattler ] . flag40 = 1 ;
2017-09-25 00:09:13 +02:00
}
else if ( ! ( flags & 1 ) )
{
2018-02-06 20:48:02 +01:00
BtlController_EmitLinkStandbyMsg ( 0 , 2 , 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
}
if ( gBitTable [ 1 ] & hitmarkerFaintBits )
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 1 ;
2018-07-01 11:15:42 +02:00
if ( HasNoMonsToSwitch ( 1 , 6 , 6 ) )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags | = gBitTable [ gActiveBattler ] ;
gHitMarker & = ~ ( HITMARKER_FAINTED ( gActiveBattler ) ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitCmd42 ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
2018-02-06 02:46:59 +01:00
else if ( ! gSpecialStatuses [ gActiveBattler ] . flag40 )
2017-09-25 00:09:13 +02:00
{
2017-11-12 17:06:31 +01:00
sub_804CF10 ( gBattleStruct - > monToSwitchIntoId [ 3 ] ) ;
2018-02-06 02:46:59 +01:00
gSpecialStatuses [ gActiveBattler ] . flag40 = 1 ;
2017-09-25 00:09:13 +02:00
}
else
{
2018-02-06 20:48:02 +01:00
BtlController_EmitLinkStandbyMsg ( 0 , 2 , 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
flags | = 2 ;
}
}
if ( gBitTable [ 3 ] & hitmarkerFaintBits & & ! ( gBitTable [ 1 ] & hitmarkerFaintBits ) )
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 3 ;
2018-07-01 11:15:42 +02:00
if ( HasNoMonsToSwitch ( 3 , 6 , 6 ) )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags | = gBitTable [ gActiveBattler ] ;
gHitMarker & = ~ ( HITMARKER_FAINTED ( gActiveBattler ) ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitCmd42 ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
2018-02-06 02:46:59 +01:00
else if ( ! gSpecialStatuses [ gActiveBattler ] . flag40 )
2017-09-25 00:09:13 +02:00
{
2017-11-12 17:06:31 +01:00
sub_804CF10 ( gBattleStruct - > monToSwitchIntoId [ 1 ] ) ;
2018-02-06 02:46:59 +01:00
gSpecialStatuses [ gActiveBattler ] . flag40 = 1 ;
2017-09-25 00:09:13 +02:00
}
else if ( ! ( flags & 2 ) )
{
2018-02-06 20:48:02 +01:00
BtlController_EmitLinkStandbyMsg ( 0 , 2 , 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
}
flag40_0 = gSpecialStatuses [ 0 ] . flag40 ;
if ( ! flag40_0 )
{
flag40_2 = gSpecialStatuses [ 2 ] . flag40 ;
if ( ! flag40_2 & & hitmarkerFaintBits ! = 0 )
{
2018-02-06 02:46:59 +01:00
if ( gAbsentBattlerFlags & gBitTable [ 0 ] )
gActiveBattler = 2 ;
2017-09-25 00:09:13 +02:00
else
2018-02-06 02:46:59 +01:00
gActiveBattler = 0 ;
2017-09-25 00:09:13 +02:00
2018-02-06 20:48:02 +01:00
BtlController_EmitLinkStandbyMsg ( 0 , 2 , 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
}
flag40_1 = gSpecialStatuses [ 1 ] . flag40 ;
if ( ! flag40_1 )
{
flag40_3 = gSpecialStatuses [ 3 ] . flag40 ;
if ( ! flag40_3 & & hitmarkerFaintBits ! = 0 )
{
2018-02-06 02:46:59 +01:00
if ( gAbsentBattlerFlags & gBitTable [ 1 ] )
gActiveBattler = 3 ;
2017-09-25 00:09:13 +02:00
else
2018-02-06 02:46:59 +01:00
gActiveBattler = 1 ;
2017-09-25 00:09:13 +02:00
2018-02-06 20:48:02 +01:00
BtlController_EmitLinkStandbyMsg ( 0 , 2 , 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
}
}
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 )
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 2 ;
2018-07-01 11:15:42 +02:00
if ( HasNoMonsToSwitch ( 2 , gBattleBufferB [ 0 ] [ 1 ] , 6 ) )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags | = gBitTable [ gActiveBattler ] ;
gHitMarker & = ~ ( HITMARKER_FAINTED ( gActiveBattler ) ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitCmd42 ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
2018-02-06 02:46:59 +01:00
else if ( ! gSpecialStatuses [ gActiveBattler ] . flag40 )
2017-09-25 00:09:13 +02:00
{
2017-11-12 17:06:31 +01:00
sub_804CF10 ( gBattleStruct - > monToSwitchIntoId [ 0 ] ) ;
2018-02-06 02:46:59 +01:00
gSpecialStatuses [ gActiveBattler ] . flag40 = 1 ;
2017-09-25 00:09:13 +02:00
}
}
if ( gBitTable [ 3 ] & hitmarkerFaintBits & & hitmarkerFaintBits & gBitTable [ 1 ] )
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 3 ;
2018-07-01 11:15:42 +02:00
if ( HasNoMonsToSwitch ( 3 , gBattleBufferB [ 1 ] [ 1 ] , 6 ) )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags | = gBitTable [ gActiveBattler ] ;
gHitMarker & = ~ ( HITMARKER_FAINTED ( gActiveBattler ) ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitCmd42 ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
2018-02-06 02:46:59 +01:00
else if ( ! gSpecialStatuses [ gActiveBattler ] . flag40 )
2017-09-25 00:09:13 +02:00
{
2017-11-12 17:06:31 +01:00
sub_804CF10 ( gBattleStruct - > monToSwitchIntoId [ 1 ] ) ;
2018-02-06 02:46:59 +01:00
gSpecialStatuses [ gActiveBattler ] . flag40 = 1 ;
2017-09-25 00:09:13 +02:00
}
}
gBattlescriptCurrInstr + = 6 ;
}
else
{
gBattlescriptCurrInstr + = 6 ;
}
}
else
{
gBattlescriptCurrInstr + = 6 ;
}
hitmarkerFaintBits = gHitMarker > > 0x1C ;
2018-02-08 11:17:41 +01:00
gBattlerFainted = 0 ;
2017-09-25 00:09:13 +02:00
while ( 1 )
{
2018-02-08 11:17:41 +01:00
if ( gBitTable [ gBattlerFainted ] & hitmarkerFaintBits )
2017-09-25 00:09:13 +02:00
break ;
2018-02-08 11:17:41 +01:00
if ( gBattlerFainted > = gBattlersCount )
2017-09-25 00:09:13 +02:00
break ;
2018-02-08 11:17:41 +01:00
gBattlerFainted + + ;
2017-09-25 00:09:13 +02:00
}
2018-02-08 11:17:41 +01:00
if ( gBattlerFainted = = gBattlersCount )
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr = jumpPtr ;
}
else
{
if ( gBattlescriptCurrInstr [ 1 ] & 0x80 )
2018-07-07 19:57:09 +02:00
hitmarkerFaintBits = PARTY_CHOOSE_MON ; // Used here as the caseId for the EmitChoose function.
2017-09-25 00:09:13 +02:00
else
2018-07-07 19:57:09 +02:00
hitmarkerFaintBits = PARTY_MUST_CHOOSE_MON ;
2017-09-25 00:09:13 +02:00
2018-02-08 12:13:29 +01:00
battlerId = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] & ~ ( 0x80 ) ) ;
if ( gSpecialStatuses [ battlerId ] . flag40 )
2017-09-25 00:09:13 +02:00
{
gBattlescriptCurrInstr + = 6 ;
}
2018-07-01 11:15:42 +02:00
else if ( HasNoMonsToSwitch ( battlerId , 6 , 6 ) )
2017-09-25 00:09:13 +02:00
{
2018-02-08 12:13:29 +01:00
gActiveBattler = battlerId ;
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags | = gBitTable [ gActiveBattler ] ;
gHitMarker & = ~ ( HITMARKER_FAINTED ( gActiveBattler ) ) ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr = jumpPtr ;
}
else
{
2018-02-08 12:13:29 +01:00
gActiveBattler = battlerId ;
2018-02-06 20:48:02 +01:00
* ( gBattleStruct - > field_58 + gActiveBattler ) = gBattlerPartyIndexes [ gActiveBattler ] ;
2018-02-06 02:46:59 +01:00
* ( gBattleStruct - > monToSwitchIntoId + gActiveBattler ) = 6 ;
gBattleStruct - > field_93 & = ~ ( gBitTable [ gActiveBattler ] ) ;
2017-09-25 00:09:13 +02:00
2018-02-06 20:48:02 +01:00
BtlController_EmitChoosePokemon ( 0 , hitmarkerFaintBits , * ( gBattleStruct - > monToSwitchIntoId + ( gActiveBattler ^ 2 ) ) , 0 , gBattleStruct - > field_60 [ gActiveBattler ] ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + = 6 ;
2018-02-06 02:46:59 +01:00
if ( GetBattlerPosition ( gActiveBattler ) = = 0 & & gBattleResults . playerSwitchesCounter < 0xFF )
2017-09-25 00:09:13 +02:00
gBattleResults . playerSwitchesCounter + + ;
if ( gBattleTypeFlags & BATTLE_TYPE_MULTI )
{
2018-02-06 02:46:59 +01:00
for ( gActiveBattler = 0 ; gActiveBattler < gBattlersCount ; gActiveBattler + + )
2017-09-25 00:09:13 +02:00
{
2018-02-08 12:13:29 +01:00
if ( gActiveBattler ! = battlerId )
2017-09-25 00:09:13 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitLinkStandbyMsg ( 0 , 2 , 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
}
}
else
{
2018-02-08 12:13:29 +01:00
gActiveBattler = GetBattlerAtPosition ( GetBattlerPosition ( battlerId ) ^ BIT_SIDE ) ;
2018-02-06 02:46:59 +01:00
if ( gAbsentBattlerFlags & gBitTable [ gActiveBattler ] )
gActiveBattler ^ = BIT_FLANK ;
2017-09-25 00:09:13 +02:00
2018-02-06 20:48:02 +01:00
BtlController_EmitLinkStandbyMsg ( 0 , 2 , 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
}
}
}
2017-11-25 18:42:31 +01:00
static void atk51_switchhandleorder ( void )
2017-09-25 00:09:13 +02:00
{
s32 i ;
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-09-25 00:09:13 +02:00
return ;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( 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 :
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-25 00:09:13 +02:00
{
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 ] ) )
{
2018-02-06 20:48:02 +01:00
RecordedBattle_SetBattlerAction ( i , gBattleBufferB [ i ] [ 1 ] ) ;
2017-09-25 00:09:13 +02:00
gBattleStruct - > field_93 | = gBitTable [ i ] ;
}
}
}
break ;
case 1 :
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_MULTI ) )
2018-02-06 02:46:59 +01:00
sub_803BDA0 ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
break ;
case 2 :
2018-02-06 02:46:59 +01:00
if ( ! ( gBattleStruct - > field_93 & gBitTable [ gActiveBattler ] ) )
2017-09-25 00:09:13 +02:00
{
2018-02-06 20:48:02 +01:00
RecordedBattle_SetBattlerAction ( gActiveBattler , gBattleBufferB [ gActiveBattler ] [ 1 ] ) ;
2018-02-06 02:46:59 +01:00
gBattleStruct - > field_93 | = gBitTable [ gActiveBattler ] ;
2017-09-25 00:09:13 +02:00
}
// fall through
case 3 :
2018-02-06 02:46:59 +01:00
gBattleCommunication [ 0 ] = gBattleBufferB [ gActiveBattler ] [ 1 ] ;
* ( gBattleStruct - > monToSwitchIntoId + gActiveBattler ) = gBattleBufferB [ gActiveBattler ] [ 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
{
2018-02-06 02:46:59 +01:00
* ( gActiveBattler * 3 + ( u8 * ) ( gBattleStruct - > field_60 ) + 0 ) & = 0xF ;
* ( gActiveBattler * 3 + ( u8 * ) ( gBattleStruct - > field_60 ) + 0 ) | = ( gBattleBufferB [ gActiveBattler ] [ 2 ] & 0xF0 ) ;
* ( gActiveBattler * 3 + ( u8 * ) ( gBattleStruct - > field_60 ) + 1 ) = gBattleBufferB [ gActiveBattler ] [ 3 ] ;
2017-09-25 00:09:13 +02:00
2018-02-06 02:46:59 +01:00
* ( ( gActiveBattler ^ BIT_FLANK ) * 3 + ( u8 * ) ( gBattleStruct - > field_60 ) + 0 ) & = ( 0xF0 ) ;
* ( ( gActiveBattler ^ BIT_FLANK ) * 3 + ( u8 * ) ( gBattleStruct - > field_60 ) + 0 ) | = ( gBattleBufferB [ gActiveBattler ] [ 2 ] & 0xF0 ) > > 4 ;
* ( ( gActiveBattler ^ BIT_FLANK ) * 3 + ( u8 * ) ( gBattleStruct - > field_60 ) + 2 ) = gBattleBufferB [ gActiveBattler ] [ 3 ] ;
2017-09-25 00:09:13 +02:00
}
else if ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER )
{
2018-02-06 02:46:59 +01:00
sub_80571DC ( gActiveBattler , * ( gBattleStruct - > monToSwitchIntoId + gActiveBattler ) ) ;
2017-09-25 00:09:13 +02:00
}
else
{
2018-02-06 02:46:59 +01:00
sub_803BDA0 ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
2018-02-06 23:09:39 +01:00
PREPARE_SPECIES_BUFFER ( gBattleTextBuff1 , gBattleMons [ gBattlerAttacker ] . species )
2018-02-06 02:46:59 +01:00
PREPARE_MON_NICK_BUFFER ( gBattleTextBuff2 , gActiveBattler , gBattleBufferB [ gActiveBattler ] [ 1 ] )
2017-09-25 00:09:13 +02:00
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 ;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-02-06 02:46:59 +01:00
sub_803FA70 ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
2018-02-06 02:46:59 +01:00
gHitMarker & = ~ ( HITMARKER_FAINTED ( gActiveBattler ) ) ;
gSpecialStatuses [ gActiveBattler ] . flag40 = 0 ;
2017-09-25 00:09:13 +02:00
2018-02-06 02:46:59 +01:00
if ( ! ( gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] & SIDE_STATUS_SPIKES_DAMAGED )
& & ( gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] & SIDE_STATUS_SPIKES )
2018-03-01 00:59:52 +01:00
& & ! IS_BATTLER_OF_TYPE ( gActiveBattler , TYPE_FLYING )
2018-02-06 02:46:59 +01:00
& & gBattleMons [ gActiveBattler ] . ability ! = ABILITY_LEVITATE )
2017-09-25 00:09:13 +02:00
{
u8 spikesDmg ;
2018-02-06 02:46:59 +01:00
gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] | = SIDE_STATUS_SPIKES_DAMAGED ;
2017-09-25 00:09:13 +02:00
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . status2 & = ~ ( STATUS2_DESTINY_BOND ) ;
2017-09-25 00:09:13 +02:00
gHitMarker & = ~ ( HITMARKER_DESTINYBOND ) ;
2018-02-06 02:46:59 +01:00
spikesDmg = ( 5 - gSideTimers [ GetBattlerSide ( gActiveBattler ) ] . spikesAmount ) * 2 ;
gBattleMoveDamage = gBattleMons [ gActiveBattler ] . maxHP / ( spikesDmg ) ;
2017-09-25 00:09:13 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = gActiveBattler ;
2017-09-25 00:09:13 +02:00
BattleScriptPushCursor ( ) ;
2018-02-08 11:17:41 +01:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_TARGET )
2017-11-25 18:42:31 +01:00
gBattlescriptCurrInstr = BattleScript_SpikesOnTarget ;
2018-02-08 11:17:41 +01:00
else if ( gBattlescriptCurrInstr [ 1 ] = = BS_ATTACKER )
2017-11-25 18:42:31 +01:00
gBattlescriptCurrInstr = BattleScript_SpikesOnAttacker ;
2017-09-25 00:09:13 +02:00
else
2018-02-08 11:17:41 +01:00
gBattlescriptCurrInstr = BattleScript_SpikesOnFaintedBattler ;
2017-09-25 00:09:13 +02:00
}
else
{
2019-01-19 22:32:25 +01:00
// There is a hack here to ensure the truant counter will be 0 when the battler's next turn starts.
// The truant counter is not updated in the case where a mon switches in after a lost judgement in the battle arena.
if ( gBattleMons [ gActiveBattler ] . ability = = ABILITY_TRUANT & & ! gDisableStructs [ gActiveBattler ] . truantSwitchInHack )
2018-02-06 02:46:59 +01:00
gDisableStructs [ gActiveBattler ] . truantCounter = 1 ;
2017-09-25 00:09:13 +02:00
2019-01-19 22:32:25 +01:00
gDisableStructs [ gActiveBattler ] . truantSwitchInHack = 0 ;
2017-09-25 00:09:13 +02:00
2018-09-01 20:00:13 +02:00
if ( ! AbilityBattleEffects ( ABILITYEFFECT_ON_SWITCHIN , gActiveBattler , 0 , 0 , 0 )
2018-12-05 15:31:01 +01:00
& & ! ItemBattleEffects ( ITEMEFFECT_ON_SWITCH_IN , gActiveBattler , FALSE ) )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] & = ~ ( SIDE_STATUS_SPIKES_DAMAGED ) ;
2017-09-25 00:09:13 +02:00
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-25 00:09:13 +02:00
{
2018-06-28 21:06:32 +02:00
if ( gBattlerByTurnOrder [ i ] = = gActiveBattler )
2018-02-06 23:09:39 +01:00
gActionsByTurnOrder [ i ] = B_ACTION_CANCEL_PARTNER ;
2017-09-25 00:09:13 +02:00
}
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
u16 * hpOnSwitchout = & gBattleStruct - > hpOnSwitchout [ GetBattlerSide ( 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 ;
2018-02-08 11:17:41 +01:00
gBattlerFainted + + ;
2017-09-25 00:09:13 +02:00
while ( 1 )
{
2018-02-08 11:17:41 +01:00
if ( hitmarkerFaintBits & gBitTable [ gBattlerFainted ] & & ! ( gAbsentBattlerFlags & gBitTable [ gBattlerFainted ] ) )
2017-09-25 00:09:13 +02:00
break ;
2018-02-08 11:17:41 +01:00
if ( gBattlerFainted > = gBattlersCount )
2017-09-25 00:09:13 +02:00
break ;
2018-02-08 11:17:41 +01:00
gBattlerFainted + + ;
2017-09-25 00:09:13 +02:00
}
}
gBattlescriptCurrInstr + = 2 ;
}
}
}
2017-11-25 18:42:31 +01:00
static void atk53_trainerslidein ( void )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gActiveBattler = GetBattlerAtPosition ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitTrainerSlide ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + = 2 ;
}
2017-11-25 18:42:31 +01:00
static void atk54_playse ( void )
2017-09-25 00:09:13 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-03-01 00:59:52 +01:00
BtlController_EmitPlaySE ( 0 , T2_READ_16 ( gBattlescriptCurrInstr + 1 ) ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + = 3 ;
}
2017-11-25 18:42:31 +01:00
static void atk55_fanfare ( void )
2017-09-25 00:09:13 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-03-01 00:59:52 +01:00
BtlController_EmitPlayFanfareOrBGM ( 0 , T2_READ_16 ( gBattlescriptCurrInstr + 1 ) , FALSE ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + = 3 ;
}
2017-11-25 18:42:31 +01:00
static void atk56_playfaintcry ( void )
2017-09-25 00:09:13 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitFaintingCry ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + = 2 ;
}
2017-09-28 15:34:21 +02:00
static void atk57 ( void )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gActiveBattler = GetBattlerAtPosition ( B_POSITION_PLAYER_LEFT ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitCmd55 ( 0 , gBattleOutcome ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + = 1 ;
}
2017-11-25 18:42:31 +01:00
static void atk58_returntoball ( void )
2017-09-25 00:09:13 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitReturnMonToBall ( 0 , 1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + = 2 ;
}
2017-11-25 18:42:31 +01:00
static void atk59_handlelearnnewmove ( void )
2017-09-25 00:09:13 +02:00
{
2018-03-01 00:59:52 +01:00
const u8 * jumpPtr1 = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
const u8 * jumpPtr2 = T1_READ_PTR ( gBattlescriptCurrInstr + 5 ) ;
2017-09-25 00:09:13 +02:00
2018-02-07 22:53:40 +01:00
u16 ret = MonTryLearningNewMove ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , gBattlescriptCurrInstr [ 9 ] ) ;
2017-09-25 00:09:13 +02:00
while ( ret = = 0xFFFE )
2018-02-07 22:53:40 +01:00
ret = MonTryLearningNewMove ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , 0 ) ;
2017-09-25 00:09:13 +02:00
if ( ret = = 0 )
{
gBattlescriptCurrInstr = jumpPtr2 ;
}
2018-12-05 15:31:01 +01:00
else if ( ret = = 0xFFFF )
2017-09-25 00:09:13 +02:00
{
gBattlescriptCurrInstr + = 10 ;
}
else
{
2018-02-06 02:46:59 +01:00
gActiveBattler = GetBattlerAtPosition ( B_POSITION_PLAYER_LEFT ) ;
2017-09-25 00:09:13 +02:00
2018-02-07 22:53:40 +01:00
if ( gBattlerPartyIndexes [ gActiveBattler ] = = gBattleStruct - > expGetterMonId
2018-02-06 02:46:59 +01:00
& & ! ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_TRANSFORMED ) )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
GiveMoveToBattleMon ( & gBattleMons [ gActiveBattler ] , ret ) ;
2017-09-25 00:09:13 +02:00
}
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
{
2018-02-06 02:46:59 +01:00
gActiveBattler = GetBattlerAtPosition ( B_POSITION_PLAYER_RIGHT ) ;
2018-02-07 22:53:40 +01:00
if ( gBattlerPartyIndexes [ gActiveBattler ] = = gBattleStruct - > expGetterMonId
2018-02-06 02:46:59 +01:00
& & ! ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_TRANSFORMED ) )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
GiveMoveToBattleMon ( & gBattleMons [ gActiveBattler ] , ret ) ;
2017-09-25 00:09:13 +02:00
}
}
gBattlescriptCurrInstr = jumpPtr1 ;
}
}
2017-09-28 15:34:21 +02:00
static void atk5A_yesnoboxlearnmove ( void )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 0 ;
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 ) ;
2018-06-17 16:48:58 +02:00
BattlePutTextOnWindow ( 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 ) ;
2019-04-04 23:05:46 +02:00
BeginNormalPaletteFade ( 0xFFFFFFFF , 0 , 0 , 0x10 , RGB_BLACK ) ;
2017-09-25 00:09:13 +02:00
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 ( ) ;
2018-08-12 21:54:07 +02:00
ShowSelectMovePokemonSummaryScreen ( gPlayerParty , gBattleStruct - > expGetterMonId , gPlayerPartyCount - 1 , ReshowBattleScreenAfterMenu , gMoveToLearn ) ;
2017-09-25 00:09:13 +02:00
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
{
2018-02-07 22:53:40 +01:00
u16 moveId = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_MOVE1 + movePosition ) ;
2017-09-25 00:09:13 +02:00
if ( IsHMMove2 ( moveId ) )
{
2018-02-06 02:46:59 +01:00
PrepareStringBattle ( STRINGID_HMMOVESCANTBEFORGOTTEN , gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
gBattleScripting . learnMoveState = 6 ;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-25 00:09:13 +02:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff2 , moveId )
2018-02-07 22:53:40 +01:00
RemoveMonPPBonus ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , movePosition ) ;
SetMonMoveSlot ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , gMoveToLearn , movePosition ) ;
2017-09-25 00:09:13 +02:00
2018-02-07 22:53:40 +01:00
if ( gBattlerPartyIndexes [ 0 ] = = gBattleStruct - > expGetterMonId
2017-09-25 00:09:13 +02:00
& & ! ( gBattleMons [ 0 ] . status2 & STATUS2_TRANSFORMED )
2019-01-19 22:32:25 +01:00
& & ! ( gDisableStructs [ 0 ] . mimickedMoves & gBitTable [ movePosition ] ) )
2017-09-25 00:09:13 +02:00
{
RemoveBattleMonPPBonus ( & gBattleMons [ 0 ] , movePosition ) ;
SetBattleMonMoveSlot ( & gBattleMons [ 0 ] , gMoveToLearn , movePosition ) ;
}
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE
2018-02-07 22:53:40 +01:00
& & gBattlerPartyIndexes [ 2 ] = = gBattleStruct - > expGetterMonId
2017-09-25 00:09:13 +02:00
& & ! ( gBattleMons [ 2 ] . status2 & STATUS2_TRANSFORMED )
2019-01-19 22:32:25 +01:00
& & ! ( gDisableStructs [ 2 ] . mimickedMoves & gBitTable [ movePosition ] ) )
2017-09-25 00:09:13 +02:00
{
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 :
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-25 00:09:13 +02:00
{
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 ) ;
2018-06-17 16:48:58 +02:00
BattlePutTextOnWindow ( 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 )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-25 00:09:13 +02:00
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 ) ;
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( 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
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-25 00:09:13 +02:00
2018-01-16 22:12:38 +01:00
if ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2017-09-25 00:09:13 +02:00
{
gBattlescriptCurrInstr + = 2 ;
}
2018-02-06 02:46:59 +01:00
else if ( ! ( gHitMarker & HITMARKER_IGNORE_SUBSTITUTE ) | | ! ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_SUBSTITUTE ) | | gDisableStructs [ gActiveBattler ] . substituteHP = = 0 )
2017-09-25 00:09:13 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitHitAnimation ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + = 2 ;
}
else
{
gBattlescriptCurrInstr + = 2 ;
}
}
static u32 GetTrainerMoneyToGive ( u16 trainerId )
{
u32 i = 0 ;
u32 lastMonLevel = 0 ;
u32 moneyReward = 0 ;
2018-06-30 18:55:34 +02:00
if ( trainerId = = TRAINER_SECRET_BASE )
2017-09-25 00:09:13 +02:00
{
2018-02-07 13:49:33 +01:00
moneyReward = 20 * gBattleResources - > secretBase - > party . levels [ 0 ] * gBattleStruct - > moneyMultiplier ;
2017-09-25 00:09:13 +02:00
}
else
{
switch ( gTrainers [ trainerId ] . partyFlags )
{
case 0 :
{
const struct TrainerMonNoItemDefaultMoves * party = gTrainers [ trainerId ] . party . NoItemDefaultMoves ;
lastMonLevel = party [ gTrainers [ trainerId ] . partySize - 1 ] . lvl ;
}
break ;
2017-12-17 21:19:08 +01:00
case F_TRAINER_PARTY_CUSTOM_MOVESET :
2017-09-25 00:09:13 +02:00
{
const struct TrainerMonNoItemCustomMoves * party = gTrainers [ trainerId ] . party . NoItemCustomMoves ;
lastMonLevel = party [ gTrainers [ trainerId ] . partySize - 1 ] . lvl ;
}
break ;
2017-12-17 21:19:08 +01:00
case F_TRAINER_PARTY_HELD_ITEM :
2017-09-25 00:09:13 +02:00
{
const struct TrainerMonItemDefaultMoves * party = gTrainers [ trainerId ] . party . ItemDefaultMoves ;
lastMonLevel = party [ gTrainers [ trainerId ] . partySize - 1 ] . lvl ;
}
break ;
2017-12-17 21:19:08 +01:00
case F_TRAINER_PARTY_CUSTOM_MOVESET | F_TRAINER_PARTY_HELD_ITEM :
2017-09-25 00:09:13 +02:00
{
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 ) ;
2019-04-04 21:24:21 +02:00
PREPARE_WORD_NUMBER_BUFFER ( gBattleTextBuff1 , 5 , moneyReward ) ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atk5E ( void )
2017-09-25 00:09:13 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-25 00:09:13 +02:00
switch ( gBattleCommunication [ 0 ] )
{
case 0 :
2018-02-06 20:48:02 +01:00
BtlController_EmitGetMonData ( 0 , REQUEST_ALL_BATTLE , 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
gBattleCommunication [ 0 ] + + ;
break ;
case 1 :
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-25 00:09:13 +02:00
{
s32 i ;
2018-06-30 14:12:17 +02:00
struct BattlePokemon * bufferPoke = ( struct BattlePokemon * ) & gBattleBufferB [ gActiveBattler ] [ 4 ] ;
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . moves [ i ] = bufferPoke - > moves [ i ] ;
gBattleMons [ gActiveBattler ] . pp [ i ] = bufferPoke - > pp [ i ] ;
2017-09-25 00:09:13 +02:00
}
gBattlescriptCurrInstr + = 2 ;
}
break ;
}
}
2018-06-30 14:12:17 +02:00
static void atk5F_swapattackerwithtarget ( void )
2017-09-25 00:09:13 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
gBattlerAttacker = gBattlerTarget ;
gBattlerTarget = gActiveBattler ;
2017-09-25 00:09:13 +02:00
2018-06-30 14:12:17 +02:00
if ( gHitMarker & HITMARKER_SWAP_ATTACKER_TARGET )
gHitMarker & = ~ ( HITMARKER_SWAP_ATTACKER_TARGET ) ;
2017-09-25 00:09:13 +02:00
else
2018-06-30 14:12:17 +02:00
gHitMarker | = HITMARKER_SWAP_ATTACKER_TARGET ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atk60_incrementgamestat ( void )
2017-09-25 00:09:13 +02:00
{
2018-02-06 23:09:39 +01:00
if ( GetBattlerSide ( gBattlerAttacker ) = = B_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 ;
2018-06-30 14:12:17 +02:00
struct Pokemon * party ;
struct HpAndStatus hpStatuses [ PARTY_SIZE ] ;
2017-09-25 00:09:13 +02:00
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-09-25 00:09:13 +02:00
return ;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-25 00:09:13 +02:00
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_PLAYER )
2017-09-25 00:09:13 +02:00
party = gPlayerParty ;
else
party = gEnemyParty ;
2018-06-30 14:12:17 +02:00
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2017-09-25 00:09:13 +02:00
{
if ( GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) = = SPECIES_NONE
| | GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) = = SPECIES_EGG )
{
2018-12-05 15:31:01 +01:00
hpStatuses [ i ] . hp = 0xFFFF ;
2017-09-25 00:09:13 +02:00
hpStatuses [ i ] . status = 0 ;
}
else
{
hpStatuses [ i ] . hp = GetMonData ( & party [ i ] , MON_DATA_HP ) ;
hpStatuses [ i ] . status = GetMonData ( & party [ i ] , MON_DATA_STATUS ) ;
}
}
2018-02-06 20:48:02 +01:00
BtlController_EmitDrawPartyStatusSummary ( 0 , hpStatuses , 1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + = 2 ;
}
2018-06-28 21:06:32 +02:00
static void atk62_hidepartystatussummary ( void )
2017-09-25 00:09:13 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-06-28 21:06:32 +02:00
BtlController_EmitHidePartyStatusSummary ( 0 ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + = 2 ;
}
2018-09-22 19:08:41 +02:00
static void atk63_jumptocalledmove ( void )
2017-09-25 00:09:13 +02:00
{
2017-12-02 00:03:46 +01:00
if ( gBattlescriptCurrInstr [ 1 ] )
2018-09-22 18:41:00 +02:00
gCurrentMove = gCalledMove ;
2017-09-25 00:09:13 +02:00
else
2018-09-22 18:41:00 +02:00
gChosenMove = gCurrentMove = gCalledMove ;
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
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-25 00:09:13 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-02-06 02:46:59 +01:00
if ( ! ( gStatuses3 [ gActiveBattler ] & STATUS3_SEMI_INVULNERABLE )
& & gDisableStructs [ gActiveBattler ] . substituteHP = = 0
2017-09-25 00:09:13 +02:00
& & ! ( gHitMarker & HITMARKER_NO_ANIMATIONS ) )
{
2018-02-06 20:48:02 +01:00
BtlController_EmitStatusAnimation ( 0 , FALSE , gBattleMons [ gActiveBattler ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
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 ;
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-25 00:09:13 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-03-01 00:59:52 +01:00
wantedToAnimate = T1_READ_32 ( gBattlescriptCurrInstr + 2 ) ;
2018-02-06 02:46:59 +01:00
if ( ! ( gStatuses3 [ gActiveBattler ] & STATUS3_SEMI_INVULNERABLE )
& & gDisableStructs [ gActiveBattler ] . substituteHP = = 0
2017-09-25 00:09:13 +02:00
& & ! ( gHitMarker & HITMARKER_NO_ANIMATIONS ) )
{
2018-02-06 20:48:02 +01:00
BtlController_EmitStatusAnimation ( 0 , TRUE , gBattleMons [ gActiveBattler ] . status2 & wantedToAnimate ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
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 ;
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-25 00:09:13 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-03-01 00:59:52 +01:00
wantedStatus = T1_READ_32 ( gBattlescriptCurrInstr + 3 ) ;
2018-02-06 02:46:59 +01:00
if ( ! ( gStatuses3 [ gActiveBattler ] & STATUS3_SEMI_INVULNERABLE )
& & gDisableStructs [ gActiveBattler ] . substituteHP = = 0
2017-09-25 00:09:13 +02:00
& & ! ( gHitMarker & HITMARKER_NO_ANIMATIONS ) )
{
2018-02-06 20:48:02 +01:00
BtlController_EmitStatusAnimation ( 0 , gBattlescriptCurrInstr [ 2 ] , wantedStatus ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
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 ) ;
2018-06-17 16:48:58 +02:00
BattlePutTextOnWindow ( 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 ;
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2018-02-06 23:09:39 +01:00
gActionsByTurnOrder [ i ] = B_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
{
2018-02-08 11:17:41 +01:00
u8 holdEffect , param ;
2017-09-25 00:09:13 +02:00
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . item = = ITEM_ENIGMA_BERRY )
2017-09-25 00:09:13 +02:00
{
2018-02-08 11:17:41 +01:00
holdEffect = gEnigmaBerries [ gBattlerTarget ] . holdEffect ;
param = gEnigmaBerries [ gBattlerTarget ] . holdEffectParam ;
2017-09-25 00:09:13 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ gBattlerTarget ] . item ) ;
2018-02-08 11:17:41 +01:00
param = ItemId_GetHoldEffectParam ( gBattleMons [ gBattlerTarget ] . item ) ;
2017-09-25 00:09:13 +02:00
}
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerTarget ;
2017-09-25 00:09:13 +02:00
2018-02-08 11:17:41 +01:00
if ( holdEffect = = HOLD_EFFECT_FOCUS_BAND & & ( Random ( ) % 100 ) < param )
2017-09-25 00:09:13 +02:00
{
2018-02-06 23:09:39 +01:00
RecordItemEffectBattle ( gBattlerTarget , holdEffect ) ;
gSpecialStatuses [ gBattlerTarget ] . focusBanded = 1 ;
2017-09-25 00:09:13 +02:00
}
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_SUBSTITUTE )
2017-09-25 00:09:13 +02:00
goto END ;
2018-02-06 23:09:39 +01:00
if ( gBattleMoves [ gCurrentMove ] . effect ! = EFFECT_FALSE_SWIPE & & ! gProtectStructs [ gBattlerTarget ] . endured
& & ! gSpecialStatuses [ gBattlerTarget ] . focusBanded )
2017-09-25 00:09:13 +02:00
goto END ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . hp > gBattleMoveDamage )
2017-09-25 00:09:13 +02:00
goto END ;
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . hp - 1 ;
2017-09-25 00:09:13 +02:00
2018-02-06 23:09:39 +01:00
if ( gProtectStructs [ gBattlerTarget ] . endured )
2017-09-25 00:09:13 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_FOE_ENDURED ;
2017-09-25 00:09:13 +02:00
}
2018-02-06 23:09:39 +01:00
else if ( gSpecialStatuses [ gBattlerTarget ] . focusBanded )
2017-09-25 00:09:13 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_FOE_HUNG_ON ;
2018-02-06 23:09:39 +01:00
gLastUsedItem = gBattleMons [ gBattlerTarget ] . item ;
2017-09-25 00:09:13 +02:00
}
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 ;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-26 22:39:59 +02:00
2018-02-06 02:46:59 +01:00
usedHeldItem = & gBattleStruct - > usedHeldItems [ gActiveBattler ] ;
* usedHeldItem = gBattleMons [ gActiveBattler ] . item ;
gBattleMons [ gActiveBattler ] . item = 0 ;
2017-09-26 22:39:59 +02:00
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_HELDITEM_BATTLE , 0 , 2 , & gBattleMons [ gActiveBattler ] . item ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 2 ;
}
2017-09-28 15:34:21 +02:00
static void atk6B_atknameinbuff1 ( void )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
PREPARE_MON_NICK_BUFFER ( gBattleTextBuff1 , gBattlerAttacker , gBattlerPartyIndexes [ gBattlerAttacker ] )
2017-09-26 22:39:59 +02:00
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 ;
2018-12-26 13:05:02 +01:00
SetBgAttribute ( 2 , BG_ATTR_PRIORITY , 0 ) ;
2017-09-26 22:39:59 +02:00
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 ;
2018-12-26 13:05:02 +01:00
SetBgAttribute ( 0 , BG_ATTR_PRIORITY , 1 ) ;
SetBgAttribute ( 1 , BG_ATTR_PRIORITY , 0 ) ;
2017-09-26 22:39:59 +02:00
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 :
2019-04-04 21:24:21 +02:00
DrawLevelUpWindow1 ( ) ;
2017-09-26 22:39:59 +02:00
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 ) ;
2019-04-04 21:24:21 +02:00
DrawLevelUpWindow2 ( ) ;
2017-09-26 22:39:59 +02:00
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 ) ;
2018-12-26 13:05:02 +01:00
SetBgAttribute ( 2 , BG_ATTR_PRIORITY , 2 ) ;
2017-09-26 22:39:59 +02:00
ShowBg ( 2 ) ;
gBattleScripting . atk6C_state = 10 ;
}
break ;
case 10 :
if ( ! IsDma3ManagerBusyWithBgCopy ( ) )
{
2018-12-26 13:05:02 +01:00
SetBgAttribute ( 0 , BG_ATTR_PRIORITY , 0 ) ;
SetBgAttribute ( 1 , BG_ATTR_PRIORITY , 1 ) ;
2017-09-26 22:39:59 +02:00
ShowBg ( 0 ) ;
ShowBg ( 1 ) ;
gBattlescriptCurrInstr + + ;
}
break ;
}
}
2019-04-04 21:24:21 +02:00
static void DrawLevelUpWindow1 ( void )
2017-09-26 22:39:59 +02:00
{
2019-04-04 21:24:21 +02:00
u16 currStats [ NUM_STATS ] ;
2017-09-26 22:39:59 +02:00
2019-04-04 21:24:21 +02:00
GetMonLevelUpWindowStats ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , currStats ) ;
DrawLevelUpWindowPg1 ( 0xD , gBattleResources - > beforeLvlUp - > stats , currStats , 0xE , 0xD , 0xF ) ;
2017-09-26 22:39:59 +02:00
}
2019-04-04 21:24:21 +02:00
static void DrawLevelUpWindow2 ( void )
2017-09-26 22:39:59 +02:00
{
2019-04-04 21:24:21 +02:00
u16 currStats [ NUM_STATS ] ;
2017-09-26 22:39:59 +02:00
2019-04-04 21:24:21 +02:00
GetMonLevelUpWindowStats ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , currStats ) ;
DrawLevelUpWindowPg2 ( 0xD , currStats , 0xE , 0xD , 0xF ) ;
2017-09-26 22:39:59 +02:00
}
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 ;
2018-11-06 17:44:48 +01:00
struct TextPrinterTemplate printerTemplate ;
2017-09-26 22:39:59 +02:00
u8 * txtPtr ;
u32 var ;
2018-02-07 22:53:40 +01:00
monLevel = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_LEVEL ) ;
monGender = GetMonGender ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] ) ;
GetMonNickname ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , gStringVar4 ) ;
2017-09-26 22:39:59 +02:00
2018-11-06 17:44:48 +01:00
printerTemplate . currentChar = gStringVar4 ;
printerTemplate . windowId = 14 ;
printerTemplate . fontId = 0 ;
printerTemplate . x = 32 ;
printerTemplate . y = 0 ;
printerTemplate . currentX = 32 ;
printerTemplate . currentY = 0 ;
printerTemplate . letterSpacing = 0 ;
printerTemplate . lineSpacing = 0 ;
2018-11-06 18:30:21 +01:00
printerTemplate . unk = 0 ;
2018-11-06 17:44:48 +01:00
printerTemplate . fgColor = TEXT_COLOR_WHITE ;
printerTemplate . bgColor = TEXT_COLOR_TRANSPARENT ;
printerTemplate . shadowColor = TEXT_COLOR_DARK_GREY ;
AddTextPrinter ( & printerTemplate , 0xFF , NULL ) ;
2017-09-26 22:39:59 +02:00
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 ;
}
2018-11-06 17:44:48 +01:00
printerTemplate . y = 10 ;
printerTemplate . currentY = 10 ;
AddTextPrinter ( & printerTemplate , 0xFF , NULL ) ;
2017-09-26 22:39:59 +02:00
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 ) ;
}
2017-12-02 21:44:50 +01:00
# define sDestroy data[0]
# define sSavedLvlUpBoxXPosition data[1]
2017-09-26 22:39:59 +02:00
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 ;
2018-02-07 22:53:40 +01:00
u16 species = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPECIES ) ;
u32 personality = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_PERSONALITY ) ;
2017-09-26 22:39:59 +02:00
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
{
2018-02-07 22:53:40 +01:00
if ( gBattlerPartyIndexes [ 0 ] = = gBattleStruct - > expGetterMonId )
2017-09-26 22:39:59 +02:00
return TRUE ;
2018-02-07 22:53:40 +01:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE & & gBattlerPartyIndexes [ 2 ] = = gBattleStruct - > expGetterMonId )
2017-09-26 22:39:59 +02:00
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
{
2018-02-06 23:09:39 +01:00
gBattlerAttacker = GetBattlerAtPosition ( B_POSITION_PLAYER_LEFT ) ;
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
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSpriteInvisibility ( 0 , FALSE ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 2 ;
}
2017-11-25 18:42:31 +01:00
static void atk70_recordlastability ( void )
2017-09-26 22:39:59 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-02-06 02:46:59 +01:00
RecordAbilityBattle ( gActiveBattler , gLastUsedAbility ) ;
2018-02-08 12:13:29 +01:00
gBattlescriptCurrInstr + = 1 ; // UB: Should be + 2, one byte for command and one byte for battlerId argument.
2017-09-26 22:39:59 +02:00
}
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
{
2018-02-08 11:17:41 +01:00
if ( TryRunFromBattle ( gBattlerFainted ) )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
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 ) )
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-02-06 02:46:59 +01:00
opposingBank = gActiveBattler ^ BIT_SIDE ;
2017-09-26 22:39:59 +02:00
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 ) )
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-02-06 02:46:59 +01:00
opposingBank = gActiveBattler ^ BIT_SIDE ;
hpSwitchout = * ( gBattleStruct - > hpOnSwitchout + GetBattlerSide ( opposingBank ) ) ;
2017-09-26 22:39:59 +02:00
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
{
2018-02-07 22:53:40 +01:00
gBattlerInMenuId = gBattlerAttacker ;
2018-02-09 18:46:00 +01:00
PokemonUseItemEffects ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ] ] , gLastUsedItem , gBattlerPartyIndexes [ gBattlerAttacker ] , 0 , 1 ) ;
2017-09-26 22:39:59 +02:00
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 ;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-26 22:39:59 +02:00
switch ( gBattlescriptCurrInstr [ 2 ] )
{
case VARIOUS_CANCEL_MULTI_TURN_MOVES :
2018-02-06 02:46:59 +01:00
CancelMultiTurnMoves ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
break ;
case VARIOUS_SET_MAGIC_COAT_TARGET :
2018-02-06 23:09:39 +01:00
gBattlerAttacker = gBattlerTarget ;
side = GetBattlerSide ( gBattlerAttacker ) ^ BIT_SIDE ;
2017-09-26 22:39:59 +02:00
if ( gSideTimers [ side ] . followmeTimer ! = 0 & & gBattleMons [ gSideTimers [ side ] . followmeTarget ] . hp ! = 0 )
2018-02-06 23:09:39 +01:00
gBattlerTarget = gSideTimers [ side ] . followmeTarget ;
2017-09-26 22:39:59 +02:00
else
2018-02-06 23:09:39 +01:00
gBattlerTarget = gActiveBattler ;
2017-09-26 22:39:59 +02:00
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 :
2018-02-06 23:09:39 +01:00
gBattlerTarget = GetMoveTarget ( gCurrentMove , 0 ) ;
2017-09-26 22:39:59 +02:00
break ;
case 4 :
2018-02-06 02:46:59 +01:00
if ( gHitMarker & HITMARKER_FAINTED ( gActiveBattler ) )
2017-09-26 22:39:59 +02:00
gBattleCommunication [ 0 ] = 1 ;
else
gBattleCommunication [ 0 ] = 0 ;
break ;
case VARIOUS_RESET_INTIMIDATE_TRACE_BITS :
2018-07-16 20:47:30 +02:00
gSpecialStatuses [ gActiveBattler ] . intimidatedMon = 0 ;
2018-02-06 02:46:59 +01:00
gSpecialStatuses [ gActiveBattler ] . traced = 0 ;
2017-09-26 22:39:59 +02:00
break ;
case VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP :
2018-02-07 22:53:40 +01:00
if ( gBattlerPartyIndexes [ 0 ] = = gBattleStruct - > expGetterMonId | | gBattlerPartyIndexes [ 2 ] = = gBattleStruct - > expGetterMonId )
2017-09-26 22:39:59 +02:00
{
u16 * choicedMove ;
2018-02-07 22:53:40 +01:00
if ( gBattlerPartyIndexes [ 0 ] = = gBattleStruct - > expGetterMonId )
2018-02-06 02:46:59 +01:00
gActiveBattler = 0 ;
2017-09-26 22:39:59 +02:00
else
2018-02-06 02:46:59 +01:00
gActiveBattler = 2 ;
2017-09-26 22:39:59 +02:00
2018-02-06 02:46:59 +01:00
choicedMove = & gBattleStruct - > choicedMove [ gActiveBattler ] ;
2017-09-26 22:39:59 +02:00
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-26 22:39:59 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . moves [ i ] = = * choicedMove )
2017-09-26 22:39:59 +02:00
break ;
}
2018-12-25 18:50:15 +01:00
if ( i = = MAX_MON_MOVES )
2017-09-26 22:39:59 +02:00
* 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 ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = gActiveBattler = gBattleCommunication [ 1 ] ;
if ( ! ( gBattleStruct - > field_92 & gBitTable [ gActiveBattler ] )
& & gBattleMons [ gActiveBattler ] . maxHP / 2 > = gBattleMons [ gActiveBattler ] . hp
& & gBattleMons [ gActiveBattler ] . hp ! = 0
& & ! ( gBattleMons [ gActiveBattler ] . status1 & STATUS1_SLEEP ) )
2017-09-26 22:39:59 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleStruct - > field_92 | = gBitTable [ gActiveBattler ] ;
2017-09-26 22:39:59 +02:00
gBattleCommunication [ 0 ] = 1 ;
2018-02-06 02:46:59 +01:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = sUnknown_0831C4F8 [ GetNatureFromPersonality ( gBattleMons [ gActiveBattler ] . personality ) ] ;
2017-09-26 22:39:59 +02:00
}
break ;
2018-11-11 18:33:16 +01:00
case VARIOUS_ARENA_JUDGMENT_WINDOW :
i = BattleArena_ShowJudgmentWindow ( & gBattleCommunication [ 0 ] ) ;
2017-09-26 22:39:59 +02:00
if ( i = = 0 )
return ;
gBattleCommunication [ 1 ] = i ;
break ;
2018-11-11 18:33:16 +01:00
case VARIOUS_ARENA_OPPONENT_MON_LOST :
2017-09-26 22:39:59 +02:00
gBattleMons [ 1 ] . hp = 0 ;
gHitMarker | = HITMARKER_FAINTED ( 1 ) ;
2018-11-11 18:33:16 +01:00
gBattleStruct - > arenaLostOpponentMons | = gBitTable [ gBattlerPartyIndexes [ 1 ] ] ;
2019-01-19 22:32:25 +01:00
gDisableStructs [ 1 ] . truantSwitchInHack = 1 ;
2017-09-26 22:39:59 +02:00
break ;
2018-11-11 18:33:16 +01:00
case VARIOUS_ARENA_PLAYER_MON_LOST :
2017-09-26 22:39:59 +02:00
gBattleMons [ 0 ] . hp = 0 ;
gHitMarker | = HITMARKER_FAINTED ( 0 ) ;
gHitMarker | = HITMARKER_x400000 ;
2018-11-11 18:33:16 +01:00
gBattleStruct - > arenaLostPlayerMons | = gBitTable [ gBattlerPartyIndexes [ 0 ] ] ;
2019-01-19 22:32:25 +01:00
gDisableStructs [ 0 ] . truantSwitchInHack = 1 ;
2017-09-26 22:39:59 +02:00
break ;
2018-11-11 18:33:16 +01:00
case VARIOUS_ARENA_BOTH_MONS_LOST :
2017-09-26 22:39:59 +02:00
gBattleMons [ 0 ] . hp = 0 ;
gBattleMons [ 1 ] . hp = 0 ;
gHitMarker | = HITMARKER_FAINTED ( 0 ) ;
gHitMarker | = HITMARKER_FAINTED ( 1 ) ;
gHitMarker | = HITMARKER_x400000 ;
2018-11-11 18:33:16 +01:00
gBattleStruct - > arenaLostPlayerMons | = gBitTable [ gBattlerPartyIndexes [ 0 ] ] ;
gBattleStruct - > arenaLostOpponentMons | = gBitTable [ gBattlerPartyIndexes [ 1 ] ] ;
2019-01-19 22:32:25 +01:00
gDisableStructs [ 0 ] . truantSwitchInHack = 1 ;
gDisableStructs [ 1 ] . truantSwitchInHack = 1 ;
2017-09-26 22:39:59 +02:00
break ;
2017-10-22 01:04:02 +02:00
case VARIOUS_EMIT_YESNOBOX :
2018-02-06 20:48:02 +01:00
BtlController_EmitUnknownYesNoBox ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
break ;
case 14 :
2019-02-08 16:41:36 +01:00
DrawArenaRefereeTextBox ( ) ;
2017-09-26 22:39:59 +02:00
break ;
case 15 :
2019-02-08 16:41:36 +01:00
RemoveArenaRefereeTextBox ( ) ;
2017-09-26 22:39:59 +02:00
break ;
2018-11-11 18:33:16 +01:00
case VARIOUS_ARENA_JUDGMENT_STRING :
2017-09-26 22:39:59 +02:00
BattleStringExpandPlaceholdersToDisplayedString ( gRefereeStringsTable [ gBattlescriptCurrInstr [ 1 ] ] ) ;
2018-06-17 16:48:58 +02:00
BattlePutTextOnWindow ( gDisplayedStringBattle , 0x16 ) ;
2017-09-26 22:39:59 +02:00
break ;
2018-11-11 18:33:16 +01:00
case VARIOUS_ARENA_WAIT_STRING :
2017-09-26 22:39:59 +02:00
if ( IsTextPrinterActive ( 0x16 ) )
return ;
break ;
case VARIOUS_WAIT_CRY :
if ( ! IsCryFinished ( ) )
return ;
break ;
case VARIOUS_RETURN_OPPONENT_MON1 :
2018-02-06 02:46:59 +01:00
gActiveBattler = 1 ;
if ( gBattleMons [ gActiveBattler ] . hp ! = 0 )
2017-09-26 22:39:59 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitReturnMonToBall ( 0 , 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
}
break ;
case VARIOUS_RETURN_OPPONENT_MON2 :
2018-02-06 02:46:59 +01:00
if ( gBattlersCount > 3 )
2017-09-26 22:39:59 +02:00
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 3 ;
if ( gBattleMons [ gActiveBattler ] . hp ! = 0 )
2017-09-26 22:39:59 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitReturnMonToBall ( 0 , 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
}
}
break ;
2018-08-25 21:04:12 +02:00
case VARIOUS_VOLUME_DOWN :
2018-01-10 04:30:54 +01:00
m4aMPlayVolumeControl ( & gMPlayInfo_BGM , 0xFFFF , 0x55 ) ;
2017-09-26 22:39:59 +02:00
break ;
2018-08-25 21:04:12 +02:00
case VARIOUS_VOLUME_UP :
2018-01-10 04:30:54 +01:00
m4aMPlayVolumeControl ( & gMPlayInfo_BGM , 0xFFFF , 0x100 ) ;
2017-09-26 22:39:59 +02:00
break ;
2018-11-11 18:33:16 +01:00
case VARIOUS_SET_ALREADY_STATUS_MOVE_ATTEMPT :
gBattleStruct - > alreadyStatusedMoveAttempt | = gBitTable [ gActiveBattler ] ;
2017-09-26 22:39:59 +02:00
break ;
case 24 :
2018-02-06 02:46:59 +01:00
if ( sub_805725C ( gActiveBattler ) )
2017-09-26 22:39:59 +02:00
return ;
break ;
case VARIOUS_SET_TELEPORT_OUTCOME :
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_PLAYER )
2018-01-16 22:12:38 +01:00
gBattleOutcome = B_OUTCOME_PLAYER_TELEPORTED ;
2017-09-26 22:39:59 +02:00
else
2018-02-08 00:35:13 +01:00
gBattleOutcome = B_OUTCOME_MON_TELEPORTED ;
2017-09-26 22:39:59 +02:00
break ;
case VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC :
2018-02-06 20:48:02 +01:00
BtlController_EmitPlayFanfareOrBGM ( 0 , MUS_KACHI1 , TRUE ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
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 ;
2018-02-06 23:09:39 +01:00
u16 lastMove = gLastResultingMoves [ gBattlerAttacker ] ;
2017-09-26 22:39:59 +02:00
if ( lastMove ! = MOVE_PROTECT & & lastMove ! = MOVE_DETECT & & lastMove ! = MOVE_ENDURE )
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerAttacker ] . protectUses = 0 ;
2017-09-26 22:39:59 +02:00
2018-02-06 02:46:59 +01:00
if ( gCurrentTurnActionNumber = = ( gBattlersCount - 1 ) )
2017-09-26 22:39:59 +02:00
notLastTurn = FALSE ;
2018-02-06 23:09:39 +01:00
if ( sProtectSuccessRates [ gDisableStructs [ gBattlerAttacker ] . protectUses ] > = Random ( ) & & notLastTurn )
2017-09-26 22:39:59 +02:00
{
if ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_PROTECT )
{
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . protected = 1 ;
2017-09-26 22:39:59 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
if ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_ENDURE )
{
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . endured = 1 ;
2017-09-26 22:39:59 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerAttacker ] . protectUses + + ;
2017-09-26 22:39:59 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerAttacker ] . protectUses = 0 ;
2017-09-26 22:39:59 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-26 22:39:59 +02:00
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk78_faintifabilitynotdamp ( void )
2017-09-26 22:39:59 +02:00
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-09-26 22:39:59 +02:00
return ;
2018-02-06 23:09:39 +01:00
for ( gBattlerTarget = 0 ; gBattlerTarget < gBattlersCount ; gBattlerTarget + + )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . ability = = ABILITY_DAMP )
2017-09-26 22:39:59 +02:00
break ;
}
2018-02-06 23:09:39 +01:00
if ( gBattlerTarget = = gBattlersCount )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gBattleMons [ gActiveBattler ] . hp ;
2018-02-06 20:48:02 +01:00
BtlController_EmitHealthBarUpdate ( 0 , INSTANT_HP_BAR_DROP ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + + ;
2018-02-06 23:09:39 +01:00
for ( gBattlerTarget = 0 ; gBattlerTarget < gBattlersCount ; gBattlerTarget + + )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattlerTarget = = gBattlerAttacker )
2017-09-26 22:39:59 +02:00
continue ;
2018-02-06 23:09:39 +01:00
if ( ! ( gAbsentBattlerFlags & gBitTable [ gBattlerTarget ] ) )
2017-09-26 22:39:59 +02:00
break ;
}
}
else
{
gLastUsedAbility = ABILITY_DAMP ;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle ( gBattlerTarget , gBattleMons [ gBattlerTarget ] . ability ) ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = BattleScript_DampStopsExplosion ;
}
}
2017-09-28 15:34:21 +02:00
static void atk79_setatkhptozero ( void )
2017-09-26 22:39:59 +02:00
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-09-26 22:39:59 +02:00
return ;
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . hp = 0 ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_HP_BATTLE , 0 , 2 , & gBattleMons [ gActiveBattler ] . hp ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atk7A_jumpifnexttargetvalid ( void )
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
const u8 * jumpPtr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
{
2018-02-06 23:09:39 +01:00
for ( gBattlerTarget + + ; ; gBattlerTarget + + )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattlerTarget = = gBattlerAttacker )
2017-09-26 22:39:59 +02:00
continue ;
2018-02-06 23:09:39 +01:00
if ( ! ( gAbsentBattlerFlags & gBitTable [ gBattlerTarget ] ) )
2017-09-26 22:39:59 +02:00
break ;
}
2018-02-06 23:09:39 +01:00
if ( gBattlerTarget > = gBattlersCount )
2017-09-26 22:39:59 +02:00
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
{
2018-03-01 00:59:52 +01:00
const u8 * failPtr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
2018-02-08 11:17:41 +01:00
if ( gBattlescriptCurrInstr [ 5 ] = = BS_ATTACKER )
2018-02-06 23:09:39 +01:00
gBattlerTarget = gBattlerAttacker ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . maxHP / 2 ;
2017-09-26 22:39:59 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleMoveDamage * = - 1 ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . hp = = gBattleMons [ gBattlerTarget ] . maxHP )
2017-09-26 22:39:59 +02:00
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 ;
2018-02-06 02:46:59 +01:00
for ( validMovesCount = 0 , i = 0 ; i < gBattlersCount ; i + + )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( i ! = gBattlerAttacker )
2017-09-26 22:39:59 +02:00
{
2018-10-14 18:10:54 +02:00
move = * ( i * 2 + gBattlerAttacker * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 0 )
| ( * ( i * 2 + gBattlerAttacker * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 1 ) < < 8 ) ;
2017-09-26 22:39:59 +02:00
2018-12-05 15:31:01 +01:00
if ( move ! = 0 & & move ! = 0xFFFF )
2017-09-26 22:39:59 +02:00
{
movesArray [ validMovesCount ] = move ;
validMovesCount + + ;
}
}
}
2018-10-14 18:10:54 +02:00
move = * ( gBattleStruct - > lastTakenMove + gBattlerAttacker * 2 + 0 )
| ( * ( gBattleStruct - > lastTakenMove + gBattlerAttacker * 2 + 1 ) < < 8 ) ;
2017-09-26 22:39:59 +02:00
2018-12-05 15:31:01 +01:00
if ( move ! = 0 & & move ! = 0xFFFF )
2017-09-26 22:39:59 +02:00
{
gHitMarker & = ~ ( HITMARKER_ATTACKSTRING_PRINTED ) ;
gCurrentMove = move ;
2018-02-06 23:09:39 +01:00
gBattlerTarget = GetMoveTarget ( gCurrentMove , 0 ) ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = gBattleScriptsForMoveEffects [ gBattleMoves [ gCurrentMove ] . effect ] ;
}
else if ( validMovesCount )
{
gHitMarker & = ~ ( HITMARKER_ATTACKSTRING_PRINTED ) ;
i = Random ( ) % validMovesCount ;
gCurrentMove = movesArray [ i ] ;
2018-02-06 23:09:39 +01:00
gBattlerTarget = GetMoveTarget ( gCurrentMove , 0 ) ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = gBattleScriptsForMoveEffects [ gBattleMoves [ gCurrentMove ] . effect ] ;
}
else
{
2018-10-14 18:10:54 +02:00
gSpecialStatuses [ gBattlerAttacker ] . ppNotAffectedByPressure = 1 ;
2017-09-26 22:39:59 +02:00
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 )
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-26 22:39:59 +02:00
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
{
2018-02-06 23:09:39 +01:00
if ( gSideStatuses [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] & SIDE_STATUS_REFLECT )
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-26 22:39:59 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
else
{
2018-02-06 23:09:39 +01:00
gSideStatuses [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] | = SIDE_STATUS_REFLECT ;
gSideTimers [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] . reflectTimer = 5 ;
2018-02-07 22:53:40 +01:00
gSideTimers [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] . reflectBattlerId = gBattlerAttacker ;
2017-09-26 22:39:59 +02:00
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
{
2018-02-06 23:09:39 +01:00
if ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT | | gStatuses3 [ gBattlerTarget ] & STATUS3_LEECHSEED )
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-26 22:39:59 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
2018-03-01 00:59:52 +01:00
else if ( IS_BATTLER_OF_TYPE ( gBattlerTarget , TYPE_GRASS ) )
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-26 22:39:59 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
}
else
{
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerTarget ] | = gBattlerAttacker ;
gStatuses3 [ gBattlerTarget ] | = STATUS3_LEECHSEED ;
2017-09-26 22:39:59 +02:00
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 ;
2018-02-06 23:09:39 +01:00
if ( ( gBattleMons [ gBattlerTarget ] . maxHP / 2 ) < gBattleMoveDamage )
gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . maxHP / 2 ;
2017-09-26 22:39:59 +02:00
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
{
2018-03-01 00:59:52 +01:00
const u8 * failJump = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget = gBattlerAttacker ;
gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . maxHP * ( - 1 ) ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . hp = = gBattleMons [ gBattlerTarget ] . maxHP )
2017-09-26 22:39:59 +02:00
{
gBattlescriptCurrInstr = failJump ;
}
else
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status1 & ( ( u8 ) ( ~ STATUS1_SLEEP ) ) )
2017-09-26 22:39:59 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerTarget ] . status1 = 3 ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gActiveBattler ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
}
}
2017-09-28 15:34:21 +02:00
static void atk82_jumpifnotfirstturn ( void )
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
const u8 * failJump = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if ( gDisableStructs [ gBattlerAttacker ] . isFirstTurn )
2017-09-26 22:39:59 +02:00
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 + + ;
}
2018-02-08 12:13:29 +01:00
bool8 UproarWakeUpCheck ( u8 battlerId )
2017-09-26 22:39:59 +02:00
{
s32 i ;
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-26 22:39:59 +02:00
{
2018-02-08 12:13:29 +01:00
if ( ! ( gBattleMons [ i ] . status2 & STATUS2_UPROAR ) | | gBattleMons [ battlerId ] . ability = = ABILITY_SOUNDPROOF )
2017-09-26 22:39:59 +02:00
continue ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = i ;
2017-09-26 22:39:59 +02:00
2018-12-05 15:31:01 +01:00
if ( gBattlerTarget = = 0xFF )
2018-02-06 23:09:39 +01:00
gBattlerTarget = i ;
else if ( gBattlerTarget = = i )
2017-09-26 22:39:59 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
break ;
}
2018-02-06 02:46:59 +01:00
if ( i = = gBattlersCount )
2017-09-26 22:39:59 +02:00
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
{
2018-03-01 00:59:52 +01:00
const u8 * jumpPtr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if ( UproarWakeUpCheck ( gBattlerTarget ) )
2017-09-26 22:39:59 +02:00
{
gBattlescriptCurrInstr = jumpPtr ;
}
2018-02-06 23:09:39 +01:00
else if ( gBattleMons [ gBattlerTarget ] . ability = = ABILITY_INSOMNIA
| | gBattleMons [ gBattlerTarget ] . ability = = ABILITY_VITAL_SPIRIT )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gLastUsedAbility = gBattleMons [ gBattlerTarget ] . ability ;
2017-09-26 22:39:59 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
gBattlescriptCurrInstr = jumpPtr ;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle ( gBattlerTarget , gLastUsedAbility ) ;
2017-09-26 22:39:59 +02:00
}
else
{
gBattlescriptCurrInstr + = 5 ;
}
}
2017-09-28 15:34:21 +02:00
static void atk85_stockpile ( void )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gDisableStructs [ gBattlerAttacker ] . stockpileCounter = = 3 )
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-26 22:39:59 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
else
{
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerAttacker ] . stockpileCounter + + ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
PREPARE_BYTE_NUMBER_BUFFER ( gBattleTextBuff1 , 1 , gDisableStructs [ gBattlerAttacker ] . stockpileCounter )
2017-09-26 22:39:59 +02:00
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
{
2018-03-01 00:59:52 +01:00
const u8 * jumpPtr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2018-02-06 23:09:39 +01:00
if ( gDisableStructs [ gBattlerAttacker ] . stockpileCounter = = 0 )
2017-09-26 22:39:59 +02:00
{
gBattlescriptCurrInstr = jumpPtr ;
}
else
{
if ( gBattleCommunication [ 6 ] ! = 1 )
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = CalculateBaseDamage ( & gBattleMons [ gBattlerAttacker ] , & gBattleMons [ gBattlerTarget ] , gCurrentMove ,
gSideStatuses [ GET_BATTLER_SIDE ( gBattlerTarget ) ] , 0 ,
0 , gBattlerAttacker , gBattlerTarget )
* gDisableStructs [ gBattlerAttacker ] . stockpileCounter ;
gBattleScripting . animTurn = gDisableStructs [ gBattlerAttacker ] . stockpileCounter ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if ( gProtectStructs [ gBattlerAttacker ] . helpingHand )
2017-09-26 22:39:59 +02:00
gBattleMoveDamage = gBattleMoveDamage * 15 / 10 ;
}
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerAttacker ] . stockpileCounter = 0 ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
}
}
2017-09-28 15:34:21 +02:00
static void atk87_stockpiletohpheal ( void )
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
const u8 * jumpPtr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if ( gDisableStructs [ gBattlerAttacker ] . stockpileCounter = = 0 )
2017-09-26 22:39:59 +02:00
{
gBattlescriptCurrInstr = jumpPtr ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
2018-02-06 23:09:39 +01:00
else if ( gBattleMons [ gBattlerAttacker ] . maxHP = = gBattleMons [ gBattlerAttacker ] . hp )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerAttacker ] . stockpileCounter = 0 ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = jumpPtr ;
2018-02-06 23:09:39 +01:00
gBattlerTarget = gBattlerAttacker ;
2017-09-26 22:39:59 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
else
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . maxHP / ( 1 < < ( 3 - gDisableStructs [ gBattlerAttacker ] . stockpileCounter ) ) ;
2017-09-26 22:39:59 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleMoveDamage * = - 1 ;
2018-02-06 23:09:39 +01:00
gBattleScripting . animTurn = gDisableStructs [ gBattlerAttacker ] . stockpileCounter ;
gDisableStructs [ gBattlerAttacker ] . stockpileCounter = 0 ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
2018-02-06 23:09:39 +01:00
gBattlerTarget = gBattlerAttacker ;
2017-09-26 22:39:59 +02:00
}
}
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 + + ;
}
2019-03-30 12:37:18 +01:00
# define STAT_CHANGE_WORKED 0
# define STAT_CHANGE_DIDNT_WORK 1
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 )
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2017-09-26 22:39:59 +02:00
else
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget ;
2017-09-26 22:39:59 +02:00
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 )
2018-08-11 23:00:16 +02:00
if ( statValue < = - 1 ) // Stat decrease.
2017-09-26 22:39:59 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gSideTimers [ GET_BATTLER_SIDE ( gActiveBattler ) ] . mistTimer
2017-09-26 22:39:59 +02:00
& & ! certain & & gCurrentMove ! = MOVE_CURSE )
{
if ( flags = = STAT_CHANGE_BS_PTR )
{
2018-02-06 02:46:59 +01:00
if ( gSpecialStatuses [ gActiveBattler ] . statLowered )
2017-09-26 22:39:59 +02:00
{
gBattlescriptCurrInstr = BS_ptr ;
}
else
{
BattleScriptPush ( BS_ptr ) ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = gActiveBattler ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = BattleScript_MistProtected ;
2018-02-06 02:46:59 +01:00
gSpecialStatuses [ gActiveBattler ] . statLowered = 1 ;
2017-09-26 22:39:59 +02:00
}
}
return STAT_CHANGE_DIDNT_WORK ;
}
else if ( gCurrentMove ! = MOVE_CURSE
& & notProtectAffected ! = TRUE & & JumpIfMoveAffectedByProtect ( 0 ) )
{
gBattlescriptCurrInstr = BattleScript_ButItFailed ;
return STAT_CHANGE_DIDNT_WORK ;
}
2018-02-06 02:46:59 +01:00
else if ( ( gBattleMons [ gActiveBattler ] . ability = = ABILITY_CLEAR_BODY
| | gBattleMons [ gActiveBattler ] . ability = = ABILITY_WHITE_SMOKE )
2017-09-26 22:39:59 +02:00
& & ! certain & & gCurrentMove ! = MOVE_CURSE )
{
if ( flags = = STAT_CHANGE_BS_PTR )
{
2018-02-06 02:46:59 +01:00
if ( gSpecialStatuses [ gActiveBattler ] . statLowered )
2017-09-26 22:39:59 +02:00
{
gBattlescriptCurrInstr = BS_ptr ;
}
else
{
BattleScriptPush ( BS_ptr ) ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = gActiveBattler ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = BattleScript_AbilityNoStatLoss ;
2018-02-06 02:46:59 +01:00
gLastUsedAbility = gBattleMons [ gActiveBattler ] . ability ;
RecordAbilityBattle ( gActiveBattler , gLastUsedAbility ) ;
gSpecialStatuses [ gActiveBattler ] . statLowered = 1 ;
2017-09-26 22:39:59 +02:00
}
}
return STAT_CHANGE_DIDNT_WORK ;
}
2018-02-06 02:46:59 +01:00
else if ( gBattleMons [ gActiveBattler ] . ability = = ABILITY_KEEN_EYE
2018-02-08 12:13:29 +01:00
& & ! certain & & statId = = STAT_ACC )
2017-09-26 22:39:59 +02:00
{
if ( flags = = STAT_CHANGE_BS_PTR )
{
BattleScriptPush ( BS_ptr ) ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = gActiveBattler ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss ;
2018-02-06 02:46:59 +01:00
gLastUsedAbility = gBattleMons [ gActiveBattler ] . ability ;
RecordAbilityBattle ( gActiveBattler , gLastUsedAbility ) ;
2017-09-26 22:39:59 +02:00
}
return STAT_CHANGE_DIDNT_WORK ;
}
2018-02-06 02:46:59 +01:00
else if ( gBattleMons [ gActiveBattler ] . ability = = ABILITY_HYPER_CUTTER
2018-02-08 12:13:29 +01:00
& & ! certain & & statId = = STAT_ATK )
2017-09-26 22:39:59 +02:00
{
if ( flags = = STAT_CHANGE_BS_PTR )
{
BattleScriptPush ( BS_ptr ) ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = gActiveBattler ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss ;
2018-02-06 02:46:59 +01:00
gLastUsedAbility = gBattleMons [ gActiveBattler ] . ability ;
RecordAbilityBattle ( gActiveBattler , gLastUsedAbility ) ;
2017-09-26 22:39:59 +02:00
}
return STAT_CHANGE_DIDNT_WORK ;
}
2018-02-06 02:46:59 +01:00
else if ( gBattleMons [ gActiveBattler ] . ability = = ABILITY_SHIELD_DUST & & flags = = 0 )
2017-09-26 22:39:59 +02:00
{
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 ;
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . statStages [ statId ] = = 0 )
2017-09-26 22:39:59 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
else
2018-02-06 23:09:39 +01:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = ( gBattlerTarget = = gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
}
}
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 ;
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . statStages [ statId ] = = 0xC )
2017-09-26 22:39:59 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
else
2018-02-06 23:09:39 +01:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = ( gBattlerTarget = = gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
}
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . statStages [ statId ] + = statValue ;
if ( gBattleMons [ gActiveBattler ] . statStages [ statId ] < 0 )
gBattleMons [ gActiveBattler ] . statStages [ statId ] = 0 ;
if ( gBattleMons [ gActiveBattler ] . statStages [ statId ] > 0xC )
gBattleMons [ gActiveBattler ] . statStages [ statId ] = 0xC ;
2017-09-26 22:39:59 +02:00
if ( gBattleCommunication [ MULTISTRING_CHOOSER ] = = 2 & & flags & STAT_CHANGE_BS_PTR )
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-26 22:39:59 +02:00
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
{
2018-03-01 00:59:52 +01:00
const u8 * jumpPtr = T1_READ_PTR ( 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 ;
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-26 22:39:59 +02:00
{
2018-11-18 20:00:36 +01:00
for ( j = 0 ; j < NUM_BATTLE_STATS ; j + + )
2017-09-26 22:39:59 +02:00
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
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 | = STATUS2_MULTIPLETURNS ;
gLockedMoves [ gBattlerAttacker ] = gCurrentMove ;
gTakenDmg [ gBattlerAttacker ] = 0 ;
gBattleMons [ gBattlerAttacker ] . status2 | = ( STATUS2_BIDE - 0x100 ) ; // 2 turns
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atk8C_confuseifrepeatingattackends ( void )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( ! ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_LOCK_CONFUSE ) )
2017-09-26 22:39:59 +02:00
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
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . level > = gBattleMons [ gBattlerTarget ] . level )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
* ( gBattleStruct - > field_58 + gBattlerTarget ) = gBattlerPartyIndexes [ gBattlerTarget ] ;
2017-09-26 22:39:59 +02:00
}
else
{
u16 random = Random ( ) & 0xFF ;
2018-02-06 23:09:39 +01:00
if ( ( u32 ) ( ( random * ( gBattleMons [ gBattlerAttacker ] . level + gBattleMons [ gBattlerTarget ] . level ) > > 8 ) + 1 ) < = ( gBattleMons [ gBattlerTarget ] . level / 4 ) )
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
return FALSE ;
}
2018-02-06 23:09:39 +01:00
* ( gBattleStruct - > field_58 + gBattlerTarget ) = gBattlerPartyIndexes [ gBattlerTarget ] ;
2017-09-26 22:39:59 +02:00
}
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 ;
2018-02-08 12:13:29 +01:00
s32 battler1PartyId = 0 ;
s32 battler2PartyId = 0 ;
2017-09-26 22:39:59 +02:00
# 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 ) )
{
2018-02-06 23:09:39 +01:00
if ( GetBattlerSide ( gBattlerTarget ) = = B_SIDE_PLAYER )
2017-09-26 22:39:59 +02:00
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 ) )
{
2018-02-06 23:09:39 +01:00
if ( ( gBattlerTarget & BIT_FLANK ) ! = 0 )
2017-09-26 22:39:59 +02:00
{
firstMonId = 3 ;
lastMonId = 6 ;
}
else
{
firstMonId = 0 ;
lastMonId = 3 ;
}
monsCount = 3 ;
minNeeded = 1 ;
2018-02-08 12:13:29 +01:00
battler2PartyId = gBattlerPartyIndexes [ gBattlerTarget ] ;
battler1PartyId = gBattlerPartyIndexes [ gBattlerTarget ^ BIT_FLANK ] ;
2017-09-26 22:39:59 +02:00
}
else if ( ( gBattleTypeFlags & BATTLE_TYPE_MULTI & & gBattleTypeFlags & BATTLE_TYPE_LINK )
| | ( gBattleTypeFlags & BATTLE_TYPE_MULTI & & gBattleTypeFlags & BATTLE_TYPE_x2000000 ) )
{
2018-07-01 11:15:42 +02:00
if ( GetLinkTrainerFlankId ( GetBattlerMultiplayerId ( gBattlerTarget ) ) = = 1 )
2017-09-26 22:39:59 +02:00
{
firstMonId = 3 ;
lastMonId = 6 ;
}
else
{
firstMonId = 0 ;
lastMonId = 3 ;
}
monsCount = 3 ;
minNeeded = 1 ;
2018-02-08 12:13:29 +01:00
battler2PartyId = gBattlerPartyIndexes [ gBattlerTarget ] ;
battler1PartyId = gBattlerPartyIndexes [ gBattlerTarget ^ BIT_FLANK ] ;
2017-09-26 22:39:59 +02:00
}
else if ( gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS )
{
2018-02-06 23:09:39 +01:00
if ( GetBattlerSide ( gBattlerTarget ) = = B_SIDE_PLAYER )
2017-09-26 22:39:59 +02:00
{
firstMonId = 0 ;
lastMonId = 6 ;
monsCount = 6 ;
minNeeded = 2 ; // since there are two opponents, it has to be a double battle
}
else
{
2018-02-06 23:09:39 +01:00
if ( ( gBattlerTarget & BIT_FLANK ) ! = 0 )
2017-09-26 22:39:59 +02:00
{
firstMonId = 3 ;
lastMonId = 6 ;
}
else
{
firstMonId = 0 ;
lastMonId = 3 ;
}
monsCount = 3 ;
minNeeded = 1 ;
}
2018-02-08 12:13:29 +01:00
battler2PartyId = gBattlerPartyIndexes [ gBattlerTarget ] ;
battler1PartyId = gBattlerPartyIndexes [ gBattlerTarget ^ BIT_FLANK ] ;
2017-09-26 22:39:59 +02:00
}
else if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
{
firstMonId = 0 ;
lastMonId = 6 ;
monsCount = 6 ;
minNeeded = 2 ;
2018-02-08 12:13:29 +01:00
battler2PartyId = gBattlerPartyIndexes [ gBattlerTarget ] ;
battler1PartyId = gBattlerPartyIndexes [ gBattlerTarget ^ BIT_FLANK ] ;
2017-09-26 22:39:59 +02:00
}
else
{
firstMonId = 0 ;
lastMonId = 6 ;
monsCount = 6 ;
minNeeded = 1 ;
2018-02-08 12:13:29 +01:00
battler2PartyId = gBattlerPartyIndexes [ gBattlerTarget ] ; // there is only one pokemon out in single battles
battler1PartyId = gBattlerPartyIndexes [ gBattlerTarget ] ;
2017-09-26 22:39:59 +02:00
}
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 )
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
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 ;
}
2018-02-08 12:13:29 +01:00
while ( i = = battler2PartyId
| | i = = battler1PartyId
2017-09-26 22:39:59 +02:00
| | GetMonData ( & party [ i ] , MON_DATA_SPECIES ) = = SPECIES_NONE
| | GetMonData ( & party [ i ] , MON_DATA_IS_EGG ) = = TRUE
| | GetMonData ( & party [ i ] , MON_DATA_HP ) = = 0 ) ;
}
2018-02-06 23:09:39 +01:00
* ( gBattleStruct - > monToSwitchIntoId + gBattlerTarget ) = i ;
2017-09-26 22:39:59 +02:00
2018-12-18 11:38:08 +01:00
if ( ! IsMultiBattle ( ) )
2018-02-06 23:09:39 +01:00
sub_803BDA0 ( gBattlerTarget ) ;
2017-09-26 22:39:59 +02:00
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 ) )
{
2018-02-06 23:09:39 +01:00
sub_81B8E80 ( gBattlerTarget , i , 0 ) ;
sub_81B8E80 ( gBattlerTarget ^ BIT_FLANK , i , 1 ) ;
2017-09-26 22:39:59 +02:00
}
if ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER )
2018-02-06 23:09:39 +01:00
sub_80571DC ( gBattlerTarget , i ) ;
2017-09-26 22:39:59 +02:00
}
}
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 ;
2018-12-25 18:50:15 +01:00
while ( validMoves < MAX_MON_MOVES )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . moves [ validMoves ] = = 0 )
2017-09-26 22:39:59 +02:00
break ;
validMoves + + ;
}
for ( moveChecked = 0 ; moveChecked < validMoves ; moveChecked + + )
{
2018-02-06 23:09:39 +01:00
moveType = gBattleMoves [ gBattleMons [ gBattlerAttacker ] . moves [ moveChecked ] ] . type ;
2017-09-26 22:39:59 +02:00
if ( moveType = = TYPE_MYSTERY )
{
2018-03-01 00:59:52 +01:00
if ( IS_BATTLER_OF_TYPE ( gBattlerAttacker , TYPE_GHOST ) )
2017-09-26 22:39:59 +02:00
moveType = TYPE_GHOST ;
else
moveType = TYPE_NORMAL ;
}
2018-02-06 23:09:39 +01:00
if ( moveType ! = gBattleMons [ gBattlerAttacker ] . type1
& & moveType ! = gBattleMons [ gBattlerAttacker ] . type2 )
2017-09-26 22:39:59 +02:00
{
break ;
}
}
if ( moveChecked = = validMoves )
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
else
{
do
{
while ( ( moveChecked = Random ( ) & 3 ) > = validMoves ) ;
2018-02-06 23:09:39 +01:00
moveType = gBattleMoves [ gBattleMons [ gBattlerAttacker ] . moves [ moveChecked ] ] . type ;
2017-09-26 22:39:59 +02:00
if ( moveType = = TYPE_MYSTERY )
{
2018-03-01 00:59:52 +01:00
if ( IS_BATTLER_OF_TYPE ( gBattlerAttacker , TYPE_GHOST ) )
2017-09-26 22:39:59 +02:00
moveType = TYPE_GHOST ;
else
moveType = TYPE_NORMAL ;
}
}
2018-02-06 23:09:39 +01:00
while ( moveType = = gBattleMons [ gBattlerAttacker ] . type1 | | moveType = = gBattleMons [ gBattlerAttacker ] . type2 ) ;
2017-09-26 22:39:59 +02:00
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE ( gBattlerAttacker , moveType ) ;
PREPARE_TYPE_BUFFER ( gBattleTextBuff1 , moveType ) ;
2017-09-26 22:39:59 +02:00
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
{
2018-02-06 23:09:39 +01:00
if ( gSideStatuses [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] & SIDE_STATUS_LIGHTSCREEN )
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-26 22:39:59 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
else
{
2018-02-06 23:09:39 +01:00
gSideStatuses [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] | = SIDE_STATUS_LIGHTSCREEN ;
gSideTimers [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] . lightscreenTimer = 5 ;
2018-02-07 22:53:40 +01:00
gSideTimers [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] . lightscreenBattlerId = gBattlerAttacker ;
2017-09-26 22:39:59 +02:00
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 ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . item = = ITEM_ENIGMA_BERRY )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
holdEffect = gEnigmaBerries [ gBattlerTarget ] . holdEffect ;
param = gEnigmaBerries [ gBattlerTarget ] . holdEffectParam ;
2017-09-26 22:39:59 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ gBattlerTarget ] . item ) ;
param = ItemId_GetHoldEffectParam ( gBattleMons [ gBattlerTarget ] . item ) ;
2017-09-26 22:39:59 +02:00
}
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerTarget ;
2017-09-26 22:39:59 +02:00
if ( holdEffect = = HOLD_EFFECT_FOCUS_BAND & & ( Random ( ) % 100 ) < param )
{
2018-02-06 23:09:39 +01:00
RecordItemEffectBattle ( gBattlerTarget , HOLD_EFFECT_FOCUS_BAND ) ;
gSpecialStatuses [ gBattlerTarget ] . focusBanded = 1 ;
2017-09-26 22:39:59 +02:00
}
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . ability = = ABILITY_STURDY )
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-26 22:39:59 +02:00
gLastUsedAbility = ABILITY_STURDY ;
gBattlescriptCurrInstr = BattleScript_SturdyPreventsOHKO ;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle ( gBattlerTarget , ABILITY_STURDY ) ;
2017-09-26 22:39:59 +02:00
}
else
{
u16 chance ;
2018-02-06 23:09:39 +01:00
if ( ! ( gStatuses3 [ gBattlerTarget ] & STATUS3_ALWAYS_HITS ) )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
chance = gBattleMoves [ gCurrentMove ] . accuracy + ( gBattleMons [ gBattlerAttacker ] . level - gBattleMons [ gBattlerTarget ] . level ) ;
if ( Random ( ) % 100 + 1 < chance & & gBattleMons [ gBattlerAttacker ] . level > = gBattleMons [ gBattlerTarget ] . level )
2017-09-26 22:39:59 +02:00
chance = TRUE ;
else
chance = FALSE ;
}
2018-02-06 23:09:39 +01:00
else if ( gDisableStructs [ gBattlerTarget ] . battlerWithSureHit = = gBattlerAttacker
& & gBattleMons [ gBattlerAttacker ] . level > = gBattleMons [ gBattlerTarget ] . level )
2017-09-26 22:39:59 +02:00
{
chance = TRUE ;
}
else
{
2018-02-06 23:09:39 +01:00
chance = gBattleMoves [ gCurrentMove ] . accuracy + ( gBattleMons [ gBattlerAttacker ] . level - gBattleMons [ gBattlerTarget ] . level ) ;
if ( Random ( ) % 100 + 1 < chance & & gBattleMons [ gBattlerAttacker ] . level > = gBattleMons [ gBattlerTarget ] . level )
2017-09-26 22:39:59 +02:00
chance = TRUE ;
else
chance = FALSE ;
}
if ( chance )
{
2018-02-06 23:09:39 +01:00
if ( gProtectStructs [ gBattlerTarget ] . endured )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . hp - 1 ;
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_FOE_ENDURED ;
2017-09-26 22:39:59 +02:00
}
2018-02-06 23:09:39 +01:00
else if ( gSpecialStatuses [ gBattlerTarget ] . focusBanded )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . hp - 1 ;
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_FOE_HUNG_ON ;
2018-02-06 23:09:39 +01:00
gLastUsedItem = gBattleMons [ gBattlerTarget ] . item ;
2017-09-26 22:39:59 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . hp ;
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_ONE_HIT_KO ;
2017-09-26 22:39:59 +02:00
}
gBattlescriptCurrInstr + = 5 ;
}
else
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . level > = gBattleMons [ gBattlerTarget ] . level )
2017-09-26 22:39:59 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
}
}
2017-09-28 15:34:21 +02:00
static void atk94_damagetohalftargethp ( void ) // super fang
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . hp / 2 ;
2017-09-26 22:39:59 +02:00
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 )
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-26 22:39:59 +02:00
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 )
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . type1 ! = TYPE_ROCK
& & gBattleMons [ gBattlerAttacker ] . type1 ! = TYPE_STEEL
& & gBattleMons [ gBattlerAttacker ] . type1 ! = TYPE_GROUND
& & gBattleMons [ gBattlerAttacker ] . type2 ! = TYPE_ROCK
& & gBattleMons [ gBattlerAttacker ] . type2 ! = TYPE_STEEL
& & gBattleMons [ gBattlerAttacker ] . type2 ! = TYPE_GROUND
& & gBattleMons [ gBattlerAttacker ] . ability ! = ABILITY_SAND_VEIL
& & ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_UNDERGROUND )
& & ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_UNDERWATER ) )
{
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . maxHP / 16 ;
2017-09-26 22:39:59 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
}
else
{
gBattleMoveDamage = 0 ;
}
}
if ( gBattleWeather & WEATHER_HAIL )
{
2018-03-01 00:59:52 +01:00
if ( ! IS_BATTLER_OF_TYPE ( gBattlerAttacker , TYPE_ICE )
2018-02-06 23:09:39 +01:00
& & ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_UNDERGROUND )
& & ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_UNDERWATER ) )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . maxHP / 16 ;
2017-09-26 22:39:59 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
}
else
{
gBattleMoveDamage = 0 ;
}
}
}
else
{
gBattleMoveDamage = 0 ;
}
2018-02-06 23:09:39 +01:00
if ( gAbsentBattlerFlags & gBitTable [ gBattlerAttacker ] )
2017-09-26 22:39:59 +02:00
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 ;
2018-02-06 23:09:39 +01:00
if ( GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_PLAYER )
monAttacker = & gPlayerParty [ gBattlerPartyIndexes [ gBattlerAttacker ] ] ;
2017-09-26 22:39:59 +02:00
else
2018-02-06 23:09:39 +01:00
monAttacker = & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ] ] ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if ( GetBattlerSide ( gBattlerTarget ) = = B_SIDE_PLAYER )
monTarget = & gPlayerParty [ gBattlerPartyIndexes [ gBattlerTarget ] ] ;
2017-09-26 22:39:59 +02:00
else
2018-02-06 23:09:39 +01:00
monTarget = & gEnemyParty [ gBattlerPartyIndexes [ gBattlerTarget ] ] ;
2017-09-26 22:39:59 +02:00
speciesAttacker = GetMonData ( monAttacker , MON_DATA_SPECIES ) ;
personalityAttacker = GetMonData ( monAttacker , MON_DATA_PERSONALITY ) ;
speciesTarget = GetMonData ( monTarget , MON_DATA_SPECIES ) ;
personalityTarget = GetMonData ( monTarget , MON_DATA_PERSONALITY ) ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . ability = = ABILITY_OBLIVIOUS )
2017-09-26 22:39:59 +02:00
{
gBattlescriptCurrInstr = BattleScript_ObliviousPreventsAttraction ;
gLastUsedAbility = ABILITY_OBLIVIOUS ;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle ( gBattlerTarget , ABILITY_OBLIVIOUS ) ;
2017-09-26 22:39:59 +02:00
}
else
{
if ( GetGenderFromSpeciesAndPersonality ( speciesAttacker , personalityAttacker ) = = GetGenderFromSpeciesAndPersonality ( speciesTarget , personalityTarget )
2018-02-06 23:09:39 +01:00
| | gBattleMons [ gBattlerTarget ] . status2 & STATUS2_INFATUATION
2017-09-26 22:39:59 +02:00
| | GetGenderFromSpeciesAndPersonality ( speciesAttacker , personalityAttacker ) = = MON_GENDERLESS
| | GetGenderFromSpeciesAndPersonality ( speciesTarget , personalityTarget ) = = MON_GENDERLESS )
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
2017-09-26 22:39:59 +02:00
else
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerTarget ] . status2 | = STATUS2_INFATUATED_WITH ( gBattlerAttacker ) ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
}
}
}
2017-11-25 18:42:31 +01:00
static void atk98_updatestatusicon ( void )
2017-09-26 22:39:59 +02:00
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-09-26 22:39:59 +02:00
return ;
2017-09-28 15:34:21 +02:00
if ( gBattlescriptCurrInstr [ 1 ] ! = BS_ATTACKER_WITH_PARTNER )
2017-09-26 22:39:59 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitStatusIconUpdate ( 0 , gBattleMons [ gActiveBattler ] . status1 , gBattleMons [ gActiveBattler ] . status2 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 2 ;
}
else
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-02-06 02:46:59 +01:00
if ( ! ( gAbsentBattlerFlags & gBitTable [ gActiveBattler ] ) )
2017-09-26 22:39:59 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitStatusIconUpdate ( 0 , gBattleMons [ gActiveBattler ] . status1 , gBattleMons [ gActiveBattler ] . status2 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
}
if ( ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE ) )
{
2018-02-06 23:09:39 +01:00
gActiveBattler = GetBattlerAtPosition ( GetBattlerPosition ( gBattlerAttacker ) ^ BIT_FLANK ) ;
2018-02-06 02:46:59 +01:00
if ( ! ( gAbsentBattlerFlags & gBitTable [ gActiveBattler ] ) )
2017-09-26 22:39:59 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitStatusIconUpdate ( 0 , gBattleMons [ gActiveBattler ] . status1 , gBattleMons [ gActiveBattler ] . status2 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
}
}
gBattlescriptCurrInstr + = 2 ;
}
}
2017-09-28 15:34:21 +02:00
static void atk99_setmist ( void )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gSideTimers [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] . mistTimer )
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_FAILED ;
2017-09-26 22:39:59 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
else
{
2018-02-06 23:09:39 +01:00
gSideTimers [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] . mistTimer = 5 ;
2018-02-07 22:53:40 +01:00
gSideTimers [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] . mistBattlerId = gBattlerAttacker ;
2018-02-06 23:09:39 +01:00
gSideStatuses [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] | = SIDE_STATUS_MIST ;
2017-09-26 22:39:59 +02:00
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
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_FOCUS_ENERGY )
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_FAILED ;
2017-09-26 22:39:59 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
else
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 | = STATUS2_FOCUS_ENERGY ;
2017-09-26 22:39:59 +02:00
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
{
2018-12-05 15:31:01 +01:00
gChosenMove = 0xFFFF ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + + ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_TRANSFORMED
| | gStatuses3 [ gBattlerTarget ] & STATUS3_SEMI_INVULNERABLE )
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_FAILED ;
2017-09-26 22:39:59 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
else
{
s32 i ;
u8 * battleMonAttacker , * battleMonTarget ;
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 | = STATUS2_TRANSFORMED ;
gDisableStructs [ gBattlerAttacker ] . disabledMove = 0 ;
2018-10-14 18:10:54 +02:00
gDisableStructs [ gBattlerAttacker ] . disableTimer = 0 ;
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerAttacker ] . transformedMonPersonality = gBattleMons [ gBattlerTarget ] . personality ;
2019-01-19 22:32:25 +01:00
gDisableStructs [ gBattlerAttacker ] . mimickedMoves = 0 ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
PREPARE_SPECIES_BUFFER ( gBattleTextBuff1 , gBattleMons [ gBattlerTarget ] . species )
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
battleMonAttacker = ( u8 * ) ( & gBattleMons [ gBattlerAttacker ] ) ;
battleMonTarget = ( u8 * ) ( & gBattleMons [ gBattlerTarget ] ) ;
2017-09-26 22:39:59 +02:00
for ( i = 0 ; i < offsetof ( struct BattlePokemon , pp ) ; i + + )
battleMonAttacker [ i ] = battleMonTarget [ i ] ;
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMoves [ gBattleMons [ gBattlerAttacker ] . moves [ i ] ] . pp < 5 )
gBattleMons [ gBattlerAttacker ] . pp [ i ] = gBattleMoves [ gBattleMons [ gBattlerAttacker ] . moves [ i ] ] . pp ;
2017-09-26 22:39:59 +02:00
else
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . pp [ i ] = 5 ;
2017-09-26 22:39:59 +02:00
}
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-02-06 20:48:02 +01:00
BtlController_EmitResetActionMoveSelection ( 0 , RESET_MOVE_SELECTION ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
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
{
2018-02-06 23:09:39 +01:00
u32 hp = gBattleMons [ gBattlerAttacker ] . maxHP / 4 ;
if ( gBattleMons [ gBattlerAttacker ] . maxHP / 4 = = 0 )
2017-09-26 22:39:59 +02:00
hp = 1 ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . hp < = hp )
2017-09-26 22:39:59 +02:00
{
gBattleMoveDamage = 0 ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
else
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . maxHP / 4 ; // one bit value will only work for pokemon which max hp can go to 1020(which is more than possible in games)
2017-09-26 22:39:59 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 | = STATUS2_SUBSTITUTE ;
gBattleMons [ gBattlerAttacker ] . status2 & = ~ ( STATUS2_WRAPPED ) ;
gDisableStructs [ gBattlerAttacker ] . substituteHP = gBattleMoveDamage ;
2017-09-26 22:39:59 +02:00
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
{
2018-12-05 15:31:01 +01:00
gChosenMove = 0xFFFF ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if ( IsMoveUncopyableByMimic ( gLastMoves [ gBattlerTarget ] )
| | gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_TRANSFORMED
| | gLastMoves [ gBattlerTarget ] = = 0
2018-12-05 15:31:01 +01:00
| | gLastMoves [ gBattlerTarget ] = = 0xFFFF )
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
else
{
2019-01-19 22:32:25 +01:00
int i ;
2017-09-26 22:39:59 +02:00
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . moves [ i ] = = gLastMoves [ gBattlerTarget ] )
2017-09-26 22:39:59 +02:00
break ;
}
2018-12-25 18:50:15 +01:00
if ( i = = MAX_MON_MOVES )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . moves [ gCurrMovePos ] = gLastMoves [ gBattlerTarget ] ;
if ( gBattleMoves [ gLastMoves [ gBattlerTarget ] ] . pp < 5 )
gBattleMons [ gBattlerAttacker ] . pp [ gCurrMovePos ] = gBattleMoves [ gLastMoves [ gBattlerTarget ] ] . pp ;
2017-09-26 22:39:59 +02:00
else
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . pp [ gCurrMovePos ] = 5 ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , gLastMoves [ gBattlerTarget ] )
2017-09-26 22:39:59 +02:00
2019-01-19 22:32:25 +01:00
gDisableStructs [ gBattlerAttacker ] . mimickedMoves | = gBitTable [ gCurrMovePos ] ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
}
}
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 ;
2018-06-30 18:55:34 +02:00
if ( gCurrentMove > = MOVES_COUNT )
2017-09-26 22:39:59 +02:00
continue ;
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + ) ; // ?
2017-09-26 22:39:59 +02:00
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 ] ;
2018-02-06 23:09:39 +01:00
gBattlerTarget = GetMoveTarget ( gCurrentMove , 0 ) ;
2017-11-11 22:58:23 +01:00
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
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . level ;
2017-09-26 22:39:59 +02:00
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 ;
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . level * ( randDamage + 50 ) / 100 ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkA1_counterdamagecalculator ( void )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
u8 sideAttacker = GetBattlerSide ( gBattlerAttacker ) ;
2018-02-07 22:53:40 +01:00
u8 sideTarget = GetBattlerSide ( gProtectStructs [ gBattlerAttacker ] . physicalBattlerId ) ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if ( gProtectStructs [ gBattlerAttacker ] . physicalDmg
2017-09-26 22:39:59 +02:00
& & sideAttacker ! = sideTarget
2018-02-07 22:53:40 +01:00
& & gBattleMons [ gProtectStructs [ gBattlerAttacker ] . physicalBattlerId ] . hp )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gProtectStructs [ gBattlerAttacker ] . physicalDmg * 2 ;
2017-09-26 22:39:59 +02:00
if ( gSideTimers [ sideTarget ] . followmeTimer & & gBattleMons [ gSideTimers [ sideTarget ] . followmeTarget ] . hp )
2018-02-06 23:09:39 +01:00
gBattlerTarget = gSideTimers [ sideTarget ] . followmeTarget ;
2017-09-26 22:39:59 +02:00
else
2018-02-07 22:53:40 +01:00
gBattlerTarget = gProtectStructs [ gBattlerAttacker ] . physicalBattlerId ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
}
else
{
2018-10-14 18:10:54 +02:00
gSpecialStatuses [ gBattlerAttacker ] . ppNotAffectedByPressure = 1 ;
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
}
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
{
2018-02-06 23:09:39 +01:00
u8 sideAttacker = GetBattlerSide ( gBattlerAttacker ) ;
2018-02-07 22:53:40 +01:00
u8 sideTarget = GetBattlerSide ( gProtectStructs [ gBattlerAttacker ] . specialBattlerId ) ;
2017-09-26 22:39:59 +02:00
2018-02-07 22:53:40 +01:00
if ( gProtectStructs [ gBattlerAttacker ] . specialDmg & & sideAttacker ! = sideTarget & & gBattleMons [ gProtectStructs [ gBattlerAttacker ] . specialBattlerId ] . hp )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gProtectStructs [ gBattlerAttacker ] . specialDmg * 2 ;
2017-09-26 22:39:59 +02:00
if ( gSideTimers [ sideTarget ] . followmeTimer & & gBattleMons [ gSideTimers [ sideTarget ] . followmeTarget ] . hp )
2018-02-06 23:09:39 +01:00
gBattlerTarget = gSideTimers [ sideTarget ] . followmeTarget ;
2017-09-26 22:39:59 +02:00
else
2018-02-07 22:53:40 +01:00
gBattlerTarget = gProtectStructs [ gBattlerAttacker ] . specialBattlerId ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
}
else
{
2018-10-14 18:10:54 +02:00
gSpecialStatuses [ gBattlerAttacker ] . ppNotAffectedByPressure = 1 ;
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
}
2017-09-28 15:34:21 +02:00
static void atkA3_disablelastusedattack ( void )
2017-09-26 22:39:59 +02:00
{
s32 i ;
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . moves [ i ] = = gLastMoves [ gBattlerTarget ] )
2017-09-26 22:39:59 +02:00
break ;
}
2018-02-06 23:09:39 +01:00
if ( gDisableStructs [ gBattlerTarget ] . disabledMove = = 0
2018-12-25 18:50:15 +01:00
& & i ! = MAX_MON_MOVES & & gBattleMons [ gBattlerTarget ] . pp [ i ] ! = 0 )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , gBattleMons [ gBattlerTarget ] . moves [ i ] )
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerTarget ] . disabledMove = gBattleMons [ gBattlerTarget ] . moves [ i ] ;
2018-10-14 18:10:54 +02:00
gDisableStructs [ gBattlerTarget ] . disableTimer = ( Random ( ) & 3 ) + 2 ;
gDisableStructs [ gBattlerTarget ] . disableTimerStartValue = gDisableStructs [ gBattlerTarget ] . disableTimer ; // used to save the random amount of turns?
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
}
2017-11-25 18:42:31 +01:00
static void atkA4_trysetencore ( void )
2017-09-26 22:39:59 +02:00
{
s32 i ;
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . moves [ i ] = = gLastMoves [ gBattlerTarget ] )
2017-09-26 22:39:59 +02:00
break ;
}
2018-02-06 23:09:39 +01:00
if ( gLastMoves [ gBattlerTarget ] = = MOVE_STRUGGLE
| | gLastMoves [ gBattlerTarget ] = = MOVE_ENCORE
| | gLastMoves [ gBattlerTarget ] = = MOVE_MIRROR_MOVE )
2017-09-26 22:39:59 +02:00
{
i = 4 ;
}
2018-02-06 23:09:39 +01:00
if ( gDisableStructs [ gBattlerTarget ] . encoredMove = = 0
& & i ! = 4 & & gBattleMons [ gBattlerTarget ] . pp [ i ] ! = 0 )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerTarget ] . encoredMove = gBattleMons [ gBattlerTarget ] . moves [ i ] ;
gDisableStructs [ gBattlerTarget ] . encoredMovePos = i ;
2018-10-14 18:10:54 +02:00
gDisableStructs [ gBattlerTarget ] . encoreTimer = ( Random ( ) & 3 ) + 3 ;
gDisableStructs [ gBattlerTarget ] . encoreTimerStartValue = gDisableStructs [ gBattlerTarget ] . encoreTimer ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
}
2017-09-28 15:34:21 +02:00
static void atkA5_painsplitdmgcalc ( void )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( ! ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_SUBSTITUTE ) )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
s32 hpDiff = ( gBattleMons [ gBattlerAttacker ] . hp + gBattleMons [ gBattlerTarget ] . hp ) / 2 ;
s32 painSplitHp = gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . hp - hpDiff ;
2017-09-26 22:39:59 +02:00
u8 * storeLoc = ( void * ) ( & gBattleScripting . painSplitHp ) ;
storeLoc [ 0 ] = ( painSplitHp ) ;
storeLoc [ 1 ] = ( painSplitHp & 0x0000FF00 ) > > 8 ;
storeLoc [ 2 ] = ( painSplitHp & 0x00FF0000 ) > > 16 ;
storeLoc [ 3 ] = ( painSplitHp & 0xFF000000 ) > > 24 ;
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . hp - hpDiff ;
2018-12-05 15:31:01 +01:00
gSpecialStatuses [ gBattlerTarget ] . dmg = 0xFFFF ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
}
2017-09-28 15:34:21 +02:00
static void atkA6_settypetorandomresistance ( void ) // conversion 2
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gLastLandedMoves [ gBattlerAttacker ] = = 0
2018-12-05 15:31:01 +01:00
| | gLastLandedMoves [ gBattlerAttacker ] = = 0xFFFF )
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
2018-02-06 23:09:39 +01:00
else if ( IsTwoTurnsMove ( gLastLandedMoves [ gBattlerAttacker ] )
& & gBattleMons [ gLastHitBy [ gBattlerAttacker ] ] . status2 & STATUS2_MULTIPLETURNS )
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
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
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( i ) = = gLastHitByType [ gBattlerAttacker ]
2017-11-11 20:01:04 +01:00
& & TYPE_EFFECT_MULTIPLIER ( i ) < = TYPE_MUL_NOT_EFFECTIVE
2018-03-01 00:59:52 +01:00
& & ! IS_BATTLER_OF_TYPE ( gBattlerAttacker , TYPE_EFFECT_DEF_TYPE ( i ) ) )
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE ( gBattlerAttacker , TYPE_EFFECT_DEF_TYPE ( i ) ) ;
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 :
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( j ) = = gLastHitByType [ gBattlerAttacker ]
& & TYPE_EFFECT_MULTIPLIER ( j ) < = 5
2018-03-01 00:59:52 +01:00
& & ! IS_BATTLER_OF_TYPE ( gBattlerAttacker , TYPE_EFFECT_DEF_TYPE ( i ) ) )
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE ( gBattlerAttacker , TYPE_EFFECT_DEF_TYPE ( rands ) ) ;
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
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
}
2017-09-28 15:34:21 +02:00
static void atkA7_setalwayshitflag ( void )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerTarget ] & = ~ ( STATUS3_ALWAYS_HITS ) ;
gStatuses3 [ gBattlerTarget ] | = 0x10 ;
gDisableStructs [ gBattlerTarget ] . battlerWithSureHit = gBattlerAttacker ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkA8_copymovepermanently ( void ) // sketch
2017-09-26 22:39:59 +02:00
{
2018-12-05 15:31:01 +01:00
gChosenMove = 0xFFFF ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if ( ! ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_TRANSFORMED )
& & gLastPrintedMoves [ gBattlerTarget ] ! = MOVE_STRUGGLE
& & gLastPrintedMoves [ gBattlerTarget ] ! = 0
2018-12-05 15:31:01 +01:00
& & gLastPrintedMoves [ gBattlerTarget ] ! = 0xFFFF
2018-02-06 23:09:39 +01:00
& & gLastPrintedMoves [ gBattlerTarget ] ! = MOVE_SKETCH )
2017-09-26 22:39:59 +02:00
{
s32 i ;
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . moves [ i ] = = MOVE_SKETCH )
2017-09-26 22:39:59 +02:00
continue ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . moves [ i ] = = gLastPrintedMoves [ gBattlerTarget ] )
2017-09-26 22:39:59 +02:00
break ;
}
2018-12-25 18:50:15 +01:00
if ( i ! = MAX_MON_MOVES )
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
else // sketch worked
{
struct MovePpInfo movePpData ;
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . moves [ gCurrMovePos ] = gLastPrintedMoves [ gBattlerTarget ] ;
gBattleMons [ gBattlerAttacker ] . pp [ gCurrMovePos ] = gBattleMoves [ gLastPrintedMoves [ gBattlerTarget ] ] . pp ;
gActiveBattler = gBattlerAttacker ;
2017-09-26 22:39:59 +02:00
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
movePpData . moves [ i ] = gBattleMons [ gBattlerAttacker ] . moves [ i ] ;
movePpData . pp [ i ] = gBattleMons [ gBattlerAttacker ] . pp [ i ] ;
2017-09-26 22:39:59 +02:00
}
2018-02-06 23:09:39 +01:00
movePpData . ppBonuses = gBattleMons [ gBattlerAttacker ] . ppBonuses ;
2017-09-26 22:39:59 +02:00
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_MOVES_PP_BATTLE , 0 , sizeof ( struct MovePpInfo ) , & movePpData ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , gLastPrintedMoves [ gBattlerTarget ] )
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
}
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
}
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 ;
}
2018-02-08 12:13:29 +01:00
static u8 AttacksThisTurn ( u8 battlerId , 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 )
{
2019-01-13 13:15:23 +01:00
if ( ( gHitMarker & HITMARKER_CHARGING ) )
2017-09-27 23:43:45 +02:00
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 ;
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( IsInvalidForSleepTalkOrAssist ( gBattleMons [ gBattlerAttacker ] . moves [ i ] )
| | gBattleMons [ gBattlerAttacker ] . moves [ i ] = = MOVE_FOCUS_PUNCH
| | gBattleMons [ gBattlerAttacker ] . moves [ i ] = = MOVE_UPROAR
| | IsTwoTurnsMove ( gBattleMons [ gBattlerAttacker ] . moves [ i ] ) )
2017-09-27 23:43:45 +02:00
{
unusableMovesBits | = gBitTable [ i ] ;
}
}
2018-02-06 23:09:39 +01:00
unusableMovesBits = CheckMoveLimitations ( gBattlerAttacker , unusableMovesBits , ~ ( MOVE_LIMITATION_PP ) ) ;
2017-09-27 23:43:45 +02:00
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 ) ) ;
2018-09-22 18:41:00 +02:00
gCalledMove = gBattleMons [ gBattlerAttacker ] . moves [ movePosition ] ;
2017-09-27 23:43:45 +02:00
gCurrMovePos = movePosition ;
gHitMarker & = ~ ( HITMARKER_ATTACKSTRING_PRINTED ) ;
2018-09-22 18:41:00 +02:00
gBattlerTarget = GetMoveTarget ( gCalledMove , 0 ) ;
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
}
2017-11-25 18:42:31 +01:00
static void atkAA_setdestinybond ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 | = STATUS2_DESTINY_BOND ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void TrySetDestinyBondToHappen ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
u8 sideAttacker = GetBattlerSide ( gBattlerAttacker ) ;
u8 sideTarget = GetBattlerSide ( gBattlerTarget ) ;
if ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_DESTINY_BOND
2017-09-27 23:43:45 +02:00
& & 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 ;
2018-02-06 23:09:39 +01:00
s32 hpFraction = GetScaledHPFraction ( gBattleMons [ gBattlerAttacker ] . hp , gBattleMons [ gBattlerAttacker ] . maxHP , 48 ) ;
2017-09-27 23:43:45 +02:00
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
{
2018-02-06 23:09:39 +01:00
if ( gLastMoves [ gBattlerTarget ] ! = 0
2018-12-05 15:31:01 +01:00
& & gLastMoves [ gBattlerTarget ] ! = 0xFFFF )
2017-09-27 23:43:45 +02:00
{
s32 i ;
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gLastMoves [ gBattlerTarget ] = = gBattleMons [ gBattlerTarget ] . moves [ i ] )
2017-09-27 23:43:45 +02:00
break ;
}
2018-12-25 18:50:15 +01:00
if ( i ! = MAX_MON_MOVES & & gBattleMons [ gBattlerTarget ] . pp [ i ] > 1 )
2017-09-27 23:43:45 +02:00
{
s32 ppToDeduct = ( Random ( ) & 3 ) + 2 ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . pp [ i ] < ppToDeduct )
ppToDeduct = gBattleMons [ gBattlerTarget ] . pp [ i ] ;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , gLastMoves [ gBattlerTarget ] )
2017-09-27 23:43:45 +02:00
ConvertIntToDecimalStringN ( gBattleTextBuff2 , ppToDeduct , 0 , 1 ) ;
PREPARE_BYTE_NUMBER_BUFFER ( gBattleTextBuff2 , 1 , ppToDeduct )
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerTarget ] . pp [ i ] - = ppToDeduct ;
gActiveBattler = gBattlerTarget ;
2017-09-27 23:43:45 +02:00
2019-01-19 22:32:25 +01:00
if ( ! ( gDisableStructs [ gActiveBattler ] . mimickedMoves & gBitTable [ i ] )
2018-02-06 02:46:59 +01:00
& & ! ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_TRANSFORMED ) )
2017-09-27 23:43:45 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_PPMOVE1_BATTLE + i , 0 , 1 , & gBattleMons [ gActiveBattler ] . pp [ i ] ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-27 23:43:45 +02:00
}
gBattlescriptCurrInstr + = 5 ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . pp [ i ] = = 0 )
CancelMultiTurnMoves ( gBattlerTarget ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
}
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 )
{
2018-06-30 14:12:17 +02:00
struct Pokemon * party ;
2017-09-27 23:43:45 +02:00
s32 i ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
2018-02-06 23:09:39 +01:00
if ( GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_PLAYER )
2017-09-27 23:43:45 +02:00
party = gPlayerParty ;
else
party = gEnemyParty ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . ability ! = ABILITY_SOUNDPROOF )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status1 = 0 ;
gBattleMons [ gBattlerAttacker ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
RecordAbilityBattle ( gBattlerAttacker , gBattleMons [ gBattlerAttacker ] . ability ) ;
2017-09-27 23:43:45 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] | = 1 ;
}
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattleScripting . battler = GetBattlerAtPosition ( GetBattlerPosition ( gBattlerAttacker ) ^ BIT_FLANK ) ;
2017-09-27 23:43:45 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE
2018-02-06 02:46:59 +01:00
& & ! ( gAbsentBattlerFlags & gBitTable [ gActiveBattler ] ) )
2017-09-27 23:43:45 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . ability ! = ABILITY_SOUNDPROOF )
2017-09-27 23:43:45 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . status1 = 0 ;
gBattleMons [ gActiveBattler ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 02:46:59 +01:00
RecordAbilityBattle ( gActiveBattler , gBattleMons [ gActiveBattler ] . ability ) ;
2017-09-27 23:43:45 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] | = 2 ;
}
}
2018-06-30 14:12:17 +02:00
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2017-09-27 23:43:45 +02:00
{
u16 species = GetMonData ( & party [ i ] , MON_DATA_SPECIES2 ) ;
u8 abilityBit = GetMonData ( & party [ i ] , MON_DATA_ALT_ABILITY ) ;
2018-12-17 18:28:11 +01:00
if ( species ! = SPECIES_NONE & & species ! = SPECIES_EGG )
2017-09-27 23:43:45 +02:00
{
u8 ability ;
2018-02-06 23:09:39 +01:00
if ( gBattlerPartyIndexes [ gBattlerAttacker ] = = i )
ability = gBattleMons [ gBattlerAttacker ] . ability ;
2017-09-27 23:43:45 +02:00
else if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE
2018-02-06 20:48:02 +01:00
& & gBattlerPartyIndexes [ gActiveBattler ] = = i
2018-02-06 02:46:59 +01:00
& & ! ( gAbsentBattlerFlags & gBitTable [ gActiveBattler ] ) )
ability = gBattleMons [ gActiveBattler ] . ability ;
2017-09-27 23:43:45 +02:00
else
ability = GetAbilityBySpecies ( species , abilityBit ) ;
if ( ability ! = ABILITY_SOUNDPROOF )
toHeal | = ( 1 < < i ) ;
}
}
}
else // Aromatherapy
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 4 ;
toHeal = 0x3F ;
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status1 = 0 ;
gBattleMons [ gBattlerAttacker ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
gActiveBattler = GetBattlerAtPosition ( GetBattlerPosition ( gBattlerAttacker ) ^ BIT_FLANK ) ;
2017-09-27 23:43:45 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE
2018-02-06 02:46:59 +01:00
& & ! ( gAbsentBattlerFlags & gBitTable [ gActiveBattler ] ) )
2017-09-27 23:43:45 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . status1 = 0 ;
gBattleMons [ gActiveBattler ] . status2 & = ~ ( STATUS2_NIGHTMARE ) ;
2017-09-27 23:43:45 +02:00
}
}
if ( toHeal )
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , toHeal , 4 , & zero ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-27 23:43:45 +02:00
}
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkAF_cursetarget ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_CURSED )
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerTarget ] . status2 | = STATUS2_CURSED ;
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . maxHP / 2 ;
2017-09-27 23:43:45 +02:00
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
{
2018-02-06 23:09:39 +01:00
u8 targetSide = GetBattlerSide ( gBattlerAttacker ) ^ BIT_SIDE ;
2017-09-27 23:43:45 +02:00
if ( gSideTimers [ targetSide ] . spikesAmount = = 3 )
{
2018-10-14 18:10:54 +02:00
gSpecialStatuses [ gBattlerAttacker ] . ppNotAffectedByPressure = 1 ;
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-01-16 22:12:38 +01:00
gSideStatuses [ targetSide ] | = SIDE_STATUS_SPIKES ;
2017-09-27 23:43:45 +02:00
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
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerTarget ] . status2 | = STATUS2_FORESIGHT ;
2017-09-27 23:43:45 +02:00
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 ;
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-27 23:43:45 +02:00
{
if ( gStatuses3 [ i ] & STATUS3_PERISH_SONG
| | gBattleMons [ i ] . ability = = ABILITY_SOUNDPROOF )
{
notAffectedCount + + ;
}
else
{
gStatuses3 [ i ] | = STATUS3_PERISH_SONG ;
2018-10-14 18:10:54 +02:00
gDisableStructs [ i ] . perishSongTimer = 3 ;
gDisableStructs [ i ] . perishSongTimerStartValue = 3 ;
2017-09-27 23:43:45 +02:00
}
}
2018-02-06 23:09:39 +01:00
PressurePPLoseOnUsingPerishSong ( gBattlerAttacker ) ;
2017-09-27 23:43:45 +02:00
2018-02-06 02:46:59 +01:00
if ( notAffectedCount = = gBattlersCount )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
else
gBattlescriptCurrInstr + = 5 ;
}
2017-09-28 15:34:21 +02:00
static void atkB3_rolloutdamagecalculation ( void )
2017-09-27 23:43:45 +02:00
{
2018-01-16 22:12:38 +01:00
if ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
CancelMultiTurnMoves ( gBattlerAttacker ) ;
2017-11-25 18:42:31 +01:00
gBattlescriptCurrInstr = BattleScript_MoveMissedPause ;
2017-09-27 23:43:45 +02:00
}
else
{
s32 i ;
2018-02-06 23:09:39 +01:00
if ( ! ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_MULTIPLETURNS ) ) // first hit
2017-09-27 23:43:45 +02:00
{
2018-10-14 18:10:54 +02:00
gDisableStructs [ gBattlerAttacker ] . rolloutTimer = 5 ;
gDisableStructs [ gBattlerAttacker ] . rolloutTimerStartValue = 5 ;
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 | = STATUS2_MULTIPLETURNS ;
gLockedMoves [ gBattlerAttacker ] = gCurrentMove ;
2017-09-27 23:43:45 +02:00
}
2018-10-14 18:10:54 +02:00
if ( - - gDisableStructs [ gBattlerAttacker ] . rolloutTimer = = 0 ) // last hit
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 & = ~ ( STATUS2_MULTIPLETURNS ) ;
2017-09-27 23:43:45 +02:00
}
gDynamicBasePower = gBattleMoves [ gCurrentMove ] . power ;
2018-10-14 18:10:54 +02:00
for ( i = 1 ; i < ( 5 - gDisableStructs [ gBattlerAttacker ] . rolloutTimer ) ; i + + )
2017-09-27 23:43:45 +02:00
gDynamicBasePower * = 2 ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_DEFENSE_CURL )
2017-09-27 23:43:45 +02:00
gDynamicBasePower * = 2 ;
gBattlescriptCurrInstr + + ;
}
}
2017-09-28 15:34:21 +02:00
static void atkB4_jumpifconfusedandstatmaxed ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_CONFUSION
& & gBattleMons [ gBattlerTarget ] . statStages [ gBattlescriptCurrInstr [ 1 ] ] = = 0xC )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 2 ) ;
2017-09-27 23:43:45 +02:00
else
gBattlescriptCurrInstr + = 6 ;
}
2017-09-28 15:34:21 +02:00
static void atkB5_furycuttercalc ( void )
2017-09-27 23:43:45 +02:00
{
2018-01-16 22:12:38 +01:00
if ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerAttacker ] . furyCutterCounter = 0 ;
2017-11-25 18:42:31 +01:00
gBattlescriptCurrInstr = BattleScript_MoveMissedPause ;
2017-09-27 23:43:45 +02:00
}
else
{
s32 i ;
2018-02-06 23:09:39 +01:00
if ( gDisableStructs [ gBattlerAttacker ] . furyCutterCounter ! = 5 )
gDisableStructs [ gBattlerAttacker ] . furyCutterCounter + + ;
2017-09-27 23:43:45 +02:00
gDynamicBasePower = gBattleMoves [ gCurrentMove ] . power ;
2018-02-06 23:09:39 +01:00
for ( i = 1 ; i < gDisableStructs [ gBattlerAttacker ] . furyCutterCounter ; i + + )
2017-09-27 23:43:45 +02:00
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 )
2018-02-06 23:09:39 +01:00
gDynamicBasePower = 10 * ( gBattleMons [ gBattlerAttacker ] . friendship ) / 25 ;
2017-09-27 23:43:45 +02:00
else // EFFECT_FRUSTRATION
2018-02-06 23:09:39 +01:00
gDynamicBasePower = 10 * ( 255 - gBattleMons [ gBattlerAttacker ] . friendship ) / 25 ;
2017-09-27 23:43:45 +02:00
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
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . maxHP / 4 ;
2017-09-27 23:43:45 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleMoveDamage * = - 1 ;
}
if ( rand < 204 )
2017-11-25 18:42:31 +01:00
gBattlescriptCurrInstr = BattleScript_HitFromCritCalc ;
2018-02-06 23:09:39 +01:00
else if ( gBattleMons [ gBattlerTarget ] . maxHP = = gBattleMons [ gBattlerTarget ] . hp )
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr = BattleScript_AlreadyAtFullHp ;
else
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags & = ~ ( MOVE_RESULT_DOESNT_AFFECT_FOE ) ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr = BattleScript_PresentHealTarget ;
}
}
2017-11-25 18:42:31 +01:00
static void atkB8_setsafeguard ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gSideStatuses [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] & SIDE_STATUS_SAFEGUARD )
2017-09-27 23:43:45 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-27 23:43:45 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
else
{
2018-02-06 23:09:39 +01:00
gSideStatuses [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] | = SIDE_STATUS_SAFEGUARD ;
gSideTimers [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] . safeguardTimer = 5 ;
2018-02-07 22:53:40 +01:00
gSideTimers [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] . safeguardBattlerId = gBattlerAttacker ;
2017-09-27 23:43:45 +02:00
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 )
2018-02-06 23:09:39 +01:00
for ( gBattlerTarget = 0 ; gBattlerTarget < gBattlersCount ; gBattlerTarget + + )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattlerTarget = = gBattlerAttacker )
2017-09-27 23:43:45 +02:00
continue ;
2018-02-06 23:09:39 +01:00
if ( ! ( gAbsentBattlerFlags & gBitTable [ gBattlerTarget ] ) ) // a valid target was found
2017-09-27 23:43:45 +02:00
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 )
{
2018-02-06 23:09:39 +01:00
if ( GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_PLAYER )
gBattlerTarget = GetBattlerAtPosition ( B_POSITION_OPPONENT_LEFT ) ;
2017-09-27 23:43:45 +02:00
else
2018-02-06 23:09:39 +01:00
gBattlerTarget = GetBattlerAtPosition ( B_POSITION_PLAYER_LEFT ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
if ( GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_PLAYER )
gBattlerTarget = GetBattlerAtPosition ( B_POSITION_OPPONENT_RIGHT ) ;
2017-09-27 23:43:45 +02:00
else
2018-02-06 23:09:39 +01:00
gBattlerTarget = GetBattlerAtPosition ( B_POSITION_PLAYER_RIGHT ) ;
2017-09-27 23:43:45 +02:00
}
2018-02-06 23:09:39 +01:00
if ( gChosenActionByBattler [ gBattlerTarget ] = = B_ACTION_USE_MOVE
& & gBattlerAttacker = = * ( gBattleStruct - > moveTarget + gBattlerTarget )
& & ! ( gBattleMons [ gBattlerTarget ] . status1 & ( STATUS1_SLEEP | STATUS1_FREEZE ) )
& & gBattleMons [ gBattlerAttacker ] . hp
& & ! gDisableStructs [ gBattlerTarget ] . truantCounter
& & gChosenMoveByBattler [ gBattlerTarget ] = = MOVE_PURSUIT )
2017-09-27 23:43:45 +02:00
{
s32 i ;
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-27 23:43:45 +02:00
{
2018-06-28 21:06:32 +02:00
if ( gBattlerByTurnOrder [ i ] = = gBattlerTarget )
2017-10-04 19:25:14 +02:00
gActionsByTurnOrder [ i ] = 11 ;
2017-09-27 23:43:45 +02:00
}
gCurrentMove = MOVE_PURSUIT ;
2018-02-08 11:17:41 +01:00
gCurrMovePos = gChosenMovePos = * ( gBattleStruct - > chosenMovePositions + gBattlerTarget ) ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 5 ;
gBattleScripting . animTurn = 1 ;
gHitMarker & = ~ ( HITMARKER_ATTACKSTRING_PRINTED ) ;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
}
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 )
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-27 23:43:45 +02:00
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
{
2018-02-06 23:09:39 +01:00
u32 halfHp = gBattleMons [ gBattlerAttacker ] . maxHP / 2 ;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
if ( ! ( gBattleMons [ gBattlerAttacker ] . maxHP / 2 ) )
2017-09-27 23:43:45 +02:00
halfHp = 1 ;
2018-02-08 12:13:29 +01:00
if ( gBattleMons [ gBattlerAttacker ] . statStages [ STAT_ATK ] < 12
2018-02-06 23:09:39 +01:00
& & gBattleMons [ gBattlerAttacker ] . hp > halfHp )
2017-09-27 23:43:45 +02:00
{
2018-02-08 12:13:29 +01:00
gBattleMons [ gBattlerAttacker ] . statStages [ STAT_ATK ] = 12 ;
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . maxHP / 2 ;
2017-09-27 23:43:45 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattlescriptCurrInstr + = 5 ;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
}
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 ;
2018-11-18 20:00:36 +01:00
for ( i = 0 ; i < NUM_BATTLE_STATS ; i + + )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . statStages [ i ] = gBattleMons [ gBattlerTarget ] . statStages [ i ] ;
2017-09-27 23:43:45 +02:00
}
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
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_WRAPPED )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleScripting . battler = gBattlerTarget ;
gBattleMons [ gBattlerAttacker ] . status2 & = ~ ( STATUS2_WRAPPED ) ;
gBattlerTarget = * ( gBattleStruct - > wrappedBy + gBattlerAttacker ) ;
2017-09-27 23:43:45 +02:00
gBattleTextBuff1 [ 0 ] = B_BUFF_PLACEHOLDER_BEGIN ;
gBattleTextBuff1 [ 1 ] = B_BUFF_MOVE ;
2018-02-06 23:09:39 +01:00
gBattleTextBuff1 [ 2 ] = * ( gBattleStruct - > wrappedMove + gBattlerAttacker * 2 + 0 ) ;
gBattleTextBuff1 [ 3 ] = * ( gBattleStruct - > wrappedMove + gBattlerAttacker * 2 + 1 ) ;
2017-09-27 23:43:45 +02:00
gBattleTextBuff1 [ 4 ] = B_BUFF_EOS ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_WrapFree ;
}
2018-02-06 23:09:39 +01:00
else if ( gStatuses3 [ gBattlerAttacker ] & STATUS3_LEECHSEED )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] & = ~ ( STATUS3_LEECHSEED ) ;
2018-07-01 11:15:42 +02:00
gStatuses3 [ gBattlerAttacker ] & = ~ ( STATUS3_LEECHSEED_BATTLER ) ;
2017-09-27 23:43:45 +02:00
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_LeechSeedFree ;
}
2018-02-06 23:09:39 +01:00
else if ( gSideStatuses [ GetBattlerSide ( gBattlerAttacker ) ] & SIDE_STATUS_SPIKES )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gSideStatuses [ GetBattlerSide ( gBattlerAttacker ) ] & = ~ ( SIDE_STATUS_SPIKES ) ;
gSideTimers [ GetBattlerSide ( gBattlerAttacker ) ] . spikesAmount = 0 ;
2017-09-27 23:43:45 +02:00
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
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 | = STATUS2_DEFENSE_CURL ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkC0_recoverbasedonsunlight ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattlerTarget = gBattlerAttacker ;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . hp ! = gBattleMons [ gBattlerAttacker ] . maxHP )
2017-09-27 23:43:45 +02:00
{
if ( gBattleWeather = = 0 | | ! WEATHER_HAS_EFFECT )
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . maxHP / 2 ;
2017-09-27 23:43:45 +02:00
else if ( gBattleWeather & WEATHER_SUN_ANY )
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = 20 * gBattleMons [ gBattlerAttacker ] . maxHP / 30 ;
2017-09-27 23:43:45 +02:00
else // not sunny weather
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . maxHP / 4 ;
2017-09-27 23:43:45 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleMoveDamage * = - 1 ;
gBattlescriptCurrInstr + = 5 ;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
}
2017-11-25 18:42:31 +01:00
static void atkC1_hiddenpowercalc ( void )
2017-09-27 23:43:45 +02:00
{
2018-03-01 15:02:44 +01:00
u8 powerBits ;
u8 typeBits ;
2017-09-27 23:43:45 +02:00
2018-03-01 15:02:44 +01:00
powerBits = ( ( gBattleMons [ gBattlerAttacker ] . hpIV & 2 ) > > 1 )
| ( ( gBattleMons [ gBattlerAttacker ] . attackIV & 2 ) < < 0 )
| ( ( gBattleMons [ gBattlerAttacker ] . defenseIV & 2 ) < < 1 )
| ( ( gBattleMons [ gBattlerAttacker ] . speedIV & 2 ) < < 2 )
| ( ( gBattleMons [ gBattlerAttacker ] . spAttackIV & 2 ) < < 3 )
| ( ( gBattleMons [ gBattlerAttacker ] . spDefenseIV & 2 ) < < 4 ) ;
2017-09-27 23:43:45 +02:00
2018-03-01 15:02:44 +01:00
typeBits = ( ( gBattleMons [ gBattlerAttacker ] . hpIV & 1 ) < < 0 )
| ( ( gBattleMons [ gBattlerAttacker ] . attackIV & 1 ) < < 1 )
| ( ( gBattleMons [ gBattlerAttacker ] . defenseIV & 1 ) < < 2 )
| ( ( gBattleMons [ gBattlerAttacker ] . speedIV & 1 ) < < 3 )
| ( ( gBattleMons [ gBattlerAttacker ] . spAttackIV & 1 ) < < 4 )
| ( ( gBattleMons [ gBattlerAttacker ] . spDefenseIV & 1 ) < < 5 ) ;
2017-09-27 23:43:45 +02:00
gDynamicBasePower = ( 40 * powerBits ) / 63 + 30 ;
gBattleStruct - > dynamicMoveType = ( 15 * typeBits ) / 63 + 1 ;
2018-03-01 15:02:44 +01:00
if ( gBattleStruct - > dynamicMoveType > = TYPE_MYSTERY )
2017-09-27 23:43:45 +02:00
gBattleStruct - > dynamicMoveType + + ;
gBattleStruct - > dynamicMoveType | = 0xC0 ;
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atkC2_selectfirstvalidtarget ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
for ( gBattlerTarget = 0 ; gBattlerTarget < gBattlersCount ; gBattlerTarget + + )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattlerTarget = = gBattlerAttacker )
2017-09-27 23:43:45 +02:00
continue ;
2018-02-06 23:09:39 +01:00
if ( ! ( gAbsentBattlerFlags & gBitTable [ gBattlerTarget ] ) )
2017-09-27 23:43:45 +02:00
break ;
}
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atkC3_trysetfutureattack ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gWishFutureKnock . futureSightCounter [ gBattlerTarget ] ! = 0 )
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gSideStatuses [ GET_BATTLER_SIDE ( gBattlerTarget ) ] | = SIDE_STATUS_FUTUREATTACK ;
gWishFutureKnock . futureSightMove [ gBattlerTarget ] = gCurrentMove ;
gWishFutureKnock . futureSightAttacker [ gBattlerTarget ] = gBattlerAttacker ;
gWishFutureKnock . futureSightCounter [ gBattlerTarget ] = 3 ;
gWishFutureKnock . futureSightDmg [ gBattlerTarget ] = CalculateBaseDamage ( & gBattleMons [ gBattlerAttacker ] , & gBattleMons [ gBattlerTarget ] , gCurrentMove ,
gSideStatuses [ GET_BATTLER_SIDE ( gBattlerTarget ) ] , 0 ,
0 , gBattlerAttacker , gBattlerTarget ) ;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
if ( gProtectStructs [ gBattlerAttacker ] . helpingHand )
gWishFutureKnock . futureSightDmg [ gBattlerTarget ] = gWishFutureKnock . futureSightDmg [ gBattlerTarget ] * 15 / 10 ;
2017-09-27 23:43:45 +02:00
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
2018-02-06 23:09:39 +01:00
if ( GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_PLAYER )
2017-09-27 23:43:45 +02:00
party = gPlayerParty ;
else
party = gEnemyParty ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . hp = = 0 )
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
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 )
{
2018-02-06 23:09:39 +01:00
PREPARE_MON_NICK_WITH_PREFIX_BUFFER ( gBattleTextBuff1 , gBattlerAttacker , gBattleCommunication [ 0 ] )
2017-09-27 23:43:45 +02:00
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 ) ;
2018-02-06 23:09:39 +01:00
gBattleMoveDamage / = gBaseStats [ gBattleMons [ gBattlerTarget ] . species ] . baseDefense ;
2017-09-27 23:43:45 +02:00
gBattleMoveDamage = ( gBattleMoveDamage / 50 ) + 2 ;
2018-02-06 23:09:39 +01:00
if ( gProtectStructs [ gBattlerAttacker ] . helpingHand )
2017-09-27 23:43:45 +02:00
gBattleMoveDamage = gBattleMoveDamage * 15 / 10 ;
gBattleCommunication [ 0 ] + + ;
}
else if ( beforeLoop ! = 0 )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
else
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 5 ) ;
2017-09-27 23:43:45 +02:00
}
}
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 :
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] | = STATUS3_ON_AIR ;
2017-09-27 23:43:45 +02:00
break ;
case MOVE_DIG :
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] | = STATUS3_UNDERGROUND ;
2017-09-27 23:43:45 +02:00
break ;
case MOVE_DIVE :
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] | = STATUS3_UNDERWATER ;
2017-09-27 23:43:45 +02:00
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 :
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] & = ~ STATUS3_ON_AIR ;
2017-09-27 23:43:45 +02:00
break ;
case MOVE_DIG :
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] & = ~ STATUS3_UNDERGROUND ;
2017-09-27 23:43:45 +02:00
break ;
case MOVE_DIVE :
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] & = ~ STATUS3_UNDERWATER ;
2017-09-27 23:43:45 +02:00
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 )
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] | = STATUS3_MINIMIZED ;
2017-09-27 23:43:45 +02:00
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 )
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-27 23:43:45 +02:00
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
{
2018-02-08 12:13:29 +01:00
if ( gBattleMons [ gBattlerTarget ] . statStages [ STAT_ATK ] = = 0
& & gBattleMons [ gBattlerTarget ] . statStages [ STAT_SPATK ] = = 0
2017-09-27 23:43:45 +02:00
& & gBattleCommunication [ 6 ] ! = 1 )
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gBattleMons [ gActiveBattler ] . hp ;
2018-02-06 20:48:02 +01:00
BtlController_EmitHealthBarUpdate ( 0 , INSTANT_HP_BAR_DROP ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-27 23:43:45 +02:00
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
{
2018-02-06 23:09:39 +01:00
gSideTimers [ GetBattlerSide ( gBattlerAttacker ) ] . followmeTimer = 1 ;
gSideTimers [ GetBattlerSide ( gBattlerAttacker ) ] . followmeTarget = gBattlerAttacker ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + + ;
}
2017-09-28 15:34:21 +02:00
static void atkCB_setcharge ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] | = STATUS3_CHARGED_UP ;
2018-10-14 18:10:54 +02:00
gDisableStructs [ gBattlerAttacker ] . chargeTimer = 2 ;
2018-10-14 18:37:52 +02:00
gDisableStructs [ gBattlerAttacker ] . chargeTimerStartValue = 2 ;
2017-09-27 23:43:45 +02:00
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 ] ;
2018-02-06 23:09:39 +01:00
gBattlerTarget = GetMoveTarget ( gCurrentMove , 0 ) ;
2017-09-27 23:43:45 +02:00
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
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . status1 & ( STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON ) )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status1 = 0 ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 5 ;
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gActiveBattler ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
}
2017-09-28 15:34:21 +02:00
static void atkCE_settorment ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_TORMENT )
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerTarget ] . status2 | = STATUS2_TORMENT ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 5 ;
}
}
2017-09-28 15:34:21 +02:00
static void atkCF_jumpifnodamage ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gProtectStructs [ gBattlerAttacker ] . physicalDmg | | gProtectStructs [ gBattlerAttacker ] . specialDmg )
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 5 ;
else
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
2017-09-28 15:34:21 +02:00
static void atkD0_settaunt ( void )
2017-09-27 23:43:45 +02:00
{
2018-10-14 18:10:54 +02:00
if ( gDisableStructs [ gBattlerTarget ] . tauntTimer = = 0 )
2017-09-27 23:43:45 +02:00
{
2018-10-14 18:10:54 +02:00
gDisableStructs [ gBattlerTarget ] . tauntTimer = 2 ;
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerTarget ] . tauntTimer2 = 2 ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 5 ;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
}
2017-11-25 18:42:31 +01:00
static void atkD1_trysethelpinghand ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattlerTarget = GetBattlerAtPosition ( GetBattlerPosition ( gBattlerAttacker ) ^ BIT_FLANK ) ;
2017-09-27 23:43:45 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE
2018-02-06 23:09:39 +01:00
& & ! ( gAbsentBattlerFlags & gBitTable [ gBattlerTarget ] )
& & ! gProtectStructs [ gBattlerAttacker ] . helpingHand
& & ! gProtectStructs [ gBattlerTarget ] . helpingHand )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerTarget ] . helpingHand = 1 ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 5 ;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
}
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
2018-09-20 22:00:00 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_TRAINER_HILL
2018-02-06 23:09:39 +01:00
| | ( GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_OPPONENT
2017-09-27 23:43:45 +02:00
& & ! ( gBattleTypeFlags & ( BATTLE_TYPE_LINK
| BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_FRONTIER
| BATTLE_TYPE_SECRET_BASE
| BATTLE_TYPE_x2000000 ) ) ) )
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
u8 sideAttacker = GetBattlerSide ( gBattlerAttacker ) ;
u8 sideTarget = GetBattlerSide ( gBattlerTarget ) ;
2017-09-27 23:43:45 +02:00
// 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 ) )
2018-10-14 18:37:52 +02:00
& & ( gWishFutureKnock . knockedOffMons [ sideAttacker ] & gBitTable [ gBattlerPartyIndexes [ gBattlerAttacker ] ]
| | gWishFutureKnock . knockedOffMons [ sideTarget ] & gBitTable [ gBattlerPartyIndexes [ gBattlerTarget ] ] ) )
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
// can't swap if two pokemon don't have an item
// or if either of them is an enigma berry or a mail
2018-02-06 23:09:39 +01:00
else if ( ( gBattleMons [ gBattlerAttacker ] . item = = 0 & & gBattleMons [ gBattlerTarget ] . item = = 0 )
| | gBattleMons [ gBattlerAttacker ] . item = = ITEM_ENIGMA_BERRY
| | gBattleMons [ gBattlerTarget ] . item = = ITEM_ENIGMA_BERRY
| | IS_ITEM_MAIL ( gBattleMons [ gBattlerAttacker ] . item )
| | IS_ITEM_MAIL ( gBattleMons [ gBattlerTarget ] . item ) )
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
// check if ability prevents swapping
2018-02-06 23:09:39 +01:00
else if ( gBattleMons [ gBattlerTarget ] . ability = = ABILITY_STICKY_HOLD )
2017-09-27 23:43:45 +02:00
{
gBattlescriptCurrInstr = BattleScript_StickyHoldActivates ;
2018-02-06 23:09:39 +01:00
gLastUsedAbility = gBattleMons [ gBattlerTarget ] . ability ;
RecordAbilityBattle ( gBattlerTarget , gLastUsedAbility ) ;
2017-09-27 23:43:45 +02:00
}
// took a while, but all checks passed and items can be safely swapped
else
{
u16 oldItemAtk , * newItemAtk ;
2018-02-06 23:09:39 +01:00
newItemAtk = & gBattleStruct - > changedItems [ gBattlerAttacker ] ;
oldItemAtk = gBattleMons [ gBattlerAttacker ] . item ;
* newItemAtk = gBattleMons [ gBattlerTarget ] . item ;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . item = 0 ;
gBattleMons [ gBattlerTarget ] . item = oldItemAtk ;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_HELDITEM_BATTLE , 0 , 2 , newItemAtk ) ;
2018-02-06 23:09:39 +01:00
MarkBattlerForControllerExec ( gBattlerAttacker ) ;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget ;
BtlController_EmitSetMonData ( 0 , REQUEST_HELDITEM_BATTLE , 0 , 2 , & gBattleMons [ gBattlerTarget ] . item ) ;
MarkBattlerForControllerExec ( gBattlerTarget ) ;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gBattlerTarget ] ) + 0 ) = 0 ;
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gBattlerTarget ] ) + 1 ) = 0 ;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gBattlerAttacker ] ) + 0 ) = 0 ;
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gBattlerAttacker ] ) + 1 ) = 0 ;
2017-09-27 23:43:45 +02:00
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
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . ability ! = 0
& & gBattleMons [ gBattlerTarget ] . ability ! = ABILITY_WONDER_GUARD )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . ability = gBattleMons [ gBattlerTarget ] . ability ;
gLastUsedAbility = gBattleMons [ gBattlerTarget ] . ability ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 5 ;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
}
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
2018-02-06 23:09:39 +01:00
if ( gWishFutureKnock . wishCounter [ gBattlerAttacker ] = = 0 )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gWishFutureKnock . wishCounter [ gBattlerAttacker ] = 2 ;
2018-02-07 22:53:40 +01:00
gWishFutureKnock . wishMonId [ gBattlerAttacker ] = gBattlerPartyIndexes [ gBattlerAttacker ] ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 6 ;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 2 ) ;
2017-09-27 23:43:45 +02:00
}
break ;
case 1 : // heal effect
2018-02-07 22:53:40 +01:00
PREPARE_MON_NICK_WITH_PREFIX_BUFFER ( gBattleTextBuff1 , gBattlerTarget , gWishFutureKnock . wishMonId [ gBattlerTarget ] )
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . maxHP / 2 ;
2017-09-27 23:43:45 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleMoveDamage * = - 1 ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . hp = = gBattleMons [ gBattlerTarget ] . maxHP )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 2 ) ;
2017-09-27 23:43:45 +02:00
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
{
2018-02-06 23:09:39 +01:00
if ( gStatuses3 [ gBattlerAttacker ] & STATUS3_ROOTED )
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] | = STATUS3_ROOTED ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 5 ;
}
}
2017-09-28 15:34:21 +02:00
static void atkD6_doubledamagedealtifdamaged ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( ( gProtectStructs [ gBattlerAttacker ] . physicalDmg
2018-02-07 22:53:40 +01:00
& & gProtectStructs [ gBattlerAttacker ] . physicalBattlerId = = gBattlerTarget )
2018-02-06 23:09:39 +01:00
| | ( gProtectStructs [ gBattlerAttacker ] . specialDmg
2018-02-07 22:53:40 +01:00
& & gProtectStructs [ gBattlerAttacker ] . specialBattlerId = = gBattlerTarget ) )
2017-09-27 23:43:45 +02:00
{
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
{
2018-02-06 23:09:39 +01:00
if ( gStatuses3 [ gBattlerTarget ] & STATUS3_YAWN
| | gBattleMons [ gBattlerTarget ] . status1 & STATUS1_ANY )
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerTarget ] | = 0x1000 ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 5 ;
}
}
2017-09-28 15:34:21 +02:00
static void atkD8_setdamagetohealthdifference ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . hp < = gBattleMons [ gBattlerAttacker ] . hp )
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . hp - gBattleMons [ gBattlerAttacker ] . hp ;
2017-09-27 23:43:45 +02:00
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 ;
2018-02-06 23:09:39 +01:00
gDynamicBasePower = gBattleMons [ gBattlerAttacker ] . hp * power / gBattleMons [ gBattlerAttacker ] . maxHP ;
2017-09-27 23:43:45 +02:00
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
{
2018-02-06 23:09:39 +01:00
if ( ( gBattleMons [ gBattlerAttacker ] . ability = = 0
& & gBattleMons [ gBattlerTarget ] . ability = = 0 )
| | gBattleMons [ gBattlerAttacker ] . ability = = ABILITY_WONDER_GUARD
| | gBattleMons [ gBattlerTarget ] . ability = = ABILITY_WONDER_GUARD
2018-01-16 22:12:38 +01:00
| | gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
u8 abilityAtk = gBattleMons [ gBattlerAttacker ] . ability ;
gBattleMons [ gBattlerAttacker ] . ability = gBattleMons [ gBattlerTarget ] . ability ;
gBattleMons [ gBattlerTarget ] . ability = abilityAtk ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 5 ;
}
}
2019-03-02 23:40:38 +01:00
static void atkDB_tryimprison ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( ( gStatuses3 [ gBattlerAttacker ] & STATUS3_IMPRISONED_OTHERS ) )
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-08 12:13:29 +01:00
u8 battlerId , sideAttacker ;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
sideAttacker = GetBattlerSide ( gBattlerAttacker ) ;
2019-03-02 23:40:38 +01:00
PressurePPLoseOnUsingImprison ( gBattlerAttacker ) ;
2018-02-08 12:13:29 +01:00
for ( battlerId = 0 ; battlerId < gBattlersCount ; battlerId + + )
2017-09-27 23:43:45 +02:00
{
2018-02-08 12:13:29 +01:00
if ( sideAttacker ! = GetBattlerSide ( battlerId ) )
2017-09-27 23:43:45 +02:00
{
s32 attackerMoveId ;
2018-12-25 18:50:15 +01:00
for ( attackerMoveId = 0 ; attackerMoveId < MAX_MON_MOVES ; attackerMoveId + + )
2017-09-27 23:43:45 +02:00
{
s32 i ;
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-27 23:43:45 +02:00
{
2018-02-08 12:13:29 +01:00
if ( gBattleMons [ gBattlerAttacker ] . moves [ attackerMoveId ] = = gBattleMons [ battlerId ] . moves [ i ]
2018-02-06 23:09:39 +01:00
& & gBattleMons [ gBattlerAttacker ] . moves [ attackerMoveId ] ! = MOVE_NONE )
2017-09-27 23:43:45 +02:00
break ;
}
2018-12-25 18:50:15 +01:00
if ( i ! = MAX_MON_MOVES )
2017-09-27 23:43:45 +02:00
break ;
}
2018-12-25 18:50:15 +01:00
if ( attackerMoveId ! = MAX_MON_MOVES )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] | = STATUS3_IMPRISONED_OTHERS ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 5 ;
break ;
}
}
}
2018-02-08 12:13:29 +01:00
if ( battlerId = = gBattlersCount ) // In Generation 3 games, Imprison fails if the user doesn't share any moves with any of the foes
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
}
2017-11-25 18:42:31 +01:00
static void atkDC_trysetgrudge ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gStatuses3 [ gBattlerAttacker ] & STATUS3_GRUDGE )
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] | = STATUS3_GRUDGE ;
2017-09-27 23:43:45 +02:00
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 ;
2018-12-05 15:31:01 +01:00
for ( i = 0 ; sWeightToDamageTable [ i ] ! = 0xFFFF ; i + = 2 )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( sWeightToDamageTable [ i ] > GetPokedexHeightWeight ( SpeciesToNationalPokedexNum ( gBattleMons [ gBattlerTarget ] . species ) , 1 ) )
2017-09-27 23:43:45 +02:00
break ;
}
2018-12-05 15:31:01 +01:00
if ( sWeightToDamageTable [ i ] ! = 0xFFFF )
2017-09-27 23:43:45 +02:00
gDynamicBasePower = sWeightToDamageTable [ i + 1 ] ;
else
gDynamicBasePower = 120 ;
gBattlescriptCurrInstr + + ;
}
2019-04-03 16:36:50 +02:00
static void atkDE_assistattackselect ( void )
2017-09-27 23:43:45 +02:00
{
s32 chooseableMovesNo = 0 ;
struct Pokemon * party ;
s32 monId , moveId ;
u16 * movesArray = gBattleStruct - > assistPossibleMoves ;
2018-02-06 23:09:39 +01:00
if ( GET_BATTLER_SIDE ( gBattlerAttacker ) ! = B_SIDE_PLAYER )
2017-09-27 23:43:45 +02:00
party = gEnemyParty ;
else
party = gPlayerParty ;
for ( monId = 0 ; monId < 6 ; monId + + )
{
2018-02-06 23:09:39 +01:00
if ( monId = = gBattlerPartyIndexes [ gBattlerAttacker ] )
2017-09-27 23:43:45 +02:00
continue ;
if ( GetMonData ( & party [ monId ] , MON_DATA_SPECIES2 ) = = SPECIES_NONE )
continue ;
if ( GetMonData ( & party [ monId ] , MON_DATA_SPECIES2 ) = = SPECIES_EGG )
continue ;
2018-12-25 18:50:15 +01:00
for ( moveId = 0 ; moveId < MAX_MON_MOVES ; moveId + + )
2017-09-27 23:43:45 +02:00
{
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 ) ;
2018-09-22 18:41:00 +02:00
gCalledMove = movesArray [ ( ( Random ( ) & 0xFF ) * chooseableMovesNo ) > > 8 ] ;
gBattlerTarget = GetMoveTarget ( gCalledMove , 0 ) ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 5 ;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
}
2017-11-25 18:42:31 +01:00
static void atkDF_trysetmagiccoat ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattlerTarget = gBattlerAttacker ;
2018-10-14 18:10:54 +02:00
gSpecialStatuses [ gBattlerAttacker ] . ppNotAffectedByPressure = 1 ;
2018-02-06 02:46:59 +01:00
if ( gCurrentTurnActionNumber = = gBattlersCount - 1 ) // moves last turn
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . bounceMove = 1 ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 5 ;
}
}
2017-11-25 18:42:31 +01:00
static void atkE0_trysetsnatch ( void ) // snatch
2017-09-27 23:43:45 +02:00
{
2018-10-14 18:10:54 +02:00
gSpecialStatuses [ gBattlerAttacker ] . ppNotAffectedByPressure = 1 ;
2018-02-06 02:46:59 +01:00
if ( gCurrentTurnActionNumber = = gBattlersCount - 1 ) // moves last turn
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . stealMove = 1 ;
2017-09-27 23:43:45 +02:00
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 ;
2018-07-01 11:15:42 +02:00
gBattleScripting . battler = gBattleStruct - > intimidateBattler ;
2018-02-06 02:46:59 +01:00
side = GetBattlerSide ( gBattleScripting . battler ) ;
2017-09-27 23:43:45 +02:00
2018-02-06 02:46:59 +01:00
PREPARE_ABILITY_BUFFER ( gBattleTextBuff1 , gBattleMons [ gBattleScripting . battler ] . ability )
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
for ( ; gBattlerTarget < gBattlersCount ; gBattlerTarget + + )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( GetBattlerSide ( gBattlerTarget ) = = side )
2017-09-27 23:43:45 +02:00
continue ;
2018-02-06 23:09:39 +01:00
if ( ! ( gAbsentBattlerFlags & gBitTable [ gBattlerTarget ] ) )
2017-09-27 23:43:45 +02:00
break ;
}
2018-02-06 23:09:39 +01:00
if ( gBattlerTarget > = gBattlersCount )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
else
gBattlescriptCurrInstr + = 5 ;
}
2017-11-25 18:42:31 +01:00
static void atkE2_switchoutabilities ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-27 23:43:45 +02:00
2018-02-06 02:46:59 +01:00
switch ( gBattleMons [ gActiveBattler ] . ability )
2017-09-27 23:43:45 +02:00
{
case ABILITY_NATURAL_CURE :
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . status1 = 0 ;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , gBitTable [ * ( gBattleStruct - > field_58 + gActiveBattler ) ] , 4 , & gBattleMons [ gActiveBattler ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-27 23:43:45 +02:00
break ;
}
gBattlescriptCurrInstr + = 2 ;
}
2017-09-28 15:34:21 +02:00
static void atkE3_jumpifhasnohp ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-27 23:43:45 +02:00
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . hp = = 0 )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 2 ) ;
2017-09-27 23:43:45 +02:00
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 ;
2017-12-16 01:08:55 +01:00
case BATTLE_TERRAIN_MOUNTAIN :
2017-09-27 23:43:45 +02:00
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
{
2018-11-17 15:30:34 +01:00
s32 i ;
u16 species , heldItem ;
u8 ability ;
if ( InBattlePike ( ) )
2017-09-27 23:43:45 +02:00
{
2018-11-17 15:30:34 +01:00
}
else if ( InBattlePyramid ( ) )
{
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2017-09-27 23:43:45 +02:00
{
2018-11-17 15:30:34 +01:00
species = GetMonData ( & gPlayerParty [ i ] , MON_DATA_SPECIES2 ) ;
heldItem = GetMonData ( & gPlayerParty [ i ] , MON_DATA_HELD_ITEM ) ;
2017-09-27 23:43:45 +02:00
2018-11-17 15:30:34 +01:00
if ( GetMonData ( & gPlayerParty [ i ] , MON_DATA_ALT_ABILITY ) )
ability = gBaseStats [ species ] . ability2 ;
else
ability = gBaseStats [ species ] . ability1 ;
2017-09-27 23:43:45 +02:00
2018-11-17 15:30:34 +01:00
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 ) ;
2017-09-27 23:43:45 +02:00
}
}
2018-11-17 15:30:34 +01:00
}
else
{
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2017-09-27 23:43:45 +02:00
{
2018-11-17 15:30:34 +01:00
species = GetMonData ( & gPlayerParty [ i ] , MON_DATA_SPECIES2 ) ;
heldItem = GetMonData ( & gPlayerParty [ i ] , MON_DATA_HELD_ITEM ) ;
2017-09-27 23:43:45 +02:00
2018-11-17 15:30:34 +01:00
if ( GetMonData ( & gPlayerParty [ i ] , MON_DATA_ALT_ABILITY ) )
ability = gBaseStats [ species ] . ability2 ;
else
ability = gBaseStats [ species ] . ability1 ;
2017-09-27 23:43:45 +02:00
2018-11-17 15:30:34 +01:00
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 ;
2017-09-27 23:43:45 +02:00
2018-11-17 15:30:34 +01:00
for ( j = 0 ; j < 9 ; j + + )
{
if ( sPickupProbabilities [ j ] > rand )
2017-09-27 23:43:45 +02:00
{
2018-11-17 15:30:34 +01:00
SetMonData ( & gPlayerParty [ i ] , MON_DATA_HELD_ITEM , & sPickupItems [ lvlDivBy10 + j ] ) ;
break ;
}
else if ( rand = = 99 | | rand = = 98 )
{
SetMonData ( & gPlayerParty [ i ] , MON_DATA_HELD_ITEM , & sRarePickupItems [ lvlDivBy10 + ( 99 - rand ) ] ) ;
break ;
2017-09-27 23:43:45 +02:00
}
}
}
}
}
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
{
2018-02-06 02:46:59 +01:00
gActiveBattler = gBattleScripting . battler ;
2017-09-28 15:34:21 +02:00
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_SUBSTITUTE )
2017-09-28 15:34:21 +02:00
* ( & gBattleStruct - > formToChangeInto ) | = 0x80 ;
2018-02-06 20:48:02 +01:00
BtlController_EmitBattleAnimation ( 0 , B_ANIM_CASTFORM_CHANGE , gBattleStruct - > formToChangeInto ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-28 15:34:21 +02:00
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 + + ;
2018-02-06 02:46:59 +01:00
form = CastformDataTypeChange ( gBattleScripting . battler ) ;
2017-09-28 15:34:21 +02:00
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 )
{
2018-02-06 23:09:39 +01:00
if ( ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_MUDSPORT ) )
2017-09-28 15:34:21 +02:00
{
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] | = STATUS3_MUDSPORT ;
2017-09-28 15:34:21 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
worked = TRUE ;
}
}
else // water sport
{
2018-02-06 23:09:39 +01:00
if ( ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_WATERSPORT ) )
2017-09-28 15:34:21 +02:00
{
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] | = STATUS3_WATERSPORT ;
2017-09-28 15:34:21 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
worked = TRUE ;
}
}
if ( worked )
gBattlescriptCurrInstr + = 5 ;
else
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 15:34:21 +02:00
}
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 ;
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-02-06 02:46:59 +01:00
usedHeldItem = & gBattleStruct - > usedHeldItems [ gActiveBattler ] ;
if ( * usedHeldItem ! = 0 & & gBattleMons [ gActiveBattler ] . item = = 0 )
2017-09-28 15:34:21 +02:00
{
gLastUsedItem = * usedHeldItem ;
* usedHeldItem = 0 ;
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . item = gLastUsedItem ;
2017-09-28 15:34:21 +02:00
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData ( 0 , REQUEST_HELDITEM_BATTLE , 0 , 2 , & gBattleMons [ gActiveBattler ] . item ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr + = 5 ;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 15:34:21 +02:00
}
}
static void atkEB_settypetoterrain ( void )
{
2018-03-01 00:59:52 +01:00
if ( ! IS_BATTLER_OF_TYPE ( gBattlerAttacker , sTerrainToType [ gBattleTerrain ] ) )
2017-09-28 15:34:21 +02:00
{
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE ( gBattlerAttacker , sTerrainToType [ gBattleTerrain ] ) ;
PREPARE_TYPE_BUFFER ( gBattleTextBuff1 , sTerrainToType [ gBattleTerrain ] ) ;
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr + = 5 ;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 15:34:21 +02:00
}
}
2017-11-25 18:42:31 +01:00
static void atkEC_pursuitrelated ( void )
2017-09-28 15:34:21 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = GetBattlerAtPosition ( GetBattlerPosition ( gBattlerAttacker ) ^ BIT_FLANK ) ;
2017-09-28 15:34:21 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE
2018-02-06 02:46:59 +01:00
& & ! ( gAbsentBattlerFlags & gBitTable [ gActiveBattler ] )
2018-02-06 23:09:39 +01:00
& & gChosenActionByBattler [ gActiveBattler ] = = 0
& & gChosenMoveByBattler [ gActiveBattler ] = = MOVE_PURSUIT )
2017-09-28 15:34:21 +02:00
{
2018-02-06 02:46:59 +01:00
gActionsByTurnOrder [ gActiveBattler ] = 11 ;
2017-09-28 15:34:21 +02:00
gCurrentMove = MOVE_PURSUIT ;
gBattlescriptCurrInstr + = 5 ;
gBattleScripting . animTurn = 1 ;
2018-02-06 23:09:39 +01:00
gBattleScripting . field_20 = gBattlerAttacker ;
gBattlerAttacker = gActiveBattler ;
2017-09-28 15:34:21 +02:00
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 15:34:21 +02:00
}
}
2018-06-30 14:12:17 +02:00
static void atkEF_snatchsetbattlers ( void )
2017-09-28 15:34:21 +02:00
{
2018-02-08 11:17:41 +01:00
gEffectBattler = gBattlerAttacker ;
2017-09-28 15:34:21 +02:00
2018-02-06 23:09:39 +01:00
if ( gBattlerAttacker = = gBattlerTarget )
gBattlerAttacker = gBattlerTarget = gBattleScripting . battler ;
2017-09-28 15:34:21 +02:00
else
2018-02-06 23:09:39 +01:00
gBattlerTarget = gBattleScripting . battler ;
2017-09-28 15:34:21 +02:00
2018-02-08 11:17:41 +01:00
gBattleScripting . battler = gEffectBattler ;
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr + + ;
}
static void atkEE_removelightscreenreflect ( void ) // brick break
{
2018-02-06 23:09:39 +01:00
u8 opposingSide = GetBattlerSide ( gBattlerAttacker ) ^ BIT_SIDE ;
2017-09-28 15:34:21 +02:00
if ( gSideTimers [ opposingSide ] . reflectTimer | | gSideTimers [ opposingSide ] . lightscreenTimer )
{
2018-01-16 22:12:38 +01:00
gSideStatuses [ opposingSide ] & = ~ ( SIDE_STATUS_REFLECT ) ;
gSideStatuses [ opposingSide ] & = ~ ( SIDE_STATUS_LIGHTSCREEN ) ;
2017-09-28 15:34:21 +02:00
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 ;
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-09-28 15:34:21 +02:00
return ;
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
gBattlerTarget = gBattlerAttacker ^ BIT_SIDE ;
2017-09-28 15:34:21 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_TRAINER )
{
2018-02-06 20:48:02 +01:00
BtlController_EmitBallThrowAnim ( 0 , BALL_TRAINER_BLOCK ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr = BattleScript_TrainerBallBlock ;
}
else if ( gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL )
{
2018-02-06 20:48:02 +01:00
BtlController_EmitBallThrowAnim ( 0 , BALL_3_SHAKES_SUCCESS ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr = BattleScript_WallyBallThrow ;
}
else
{
u32 odds ;
u8 catchRate ;
if ( gLastUsedItem = = ITEM_SAFARI_BALL )
2018-07-01 11:15:42 +02:00
catchRate = gBattleStruct - > safariCatchFactor * 1275 / 100 ;
2017-09-28 15:34:21 +02:00
else
2018-02-06 23:09:39 +01:00
catchRate = gBaseStats [ gBattleMons [ gBattlerTarget ] . species ] . catchRate ;
2017-09-28 15:34:21 +02:00
if ( gLastUsedItem > ITEM_SAFARI_BALL )
{
switch ( gLastUsedItem )
{
case ITEM_NET_BALL :
2018-03-01 00:59:52 +01:00
if ( IS_BATTLER_OF_TYPE ( gBattlerTarget , TYPE_WATER ) | | IS_BATTLER_OF_TYPE ( gBattlerTarget , TYPE_BUG ) )
2017-09-28 15:34:21 +02:00
ballMultiplier = 30 ;
else
ballMultiplier = 10 ;
break ;
case ITEM_DIVE_BALL :
2018-12-27 23:30:47 +01:00
if ( GetCurrentMapType ( ) = = MAP_TYPE_UNDERWATER )
2017-09-28 15:34:21 +02:00
ballMultiplier = 35 ;
else
ballMultiplier = 10 ;
break ;
case ITEM_NEST_BALL :
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . level < 40 )
2017-09-28 15:34:21 +02:00
{
2018-02-06 23:09:39 +01:00
ballMultiplier = 40 - gBattleMons [ gBattlerTarget ] . level ;
2017-09-28 15:34:21 +02:00
if ( ballMultiplier < = 9 )
ballMultiplier = 10 ;
}
else
{
ballMultiplier = 10 ;
}
break ;
case ITEM_REPEAT_BALL :
2018-02-06 23:09:39 +01:00
if ( GetSetPokedexFlag ( SpeciesToNationalPokedexNum ( gBattleMons [ gBattlerTarget ] . species ) , FLAG_GET_CAUGHT ) )
2017-09-28 15:34:21 +02:00
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 )
2018-02-06 23:09:39 +01:00
* ( gBattleMons [ gBattlerTarget ] . maxHP * 3 - gBattleMons [ gBattlerTarget ] . hp * 2 )
/ ( 3 * gBattleMons [ gBattlerTarget ] . maxHP ) ;
2017-09-28 15:34:21 +02:00
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status1 & ( STATUS1_SLEEP | STATUS1_FREEZE ) )
2017-09-28 15:34:21 +02:00
odds * = 2 ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status1 & ( STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON ) )
2017-09-28 15:34:21 +02:00
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
{
2018-02-06 20:48:02 +01:00
BtlController_EmitBallThrowAnim ( 0 , BALL_3_SHAKES_SUCCESS ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr = BattleScript_SuccessBallThrow ;
2018-02-06 23:09:39 +01:00
SetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerTarget ] ] , MON_DATA_POKEBALL , & gLastUsedItem ) ;
2017-09-28 15:34:21 +02:00
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?
2018-02-06 20:48:02 +01:00
BtlController_EmitBallThrowAnim ( 0 , shakes ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-28 15:34:21 +02:00
if ( shakes = = BALL_3_SHAKES_SUCCESS ) // mon caught, copy of the code above
{
gBattlescriptCurrInstr = BattleScript_SuccessBallThrow ;
2018-02-06 23:09:39 +01:00
SetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerTarget ] ] , MON_DATA_POKEBALL , & gLastUsedItem ) ;
2017-09-28 15:34:21 +02:00
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
{
2018-02-06 23:09:39 +01:00
if ( GiveMonToPlayer ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] ) ! = MON_GIVEN_TO_PARTY )
2017-09-28 15:34:21 +02:00
{
if ( ! sub_813B21C ( ) )
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
StringCopy ( gStringVar1 , GetBoxNamePtr ( VarGet ( VAR_STORAGE_UNKNOWN ) ) ) ;
2018-02-06 23:09:39 +01:00
GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] , MON_DATA_NICKNAME , gStringVar2 ) ;
2017-09-28 15:34:21 +02:00
}
else
{
StringCopy ( gStringVar1 , GetBoxNamePtr ( VarGet ( VAR_STORAGE_UNKNOWN ) ) ) ;
2018-02-06 23:09:39 +01:00
GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] , MON_DATA_NICKNAME , gStringVar2 ) ;
2017-09-28 15:34:21 +02:00
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 ] + + ;
}
2018-02-06 23:09:39 +01:00
gBattleResults . caughtMonSpecies = GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] , MON_DATA_SPECIES , NULL ) ;
GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] , MON_DATA_NICKNAME , gBattleResults . caughtMonNick ) ;
gBattleResults . caughtMonBall = GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] , MON_DATA_POKEBALL , NULL ) ;
2017-09-28 15:34:21 +02:00
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 ) )
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 15:34:21 +02:00
}
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 :
2019-04-04 23:05:46 +02:00
BeginNormalPaletteFade ( 0xFFFFFFFF , 0 , 0 , 0x10 , RGB_BLACK ) ;
2017-09-28 15:34:21 +02:00
gBattleCommunication [ 0 ] + + ;
break ;
case 1 :
if ( ! gPaletteFade . active )
{
FreeAllWindowBuffers ( ) ;
gBattleCommunication [ TASK_ID ] = CreateDexDisplayMonDataTask ( SpeciesToNationalPokedexNum ( species ) ,
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerTarget ] . otId ,
gBattleMons [ gBattlerTarget ] . personality ) ;
2017-09-28 15:34:21 +02:00
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 ( ) )
{
2019-04-04 23:05:46 +02:00
BeginNormalPaletteFade ( 0xFFFF , 0 , 0x10 , 0 , RGB_BLACK ) ;
2017-09-28 15:34:21 +02:00
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 ) ;
2018-06-17 16:48:58 +02:00
BattlePutTextOnWindow ( 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 )
{
2018-02-06 23:09:39 +01:00
GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] , MON_DATA_NICKNAME , gBattleStruct - > caughtMonNick ) ;
2017-09-28 15:34:21 +02:00
FreeAllWindowBuffers ( ) ;
DoNamingScreen ( NAMING_SCREEN_CAUGHT_MON , gBattleStruct - > caughtMonNick ,
2018-02-06 23:09:39 +01:00
GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] , MON_DATA_SPECIES ) ,
GetMonGender ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] ) ,
GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] , MON_DATA_PERSONALITY , NULL ) ,
2017-09-28 15:34:21 +02:00
BattleMainCB2 ) ;
gBattleCommunication [ MULTIUSE_STATE ] + + ;
}
break ;
case 3 :
if ( gMain . callback2 = = BattleMainCB2 & & ! gPaletteFade . active )
{
2018-02-06 23:09:39 +01:00
SetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] , MON_DATA_NICKNAME , gBattleStruct - > caughtMonNick ) ;
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 15:34:21 +02:00
}
break ;
case 4 :
if ( CalculatePlayerPartyCount ( ) = = 6 )
gBattlescriptCurrInstr + = 5 ;
else
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 15:34:21 +02:00
break ;
}
}
static void atkF4_subattackerhpbydmg ( void )
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . hp - = gBattleMoveDamage ;
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr + + ;
}
static void atkF5_removeattackerstatus1 ( void )
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status1 = 0 ;
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr + + ;
}
2017-11-25 18:42:31 +01:00
static void atkF6_finishaction ( void )
2017-09-28 15:34:21 +02:00
{
2018-02-06 23:09:39 +01:00
gCurrentActionFuncId = B_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
{
2018-02-06 23:09:39 +01:00
gCurrentActionFuncId = B_ACTION_FINISHED ;
2018-02-06 02:46:59 +01:00
gCurrentTurnActionNumber = gBattlersCount ;
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
{
2018-02-06 02:46:59 +01:00
gActiveBattler = GetBattlerAtPosition ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitTrainerSlideBack ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr + = 2 ;
}