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-07-27 23:40:10 +02:00
# include "constants/battle_config.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"
2019-10-18 01:22:03 +02:00
# include "constants/party_menu.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
// this file's functions
2019-03-31 15:19:25 +02:00
# define STAT_CHANGE_WORKED 0
# define STAT_CHANGE_DIDNT_WORK 1
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.
2019-02-14 13:17:27 +01:00
static u32 ChangeStatBuffs ( s8 statValue , u32 statId , u32 flags , const u8 * BS_ptr ) ;
2017-09-28 15:34:21 +02:00
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 ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_attackcanceler ( void ) ;
static void Cmd_accuracycheck ( void ) ;
static void Cmd_attackstring ( void ) ;
static void Cmd_ppreduce ( void ) ;
static void Cmd_critcalc ( void ) ;
static void Cmd_damagecalc ( void ) ;
static void Cmd_typecalc ( void ) ;
2019-11-10 12:09:14 +01:00
static void Cmd_adjustdamage ( void ) ;
static void Cmd_multihitresultmessage ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_attackanimation ( void ) ;
static void Cmd_waitanimation ( void ) ;
static void Cmd_healthbarupdate ( void ) ;
static void Cmd_datahpupdate ( void ) ;
static void Cmd_critmessage ( void ) ;
static void Cmd_effectivenesssound ( void ) ;
static void Cmd_resultmessage ( void ) ;
static void Cmd_printstring ( void ) ;
static void Cmd_printselectionstring ( void ) ;
static void Cmd_waitmessage ( void ) ;
static void Cmd_printfromtable ( void ) ;
static void Cmd_printselectionstringfromtable ( void ) ;
static void Cmd_seteffectwithchance ( void ) ;
static void Cmd_seteffectprimary ( void ) ;
static void Cmd_seteffectsecondary ( void ) ;
static void Cmd_clearstatusfromeffect ( void ) ;
static void Cmd_tryfaintmon ( void ) ;
static void Cmd_dofaintanimation ( void ) ;
static void Cmd_cleareffectsonfaint ( void ) ;
static void Cmd_jumpifstatus ( void ) ;
static void Cmd_jumpifstatus2 ( void ) ;
static void Cmd_jumpifability ( void ) ;
static void Cmd_jumpifsideaffecting ( void ) ;
static void Cmd_jumpifstat ( void ) ;
static void Cmd_jumpifstatus3condition ( void ) ;
2019-11-10 12:09:14 +01:00
static void Cmd_jumpbasedontype ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_getexp ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk24 ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_movevaluescleanup ( void ) ;
static void Cmd_setmultihit ( void ) ;
static void Cmd_decrementmultihit ( void ) ;
static void Cmd_goto ( void ) ;
static void Cmd_jumpifbyte ( void ) ;
static void Cmd_jumpifhalfword ( void ) ;
static void Cmd_jumpifword ( void ) ;
static void Cmd_jumpifarrayequal ( void ) ;
static void Cmd_jumpifarraynotequal ( void ) ;
static void Cmd_setbyte ( void ) ;
static void Cmd_addbyte ( void ) ;
static void Cmd_subbyte ( void ) ;
static void Cmd_copyarray ( void ) ;
static void Cmd_copyarraywithindex ( void ) ;
static void Cmd_orbyte ( void ) ;
static void Cmd_orhalfword ( void ) ;
static void Cmd_orword ( void ) ;
static void Cmd_bicbyte ( void ) ;
static void Cmd_bichalfword ( void ) ;
static void Cmd_bicword ( void ) ;
static void Cmd_pause ( void ) ;
static void Cmd_waitstate ( void ) ;
2019-11-10 12:09:14 +01:00
static void Cmd_update ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_return ( void ) ;
static void Cmd_end ( void ) ;
static void Cmd_end2 ( void ) ;
static void Cmd_end3 ( void ) ;
static void Cmd_jumpifaffectedbyprotect ( void ) ;
static void Cmd_call ( void ) ;
2019-11-10 12:09:14 +01:00
static void Cmd_setroost ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_jumpifabilitypresent ( void ) ;
static void Cmd_endselectionscript ( void ) ;
static void Cmd_playanimation ( void ) ;
static void Cmd_playanimation2 ( void ) ;
static void Cmd_setgraphicalstatchangevalues ( void ) ;
static void Cmd_playstatchangeanimation ( void ) ;
static void Cmd_moveend ( void ) ;
2019-11-10 12:09:14 +01:00
static void Cmd_sethealblock ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_returnatktoball ( void ) ;
static void Cmd_getswitchedmondata ( void ) ;
static void Cmd_switchindataupdate ( void ) ;
static void Cmd_switchinanim ( void ) ;
static void Cmd_jumpifcantswitch ( void ) ;
static void Cmd_openpartyscreen ( void ) ;
static void Cmd_switchhandleorder ( void ) ;
static void Cmd_switchineffects ( void ) ;
static void Cmd_trainerslidein ( void ) ;
static void Cmd_playse ( void ) ;
static void Cmd_fanfare ( void ) ;
static void Cmd_playfaintcry ( void ) ;
2017-09-28 15:34:21 +02:00
static void atk57 ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_returntoball ( void ) ;
static void Cmd_handlelearnnewmove ( void ) ;
static void Cmd_yesnoboxlearnmove ( void ) ;
static void Cmd_yesnoboxstoplearningmove ( void ) ;
static void Cmd_hitanimation ( void ) ;
static void Cmd_getmoneyreward ( void ) ;
2017-11-25 18:42:31 +01:00
static void atk5E ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_swapattackerwithtarget ( void ) ;
static void Cmd_incrementgamestat ( void ) ;
static void Cmd_drawpartystatussummary ( void ) ;
static void Cmd_hidepartystatussummary ( void ) ;
static void Cmd_jumptocalledmove ( void ) ;
static void Cmd_statusanimation ( void ) ;
static void Cmd_status2animation ( void ) ;
static void Cmd_chosenstatusanimation ( void ) ;
static void Cmd_yesnobox ( void ) ;
static void Cmd_cancelallactions ( void ) ;
2019-11-10 12:09:14 +01:00
static void Cmd_setgravity ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_removeitem ( void ) ;
static void Cmd_atknameinbuff1 ( void ) ;
static void Cmd_drawlvlupbox ( void ) ;
static void Cmd_resetsentmonsvalue ( void ) ;
static void Cmd_setatktoplayer0 ( void ) ;
static void Cmd_makevisible ( void ) ;
2019-11-10 12:09:14 +01:00
static void Cmd_recordability ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_buffermovetolearn ( void ) ;
static void Cmd_jumpifplayerran ( void ) ;
static void Cmd_hpthresholds ( void ) ;
static void Cmd_hpthresholds2 ( void ) ;
static void Cmd_useitemonopponent ( void ) ;
static void Cmd_various ( void ) ;
static void Cmd_setprotectlike ( void ) ;
static void Cmd_faintifabilitynotdamp ( void ) ;
static void Cmd_setatkhptozero ( void ) ;
static void Cmd_jumpifnexttargetvalid ( void ) ;
static void Cmd_tryhealhalfhealth ( void ) ;
static void Cmd_trymirrormove ( void ) ;
static void Cmd_setrain ( void ) ;
static void Cmd_setreflect ( void ) ;
static void Cmd_setseeded ( void ) ;
static void Cmd_manipulatedamage ( void ) ;
static void Cmd_trysetrest ( void ) ;
static void Cmd_jumpifnotfirstturn ( void ) ;
2019-11-10 12:09:14 +01:00
static void Cmd_setmiracleeye ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_jumpifcantmakeasleep ( void ) ;
static void Cmd_stockpile ( void ) ;
static void Cmd_stockpiletobasedamage ( void ) ;
static void Cmd_stockpiletohpheal ( void ) ;
2019-11-10 12:09:14 +01:00
static void Cmd_setdrainedhp ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_statbuffchange ( void ) ;
static void Cmd_normalisebuffs ( void ) ;
static void Cmd_setbide ( void ) ;
static void Cmd_confuseifrepeatingattackends ( void ) ;
static void Cmd_setmultihitcounter ( void ) ;
static void Cmd_initmultihitstring ( void ) ;
static void Cmd_forcerandomswitch ( void ) ;
static void Cmd_tryconversiontypechange ( void ) ;
static void Cmd_givepaydaymoney ( void ) ;
static void Cmd_setlightscreen ( void ) ;
static void Cmd_tryKO ( void ) ;
static void Cmd_damagetohalftargethp ( void ) ;
static void Cmd_setsandstorm ( void ) ;
static void Cmd_weatherdamage ( void ) ;
static void Cmd_tryinfatuating ( void ) ;
static void Cmd_updatestatusicon ( void ) ;
static void Cmd_setmist ( void ) ;
static void Cmd_setfocusenergy ( void ) ;
static void Cmd_transformdataexecution ( void ) ;
static void Cmd_setsubstitute ( void ) ;
static void Cmd_mimicattackcopy ( void ) ;
static void Cmd_metronome ( void ) ;
static void Cmd_dmgtolevel ( void ) ;
static void Cmd_psywavedamageeffect ( void ) ;
static void Cmd_counterdamagecalculator ( void ) ;
static void Cmd_mirrorcoatdamagecalculator ( void ) ;
static void Cmd_disablelastusedattack ( void ) ;
static void Cmd_trysetencore ( void ) ;
static void Cmd_painsplitdmgcalc ( void ) ;
static void Cmd_settypetorandomresistance ( void ) ;
static void Cmd_setalwayshitflag ( void ) ;
static void Cmd_copymovepermanently ( void ) ;
static void Cmd_trychoosesleeptalkmove ( void ) ;
static void Cmd_setdestinybond ( void ) ;
static void Cmd_trysetdestinybondtohappen ( void ) ;
2019-11-10 12:09:14 +01:00
static void Cmd_settailwind ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_tryspiteppreduce ( void ) ;
static void Cmd_healpartystatus ( void ) ;
static void Cmd_cursetarget ( void ) ;
static void Cmd_trysetspikes ( void ) ;
static void Cmd_setforesight ( void ) ;
static void Cmd_trysetperishsong ( void ) ;
2019-11-10 12:09:14 +01:00
static void Cmd_handlerollout ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_jumpifconfusedandstatmaxed ( void ) ;
2019-11-10 12:09:14 +01:00
static void Cmd_handlefurycutter ( void ) ;
static void Cmd_setembargo ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_presentdamagecalculation ( void ) ;
static void Cmd_setsafeguard ( void ) ;
static void Cmd_magnitudedamagecalculation ( void ) ;
static void Cmd_jumpifnopursuitswitchdmg ( void ) ;
static void Cmd_setsunny ( void ) ;
static void Cmd_maxattackhalvehp ( void ) ;
static void Cmd_copyfoestats ( void ) ;
static void Cmd_rapidspinfree ( void ) ;
static void Cmd_setdefensecurlbit ( void ) ;
static void Cmd_recoverbasedonsunlight ( void ) ;
2019-11-10 12:09:14 +01:00
static void Cmd_setstickyweb ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_selectfirstvalidtarget ( void ) ;
static void Cmd_trysetfutureattack ( void ) ;
static void Cmd_trydobeatup ( void ) ;
static void Cmd_setsemiinvulnerablebit ( void ) ;
static void Cmd_clearsemiinvulnerablebit ( void ) ;
static void Cmd_setminimize ( void ) ;
static void Cmd_sethail ( void ) ;
static void Cmd_jumpifattackandspecialattackcannotfall ( void ) ;
static void Cmd_setforcedtarget ( void ) ;
static void Cmd_setcharge ( void ) ;
static void Cmd_callterrainattack ( void ) ;
static void Cmd_cureifburnedparalysedorpoisoned ( void ) ;
static void Cmd_settorment ( void ) ;
static void Cmd_jumpifnodamage ( void ) ;
static void Cmd_settaunt ( void ) ;
static void Cmd_trysethelpinghand ( void ) ;
static void Cmd_tryswapitems ( void ) ;
static void Cmd_trycopyability ( void ) ;
static void Cmd_trywish ( void ) ;
2019-11-10 12:09:14 +01:00
static void Cmd_settoxicspikes ( void ) ;
static void Cmd_setgastroacid ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_setyawn ( void ) ;
static void Cmd_setdamagetohealthdifference ( void ) ;
2019-11-10 12:09:14 +01:00
static void Cmd_setroom ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_tryswapabilities ( void ) ;
static void Cmd_tryimprison ( void ) ;
2019-11-10 12:09:14 +01:00
static void Cmd_setstealthrock ( void ) ;
static void Cmd_setuserstatus3 ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_assistattackselect ( void ) ;
static void Cmd_trysetmagiccoat ( void ) ;
static void Cmd_trysetsnatch ( void ) ;
static void Cmd_trygetintimidatetarget ( void ) ;
static void Cmd_switchoutabilities ( void ) ;
static void Cmd_jumpifhasnohp ( void ) ;
static void Cmd_getsecretpowereffect ( void ) ;
static void Cmd_pickup ( void ) ;
static void Cmd_docastformchangeanimation ( void ) ;
static void Cmd_trycastformdatachange ( void ) ;
static void Cmd_settypebasedhalvers ( void ) ;
2019-11-10 12:09:14 +01:00
static void Cmd_jumpifsubstituteblocks ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_tryrecycleitem ( void ) ;
static void Cmd_settypetoterrain ( void ) ;
static void Cmd_pursuitrelated ( void ) ;
static void Cmd_snatchsetbattlers ( void ) ;
static void Cmd_removelightscreenreflect ( void ) ;
static void Cmd_handleballthrow ( void ) ;
static void Cmd_givecaughtmon ( void ) ;
static void Cmd_trysetcaughtmondexflags ( void ) ;
static void Cmd_displaydexinfo ( void ) ;
static void Cmd_trygivecaughtmonnick ( void ) ;
static void Cmd_subattackerhpbydmg ( void ) ;
static void Cmd_removeattackerstatus1 ( void ) ;
static void Cmd_finishaction ( void ) ;
static void Cmd_finishturn ( void ) ;
static void Cmd_trainerslideout ( void ) ;
2019-11-10 12:09:14 +01:00
static void Cmd_settelekinesis ( void ) ;
static void Cmd_swapstatstages ( void ) ;
static void Cmd_averagestats ( void ) ;
static void Cmd_jumpifoppositegenders ( void ) ;
static void Cmd_trygetbaddreamstarget ( void ) ;
static void Cmd_tryworryseed ( void ) ;
static void Cmd_metalburstdamagecalculator ( void ) ;
2017-09-04 15:05:11 +02:00
void ( * const gBattleScriptingCommandsTable [ ] ) ( void ) =
{
2019-11-10 12:09:14 +01:00
Cmd_attackcanceler , // 0x0
Cmd_accuracycheck , // 0x1
Cmd_attackstring , // 0x2
Cmd_ppreduce , // 0x3
Cmd_critcalc , // 0x4
Cmd_damagecalc , // 0x5
Cmd_typecalc , // 0x6
Cmd_adjustdamage , // 0x7
Cmd_multihitresultmessage , // 0x8
Cmd_attackanimation , // 0x9
Cmd_waitanimation , // 0xA
Cmd_healthbarupdate , // 0xB
Cmd_datahpupdate , // 0xC
Cmd_critmessage , // 0xD
Cmd_effectivenesssound , // 0xE
Cmd_resultmessage , // 0xF
Cmd_printstring , // 0x10
Cmd_printselectionstring , // 0x11
Cmd_waitmessage , // 0x12
Cmd_printfromtable , // 0x13
Cmd_printselectionstringfromtable , // 0x14
Cmd_seteffectwithchance , // 0x15
Cmd_seteffectprimary , // 0x16
Cmd_seteffectsecondary , // 0x17
Cmd_clearstatusfromeffect , // 0x18
Cmd_tryfaintmon , // 0x19
Cmd_dofaintanimation , // 0x1A
Cmd_cleareffectsonfaint , // 0x1B
Cmd_jumpifstatus , // 0x1C
Cmd_jumpifstatus2 , // 0x1D
Cmd_jumpifability , // 0x1E
Cmd_jumpifsideaffecting , // 0x1F
Cmd_jumpifstat , // 0x20
Cmd_jumpifstatus3condition , // 0x21
Cmd_jumpbasedontype , // 0x22
Cmd_getexp , // 0x23
atk24 , // 0x24
Cmd_movevaluescleanup , // 0x25
Cmd_setmultihit , // 0x26
Cmd_decrementmultihit , // 0x27
Cmd_goto , // 0x28
Cmd_jumpifbyte , // 0x29
Cmd_jumpifhalfword , // 0x2A
Cmd_jumpifword , // 0x2B
Cmd_jumpifarrayequal , // 0x2C
Cmd_jumpifarraynotequal , // 0x2D
Cmd_setbyte , // 0x2E
Cmd_addbyte , // 0x2F
Cmd_subbyte , // 0x30
Cmd_copyarray , // 0x31
Cmd_copyarraywithindex , // 0x32
Cmd_orbyte , // 0x33
Cmd_orhalfword , // 0x34
Cmd_orword , // 0x35
Cmd_bicbyte , // 0x36
Cmd_bichalfword , // 0x37
Cmd_bicword , // 0x38
Cmd_pause , // 0x39
Cmd_waitstate , // 0x3A
Cmd_update , // 0x3B
Cmd_return , // 0x3C
Cmd_end , // 0x3D
Cmd_end2 , // 0x3E
Cmd_end3 , // 0x3F
Cmd_jumpifaffectedbyprotect , // 0x40
Cmd_call , // 0x41
Cmd_setroost , // 0x42
Cmd_jumpifabilitypresent , // 0x43
Cmd_endselectionscript , // 0x44
Cmd_playanimation , // 0x45
Cmd_playanimation2 , // 0x46
Cmd_setgraphicalstatchangevalues , // 0x47
Cmd_playstatchangeanimation , // 0x48
Cmd_moveend , // 0x49
Cmd_sethealblock , // 0x4A
Cmd_returnatktoball , // 0x4B
Cmd_getswitchedmondata , // 0x4C
Cmd_switchindataupdate , // 0x4D
Cmd_switchinanim , // 0x4E
Cmd_jumpifcantswitch , // 0x4F
Cmd_openpartyscreen , // 0x50
Cmd_switchhandleorder , // 0x51
Cmd_switchineffects , // 0x52
Cmd_trainerslidein , // 0x53
Cmd_playse , // 0x54
Cmd_fanfare , // 0x55
Cmd_playfaintcry , // 0x56
atk57 , // 0x57
Cmd_returntoball , // 0x58
Cmd_handlelearnnewmove , // 0x59
Cmd_yesnoboxlearnmove , // 0x5A
Cmd_yesnoboxstoplearningmove , // 0x5B
Cmd_hitanimation , // 0x5C
Cmd_getmoneyreward , // 0x5D
atk5E , // 0x5E
Cmd_swapattackerwithtarget , // 0x5F
Cmd_incrementgamestat , // 0x60
Cmd_drawpartystatussummary , // 0x61
Cmd_hidepartystatussummary , // 0x62
Cmd_jumptocalledmove , // 0x63
Cmd_statusanimation , // 0x64
Cmd_status2animation , // 0x65
Cmd_chosenstatusanimation , // 0x66
Cmd_yesnobox , // 0x67
Cmd_cancelallactions , // 0x68
Cmd_setgravity , // 0x69
Cmd_removeitem , // 0x6A
Cmd_atknameinbuff1 , // 0x6B
Cmd_drawlvlupbox , // 0x6C
Cmd_resetsentmonsvalue , // 0x6D
Cmd_setatktoplayer0 , // 0x6E
Cmd_makevisible , // 0x6F
Cmd_recordability , // 0x70
Cmd_buffermovetolearn , // 0x71
Cmd_jumpifplayerran , // 0x72
Cmd_hpthresholds , // 0x73
Cmd_hpthresholds2 , // 0x74
Cmd_useitemonopponent , // 0x75
Cmd_various , // 0x76
Cmd_setprotectlike , // 0x77
Cmd_faintifabilitynotdamp , // 0x78
Cmd_setatkhptozero , // 0x79
Cmd_jumpifnexttargetvalid , // 0x7A
Cmd_tryhealhalfhealth , // 0x7B
Cmd_trymirrormove , // 0x7C
Cmd_setrain , // 0x7D
Cmd_setreflect , // 0x7E
Cmd_setseeded , // 0x7F
Cmd_manipulatedamage , // 0x80
Cmd_trysetrest , // 0x81
Cmd_jumpifnotfirstturn , // 0x82
Cmd_setmiracleeye , // 0x83
Cmd_jumpifcantmakeasleep , // 0x84
Cmd_stockpile , // 0x85
Cmd_stockpiletobasedamage , // 0x86
Cmd_stockpiletohpheal , // 0x87
Cmd_setdrainedhp , // 0x88
Cmd_statbuffchange , // 0x89
Cmd_normalisebuffs , // 0x8A
Cmd_setbide , // 0x8B
Cmd_confuseifrepeatingattackends , // 0x8C
Cmd_setmultihitcounter , // 0x8D
Cmd_initmultihitstring , // 0x8E
Cmd_forcerandomswitch , // 0x8F
Cmd_tryconversiontypechange , // 0x90
Cmd_givepaydaymoney , // 0x91
Cmd_setlightscreen , // 0x92
Cmd_tryKO , // 0x93
Cmd_damagetohalftargethp , // 0x94
Cmd_setsandstorm , // 0x95
Cmd_weatherdamage , // 0x96
Cmd_tryinfatuating , // 0x97
Cmd_updatestatusicon , // 0x98
Cmd_setmist , // 0x99
Cmd_setfocusenergy , // 0x9A
Cmd_transformdataexecution , // 0x9B
Cmd_setsubstitute , // 0x9C
Cmd_mimicattackcopy , // 0x9D
Cmd_metronome , // 0x9E
Cmd_dmgtolevel , // 0x9F
Cmd_psywavedamageeffect , // 0xA0
Cmd_counterdamagecalculator , // 0xA1
Cmd_mirrorcoatdamagecalculator , // 0xA2
Cmd_disablelastusedattack , // 0xA3
Cmd_trysetencore , // 0xA4
Cmd_painsplitdmgcalc , // 0xA5
Cmd_settypetorandomresistance , // 0xA6
Cmd_setalwayshitflag , // 0xA7
Cmd_copymovepermanently , // 0xA8
Cmd_trychoosesleeptalkmove , // 0xA9
Cmd_setdestinybond , // 0xAA
Cmd_trysetdestinybondtohappen , // 0xAB
Cmd_settailwind , // 0xAC
Cmd_tryspiteppreduce , // 0xAD
Cmd_healpartystatus , // 0xAE
Cmd_cursetarget , // 0xAF
Cmd_trysetspikes , // 0xB0
Cmd_setforesight , // 0xB1
Cmd_trysetperishsong , // 0xB2
Cmd_handlerollout , // 0xB3
Cmd_jumpifconfusedandstatmaxed , // 0xB4
Cmd_handlefurycutter , // 0xB5
Cmd_setembargo , // 0xB6
Cmd_presentdamagecalculation , // 0xB7
Cmd_setsafeguard , // 0xB8
Cmd_magnitudedamagecalculation , // 0xB9
Cmd_jumpifnopursuitswitchdmg , // 0xBA
Cmd_setsunny , // 0xBB
Cmd_maxattackhalvehp , // 0xBC
Cmd_copyfoestats , // 0xBD
Cmd_rapidspinfree , // 0xBE
Cmd_setdefensecurlbit , // 0xBF
Cmd_recoverbasedonsunlight , // 0xC0
Cmd_setstickyweb , // 0xC1
Cmd_selectfirstvalidtarget , // 0xC2
Cmd_trysetfutureattack , // 0xC3
Cmd_trydobeatup , // 0xC4
Cmd_setsemiinvulnerablebit , // 0xC5
Cmd_clearsemiinvulnerablebit , // 0xC6
Cmd_setminimize , // 0xC7
Cmd_sethail , // 0xC8
Cmd_jumpifattackandspecialattackcannotfall , // 0xC9
Cmd_setforcedtarget , // 0xCA
Cmd_setcharge , // 0xCB
Cmd_callterrainattack , // 0xCC
Cmd_cureifburnedparalysedorpoisoned , // 0xCD
Cmd_settorment , // 0xCE
Cmd_jumpifnodamage , // 0xCF
Cmd_settaunt , // 0xD0
Cmd_trysethelpinghand , // 0xD1
Cmd_tryswapitems , // 0xD2
Cmd_trycopyability , // 0xD3
Cmd_trywish , // 0xD4
Cmd_settoxicspikes , // 0xD5
Cmd_setgastroacid , // 0xD6
Cmd_setyawn , // 0xD7
Cmd_setdamagetohealthdifference , // 0xD8
Cmd_setroom , // 0xD9
Cmd_tryswapabilities , // 0xDA
Cmd_tryimprison , // 0xDB
Cmd_setstealthrock , // 0xDC
Cmd_setuserstatus3 , // 0xDD
Cmd_assistattackselect , // 0xDE
Cmd_trysetmagiccoat , // 0xDF
Cmd_trysetsnatch , // 0xE0
Cmd_trygetintimidatetarget , // 0xE1
Cmd_switchoutabilities , // 0xE2
Cmd_jumpifhasnohp , // 0xE3
Cmd_getsecretpowereffect , // 0xE4
Cmd_pickup , // 0xE5
Cmd_docastformchangeanimation , // 0xE6
Cmd_trycastformdatachange , // 0xE7
Cmd_settypebasedhalvers , // 0xE8
Cmd_jumpifsubstituteblocks , // 0xE9
Cmd_tryrecycleitem , // 0xEA
Cmd_settypetoterrain , // 0xEB
Cmd_pursuitrelated , // 0xEC
Cmd_snatchsetbattlers , // 0xED
Cmd_removelightscreenreflect , // 0xEE
Cmd_handleballthrow , // 0xEF
Cmd_givecaughtmon , // 0xF0
Cmd_trysetcaughtmondexflags , // 0xF1
Cmd_displaydexinfo , // 0xF2
Cmd_trygivecaughtmonnick , // 0xF3
Cmd_subattackerhpbydmg , // 0xF4
Cmd_removeattackerstatus1 , // 0xF5
Cmd_finishaction , // 0xF6
Cmd_finishturn , // 0xF7
Cmd_trainerslideout , // 0xF8
Cmd_settelekinesis , // 0xF9
Cmd_swapstatstages , // 0xFA
Cmd_averagestats , // 0xFB
Cmd_jumpifoppositegenders , // 0xFC
Cmd_trygetbaddreamstarget , // 0xFD
Cmd_tryworryseed , // 0xFE
Cmd_metalburstdamagecalculator , // 0xFF
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
} ;
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
[ 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_UPROAR ] = BattleScript_MoveEffectUproar ,
[ MOVE_EFFECT_PAYDAY ] = BattleScript_MoveEffectPayDay ,
[ MOVE_EFFECT_WRAP ] = BattleScript_MoveEffectWrap ,
[ MOVE_EFFECT_RECOIL_25 ] = BattleScript_MoveEffectRecoil ,
[ 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
# 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 ,
2019-12-04 21:25:13 +01:00
. affineMode = ST_OAM_AFFINE_OFF ,
. objMode = ST_OAM_OBJ_NORMAL ,
2017-09-28 16:32:23 +02:00
. mosaic = 0 ,
2019-12-04 21:25:13 +01:00
. bpp = ST_OAM_4BPP ,
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
# define METRONOME_FORBIDDEN_END 0xFFFF
# define ASSIST_FORBIDDEN_END 0xFFFF
2018-09-22 18:37:03 +02:00
# define COPYCAT_FORBIDDEN_END 0xFFFF
2019-04-20 21:11:49 +02:00
# define INSTRUCT_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-09 13:12:02 +01:00
MOVE_TRANSFORM ,
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 ,
2018-12-09 13:12:02 +01:00
MOVE_CIRCLE_THROW ,
MOVE_DRAGON_TAIL ,
MOVE_RAGE_POWDER ,
MOVE_MAT_BLOCK ,
MOVE_SPIKY_SHIELD ,
MOVE_SHELL_TRAP ,
MOVE_SPOTLIGHT ,
MOVE_FEINT ,
MOVE_KING_S_SHIELD ,
2018-12-08 04:33:41 +01:00
METRONOME_FORBIDDEN_END
2017-09-28 16:32:23 +02:00
} ;
2019-04-20 21:11:49 +02:00
static const u16 sMoveEffectsForbiddenToInstruct [ ] =
2019-05-02 23:10:01 +02:00
{
2019-04-20 21:11:49 +02:00
EFFECT_ASSIST ,
//EFFECT_BEAK_BLAST,
EFFECT_BIDE ,
EFFECT_FOCUS_PUNCH ,
//EFFECT_GEOMANCY,
EFFECT_INSTRUCT ,
EFFECT_ME_FIRST ,
EFFECT_METRONOME ,
EFFECT_MIRROR_MOVE ,
EFFECT_NATURE_POWER ,
EFFECT_PLACEHOLDER ,
EFFECT_RECHARGE ,
EFFECT_SEMI_INVULNERABLE ,
//EFFECT_SHELL_TRAP,
EFFECT_SKETCH ,
//EFFECT_SKY_DROP,
EFFECT_SKULL_BASH ,
EFFECT_SLEEP_TALK ,
EFFECT_SOLARBEAM ,
EFFECT_TRANSFORM ,
EFFECT_TWO_TURNS_ATTACK ,
INSTRUCT_FORBIDDEN_END
} ;
2017-09-28 16:32:23 +02:00
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
} ;
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
2018-10-06 15:50:35 +02:00
bool32 IsBattlerProtected ( u8 battlerId , u16 move )
{
if ( ! ( gBattleMoves [ move ] . flags & FLAG_PROTECT_AFFECTED ) )
return FALSE ;
2018-11-24 19:37:10 +01:00
else if ( gBattleMoves [ move ] . effect = = MOVE_EFFECT_FEINT )
return FALSE ;
2018-10-06 15:50:35 +02:00
else if ( gProtectStructs [ battlerId ] . protected )
return TRUE ;
2018-12-22 15:10:24 +01:00
else if ( gSideStatuses [ GetBattlerSide ( battlerId ) ] & SIDE_STATUS_WIDE_GUARD
2018-10-06 15:50:35 +02:00
& & gBattleMoves [ move ] . target & ( MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY ) )
return TRUE ;
else if ( gProtectStructs [ battlerId ] . banefulBunkered )
return TRUE ;
else if ( gProtectStructs [ battlerId ] . spikyShielded )
return TRUE ;
else if ( gProtectStructs [ battlerId ] . kingsShielded & & gBattleMoves [ move ] . power ! = 0 )
return TRUE ;
2018-12-22 15:10:24 +01:00
else if ( gSideStatuses [ GetBattlerSide ( battlerId ) ] & SIDE_STATUS_QUICK_GUARD
2019-02-16 14:54:17 +01:00
& & GetChosenMovePriority ( gBattlerAttacker ) > 0 )
2018-10-06 15:50:35 +02:00
return TRUE ;
2019-02-01 14:34:16 +01:00
else if ( gSideStatuses [ GetBattlerSide ( battlerId ) ] & SIDE_STATUS_CRAFTY_SHIELD
& & gBattleMoves [ move ] . power = = 0 )
return TRUE ;
2019-03-31 18:17:13 +02:00
else if ( gSideStatuses [ GetBattlerSide ( battlerId ) ] & SIDE_STATUS_MAT_BLOCK
& & gBattleMoves [ move ] . power ! = 0 )
return TRUE ;
2018-10-06 15:50:35 +02:00
else
return FALSE ;
}
2019-08-22 15:57:33 +02:00
static bool32 NoTargetPresent ( u32 move )
{
if ( ! IsBattlerAlive ( gBattlerTarget ) )
gBattlerTarget = GetMoveTarget ( move , 0 ) ;
switch ( gBattleMoves [ move ] . target )
{
case MOVE_TARGET_SELECTED :
case MOVE_TARGET_DEPENDS :
case MOVE_TARGET_RANDOM :
if ( ! IsBattlerAlive ( gBattlerTarget ) )
return TRUE ;
break ;
case MOVE_TARGET_BOTH :
if ( ! IsBattlerAlive ( gBattlerTarget ) & & ! IsBattlerAlive ( BATTLE_PARTNER ( gBattlerTarget ) ) )
return TRUE ;
break ;
case MOVE_TARGET_FOES_AND_ALLY :
if ( ! IsBattlerAlive ( gBattlerTarget ) & & ! IsBattlerAlive ( BATTLE_PARTNER ( gBattlerTarget ) ) & & ! IsBattlerAlive ( BATTLE_PARTNER ( gBattlerAttacker ) ) )
return TRUE ;
break ;
}
return FALSE ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_attackcanceler ( void )
2017-09-19 21:01:12 +02:00
{
2019-08-22 15:57:33 +02:00
s32 i , moveType ;
2017-09-19 21:01:12 +02:00
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-11-30 21:21:43 +01:00
// Check Protean activation.
GET_MOVE_TYPE ( gCurrentMove , moveType ) ;
if ( GetBattlerAbility ( gBattlerAttacker ) = = ABILITY_PROTEAN
& & ( gBattleMons [ gBattlerAttacker ] . type1 ! = moveType | | gBattleMons [ gBattlerAttacker ] . type2 ! = moveType | |
( gBattleMons [ gBattlerAttacker ] . type3 ! = moveType & & gBattleMons [ gBattlerAttacker ] . type3 ! = TYPE_MYSTERY ) )
& & gCurrentMove ! = MOVE_STRUGGLE )
{
PREPARE_TYPE_BUFFER ( gBattleTextBuff1 , moveType ) ;
SET_BATTLER_TYPE ( gBattlerAttacker , moveType ) ;
2019-02-04 12:43:20 +01:00
gBattlerAbility = gBattlerAttacker ;
2018-11-30 21:21:43 +01:00
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_ProteanActivates ;
return ;
}
2018-12-01 11:35:49 +01:00
if ( AtkCanceller_UnableToUseMove2 ( ) )
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
{
2019-08-22 15:57:33 +02:00
switch ( IsMonDisobedient ( ) )
2017-09-19 21:01:12 +02:00
{
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 ;
2019-08-22 15:57:33 +02:00
if ( NoTargetPresent ( gCurrentMove ) )
{
gBattlescriptCurrInstr = BattleScript_ButItFailedAtkStringPpReduce ;
return ;
}
2018-07-28 10:41:20 +02:00
if ( gProtectStructs [ gBattlerTarget ] . bounceMove
& & gBattleMoves [ gCurrentMove ] . flags & FLAG_MAGICCOAT_AFFECTED
& & ! gProtectStructs [ gBattlerAttacker ] . usesBouncedMove )
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 ;
2018-07-28 10:41:20 +02:00
gProtectStructs [ gBattlerTarget ] . usesBouncedMove = 1 ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_MagicCoatBounce ;
return ;
}
else if ( GetBattlerAbility ( gBattlerTarget ) = = ABILITY_MAGIC_BOUNCE
& & gBattleMoves [ gCurrentMove ] . flags & FLAG_MAGICCOAT_AFFECTED
& & ! gProtectStructs [ gBattlerAttacker ] . usesBouncedMove )
{
RecordAbilityBattle ( gBattlerTarget , ABILITY_MAGIC_BOUNCE ) ;
gProtectStructs [ gBattlerTarget ] . usesBouncedMove = 1 ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
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-07-22 19:34:13 +02:00
RecordAbilityBattle ( gBattlerTarget , gLastUsedAbility ) ;
}
else if ( gSpecialStatuses [ gBattlerTarget ] . stormDrainRedirected )
{
gSpecialStatuses [ gBattlerTarget ] . stormDrainRedirected = 0 ;
gLastUsedAbility = ABILITY_STORM_DRAIN ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_TookAttack ;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle ( gBattlerTarget , gLastUsedAbility ) ;
2017-09-19 21:01:12 +02:00
}
2018-10-06 15:50:35 +02:00
else if ( IsBattlerProtected ( gBattlerTarget , gCurrentMove )
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 + + ;
}
}
2018-07-22 18:40:18 +02:00
static bool32 JumpIfMoveFailed ( u8 adder , u16 move )
2017-09-19 21:01:12 +02:00
{
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-07-22 18:40:18 +02:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
return TRUE ;
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 ) )
2018-07-22 18:40:18 +02:00
return TRUE ;
2017-09-19 21:01:12 +02:00
}
2018-07-22 18:40:18 +02:00
gBattlescriptCurrInstr + = adder ;
return FALSE ;
2017-09-19 21:01:12 +02:00
}
2019-08-23 13:55:36 +02:00
static void Cmd_jumpifaffectedbyprotect ( void )
2017-09-19 21:01:12 +02:00
{
2018-10-06 15:50:35 +02:00
if ( IsBattlerProtected ( gBattlerTarget , gCurrentMove ) )
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-10-06 15:50:35 +02:00
if ( IsBattlerProtected ( gBattlerTarget , move ) )
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 ;
}
2018-07-22 18:40:18 +02:00
static bool32 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-07-22 15:08:32 +02:00
else if ( gBattleMoves [ move ] . effect = = EFFECT_TOXIC & & IS_BATTLER_OF_TYPE ( gBattlerAttacker , TYPE_POISON ) )
{
JumpIfMoveFailed ( 7 , move ) ;
return TRUE ;
}
2018-07-22 18:40:18 +02:00
else if ( GetBattlerAbility ( gBattlerAttacker ) = = ABILITY_NO_GUARD )
{
if ( ! JumpIfMoveFailed ( 7 , move ) )
RecordAbilityBattle ( gBattlerAttacker , ABILITY_NO_GUARD ) ;
return TRUE ;
}
else if ( GetBattlerAbility ( gBattlerTarget ) = = ABILITY_NO_GUARD )
{
if ( ! JumpIfMoveFailed ( 7 , move ) )
RecordAbilityBattle ( gBattlerTarget , ABILITY_NO_GUARD ) ;
return TRUE ;
}
2017-09-19 21:01:12 +02:00
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 ;
2018-12-08 16:19:50 +01:00
if ( gStatuses3 [ gBattlerTarget ] & STATUS3_PHANTOM_FORCE )
{
gMoveResultFlags | = MOVE_RESULT_MISSED ;
JumpIfMoveFailed ( 7 , move ) ;
return TRUE ;
}
2019-08-05 11:39:31 +02:00
if ( ( WEATHER_HAS_EFFECT & &
( ( ( gBattleWeather & WEATHER_RAIN_ANY ) & & ( gBattleMoves [ move ] . effect = = EFFECT_THUNDER | | gBattleMoves [ move ] . effect = = EFFECT_HURRICANE ) )
| | ( ( ( gBattleWeather & WEATHER_HAIL_ANY ) & & move = = MOVE_BLIZZARD ) ) ) )
2018-08-11 12:16:00 +02:00
| | ( gBattleMoves [ move ] . effect = = EFFECT_VITAL_THROW )
| | ( gBattleMoves [ move ] . accuracy = = 0 ) )
2017-09-19 21:01:12 +02:00
{
JumpIfMoveFailed ( 7 , move ) ;
return TRUE ;
}
return FALSE ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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-01 22:39:42 +02:00
if ( move = = ACC_CURR_MOVE )
move = gCurrentMove ;
2018-08-11 12:16:00 +02:00
if ( move = = NO_ACC_CALC_CHECK_LOCK_ON )
2017-09-19 21:01:12 +02:00
{
2018-07-30 20:41:16 +02:00
if ( gStatuses3 [ gBattlerTarget ] & STATUS3_ALWAYS_HITS & & gDisableStructs [ gBattlerTarget ] . battlerWithSureHit = = gBattlerAttacker )
2017-09-19 21:01:12 +02:00
gBattlescriptCurrInstr + = 7 ;
2018-07-30 20:41:16 +02:00
else if ( gStatuses3 [ gBattlerTarget ] & ( STATUS3_SEMI_INVULNERABLE ) )
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-07-22 15:08:32 +02:00
u8 type , moveAcc , atkHoldEffect , atkParam , defHoldEffect , defParam , atkAbility , defAbility ;
s8 buff , accStage , evasionStage ;
u32 calc ;
2017-09-19 21:01:12 +02:00
GET_MOVE_TYPE ( move , type ) ;
if ( JumpIfMoveAffectedByProtect ( move ) )
return ;
if ( AccuracyCalcHelper ( move ) )
return ;
2018-07-22 15:08:32 +02:00
atkAbility = GetBattlerAbility ( gBattlerAttacker ) ;
defAbility = GetBattlerAbility ( gBattlerTarget ) ;
accStage = gBattleMons [ gBattlerAttacker ] . statStages [ STAT_ACC ] ;
evasionStage = gBattleMons [ gBattlerTarget ] . statStages [ STAT_EVASION ] ;
if ( atkAbility = = ABILITY_UNAWARE )
evasionStage = 6 ;
if ( gBattleMoves [ move ] . flags & FLAG_STAT_STAGES_IGNORED )
evasionStage = 6 ;
if ( defAbility = = ABILITY_UNAWARE )
accStage = 6 ;
if ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_FORESIGHT | | gStatuses3 [ gBattlerTarget ] & STATUS3_MIRACLE_EYED )
buff = accStage ;
2017-09-19 21:01:12 +02:00
else
2018-07-22 15:08:32 +02:00
buff = accStage + 6 - evasionStage ;
2017-09-19 21:01:12 +02:00
if ( buff < 0 )
buff = 0 ;
if ( buff > 0xC )
buff = 0xC ;
moveAcc = gBattleMoves [ move ] . accuracy ;
2018-08-05 13:39:22 +02:00
// Check Thunder and Hurricane on sunny weather.
if ( WEATHER_HAS_EFFECT & & gBattleWeather & WEATHER_SUN_ANY & & ( gBattleMoves [ move ] . effect = = EFFECT_THUNDER | | gBattleMoves [ move ] . effect = = EFFECT_HURRICANE ) )
2017-09-19 21:01:12 +02:00
moveAcc = 50 ;
2018-07-26 21:56:23 +02:00
// Check Wonder Skin.
if ( defAbility = = ABILITY_WONDER_SKIN & & gBattleMoves [ move ] . power = = 0 )
moveAcc = 50 ;
2017-09-19 21:01:12 +02:00
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-07-22 15:08:32 +02:00
if ( atkAbility = = ABILITY_COMPOUND_EYES )
2017-09-19 21:01:12 +02:00
calc = ( calc * 130 ) / 100 ; // 1.3 compound eyes boost
2018-07-22 15:08:32 +02:00
else if ( atkAbility = = ABILITY_VICTORY_STAR )
calc = ( calc * 110 ) / 100 ; // 1.1 victory star boost
if ( IsBattlerAlive ( BATTLE_PARTNER ( gBattlerAttacker ) ) & & GetBattlerAbility ( BATTLE_PARTNER ( gBattlerAttacker ) ) = = ABILITY_VICTORY_STAR )
calc = ( calc * 110 ) / 100 ; // 1.1 ally's victory star boost
if ( defAbility = = ABILITY_SAND_VEIL & & WEATHER_HAS_EFFECT & & gBattleWeather & WEATHER_SANDSTORM_ANY )
2017-09-19 21:01:12 +02:00
calc = ( calc * 80 ) / 100 ; // 1.2 sand veil loss
2018-07-22 15:08:32 +02:00
else if ( defAbility = = ABILITY_SNOW_CLOAK & & WEATHER_HAS_EFFECT & & gBattleWeather & WEATHER_HAIL_ANY )
calc = ( calc * 80 ) / 100 ; // 1.2 snow cloak loss
else if ( defAbility = = ABILITY_TANGLED_FEET & & gBattleMons [ gBattlerTarget ] . status2 & STATUS2_CONFUSION )
calc = ( calc * 50 ) / 100 ; // 1.5 tangled feet loss
2018-07-16 22:45:06 +02:00
2018-07-22 15:08:32 +02:00
if ( atkAbility = = ABILITY_HUSTLE & & IS_MOVE_PHYSICAL ( move ) )
2017-09-19 21:01:12 +02:00
calc = ( calc * 80 ) / 100 ; // 1.2 hustle loss
2018-07-22 15:08:32 +02:00
defHoldEffect = GetBattlerHoldEffect ( gBattlerTarget , TRUE ) ;
defParam = GetBattlerHoldEffectParam ( gBattlerTarget ) ;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerTarget ;
2017-09-19 21:01:12 +02:00
2018-07-22 15:08:32 +02:00
atkHoldEffect = GetBattlerHoldEffect ( gBattlerAttacker , TRUE ) ;
atkParam = GetBattlerHoldEffectParam ( gBattlerAttacker ) ;
if ( defHoldEffect = = HOLD_EFFECT_EVASION_UP )
calc = ( calc * ( 100 - defParam ) ) / 100 ;
if ( atkHoldEffect = = HOLD_EFFECT_WIDE_LENS )
calc = ( calc * ( 100 + atkParam ) ) / 100 ;
else if ( atkHoldEffect = = HOLD_EFFECT_ZOOM_LENS & & GetBattlerTurnOrderNum ( gBattlerAttacker ) > GetBattlerTurnOrderNum ( gBattlerTarget ) ) ;
calc = ( calc * ( 100 + atkParam ) ) / 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 ;
2019-02-24 10:04:21 +01:00
if ( gBattleMoves [ move ] . power )
CalcTypeEffectivenessMultiplier ( move , type , gBattlerAttacker , gBattlerTarget , TRUE ) ;
2017-09-19 21:01:12 +02:00
}
JumpIfMoveFailed ( 7 , move ) ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
2019-08-23 13:55:36 +02:00
static void Cmd_ppreduce ( void )
2017-09-20 00:28:00 +02:00
{
2019-03-31 21:38:58 +02:00
s32 i , 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 :
2019-03-31 21:38:58 +02:00
for ( i = 0 ; i < gBattlersCount ; i + + )
{
if ( i ! = gBattlerAttacker & & IsBattlerAlive ( i ) )
ppToDeduct + = ( GetBattlerAbility ( i ) = = ABILITY_PRESSURE ) ;
}
2017-09-20 00:28:00 +02:00
break ;
case MOVE_TARGET_BOTH :
case MOVE_TARGET_OPPONENTS_FIELD :
2019-03-31 21:38:58 +02:00
for ( i = 0 ; i < gBattlersCount ; i + + )
{
if ( GetBattlerSide ( i ) ! = GetBattlerSide ( gBattlerAttacker ) & & IsBattlerAlive ( i ) )
ppToDeduct + = ( GetBattlerAbility ( i ) = = ABILITY_PRESSURE ) ;
}
2017-09-20 00:28:00 +02:00
break ;
default :
2019-03-31 21:38:58 +02:00
if ( gBattlerAttacker ! = gBattlerTarget & & GetBattlerAbility ( gBattlerTarget ) = = 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 + + ;
}
2019-05-07 15:26:58 +02:00
// The chance is 1/N for each stage.
# if B_CRIT_CHANCE == GEN_7
static const u8 sCriticalHitChance [ ] = { 24 , 8 , 2 , 1 , 1 } ;
# elif B_CRIT_CHANCE == GEN_6
static const u8 sCriticalHitChance [ ] = { 16 , 8 , 2 , 1 , 1 } ;
# else
static const u8 sCriticalHitChance [ ] = { 16 , 8 , 4 , 3 , 2 } ; // Gens 2,3,4,5
# endif // B_CRIT_CHANCE
2018-07-23 21:36:05 +02:00
s32 CalcCritChanceStage ( u8 battlerAtk , u8 battlerDef , u32 move , bool32 recordAbility )
2017-09-20 00:28:00 +02:00
{
2018-07-23 21:36:05 +02:00
s32 critChance = 0 ;
u32 abilityAtk = GetBattlerAbility ( gBattlerAttacker ) ;
u32 abilityDef = GetBattlerAbility ( gBattlerTarget ) ;
2017-09-20 00:28:00 +02:00
2018-07-23 21:36:05 +02:00
if ( gSideStatuses [ battlerDef ] & SIDE_STATUS_LUCKY_CHANT
| | gStatuses3 [ gBattlerAttacker ] & STATUS3_CANT_SCORE_A_CRIT )
{
critChance = - 1 ;
}
else if ( abilityDef = = ABILITY_BATTLE_ARMOR | | abilityDef = = ABILITY_SHELL_ARMOR )
{
if ( recordAbility )
RecordAbilityBattle ( battlerDef , abilityDef ) ;
critChance = - 1 ;
}
else if ( gStatuses3 [ battlerAtk ] & STATUS3_LASER_FOCUS
| | gBattleMoves [ move ] . effect = = EFFECT_ALWAYS_CRIT
| | ( abilityAtk = = ABILITY_MERCILESS & & gBattleMons [ battlerDef ] . status1 & STATUS1_PSN_ANY ) )
{
2018-07-23 22:18:56 +02:00
critChance = - 2 ;
2018-07-23 21:36:05 +02:00
}
2017-09-20 00:28:00 +02:00
else
2018-07-23 21:36:05 +02:00
{
u32 holdEffectAtk = GetBattlerHoldEffect ( battlerAtk , TRUE ) ;
critChance = 2 * ( ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_FOCUS_ENERGY ) ! = 0 )
+ ( ( gBattleMoves [ gCurrentMove ] . flags & FLAG_HIGH_CRIT ) ! = 0 )
+ ( holdEffectAtk = = HOLD_EFFECT_SCOPE_LENS )
+ 2 * ( holdEffectAtk = = HOLD_EFFECT_LUCKY_PUNCH & & gBattleMons [ gBattlerAttacker ] . species = = SPECIES_CHANSEY )
+ 2 * ( holdEffectAtk = = HOLD_EFFECT_STICK & & gBattleMons [ gBattlerAttacker ] . species = = SPECIES_FARFETCHD )
+ ( abilityAtk = = ABILITY_SUPER_LUCK ) ;
2017-09-20 00:28:00 +02:00
2019-05-07 15:26:58 +02:00
if ( critChance > = ARRAY_COUNT ( sCriticalHitChance ) )
critChance = ARRAY_COUNT ( sCriticalHitChance ) - 1 ;
}
2017-09-20 00:28:00 +02:00
2018-07-23 21:36:05 +02:00
return critChance ;
}
2019-11-10 12:09:14 +01:00
static void Cmd_critcalc ( void )
2018-07-23 21:36:05 +02:00
{
s32 critChance = CalcCritChanceStage ( gBattlerAttacker , gBattlerTarget , gCurrentMove , TRUE ) ;
gPotentialItemEffectBattler = gBattlerAttacker ;
if ( gBattleTypeFlags & ( BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_FIRST_BATTLE ) )
gIsCriticalHit = FALSE ;
else if ( critChance = = - 1 )
gIsCriticalHit = FALSE ;
2018-07-23 22:18:56 +02:00
else if ( critChance = = - 2 )
gIsCriticalHit = TRUE ;
2018-07-27 23:40:10 +02:00
else if ( Random ( ) % sCriticalHitChance [ critChance ] = = 0 )
2018-07-14 22:56:03 +02:00
gIsCriticalHit = TRUE ;
2017-09-20 00:28:00 +02:00
else
2018-07-14 22:56:03 +02:00
gIsCriticalHit = FALSE ;
2017-09-20 00:28:00 +02:00
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_damagecalc ( void )
2017-09-20 00:28:00 +02:00
{
2018-07-14 19:29:25 +02:00
u8 moveType ;
2017-09-20 00:28:00 +02:00
2018-07-14 19:29:25 +02:00
GET_MOVE_TYPE ( gCurrentMove , moveType ) ;
2019-04-02 00:14:01 +02:00
gBattleMoveDamage = CalculateMoveDamage ( gCurrentMove , gBattlerAttacker , gBattlerTarget , moveType , 0 , gIsCriticalHit , TRUE , TRUE ) ;
2017-09-20 00:28:00 +02:00
gBattlescriptCurrInstr + + ;
}
2019-11-10 12:09:14 +01:00
static void Cmd_typecalc ( void )
2017-09-20 00:28:00 +02:00
{
u8 moveType ;
GET_MOVE_TYPE ( gCurrentMove , moveType ) ;
2018-07-15 12:39:07 +02:00
CalcTypeEffectivenessMultiplier ( gCurrentMove , moveType , gBattlerAttacker , gBattlerTarget , TRUE ) ;
2017-09-20 00:28:00 +02:00
gBattlescriptCurrInstr + + ;
}
2019-11-10 12:09:14 +01:00
static void Cmd_adjustdamage ( 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
2018-08-02 20:24:18 +02:00
if ( DoesSubstituteBlockMove ( gBattlerAttacker , gBattlerTarget , gCurrentMove ) )
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-07-21 15:11:13 +02:00
holdEffect = GetBattlerHoldEffect ( gBattlerTarget , TRUE ) ;
param = GetBattlerHoldEffectParam ( gBattlerTarget ) ;
gPotentialItemEffectBattler = gBattlerTarget ;
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-07-14 22:56:03 +02:00
else if ( holdEffect = = HOLD_EFFECT_FOCUS_SASH & & BATTLER_MAX_HP ( gBattlerTarget ) )
{
RecordItemEffectBattle ( gBattlerTarget , holdEffect ) ;
gSpecialStatuses [ gBattlerTarget ] . focusSashed = 1 ;
}
2018-07-21 15:11:13 +02:00
else if ( GetBattlerAbility ( gBattlerTarget ) = = ABILITY_STURDY & & BATTLER_MAX_HP ( gBattlerTarget ) )
{
RecordAbilityBattle ( gBattlerTarget , ABILITY_STURDY ) ;
gSpecialStatuses [ gBattlerTarget ] . sturdied = 1 ;
}
2018-07-14 22:56:03 +02:00
if ( gBattleMoves [ gCurrentMove ] . effect ! = EFFECT_FALSE_SWIPE
& & ! gProtectStructs [ gBattlerTarget ] . endured
& & ! gSpecialStatuses [ gBattlerTarget ] . focusBanded
2018-07-21 15:11:13 +02:00
& & ! gSpecialStatuses [ gBattlerTarget ] . focusSashed
& & ! gSpecialStatuses [ gBattlerTarget ] . sturdied )
2017-09-20 00:28:00 +02:00
goto END ;
2018-07-21 15:11:13 +02:00
// Handle reducing the dmg to 1 hp.
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-07-14 22:56:03 +02:00
else if ( gSpecialStatuses [ gBattlerTarget ] . focusBanded | | gSpecialStatuses [ gBattlerTarget ] . focusSashed )
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
}
2018-07-21 15:11:13 +02:00
else if ( gSpecialStatuses [ gBattlerTarget ] . sturdied )
{
gMoveResultFlags | = MOVE_RESULT_STURDIED ;
gLastUsedAbility = ABILITY_STURDY ;
}
2017-09-20 00:28:00 +02:00
2018-07-14 22:56:03 +02:00
END :
gBattlescriptCurrInstr + + ;
2019-05-07 15:26:58 +02:00
2019-05-10 11:03:33 +02:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) & & gBattleMoveDamage > = 1 )
gSpecialStatuses [ gBattlerAttacker ] . damagedMons | = gBitTable [ gBattlerTarget ] ;
2019-05-07 15:26:58 +02:00
// Check gems and damage reducing berries.
if ( gSpecialStatuses [ gBattlerTarget ] . berryReduced
& & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
& & gBattleMons [ gBattlerTarget ] . item )
{
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_BerryReduceDmg ;
2019-05-20 10:10:00 +02:00
gLastUsedItem = gBattleMons [ gBattlerTarget ] . item ;
2019-05-07 15:26:58 +02:00
}
if ( gSpecialStatuses [ gBattlerAttacker ] . gemBoost
& & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
& & gBattleMons [ gBattlerAttacker ] . item )
{
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_GemActivates ;
2019-05-20 10:10:00 +02:00
gLastUsedItem = gBattleMons [ gBattlerAttacker ] . item ;
2019-05-07 15:26:58 +02:00
}
2018-07-14 22:56:03 +02:00
}
2019-11-10 12:09:14 +01:00
static void Cmd_multihitresultmessage ( void )
2018-07-14 22:56:03 +02:00
{
2018-07-21 15:11:13 +02:00
if ( gBattleControllerExecFlags )
return ;
2018-07-14 22:56:03 +02:00
2018-07-21 15:11:13 +02:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_FAILED ) & & ! ( gMoveResultFlags & MOVE_RESULT_FOE_ENDURED ) )
{
if ( gMoveResultFlags & MOVE_RESULT_STURDIED )
{
gMoveResultFlags & = ~ ( MOVE_RESULT_STURDIED | MOVE_RESULT_FOE_HUNG_ON ) ;
gSpecialStatuses [ gBattlerTarget ] . sturdied = 0 ; // Delete this line to make Sturdy last for the duration of the whole move turn.
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_SturdiedMsg ;
return ;
}
else if ( gMoveResultFlags & MOVE_RESULT_FOE_HUNG_ON )
{
gLastUsedItem = gBattleMons [ gBattlerTarget ] . item ;
gPotentialItemEffectBattler = gBattlerTarget ;
gMoveResultFlags & = ~ ( MOVE_RESULT_STURDIED | MOVE_RESULT_FOE_HUNG_ON ) ;
gSpecialStatuses [ gBattlerTarget ] . focusBanded = 0 ; // Delete this line to make Focus Band last for the duration of the whole move turn.
gSpecialStatuses [ gBattlerTarget ] . focusSashed = 0 ; // Delete this line to make Focus Sash last for the duration of the whole move turn.
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_HangedOnMsg ;
return ;
}
}
gBattlescriptCurrInstr + + ;
2017-09-20 00:28:00 +02:00
}
2019-11-10 12:09:14 +01:00
static void Cmd_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 ;
}
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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-08-02 20:24:18 +02:00
if ( DoesSubstituteBlockMove ( gBattlerAttacker , gActiveBattler , gCurrentMove ) & & 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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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-08-02 20:24:18 +02:00
if ( DoesSubstituteBlockMove ( gBattlerAttacker , gActiveBattler , gCurrentMove ) & & 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 21:04:56 +02:00
if ( IS_MOVE_PHYSICAL ( gCurrentMove ) & & ! ( 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 21:04:56 +02:00
else if ( ! IS_MOVE_PHYSICAL ( gCurrentMove ) & & ! ( 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 )
gSpecialStatuses [ gActiveBattler ] . dmg = 0xFFFF ;
2017-09-20 12:56:45 +02:00
}
gBattlescriptCurrInstr + = 2 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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-07-14 22:56:03 +02:00
if ( gIsCriticalHit = = TRUE & & ! ( 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 + + ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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-08-01 22:39:42 +02:00
switch ( gMoveResultFlags & ( ~ ( 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 :
2018-07-21 15:11:13 +02:00
case MOVE_RESULT_STURDIED :
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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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-07-21 15:11:13 +02:00
switch ( gMoveResultFlags & ( ~ 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-07-21 15:11:13 +02:00
else if ( gMoveResultFlags & MOVE_RESULT_STURDIED )
{
gMoveResultFlags & = ~ ( MOVE_RESULT_STURDIED | MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON ) ;
gSpecialStatuses [ gBattlerTarget ] . sturdied = 0 ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_SturdiedMsg ;
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 + + ;
2019-05-07 15:26:58 +02:00
// Print berry reducing message after result message.
if ( gSpecialStatuses [ gBattlerTarget ] . berryReduced
& & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
{
gSpecialStatuses [ gBattlerTarget ] . berryReduced = 0 ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_PrintBerryReduceString ;
}
2017-09-20 12:56:45 +02:00
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ) ;
2019-02-16 12:54:11 +01:00
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr + = 3 ;
2019-02-16 12:54:11 +01:00
PrepareStringBattle ( var , gBattlerAttacker ) ;
2017-09-20 12:56:45 +02:00
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
2019-08-23 13:55:36 +02:00
static void Cmd_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
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ] ;
gBattlescriptCurrInstr + = 5 ;
2019-02-16 12:54:11 +01:00
PrepareStringBattle ( * ptr , gBattlerAttacker ) ;
2017-09-20 12:56:45 +02:00
gBattleCommunication [ MSG_DISPLAY ] = 1 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
2019-12-23 18:25:26 +01:00
static void CheckSetUnburden ( u8 battlerId )
{
if ( GetBattlerAbility ( battlerId ) = = ABILITY_UNBURDEN )
{
gBattleResources - > flags - > flags [ battlerId ] | = RESOURCE_FLAG_UNBURDEN ;
RecordAbilityBattle ( battlerId , ABILITY_UNBURDEN ) ;
}
}
2017-09-20 22:54:26 +02:00
# define INCREMENT_RESET_RETURN \
{ \
gBattlescriptCurrInstr + + ; \
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = 0 ; \
2017-09-20 22:54:26 +02:00
return ; \
}
# define RESET_RETURN \
{ \
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = 0 ; \
2017-09-20 22:54:26 +02:00
return ; \
}
2019-02-14 13:17:27 +01:00
void SetMoveEffect ( bool32 primary , u32 certain )
2017-09-20 22:54:26 +02:00
{
2019-02-14 13:17:27 +01:00
s32 i , byTwo , affectsUser = 0 ;
2017-09-20 22:54:26 +02:00
bool32 statusChanged = FALSE ;
bool32 noSunCanFreeze = TRUE ;
2019-02-14 13:17:27 +01:00
if ( gBattleScripting . moveEffect & MOVE_EFFECT_AFFECTS_USER )
2017-09-20 22:54:26 +02:00
{
2018-02-08 12:13:29 +01:00
gEffectBattler = gBattlerAttacker ; // battlerId that effects get applied on
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect & = ~ ( MOVE_EFFECT_AFFECTS_USER ) ;
2017-09-20 22:54:26 +02:00
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
}
2019-04-06 00:03:03 +02:00
// Just in case this flag is still set
gBattleScripting . moveEffect & = ~ ( MOVE_EFFECT_CERTAIN ) ;
2017-09-20 22:54:26 +02:00
2019-03-31 21:38:58 +02:00
if ( GetBattlerAbility ( gEffectBattler ) = = ABILITY_SHIELD_DUST & & ! ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
2019-02-14 13:17:27 +01:00
& & ! primary & & gBattleScripting . moveEffect < = 9 )
2017-09-20 22:54:26 +02:00
INCREMENT_RESET_RETURN
2018-02-08 11:17:41 +01:00
if ( gSideStatuses [ GET_BATTLER_SIDE ( gEffectBattler ) ] & SIDE_STATUS_SAFEGUARD & & ! ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
2019-02-14 13:17:27 +01:00
& & ! primary & & gBattleScripting . moveEffect < = 7 )
2017-09-20 22:54:26 +02:00
INCREMENT_RESET_RETURN
2019-10-21 14:48:03 +02:00
if ( GetBattlerAbility ( gBattlerAttacker ) = = ABILITY_SHEER_FORCE
& & gBattleMoves [ gCurrentMove ] . flags & FLAG_SHEER_FORCE_BOOST
& & affectsUser ! = MOVE_EFFECT_AFFECTS_USER )
INCREMENT_RESET_RETURN
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . hp = = 0
2019-02-14 13:17:27 +01:00
& & gBattleScripting . moveEffect ! = MOVE_EFFECT_PAYDAY
& & gBattleScripting . moveEffect ! = MOVE_EFFECT_STEAL_ITEM )
2017-09-20 22:54:26 +02:00
INCREMENT_RESET_RETURN
2018-08-02 20:24:18 +02:00
if ( DoesSubstituteBlockMove ( gBattlerAttacker , gEffectBattler , gCurrentMove ) & & affectsUser ! = MOVE_EFFECT_AFFECTS_USER )
2017-09-20 22:54:26 +02:00
INCREMENT_RESET_RETURN
2019-02-14 13:17:27 +01:00
if ( gBattleScripting . moveEffect < = 6 ) // status change
2017-09-20 22:54:26 +02:00
{
2019-02-14 13:17:27 +01:00
switch ( sStatusFlagsForMoveEffects [ gBattleScripting . moveEffect ] )
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
2019-03-31 21:38:58 +02:00
if ( GetBattlerAbility ( gEffectBattler ) ! = 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 ;
2019-03-31 21:38:58 +02:00
if ( GetBattlerAbility ( gEffectBattler ) = = ABILITY_VITAL_SPIRIT
| | GetBattlerAbility ( gEffectBattler ) = = ABILITY_INSOMNIA
2019-03-31 22:02:39 +02:00
| | IsAbilityOnSide ( gEffectBattler , ABILITY_SWEET_VEIL )
2019-12-16 09:29:20 +01:00
| | IsFlowerVeilProtected ( gEffectBattler )
| | IsLeafGuardProtected ( gEffectBattler ) )
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 :
2019-03-31 21:38:58 +02:00
if ( GetBattlerAbility ( gEffectBattler ) = = 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 ;
2019-12-23 17:50:13 +01:00
if ( GetBattlerAbility ( gEffectBattler ) = = ABILITY_IMMUNITY
2019-12-16 09:29:20 +01:00
| | IsFlowerVeilProtected ( gEffectBattler )
| | IsLeafGuardProtected ( gEffectBattler ) )
2017-09-20 22:54:26 +02:00
break ;
statusChanged = TRUE ;
break ;
2018-01-16 22:12:38 +01:00
case STATUS1_BURN :
2019-03-31 21:38:58 +02:00
if ( GetBattlerAbility ( gEffectBattler ) = = 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 ;
2019-12-23 17:50:13 +01:00
if ( GetBattlerAbility ( gEffectBattler ) = = ABILITY_WATER_VEIL
2019-12-16 09:29:20 +01:00
| | IsFlowerVeilProtected ( gEffectBattler )
| | IsLeafGuardProtected ( gEffectBattler ) )
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 ;
2019-12-23 17:50:13 +01:00
if ( GetBattlerAbility ( gEffectBattler ) = = ABILITY_MAGMA_ARMOR
2019-12-16 09:29:20 +01:00
| | IsFlowerVeilProtected ( gEffectBattler )
| | IsLeafGuardProtected ( gEffectBattler ) )
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 :
2019-03-31 21:38:58 +02:00
if ( GetBattlerAbility ( gEffectBattler ) = = 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-07-29 12:45:08 +02:00
if ( ( IS_BATTLER_OF_TYPE ( gEffectBattler , TYPE_ELECTRIC ) )
& & ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
& & ( primary = = TRUE | | certain = = MOVE_EFFECT_CERTAIN ) )
{
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
gBattlescriptCurrInstr = BattleScript_PRLZPrevention ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
RESET_RETURN
}
if ( IS_BATTLER_OF_TYPE ( gEffectBattler , TYPE_ELECTRIC ) )
break ;
2019-12-23 17:50:13 +01:00
if ( GetBattlerAbility ( gEffectBattler ) = = ABILITY_LIMBER
2019-12-16 09:29:20 +01:00
| | IsFlowerVeilProtected ( gEffectBattler )
| | IsLeafGuardProtected ( gEffectBattler ) )
2018-07-29 12:45:08 +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_TOXIC_POISON :
2019-03-31 21:38:58 +02:00
if ( GetBattlerAbility ( gEffectBattler ) = = 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
{
2019-12-23 17:50:13 +01:00
if ( GetBattlerAbility ( gEffectBattler ) = = ABILITY_IMMUNITY
2019-12-16 09:29:20 +01:00
| | IsFlowerVeilProtected ( gEffectBattler )
| | IsLeafGuardProtected ( gEffectBattler ) )
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
2019-02-14 13:17:27 +01:00
if ( sStatusFlagsForMoveEffects [ gBattleScripting . moveEffect ] = = 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
2019-02-14 13:17:27 +01:00
gBattleMons [ gEffectBattler ] . status1 | = sStatusFlagsForMoveEffects [ gBattleScripting . moveEffect ] ;
2017-09-20 22:54:26 +02:00
2019-02-14 13:17:27 +01:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleScripting . moveEffect ] ;
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
2019-02-14 13:17:27 +01:00
if ( gBattleScripting . moveEffect = = MOVE_EFFECT_POISON
| | gBattleScripting . moveEffect = = MOVE_EFFECT_TOXIC
| | gBattleScripting . moveEffect = = MOVE_EFFECT_PARALYSIS
| | gBattleScripting . moveEffect = = MOVE_EFFECT_BURN )
2017-09-20 22:54:26 +02:00
{
2019-03-31 21:38:58 +02:00
gBattleStruct - > synchronizeMoveEffect = gBattleScripting . moveEffect ;
2017-09-20 22:54:26 +02:00
gHitMarker | = HITMARKER_SYNCHRONISE_EFFECT ;
}
return ;
}
else if ( statusChanged = = FALSE )
{
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = 0 ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr + + ;
return ;
}
2017-09-22 21:33:49 +02:00
return ;
2017-09-20 22:54:26 +02:00
}
else
{
2019-02-14 13:17:27 +01:00
if ( gBattleMons [ gEffectBattler ] . status2 & sStatusFlagsForMoveEffects [ gBattleScripting . moveEffect ] )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
u8 side ;
2019-02-14 13:17:27 +01:00
switch ( gBattleScripting . moveEffect )
2017-09-20 22:54:26 +02:00
{
case MOVE_EFFECT_CONFUSION :
2019-03-31 21:38:58 +02:00
if ( GetBattlerAbility ( gEffectBattler ) = = ABILITY_OWN_TEMPO
2018-02-08 11:17:41 +01:00
| | 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 ) ;
2019-02-14 13:17:27 +01:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleScripting . moveEffect ] ;
2017-09-20 22:54:26 +02:00
}
break ;
case MOVE_EFFECT_FLINCH :
2018-09-22 10:45:43 +02:00
if ( GetBattlerAbility ( gEffectBattler ) = = 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 )
2019-02-14 13:17:27 +01:00
gBattleMons [ gEffectBattler ] . status2 | = sStatusFlagsForMoveEffects [ gBattleScripting . moveEffect ] ;
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 ) ;
2019-02-14 13:17:27 +01:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleScripting . moveEffect ] ;
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 )
gPaydayMoney = 0xFFFF ;
}
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2019-02-14 13:17:27 +01:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleScripting . moveEffect ] ;
2017-09-20 22:54:26 +02:00
break ;
2019-04-03 21:33:37 +02:00
case MOVE_EFFECT_HAPPY_HOUR :
if ( GET_BATTLER_SIDE ( gBattlerAttacker ) = = B_SIDE_PLAYER )
{
gBattleStruct - > moneyMultiplier * = 2 ;
}
gBattlescriptCurrInstr + + ;
break ;
2017-09-20 22:54:26 +02:00
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
{
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = Random ( ) % 3 + 3 ;
2017-09-20 22:54:26 +02:00
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-09-22 12:20:33 +02:00
gBattleMons [ gEffectBattler ] . status2 | = STATUS2_WRAPPED ;
if ( GetBattlerHoldEffect ( gBattlerAttacker , TRUE ) = = HOLD_EFFECT_GRIP_CLAW )
gDisableStructs [ gEffectBattler ] . wrapTurns = 7 ;
else
gDisableStructs [ gEffectBattler ] . wrapTurns = ( ( Random ( ) % 2 ) + 4 ) ;
2017-09-20 22:54:26 +02:00
2019-01-27 13:52:02 +01:00
gBattleStruct - > wrappedMove [ gEffectBattler ] = gCurrentMove ;
gBattleStruct - > wrappedBy [ gEffectBattler ] = gBattlerAttacker ;
2017-09-20 22:54:26 +02:00
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2019-02-14 13:17:27 +01:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleScripting . moveEffect ] ;
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
{
2018-09-22 12:20:33 +02:00
if ( gBattleCommunication [ MULTISTRING_CHOOSER ] > 5 )
2017-09-22 21:33:49 +02:00
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 ) ;
2019-02-14 13:17:27 +01:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleScripting . moveEffect ] ;
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 ) ,
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect - MOVE_EFFECT_ATK_PLUS_1 + 1 ,
2017-09-22 21:33:49 +02:00
affectsUser , 0 ) )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2019-02-14 13:17:27 +01:00
gBattleScripting . animArg1 = gBattleScripting . moveEffect & ~ ( 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 ,
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect - MOVE_EFFECT_ATK_MINUS_1 + 1 ,
2017-09-22 21:33:49 +02:00
affectsUser , 0 ) )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2019-02-14 13:17:27 +01:00
gBattleScripting . animArg1 = gBattleScripting . moveEffect & ~ ( 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 ) ,
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect - MOVE_EFFECT_ATK_PLUS_2 + 1 ,
2017-09-22 21:33:49 +02:00
affectsUser , 0 ) )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2019-02-14 13:17:27 +01:00
gBattleScripting . animArg1 = gBattleScripting . moveEffect & ~ ( 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 ,
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect - MOVE_EFFECT_ATK_MINUS_2 + 1 ,
2017-09-22 21:33:49 +02:00
affectsUser , 0 ) )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2019-02-14 13:17:27 +01:00
gBattleScripting . animArg1 = gBattleScripting . moveEffect & ~ ( 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
{
2019-01-27 13:52:02 +01:00
gLastUsedItem = gBattleStruct - > changedItems [ gBattlerAttacker ] = gBattleMons [ gBattlerTarget ] . item ;
2019-12-25 12:19:09 +01:00
gBattleMons [ gBattlerTarget ] . item = 0 ;
2019-12-22 07:54:13 +01:00
2019-12-23 18:25:26 +01:00
CheckSetUnburden ( gBattlerTarget ) ;
2019-12-25 12:19:09 +01:00
gBattleResources - > flags - > flags [ gBattlerAttacker ] & = ~ ( RESOURCE_FLAG_UNBURDEN ) ;
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 ;
2019-01-27 13:52:02 +01:00
gBattleStruct - > choicedMove [ gBattlerTarget ] = 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 ;
2018-11-24 21:06:53 +01:00
case MOVE_EFFECT_REMOVE_STATUS : // Smelling salts
if ( ! ( gBattleMons [ gBattlerTarget ] . status1 & gBattleMoves [ gCurrentMove ] . argument ) )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2018-11-24 21:06:53 +01:00
gBattleMons [ gBattlerTarget ] . status1 & = ~ ( gBattleMoves [ gCurrentMove ] . argument ) ;
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-22 01:12:27 +02:00
case MOVE_EFFECT_DEF_SPDEF_DOWN : // Close Combat
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
gBattlescriptCurrInstr = BattleScript_DefSpDefDown ;
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 ) ;
2019-02-14 13:17:27 +01:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleScripting . moveEffect ] ;
2017-09-20 22:54:26 +02:00
break ;
2018-09-22 11:13:17 +02:00
case MOVE_EFFECT_RECOIL_50 : // Head Smash
gBattleMoveDamage = gHpDealt / 2 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
gBattlescriptCurrInstr = BattleScript_MoveEffectRecoil ;
break ;
2018-09-22 10:45:43 +02:00
case MOVE_EFFECT_RECOIL_33_STATUS : // Flare Blitz - can burn, Volt Tackle - can paralyze
gBattleScripting . savedDmg = gHpDealt / 3 ;
if ( gBattleScripting . savedDmg = = 0 )
gBattleScripting . savedDmg = 1 ;
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
gBattlescriptCurrInstr = BattleScript_MoveEffectRecoilWithStatus ;
break ;
2017-09-20 22:54:26 +02:00
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 :
2019-03-31 21:38:58 +02:00
if ( GetBattlerAbility ( gEffectBattler ) = = 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 ] ] ;
2019-12-23 18:25:26 +01:00
CheckSetUnburden ( 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 ;
2019-01-27 13:52:02 +01:00
gBattleStruct - > choicedMove [ gEffectBattler ] = 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 ;
2018-09-22 16:15:00 +02:00
case MOVE_EFFECT_CLEAR_SMOG :
2018-11-18 20:49:52 +01:00
for ( i = 0 ; i < NUM_BATTLE_STATS ; i + + )
2018-09-22 16:15:00 +02:00
{
if ( gBattleMons [ gEffectBattler ] . statStages [ i ] ! = 6 )
break ;
}
2018-11-18 20:49:52 +01:00
if ( ( gSpecialStatuses [ gEffectBattler ] . physicalDmg | | gSpecialStatuses [ gEffectBattler ] . specialDmg ) & & i ! = NUM_BATTLE_STATS )
2018-09-22 16:15:00 +02:00
{
2018-11-18 20:49:52 +01:00
for ( i = 0 ; i < NUM_BATTLE_STATS ; i + + )
2018-09-22 16:15:00 +02:00
gBattleMons [ gEffectBattler ] . statStages [ i ] = 6 ;
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
gBattlescriptCurrInstr = BattleScript_MoveEffectClearSmog ;
}
break ;
2018-09-29 15:43:56 +02:00
case MOVE_EFFECT_SMACK_DOWN :
if ( ! IsBattlerGrounded ( gBattlerTarget ) )
{
gStatuses3 [ gBattlerTarget ] | = STATUS3_SMACKED_DOWN ;
gStatuses3 [ gBattlerTarget ] & = ~ ( STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS | STATUS3_ON_AIR ) ;
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
gBattlescriptCurrInstr = BattleScript_MoveEffectSmackDown ;
}
break ;
2018-09-29 18:40:14 +02:00
case MOVE_EFFECT_FLAME_BURST :
if ( IsBattlerAlive ( BATTLE_PARTNER ( gBattlerTarget ) ) & & GetBattlerAbility ( BATTLE_PARTNER ( gBattlerTarget ) ) ! = ABILITY_MAGIC_GUARD )
{
gBattleScripting . battler = BATTLE_PARTNER ( gBattlerTarget ) ;
gBattleMoveDamage = gBattleMons [ BATTLE_PARTNER ( gBattlerTarget ) ] . hp / 16 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattlescriptCurrInstr = BattleScript_MoveEffectFlameBurst ;
}
break ;
2018-11-24 19:37:10 +01:00
case MOVE_EFFECT_FEINT :
if ( gProtectStructs [ gBattlerTarget ] . protected
2018-12-22 15:10:24 +01:00
| | gSideStatuses [ GetBattlerSide ( gBattlerTarget ) ] & SIDE_STATUS_WIDE_GUARD
| | gSideStatuses [ GetBattlerSide ( gBattlerTarget ) ] & SIDE_STATUS_QUICK_GUARD
2019-02-01 14:34:16 +01:00
| | gSideStatuses [ GetBattlerSide ( gBattlerTarget ) ] & SIDE_STATUS_CRAFTY_SHIELD
2019-03-31 18:17:13 +02:00
| | gSideStatuses [ GetBattlerSide ( gBattlerTarget ) ] & SIDE_STATUS_MAT_BLOCK
2018-11-24 19:37:10 +01:00
| | gProtectStructs [ gBattlerTarget ] . spikyShielded
| | gProtectStructs [ gBattlerTarget ] . kingsShielded
| | gProtectStructs [ gBattlerTarget ] . banefulBunkered )
{
gProtectStructs [ gBattlerTarget ] . protected = 0 ;
2018-12-22 15:10:24 +01:00
gSideStatuses [ GetBattlerSide ( gBattlerTarget ) ] & = ~ ( SIDE_STATUS_WIDE_GUARD ) ;
gSideStatuses [ GetBattlerSide ( gBattlerTarget ) ] & = ~ ( SIDE_STATUS_QUICK_GUARD ) ;
2019-02-01 14:34:16 +01:00
gSideStatuses [ GetBattlerSide ( gBattlerTarget ) ] & = ~ ( SIDE_STATUS_CRAFTY_SHIELD ) ;
2019-03-31 18:17:13 +02:00
gSideStatuses [ GetBattlerSide ( gBattlerTarget ) ] & = ~ ( SIDE_STATUS_MAT_BLOCK ) ;
2018-11-24 19:37:10 +01:00
gProtectStructs [ gBattlerTarget ] . spikyShielded = 0 ;
gProtectStructs [ gBattlerTarget ] . kingsShielded = 0 ;
gProtectStructs [ gBattlerTarget ] . banefulBunkered = 0 ;
2018-12-08 16:19:50 +01:00
if ( gCurrentMove = = MOVE_FEINT )
{
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
gBattlescriptCurrInstr = BattleScript_MoveEffectFeint ;
}
2018-11-24 19:37:10 +01:00
}
break ;
2019-02-14 12:15:53 +01:00
case MOVE_EFFECT_SPECTRAL_THIEF :
gBattleStruct - > stolenStats [ 0 ] = 0 ; // Stats to steal.
gBattleScripting . animArg1 = 0 ;
for ( i = STAT_ATK ; i < NUM_BATTLE_STATS ; i + + )
{
if ( gBattleMons [ gBattlerTarget ] . statStages [ i ] > 6 & & gBattleMons [ gBattlerAttacker ] . statStages [ i ] ! = 12 )
{
gBattleStruct - > stolenStats [ 0 ] | = gBitTable [ i ] ;
// Store by how many stages to raise the stat.
gBattleStruct - > stolenStats [ i ] = gBattleMons [ gBattlerTarget ] . statStages [ i ] - 6 ;
while ( gBattleMons [ gBattlerAttacker ] . statStages [ i ] + gBattleStruct - > stolenStats [ i ] > 12 )
gBattleStruct - > stolenStats [ i ] - - ;
gBattleMons [ gBattlerTarget ] . statStages [ i ] = 6 ;
if ( gBattleStruct - > stolenStats [ i ] > = 2 )
byTwo + + ;
if ( gBattleScripting . animArg1 = = 0 )
{
if ( byTwo )
gBattleScripting . animArg1 = STAT_ANIM_PLUS2 - 1 + i ;
else
gBattleScripting . animArg1 = STAT_ANIM_PLUS1 - 1 + i ;
}
else
{
if ( byTwo )
gBattleScripting . animArg1 = STAT_ANIM_MULTIPLE_PLUS2 ;
else
gBattleScripting . animArg1 = STAT_ANIM_MULTIPLE_PLUS1 ;
}
}
}
if ( gBattleStruct - > stolenStats [ 0 ] ! = 0 )
{
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
gBattlescriptCurrInstr = BattleScript_SpectralThiefSteal ;
}
break ;
2019-03-07 12:20:57 +01:00
case MOVE_EFFECT_V_CREATE :
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
gBattlescriptCurrInstr = BattleScript_VCreateStatLoss ;
break ;
2019-04-15 16:55:37 +02:00
case MOVE_EFFECT_CORE_ENFORCER :
if ( GetBattlerTurnOrderNum ( gBattlerAttacker ) > GetBattlerTurnOrderNum ( gBattlerTarget ) )
{
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
gBattlescriptCurrInstr = BattleScript_MoveEffectCoreEnforcer ;
}
break ;
2019-04-16 15:01:48 +02:00
case MOVE_EFFECT_THROAT_CHOP :
gDisableStructs [ gEffectBattler ] . throatChopTimer = 2 ;
gBattlescriptCurrInstr + + ;
break ;
2019-05-10 15:12:33 +02:00
case MOVE_EFFECT_INCINERATE :
if ( GetBattlerHoldEffect ( gEffectBattler , FALSE ) = = HOLD_EFFECT_GEMS
| | ( gBattleMons [ gEffectBattler ] . item > = FIRST_BERRY_INDEX & & gBattleMons [ gEffectBattler ] . item < = LAST_BERRY_INDEX ) )
{
gLastUsedItem = gBattleMons [ gEffectBattler ] . item ;
gBattleMons [ gEffectBattler ] . item = 0 ;
2019-12-23 18:25:26 +01:00
CheckSetUnburden ( gEffectBattler ) ;
2019-12-22 07:54:13 +01:00
2019-05-10 15:12:33 +02:00
gActiveBattler = gEffectBattler ;
BtlController_EmitSetMonData ( 0 , REQUEST_HELDITEM_BATTLE , 0 , 2 , & gBattleMons [ gEffectBattler ] . item ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
gBattlescriptCurrInstr = BattleScript_MoveEffectIncinerate ;
}
break ;
2019-05-23 12:32:14 +02:00
case MOVE_EFFECT_BUG_BITE :
if ( ( gBattleMons [ gEffectBattler ] . item > = FIRST_BERRY_INDEX & & gBattleMons [ gEffectBattler ] . item < = LAST_BERRY_INDEX )
& & GetBattlerAbility ( gEffectBattler ) ! = ABILITY_STICKY_HOLD )
{
gLastUsedItem = gBattleMons [ gEffectBattler ] . item ;
gBattleMons [ gEffectBattler ] . item = 0 ;
2019-12-23 18:25:26 +01:00
CheckSetUnburden ( gEffectBattler ) ;
2019-12-22 07:54:13 +01:00
2019-05-23 12:32:14 +02:00
gActiveBattler = gEffectBattler ;
BtlController_EmitSetMonData ( 0 , REQUEST_HELDITEM_BATTLE , 0 , 2 , & gBattleMons [ gEffectBattler ] . item ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
gBattlescriptCurrInstr = BattleScript_MoveEffectBugBite ;
}
break ;
2017-09-20 22:54:26 +02:00
}
}
}
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = 0 ;
2017-09-20 22:54:26 +02:00
}
2017-09-22 21:33:49 +02:00
2019-08-23 13:55:36 +02:00
static void Cmd_seteffectwithchance ( void )
2017-09-22 21:33:49 +02:00
{
u32 percentChance ;
2018-09-22 10:45:43 +02:00
if ( GetBattlerAbility ( gBattlerAttacker ) = = ABILITY_SERENE_GRACE )
2017-09-22 21:33:49 +02:00
percentChance = gBattleMoves [ gCurrentMove ] . secondaryEffectChance * 2 ;
else
percentChance = gBattleMoves [ gCurrentMove ] . secondaryEffectChance ;
2019-02-14 13:17:27 +01:00
if ( gBattleScripting . moveEffect & MOVE_EFFECT_CERTAIN
2018-01-16 22:12:38 +01:00
& & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
2017-09-22 21:33:49 +02:00
{
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect & = ~ ( MOVE_EFFECT_CERTAIN ) ;
2017-09-22 21:33:49 +02:00
SetMoveEffect ( 0 , MOVE_EFFECT_CERTAIN ) ;
}
else if ( Random ( ) % 100 < percentChance
2019-02-14 13:17:27 +01:00
& & gBattleScripting . moveEffect
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 + + ;
}
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = 0 ;
2017-12-02 23:31:58 +01:00
gBattleScripting . multihitMoveEffect = 0 ;
2017-09-22 21:33:49 +02:00
}
2019-08-23 13:55:36 +02:00
static void Cmd_seteffectprimary ( void )
2017-09-22 21:33:49 +02:00
{
SetMoveEffect ( TRUE , 0 ) ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_seteffectsecondary ( void )
2017-09-22 21:33:49 +02:00
{
SetMoveEffect ( FALSE , 0 ) ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
2019-02-14 13:17:27 +01:00
if ( gBattleScripting . moveEffect < = MOVE_EFFECT_TOXIC )
gBattleMons [ gActiveBattler ] . status1 & = ( ~ sStatusFlagsForMoveEffects [ gBattleScripting . moveEffect ] ) ;
2017-09-22 21:33:49 +02:00
else
2019-02-14 13:17:27 +01:00
gBattleMons [ gActiveBattler ] . status2 & = ( ~ sStatusFlagsForMoveEffects [ gBattleScripting . moveEffect ] ) ;
2017-09-22 21:33:49 +02:00
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = 0 ;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr + = 2 ;
2017-12-02 23:31:58 +01:00
gBattleScripting . multihitMoveEffect = 0 ;
2017-09-22 21:33:49 +02:00
}
2019-08-23 13:55:36 +02:00
static void Cmd_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-07-24 21:47:00 +02:00
gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] & = ~ ( SIDE_STATUS_SPIKES_DAMAGED | SIDE_STATUS_TOXIC_SPIKES_DAMAGED | SIDE_STATUS_STEALTH_ROCK_DAMAGED | SIDE_STATUS_STICKY_WEB_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 ;
}
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_jumpifability ( void )
2017-09-22 21:33:49 +02:00
{
2019-03-31 21:38:58 +02:00
u32 battlerId ;
bool32 hasAbility = FALSE ;
u32 ability = gBattlescriptCurrInstr [ 2 ] ;
2017-09-22 21:33:49 +02:00
2019-03-31 21:38:58 +02:00
switch ( gBattlescriptCurrInstr [ 1 ] )
2017-09-22 21:33:49 +02:00
{
2019-03-31 21:38:58 +02:00
default :
battlerId = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
if ( GetBattlerAbility ( battlerId ) = = ability )
hasAbility = TRUE ;
break ;
case BS_ATTACKER_SIDE :
battlerId = IsAbilityOnSide ( gBattlerAttacker , ability ) ;
2018-02-08 12:13:29 +01:00
if ( battlerId )
2017-09-22 21:33:49 +02:00
{
2019-03-31 21:38:58 +02:00
battlerId - - ;
hasAbility = TRUE ;
2017-09-22 21:33:49 +02:00
}
2019-03-31 21:38:58 +02:00
break ;
case BS_TARGET_SIDE :
battlerId = IsAbilityOnOpposingSide ( gBattlerAttacker , ability ) ;
2018-02-08 12:13:29 +01:00
if ( battlerId )
2017-09-22 21:33:49 +02:00
{
2019-03-31 21:38:58 +02:00
battlerId - - ;
hasAbility = TRUE ;
2017-09-22 21:33:49 +02:00
}
2019-03-31 21:38:58 +02:00
break ;
}
if ( hasAbility )
{
gLastUsedAbility = ability ;
gBattlescriptCurrInstr = T2_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
RecordAbilityBattle ( battlerId , gLastUsedAbility ) ;
gBattlerAbility = battlerId ;
2017-09-22 21:33:49 +02:00
}
else
{
2019-03-31 21:38:58 +02:00
gBattlescriptCurrInstr + = 7 ;
2017-09-22 21:33:49 +02:00
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_jumpifsideaffecting ( void )
2017-09-22 21:33:49 +02:00
{
u8 side ;
2018-07-24 20:13:02 +02:00
u32 flags ;
const u8 * jumpPtr ;
2017-09-22 21:33:49 +02:00
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-07-24 20:13:02 +02:00
flags = T2_READ_32 ( gBattlescriptCurrInstr + 2 ) ;
jumpPtr = T2_READ_PTR ( gBattlescriptCurrInstr + 6 ) ;
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
2018-07-24 20:13:02 +02:00
gBattlescriptCurrInstr + = 10 ;
2017-09-22 21:33:49 +02:00
}
2019-08-23 13:55:36 +02:00
static void Cmd_jumpifstat ( void )
2017-09-22 21:33:49 +02:00
{
2018-12-26 19:12:07 +01:00
bool32 ret = 0 ;
2018-02-08 12:13:29 +01:00
u8 battlerId = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-12-26 19:12:07 +01:00
u8 statValue = gBattleMons [ battlerId ] . statStages [ gBattlescriptCurrInstr [ 3 ] ] ;
u8 cmpTo = gBattlescriptCurrInstr [ 4 ] ;
u8 cmpKind = gBattlescriptCurrInstr [ 2 ] ;
2017-09-22 21:33:49 +02:00
2018-12-26 19:12:07 +01:00
// Because this command is used as a way of checking if a stat can be lowered/raised,
// we need to do some modification at run-time.
if ( GetBattlerAbility ( battlerId ) = = ABILITY_CONTRARY )
{
if ( cmpKind = = CMP_GREATER_THAN )
cmpKind = CMP_LESS_THAN ;
else if ( cmpKind = = CMP_LESS_THAN )
cmpKind = CMP_GREATER_THAN ;
if ( cmpTo = = 0 )
cmpTo = 0xC ;
else if ( cmpTo = = 0xC )
cmpTo = 0 ;
}
switch ( cmpKind )
2017-09-22 21:33:49 +02:00
{
case CMP_EQUAL :
2018-12-26 19:12:07 +01:00
if ( statValue = = cmpTo )
2017-09-22 21:33:49 +02:00
ret + + ;
break ;
case CMP_NOT_EQUAL :
2018-12-26 19:12:07 +01:00
if ( statValue ! = cmpTo )
2017-09-22 21:33:49 +02:00
ret + + ;
break ;
case CMP_GREATER_THAN :
2018-12-26 19:12:07 +01:00
if ( statValue > cmpTo )
2017-09-22 21:33:49 +02:00
ret + + ;
break ;
case CMP_LESS_THAN :
2018-12-26 19:12:07 +01:00
if ( statValue < cmpTo )
2017-09-22 21:33:49 +02:00
ret + + ;
break ;
case CMP_COMMON_BITS :
2018-12-26 19:12:07 +01:00
if ( statValue & cmpTo )
2017-09-22 21:33:49 +02:00
ret + + ;
break ;
case CMP_NO_COMMON_BITS :
2018-12-26 19:12:07 +01:00
if ( ! ( statValue & cmpTo ) )
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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-11-10 12:09:14 +01:00
static void Cmd_jumpbasedontype ( 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 ] ;
2019-03-31 21:38:58 +02:00
const u8 * jumpPtr = T2_READ_PTR ( gBattlescriptCurrInstr + 4 ) ;
2017-09-22 21:33:49 +02:00
2019-03-31 21:38:58 +02:00
// jumpiftype
if ( gBattlescriptCurrInstr [ 3 ] )
{
if ( IS_BATTLER_OF_TYPE ( battlerId , type ) )
gBattlescriptCurrInstr = jumpPtr ;
else
gBattlescriptCurrInstr + = 8 ;
}
// jumpifnottype
2017-09-22 21:33:49 +02:00
else
2019-03-31 21:38:58 +02:00
{
if ( ! IS_BATTLER_OF_TYPE ( battlerId , type ) )
gBattlescriptCurrInstr = jumpPtr ;
else
gBattlescriptCurrInstr + = 8 ;
}
2017-09-22 21:33:49 +02:00
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
2019-08-23 14:46:21 +02:00
switch ( gBattleScripting . getexpState )
2017-09-22 21:33:49 +02:00
{
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 ) ) )
{
2019-08-23 14:46:21 +02:00
gBattleScripting . getexpState = 6 ; // goto last case
2017-09-22 21:33:49 +02:00
}
else
{
2019-08-23 14:46:21 +02:00
gBattleScripting . getexpState + + ;
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 ;
}
2019-08-23 14:46:21 +02:00
gBattleScripting . getexpState + + ;
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 ;
2019-08-23 14:46:21 +02:00
gBattleScripting . getexpState = 5 ;
2017-09-22 21:33:49 +02:00
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 ;
2019-08-23 14:46:21 +02:00
gBattleScripting . getexpState = 5 ;
2017-09-22 21:33:49 +02:00
gBattleMoveDamage = 0 ; // used for exp
}
else
{
2018-10-16 22:19:53 +02:00
// Music change in a wild battle after fainting opposing pokemon.
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_TRAINER )
& & ( gBattleMons [ 0 ] . hp | | ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE & & gBattleMons [ 2 ] . hp ) )
& & ! IsBattlerAlive ( GetBattlerAtPosition ( B_POSITION_OPPONENT_LEFT ) )
& & ! IsBattlerAlive ( GetBattlerAtPosition ( B_POSITION_OPPONENT_RIGHT ) )
& & ! gBattleStruct - > wildVictorySong )
2017-09-22 21:33:49 +02:00
{
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 ;
2019-08-23 14:46:21 +02:00
gBattleScripting . getexpState + + ;
2017-09-22 21:33:49 +02:00
}
}
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
{
2019-01-05 16:00:57 +01:00
gBattleResources - > bufferB [ 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
}
2019-08-23 14:46:21 +02:00
gBattleScripting . getexpState + + ;
2017-09-22 21:33:49 +02:00
}
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 ;
2019-01-05 16:00:57 +01:00
if ( gBattleResources - > bufferB [ gActiveBattler ] [ 0 ] = = CONTROLLER_TWORETURNVALUES & & gBattleResources - > bufferB [ gActiveBattler ] [ 1 ] = = RET_VALUE_LEVELED_UP )
2017-09-22 21:33:49 +02:00
{
2018-09-29 18:40:14 +02:00
u16 temp , battlerId = 0xFF ;
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 ;
2019-01-05 16:00:57 +01:00
gBattleMoveDamage = ( gBattleResources - > bufferB [ gActiveBattler ] [ 2 ] | ( gBattleResources - > bufferB [ 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 )
2018-09-29 18:40:14 +02:00
battlerId = 0 ;
else if ( gBattlerPartyIndexes [ 2 ] = = gBattleStruct - > expGetterMonId & & gBattleMons [ 2 ] . hp & & ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE ) )
battlerId = 2 ;
if ( battlerId ! = 0xFF )
2017-09-22 21:33:49 +02:00
{
2018-09-29 18:40:14 +02:00
gBattleMons [ battlerId ] . level = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_LEVEL ) ;
gBattleMons [ battlerId ] . hp = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_HP ) ;
gBattleMons [ battlerId ] . maxHP = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_MAX_HP ) ;
gBattleMons [ battlerId ] . attack = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_ATK ) ;
gBattleMons [ battlerId ] . defense = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_DEF ) ;
gBattleMons [ battlerId ] . speed = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPEED ) ;
gBattleMons [ battlerId ] . spAttack = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPATK ) ;
gBattleMons [ battlerId ] . spDefense = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPDEF ) ;
if ( gStatuses3 [ battlerId ] & STATUS3_POWER_TRICK )
SWAP ( gBattleMons [ battlerId ] . attack , gBattleMons [ battlerId ] . defense , temp ) ;
2017-09-22 21:33:49 +02:00
}
2018-09-29 18:40:14 +02:00
2019-08-23 14:46:21 +02:00
gBattleScripting . getexpState = 5 ;
2017-09-22 21:33:49 +02:00
}
else
{
gBattleMoveDamage = 0 ;
2019-08-23 14:46:21 +02:00
gBattleScripting . getexpState = 5 ;
2017-09-22 21:33:49 +02:00
}
}
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
{
2019-08-23 14:46:21 +02:00
gBattleScripting . getexpState = 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 )
2019-08-23 14:46:21 +02:00
gBattleScripting . getexpState = 2 ; // loop again
2017-09-22 21:33:49 +02:00
else
2019-08-23 14:46:21 +02:00
gBattleScripting . getexpState = 6 ; // we're done
2017-09-22 21:33:49 +02:00
}
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 ;
}
}
2019-08-22 15:57:33 +02:00
static bool32 NoAliveMonsForPlayer ( void )
2017-09-22 21:33:49 +02:00
{
2018-07-26 22:52:13 +02:00
u32 i ;
u32 HP_count = 0 ;
2017-09-22 21:33:49 +02:00
2018-11-24 01:02:02 +01:00
if ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER & & ( gPartnerTrainerId = = TRAINER_STEVEN_PARTNER | | gPartnerTrainerId > = TRAINER_CUSTOM_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-07-26 22:52:13 +02: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 ) ;
}
}
}
2018-07-26 22:52:13 +02:00
return ( HP_count = = 0 ) ;
}
2019-08-22 15:57:33 +02:00
static bool32 NoAliveMonsForOpponent ( void )
2018-07-26 22:52:13 +02:00
{
u32 i ;
u32 HP_count = 0 ;
2017-09-22 21:33:49 +02:00
2018-07-26 22:52:13 +02:00
for ( 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 ) ;
}
}
2018-07-26 22:52:13 +02:00
return ( HP_count = = 0 ) ;
}
2019-08-22 15:57:33 +02:00
bool32 NoAliveMonsForEitherParty ( void )
{
return ( NoAliveMonsForPlayer ( ) | | NoAliveMonsForOpponent ( ) ) ;
}
2018-07-26 22:52:13 +02:00
static void atk24 ( void )
{
if ( gBattleControllerExecFlags )
return ;
2019-08-22 15:57:33 +02:00
if ( NoAliveMonsForPlayer ( ) )
2018-07-26 22:52:13 +02:00
gBattleOutcome | = B_OUTCOME_LOST ;
2019-08-22 15:57:33 +02:00
if ( NoAliveMonsForOpponent ( ) )
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 ) ) )
{
2018-07-26 22:52:13 +02:00
s32 i ;
2017-09-22 21:33:49 +02:00
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 ;
}
}
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 ;
2018-07-14 22:56:03 +02:00
gIsCriticalHit = FALSE ;
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = 0 ;
2017-09-22 21:33:49 +02:00
gBattleCommunication [ 6 ] = 0 ;
gHitMarker & = ~ ( HITMARKER_DESTINYBOND ) ;
gHitMarker & = ~ ( HITMARKER_SYNCHRONISE_EFFECT ) ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_movevaluescleanup ( void )
2017-09-22 21:33:49 +02:00
{
MoveValuesCleanUp ( ) ;
gBattlescriptCurrInstr + = 1 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-11-10 12:09:14 +01:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_return ( void )
2017-09-22 21:33:49 +02:00
{
BattleScriptPop ( ) ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
2019-11-10 12:09:14 +01:00
static void Cmd_setroost ( void )
2017-09-22 21:33:49 +02:00
{
2018-07-21 16:34:43 +02:00
gBattleResources - > flags - > flags [ gBattlerAttacker ] | = RESOURCE_FLAG_ROOST ;
// Pure flying type.
if ( gBattleMons [ gBattlerAttacker ] . type1 = = TYPE_FLYING & & gBattleMons [ gBattlerAttacker ] . type2 = = TYPE_FLYING )
{
gBattleStruct - > roostTypes [ gBattlerAttacker ] [ 0 ] = TYPE_FLYING ;
gBattleStruct - > roostTypes [ gBattlerAttacker ] [ 1 ] = TYPE_FLYING ;
gBattleStruct - > roostTypes [ gBattlerAttacker ] [ 2 ] = TYPE_FLYING ;
SET_BATTLER_TYPE ( gBattlerAttacker , TYPE_NORMAL ) ;
}
// Dual Type with Flying Type.
else if ( ( gBattleMons [ gBattlerAttacker ] . type1 = = TYPE_FLYING & & gBattleMons [ gBattlerAttacker ] . type2 ! = TYPE_FLYING )
| | ( gBattleMons [ gBattlerAttacker ] . type2 = = TYPE_FLYING & & gBattleMons [ gBattlerAttacker ] . type1 ! = TYPE_FLYING ) )
{
gBattleStruct - > roostTypes [ gBattlerAttacker ] [ 0 ] = gBattleMons [ gBattlerAttacker ] . type1 ;
gBattleStruct - > roostTypes [ gBattlerAttacker ] [ 1 ] = gBattleMons [ gBattlerAttacker ] . type2 ;
if ( gBattleMons [ gBattlerAttacker ] . type1 = = TYPE_FLYING )
gBattleMons [ gBattlerAttacker ] . type1 = TYPE_MYSTERY ;
if ( gBattleMons [ gBattlerAttacker ] . type2 = = TYPE_FLYING )
gBattleMons [ gBattlerAttacker ] . type2 = TYPE_MYSTERY ;
}
// Non-flying type.
else if ( ! IS_BATTLER_OF_TYPE ( gBattlerAttacker , TYPE_FLYING ) )
{
gBattleStruct - > roostTypes [ gBattlerAttacker ] [ 0 ] = gBattleMons [ gBattlerAttacker ] . type1 ;
gBattleStruct - > roostTypes [ gBattlerAttacker ] [ 1 ] = gBattleMons [ gBattlerAttacker ] . type2 ;
}
2018-07-14 12:02:29 +02:00
gBattlescriptCurrInstr + + ;
2017-09-22 21:33:49 +02:00
}
2019-08-23 13:55:36 +02:00
static void Cmd_jumpifabilitypresent ( void )
2017-09-22 21:33:49 +02:00
{
2019-03-31 21:38:58 +02:00
if ( IsAbilityOnField ( gBattlescriptCurrInstr [ 1 ] ) )
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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
2019-05-02 23:10:01 +02:00
| | gBattlescriptCurrInstr [ 2 ] = = B_ANIM_MEGA_EVOLUTION
2019-08-08 13:06:55 +02:00
| | gBattlescriptCurrInstr [ 2 ] = = B_ANIM_ILLUSION_OFF
2017-09-22 21:33:49 +02:00
| | 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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
2019-05-02 23:10:01 +02:00
| | * animationIdPtr = = B_ANIM_MEGA_EVOLUTION
2019-08-08 13:06:55 +02:00
| | * animationIdPtr = = B_ANIM_ILLUSION_OFF
2017-09-22 21:33:49 +02:00
| | * 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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_setgraphicalstatchangevalues ( void )
2017-09-22 21:33:49 +02:00
{
2019-03-23 16:33:08 +01:00
u8 value = GET_STAT_BUFF_VALUE_WITH_SIGN ( gBattleScripting . statChanger ) ;
switch ( value )
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-09-22 12:20:33 +02:00
case SET_STAT_BUFF_VALUE ( 3 ) : // +3
2018-10-07 19:40:34 +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-09-22 12:20:33 +02:00
case SET_STAT_BUFF_VALUE ( 3 ) | STAT_BUFF_NEGATIVE : // -3
2018-10-07 19:40:34 +02:00
value = STAT_ANIM_MINUS2 ;
2017-09-22 21:33:49 +02:00
break ;
2019-03-23 16:33:08 +01:00
default : // <-12,-4> and <4, 12>
if ( value & STAT_BUFF_NEGATIVE )
value = STAT_ANIM_MINUS2 ;
else
value = STAT_ANIM_PLUS2 ;
break ;
2017-09-22 21:33:49 +02:00
}
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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_playstatchangeanimation ( void )
2017-09-22 21:33:49 +02:00
{
2019-03-07 12:20:57 +01:00
u32 ability ;
2017-09-23 00:06:52 +02:00
u32 currStat = 0 ;
2019-03-07 12:20:57 +01:00
u32 statAnimId = 0 ;
u32 changeableStatsCount = 0 ;
u32 statsToCheck = 0 ;
u32 startingStatAnimId = 0 ;
u32 flags = gBattlescriptCurrInstr [ 3 ] ;
2017-09-22 21:33:49 +02:00
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2019-03-07 12:20:57 +01:00
ability = GetBattlerAbility ( gActiveBattler ) ;
2017-09-23 00:06:52 +02:00
statsToCheck = gBattlescriptCurrInstr [ 2 ] ;
2017-09-22 21:33:49 +02:00
2019-03-07 12:20:57 +01:00
// Handle Contrary and Simple
if ( ability = = ABILITY_CONTRARY )
2019-11-10 12:09:14 +01:00
flags ^ = STAT_CHANGE_NEGATIVE ;
2019-03-07 12:20:57 +01:00
else if ( ability = = ABILITY_SIMPLE )
2019-11-10 12:09:14 +01:00
flags | = STAT_CHANGE_BY_TWO ;
2019-03-07 12:20:57 +01:00
2019-11-10 12:09:14 +01:00
if ( flags & STAT_CHANGE_NEGATIVE ) // goes down
2017-09-22 21:33:49 +02:00
{
2019-11-10 12:09:14 +01:00
if ( flags & STAT_CHANGE_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
{
2019-11-10 12:09:14 +01:00
if ( flags & STAT_CHANGE_CANT_PREVENT )
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
2019-03-07 12:20:57 +01:00
& & ability ! = ABILITY_CLEAR_BODY
& & ability ! = ABILITY_WHITE_SMOKE
& & ! ( ability = = ABILITY_KEEN_EYE & & currStat = = STAT_ACC )
2019-12-19 20:01:46 +01:00
& & ! ( ability = = ABILITY_HYPER_CUTTER & & currStat = = STAT_ATK )
& & ! ( ability = = ABILITY_BIG_PECKS & & currStat = = STAT_DEF ) )
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
{
2019-11-10 12:09:14 +01:00
if ( flags & STAT_CHANGE_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
{
2019-11-10 12:09:14 +01:00
if ( flags & STAT_CHANGE_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
{
2019-11-10 12:09:14 +01:00
if ( flags & STAT_CHANGE_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
}
}
2019-11-10 12:09:14 +01:00
if ( flags & STAT_CHANGE_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 ) ;
2019-11-10 12:09:14 +01:00
if ( flags & STAT_CHANGE_ONLY_MULTIPLE & & changeableStatsCount > 1 )
2018-07-29 15:33:16 +02:00
gBattleScripting . statAnimPlayed = TRUE ;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr + = 4 ;
}
else
{
gBattlescriptCurrInstr + = 4 ;
}
}
2017-09-23 20:13:45 +02:00
2019-08-23 13:55:36 +02:00
static void Cmd_moveend ( void )
2017-09-23 20:13:45 +02:00
{
s32 i ;
2018-09-01 20:00:13 +02:00
bool32 effect = FALSE ;
2019-03-30 11:50:55 +01:00
u32 moveType = 0 ;
u32 holdEffectAtk = 0 ;
2018-09-01 20:00:13 +02:00
u16 * choicedMoveAtk = NULL ;
2019-03-30 11:50:55 +01:00
u32 arg1 , arg2 ;
u32 originallyUsedMove ;
2017-09-23 20:13:45 +02:00
2017-11-26 18:07:00 +01:00
if ( gChosenMove = = 0xFFFF )
2017-11-26 14:17:02 +01:00
originallyUsedMove = 0 ;
2017-09-23 20:13:45 +02:00
else
2017-11-26 18:07:00 +01:00
originallyUsedMove = gChosenMove ;
2017-09-23 20:13:45 +02:00
arg1 = gBattlescriptCurrInstr [ 1 ] ;
arg2 = gBattlescriptCurrInstr [ 2 ] ;
2019-03-30 11:50:55 +01:00
holdEffectAtk = GetBattlerHoldEffect ( gBattlerAttacker , TRUE ) ;
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
{
2019-08-23 14:46:21 +02:00
switch ( gBattleScripting . moveendState )
2017-09-23 20:13:45 +02:00
{
2019-11-10 12:09:14 +01:00
case MOVEEND_PROTECT_LIKE_EFFECT :
2019-04-15 13:02:25 +02:00
if ( gBattleMoves [ gCurrentMove ] . flags & FLAG_MAKES_CONTACT )
2019-03-15 13:54:11 +01:00
{
2019-04-15 13:02:25 +02:00
if ( gProtectStructs [ gBattlerTarget ] . spikyShielded & & GetBattlerAbility ( gBattlerAttacker ) ! = ABILITY_MAGIC_GUARD )
{
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . maxHP / 8 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , MOVE_SPIKY_SHIELD ) ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_SpikyShieldEffect ;
effect = 1 ;
}
else if ( gProtectStructs [ gBattlerTarget ] . kingsShielded )
{
i = gBattlerAttacker ;
gBattlerAttacker = gBattlerTarget ;
gBattlerTarget = i ; // gBattlerTarget and gBattlerAttacker are swapped in order to activate Defiant, if applicable
gBattleScripting . moveEffect = MOVE_EFFECT_ATK_MINUS_2 ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_KingsShieldEffect ;
effect = 1 ;
}
else if ( gProtectStructs [ gBattlerTarget ] . banefulBunkered )
{
gBattleScripting . moveEffect = MOVE_EFFECT_POISON | MOVE_EFFECT_AFFECTS_USER ;
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , MOVE_BANEFUL_BUNKER ) ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_BanefulBunkerEffect ;
effect = 1 ;
}
2019-03-15 13:54:11 +01:00
}
2019-11-10 12:09:14 +01:00
gBattleScripting . moveendState + + ;
2019-03-15 13:54:11 +01:00
break ;
2019-08-23 14:46:21 +02:00
case MOVEEND_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 ;
}
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState + + ;
2017-09-23 20:13:45 +02:00
break ;
2019-08-23 14:46:21 +02:00
case MOVEEND_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-08-11 13:30:34 +02:00
& & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) & & ( moveType = = TYPE_FIRE | | gBattleMoves [ gCurrentMove ] . effect = = EFFECT_SCALD ) )
2018-01-16 22:12:38 +01:00
{
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 ;
}
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState + + ;
2017-09-23 20:13:45 +02:00
break ;
2019-08-23 14:46:21 +02:00
case MOVEEND_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 ;
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState + + ;
2017-09-23 20:13:45 +02:00
break ;
2019-11-10 12:09:14 +01:00
case MOVEEND_ABILITIES : // Such as abilities activating on contact(Poison Spore, Rough Skin, etc.).
2018-09-01 20:00:13 +02:00
if ( AbilityBattleEffects ( ABILITYEFFECT_MOVE_END , gBattlerTarget , 0 , 0 , 0 ) )
2017-09-23 20:13:45 +02:00
effect = TRUE ;
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState + + ;
2017-09-23 20:13:45 +02:00
break ;
2019-11-10 12:09:14 +01:00
case MOVEEND_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
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState + + ;
2017-09-23 20:13:45 +02:00
break ;
2019-08-23 14:46:21 +02:00
case MOVEEND_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 ;
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState + + ;
2017-09-23 20:13:45 +02:00
break ;
2019-08-23 14:46:21 +02:00
case MOVEEND_CHOICE_MOVE : // update choice band move
2019-08-28 00:06:17 +02:00
if ( gHitMarker & HITMARKER_OBEYS
2019-10-10 16:18:48 +02:00
& & HOLD_EFFECT_CHOICE ( holdEffectAtk )
& & gChosenMove ! = MOVE_STRUGGLE
2019-08-28 00:06:17 +02:00
& & ( * choicedMoveAtk = = 0 | | * choicedMoveAtk = = 0xFFFF ) )
2017-09-23 20:13:45 +02:00
{
2019-10-10 16:18:48 +02:00
if ( ( gBattleMoves [ gChosenMove ] . effect = = EFFECT_BATON_PASS
2018-07-26 20:36:16 +02:00
| | gBattleMoves [ gChosenMove ] . effect = = EFFECT_HEALING_WISH
| | gBattleMoves [ gChosenMove ] . effect = = EFFECT_HIT_ESCAPE )
2019-10-10 16:18:48 +02:00
& & ! ( gMoveResultFlags & MOVE_RESULT_FAILED ) )
2017-09-23 20:13:45 +02:00
{
2019-09-26 21:02:38 +02:00
+ + gBattleScripting . moveendState ;
2019-08-28 00:06:17 +02:00
break ;
2017-09-23 20:13:45 +02:00
}
2019-08-28 00:06:17 +02:00
* choicedMoveAtk = gChosenMove ;
2017-09-23 20:13:45 +02:00
}
2019-08-28 00:06:17 +02:00
for ( i = 0 ; i < MAX_MON_MOVES ; + + i )
{
if ( gBattleMons [ gBattlerAttacker ] . moves [ i ] = = * choicedMoveAtk )
break ;
2017-09-23 20:13:45 +02:00
}
2019-08-28 00:06:17 +02:00
if ( i = = MAX_MON_MOVES )
* choicedMoveAtk = 0 ;
2019-09-26 21:02:38 +02:00
+ + gBattleScripting . moveendState ;
2017-09-23 20:13:45 +02:00
break ;
2019-08-23 14:46:21 +02:00
case MOVEEND_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
{
2019-01-27 13:52:02 +01:00
if ( gBattleStruct - > changedItems [ i ] ! = 0 )
2017-09-23 20:13:45 +02:00
{
2019-01-27 13:52:02 +01:00
gBattleMons [ i ] . item = gBattleStruct - > changedItems [ i ] ;
gBattleStruct - > changedItems [ i ] = 0 ;
2017-09-23 20:13:45 +02:00
}
}
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState + + ;
2017-09-23 20:13:45 +02:00
break ;
2019-11-10 12:09:14 +01:00
case MOVEEND_ITEM_EFFECTS_TARGET :
2019-05-09 20:31:58 +02:00
if ( ItemBattleEffects ( ITEMEFFECT_TARGET , gBattlerTarget , FALSE ) )
effect = TRUE ;
2019-11-10 12:09:14 +01:00
gBattleScripting . moveendState + + ;
2019-05-09 20:31:58 +02:00
break ;
2019-08-23 14:46:21 +02:00
case MOVEEND_ITEM_EFFECTS_ALL : // item effects for all battlers
2018-09-01 20:00:13 +02:00
if ( ItemBattleEffects ( ITEMEFFECT_MOVE_END , 0 , FALSE ) )
2017-09-23 20:13:45 +02:00
effect = TRUE ;
else
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState + + ;
2017-09-23 20:13:45 +02:00
break ;
2019-08-23 14:46:21 +02:00
case MOVEEND_KINGSROCK_SHELLBELL : // king's rock and shell bell
2018-09-01 20:00:13 +02:00
if ( ItemBattleEffects ( ITEMEFFECT_KINGSROCK_SHELLBELL , 0 , FALSE ) )
2017-09-23 20:13:45 +02:00
effect = TRUE ;
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState + + ;
2017-09-23 20:13:45 +02:00
break ;
2019-08-23 14:46:21 +02:00
case MOVEEND_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 ) ;
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState + + ;
2017-09-23 20:13:45 +02:00
return ;
}
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState + + ;
2017-09-23 20:13:45 +02:00
break ;
2019-08-23 14:46:21 +02:00
case MOVEEND_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 ;
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState + + ;
2017-09-23 20:13:45 +02:00
return ;
}
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState + + ;
2017-09-23 20:13:45 +02:00
break ;
2019-08-23 14:46:21 +02:00
case MOVEEND_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 ) ;
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState + + ;
2017-09-23 20:13:45 +02:00
return ;
}
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState + + ;
2017-09-23 20:13:45 +02:00
break ;
2019-08-23 14:46:21 +02:00
case MOVEEND_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 ) ;
}
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState + + ;
2017-09-23 20:13:45 +02:00
break ;
2019-08-23 14:46:21 +02:00
case MOVEEND_UPDATE_LAST_MOVES :
2019-04-13 14:36:08 +02:00
if ( gMoveResultFlags & ( MOVE_RESULT_FAILED | MOVE_RESULT_DOESNT_AFFECT_FOE ) )
gBattleStruct - > lastMoveFailed | = gBitTable [ gBattlerAttacker ] ;
else
gBattleStruct - > lastMoveFailed & = ~ ( gBitTable [ gBattlerAttacker ] ) ;
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
}
2019-11-14 00:03:20 +01:00
if ( ! gSpecialStatuses [ gBattlerAttacker ] . dancerUsedMove )
2017-09-23 20:13:45 +02:00
{
2019-11-14 00:03:20 +01:00
gDisableStructs [ gBattlerAttacker ] . usedMoves | = gBitTable [ gCurrMovePos ] ;
gBattleStruct - > lastMoveTarget [ gBattlerAttacker ] = gBattlerTarget ;
if ( gHitMarker & HITMARKER_ATTACKSTRING_PRINTED )
{
gLastPrintedMoves [ gBattlerAttacker ] = gChosenMove ;
gLastUsedMove = gCurrentMove ;
}
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 ] )
2018-07-26 20:36:16 +02:00
& & gBattleMoves [ originallyUsedMove ] . effect ! = EFFECT_BATON_PASS
& & gBattleMoves [ originallyUsedMove ] . effect ! = EFFECT_HEALING_WISH )
2017-09-23 20:13:45 +02:00
{
if ( gHitMarker & HITMARKER_OBEYS )
2019-11-14 00:03:20 +01:00
{ if ( ! gSpecialStatuses [ gBattlerAttacker ] . dancerUsedMove )
{
gLastMoves [ gBattlerAttacker ] = gChosenMove ;
gLastResultingMoves [ gBattlerAttacker ] = gCurrentMove ;
}
2017-09-23 20:13:45 +02:00
}
else
{
2018-02-06 23:09:39 +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
{
2017-11-26 18:07:00 +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-02-06 23:09:39 +01:00
gLastLandedMoves [ gBattlerTarget ] = 0xFFFF ;
2017-09-23 20:13:45 +02:00
}
}
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState + + ;
2017-09-23 20:13:45 +02:00
break ;
2019-08-23 14:46:21 +02:00
case MOVEEND_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
{
2019-01-27 13:52:02 +01:00
gBattleStruct - > lastTakenMove [ gBattlerTarget ] = gChosenMove ;
gBattleStruct - > lastTakenMoveFrom [ gBattlerTarget ] [ gBattlerAttacker ] = gChosenMove ;
2017-09-23 20:13:45 +02:00
}
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState + + ;
2017-09-23 20:13:45 +02:00
break ;
2019-08-23 14:46:21 +02:00
case MOVEEND_NEXT_TARGET : // For moves hitting two opposing Pokemon.
2018-09-29 16:41:25 +02:00
if ( ! ( gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE )
& & gBattleTypeFlags & BATTLE_TYPE_DOUBLE
& & ! gProtectStructs [ gBattlerAttacker ] . chargingTurn
& & ( gBattleMoves [ gCurrentMove ] . target = = MOVE_TARGET_BOTH | | gBattleMoves [ gCurrentMove ] . target = = MOVE_TARGET_FOES_AND_ALLY )
2017-09-23 20:13:45 +02:00
& & ! ( gHitMarker & HITMARKER_NO_ATTACKSTRING ) )
{
2018-09-29 16:41:25 +02:00
u8 battlerId ;
if ( gBattleMoves [ gCurrentMove ] . target = = MOVE_TARGET_FOES_AND_ALLY )
2017-09-23 20:13:45 +02:00
{
2018-09-29 16:41:25 +02:00
for ( battlerId = gBattlerTarget + 1 ; battlerId < gBattlersCount ; battlerId + + )
{
if ( battlerId = = gBattlerAttacker )
continue ;
if ( IsBattlerAlive ( battlerId ) )
break ;
}
}
else
{
battlerId = GetBattlerAtPosition ( BATTLE_PARTNER ( GetBattlerPosition ( gBattlerTarget ) ) ) ;
2017-09-23 20:13:45 +02:00
gHitMarker | = HITMARKER_NO_ATTACKSTRING ;
2018-09-29 16:41:25 +02:00
}
2019-04-02 00:14:01 +02:00
if ( IsBattlerAlive ( battlerId ) )
2018-09-29 16:41:25 +02:00
{
gBattlerTarget = battlerId ;
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState = 0 ;
2017-09-23 20:13:45 +02:00
MoveValuesCleanUp ( ) ;
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = gBattleScripting . savedMoveEffect ;
2017-09-23 20:13:45 +02:00
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 ;
}
}
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState + + ;
2017-09-23 20:13:45 +02:00
break ;
2019-11-10 12:09:14 +01:00
case MOVEEND_LIFE_ORB :
2019-05-10 11:03:33 +02:00
if ( GetBattlerHoldEffect ( gBattlerAttacker , TRUE ) = = HOLD_EFFECT_LIFE_ORB
& & ! ( GetBattlerAbility ( gBattlerAttacker ) = = ABILITY_SHEER_FORCE & & gBattleMoves [ gCurrentMove ] . flags & FLAG_SHEER_FORCE_BOOST )
& & GetBattlerAbility ( gBattlerAttacker ) ! = ABILITY_MAGIC_GUARD
& & gSpecialStatuses [ gBattlerAttacker ] . damagedMons )
{
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . maxHP / 10 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
effect = TRUE ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_ItemHurtRet ;
2019-05-23 09:20:02 +02:00
gLastUsedItem = gBattleMons [ gBattlerAttacker ] . item ;
2019-05-10 11:03:33 +02:00
}
2019-11-10 12:09:14 +01:00
gBattleScripting . moveendState + + ;
2019-05-10 11:03:33 +02:00
break ;
2019-11-14 00:03:20 +01:00
case MOVEEND_DANCER : // Special case because it's so annoying
if ( gBattleMoves [ gCurrentMove ] . flags & FLAG_DANCE )
{
u8 battler , nextDancer = 0 ;
2019-12-09 08:41:09 +01:00
2019-11-14 00:03:20 +01:00
if ( ! ( gBattleStruct - > lastMoveFailed & gBitTable [ gBattlerAttacker ]
| | ( ! gSpecialStatuses [ gBattlerAttacker ] . dancerUsedMove
& & gProtectStructs [ gBattlerAttacker ] . usesBouncedMove ) ) )
{ // Dance move succeeds
// Set target for other Dancer mons; set bit so that mon cannot activate Dancer off of its own move
if ( ! gSpecialStatuses [ gBattlerAttacker ] . dancerUsedMove )
{
gBattleScripting . savedBattler = gBattlerTarget | 0x4 ;
gBattleScripting . savedBattler | = ( gBattlerAttacker < < 4 ) ;
gSpecialStatuses [ gBattlerAttacker ] . dancerUsedMove = 1 ;
}
for ( battler = 0 ; battler < MAX_BATTLERS_COUNT ; battler + + )
{
if ( GetBattlerAbility ( battler ) = = ABILITY_DANCER & & ! gSpecialStatuses [ battler ] . dancerUsedMove )
{
if ( ! nextDancer | | ( gBattleMons [ battler ] . speed < gBattleMons [ nextDancer & 0x3 ] . speed ) )
2019-12-09 08:41:09 +01:00
nextDancer = battler | 0x4 ;
2019-11-14 00:03:20 +01:00
}
}
if ( nextDancer & & AbilityBattleEffects ( ABILITYEFFECT_MOVE_END_OTHER , nextDancer & 0x3 , 0 , 0 , 0 ) )
effect = TRUE ;
}
}
2019-12-09 08:41:09 +01:00
gBattleScripting . moveendState + + ;
2019-11-14 00:03:20 +01:00
break ;
2019-11-10 12:09:14 +01:00
case MOVEEND_CLEAR_BITS : // Clear bits active while using a move for all targets and all hits.
2019-04-20 21:11:49 +02:00
if ( gSpecialStatuses [ gBattlerAttacker ] . instructedChosenTarget )
* ( gBattleStruct - > moveTarget + gBattlerAttacker ) = gSpecialStatuses [ gBattlerAttacker ] . instructedChosenTarget & 0x3 ;
2019-11-14 00:03:20 +01:00
if ( gSpecialStatuses [ gBattlerAttacker ] . dancerOriginalTarget )
* ( gBattleStruct - > moveTarget + gBattlerAttacker ) = gSpecialStatuses [ gBattlerAttacker ] . dancerOriginalTarget & 0x3 ;
2018-07-28 10:41:20 +02:00
gProtectStructs [ gBattlerAttacker ] . usesBouncedMove = 0 ;
2018-07-28 18:41:57 +02:00
gBattleStruct - > ateBoost [ gBattlerAttacker ] = 0 ;
2018-08-05 16:43:07 +02:00
gStatuses3 [ gBattlerAttacker ] & = ~ ( STATUS3_ME_FIRST ) ;
2019-05-07 15:26:58 +02:00
gSpecialStatuses [ gBattlerAttacker ] . gemBoost = 0 ;
2019-05-10 11:03:33 +02:00
gSpecialStatuses [ gBattlerAttacker ] . damagedMons = 0 ;
2019-05-07 15:26:58 +02:00
gSpecialStatuses [ gBattlerTarget ] . berryReduced = 0 ;
2019-11-10 12:09:14 +01:00
gBattleScripting . moveendState + + ;
2018-07-28 10:41:20 +02:00
break ;
2019-08-23 14:46:21 +02:00
case MOVEEND_COUNT :
2017-09-23 20:13:45 +02:00
break ;
}
if ( arg1 = = 1 & & effect = = FALSE )
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState = MOVEEND_COUNT ;
if ( arg1 = = 2 & & arg2 = = gBattleScripting . moveendState )
gBattleScripting . moveendState = MOVEEND_COUNT ;
2017-09-23 20:13:45 +02:00
2019-08-23 14:46:21 +02:00
} while ( gBattleScripting . moveendState ! = MOVEEND_COUNT & & effect = = FALSE ) ;
2017-09-23 20:13:45 +02:00
2019-08-23 14:46:21 +02:00
if ( gBattleScripting . moveendState = = MOVEEND_COUNT & & effect = = FALSE )
2017-09-23 20:13:45 +02:00
gBattlescriptCurrInstr + = 3 ;
}
2019-11-10 12:09:14 +01:00
static void Cmd_sethealblock ( void )
2017-09-24 00:29:52 +02:00
{
2018-07-30 20:41:16 +02:00
if ( gStatuses3 [ gBattlerTarget ] & STATUS3_HEAL_BLOCK )
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
gStatuses3 [ gBattlerTarget ] | = STATUS3_HEAL_BLOCK ;
gDisableStructs [ gBattlerTarget ] . healBlockTimer = 5 ;
gBattlescriptCurrInstr + = 5 ;
}
2017-09-24 00:29:52 +02:00
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + )
{
2019-01-05 16:00:57 +01:00
monData [ i ] = gBattleResources - > bufferB [ 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 ;
2018-11-17 23:47:35 +01:00
gBattleMons [ gActiveBattler ] . type3 = TYPE_MYSTERY ;
2019-05-14 15:22:16 +02:00
gBattleMons [ gActiveBattler ] . ability = GetAbilityBySpecies ( gBattleMons [ gActiveBattler ] . species , gBattleMons [ gActiveBattler ] . abilityNum ) ;
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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
2019-08-23 13:55:36 +02:00
static void Cmd_jumpifcantswitch ( void )
2017-09-24 00:29:52 +02:00
{
2018-02-28 19:37:48 +01:00
s32 i ;
s32 lastMonId ;
2019-01-27 20:54:34 +01:00
u8 battlerIn1 , battlerIn2 ;
2018-02-28 19:37:48 +01:00
struct Pokemon * party ;
2017-09-24 00:29:52 +02:00
2019-09-15 23:58:12 +02:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] & ~ ( SWITCH_IGNORE_ESCAPE_PREVENTION ) ) ;
2017-09-24 00:29:52 +02:00
2019-09-15 23:58:12 +02:00
if ( ! ( gBattlescriptCurrInstr [ 1 ] & SWITCH_IGNORE_ESCAPE_PREVENTION )
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
}
2019-01-27 20:54:34 +01:00
else if ( BATTLE_TWO_VS_ONE_OPPONENT & & GetBattlerSide ( gActiveBattler ) = = B_SIDE_OPPONENT )
{
battlerIn1 = GetBattlerAtPosition ( B_POSITION_OPPONENT_LEFT ) ;
battlerIn2 = GetBattlerAtPosition ( B_POSITION_OPPONENT_RIGHT ) ;
party = gEnemyParty ;
for ( i = 0 ; i < PARTY_SIZE ; i + + )
{
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 ] )
break ;
}
if ( i = = PARTY_SIZE )
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 2 ) ;
else
gBattlescriptCurrInstr + = 6 ;
}
2017-09-24 00:29:52 +02:00
else if ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER )
{
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-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 ;
}
}
2019-10-18 01:22:03 +02:00
static void sub_804CF10 ( u8 slotId )
2017-09-24 00:29:52 +02:00
{
2018-02-06 20:48:02 +01:00
* ( gBattleStruct - > field_58 + gActiveBattler ) = gBattlerPartyIndexes [ gActiveBattler ] ;
2019-10-18 01:22:03 +02:00
* ( gBattleStruct - > monToSwitchIntoId + gActiveBattler ) = PARTY_SIZE ;
2018-02-06 02:46:59 +01:00
gBattleStruct - > field_93 & = ~ ( gBitTable [ gActiveBattler ] ) ;
2017-09-24 00:29:52 +02:00
2019-10-18 01:22:03 +02:00
BtlController_EmitChoosePokemon ( 0 , PARTY_ACTION_SEND_OUT , slotId , ABILITY_NONE , 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
2019-08-23 13:55:36 +02:00
static void Cmd_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
{
2019-10-18 01:22:03 +02:00
sub_804CF10 ( PARTY_SIZE ) ;
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 ;
2019-01-05 16:00:57 +01:00
if ( HasNoMonsToSwitch ( 2 , gBattleResources - > bufferB [ 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 ;
2019-01-05 16:00:57 +01:00
if ( HasNoMonsToSwitch ( 3 , gBattleResources - > bufferB [ 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 )
2019-10-18 01:22:03 +02:00
hitmarkerFaintBits = PARTY_ACTION_CHOOSE_MON ; // Used here as the caseId for the EmitChoose function.
2017-09-25 00:09:13 +02:00
else
2019-10-18 01:22:03 +02:00
hitmarkerFaintBits = PARTY_ACTION_SEND_OUT ;
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
2019-10-18 01:22:03 +02:00
BtlController_EmitChoosePokemon ( 0 , hitmarkerFaintBits , * ( gBattleStruct - > monToSwitchIntoId + ( gActiveBattler ^ 2 ) ) , ABILITY_NONE , gBattleStruct - > field_60 [ gActiveBattler ] ) ;
2018-02-06 20:48:02 +01:00
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
}
}
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
{
2019-01-05 16:00:57 +01:00
if ( gBattleResources - > bufferB [ i ] [ 0 ] = = 0x22 )
2017-09-25 00:09:13 +02:00
{
2019-01-05 16:00:57 +01:00
* ( gBattleStruct - > monToSwitchIntoId + i ) = gBattleResources - > bufferB [ i ] [ 1 ] ;
2017-09-25 00:09:13 +02:00
if ( ! ( gBattleStruct - > field_93 & gBitTable [ i ] ) )
{
2019-01-05 16:00:57 +01:00
RecordedBattle_SetBattlerAction ( i , gBattleResources - > bufferB [ i ] [ 1 ] ) ;
2017-09-25 00:09:13 +02:00
gBattleStruct - > field_93 | = gBitTable [ i ] ;
}
}
}
break ;
case 1 :
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_MULTI ) )
2019-10-26 03:55:01 +02:00
SwitchPartyOrder ( 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
{
2019-01-05 16:00:57 +01:00
RecordedBattle_SetBattlerAction ( gActiveBattler , gBattleResources - > bufferB [ 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 :
2019-01-05 16:00:57 +01:00
gBattleCommunication [ 0 ] = gBattleResources - > bufferB [ gActiveBattler ] [ 1 ] ;
* ( gBattleStruct - > monToSwitchIntoId + gActiveBattler ) = gBattleResources - > bufferB [ 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 ;
2019-01-05 16:00:57 +01:00
* ( gActiveBattler * 3 + ( u8 * ) ( gBattleStruct - > field_60 ) + 0 ) | = ( gBattleResources - > bufferB [ gActiveBattler ] [ 2 ] & 0xF0 ) ;
* ( gActiveBattler * 3 + ( u8 * ) ( gBattleStruct - > field_60 ) + 1 ) = gBattleResources - > bufferB [ 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 ) ;
2019-01-05 16:00:57 +01:00
* ( ( gActiveBattler ^ BIT_FLANK ) * 3 + ( u8 * ) ( gBattleStruct - > field_60 ) + 0 ) | = ( gBattleResources - > bufferB [ gActiveBattler ] [ 2 ] & 0xF0 ) > > 4 ;
* ( ( gActiveBattler ^ BIT_FLANK ) * 3 + ( u8 * ) ( gBattleStruct - > field_60 ) + 2 ) = gBattleResources - > bufferB [ gActiveBattler ] [ 3 ] ;
2017-09-25 00:09:13 +02:00
}
else if ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER )
{
2019-10-26 03:55:01 +02:00
SwitchPartyOrderInGameMulti ( gActiveBattler , * ( gBattleStruct - > monToSwitchIntoId + gActiveBattler ) ) ;
2017-09-25 00:09:13 +02:00
}
else
{
2019-10-26 03:55:01 +02:00
SwitchPartyOrder ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
2018-02-06 23:09:39 +01:00
PREPARE_SPECIES_BUFFER ( gBattleTextBuff1 , gBattleMons [ gBattlerAttacker ] . species )
2019-01-05 16:00:57 +01:00
PREPARE_MON_NICK_BUFFER ( gBattleTextBuff2 , gActiveBattler , gBattleResources - > bufferB [ gActiveBattler ] [ 1 ] )
2017-09-25 00:09:13 +02:00
break ;
}
gBattlescriptCurrInstr + = 3 ;
}
2018-07-24 21:47:00 +02:00
static void SetDmgHazardsBattlescript ( u8 battlerId , u8 multistringId )
{
gBattleMons [ battlerId ] . status2 & = ~ ( STATUS2_DESTINY_BOND ) ;
gHitMarker & = ~ ( HITMARKER_DESTINYBOND ) ;
gBattleScripting . battler = battlerId ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = multistringId ;
BattleScriptPushCursor ( ) ;
if ( gBattlescriptCurrInstr [ 1 ] = = BS_TARGET )
gBattlescriptCurrInstr = BattleScript_DmgHazardsOnTarget ;
else if ( gBattlescriptCurrInstr [ 1 ] = = BS_ATTACKER )
gBattlescriptCurrInstr = BattleScript_DmgHazardsOnAttacker ;
else
gBattlescriptCurrInstr = BattleScript_DmgHazardsOnFaintedBattler ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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-07-24 21:47:00 +02:00
& & IsBattlerGrounded ( gActiveBattler ) )
2017-09-25 00:09:13 +02:00
{
2018-07-24 21:47:00 +02:00
u8 spikesDmg = ( 5 - gSideTimers [ GetBattlerSide ( gActiveBattler ) ] . spikesAmount ) * 2 ;
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gBattleMons [ gActiveBattler ] . maxHP / ( spikesDmg ) ;
2017-09-25 00:09:13 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2018-07-24 21:47:00 +02:00
gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] | = SIDE_STATUS_SPIKES_DAMAGED ;
SetDmgHazardsBattlescript ( gActiveBattler , 0 ) ;
}
else if ( ! ( gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] & SIDE_STATUS_STEALTH_ROCK_DAMAGED )
& & ( gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] & SIDE_STATUS_STEALTH_ROCK ) )
{
gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] | = SIDE_STATUS_STEALTH_ROCK_DAMAGED ;
gBattleMoveDamage = GetStealthHazardDamage ( gBattleMoves [ MOVE_STEALTH_ROCK ] . type , gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
2018-07-24 21:47:00 +02:00
if ( gBattleMoveDamage ! = 0 )
SetDmgHazardsBattlescript ( gActiveBattler , 1 ) ;
}
else if ( ! ( gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] & SIDE_STATUS_TOXIC_SPIKES_DAMAGED )
& & ( gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] & SIDE_STATUS_TOXIC_SPIKES )
& & IsBattlerGrounded ( gActiveBattler ) )
{
gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] | = SIDE_STATUS_TOXIC_SPIKES_DAMAGED ;
if ( IS_BATTLER_OF_TYPE ( gActiveBattler , TYPE_POISON ) ) // Absorb the toxic spikes.
{
gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] & = ~ ( SIDE_STATUS_TOXIC_SPIKES ) ;
gSideTimers [ GetBattlerSide ( gActiveBattler ) ] . toxicSpikesAmount = 0 ;
gBattleScripting . battler = gActiveBattler ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_ToxicSpikesAbsorbed ;
}
2017-09-25 00:09:13 +02:00
else
2018-07-24 21:47:00 +02:00
{
if ( ! ( gBattleMons [ gActiveBattler ] . status1 & STATUS1_ANY )
& & ! IS_BATTLER_OF_TYPE ( gActiveBattler , TYPE_STEEL )
& & GetBattlerAbility ( gActiveBattler ) ! = ABILITY_IMMUNITY
& & ! ( gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] & SIDE_STATUS_SAFEGUARD ) )
{
if ( gSideTimers [ GetBattlerSide ( gActiveBattler ) ] . toxicSpikesAmount > = 2 )
gBattleMons [ gActiveBattler ] . status1 | = STATUS1_TOXIC_POISON ;
else
gBattleMons [ gActiveBattler ] . status1 | = STATUS1_POISON ;
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gActiveBattler ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
gBattleScripting . battler = gActiveBattler ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_ToxicSpikesPoisoned ;
}
}
2017-09-25 00:09:13 +02:00
}
2018-07-24 22:09:55 +02:00
else if ( ! ( gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] & SIDE_STATUS_STICKY_WEB_DAMAGED )
& & ( gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] & SIDE_STATUS_STICKY_WEB )
& & IsBattlerGrounded ( gActiveBattler ) )
{
gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] | = SIDE_STATUS_STICKY_WEB_DAMAGED ;
gBattleScripting . battler = gActiveBattler ;
SET_STATCHANGER ( STAT_SPEED , 1 , TRUE ) ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_StickyWebOnSwitchIn ;
}
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.
2019-08-30 12:51:56 +02:00
if ( gBattleMons [ gActiveBattler ] . ability = = ABILITY_TRUANT
& & gCurrentActionFuncId ! = B_ACTION_USE_MOVE
& & ! 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
2019-08-30 12:25:21 +02:00
if ( AbilityBattleEffects ( ABILITYEFFECT_ON_SWITCHIN , gActiveBattler , 0 , 0 , 0 )
| | ItemBattleEffects ( ITEMEFFECT_ON_SWITCH_IN , gActiveBattler , FALSE )
| | AbilityBattleEffects ( ABILITYEFFECT_INTIMIDATE2 , 0 , 0 , 0 , 0 )
| | AbilityBattleEffects ( ABILITYEFFECT_TRACE2 , 0 , 0 , 0 , 0 )
| | AbilityBattleEffects ( ABILITYEFFECT_FORECAST , 0 , 0 , 0 , 0 ) )
return ;
gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] & = ~ ( SIDE_STATUS_SPIKES_DAMAGED | SIDE_STATUS_TOXIC_SPIKES_DAMAGED | SIDE_STATUS_STEALTH_ROCK_DAMAGED | SIDE_STATUS_STICKY_WEB_DAMAGED ) ;
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-25 00:09:13 +02:00
{
2019-08-30 12:25:21 +02:00
if ( gBattlerByTurnOrder [ i ] = = gActiveBattler )
gActionsByTurnOrder [ i ] = B_ACTION_CANCEL_PARTNER ;
2017-09-25 00:09:13 +02:00
2019-08-30 12:25:21 +02:00
gBattleStruct - > hpOnSwitchout [ GetBattlerSide ( i ) ] = gBattleMons [ i ] . hp ;
}
2017-09-25 00:09:13 +02:00
2019-08-30 12:25:21 +02:00
if ( gBattlescriptCurrInstr [ 1 ] = = 5 )
{
u32 hitmarkerFaintBits = gHitMarker > > 0x1C ;
2017-09-25 00:09:13 +02:00
2019-08-30 12:25:21 +02:00
gBattlerFainted + + ;
while ( 1 )
2017-09-25 00:09:13 +02:00
{
2019-08-30 12:25:21 +02:00
if ( hitmarkerFaintBits & gBitTable [ gBattlerFainted ] & & ! ( gAbsentBattlerFlags & gBitTable [ gBattlerFainted ] ) )
break ;
if ( gBattlerFainted > = gBattlersCount )
break ;
2018-02-08 11:17:41 +01:00
gBattlerFainted + + ;
2017-09-25 00:09:13 +02:00
}
}
2019-08-30 12:25:21 +02:00
gBattlescriptCurrInstr + = 2 ;
2017-09-25 00:09:13 +02:00
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
2019-10-18 01:22:03 +02:00
u16 learnMove = MonTryLearningNewMove ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , gBattlescriptCurrInstr [ 9 ] ) ;
while ( learnMove = = MON_ALREADY_KNOWS_MOVE )
learnMove = MonTryLearningNewMove ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , FALSE ) ;
2017-09-25 00:09:13 +02:00
2019-10-18 01:22:03 +02:00
if ( learnMove = = 0 )
2017-09-25 00:09:13 +02:00
{
gBattlescriptCurrInstr = jumpPtr2 ;
}
2019-10-18 01:22:03 +02:00
else if ( learnMove = = MON_HAS_MAX_MOVES )
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
{
2019-10-18 01:22:03 +02:00
GiveMoveToBattleMon ( & gBattleMons [ gActiveBattler ] , learnMove ) ;
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
{
2019-10-18 01:22:03 +02:00
GiveMoveToBattleMon ( & gBattleMons [ gActiveBattler ] , learnMove ) ;
2017-09-25 00:09:13 +02:00
}
}
gBattlescriptCurrInstr = jumpPtr1 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 )
{
2019-10-18 01:22:03 +02:00
u8 movePosition = GetMoveSlotToReplace ( ) ;
if ( movePosition = = MAX_MON_MOVES )
2017-09-25 00:09:13 +02:00
{
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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
2019-08-25 15:33:28 +02:00
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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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-08-02 20:24:18 +02:00
else if ( ! ( gHitMarker & HITMARKER_IGNORE_SUBSTITUTE ) | | ! ( DoesSubstituteBlockMove ( gBattlerAttacker , gActiveBattler , gCurrentMove ) ) | | 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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
2019-01-05 16:00:57 +01:00
struct BattlePokemon * bufferPoke = ( struct BattlePokemon * ) & gBattleResources - > bufferB [ 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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 )
{
hpStatuses [ i ] . hp = 0xFFFF ;
hpStatuses [ i ] . status = 0 ;
}
else
{
hpStatuses [ i ] . hp = GetMonData ( & party [ i ] , MON_DATA_HP ) ;
hpStatuses [ i ] . status = GetMonData ( & party [ i ] , MON_DATA_STATUS ) ;
}
}
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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ] ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-11-10 12:09:14 +01:00
static void Cmd_setgravity ( void )
2017-09-25 00:09:13 +02:00
{
2018-07-21 16:34:43 +02:00
if ( gFieldStatuses & STATUS_FIELD_GRAVITY )
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
u32 i ;
gFieldStatuses | = STATUS_FIELD_GRAVITY ;
gFieldTimers . gravityTimer = 5 ;
gBattlescriptCurrInstr + = 5 ;
}
2017-09-25 00:09:13 +02:00
}
2017-09-26 22:39:59 +02:00
2019-08-23 13:55:36 +02:00
static void Cmd_removeitem ( void )
2017-09-26 22:39:59 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2019-05-09 20:31:58 +02:00
// Popped Air Balloon cannot be restored by no means.
if ( GetBattlerHoldEffect ( gActiveBattler , TRUE ) ! = HOLD_EFFECT_AIR_BALLOON )
gBattleStruct - > usedHeldItems [ gActiveBattler ] = gBattleMons [ gActiveBattler ] . item ;
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . item = 0 ;
2019-12-23 18:25:26 +01:00
CheckSetUnburden ( gActiveBattler ) ;
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
2019-05-09 20:31:58 +02:00
ClearBattlerItemEffectHistory ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 2 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_atknameinbuff1 ( void )
2017-09-26 22:39:59 +02:00
{
2019-05-09 20:31:58 +02:00
PREPARE_MON_NICK_BUFFER ( gBattleTextBuff1 , gBattlerAttacker , gBattlerPartyIndexes [ gBattlerAttacker ] ) ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_drawlvlupbox ( void )
2017-09-26 22:39:59 +02:00
{
2019-08-23 14:46:21 +02:00
if ( gBattleScripting . drawlvlupboxState = = 0 )
2017-09-26 22:39:59 +02:00
{
if ( IsMonGettingExpSentOut ( ) )
2019-08-23 14:46:21 +02:00
gBattleScripting . drawlvlupboxState = 3 ;
2017-09-26 22:39:59 +02:00
else
2019-08-23 14:46:21 +02:00
gBattleScripting . drawlvlupboxState = 1 ;
2017-09-26 22:39:59 +02:00
}
2019-08-23 14:46:21 +02:00
switch ( gBattleScripting . drawlvlupboxState )
2017-09-26 22:39:59 +02:00
{
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 ( ) ;
2019-08-23 14:46:21 +02:00
gBattleScripting . drawlvlupboxState = 2 ;
2017-09-26 22:39:59 +02:00
break ;
case 2 :
if ( ! sub_804F1CC ( ) )
2019-08-23 14:46:21 +02:00
gBattleScripting . drawlvlupboxState = 3 ;
2017-09-26 22:39:59 +02:00
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 ) ;
2019-08-23 14:46:21 +02:00
gBattleScripting . drawlvlupboxState = 4 ;
2017-09-26 22:39:59 +02:00
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 ) ;
2019-08-23 14:46:21 +02:00
gBattleScripting . drawlvlupboxState + + ;
2017-09-26 22:39:59 +02:00
break ;
case 5 :
case 7 :
if ( ! IsDma3ManagerBusyWithBgCopy ( ) )
{
gBattle_BG1_Y = 0 ;
2019-08-23 14:46:21 +02:00
gBattleScripting . drawlvlupboxState + + ;
2017-09-26 22:39:59 +02:00
}
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 ) ;
2019-08-23 14:46:21 +02:00
gBattleScripting . drawlvlupboxState + + ;
2017-09-26 22:39:59 +02:00
}
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 ) ;
2019-08-23 14:46:21 +02:00
gBattleScripting . drawlvlupboxState + + ;
2017-09-26 22:39:59 +02:00
}
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 ) ;
2019-08-23 14:46:21 +02:00
gBattleScripting . drawlvlupboxState = 10 ;
2017-09-26 22:39:59 +02:00
}
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 ) ;
2019-12-10 19:48:20 +01:00
DrawLevelUpWindowPg1 ( 0xD , gBattleResources - > beforeLvlUp - > stats , currStats , TEXT_DYNAMIC_COLOR_5 , TEXT_DYNAMIC_COLOR_4 , TEXT_DYNAMIC_COLOR_6 ) ;
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 ) ;
2019-12-10 19:48:20 +01:00
DrawLevelUpWindowPg2 ( 0xD , currStats , TEXT_DYNAMIC_COLOR_5 , TEXT_DYNAMIC_COLOR_4 , TEXT_DYNAMIC_COLOR_6 ) ;
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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_resetsentmonsvalue ( void )
2017-09-26 22:39:59 +02:00
{
ResetSentPokesToOpponentValue ( ) ;
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_makevisible ( void )
2017-09-26 22:39:59 +02:00
{
2018-07-26 20:36:16 +02:00
if ( gBattleControllerExecFlags )
return ;
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 ;
}
2019-11-10 12:09:14 +01:00
static void Cmd_recordability ( void )
2017-09-26 22:39:59 +02:00
{
2018-07-22 18:40:18 +02:00
u8 battler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
RecordAbilityBattle ( battler , gBattleMons [ battler ] . ability ) ;
gBattlescriptCurrInstr + = 2 ;
2017-09-26 22:39:59 +02:00
}
void BufferMoveToLearnIntoBattleTextBuff2 ( void )
{
PREPARE_MOVE_BUFFER ( gBattleTextBuff2 , gMoveToLearn ) ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_buffermovetolearn ( void )
2017-09-26 22:39:59 +02:00
{
BufferMoveToLearnIntoBattleTextBuff2 ( ) ;
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2018-07-26 23:40:55 +02:00
static bool32 HasAttackerFaintedTarget ( void )
{
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
& & gBattleMoves [ gCurrentMove ] . power ! = 0
& & ( gLastHitBy [ gBattlerTarget ] = = 0xFF | | gLastHitBy [ gBattlerTarget ] = = gBattlerAttacker )
& & gBattleStruct - > moveTarget [ gBattlerAttacker ] = = gBattlerTarget
& & gBattlerTarget ! = gBattlerAttacker
& & gCurrentTurnActionNumber = = GetBattlerTurnOrderNum ( gBattlerAttacker )
& & gChosenMove = = gChosenMoveByBattler [ gBattlerAttacker ] )
return TRUE ;
else
return FALSE ;
}
2018-08-05 12:43:57 +02:00
static void HandleTerrainMove ( u32 moveEffect )
{
u32 statusFlag = 0 ;
u8 * timer = NULL ;
switch ( moveEffect )
{
case EFFECT_MISTY_TERRAIN :
statusFlag = STATUS_FIELD_MISTY_TERRAIN , timer = & gFieldTimers . mistyTerrainTimer ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
break ;
case EFFECT_GRASSY_TERRAIN :
statusFlag = STATUS_FIELD_GRASSY_TERRAIN , timer = & gFieldTimers . grassyTerrainTimer ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
break ;
case EFFECT_ELECTRIC_TERRAIN :
statusFlag = STATUS_FIELD_ELECTRIC_TERRAIN , timer = & gFieldTimers . electricTerrainTimer ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
break ;
case EFFECT_PSYCHIC_TERRAIN :
statusFlag = STATUS_FIELD_PSYCHIC_TERRAIN , timer = & gFieldTimers . psychicTerrainTimer ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 3 ;
break ;
}
if ( gFieldStatuses & statusFlag | | statusFlag = = 0 )
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
}
else
{
2019-02-09 14:30:16 +01:00
gFieldStatuses & = ~ ( STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_GRASSY_TERRAIN | STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_PSYCHIC_TERRAIN ) ;
2018-08-05 12:43:57 +02:00
gFieldStatuses | = statusFlag ;
2019-02-09 14:30:16 +01:00
if ( GetBattlerHoldEffect ( gBattlerAttacker , TRUE ) = = HOLD_EFFECT_TERRAIN_EXTENDER )
* timer = 8 ;
else
* timer = 5 ;
2018-08-05 12:43:57 +02:00
gBattlescriptCurrInstr + = 7 ;
}
}
2018-09-22 10:45:43 +02:00
bool32 CanUseLastResort ( u8 battlerId )
{
u32 i ;
u32 knownMovesCount = 0 , usedMovesCount = 0 ;
for ( i = 0 ; i < 4 ; i + + )
{
if ( gBattleMons [ battlerId ] . moves [ i ] ! = MOVE_NONE )
knownMovesCount + + ;
if ( gDisableStructs [ battlerId ] . usedMoves & gBitTable [ i ] )
usedMovesCount + + ;
}
if ( knownMovesCount > = 2 & & usedMovesCount > = knownMovesCount - 1 )
return TRUE ;
else
return FALSE ;
}
2018-09-23 19:03:53 +02:00
# define DEFOG_CLEAR(status, structField, battlescript, move)\
{ \
if ( * sideStatuses & status ) \
{ \
if ( clear ) \
{ \
if ( move ) \
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , move ) ; \
* sideStatuses & = ~ ( status ) ; \
sideTimer - > structField = 0 ; \
BattleScriptPushCursor ( ) ; \
gBattlescriptCurrInstr = battlescript ; \
} \
return TRUE ; \
} \
}
static bool32 ClearDefogHazards ( u8 battlerAtk , bool32 clear )
{
s32 i ;
for ( i = 0 ; i < 2 ; i + + )
{
struct SideTimer * sideTimer = & gSideTimers [ i ] ;
u32 * sideStatuses = & gSideStatuses [ i ] ;
gBattlerAttacker = i ;
if ( GetBattlerSide ( battlerAtk ) ! = i )
{
DEFOG_CLEAR ( SIDE_STATUS_REFLECT , reflectTimer , BattleScript_SideStatusWoreOffReturn , MOVE_REFLECT ) ;
DEFOG_CLEAR ( SIDE_STATUS_LIGHTSCREEN , lightscreenTimer , BattleScript_SideStatusWoreOffReturn , MOVE_LIGHT_SCREEN ) ;
DEFOG_CLEAR ( SIDE_STATUS_MIST , mistTimer , BattleScript_SideStatusWoreOffReturn , MOVE_MIST ) ;
DEFOG_CLEAR ( SIDE_STATUS_AURORA_VEIL , auroraVeilTimer , BattleScript_SideStatusWoreOffReturn , MOVE_AURORA_VEIL ) ;
DEFOG_CLEAR ( SIDE_STATUS_SAFEGUARD , safeguardTimer , BattleScript_SideStatusWoreOffReturn , MOVE_SAFEGUARD ) ;
}
DEFOG_CLEAR ( SIDE_STATUS_SPIKES , spikesAmount , BattleScript_SpikesFree , 0 ) ;
DEFOG_CLEAR ( SIDE_STATUS_STEALTH_ROCK , stealthRockAmount , BattleScript_StealthRockFree , 0 ) ;
DEFOG_CLEAR ( SIDE_STATUS_TOXIC_SPIKES , toxicSpikesAmount , BattleScript_ToxicSpikesFree , 0 ) ;
DEFOG_CLEAR ( SIDE_STATUS_STICKY_WEB , stickyWebAmount , BattleScript_StickyWebFree , 0 ) ;
}
return FALSE ;
}
2019-03-31 21:38:58 +02:00
u32 IsFlowerVeilProtected ( u32 battler )
{
if ( IS_BATTLER_OF_TYPE ( battler , TYPE_GRASS ) )
return IsAbilityOnSide ( battler , ABILITY_FLOWER_VEIL ) ;
else
return 0 ;
}
2019-12-16 09:29:20 +01:00
u32 IsLeafGuardProtected ( u32 battler )
{
if ( WEATHER_HAS_EFFECT & & ( gBattleWeather & WEATHER_SUN_ANY ) )
return GetBattlerAbility ( battler ) = = ABILITY_LEAF_GUARD ;
else
return 0 ;
}
2019-11-10 12:09:14 +01:00
static void Cmd_various ( void )
2017-09-26 22:39:59 +02:00
{
2018-09-16 18:55:32 +02:00
struct Pokemon * mon ;
2018-08-04 22:23:07 +02:00
s32 i , j ;
2018-07-26 20:36:16 +02:00
u8 data [ 10 ] ;
2019-08-08 13:06:55 +02:00
u32 side , bits ;
2018-07-26 20:36:16 +02:00
if ( gBattleControllerExecFlags )
return ;
2017-09-26 22:39:59 +02:00
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-26 22:39:59 +02:00
switch ( gBattlescriptCurrInstr [ 2 ] )
{
2019-03-06 12:09:34 +01:00
// Roar will fail in a double wild battle when used by the player against one of the two alive wild mons.
// Also when an opposing wild mon uses it againt its partner.
case VARIOUS_JUMP_IF_ROAR_FAILS :
if ( WILD_DOUBLE_BATTLE
& & GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_PLAYER
& & GetBattlerSide ( gBattlerTarget ) = = B_SIDE_OPPONENT
& & IS_WHOLE_SIDE_ALIVE ( gBattlerTarget ) )
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
else if ( WILD_DOUBLE_BATTLE
& & GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_OPPONENT
& & GetBattlerSide ( gBattlerTarget ) = = B_SIDE_OPPONENT )
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
else
gBattlescriptCurrInstr + = 7 ;
return ;
2019-08-05 11:24:49 +02:00
case VARIOUS_TRACE_ABILITY :
gBattleMons [ gActiveBattler ] . ability = gBattleStruct - > tracedAbility [ gActiveBattler ] ;
break ;
2019-08-08 13:06:55 +02:00
case VARIOUS_TRY_ILLUSION_OFF :
if ( GetIllusionMonPtr ( gActiveBattler ) ! = NULL )
{
gBattlescriptCurrInstr + = 3 ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_IllusionOff ;
return ;
}
break ;
case VARIOUS_SET_SPRITEIGNORE0HP :
gBattleStruct - > spriteIgnore0Hp = gBattlescriptCurrInstr [ 3 ] ;
gBattlescriptCurrInstr + = 4 ;
return ;
case VARIOUS_UPDATE_NICK :
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_PLAYER )
mon = & gPlayerParty [ gBattlerPartyIndexes [ gActiveBattler ] ] ;
else
mon = & gEnemyParty [ gBattlerPartyIndexes [ gActiveBattler ] ] ;
UpdateHealthboxAttribute ( gHealthboxSpriteIds [ gActiveBattler ] , mon , HEALTHBOX_NICK ) ;
break ;
2019-05-20 12:03:00 +02:00
case VARIOUS_JUMP_IF_NOT_BERRY :
if ( ItemId_GetPocket ( gBattleMons [ gActiveBattler ] . item ) = = POCKET_BERRIES )
gBattlescriptCurrInstr + = 7 ;
else
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
return ;
2019-02-28 15:02:54 +01:00
case VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS :
2019-03-02 23:54:08 +01:00
if ( ( gStatuses3 [ gActiveBattler ] & ( STATUS3_SEMI_INVULNERABLE ) )
| | BATTLER_MAX_HP ( gActiveBattler )
| | ! gBattleMons [ gActiveBattler ] . hp
| | ! ( IsBattlerGrounded ( gActiveBattler ) ) )
2019-02-28 15:02:54 +01:00
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
2019-03-02 23:54:08 +01:00
}
else
{
gBattleMoveDamage = gBattleMons [ gActiveBattler ] . maxHP / 16 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleMoveDamage * = - 1 ;
2019-02-28 15:02:54 +01:00
2019-03-02 23:54:08 +01:00
gBattlescriptCurrInstr + = 7 ;
}
2019-02-28 15:02:54 +01:00
return ;
2019-02-22 23:48:28 +01:00
case VARIOUS_GRAVITY_ON_AIRBORNE_MONS :
if ( gStatuses3 [ gActiveBattler ] & STATUS3_ON_AIR )
CancelMultiTurnMoves ( gActiveBattler ) ;
2019-03-01 13:53:06 +01:00
2019-02-22 23:48:28 +01:00
gStatuses3 [ gActiveBattler ] & = ~ ( STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS | STATUS3_ON_AIR ) ;
break ;
2019-02-14 12:15:53 +01:00
case VARIOUS_SPECTRAL_THIEF :
// Raise stats
for ( i = STAT_ATK ; i < NUM_BATTLE_STATS ; i + + )
{
if ( gBattleStruct - > stolenStats [ 0 ] & gBitTable [ i ] )
{
gBattleStruct - > stolenStats [ 0 ] & = ~ ( gBitTable [ i ] ) ;
SET_STATCHANGER ( i , gBattleStruct - > stolenStats [ i ] , FALSE ) ;
2019-02-14 19:48:21 +01:00
if ( ChangeStatBuffs ( GET_STAT_BUFF_VALUE_WITH_SIGN ( gBattleScripting . statChanger ) , i , MOVE_EFFECT_CERTAIN | MOVE_EFFECT_AFFECTS_USER , NULL ) = = STAT_CHANGE_WORKED )
2019-02-14 12:15:53 +01:00
{
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_StatUpMsg ;
return ;
}
}
}
break ;
2018-12-03 12:50:32 +01:00
case VARIOUS_SET_POWDER :
gBattleMons [ gActiveBattler ] . status2 | = STATUS2_POWDER ;
break ;
2018-11-24 21:06:53 +01:00
case VARIOUS_ACUPRESSURE :
bits = 0 ;
for ( i = STAT_ATK ; i < NUM_BATTLE_STATS ; i + + )
{
if ( gBattleMons [ gActiveBattler ] . statStages [ i ] ! = 12 )
bits | = gBitTable [ i ] ;
}
if ( bits )
{
u32 statId ;
do
{
statId = ( Random ( ) % NUM_BATTLE_STATS ) + 1 ;
} while ( ! ( bits & gBitTable [ statId ] ) ) ;
if ( gBattleMons [ gActiveBattler ] . statStages [ statId ] > = 11 )
SET_STATCHANGER ( statId , 1 , FALSE ) ;
else
SET_STATCHANGER ( statId , 2 , FALSE ) ;
gBattlescriptCurrInstr + = 7 ;
}
else
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
}
return ;
2017-09-26 22:39:59 +02:00
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 ;
2018-07-22 22:21:47 +02:00
gSpecialStatuses [ gActiveBattler ] . switchInAbilityDone = 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
{
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-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-26 22:39:59 +02:00
{
2019-01-27 13:52:02 +01:00
if ( gBattleMons [ gActiveBattler ] . moves [ i ] = = gBattleStruct - > choicedMove [ gActiveBattler ] )
2017-09-26 22:39:59 +02:00
break ;
}
2018-12-25 18:50:15 +01:00
if ( i = = MAX_MON_MOVES )
2019-01-27 13:52:02 +01:00
gBattleStruct - > choicedMove [ gActiveBattler ] = 0 ;
2017-09-26 22:39:59 +02:00
}
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-09-01 12:38:38 +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-09-01 12:38:38 +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-11-23 22:26:36 +01:00
// Don't end the battle if one of the wild mons teleported from the wild double battle
// and its partner is still alive.
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_OPPONENT & & IsBattlerAlive ( BATTLE_PARTNER ( gActiveBattler ) ) )
{
gAbsentBattlerFlags | = gBitTable [ gActiveBattler ] ;
gHitMarker | = HITMARKER_FAINTED ( gActiveBattler ) ;
gBattleMons [ gActiveBattler ] . hp = 0 ;
SetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gActiveBattler ] ] , MON_DATA_HP , & gBattleMons [ gActiveBattler ] . hp ) ;
SetHealthboxSpriteInvisible ( gHealthboxSpriteIds [ gActiveBattler ] ) ;
FaintClearSetData ( ) ;
}
else if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_PLAYER )
{
2018-01-16 22:12:38 +01:00
gBattleOutcome = B_OUTCOME_PLAYER_TELEPORTED ;
2018-11-23 22:26:36 +01:00
}
2017-09-26 22:39:59 +02:00
else
2018-11-23 22:26:36 +01:00
{
2018-02-08 00:35:13 +01:00
gBattleOutcome = B_OUTCOME_MON_TELEPORTED ;
2018-11-23 22:26:36 +01:00
}
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 ;
2018-07-22 18:40:18 +02:00
case VARIOUS_STAT_TEXT_BUFFER :
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , gBattleCommunication [ 0 ] ) ;
break ;
case VARIOUS_SWITCHIN_ABILITIES :
gBattlescriptCurrInstr + = 3 ;
AbilityBattleEffects ( ABILITYEFFECT_ON_SWITCHIN , gActiveBattler , 0 , 0 , 0 ) ;
return ;
2018-07-24 22:09:55 +02:00
case VARIOUS_SAVE_TARGET :
gBattleStruct - > savedBattlerTarget = gBattlerTarget ;
break ;
case VARIOUS_RESTORE_TARGET :
gBattlerTarget = gBattleStruct - > savedBattlerTarget ;
break ;
2018-07-26 20:36:16 +02:00
case VARIOUS_INSTANT_HP_DROP :
BtlController_EmitHealthBarUpdate ( 0 , INSTANT_HP_BAR_DROP ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
break ;
case VARIOUS_CLEAR_STATUS :
gBattleMons [ gActiveBattler ] . status1 = 0 ;
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gActiveBattler ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
break ;
case VARIOUS_RESTORE_PP :
for ( i = 0 ; i < 4 ; i + + )
{
gBattleMons [ gActiveBattler ] . pp [ i ] = CalculatePPWithBonus ( gBattleMons [ gActiveBattler ] . moves [ i ] , gBattleMons [ gActiveBattler ] . ppBonuses , i ) ;
data [ i ] = gBattleMons [ gActiveBattler ] . pp [ i ] ;
}
data [ i ] = gBattleMons [ gActiveBattler ] . ppBonuses ;
BtlController_EmitSetMonData ( 0 , REQUEST_PP_DATA_BATTLE , 0 , 5 , data ) ;
2018-07-27 22:24:07 +02:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2018-07-26 20:36:16 +02:00
break ;
2018-07-26 22:52:13 +02:00
case VARIOUS_TRY_ACTIVATE_MOXIE :
if ( GetBattlerAbility ( gActiveBattler ) = = ABILITY_MOXIE
2018-07-26 23:40:55 +02:00
& & HasAttackerFaintedTarget ( )
2019-08-22 15:57:33 +02:00
& & ! NoAliveMonsForEitherParty ( )
2018-07-27 23:40:10 +02:00
& & gBattleMons [ gBattlerAttacker ] . statStages [ STAT_ATK ] ! = 12 )
2018-07-26 22:52:13 +02:00
{
gBattleMons [ gBattlerAttacker ] . statStages [ STAT_ATK ] + + ;
SET_STATCHANGER ( STAT_ATK , 1 , FALSE ) ;
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , STAT_ATK ) ;
BattleScriptPush ( gBattlescriptCurrInstr + 3 ) ;
gBattlescriptCurrInstr = BattleScript_AttackerAbilityStatRaise ;
return ;
}
break ;
2018-07-26 23:40:55 +02:00
case VARIOUS_TRY_ACTIVATE_FELL_STINGER :
if ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_FELL_STINGER
& & HasAttackerFaintedTarget ( )
2019-08-22 15:57:33 +02:00
& & ! NoAliveMonsForEitherParty ( )
2018-07-27 23:40:10 +02:00
& & gBattleMons [ gBattlerAttacker ] . statStages [ STAT_ATK ] ! = 12 )
2018-07-26 23:40:55 +02:00
{
2018-07-27 23:40:10 +02:00
if ( gBattleMons [ gBattlerAttacker ] . statStages [ STAT_ATK ] > = 11 )
2018-07-26 23:40:55 +02:00
SET_STATCHANGER ( STAT_ATK , 1 , FALSE ) ;
2018-07-27 23:40:10 +02:00
else if ( gBattleMons [ gBattlerAttacker ] . statStages [ STAT_ATK ] < = 9 & & B_FELL_STINGER_STAT_RAISE = = GEN_7 )
SET_STATCHANGER ( STAT_ATK , 3 , FALSE ) ;
2018-07-26 23:40:55 +02:00
else
SET_STATCHANGER ( STAT_ATK , 2 , FALSE ) ;
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , STAT_ATK ) ;
BattleScriptPush ( gBattlescriptCurrInstr + 3 ) ;
gBattlescriptCurrInstr = BattleScript_FellStingerRaisesStat ;
return ;
}
break ;
2018-07-29 12:21:28 +02:00
case VARIOUS_PLAY_MOVE_ANIMATION :
BtlController_EmitMoveAnimation ( 0 , T1_READ_16 ( gBattlescriptCurrInstr + 3 ) , gBattleScripting . animTurn , 0 , 0 , gBattleMons [ gActiveBattler ] . friendship , & gDisableStructs [ gActiveBattler ] , gMultiHitCounter ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
gBattlescriptCurrInstr + = 5 ;
return ;
2018-08-04 20:36:24 +02:00
case VARIOUS_SET_LUCKY_CHANT :
if ( ! ( gSideStatuses [ GET_BATTLER_SIDE ( gActiveBattler ) ] & SIDE_STATUS_LUCKY_CHANT ) )
{
gSideStatuses [ GET_BATTLER_SIDE ( gActiveBattler ) ] | = SIDE_STATUS_LUCKY_CHANT ;
gSideTimers [ GET_BATTLER_SIDE ( gActiveBattler ) ] . luckyChantBattlerId = gActiveBattler ;
gSideTimers [ GET_BATTLER_SIDE ( gActiveBattler ) ] . luckyChantTimer = 5 ;
gBattlescriptCurrInstr + = 7 ;
}
else
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
}
return ;
case VARIOUS_SUCKER_PUNCH_CHECK :
if ( GetBattlerTurnOrderNum ( gBattlerAttacker ) > GetBattlerTurnOrderNum ( gBattlerTarget ) )
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
else if ( gBattleMoves [ gBattleMons [ gBattlerTarget ] . moves [ gBattleStruct - > chosenMovePositions [ gBattlerTarget ] ] ] . power = = 0 )
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
else
gBattlescriptCurrInstr + = 7 ;
return ;
2018-08-04 22:23:07 +02:00
case VARIOUS_SET_SIMPLE_BEAM :
switch ( gBattleMons [ gActiveBattler ] . ability )
{
case ABILITY_SIMPLE :
case ABILITY_TRUANT :
case ABILITY_STANCE_CHANGE :
case ABILITY_MULTITYPE :
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
break ;
default :
gBattleMons [ gActiveBattler ] . ability = ABILITY_SIMPLE ;
gBattlescriptCurrInstr + = 7 ;
break ;
}
return ;
case VARIOUS_TRY_ENTRAINMENT :
switch ( gBattleMons [ gBattlerTarget ] . ability )
{
case ABILITY_TRUANT :
case ABILITY_MULTITYPE :
case ABILITY_STANCE_CHANGE :
case ABILITY_SCHOOLING :
case ABILITY_COMATOSE :
case ABILITY_SHIELDS_DOWN :
case ABILITY_DISGUISE :
case ABILITY_RKS_SYSTEM :
case ABILITY_BATTLE_BOND :
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
return ;
}
switch ( gBattleMons [ gBattlerAttacker ] . ability )
{
case ABILITY_TRACE :
case ABILITY_FORECAST :
case ABILITY_FLOWER_GIFT :
case ABILITY_ZEN_MODE :
case ABILITY_ILLUSION :
case ABILITY_IMPOSTER :
case ABILITY_POWER_OF_ALCHEMY :
case ABILITY_RECEIVER :
case ABILITY_DISGUISE :
case ABILITY_POWER_CONSTRUCT :
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
return ;
}
if ( gBattleMons [ gBattlerTarget ] . ability = = gBattleMons [ gBattlerAttacker ] . ability )
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
}
else
{
gBattleMons [ gBattlerTarget ] . ability = gBattleMons [ gBattlerAttacker ] . ability ;
gBattlescriptCurrInstr + = 7 ;
}
return ;
case VARIOUS_SET_LAST_USED_ABILITY :
gLastUsedAbility = gBattleMons [ gActiveBattler ] . ability ;
break ;
case VARIOUS_TRY_HEAL_PULSE :
if ( BATTLER_MAX_HP ( gActiveBattler ) )
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
}
else
{
if ( GetBattlerAbility ( gBattlerAttacker ) = = ABILITY_MEGA_LAUNCHER & & gBattleMoves [ gCurrentMove ] . flags & FLAG_MEGA_LAUNCHER_BOOST )
gBattleMoveDamage = - ( gBattleMons [ gActiveBattler ] . maxHP * 75 / 100 ) ;
else
gBattleMoveDamage = - ( gBattleMons [ gActiveBattler ] . maxHP / 2 ) ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = - 1 ;
gBattlescriptCurrInstr + = 7 ;
}
return ;
case VARIOUS_TRY_QUASH :
if ( GetBattlerTurnOrderNum ( gBattlerAttacker ) > GetBattlerTurnOrderNum ( gBattlerTarget ) )
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
}
else
{
for ( i = 0 ; i < gBattlersCount ; i + + )
data [ i ] = gBattlerByTurnOrder [ i ] ;
for ( i = 0 ; i < gBattlersCount ; i + + )
{
if ( data [ i ] = = gBattlerTarget )
{
for ( j = i + 1 ; j < gBattlersCount ; j + + )
data [ i + + ] = data [ j ] ;
}
else
{
gBattlerByTurnOrder [ i ] = data [ i ] ;
}
}
gBattlerByTurnOrder [ gBattlersCount - 1 ] = gBattlerTarget ;
gBattlescriptCurrInstr + = 7 ;
}
return ;
2018-08-04 23:34:29 +02:00
case VARIOUS_INVERT_STAT_STAGES :
2018-11-18 20:49:52 +01:00
for ( i = 0 ; i < NUM_BATTLE_STATS ; i + + )
2018-08-04 23:34:29 +02:00
{
if ( gBattleMons [ gActiveBattler ] . statStages [ i ] < 6 ) // Negative becomes positive.
gBattleMons [ gActiveBattler ] . statStages [ i ] = 6 + ( 6 - gBattleMons [ gActiveBattler ] . statStages [ i ] ) ;
else if ( gBattleMons [ gActiveBattler ] . statStages [ i ] > 6 ) // Positive becomes negative.
gBattleMons [ gActiveBattler ] . statStages [ i ] = 6 - ( gBattleMons [ gActiveBattler ] . statStages [ i ] - 6 ) ;
}
break ;
2018-08-05 12:43:57 +02:00
case VARIOUS_SET_TERRAIN :
HandleTerrainMove ( gBattleMoves [ gCurrentMove ] . effect ) ;
return ;
2018-08-05 16:43:07 +02:00
case VARIOUS_TRY_ME_FIRST :
if ( GetBattlerTurnOrderNum ( gBattlerAttacker ) > GetBattlerTurnOrderNum ( gBattlerTarget ) )
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
else if ( gBattleMoves [ gBattleMons [ gBattlerTarget ] . moves [ gBattleStruct - > chosenMovePositions [ gBattlerTarget ] ] ] . power = = 0 )
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
else
{
u16 move = gBattleMons [ gBattlerTarget ] . moves [ gBattleStruct - > chosenMovePositions [ gBattlerTarget ] ] ;
switch ( move )
{
case MOVE_STRUGGLE :
case MOVE_CHATTER :
case MOVE_FOCUS_PUNCH :
case MOVE_THIEF :
case MOVE_COVET :
case MOVE_COUNTER :
case MOVE_MIRROR_COAT :
case MOVE_METAL_BURST :
case MOVE_ME_FIRST :
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
break ;
default :
2018-09-22 19:27:56 +02:00
gCalledMove = move ;
2018-08-05 16:43:07 +02:00
gHitMarker & = ~ ( HITMARKER_ATTACKSTRING_PRINTED ) ;
2018-09-22 19:27:56 +02:00
gBattlerTarget = GetMoveTarget ( gCalledMove , 0 ) ;
2018-08-05 16:43:07 +02:00
gStatuses3 [ gBattlerAttacker ] | = STATUS3_ME_FIRST ;
gBattlescriptCurrInstr + = 7 ;
break ;
}
}
return ;
2018-08-11 12:16:00 +02:00
case VARIOUS_JUMP_IF_BATTLE_END :
2019-08-22 15:57:33 +02:00
if ( NoAliveMonsForEitherParty ( ) )
2018-08-11 12:16:00 +02:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
else
gBattlescriptCurrInstr + = 7 ;
return ;
2018-08-11 13:30:34 +02:00
case VARIOUS_TRY_ELECTRIFY :
if ( GetBattlerTurnOrderNum ( gBattlerAttacker ) > GetBattlerTurnOrderNum ( gBattlerTarget ) )
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
}
else
{
gStatuses3 [ gBattlerTarget ] | = STATUS3_ELECTRIFIED ;
gBattlescriptCurrInstr + = 7 ;
}
return ;
case VARIOUS_TRY_REFLECT_TYPE :
if ( gBattleMons [ gBattlerTarget ] . species = = SPECIES_ARCEUS | | gBattleMons [ gBattlerTarget ] . species = = SPECIES_SILVALLY )
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
}
else if ( gBattleMons [ gBattlerTarget ] . type1 = = TYPE_MYSTERY & & gBattleMons [ gBattlerTarget ] . type2 ! = TYPE_MYSTERY )
{
gBattleMons [ gBattlerAttacker ] . type1 = gBattleMons [ gBattlerTarget ] . type2 ;
gBattleMons [ gBattlerAttacker ] . type2 = gBattleMons [ gBattlerTarget ] . type2 ;
gBattlescriptCurrInstr + = 7 ;
}
else if ( gBattleMons [ gBattlerTarget ] . type1 ! = TYPE_MYSTERY & & gBattleMons [ gBattlerTarget ] . type2 = = TYPE_MYSTERY )
{
gBattleMons [ gBattlerAttacker ] . type1 = gBattleMons [ gBattlerTarget ] . type1 ;
gBattleMons [ gBattlerAttacker ] . type2 = gBattleMons [ gBattlerTarget ] . type1 ;
gBattlescriptCurrInstr + = 7 ;
}
else if ( gBattleMons [ gBattlerTarget ] . type1 = = TYPE_MYSTERY & & gBattleMons [ gBattlerTarget ] . type2 = = TYPE_MYSTERY )
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
}
else
{
gBattleMons [ gBattlerAttacker ] . type1 = gBattleMons [ gBattlerTarget ] . type1 ;
gBattleMons [ gBattlerAttacker ] . type2 = gBattleMons [ gBattlerTarget ] . type2 ;
gBattlescriptCurrInstr + = 7 ;
}
return ;
case VARIOUS_TRY_SOAK :
if ( gBattleMons [ gBattlerTarget ] . type1 = = TYPE_WATER & & gBattleMons [ gBattlerTarget ] . type2 = = TYPE_WATER )
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
}
else
{
SET_BATTLER_TYPE ( gBattlerTarget , TYPE_WATER ) ;
gBattlescriptCurrInstr + = 7 ;
}
return ;
2018-09-16 18:55:32 +02:00
case VARIOUS_HANDLE_MEGA_EVO :
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_OPPONENT )
mon = & gEnemyParty [ gBattlerPartyIndexes [ gActiveBattler ] ] ;
else
mon = & gPlayerParty [ gBattlerPartyIndexes [ gActiveBattler ] ] ;
2018-09-20 11:23:12 +02:00
2019-05-02 23:10:01 +02:00
// Change species.
if ( gBattlescriptCurrInstr [ 3 ] = = 0 )
2018-09-20 11:23:12 +02:00
{
2019-05-02 23:10:01 +02:00
gBattleStruct - > mega . evolvedSpecies [ gActiveBattler ] = gBattleMons [ gActiveBattler ] . species ;
if ( GetBattlerPosition ( gActiveBattler ) = = B_POSITION_PLAYER_LEFT
| | ( GetBattlerPosition ( gActiveBattler ) = = B_POSITION_PLAYER_RIGHT & & ! ( gBattleTypeFlags & ( BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER ) ) ) )
{
gBattleStruct - > mega . playerEvolvedSpecies = gBattleStruct - > mega . evolvedSpecies [ gActiveBattler ] ;
}
2018-09-16 18:55:32 +02:00
2019-05-02 23:10:01 +02:00
gBattleMons [ gActiveBattler ] . species = GetMegaEvolutionSpecies ( gBattleStruct - > mega . evolvedSpecies [ gActiveBattler ] , gBattleMons [ gActiveBattler ] . item ) ;
PREPARE_SPECIES_BUFFER ( gBattleTextBuff1 , gBattleMons [ gActiveBattler ] . species ) ;
2018-09-20 11:23:12 +02:00
2019-05-02 23:10:01 +02:00
BtlController_EmitSetMonData ( 0 , REQUEST_SPECIES_BATTLE , gBitTable [ gBattlerPartyIndexes [ gActiveBattler ] ] , 2 , & gBattleMons [ gActiveBattler ] . species ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
}
// Change stats.
else if ( gBattlescriptCurrInstr [ 3 ] = = 1 )
{
CalculateMonStats ( mon ) ;
gBattleMons [ gActiveBattler ] . level = GetMonData ( mon , MON_DATA_LEVEL ) ;
gBattleMons [ gActiveBattler ] . hp = GetMonData ( mon , MON_DATA_HP ) ;
gBattleMons [ gActiveBattler ] . maxHP = GetMonData ( mon , MON_DATA_MAX_HP ) ;
gBattleMons [ gActiveBattler ] . attack = GetMonData ( mon , MON_DATA_ATK ) ;
gBattleMons [ gActiveBattler ] . defense = GetMonData ( mon , MON_DATA_DEF ) ;
gBattleMons [ gActiveBattler ] . speed = GetMonData ( mon , MON_DATA_SPEED ) ;
gBattleMons [ gActiveBattler ] . spAttack = GetMonData ( mon , MON_DATA_SPATK ) ;
gBattleMons [ gActiveBattler ] . spDefense = GetMonData ( mon , MON_DATA_SPDEF ) ;
gBattleMons [ gActiveBattler ] . ability = GetMonAbility ( mon ) ;
gBattleMons [ gActiveBattler ] . type1 = gBaseStats [ gBattleMons [ gActiveBattler ] . species ] . type1 ;
gBattleMons [ gActiveBattler ] . type2 = gBaseStats [ gBattleMons [ gActiveBattler ] . species ] . type2 ;
gBattleStruct - > mega . alreadyEvolved [ GetBattlerPosition ( gActiveBattler ) ] = TRUE ;
gBattleStruct - > mega . evolvedPartyIds [ GetBattlerSide ( gActiveBattler ) ] | = gBitTable [ gBattlerPartyIndexes [ gActiveBattler ] ] ;
}
// Update healthbox.
else
{
UpdateHealthboxAttribute ( gHealthboxSpriteIds [ gActiveBattler ] , mon , HEALTHBOX_ALL ) ;
CreateMegaIndicatorSprite ( gActiveBattler , 0 ) ;
}
gBattlescriptCurrInstr + = 4 ;
return ;
2018-09-22 10:45:43 +02:00
case VARIOUS_TRY_LAST_RESORT :
if ( CanUseLastResort ( gActiveBattler ) )
gBattlescriptCurrInstr + = 7 ;
else
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
return ;
case VARIOUS_ARGUMENT_STATUS_EFFECT :
switch ( gBattleMoves [ gCurrentMove ] . argument )
{
case STATUS1_BURN :
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = MOVE_EFFECT_BURN ;
2018-09-22 10:45:43 +02:00
break ;
case STATUS1_FREEZE :
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = MOVE_EFFECT_FREEZE ;
2018-09-22 10:45:43 +02:00
break ;
case STATUS1_PARALYSIS :
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = MOVE_EFFECT_PARALYSIS ;
2018-09-22 10:45:43 +02:00
break ;
case STATUS1_POISON :
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = MOVE_EFFECT_POISON ;
2018-09-22 10:45:43 +02:00
break ;
case STATUS1_TOXIC_POISON :
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = MOVE_EFFECT_TOXIC ;
2018-09-22 10:45:43 +02:00
break ;
default :
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = 0 ;
2018-09-22 10:45:43 +02:00
break ;
}
2019-02-14 13:17:27 +01:00
if ( gBattleScripting . moveEffect ! = 0 )
2018-09-22 10:45:43 +02:00
{
BattleScriptPush ( gBattlescriptCurrInstr + 3 ) ;
gBattlescriptCurrInstr = BattleScript_EffectWithChance ;
return ;
}
break ;
2018-09-22 16:15:00 +02:00
case VARIOUS_TRY_HIT_SWITCH_TARGET :
if ( IsBattlerAlive ( gBattlerAttacker )
& & IsBattlerAlive ( gBattlerTarget )
& & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
& & TARGET_TURN_DAMAGED )
{
gBattlescriptCurrInstr = BattleScript_ForceRandomSwitch ;
}
else
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
}
return ;
2018-09-22 17:27:51 +02:00
case VARIOUS_TRY_AUTONOMIZE :
if ( GetBattlerWeight ( gActiveBattler ) > 1 )
{
gDisableStructs [ gActiveBattler ] . autonomizeCount + + ;
gBattlescriptCurrInstr + = 7 ;
}
else
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
}
return ;
2018-09-22 18:37:03 +02:00
case VARIOUS_TRY_COPYCAT :
for ( i = 0 ; sMovesForbiddenToCopy [ i ] ! = COPYCAT_FORBIDDEN_END ; i + + )
{
if ( sMovesForbiddenToCopy [ i ] = = gLastUsedMove )
break ;
}
if ( gLastUsedMove = = 0 | | gLastUsedMove = = 0xFFFF | | sMovesForbiddenToCopy [ i ] ! = COPYCAT_FORBIDDEN_END )
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
}
else
{
2018-09-22 19:27:56 +02:00
gCalledMove = gLastUsedMove ;
2018-09-22 18:37:03 +02:00
gHitMarker & = ~ ( HITMARKER_ATTACKSTRING_PRINTED ) ;
2018-09-22 19:27:56 +02:00
gBattlerTarget = GetMoveTarget ( gCalledMove , 0 ) ;
2018-09-22 18:37:03 +02:00
gBattlescriptCurrInstr + = 7 ;
}
return ;
2019-04-20 21:11:49 +02:00
case VARIOUS_TRY_INSTRUCT :
for ( i = 0 ; sMoveEffectsForbiddenToInstruct [ i ] ! = INSTRUCT_FORBIDDEN_END ; i + + )
{
if ( sMoveEffectsForbiddenToInstruct [ i ] = = gBattleMoves [ gLastMoves [ gBattlerTarget ] ] . effect )
break ;
}
if ( gLastMoves [ gBattlerTarget ] = = 0 | | gLastMoves [ gBattlerTarget ] = = 0xFFFF | | sMoveEffectsForbiddenToInstruct [ i ] ! = INSTRUCT_FORBIDDEN_END
| | gLastMoves [ gBattlerTarget ] = = MOVE_STRUGGLE | | gLastMoves [ gBattlerTarget ] = = MOVE_KING_S_SHIELD )
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
}
else
{
gSpecialStatuses [ gBattlerTarget ] . instructedChosenTarget = * ( gBattleStruct - > moveTarget + gBattlerTarget ) | 0x4 ;
gBattlerAttacker = gBattlerTarget ;
gCalledMove = gLastMoves [ gBattlerAttacker ] ;
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
{
if ( gBattleMons [ gBattlerAttacker ] . moves [ i ] = = gCalledMove )
{
gCurrMovePos = i ;
i = 4 ;
break ;
}
}
if ( i ! = 4 | | gBattleMons [ gBattlerAttacker ] . pp [ gCurrMovePos ] = = 0 )
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
else
{
gBattlerTarget = gBattleStruct - > lastMoveTarget [ gBattlerAttacker ] ;
gHitMarker & = ~ ( HITMARKER_ATTACKSTRING_PRINTED ) ;
PREPARE_MON_NICK_WITH_PREFIX_BUFFER ( gBattleTextBuff1 , gActiveBattler , gBattlerPartyIndexes [ gActiveBattler ] ) ;
2019-05-02 23:10:01 +02:00
gBattlescriptCurrInstr + = 7 ;
2019-04-20 21:11:49 +02:00
}
}
return ;
2018-09-23 14:24:06 +02:00
case VARIOUS_ABILITY_POPUP :
2018-09-29 12:47:35 +02:00
CreateAbilityPopUp ( gActiveBattler , gBattleMons [ gActiveBattler ] . ability , ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE ) ! = 0 ) ;
2018-09-23 14:24:06 +02:00
break ;
2018-09-23 19:03:53 +02:00
case VARIOUS_DEFOG :
if ( T1_READ_8 ( gBattlescriptCurrInstr + 3 ) ) // Clear
{
if ( ClearDefogHazards ( gEffectBattler , TRUE ) )
return ;
else
gBattlescriptCurrInstr + = 8 ;
}
else
{
if ( ClearDefogHazards ( gActiveBattler , FALSE ) )
gBattlescriptCurrInstr + = 8 ;
else
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 4 ) ;
}
return ;
2018-09-29 14:10:53 +02:00
case VARIOUS_JUMP_IF_TARGET_ALLY :
if ( GetBattlerSide ( gBattlerAttacker ) ! = GetBattlerSide ( gBattlerTarget ) )
gBattlescriptCurrInstr + = 7 ;
else
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
return ;
2018-09-29 15:43:56 +02:00
case VARIOUS_TRY_SYNCHRONOISE :
if ( ! DoBattlersShareType ( gBattlerAttacker , gBattlerTarget ) )
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
else
gBattlescriptCurrInstr + = 7 ;
return ;
2018-09-29 18:40:14 +02:00
case VARIOUS_PSYCHO_SHIFT :
i = TRUE ;
if ( gBattleMons [ gBattlerAttacker ] . status1 & STATUS1_PARALYSIS )
{
if ( GetBattlerAbility ( gBattlerTarget ) = = ABILITY_LIMBER )
{
gBattlerAbility = gBattlerTarget ;
BattleScriptPush ( T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ) ;
gBattlescriptCurrInstr = BattleScript_PRLZPrevention ;
i = FALSE ;
}
else if ( IS_BATTLER_OF_TYPE ( gBattlerTarget , TYPE_ELECTRIC ) )
{
BattleScriptPush ( T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ) ;
gBattlescriptCurrInstr = BattleScript_PRLZPrevention ;
i = FALSE ;
}
else
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 3 ;
}
}
else if ( gBattleMons [ gBattlerAttacker ] . status1 & STATUS1_PSN_ANY )
{
if ( GetBattlerAbility ( gBattlerTarget ) = = ABILITY_IMMUNITY )
{
gBattlerAbility = gBattlerTarget ;
BattleScriptPush ( T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ) ;
gBattlescriptCurrInstr = BattleScript_PSNPrevention ;
i = FALSE ;
}
else if ( IS_BATTLER_OF_TYPE ( gBattlerTarget , TYPE_POISON ) | | IS_BATTLER_OF_TYPE ( gBattlerTarget , TYPE_STEEL ) )
{
BattleScriptPush ( T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ) ;
gBattlescriptCurrInstr = BattleScript_PSNPrevention ;
i = FALSE ;
}
else
{
if ( gBattleMons [ gBattlerAttacker ] . status1 & STATUS1_POISON )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
}
else if ( gBattleMons [ gBattlerAttacker ] . status1 & STATUS1_BURN )
{
if ( GetBattlerAbility ( gBattlerTarget ) = = ABILITY_WATER_VEIL )
{
gBattlerAbility = gBattlerTarget ;
BattleScriptPush ( T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ) ;
gBattlescriptCurrInstr = BattleScript_BRNPrevention ;
i = FALSE ;
}
else if ( IS_BATTLER_OF_TYPE ( gBattlerTarget , TYPE_FIRE ) )
{
BattleScriptPush ( T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ) ;
gBattlescriptCurrInstr = BattleScript_BRNPrevention ;
i = FALSE ;
}
else
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 2 ;
}
}
else if ( gBattleMons [ gBattlerAttacker ] . status1 & STATUS1_SLEEP )
{
if ( GetBattlerAbility ( gBattlerTarget ) = = ABILITY_INSOMNIA | | GetBattlerAbility ( gBattlerTarget ) = = ABILITY_VITAL_SPIRIT )
{
gBattlerAbility = gBattlerTarget ;
// BattleScriptPush(T1_READ_PTR(gBattlescriptCurrInstr + 3));
// gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
i = FALSE ;
}
else
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 4 ;
}
}
if ( i = = TRUE )
{
2019-02-07 21:26:42 +01:00
gBattleMons [ gBattlerTarget ] . status1 = gBattleMons [ gBattlerAttacker ] . status1 & STATUS1_ANY ;
2018-09-29 18:40:14 +02:00
gActiveBattler = gBattlerTarget ;
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gActiveBattler ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
gBattlescriptCurrInstr + = 7 ;
}
return ;
case VARIOUS_CURE_STATUS :
gBattleMons [ gActiveBattler ] . status1 = 0 ;
BtlController_EmitSetMonData ( 0 , REQUEST_STATUS_BATTLE , 0 , 4 , & gBattleMons [ gActiveBattler ] . status1 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
break ;
case VARIOUS_POWER_TRICK :
gStatuses3 [ gActiveBattler ] ^ = STATUS3_POWER_TRICK ;
SWAP ( gBattleMons [ gActiveBattler ] . attack , gBattleMons [ gActiveBattler ] . defense , i ) ;
break ;
2018-09-29 19:37:39 +02:00
case VARIOUS_AFTER_YOU :
if ( GetBattlerTurnOrderNum ( gBattlerAttacker ) > GetBattlerTurnOrderNum ( gBattlerTarget )
| | GetBattlerTurnOrderNum ( gBattlerAttacker ) = = GetBattlerTurnOrderNum ( gBattlerTarget ) + 1 )
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
}
else
{
for ( i = 0 ; i < gBattlersCount ; i + + )
data [ i ] = gBattlerByTurnOrder [ i ] ;
if ( GetBattlerTurnOrderNum ( gBattlerAttacker ) = = 0 & & GetBattlerTurnOrderNum ( gBattlerTarget ) = = 2 )
{
gBattlerByTurnOrder [ 1 ] = gBattlerTarget ;
gBattlerByTurnOrder [ 2 ] = data [ 1 ] ;
gBattlerByTurnOrder [ 3 ] = data [ 3 ] ;
}
else if ( GetBattlerTurnOrderNum ( gBattlerAttacker ) = = 0 & & GetBattlerTurnOrderNum ( gBattlerTarget ) = = 3 )
{
gBattlerByTurnOrder [ 1 ] = gBattlerTarget ;
gBattlerByTurnOrder [ 2 ] = data [ 1 ] ;
gBattlerByTurnOrder [ 3 ] = data [ 2 ] ;
}
else
{
gBattlerByTurnOrder [ 2 ] = gBattlerTarget ;
gBattlerByTurnOrder [ 3 ] = data [ 2 ] ;
}
gBattlescriptCurrInstr + = 7 ;
}
return ;
2018-09-30 12:27:51 +02:00
case VARIOUS_BESTOW :
if ( gBattleMons [ gBattlerAttacker ] . item = = ITEM_NONE
| | gBattleMons [ gBattlerTarget ] . item ! = ITEM_NONE
| | ! CanBattlerGetOrLoseItem ( gBattlerAttacker , gBattleMons [ gBattlerAttacker ] . item )
| | ! CanBattlerGetOrLoseItem ( gBattlerTarget , gBattleMons [ gBattlerAttacker ] . item ) )
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
}
else
{
gLastUsedItem = gBattleMons [ gBattlerAttacker ] . item ;
gActiveBattler = gBattlerAttacker ;
gBattleMons [ gActiveBattler ] . item = ITEM_NONE ;
BtlController_EmitSetMonData ( 0 , REQUEST_HELDITEM_BATTLE , 0 , 2 , & gBattleMons [ gActiveBattler ] . item ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2019-12-25 12:19:09 +01:00
CheckSetUnburden ( gBattlerAttacker ) ;
2018-09-30 12:27:51 +02:00
gActiveBattler = gBattlerTarget ;
gBattleMons [ gActiveBattler ] . item = gLastUsedItem ;
BtlController_EmitSetMonData ( 0 , REQUEST_HELDITEM_BATTLE , 0 , 2 , & gBattleMons [ gActiveBattler ] . item ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2019-12-25 12:19:09 +01:00
gBattleResources - > flags - > flags [ gBattlerTarget ] & = ~ ( RESOURCE_FLAG_UNBURDEN ) ;
2018-09-30 12:27:51 +02:00
gBattlescriptCurrInstr + = 7 ;
}
return ;
2018-09-30 14:04:46 +02:00
case VARIOUS_ARGUMENT_TO_MOVE_EFFECT :
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = gBattleMoves [ gCurrentMove ] . argument ;
2018-09-30 14:04:46 +02:00
break ;
case VARIOUS_JUMP_IF_NOT_GROUNDED :
if ( ! IsBattlerGrounded ( gActiveBattler ) )
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
else
gBattlescriptCurrInstr + = 7 ;
return ;
2018-11-03 01:17:16 +01:00
case VARIOUS_HANDLE_TRAINER_SLIDE_MSG :
if ( gBattlescriptCurrInstr [ 3 ] = = 0 )
{
gBattleScripting . savedDmg = gBattlerSpriteIds [ gActiveBattler ] ;
}
else if ( gBattlescriptCurrInstr [ 3 ] = = 1 )
{
BtlController_EmitPrintString ( 0 , STRINGID_TRAINERSLIDE ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
}
else
{
gBattlerSpriteIds [ gActiveBattler ] = gBattleScripting . savedDmg ;
if ( gBattleMons [ gActiveBattler ] . hp ! = 0 )
{
BattleLoadOpponentMonSpriteGfx ( & gEnemyParty [ gBattlerPartyIndexes [ gActiveBattler ] ] , gActiveBattler ) ;
}
}
gBattlescriptCurrInstr + = 4 ;
return ;
case VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF :
if ( ShouldDoTrainerSlide ( gActiveBattler , gTrainerBattleOpponent_A , TRAINER_SLIDE_FIRST_DOWN ) )
{
BattleScriptPush ( gBattlescriptCurrInstr + 3 ) ;
gBattlescriptCurrInstr = BattleScript_TrainerSlideMsgRet ;
return ;
}
break ;
case VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON :
if ( ShouldDoTrainerSlide ( gActiveBattler , gTrainerBattleOpponent_A , TRAINER_SLIDE_LAST_SWITCHIN ) )
{
BattleScriptPush ( gBattlescriptCurrInstr + 3 ) ;
gBattlescriptCurrInstr = BattleScript_TrainerSlideMsgRet ;
return ;
}
break ;
2018-11-03 14:35:45 +01:00
case VARIOUS_SET_AURORA_VEIL :
2019-12-23 17:50:13 +01:00
if ( gSideStatuses [ GET_BATTLER_SIDE ( gActiveBattler ) ] & SIDE_STATUS_AURORA_VEIL
| | ! ( WEATHER_HAS_EFFECT & & gBattleWeather & WEATHER_HAIL_ANY ) )
2018-11-03 14:35:45 +01:00
{
gMoveResultFlags | = MOVE_RESULT_MISSED ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
else
{
gSideStatuses [ GET_BATTLER_SIDE ( gActiveBattler ) ] | = SIDE_STATUS_AURORA_VEIL ;
if ( GetBattlerHoldEffect ( gActiveBattler , TRUE ) = = HOLD_EFFECT_LIGHT_CLAY )
gSideTimers [ GET_BATTLER_SIDE ( gActiveBattler ) ] . auroraVeilTimer = 8 ;
else
gSideTimers [ GET_BATTLER_SIDE ( gActiveBattler ) ] . auroraVeilTimer = 5 ;
gSideTimers [ GET_BATTLER_SIDE ( gActiveBattler ) ] . auroraVeilBattlerId = gActiveBattler ;
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE & & CountAliveMonsInBattle ( BATTLE_ALIVE_ATK_SIDE ) = = 2 )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 5 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 5 ;
}
break ;
2018-11-17 12:10:24 +01:00
case VARIOUS_TRY_THIRD_TYPE :
if ( IS_BATTLER_OF_TYPE ( gActiveBattler , gBattleMoves [ gCurrentMove ] . argument ) )
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
}
else
{
gBattleMons [ gActiveBattler ] . type3 = gBattleMoves [ gCurrentMove ] . argument ;
PREPARE_TYPE_BUFFER ( gBattleTextBuff1 , gBattleMoves [ gCurrentMove ] . argument ) ;
gBattlescriptCurrInstr + = 7 ;
}
return ;
2017-09-26 22:39:59 +02:00
}
gBattlescriptCurrInstr + = 3 ;
}
2019-11-10 12:09:14 +01:00
static void Cmd_setprotectlike ( void )
2017-09-26 22:39:59 +02:00
{
2018-12-22 15:10:24 +01:00
bool32 fail = TRUE ;
2018-10-06 15:50:35 +02:00
bool32 notLastTurn = TRUE ;
2017-09-26 22:39:59 +02:00
2018-11-03 23:32:18 +01:00
if ( ! ( gBattleMoves [ gLastResultingMoves [ gBattlerAttacker ] ] . flags & FLAG_PROTECTION_MOVE ) )
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
{
2018-12-22 15:10:24 +01:00
if ( ! gBattleMoves [ gCurrentMove ] . argument ) // Protects one mon only.
2018-10-06 15:50:35 +02:00
{
2018-12-22 15:10:24 +01:00
if ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_ENDURE )
{
gProtectStructs [ gBattlerAttacker ] . endured = 1 ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
else if ( gCurrentMove = = MOVE_DETECT | | gCurrentMove = = MOVE_PROTECT )
{
gProtectStructs [ gBattlerAttacker ] . protected = 1 ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
else if ( gCurrentMove = = MOVE_SPIKY_SHIELD )
{
gProtectStructs [ gBattlerAttacker ] . spikyShielded = 1 ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
else if ( gCurrentMove = = MOVE_KING_S_SHIELD )
{
gProtectStructs [ gBattlerAttacker ] . kingsShielded = 1 ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
else if ( gCurrentMove = = MOVE_BANEFUL_BUNKER )
{
gProtectStructs [ gBattlerAttacker ] . banefulBunkered = 1 ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
gDisableStructs [ gBattlerAttacker ] . protectUses + + ;
fail = FALSE ;
2018-10-06 15:50:35 +02:00
}
2018-12-22 15:10:24 +01:00
else // Protects the whole side.
2018-10-06 15:50:35 +02:00
{
2018-12-22 15:10:24 +01:00
u8 side = GetBattlerSide ( gBattlerAttacker ) ;
if ( gCurrentMove = = MOVE_WIDE_GUARD & & ! ( gSideStatuses [ side ] & SIDE_STATUS_WIDE_GUARD ) )
{
gSideStatuses [ side ] | = SIDE_STATUS_WIDE_GUARD ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 3 ;
gDisableStructs [ gBattlerAttacker ] . protectUses + + ;
fail = FALSE ;
}
else if ( gCurrentMove = = MOVE_QUICK_GUARD & & ! ( gSideStatuses [ side ] & SIDE_STATUS_QUICK_GUARD ) )
{
gSideStatuses [ side ] | = SIDE_STATUS_QUICK_GUARD ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 3 ;
gDisableStructs [ gBattlerAttacker ] . protectUses + + ;
fail = FALSE ;
}
2019-02-01 14:34:16 +01:00
else if ( gCurrentMove = = MOVE_CRAFTY_SHIELD & & ! ( gSideStatuses [ side ] & SIDE_STATUS_CRAFTY_SHIELD ) )
{
gSideStatuses [ side ] | = SIDE_STATUS_CRAFTY_SHIELD ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 3 ;
gDisableStructs [ gBattlerAttacker ] . protectUses + + ;
fail = FALSE ;
}
2019-03-31 18:17:13 +02:00
else if ( gCurrentMove = = MOVE_MAT_BLOCK & & ! ( gSideStatuses [ side ] & SIDE_STATUS_MAT_BLOCK ) )
{
gSideStatuses [ side ] | = SIDE_STATUS_MAT_BLOCK ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 3 ;
fail = FALSE ;
}
2017-09-26 22:39:59 +02:00
}
}
2018-12-22 15:10:24 +01:00
if ( fail )
2017-09-26 22:39:59 +02:00
{
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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
2018-09-30 14:04:46 +02:00
for ( gBattlerTarget + + ; gBattlerTarget < gBattlersCount ; gBattlerTarget + + )
2017-09-26 22:39:59 +02:00
{
2018-09-30 14:04:46 +02:00
if ( gBattlerTarget = = gBattlerAttacker & & ! ( gBattleMoves [ gCurrentMove ] . target & MOVE_TARGET_USER ) )
continue ;
2019-08-22 15:57:33 +02:00
if ( IsBattlerAlive ( gBattlerTarget ) )
2018-09-30 14:04:46 +02:00
break ;
2017-09-26 22:39:59 +02:00
}
2018-09-30 14:04:46 +02:00
if ( gBattlerTarget > = gBattlersCount )
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
2018-09-30 14:04:46 +02:00
else
gBattlescriptCurrInstr = jumpPtr ;
2017-09-26 22:39:59 +02:00
}
2019-08-23 13:55:36 +02:00
static void Cmd_tryhealhalfhealth ( void )
2017-09-26 22:39:59 +02:00
{
2018-09-30 14:04:46 +02: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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_trymirrormove ( void )
2017-09-26 22:39:59 +02:00
{
s32 validMovesCount ;
s32 i ;
u16 move ;
2019-01-27 13:52:02 +01:00
u16 movesArray [ 4 ] = { 0 } ;
2017-09-26 22:39:59 +02:00
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
{
2019-01-27 13:52:02 +01:00
move = gBattleStruct - > lastTakenMoveFrom [ gBattlerAttacker ] [ i ] ;
2017-09-26 22:39:59 +02:00
if ( move ! = 0 & & move ! = 0xFFFF )
{
movesArray [ validMovesCount ] = move ;
validMovesCount + + ;
}
}
}
2019-01-27 13:52:02 +01:00
move = gBattleStruct - > lastTakenMove [ gBattlerAttacker ] ;
2017-09-26 22:39:59 +02:00
if ( move ! = 0 & & move ! = 0xFFFF )
{
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 + + ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_setrain ( void )
2017-09-26 22:39:59 +02:00
{
2018-07-27 23:40:10 +02:00
if ( ! TryChangeBattleWeather ( gBattlerAttacker , ENUM_WEATHER_RAIN , FALSE ) )
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
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
2018-11-03 14:35:45 +01:00
if ( GetBattlerHoldEffect ( gBattlerAttacker , TRUE ) = = HOLD_EFFECT_LIGHT_CLAY )
gSideTimers [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] . reflectTimer = 8 ;
else
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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
{
2019-08-23 14:46:21 +02:00
case DMG_CHANGE_SIGN :
2017-09-26 22:39:59 +02:00
gBattleMoveDamage * = - 1 ;
break ;
2019-09-15 23:58:12 +02:00
case DMG_RECOIL_FROM_MISS :
2017-09-26 22:39:59 +02:00
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 ;
2019-08-23 14:46:21 +02:00
case DMG_DOUBLED :
2017-09-26 22:39:59 +02:00
gBattleMoveDamage * = 2 ;
break ;
2019-11-10 12:09:14 +01:00
case DMG_1_8_TARGET_HP :
2018-07-22 21:05:12 +02:00
gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . maxHP / 8 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
break ;
2019-11-10 12:09:14 +01:00
case DMG_FULL_ATTACKER_HP :
2018-07-26 20:36:16 +02:00
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . maxHP ;
break ;
2019-11-10 12:09:14 +01:00
case DMG_CURR_ATTACKER_HP :
2018-09-22 16:15:00 +02:00
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . hp ;
break ;
2017-09-26 22:39:59 +02:00
}
gBattlescriptCurrInstr + = 2 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-11-10 12:09:14 +01:00
static void Cmd_setmiracleeye ( void )
2017-09-26 22:39:59 +02:00
{
2018-07-21 16:34:43 +02:00
if ( ! ( gStatuses3 [ gBattlerTarget ] & STATUS3_MIRACLE_EYED ) )
{
gStatuses3 [ gBattlerTarget ] | = STATUS3_MIRACLE_EYED ;
gBattlescriptCurrInstr + = 5 ;
}
else
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
}
2017-09-26 22:39:59 +02:00
}
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-02-06 23:09:39 +01:00
if ( gBattlerTarget = = 0xFF )
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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ) ;
2019-03-31 21:38:58 +02:00
u32 ability = GetBattlerAbility ( gBattlerTarget ) ;
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 ;
}
2019-03-31 21:38:58 +02:00
else if ( ability = = ABILITY_INSOMNIA | | ability = = ABILITY_VITAL_SPIRIT )
2017-09-26 22:39:59 +02:00
{
2019-03-31 21:38:58 +02:00
gLastUsedAbility = 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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_stockpile ( void )
2017-09-26 22:39:59 +02:00
{
2019-07-09 19:06:12 +02:00
switch ( gBattlescriptCurrInstr [ 1 ] )
2017-09-26 22:39:59 +02:00
{
2019-07-09 19:06:12 +02:00
case 0 :
if ( gDisableStructs [ gBattlerAttacker ] . stockpileCounter > = 3 )
{
gMoveResultFlags | = MOVE_RESULT_MISSED ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
else
{
gDisableStructs [ gBattlerAttacker ] . stockpileCounter + + ;
gDisableStructs [ gBattlerAttacker ] . stockpileBeforeDef = gBattleMons [ gBattlerAttacker ] . statStages [ STAT_DEF ] ;
gDisableStructs [ gBattlerAttacker ] . stockpileBeforeSpDef = gBattleMons [ gBattlerAttacker ] . statStages [ STAT_SPDEF ] ;
PREPARE_BYTE_NUMBER_BUFFER ( gBattleTextBuff1 , 1 , gDisableStructs [ gBattlerAttacker ] . stockpileCounter ) ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
}
break ;
case 1 : // Save def/sp def stats.
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
{
gDisableStructs [ gBattlerAttacker ] . stockpileDef + = gBattleMons [ gBattlerAttacker ] . statStages [ STAT_DEF ] - gDisableStructs [ gBattlerAttacker ] . stockpileBeforeDef ;
gDisableStructs [ gBattlerAttacker ] . stockpileSpDef + = gBattleMons [ gBattlerAttacker ] . statStages [ STAT_SPDEF ] - gDisableStructs [ gBattlerAttacker ] . stockpileBeforeSpDef ;
}
break ;
2017-09-26 22:39:59 +02:00
}
2019-07-09 19:06:12 +02:00
gBattlescriptCurrInstr + = 2 ;
2017-09-26 22:39:59 +02:00
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
gBattleScripting . animTurn = gDisableStructs [ gBattlerAttacker ] . stockpileCounter ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerAttacker ] . stockpileCounter = 0 ;
2019-07-09 19:06:12 +02:00
// Restore stat changes from stockpile.
gBattleMons [ gBattlerAttacker ] . statStages [ STAT_DEF ] - = gDisableStructs [ gBattlerAttacker ] . stockpileDef ;
gBattleMons [ gBattlerAttacker ] . statStages [ STAT_SPDEF ] - = gDisableStructs [ gBattlerAttacker ] . stockpileSpDef ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
else
{
2019-07-09 19:06:12 +02:00
if ( gBattleMons [ gBattlerAttacker ] . maxHP = = gBattleMons [ gBattlerAttacker ] . hp )
{
gDisableStructs [ gBattlerAttacker ] . stockpileCounter = 0 ;
gBattlescriptCurrInstr = jumpPtr ;
gBattlerTarget = gBattlerAttacker ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
else
{
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . maxHP / ( 1 < < ( 3 - gDisableStructs [ gBattlerAttacker ] . stockpileCounter ) ) ;
2017-09-26 22:39:59 +02:00
2019-07-09 19:06:12 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleMoveDamage * = - 1 ;
2017-09-26 22:39:59 +02:00
2019-07-09 19:06:12 +02:00
gBattleScripting . animTurn = gDisableStructs [ gBattlerAttacker ] . stockpileCounter ;
gDisableStructs [ gBattlerAttacker ] . stockpileCounter = 0 ;
gBattlescriptCurrInstr + = 5 ;
gBattlerTarget = gBattlerAttacker ;
}
// Restore stat changes from stockpile.
gBattleMons [ gBattlerAttacker ] . statStages [ STAT_DEF ] - = gDisableStructs [ gBattlerAttacker ] . stockpileDef ;
gBattleMons [ gBattlerAttacker ] . statStages [ STAT_SPDEF ] - = gDisableStructs [ gBattlerAttacker ] . stockpileSpDef ;
2017-09-26 22:39:59 +02:00
}
}
2019-11-10 12:09:14 +01:00
static void Cmd_setdrainedhp ( void )
2017-09-26 22:39:59 +02:00
{
2018-08-03 19:01:03 +02:00
if ( gBattleMoves [ gCurrentMove ] . argument ! = 0 )
gBattleMoveDamage = - ( gHpDealt * gBattleMoves [ gCurrentMove ] . argument / 100 ) ;
else
gBattleMoveDamage = - ( gHpDealt / 2 ) ;
2017-09-26 22:39:59 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = - 1 ;
gBattlescriptCurrInstr + + ;
}
2019-02-14 13:17:27 +01:00
static u32 ChangeStatBuffs ( s8 statValue , u32 statId , u32 flags , const u8 * BS_ptr )
2017-09-26 22:39:59 +02:00
{
2019-02-14 13:17:27 +01:00
bool32 certain = FALSE ;
bool32 notProtectAffected = FALSE ;
2017-09-26 22:39:59 +02:00
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
2019-03-23 17:21:14 +01:00
gSpecialStatuses [ gActiveBattler ] . changedStatsBattlerId = gBattlerAttacker ;
2017-09-26 22:39:59 +02:00
flags & = ~ ( MOVE_EFFECT_AFFECTS_USER ) ;
if ( flags & MOVE_EFFECT_CERTAIN )
certain + + ;
flags & = ~ ( MOVE_EFFECT_CERTAIN ) ;
2019-09-27 08:46:33 +02:00
if ( flags & STAT_BUFF_NOT_PROTECT_AFFECTED )
2017-09-26 22:39:59 +02:00
notProtectAffected + + ;
2019-09-27 08:46:33 +02:00
flags & = ~ ( STAT_BUFF_NOT_PROTECT_AFFECTED ) ;
2017-09-26 22:39:59 +02:00
2018-12-26 19:12:07 +01:00
if ( GetBattlerAbility ( gActiveBattler ) = = ABILITY_CONTRARY )
{
statValue ^ = STAT_BUFF_NEGATIVE ;
gBattleScripting . statChanger ^ = STAT_BUFF_NEGATIVE ;
}
2019-02-14 19:48:21 +01:00
else if ( GetBattlerAbility ( gActiveBattler ) = = ABILITY_SIMPLE )
{
statValue = ( SET_STAT_BUFF_VALUE ( GET_STAT_BUFF_VALUE ( statValue ) * 2 ) ) | ( ( statValue < = - 1 ) ? STAT_BUFF_NEGATIVE : 0 ) ;
}
2018-12-26 19:12:07 +01:00
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , statId ) ;
2017-09-26 22:39:59 +02:00
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 )
{
2019-09-27 08:46:33 +02:00
if ( flags = = STAT_BUFF_ALLOW_PTR )
2017-09-26 22:39:59 +02:00
{
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 ;
}
2019-03-31 21:38:58 +02:00
else if ( ( GetBattlerAbility ( gActiveBattler ) = = ABILITY_CLEAR_BODY
| | GetBattlerAbility ( gActiveBattler ) = = ABILITY_WHITE_SMOKE )
2017-09-26 22:39:59 +02:00
& & ! certain & & gCurrentMove ! = MOVE_CURSE )
{
2019-09-27 08:46:33 +02:00
if ( flags = = STAT_BUFF_ALLOW_PTR )
2017-09-26 22:39:59 +02:00
{
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 ;
2019-03-26 02:34:39 +01:00
gBattlerAbility = gActiveBattler ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = BattleScript_AbilityNoStatLoss ;
2019-03-31 21:38:58 +02:00
gLastUsedAbility = GetBattlerAbility ( gActiveBattler ) ;
2018-02-06 02:46:59 +01:00
RecordAbilityBattle ( gActiveBattler , gLastUsedAbility ) ;
gSpecialStatuses [ gActiveBattler ] . statLowered = 1 ;
2017-09-26 22:39:59 +02:00
}
}
return STAT_CHANGE_DIDNT_WORK ;
}
2019-03-31 21:38:58 +02:00
else if ( ( index = IsFlowerVeilProtected ( gActiveBattler ) ) & & ! certain )
{
2019-11-10 12:09:14 +01:00
if ( flags = = STAT_BUFF_ALLOW_PTR )
2019-03-31 21:38:58 +02:00
{
if ( gSpecialStatuses [ gActiveBattler ] . statLowered )
{
gBattlescriptCurrInstr = BS_ptr ;
}
else
{
BattleScriptPush ( BS_ptr ) ;
gBattleScripting . battler = gActiveBattler ;
gBattlerAbility = index - 1 ;
gBattlescriptCurrInstr = BattleScript_FlowerVeilProtectsRet ;
gLastUsedAbility = ABILITY_FLOWER_VEIL ;
gSpecialStatuses [ gActiveBattler ] . statLowered = 1 ;
}
}
return STAT_CHANGE_DIDNT_WORK ;
}
else if ( GetBattlerAbility ( gActiveBattler ) = = ABILITY_KEEN_EYE
2018-02-08 12:13:29 +01:00
& & ! certain & & statId = = STAT_ACC )
2017-09-26 22:39:59 +02:00
{
2019-09-27 08:46:33 +02:00
if ( flags = = STAT_BUFF_ALLOW_PTR )
2017-09-26 22:39:59 +02:00
{
BattleScriptPush ( BS_ptr ) ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = gActiveBattler ;
2019-03-26 02:34:39 +01:00
gBattlerAbility = gActiveBattler ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss ;
2019-03-31 21:38:58 +02:00
gLastUsedAbility = GetBattlerAbility ( gActiveBattler ) ;
2018-02-06 02:46:59 +01:00
RecordAbilityBattle ( gActiveBattler , gLastUsedAbility ) ;
2017-09-26 22:39:59 +02:00
}
return STAT_CHANGE_DIDNT_WORK ;
}
2019-03-31 21:38:58 +02:00
else if ( GetBattlerAbility ( gActiveBattler ) = = ABILITY_HYPER_CUTTER
2018-02-08 12:13:29 +01:00
& & ! certain & & statId = = STAT_ATK )
2017-09-26 22:39:59 +02:00
{
2019-09-27 08:46:33 +02:00
if ( flags = = STAT_BUFF_ALLOW_PTR )
2017-09-26 22:39:59 +02:00
{
BattleScriptPush ( BS_ptr ) ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = gActiveBattler ;
2019-03-26 02:34:39 +01:00
gBattlerAbility = gActiveBattler ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss ;
2019-03-31 21:38:58 +02:00
gLastUsedAbility = GetBattlerAbility ( gActiveBattler ) ;
2018-02-06 02:46:59 +01:00
RecordAbilityBattle ( gActiveBattler , gLastUsedAbility ) ;
2017-09-26 22:39:59 +02:00
}
return STAT_CHANGE_DIDNT_WORK ;
}
2019-03-31 21:38:58 +02:00
else if ( GetBattlerAbility ( gActiveBattler ) = = 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 ;
}
2019-02-14 12:15:53 +01:00
else if ( statValue < = - 3 )
2018-09-22 12:20:33 +02:00
{
gBattleTextBuff2 [ 1 ] = B_BUFF_STRING ;
gBattleTextBuff2 [ 2 ] = STRINGID_SEVERELY & 0xFF ;
gBattleTextBuff2 [ 3 ] = STRINGID_SEVERELY > > 8 ;
index = 4 ;
}
2017-09-26 22:39:59 +02:00
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 ;
2018-09-22 12:20:33 +02:00
}
2019-02-14 12:15:53 +01:00
else if ( statValue > = 3 )
2018-09-22 12:20:33 +02:00
{
gBattleTextBuff2 [ 1 ] = B_BUFF_STRING ;
gBattleTextBuff2 [ 2 ] = STRINGID_DRASTICALLY & 0xFF ;
gBattleTextBuff2 [ 3 ] = STRINGID_DRASTICALLY > > 8 ;
index = 4 ;
2017-09-26 22:39:59 +02:00
}
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
2019-09-27 08:46:33 +02:00
if ( gBattleCommunication [ MULTISTRING_CHOOSER ] = = 2 & & flags & STAT_BUFF_ALLOW_PTR )
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-26 22:39:59 +02:00
2019-09-27 08:46:33 +02:00
if ( gBattleCommunication [ MULTISTRING_CHOOSER ] = = 2 & & ! ( flags & STAT_BUFF_ALLOW_PTR ) )
2017-09-26 22:39:59 +02:00
return STAT_CHANGE_DIDNT_WORK ;
return STAT_CHANGE_WORKED ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_statbuffchange ( void )
2017-09-26 22:39:59 +02:00
{
2019-03-07 12:20:57 +01:00
u16 flags = T1_READ_16 ( gBattlescriptCurrInstr + 1 ) ;
const u8 * ptrBefore = gBattlescriptCurrInstr ;
2019-02-14 13:17:27 +01:00
const u8 * jumpPtr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
2019-03-07 12:20:57 +01:00
if ( ChangeStatBuffs ( GET_STAT_BUFF_VALUE_WITH_SIGN ( gBattleScripting . statChanger ) , GET_STAT_BUFF_ID ( gBattleScripting . statChanger ) , flags , jumpPtr ) = = STAT_CHANGE_WORKED )
2019-02-14 13:17:27 +01:00
gBattlescriptCurrInstr + = 7 ;
2019-03-07 12:20:57 +01:00
else if ( gBattlescriptCurrInstr = = ptrBefore ) // Prevent infinite looping.
gBattlescriptCurrInstr = jumpPtr ;
2017-09-26 22:39:59 +02:00
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
{
2019-07-09 19:06:12 +02:00
gDisableStructs [ i ] . stockpileDef = 0 ;
gDisableStructs [ i ] . stockpileSpDef = 0 ;
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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_confuseifrepeatingattackends ( void )
2017-09-26 22:39:59 +02:00
{
2019-11-14 00:03:20 +01:00
if ( ! ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_LOCK_CONFUSE ) & & ! gSpecialStatuses [ gBattlerAttacker ] . dancerUsedMove )
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = ( MOVE_EFFECT_THRASH | MOVE_EFFECT_AFFECTS_USER ) ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
2018-07-22 18:40:18 +02:00
if ( GetBattlerAbility ( gBattlerAttacker ) = = ABILITY_SKILL_LINK )
gMultiHitCounter = 5 ;
2017-09-26 22:39:59 +02:00
}
gBattlescriptCurrInstr + = 2 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_initmultihitstring ( void )
2017-09-26 22:39:59 +02:00
{
PREPARE_BYTE_NUMBER_BUFFER ( gBattleScripting . multihitString , 1 , 0 )
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
2018-09-22 16:15:00 +02:00
s32 lastMonId = 0 ; // + 1
2017-09-26 22:39:59 +02:00
s32 firstMonId = 0 ;
s32 monsCount = 0 ;
2018-09-22 16:15:00 +02:00
struct Pokemon * party = NULL ;
2017-09-26 22:39:59 +02:00
s32 validMons = 0 ;
s32 minNeeded = 0 ;
2019-03-06 12:09:34 +01:00
// Swapping pokemon happens in:
// trainer battles
// wild double battles when an opposing pokemon uses it against one of the two alive player mons
// wild double battle when a player pokemon uses it against its partner
if ( ( gBattleTypeFlags & BATTLE_TYPE_TRAINER )
| | ( WILD_DOUBLE_BATTLE
& & GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_OPPONENT
& & GetBattlerSide ( gBattlerTarget ) = = B_SIDE_PLAYER
& & IS_WHOLE_SIDE_ALIVE ( gBattlerTarget ) )
| | ( WILD_DOUBLE_BATTLE
& & GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_PLAYER
& & GetBattlerSide ( gBattlerTarget ) = = B_SIDE_PLAYER )
)
2017-09-26 22:39:59 +02:00
{
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 ;
2019-03-06 12:09:34 +01:00
if ( BATTLE_TWO_VS_ONE_OPPONENT & & GetBattlerSide ( gBattlerTarget ) = = B_SIDE_OPPONENT )
2019-01-27 20:54:34 +01:00
{
firstMonId = 0 ;
lastMonId = 6 ;
monsCount = 6 ;
minNeeded = 2 ;
battler2PartyId = gBattlerPartyIndexes [ gBattlerTarget ] ;
battler1PartyId = gBattlerPartyIndexes [ gBattlerTarget ^ BIT_FLANK ] ;
}
else if ( ( gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER & & gBattleTypeFlags & BATTLE_TYPE_LINK )
2017-09-26 22:39:59 +02:00
| | ( 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
{
2019-03-06 12:09:34 +01:00
* ( gBattleStruct - > field_58 + gBattlerTarget ) = gBattlerPartyIndexes [ gBattlerTarget ] ;
gBattlescriptCurrInstr = BattleScript_RoarSuccessSwitch ;
do
2017-09-26 22:39:59 +02:00
{
2019-03-06 12:09:34 +01:00
i = Random ( ) % monsCount ;
i + = firstMonId ;
2017-09-26 22:39:59 +02:00
}
2019-03-06 12:09:34 +01:00
while ( i = = battler2PartyId
| | i = = battler1PartyId
| | 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 ( ) )
2019-10-26 03:55:01 +02:00
SwitchPartyOrder ( 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 ) )
{
2019-10-26 03:55:01 +02:00
SwitchPartyOrderLinkMulti ( gBattlerTarget , i , 0 ) ;
SwitchPartyOrderLinkMulti ( gBattlerTarget ^ BIT_FLANK , i , 1 ) ;
2017-09-26 22:39:59 +02:00
}
if ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER )
2019-10-26 03:55:01 +02:00
SwitchPartyOrderInGameMulti ( gBattlerTarget , i ) ;
2017-09-26 22:39:59 +02:00
}
}
else
{
2019-03-06 12:09:34 +01:00
// In normal wild doubles, Roar will always fail if the user's level is less than the target's.
if ( gBattleMons [ gBattlerAttacker ] . level > = gBattleMons [ gBattlerTarget ] . level )
gBattlescriptCurrInstr = BattleScript_RoarSuccessEndBattle ;
else
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
2018-11-17 23:47:35 +01:00
& & moveType ! = gBattleMons [ gBattlerAttacker ] . type2
& & moveType ! = gBattleMons [ gBattlerAttacker ] . type3 )
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-11-17 23:47:35 +01:00
while ( moveType = = gBattleMons [ gBattlerAttacker ] . type1 | | moveType = = gBattleMons [ gBattlerAttacker ] . type2 | | moveType = = gBattleMons [ gBattlerAttacker ] . type3 ) ;
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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
2018-11-03 14:35:45 +01:00
if ( GetBattlerHoldEffect ( gBattlerAttacker , TRUE ) = = HOLD_EFFECT_LIGHT_CLAY )
gSideTimers [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] . lightscreenTimer = 8 ;
else
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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_setsandstorm ( void )
2017-09-26 22:39:59 +02:00
{
2018-07-27 23:40:10 +02:00
if ( ! TryChangeBattleWeather ( gBattlerAttacker , ENUM_WEATHER_SANDSTORM , FALSE ) )
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
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 3 ;
}
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_weatherdamage ( void )
2017-09-26 22:39:59 +02:00
{
2019-08-22 15:57:33 +02:00
if ( ! IsBattlerAlive ( gBattlerAttacker ) | | ! WEATHER_HAS_EFFECT )
{
gBattleMoveDamage = 0 ;
}
else
2017-09-26 22:39:59 +02:00
{
2018-07-22 22:41:13 +02:00
u32 ability = GetBattlerAbility ( gBattlerAttacker ) ;
2017-09-26 22:39:59 +02:00
if ( gBattleWeather & WEATHER_SANDSTORM_ANY )
{
2018-07-22 22:41:13 +02:00
if ( ! IS_BATTLER_OF_TYPE ( gBattlerAttacker , TYPE_ROCK )
& & ! IS_BATTLER_OF_TYPE ( gBattlerAttacker , TYPE_GROUND )
& & ! IS_BATTLER_OF_TYPE ( gBattlerAttacker , TYPE_STEEL )
& & ability ! = ABILITY_SAND_VEIL
& & ability ! = ABILITY_SAND_FORCE
& & ability ! = ABILITY_SAND_RUSH
2018-07-26 21:56:23 +02:00
& & ability ! = ABILITY_OVERCOAT
2018-02-06 23:09:39 +01:00
& & ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_UNDERGROUND )
2019-03-08 10:16:54 +01:00
& & ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_UNDERWATER )
& & GetBattlerHoldEffect ( gBattlerAttacker , TRUE ) ! = HOLD_EFFECT_SAFETY_GOOGLES )
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 ;
}
}
2018-07-22 22:41:13 +02:00
if ( gBattleWeather & WEATHER_HAIL_ANY )
2017-09-26 22:39:59 +02:00
{
2018-07-22 22:41:13 +02:00
if ( ability = = ABILITY_ICE_BODY
& & ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_UNDERGROUND )
2018-07-31 23:09:47 +02:00
& & ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_UNDERWATER )
& & ! BATTLER_MAX_HP ( gBattlerAttacker )
& & ! gStatuses3 [ gBattlerAttacker ] & STATUS3_HEAL_BLOCK )
2018-07-22 22:41:13 +02:00
{
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . maxHP / 16 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleMoveDamage * = - 1 ;
}
else if ( ! IS_BATTLER_OF_TYPE ( gBattlerAttacker , TYPE_ICE )
& & ability ! = ABILITY_SNOW_CLOAK
2018-07-26 21:56:23 +02:00
& & ability ! = ABILITY_OVERCOAT
2018-07-31 23:09:47 +02:00
& & ability ! = ABILITY_ICE_BODY
2018-02-06 23:09:39 +01:00
& & ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_UNDERGROUND )
2019-03-08 10:16:54 +01:00
& & ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_UNDERWATER )
& & GetBattlerHoldEffect ( gBattlerAttacker , TRUE ) ! = HOLD_EFFECT_SAFETY_GOOGLES )
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 ;
}
}
}
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_transformdataexecution ( void )
2017-09-26 22:39:59 +02:00
{
2017-11-26 18:07:00 +01:00
gChosenMove = 0xFFFF ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + + ;
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 ;
2018-09-22 10:45:43 +02:00
gDisableStructs [ gBattlerAttacker ] . usedMoves = 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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
2019-08-23 13:55:36 +02:00
static void Cmd_mimicattackcopy ( void )
2017-09-26 22:39:59 +02:00
{
2017-11-26 18:07:00 +01:00
gChosenMove = 0xFFFF ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if ( IsMoveUncopyableByMimic ( gLastMoves [ gBattlerTarget ] )
| | gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_TRANSFORMED
| | gLastMoves [ gBattlerTarget ] = = 0
| | 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
}
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
2018-10-06 15:50:35 +02:00
gCurrentMove = ( Random ( ) % ( MOVES_COUNT - 1 ) ) + 1 ;
if ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_PLACEHOLDER )
continue ;
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
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
}
2019-11-10 12:09:14 +01:00
static void Cmd_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
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
2019-01-05 16:02:58 +01:00
gDisableStructs [ gBattlerTarget ] . encoreTimer = 3 ;
2018-10-14 18:10:54 +02:00
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
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_painsplitdmgcalc ( void )
2017-09-26 22:39:59 +02:00
{
2018-08-02 20:24:18 +02:00
if ( ! ( DoesSubstituteBlockMove ( gBattlerAttacker , gBattlerTarget , gCurrentMove ) ) )
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-02-07 22:53:40 +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
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_settypetorandomresistance ( void ) // conversion 2
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gLastLandedMoves [ gBattlerAttacker ] = = 0
| | 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
{
2019-01-05 16:00:57 +01:00
u32 i , resistTypes = 0 ;
u32 hitByType = gLastHitByType [ gBattlerAttacker ] ;
2017-11-11 20:01:04 +01:00
2019-01-05 16:00:57 +01:00
for ( i = 0 ; i < NUMBER_OF_MON_TYPES ; i + + ) // Find all types that resist.
2017-09-26 22:39:59 +02:00
{
2019-01-05 16:00:57 +01:00
switch ( GetTypeModifier ( hitByType , i ) )
2017-09-26 22:39:59 +02:00
{
2019-01-05 16:00:57 +01:00
case UQ_4_12 ( 0 ) :
case UQ_4_12 ( 0.5 ) :
resistTypes | = gBitTable [ i ] ;
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
2019-01-05 16:00:57 +01:00
while ( resistTypes ! = 0 )
2017-09-26 22:39:59 +02:00
{
2019-01-05 16:00:57 +01:00
i = Random ( ) % NUMBER_OF_MON_TYPES ;
if ( resistTypes & gBitTable [ i ] )
2017-09-26 22:39:59 +02:00
{
2019-01-05 16:00:57 +01:00
if ( IS_BATTLER_OF_TYPE ( gBattlerAttacker , i ) )
2017-09-26 22:39:59 +02:00
{
2019-01-05 16:00:57 +01:00
resistTypes & = ~ ( gBitTable [ i ] ) ; // Type resists, but the user is already of this type.
}
else
{
SET_BATTLER_TYPE ( gBattlerAttacker , i ) ;
PREPARE_TYPE_BUFFER ( gBattleTextBuff1 , 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
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_copymovepermanently ( void ) // sketch
2017-09-26 22:39:59 +02:00
{
2017-11-26 18:07:00 +01:00
gChosenMove = 0xFFFF ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if ( ! ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_TRANSFORMED )
& & gLastPrintedMoves [ gBattlerTarget ] ! = MOVE_STRUGGLE
& & gLastPrintedMoves [ gBattlerTarget ] ! = 0
& & gLastPrintedMoves [ gBattlerTarget ] ! = 0xFFFF
& & 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
2018-09-30 14:04:46 +02:00
| | gBattleMoves [ move ] . effect = = EFFECT_TWO_TURNS_ATTACK
2017-09-27 23:43:45 +02:00
| | 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
2018-09-30 14:04:46 +02:00
| | gBattleMoves [ move ] . effect = = EFFECT_TWO_TURNS_ATTACK
2017-09-27 23:43:45 +02:00
| | 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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-11-10 12:09:14 +01:00
static void Cmd_settailwind ( void )
2017-09-27 23:43:45 +02:00
{
2018-07-21 16:34:43 +02:00
u8 side = GetBattlerSide ( gBattlerAttacker ) ;
if ( ! ( gSideStatuses [ side ] & SIDE_STATUS_TAILWIND ) )
{
gSideStatuses [ side ] | = SIDE_STATUS_TAILWIND ;
gSideTimers [ side ] . tailwindBattlerId = gBattlerAttacker ;
gSideTimers [ side ] . tailwindTimer = 3 ;
gBattlescriptCurrInstr + = 5 ;
}
else
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
}
2017-09-27 23:43:45 +02:00
}
2019-08-23 13:55:36 +02:00
static void Cmd_tryspiteppreduce ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gLastMoves [ gBattlerTarget ] ! = 0
& & 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
2019-09-30 21:43:44 +02:00
ConvertIntToDecimalStringN ( gBattleTextBuff2 , ppToDeduct , STR_CONV_MODE_LEFT_ALIGN , 1 ) ;
2017-09-27 23:43:45 +02:00
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
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ) ;
2019-05-14 15:22:16 +02:00
u8 abilityNum = GetMonData ( & party [ i ] , MON_DATA_ABILITY_NUM ) ;
2017-09-27 23:43:45 +02:00
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
2019-05-14 15:22:16 +02:00
ability = GetAbilityBySpecies ( species , abilityNum ) ;
2017-09-27 23:43:45 +02:00
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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-11-10 12:09:14 +01:00
static void Cmd_handlerollout ( 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
{
2018-07-16 21:42:03 +02: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 20:51:34 +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
}
gBattlescriptCurrInstr + + ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-11-10 12:09:14 +01:00
static void Cmd_handlefurycutter ( 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
{
2018-02-06 23:09:39 +01:00
if ( gDisableStructs [ gBattlerAttacker ] . furyCutterCounter ! = 5 )
gDisableStructs [ gBattlerAttacker ] . furyCutterCounter + + ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + + ;
}
}
2019-11-10 12:09:14 +01:00
static void Cmd_setembargo ( void )
2017-09-27 23:43:45 +02:00
{
2018-07-21 16:34:43 +02:00
if ( gStatuses3 [ gBattlerTarget ] & STATUS3_EMBARGO )
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
gStatuses3 [ gBattlerTarget ] | = STATUS3_EMBARGO ;
gDisableStructs [ gBattlerTarget ] . embargoTimer = 5 ;
gBattlescriptCurrInstr + = 5 ;
}
2017-09-27 23:43:45 +02:00
}
2019-08-23 13:55:36 +02:00
static void Cmd_presentdamagecalculation ( void )
2017-09-27 23:43:45 +02:00
{
2018-07-16 21:42:03 +02:00
u32 rand = Random ( ) & 0xFF ;
2017-09-27 23:43:45 +02:00
if ( rand < 102 )
2018-07-16 21:42:03 +02:00
{
gBattleStruct - > presentBasePower = 40 ;
}
2017-09-27 23:43:45 +02:00
else if ( rand < 178 )
2018-07-16 21:42:03 +02:00
{
gBattleStruct - > presentBasePower = 80 ;
}
2017-09-27 23:43:45 +02:00
else if ( rand < 204 )
2018-07-16 21:42:03 +02:00
{
gBattleStruct - > presentBasePower = 120 ;
}
2017-09-27 23:43:45 +02:00
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 ;
}
2018-07-16 21:42:03 +02:00
2017-09-27 23:43:45 +02:00
if ( rand < 204 )
2018-07-16 21:42:03 +02:00
{
2017-11-25 18:42:31 +01:00
gBattlescriptCurrInstr = BattleScript_HitFromCritCalc ;
2018-07-16 21:42:03 +02:00
}
2018-02-06 23:09:39 +01:00
else if ( gBattleMons [ gBattlerTarget ] . maxHP = = gBattleMons [ gBattlerTarget ] . hp )
2018-07-16 21:42:03 +02:00
{
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr = BattleScript_AlreadyAtFullHp ;
2018-07-16 21:42:03 +02:00
}
2017-09-27 23:43:45 +02:00
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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_magnitudedamagecalculation ( void )
2017-09-27 23:43:45 +02:00
{
2018-07-16 21:42:03 +02:00
u32 magnitude = Random ( ) % 100 ;
2017-09-27 23:43:45 +02:00
if ( magnitude < 5 )
{
2018-07-16 21:42:03 +02:00
gBattleStruct - > magnitudeBasePower = 10 ;
2017-09-27 23:43:45 +02:00
magnitude = 4 ;
}
else if ( magnitude < 15 )
{
2018-07-16 21:42:03 +02:00
gBattleStruct - > magnitudeBasePower = 30 ;
2017-09-27 23:43:45 +02:00
magnitude = 5 ;
}
else if ( magnitude < 35 )
{
2018-07-16 21:42:03 +02:00
gBattleStruct - > magnitudeBasePower = 50 ;
2017-09-27 23:43:45 +02:00
magnitude = 6 ;
}
else if ( magnitude < 65 )
{
2018-07-16 21:42:03 +02:00
gBattleStruct - > magnitudeBasePower = 70 ;
2017-09-27 23:43:45 +02:00
magnitude = 7 ;
}
else if ( magnitude < 85 )
{
2018-07-16 21:42:03 +02:00
gBattleStruct - > magnitudeBasePower = 90 ;
2017-09-27 23:43:45 +02:00
magnitude = 8 ;
}
else if ( magnitude < 95 )
{
2018-07-16 21:42:03 +02:00
gBattleStruct - > magnitudeBasePower = 110 ;
2017-09-27 23:43:45 +02:00
magnitude = 9 ;
}
else
{
2018-07-16 21:42:03 +02:00
gBattleStruct - > magnitudeBasePower = 150 ;
2017-09-27 23:43:45 +02:00
magnitude = 10 ;
}
2018-07-16 21:42:03 +02:00
PREPARE_BYTE_NUMBER_BUFFER ( gBattleTextBuff1 , 2 , magnitude ) ;
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-07-16 21:42:03 +02:00
if ( ! ( gAbsentBattlerFlags & gBitTable [ gBattlerTarget ] ) ) // A valid target was found.
2017-09-27 23:43:45 +02:00
break ;
}
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_setsunny ( void )
2017-09-27 23:43:45 +02:00
{
2018-07-27 23:40:10 +02:00
if ( ! TryChangeBattleWeather ( gBattlerAttacker , ENUM_WEATHER_SUN , FALSE ) )
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 ] = 2 ;
}
else
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 4 ;
}
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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.
}
2019-08-23 13:55:36 +02:00
static void Cmd_rapidspinfree ( void )
2017-09-27 23:43:45 +02:00
{
2018-08-04 22:23:07 +02:00
u8 atkSide = GetBattlerSide ( gBattlerAttacker ) ;
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 ) ;
2019-01-27 13:52:02 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , gBattleStruct - > wrappedMove [ gBattlerAttacker ] ) ;
2017-09-27 23:43:45 +02:00
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-08-04 22:23:07 +02:00
else if ( gSideStatuses [ atkSide ] & SIDE_STATUS_SPIKES )
2017-09-27 23:43:45 +02:00
{
2018-08-04 22:23:07 +02:00
gSideStatuses [ atkSide ] & = ~ ( SIDE_STATUS_SPIKES ) ;
gSideTimers [ atkSide ] . spikesAmount = 0 ;
2017-09-27 23:43:45 +02:00
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_SpikesFree ;
}
2018-08-04 22:23:07 +02:00
else if ( gSideStatuses [ atkSide ] & SIDE_STATUS_TOXIC_SPIKES )
{
gSideStatuses [ atkSide ] & = ~ ( SIDE_STATUS_TOXIC_SPIKES ) ;
gSideTimers [ atkSide ] . toxicSpikesAmount = 0 ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_ToxicSpikesFree ;
}
else if ( gSideStatuses [ atkSide ] & SIDE_STATUS_STICKY_WEB )
{
gSideStatuses [ atkSide ] & = ~ ( SIDE_STATUS_STICKY_WEB ) ;
gSideTimers [ atkSide ] . stickyWebAmount = 0 ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_StickyWebFree ;
}
else if ( gSideStatuses [ atkSide ] & SIDE_STATUS_STEALTH_ROCK )
{
gSideStatuses [ atkSide ] & = ~ ( SIDE_STATUS_STEALTH_ROCK ) ;
gSideTimers [ atkSide ] . stealthRockAmount = 0 ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_StealthRockFree ;
}
2017-09-27 23:43:45 +02:00
else
{
gBattlescriptCurrInstr + + ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
}
2019-11-10 12:09:14 +01:00
static void Cmd_setstickyweb ( void )
2017-09-27 23:43:45 +02:00
{
2018-08-04 20:36:24 +02:00
u8 targetSide = GetBattlerSide ( gBattlerTarget ) ;
if ( gSideStatuses [ targetSide ] & SIDE_STATUS_STICKY_WEB )
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
gSideStatuses [ targetSide ] | = SIDE_STATUS_STICKY_WEB ;
gSideTimers [ targetSide ] . stickyWebAmount = 1 ;
gBattlescriptCurrInstr + = 5 ;
}
2017-09-27 23:43:45 +02:00
}
2019-08-23 13:55:36 +02:00
static void Cmd_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-09-30 14:04:46 +02:00
if ( gBattlerTarget = = gBattlerAttacker & & ! ( gBattleMoves [ gCurrentMove ] . target & MOVE_TARGET_USER ) )
2017-09-27 23:43:45 +02:00
continue ;
2019-08-22 15:57:33 +02:00
if ( IsBattlerAlive ( gBattlerTarget ) )
2017-09-27 23:43:45 +02:00
break ;
}
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
2017-09-27 23:43:45 +02:00
if ( gCurrentMove = = MOVE_DOOM_DESIRE )
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
gBattlescriptCurrInstr + = 5 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
2018-12-08 16:19:50 +01:00
case MOVE_PHANTOM_FORCE :
case MOVE_SHADOW_FORCE :
gStatuses3 [ gBattlerAttacker ] | = STATUS3_PHANTOM_FORCE ;
break ;
2017-09-27 23:43:45 +02:00
}
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_clearsemiinvulnerablebit ( void )
2017-09-27 23:43:45 +02:00
{
2018-12-08 16:19:50 +01:00
gStatuses3 [ gBattlerAttacker ] & = ~ ( STATUS3_SEMI_INVULNERABLE ) ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_sethail ( void )
2017-09-27 23:43:45 +02:00
{
2018-07-27 23:40:10 +02:00
if ( ! TryChangeBattleWeather ( gBattlerAttacker , ENUM_WEATHER_HAIL , FALSE ) )
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 ] = 2 ;
}
else
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 5 ;
}
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
{
2019-03-24 03:45:21 +01:00
u8 turns = 4 ;
if ( GetBattlerTurnOrderNum ( gBattlerTarget ) > GetBattlerTurnOrderNum ( gBattlerAttacker ) )
turns - - ; // If the target hasn't yet moved this turn, Taunt lasts for only three turns (source: Bulbapedia)
2019-03-30 11:50:55 +01:00
2019-03-24 03:45:21 +01:00
gDisableStructs [ gBattlerTarget ] . tauntTimer = gDisableStructs [ gBattlerTarget ] . tauntTimer2 = turns ;
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
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 )
2018-09-30 12:27:51 +02:00
| | ! CanBattlerGetOrLoseItem ( gBattlerAttacker , gBattleMons [ gBattlerAttacker ] . item )
| | ! CanBattlerGetOrLoseItem ( gBattlerAttacker , gBattleMons [ gBattlerTarget ] . item )
| | ! CanBattlerGetOrLoseItem ( gBattlerTarget , gBattleMons [ gBattlerTarget ] . item )
| | ! CanBattlerGetOrLoseItem ( gBattlerTarget , gBattleMons [ gBattlerAttacker ] . 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
2019-01-27 13:52:02 +01:00
gBattleStruct - > choicedMove [ gBattlerTarget ] = 0 ;
gBattleStruct - > choicedMove [ gBattlerAttacker ] = 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 )
2019-12-22 07:54:13 +01:00
{
if ( GetBattlerAbility ( gBattlerAttacker ) = = ABILITY_UNBURDEN & & gBattleResources - > flags - > flags [ gBattlerAttacker ] & RESOURCE_FLAG_UNBURDEN )
gBattleResources - > flags - > flags [ gBattlerAttacker ] & = ~ ( RESOURCE_FLAG_UNBURDEN ) ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ; // nothing -> <- target's item
}
2017-09-27 23:43:45 +02:00
else
2019-12-22 07:54:13 +01:00
{
2019-12-23 18:25:26 +01:00
CheckSetUnburden ( gBattlerAttacker ) ;
2017-09-27 23:43:45 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ; // attacker's item -> <- nothing
2019-12-22 07:54:13 +01:00
}
2017-09-27 23:43:45 +02:00
}
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-11-10 12:09:14 +01:00
static void Cmd_settoxicspikes ( void )
2017-09-27 23:43:45 +02:00
{
2018-07-21 21:58:07 +02:00
u8 targetSide = GetBattlerSide ( gBattlerTarget ) ;
if ( gSideTimers [ targetSide ] . toxicSpikesAmount > = 2 )
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-07-21 21:58:07 +02:00
gSideTimers [ targetSide ] . toxicSpikesAmount + + ;
gSideStatuses [ targetSide ] | = SIDE_STATUS_TOXIC_SPIKES ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 5 ;
}
}
2019-11-10 12:09:14 +01:00
static void Cmd_setgastroacid ( void )
2017-09-27 23:43:45 +02:00
{
2018-07-21 21:58:07 +02:00
switch ( gBattleMons [ gBattlerTarget ] . ability )
2018-07-21 16:34:43 +02:00
{
2018-07-21 21:58:07 +02:00
case ABILITY_MULTITYPE :
case ABILITY_STANCE_CHANGE :
case ABILITY_SCHOOLING :
case ABILITY_COMATOSE :
case ABILITY_SHIELDS_DOWN :
case ABILITY_DISGUISE :
case ABILITY_RKS_SYSTEM :
case ABILITY_BATTLE_BOND :
case ABILITY_POWER_CONSTRUCT :
2018-07-21 16:34:43 +02:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2018-07-21 21:58:07 +02:00
break ;
default :
gStatuses3 [ gBattlerTarget ] | = STATUS3_GASTRO_ACID ;
2018-07-21 16:34:43 +02:00
gBattlescriptCurrInstr + = 5 ;
2018-07-21 21:58:07 +02:00
break ;
2018-07-21 16:34:43 +02:00
}
2017-09-27 23:43:45 +02:00
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2018-07-21 21:58:07 +02:00
static void HandleRoomMove ( u32 statusFlag , u8 * timer , u8 stringId )
2017-09-27 23:43:45 +02:00
{
2018-07-21 21:58:07 +02:00
if ( gFieldStatuses & statusFlag )
{
gFieldStatuses & = ~ ( statusFlag ) ;
* timer = 0 ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = stringId + 1 ;
}
else
{
gFieldStatuses | = statusFlag ;
* timer = 5 ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = stringId ;
}
}
2019-11-10 12:09:14 +01:00
static void Cmd_setroom ( void )
2018-07-21 21:58:07 +02:00
{
2018-08-05 12:43:57 +02:00
switch ( gBattleMoves [ gCurrentMove ] . effect )
2018-07-21 21:58:07 +02:00
{
2018-08-05 12:43:57 +02:00
case EFFECT_TRICK_ROOM :
2018-07-21 21:58:07 +02:00
HandleRoomMove ( STATUS_FIELD_TRICK_ROOM , & gFieldTimers . trickRoomTimer , 0 ) ;
break ;
2018-08-05 12:43:57 +02:00
case EFFECT_WONDER_ROOM :
2018-07-21 21:58:07 +02:00
HandleRoomMove ( STATUS_FIELD_WONDER_ROOM , & gFieldTimers . wonderRoomTimer , 2 ) ;
break ;
2018-08-05 12:43:57 +02:00
case EFFECT_MAGIC_ROOM :
2018-07-21 21:58:07 +02:00
HandleRoomMove ( STATUS_FIELD_MAGIC_ROOM , & gFieldTimers . magicRoomTimer , 4 ) ;
break ;
default :
gBattleCommunication [ MULTISTRING_CHOOSER ] = 6 ;
break ;
}
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
2018-07-21 21:58:07 +02:00
gBattlescriptCurrInstr + = 5 ;
2017-09-27 23:43:45 +02:00
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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-07-21 21:58:07 +02: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
}
}
2019-11-10 12:09:14 +01:00
static void Cmd_setstealthrock ( void )
2017-09-27 23:43:45 +02:00
{
2018-07-21 21:58:07 +02:00
u8 targetSide = GetBattlerSide ( gBattlerTarget ) ;
if ( gSideStatuses [ targetSide ] & SIDE_STATUS_STEALTH_ROCK )
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-07-21 21:58:07 +02:00
gSideStatuses [ targetSide ] | = SIDE_STATUS_STEALTH_ROCK ;
2018-07-24 21:47:00 +02:00
gSideTimers [ targetSide ] . stealthRockAmount = 1 ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 5 ;
}
}
2019-11-10 12:09:14 +01:00
static void Cmd_setuserstatus3 ( void )
2017-09-27 23:43:45 +02:00
{
2018-07-21 21:58:07 +02:00
u32 flags = T1_READ_32 ( gBattlescriptCurrInstr + 1 ) ;
if ( gStatuses3 [ gBattlerAttacker ] & flags )
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 5 ) ;
}
else
{
gStatuses3 [ gBattlerAttacker ] | = flags ;
2019-04-20 21:02:52 +02:00
if ( flags & STATUS3_MAGNET_RISE )
2019-02-04 13:40:13 +01:00
gDisableStructs [ gBattlerAttacker ] . magnetRiseTimer = 5 ;
2019-04-20 21:02:52 +02:00
if ( flags & STATUS3_LASER_FOCUS )
gDisableStructs [ gBattlerAttacker ] . laserFocusTimer = 2 ;
2018-07-21 21:58:07 +02:00
gBattlescriptCurrInstr + = 9 ;
}
2017-09-27 23:43:45 +02:00
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
2018-07-21 21:58:07 +02:00
for ( monId = 0 ; monId < PARTY_SIZE ; monId + + )
2017-09-27 23:43:45 +02:00
{
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
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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-07-26 21:56:23 +02:00
switch ( GetBattlerAbility ( gActiveBattler ) )
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 ) ;
2018-07-26 21:56:23 +02:00
break ;
case ABILITY_REGENERATOR :
gBattleMoveDamage = gBattleMons [ gActiveBattler ] . maxHP / 3 ;
gBattleMoveDamage + = gBattleMons [ gActiveBattler ] . hp ;
if ( gBattleMoveDamage > gBattleMons [ gActiveBattler ] . maxHP )
gBattleMons [ gActiveBattler ] . maxHP = gBattleMons [ gActiveBattler ] . maxHP ;
BtlController_EmitSetMonData ( 0 , REQUEST_HP_BATTLE , gBitTable [ * ( gBattleStruct - > field_58 + gActiveBattler ) ] , 2 , & gBattleMoveDamage ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-27 23:43:45 +02:00
break ;
}
gBattlescriptCurrInstr + = 2 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_getsecretpowereffect ( void )
2017-09-27 23:43:45 +02:00
{
switch ( gBattleTerrain )
{
case BATTLE_TERRAIN_GRASS :
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = MOVE_EFFECT_POISON ;
2017-09-27 23:43:45 +02:00
break ;
case BATTLE_TERRAIN_LONG_GRASS :
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = MOVE_EFFECT_SLEEP ;
2017-09-27 23:43:45 +02:00
break ;
case BATTLE_TERRAIN_SAND :
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = MOVE_EFFECT_ACC_MINUS_1 ;
2017-09-27 23:43:45 +02:00
break ;
case BATTLE_TERRAIN_UNDERWATER :
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = MOVE_EFFECT_DEF_MINUS_1 ;
2017-09-27 23:43:45 +02:00
break ;
case BATTLE_TERRAIN_WATER :
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = MOVE_EFFECT_ATK_MINUS_1 ;
2017-09-27 23:43:45 +02:00
break ;
case BATTLE_TERRAIN_POND :
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = MOVE_EFFECT_SPD_MINUS_1 ;
2017-09-27 23:43:45 +02:00
break ;
2017-12-16 01:08:55 +01:00
case BATTLE_TERRAIN_MOUNTAIN :
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = MOVE_EFFECT_CONFUSION ;
2017-09-27 23:43:45 +02:00
break ;
case BATTLE_TERRAIN_CAVE :
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = MOVE_EFFECT_FLINCH ;
2017-09-27 23:43:45 +02:00
break ;
default :
2019-02-14 13:17:27 +01:00
gBattleScripting . moveEffect = MOVE_EFFECT_PARALYSIS ;
2017-09-27 23:43:45 +02:00
break ;
}
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
2019-03-26 00:00:46 +01:00
u8 lvlDivBy10 ;
2018-11-17 15:30:34 +01:00
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
2019-05-14 15:22:16 +02:00
if ( GetMonData ( & gPlayerParty [ i ] , MON_DATA_ABILITY_NUM ) )
2019-05-14 15:42:55 +02:00
ability = gBaseStats [ species ] . abilities [ 1 ] ;
2018-11-17 15:30:34 +01:00
else
2019-05-14 15:42:55 +02:00
ability = gBaseStats [ species ] . abilities [ 0 ] ;
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 ) ;
2019-04-05 16:16:41 +02:00
lvlDivBy10 = ( GetMonData ( & gPlayerParty [ i ] , MON_DATA_LEVEL ) - 1 ) / 10 ; //Moving this here makes it easier to add in abilities like Honey Gather
2019-03-25 22:49:29 +01:00
if ( lvlDivBy10 > 9 )
lvlDivBy10 = 9 ;
2017-09-27 23:43:45 +02:00
2019-05-14 15:22:16 +02:00
if ( GetMonData ( & gPlayerParty [ i ] , MON_DATA_ABILITY_NUM ) )
2019-05-14 15:42:55 +02:00
ability = gBaseStats [ species ] . abilities [ 1 ] ;
2018-11-17 15:30:34 +01:00
else
2019-05-14 15:42:55 +02:00
ability = gBaseStats [ species ] . abilities [ 0 ] ;
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 ;
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
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_trycastformdatachange ( void )
2017-09-28 15:34:21 +02:00
{
u8 form ;
gBattlescriptCurrInstr + + ;
2019-06-15 14:46:35 +02:00
form = TryWeatherFormChange ( gBattleScripting . battler ) ;
2017-09-28 15:34:21 +02:00
if ( form )
{
BattleScriptPushCursorAndCallback ( BattleScript_CastformChange ) ;
* ( & gBattleStruct - > formToChangeInto ) = form - 1 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_settypebasedhalvers ( void ) // water and mud sport
2017-09-28 15:34:21 +02:00
{
bool8 worked = FALSE ;
if ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_MUD_SPORT )
{
2018-07-14 13:17:10 +02:00
if ( ! ( gFieldStatuses & STATUS_FIELD_MUDSPORT ) )
2017-09-28 15:34:21 +02:00
{
2018-07-14 13:17:10 +02:00
gFieldStatuses | = STATUS_FIELD_MUDSPORT ;
gFieldTimers . mudSportTimer = 5 ;
2017-09-28 15:34:21 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
worked = TRUE ;
}
}
else // water sport
{
2018-07-14 13:17:10 +02:00
if ( ! ( gFieldStatuses & STATUS_FIELD_WATERSPORT ) )
2017-09-28 15:34:21 +02:00
{
2018-07-14 13:17:10 +02:00
gFieldStatuses | = STATUS_FIELD_WATERSPORT ;
gFieldTimers . waterSportTimer = 5 ;
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
}
2018-08-02 20:24:18 +02:00
bool32 DoesSubstituteBlockMove ( u8 battlerAtk , u8 battlerDef , u32 move )
2017-09-28 15:34:21 +02:00
{
2018-08-02 20:24:18 +02:00
if ( ! ( gBattleMons [ battlerDef ] . status2 & STATUS2_SUBSTITUTE ) )
return FALSE ;
else if ( gBattleMoves [ move ] . flags & FLAG_SOUND & & B_SOUND_SUBSTITUTE > = GEN_6 )
return FALSE ;
else if ( GetBattlerAbility ( battlerAtk ) = = ABILITY_INFILTRATOR )
return FALSE ;
else
return TRUE ;
}
2019-11-10 12:09:14 +01:00
static void Cmd_jumpifsubstituteblocks ( void )
2018-08-02 20:24:18 +02:00
{
if ( DoesSubstituteBlockMove ( gBattlerAttacker , gBattlerTarget , gCurrentMove ) )
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
else
gBattlescriptCurrInstr + = 5 ;
2017-09-28 15:34:21 +02:00
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_settypetoterrain ( void )
2017-09-28 15:34:21 +02:00
{
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
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
2019-11-14 00:03:20 +01:00
gBattleScripting . savedBattler = gBattlerAttacker ;
2018-02-06 23:09:39 +01:00
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
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_removelightscreenreflect ( void ) // brick break
2017-09-28 15:34:21 +02:00
{
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 + + ;
}
2018-10-15 21:19:52 +02:00
static u8 GetCatchingBattler ( void )
{
if ( IsBattlerAlive ( GetBattlerAtPosition ( B_POSITION_OPPONENT_LEFT ) ) )
return GetBattlerAtPosition ( B_POSITION_OPPONENT_LEFT ) ;
else
return GetBattlerAtPosition ( B_POSITION_OPPONENT_RIGHT ) ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
2018-10-15 21:19:52 +02:00
gBattlerTarget = GetCatchingBattler ( ) ;
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
2019-09-08 18:21:24 +02:00
if ( CalculatePlayerPartyCount ( ) = = PARTY_SIZE )
2017-09-28 15:34:21 +02:00
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 ;
2019-09-08 18:21:24 +02:00
for ( shakes = 0 ; shakes < BALL_3_SHAKES_SUCCESS & & Random ( ) < odds ; shakes + + ) ;
2017-09-28 15:34:21 +02:00
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
2019-09-08 18:21:24 +02:00
if ( CalculatePlayerPartyCount ( ) = = PARTY_SIZE )
2017-09-28 15:34:21 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
else
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
}
else // not caught
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = shakes ;
gBattlescriptCurrInstr = BattleScript_ShakeBallThrow ;
}
}
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_givecaughtmon ( void )
2017-09-28 15:34:21 +02:00
{
2018-10-15 21:19:52 +02:00
if ( GiveMonToPlayer ( & gEnemyParty [ gBattlerPartyIndexes [ GetCatchingBattler ( ) ] ] ) ! = MON_GIVEN_TO_PARTY )
2017-09-28 15:34:21 +02:00
{
2019-09-17 07:49:07 +02:00
if ( ! ShouldShowBoxWasFullMessage ( ) )
2017-09-28 15:34:21 +02:00
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ;
2019-09-17 07:49:07 +02:00
StringCopy ( gStringVar1 , GetBoxNamePtr ( VarGet ( VAR_PC_BOX_TO_SEND_MON ) ) ) ;
2018-10-15 21:19:52 +02:00
GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ GetCatchingBattler ( ) ] ] , MON_DATA_NICKNAME , gStringVar2 ) ;
2017-09-28 15:34:21 +02:00
}
else
{
2019-10-10 16:18:48 +02:00
StringCopy ( gStringVar1 , GetBoxNamePtr ( VarGet ( VAR_PC_BOX_TO_SEND_MON ) ) ) ;
2018-10-15 21:19:52 +02:00
GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ GetCatchingBattler ( ) ] ] , MON_DATA_NICKNAME , gStringVar2 ) ;
2019-10-10 16:18:48 +02:00
StringCopy ( gStringVar3 , GetBoxNamePtr ( GetPCBoxToSendMon ( ) ) ) ;
2017-09-28 15:34:21 +02:00
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-10-15 21:19:52 +02:00
gBattleResults . caughtMonSpecies = GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ GetCatchingBattler ( ) ] ] , MON_DATA_SPECIES , NULL ) ;
GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ GetCatchingBattler ( ) ] ] , MON_DATA_NICKNAME , gBattleResults . caughtMonNick ) ;
gBattleResults . caughtMonBall = GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ GetCatchingBattler ( ) ] ] , MON_DATA_POKEBALL , NULL ) ;
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_trysetcaughtmondexflags ( void )
2017-09-28 15:34:21 +02:00
{
2018-10-15 21:19:52 +02:00
u16 species = GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ GetCatchingBattler ( ) ] ] , MON_DATA_SPECIES , NULL ) ;
u32 personality = GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ GetCatchingBattler ( ) ] ] , MON_DATA_PERSONALITY , NULL ) ;
2017-09-28 15:34:21 +02:00
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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_displaydexinfo ( void )
2017-09-28 15:34:21 +02:00
{
2018-10-15 21:19:52 +02:00
u16 species = GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ GetCatchingBattler ( ) ] ] , MON_DATA_SPECIES , NULL ) ;
2017-09-28 15:34:21 +02:00
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-10-15 21:19:52 +02:00
gBattleMons [ GetCatchingBattler ( ) ] . otId ,
gBattleMons [ GetCatchingBattler ( ) ] . 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 :
2019-11-07 01:18:11 +01:00
InitBattleBgsVideo ( ) ;
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
{
2019-08-25 15:33:28 +02:00
s32 destY , destX , bgId ;
2017-09-28 15:34:21 +02:00
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 ;
2019-08-25 15:33:28 +02:00
bgId = ( flags & WINDOW_x80 ) ? 1 : 0 ;
CopyToBgTilemapBufferRect_ChangePalette ( bgId , & var , destX , destY , 1 , 1 , 0x11 ) ;
2017-09-28 15:34:21 +02:00
}
}
}
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 ) ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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-10-14 22:37:07 +02:00
GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerTarget ] ] , MON_DATA_NICKNAME , gBattleStruct - > caughtMonNick ) ;
2017-09-28 15:34:21 +02:00
FreeAllWindowBuffers ( ) ;
DoNamingScreen ( NAMING_SCREEN_CAUGHT_MON , gBattleStruct - > caughtMonNick ,
2018-10-14 22:37:07 +02:00
GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerTarget ] ] , MON_DATA_SPECIES ) ,
GetMonGender ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerTarget ] ] ) ,
GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerTarget ] ] , 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-10-14 22:37:07 +02:00
SetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerTarget ] ] , 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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_subattackerhpbydmg ( void )
2017-09-28 15:34:21 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . hp - = gBattleMoveDamage ;
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_removeattackerstatus1 ( void )
2017-09-28 15:34:21 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status1 = 0 ;
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
2019-08-23 13:55:36 +02:00
static void Cmd_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
}
2019-08-23 13:55:36 +02:00
static void Cmd_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 ;
}
2018-07-21 21:58:07 +02:00
2019-11-10 12:09:14 +01:00
static void Cmd_settelekinesis ( void )
2018-07-21 21:58:07 +02:00
{
if ( gStatuses3 [ gBattlerTarget ] & ( STATUS3_TELEKINESIS | STATUS3_ROOTED | STATUS3_SMACKED_DOWN )
| | gFieldStatuses & STATUS_FIELD_GRAVITY
| | ( gBattleMons [ gBattlerTarget ] . species = = SPECIES_DIGLETT | | gBattleMons [ gBattlerTarget ] . species = = SPECIES_DUGTRIO ) )
{
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
}
else
{
gStatuses3 [ gBattlerTarget ] | = STATUS3_TELEKINESIS ;
gDisableStructs [ gBattlerTarget ] . telekinesisTimer = 3 ;
gBattlescriptCurrInstr + = 5 ;
}
}
2018-07-21 23:12:10 +02:00
2019-11-10 12:09:14 +01:00
static void Cmd_swapstatstages ( void )
2018-07-21 23:12:10 +02:00
{
u8 statId = T1_READ_8 ( gBattlescriptCurrInstr + 1 ) ;
s8 atkStatStage = gBattleMons [ gBattlerAttacker ] . statStages [ statId ] ;
s8 defStatStage = gBattleMons [ gBattlerTarget ] . statStages [ statId ] ;
gBattleMons [ gBattlerAttacker ] . statStages [ statId ] = defStatStage ;
gBattleMons [ gBattlerTarget ] . statStages [ statId ] = atkStatStage ;
gBattlescriptCurrInstr + = 2 ;
}
2019-11-10 12:09:14 +01:00
static void Cmd_averagestats ( void )
2018-07-21 23:12:10 +02:00
{
u8 statId = T1_READ_8 ( gBattlescriptCurrInstr + 1 ) ;
u16 atkStat = * ( u16 * ) ( ( & gBattleMons [ gBattlerAttacker ] . attack ) + ( statId - 1 ) ) ;
u16 defStat = * ( u16 * ) ( ( & gBattleMons [ gBattlerTarget ] . attack ) + ( statId - 1 ) ) ;
u16 average = ( atkStat + defStat ) / 2 ;
* ( u16 * ) ( ( & gBattleMons [ gBattlerAttacker ] . attack ) + ( statId - 1 ) ) = average ;
* ( u16 * ) ( ( & gBattleMons [ gBattlerTarget ] . attack ) + ( statId - 1 ) ) = average ;
gBattlescriptCurrInstr + = 2 ;
}
2018-07-22 15:08:32 +02:00
2019-11-10 12:09:14 +01:00
static void Cmd_jumpifoppositegenders ( void )
2018-07-22 15:08:32 +02:00
{
u32 atkGender = GetGenderFromSpeciesAndPersonality ( gBattleMons [ gBattlerAttacker ] . species , gBattleMons [ gBattlerAttacker ] . personality ) ;
u32 defGender = GetGenderFromSpeciesAndPersonality ( gBattleMons [ gBattlerTarget ] . species , gBattleMons [ gBattlerTarget ] . personality ) ;
if ( ( atkGender = = MON_MALE & & defGender = = MON_FEMALE ) | | ( atkGender = = MON_FEMALE & & defGender = = MON_MALE ) )
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
else
gBattlescriptCurrInstr + = 5 ;
}
2018-07-22 21:05:12 +02:00
2019-11-10 12:09:14 +01:00
static void Cmd_trygetbaddreamstarget ( void )
2018-07-22 21:05:12 +02:00
{
u8 badDreamsMonSide = GetBattlerSide ( gBattlerAttacker ) ;
for ( ; gBattlerTarget < gBattlersCount ; gBattlerTarget + + )
{
if ( GetBattlerSide ( gBattlerTarget ) = = badDreamsMonSide )
continue ;
if ( gBattleMons [ gBattlerTarget ] . status1 & STATUS1_SLEEP & & IsBattlerAlive ( gBattlerTarget ) )
break ;
}
if ( gBattlerTarget > = gBattlersCount )
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
else
gBattlescriptCurrInstr + = 5 ;
}
2018-07-23 22:18:56 +02:00
2019-11-10 12:09:14 +01:00
static void Cmd_tryworryseed ( void )
2018-07-23 22:18:56 +02:00
{
switch ( gBattleMons [ gBattlerTarget ] . ability )
{
case ABILITY_INSOMNIA :
case ABILITY_MULTITYPE :
case ABILITY_TRUANT :
case ABILITY_STANCE_CHANGE :
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
break ;
default :
gBattleMons [ gBattlerTarget ] . ability = ABILITY_INSOMNIA ;
gBattlescriptCurrInstr + = 5 ;
break ;
}
}
2018-08-04 20:36:24 +02:00
2019-11-10 12:09:14 +01:00
static void Cmd_metalburstdamagecalculator ( void )
2018-08-04 20:36:24 +02:00
{
u8 sideAttacker = GetBattlerSide ( gBattlerAttacker ) ;
u8 sideTarget = 0 ;
if ( gProtectStructs [ gBattlerAttacker ] . physicalDmg
& & sideAttacker ! = ( sideTarget = GetBattlerSide ( gProtectStructs [ gBattlerAttacker ] . physicalBattlerId ) )
& & gBattleMons [ gProtectStructs [ gBattlerAttacker ] . physicalBattlerId ] . hp )
{
gBattleMoveDamage = gProtectStructs [ gBattlerAttacker ] . physicalDmg * 150 / 100 ;
if ( gSideTimers [ sideTarget ] . followmeTimer & & gBattleMons [ gSideTimers [ sideTarget ] . followmeTarget ] . hp )
gBattlerTarget = gSideTimers [ sideTarget ] . followmeTarget ;
else
gBattlerTarget = gProtectStructs [ gBattlerAttacker ] . physicalBattlerId ;
gBattlescriptCurrInstr + = 5 ;
}
else if ( gProtectStructs [ gBattlerAttacker ] . specialDmg
& & sideAttacker ! = ( sideTarget = GetBattlerSide ( gProtectStructs [ gBattlerAttacker ] . specialBattlerId ) )
& & gBattleMons [ gProtectStructs [ gBattlerAttacker ] . specialBattlerId ] . hp )
{
gBattleMoveDamage = gProtectStructs [ gBattlerAttacker ] . specialDmg * 150 / 100 ;
if ( gSideTimers [ sideTarget ] . followmeTimer & & gBattleMons [ gSideTimers [ sideTarget ] . followmeTarget ] . hp )
gBattlerTarget = gSideTimers [ sideTarget ] . followmeTarget ;
else
gBattlerTarget = gProtectStructs [ gBattlerAttacker ] . specialBattlerId ;
gBattlescriptCurrInstr + = 5 ;
}
else
{
2018-10-14 20:51:34 +02:00
gSpecialStatuses [ gBattlerAttacker ] . ppNotAffectedByPressure = 1 ;
2018-08-04 20:36:24 +02:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
}
}