2017-09-04 15:05:11 +02:00
# include "global.h"
# include "battle.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-09-08 16:46:37 +02:00
# include "item.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-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-07 23:21:51 +01:00
# include "battle_setup.h"
# include "overworld.h"
2018-07-07 19:57:09 +02:00
# include "party_menu.h"
2018-11-11 18:33:16 +01:00
# include "battle_arena.h"
2018-11-12 14:35:56 +01:00
# include "battle_pike.h"
2018-11-18 17:52:22 +01:00
# include "battle_pyramid.h"
2018-12-24 00:02:29 +01:00
# include "field_specials.h"
# include "pokemon_summary_screen.h"
2019-03-02 04:32:50 +01:00
# include "pokenav.h"
2019-03-17 23:20:40 +01:00
# include "menu_specialized.h"
2019-04-05 00:05:51 +02:00
# include "data.h"
2021-10-13 22:39:21 +02:00
# include "constants/abilities.h"
# include "constants/battle_anim.h"
# include "constants/battle_move_effects.h"
# include "constants/battle_string_ids.h"
# include "constants/hold_effects.h"
# include "constants/items.h"
# include "constants/map_types.h"
# include "constants/moves.h"
2019-10-18 01:22:03 +02:00
# include "constants/party_menu.h"
2021-10-13 22:39:21 +02:00
# include "constants/rgb.h"
# include "constants/songs.h"
# include "constants/trainers.h"
2017-09-25 00:09:13 +02:00
2017-09-23 20:13:45 +02:00
extern const u8 * const gBattleScriptsForMoveEffects [ ] ;
2017-09-19 21:01:12 +02:00
2018-02-06 23:09:39 +01:00
# define DEFENDER_IS_PROTECTED ((gProtectStructs[gBattlerTarget].protected) && (gBattleMoves[gCurrentMove].flags & FLAG_PROTECT_AFFECTED))
2017-09-19 21:01:12 +02:00
2021-10-08 22:50:52 +02:00
# define LEVEL_UP_BANNER_START 416
# define LEVEL_UP_BANNER_END 512
# define TAG_LVLUP_BANNER_MON_ICON 55130
2017-09-28 15:34:21 +02:00
static bool8 IsTwoTurnsMove ( u16 move ) ;
2017-11-25 18:42:31 +01:00
static void TrySetDestinyBondToHappen ( void ) ;
2018-02-08 12:13:29 +01:00
static u8 AttacksThisTurn ( u8 battlerId , u16 move ) ; // Note: returns 1 if it's a charging turn, otherwise 2.
2017-09-20 00:28:00 +02:00
static void CheckWonderGuardAndLevitate ( void ) ;
2017-09-28 15:34:21 +02:00
static u8 ChangeStatBuffs ( s8 statValue , u8 statId , u8 , const u8 * BS_ptr ) ;
static bool32 IsMonGettingExpSentOut ( void ) ;
2021-10-08 22:50:52 +02:00
static void InitLevelUpBanner ( void ) ;
static bool8 SlideInLevelUpBanner ( void ) ;
static bool8 SlideOutLevelUpBanner ( void ) ;
2019-04-04 21:24:21 +02:00
static void DrawLevelUpWindow1 ( void ) ;
static void DrawLevelUpWindow2 ( void ) ;
2021-10-08 22:50:52 +02:00
static void PutMonIconOnLvlUpBanner ( void ) ;
static void DrawLevelUpBannerText ( void ) ;
static void SpriteCB_MonIconOnLvlUpBanner ( struct Sprite * sprite ) ;
2017-09-28 16:32:23 +02:00
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 ) ;
static void Cmd_adjustnormaldamage ( void ) ;
static void Cmd_adjustnormaldamage2 ( void ) ;
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 ) ;
static void Cmd_jumpiftype ( void ) ;
static void Cmd_getexp ( void ) ;
2021-10-13 01:50:32 +02:00
static void Cmd_checkteamslost ( 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 ) ;
static void Cmd_healthbar_update ( void ) ;
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 ) ;
static void Cmd_jumpiftype2 ( void ) ;
static void Cmd_jumpifabilitypresent ( void ) ;
static void Cmd_endselectionscript ( void ) ;
static void Cmd_playanimation ( void ) ;
2021-10-13 22:39:21 +02:00
static void Cmd_playanimation_var ( void ) ;
2019-08-23 13:55:36 +02:00
static void Cmd_setgraphicalstatchangevalues ( void ) ;
static void Cmd_playstatchangeanimation ( void ) ;
static void Cmd_moveend ( void ) ;
static void Cmd_typecalc2 ( void ) ;
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 ) ;
2021-01-22 08:48:22 +01:00
static void Cmd_endlinkbattle ( 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 ) ;
2021-10-13 01:50:32 +02:00
static void Cmd_updatebattlermoves ( 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 ) ;
static void Cmd_adjustsetdamage ( void ) ;
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 ) ;
static void Cmd_recordlastability ( void ) ;
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 ) ;
static void Cmd_nop ( void ) ;
static void Cmd_jumpifcantmakeasleep ( void ) ;
static void Cmd_stockpile ( void ) ;
static void Cmd_stockpiletobasedamage ( void ) ;
static void Cmd_stockpiletohpheal ( void ) ;
static void Cmd_negativedamage ( void ) ;
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 ) ;
static void Cmd_remaininghptopower ( void ) ;
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 ) ;
static void Cmd_rolloutdamagecalculation ( void ) ;
static void Cmd_jumpifconfusedandstatmaxed ( void ) ;
static void Cmd_furycuttercalc ( void ) ;
2021-03-25 18:26:22 +01:00
static void Cmd_friendshiptodamagecalculation ( 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 ) ;
static void Cmd_hiddenpowercalc ( void ) ;
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 ) ;
static void Cmd_trysetroots ( void ) ;
static void Cmd_doubledamagedealtifdamaged ( void ) ;
static void Cmd_setyawn ( void ) ;
static void Cmd_setdamagetohealthdifference ( void ) ;
static void Cmd_scaledamagebyhealthratio ( void ) ;
static void Cmd_tryswapabilities ( void ) ;
static void Cmd_tryimprison ( void ) ;
static void Cmd_trysetgrudge ( void ) ;
static void Cmd_weightdamagecalculation ( void ) ;
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 ) ;
static void Cmd_setweatherballtype ( void ) ;
static void Cmd_tryrecycleitem ( void ) ;
static void Cmd_settypetoterrain ( void ) ;
2021-10-13 22:39:21 +02:00
static void Cmd_pursuitdoubles ( void ) ;
2019-08-23 13:55:36 +02:00
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 ) ;
2017-09-04 15:05:11 +02:00
void ( * const gBattleScriptingCommandsTable [ ] ) ( void ) =
{
2019-08-23 13:55:36 +02:00
Cmd_attackcanceler , //0x0
Cmd_accuracycheck , //0x1
Cmd_attackstring , //0x2
Cmd_ppreduce , //0x3
Cmd_critcalc , //0x4
Cmd_damagecalc , //0x5
Cmd_typecalc , //0x6
Cmd_adjustnormaldamage , //0x7
Cmd_adjustnormaldamage2 , //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_jumpiftype , //0x22
Cmd_getexp , //0x23
2021-10-13 01:50:32 +02:00
Cmd_checkteamslost , //0x24
2019-08-23 13:55:36 +02:00
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_healthbar_update , //0x3B
Cmd_return , //0x3C
Cmd_end , //0x3D
Cmd_end2 , //0x3E
Cmd_end3 , //0x3F
Cmd_jumpifaffectedbyprotect , //0x40
Cmd_call , //0x41
Cmd_jumpiftype2 , //0x42
Cmd_jumpifabilitypresent , //0x43
Cmd_endselectionscript , //0x44
Cmd_playanimation , //0x45
2021-10-13 22:39:21 +02:00
Cmd_playanimation_var , //0x46
2019-08-23 13:55:36 +02:00
Cmd_setgraphicalstatchangevalues , //0x47
Cmd_playstatchangeanimation , //0x48
Cmd_moveend , //0x49
Cmd_typecalc2 , //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
2021-01-22 08:48:22 +01:00
Cmd_endlinkbattle , //0x57
2019-08-23 13:55:36 +02:00
Cmd_returntoball , //0x58
Cmd_handlelearnnewmove , //0x59
Cmd_yesnoboxlearnmove , //0x5A
Cmd_yesnoboxstoplearningmove , //0x5B
Cmd_hitanimation , //0x5C
Cmd_getmoneyreward , //0x5D
2021-10-13 01:50:32 +02:00
Cmd_updatebattlermoves , //0x5E
2019-08-23 13:55:36 +02:00
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_adjustsetdamage , //0x69
Cmd_removeitem , //0x6A
Cmd_atknameinbuff1 , //0x6B
Cmd_drawlvlupbox , //0x6C
Cmd_resetsentmonsvalue , //0x6D
Cmd_setatktoplayer0 , //0x6E
Cmd_makevisible , //0x6F
Cmd_recordlastability , //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_nop , //0x83
Cmd_jumpifcantmakeasleep , //0x84
Cmd_stockpile , //0x85
Cmd_stockpiletobasedamage , //0x86
Cmd_stockpiletohpheal , //0x87
Cmd_negativedamage , //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_remaininghptopower , //0xAC
Cmd_tryspiteppreduce , //0xAD
Cmd_healpartystatus , //0xAE
Cmd_cursetarget , //0xAF
Cmd_trysetspikes , //0xB0
Cmd_setforesight , //0xB1
Cmd_trysetperishsong , //0xB2
Cmd_rolloutdamagecalculation , //0xB3
Cmd_jumpifconfusedandstatmaxed , //0xB4
Cmd_furycuttercalc , //0xB5
2021-03-25 18:26:22 +01:00
Cmd_friendshiptodamagecalculation , //0xB6
2019-08-23 13:55:36 +02:00
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_hiddenpowercalc , //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_trysetroots , //0xD5
Cmd_doubledamagedealtifdamaged , //0xD6
Cmd_setyawn , //0xD7
Cmd_setdamagetohealthdifference , //0xD8
Cmd_scaledamagebyhealthratio , //0xD9
Cmd_tryswapabilities , //0xDA
Cmd_tryimprison , //0xDB
Cmd_trysetgrudge , //0xDC
Cmd_weightdamagecalculation , //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_setweatherballtype , //0xE9
Cmd_tryrecycleitem , //0xEA
Cmd_settypetoterrain , //0xEB
2021-10-13 22:39:21 +02:00
Cmd_pursuitdoubles , //0xEC
2019-08-23 13:55:36 +02:00
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
2017-09-04 15:05:11 +02:00
} ;
2017-09-19 21:01:12 +02:00
struct StatFractions
2017-09-04 15:05:11 +02:00
{
u8 dividend ;
u8 divisor ;
} ;
2017-09-28 16:51:24 +02:00
static const struct StatFractions sAccuracyStageRatios [ ] =
2017-09-04 15:05:11 +02:00
{
{ 33 , 100 } , // -6
{ 36 , 100 } , // -5
{ 43 , 100 } , // -4
{ 50 , 100 } , // -3
{ 60 , 100 } , // -2
{ 75 , 100 } , // -1
{ 1 , 1 } , // 0
{ 133 , 100 } , // +1
{ 166 , 100 } , // +2
{ 2 , 1 } , // +3
{ 233 , 100 } , // +4
{ 133 , 50 } , // +5
{ 3 , 1 } , // +6
} ;
// The chance is 1/N for each stage.
2017-09-28 16:51:24 +02:00
static const u16 sCriticalHitChance [ ] = { 16 , 8 , 4 , 3 , 2 } ;
2017-09-04 15:05:11 +02:00
2020-07-17 02:12:12 +02:00
static const u32 sStatusFlagsForMoveEffects [ NUM_MOVE_EFFECTS ] =
{
[ MOVE_EFFECT_SLEEP ] = STATUS1_SLEEP ,
[ MOVE_EFFECT_POISON ] = STATUS1_POISON ,
[ MOVE_EFFECT_BURN ] = STATUS1_BURN ,
[ MOVE_EFFECT_FREEZE ] = STATUS1_FREEZE ,
[ MOVE_EFFECT_PARALYSIS ] = STATUS1_PARALYSIS ,
[ MOVE_EFFECT_TOXIC ] = STATUS1_TOXIC_POISON ,
[ MOVE_EFFECT_CONFUSION ] = STATUS2_CONFUSION ,
[ MOVE_EFFECT_FLINCH ] = STATUS2_FLINCHED ,
[ MOVE_EFFECT_UPROAR ] = STATUS2_UPROAR ,
[ MOVE_EFFECT_CHARGING ] = STATUS2_MULTIPLETURNS ,
[ MOVE_EFFECT_WRAP ] = STATUS2_WRAPPED ,
[ MOVE_EFFECT_RECHARGE ] = STATUS2_RECHARGE ,
[ MOVE_EFFECT_PREVENT_ESCAPE ] = STATUS2_ESCAPE_PREVENTION ,
[ MOVE_EFFECT_NIGHTMARE ] = STATUS2_NIGHTMARE ,
[ MOVE_EFFECT_THRASH ] = STATUS2_LOCK_CONFUSE ,
2017-09-04 15:05:11 +02:00
} ;
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
{
2020-07-17 02:12:12 +02:00
[ 0 ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_SLEEP ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_POISON ] = BattleScript_MoveEffectPoison ,
[ MOVE_EFFECT_BURN ] = BattleScript_MoveEffectBurn ,
[ MOVE_EFFECT_FREEZE ] = BattleScript_MoveEffectFreeze ,
[ MOVE_EFFECT_PARALYSIS ] = BattleScript_MoveEffectParalysis ,
[ MOVE_EFFECT_TOXIC ] = BattleScript_MoveEffectToxic ,
[ MOVE_EFFECT_CONFUSION ] = BattleScript_MoveEffectConfusion ,
[ MOVE_EFFECT_FLINCH ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_TRI_ATTACK ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_UPROAR ] = BattleScript_MoveEffectUproar ,
[ MOVE_EFFECT_PAYDAY ] = BattleScript_MoveEffectPayDay ,
[ MOVE_EFFECT_CHARGING ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_WRAP ] = BattleScript_MoveEffectWrap ,
[ MOVE_EFFECT_RECOIL_25 ] = BattleScript_MoveEffectRecoil ,
[ MOVE_EFFECT_ATK_PLUS_1 ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_DEF_PLUS_1 ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_SPD_PLUS_1 ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_SP_ATK_PLUS_1 ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_SP_DEF_PLUS_1 ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_ACC_PLUS_1 ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_EVS_PLUS_1 ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_ATK_MINUS_1 ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_DEF_MINUS_1 ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_SPD_MINUS_1 ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_SP_ATK_MINUS_1 ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_SP_DEF_MINUS_1 ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_ACC_MINUS_1 ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_EVS_MINUS_1 ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_RECHARGE ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_RAGE ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_STEAL_ITEM ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_PREVENT_ESCAPE ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_NIGHTMARE ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_ALL_STATS_UP ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_RAPIDSPIN ] = BattleScript_MoveEffectSleep ,
2018-12-08 04:33:41 +01:00
[ MOVE_EFFECT_REMOVE_PARALYSIS ] = BattleScript_MoveEffectSleep ,
2020-07-17 02:12:12 +02:00
[ MOVE_EFFECT_ATK_DEF_DOWN ] = BattleScript_MoveEffectSleep ,
[ MOVE_EFFECT_RECOIL_33 ] = BattleScript_MoveEffectRecoil ,
2017-09-26 22:39:59 +02:00
} ;
2021-10-08 22:50:52 +02:00
static const struct WindowTemplate sUnusedWinTemplate = {
. bg = 0 ,
. tilemapLeft = 1 ,
. tilemapTop = 3 ,
. width = 7 ,
. height = 15 ,
. paletteNum = 31 ,
. baseBlock = 0x3F
} ;
2017-09-26 22:39:59 +02:00
2021-10-08 22:50:52 +02:00
static const u16 sLevelUpBanner_Pal [ ] = INCBIN_U16 ( " graphics/battle_interface/level_up_banner.gbapal " ) ;
static const u32 sLevelUpBanner_Gfx [ ] = INCBIN_U32 ( " graphics/battle_interface/level_up_banner.4bpp.lz " ) ;
2017-09-28 16:32:23 +02:00
// unused
static const u8 sRubyLevelUpStatBoxStats [ ] =
{
MON_DATA_MAX_HP , MON_DATA_SPATK , MON_DATA_ATK ,
2017-10-24 03:43:26 +02:00
MON_DATA_SPDEF , MON_DATA_DEF , MON_DATA_SPEED
2017-09-28 16:32:23 +02:00
} ;
2021-10-08 22:50:52 +02:00
static const struct OamData sOamData_MonIconOnLvlUpBanner =
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 ,
} ;
2021-10-08 22:50:52 +02:00
static const struct SpriteTemplate sSpriteTemplate_MonIconOnLvlUpBanner =
2017-09-28 16:32:23 +02:00
{
2021-10-08 22:50:52 +02:00
. tileTag = TAG_LVLUP_BANNER_MON_ICON ,
. paletteTag = TAG_LVLUP_BANNER_MON_ICON ,
. oam = & sOamData_MonIconOnLvlUpBanner ,
2017-09-28 16:32:23 +02:00
. anims = gDummySpriteAnimTable ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
2021-10-08 22:50:52 +02:00
. callback = SpriteCB_MonIconOnLvlUpBanner
2017-09-28 16:32:23 +02:00
} ;
2017-09-28 16:51:24 +02:00
static const u16 sProtectSuccessRates [ ] = { USHRT_MAX , USHRT_MAX / 2 , USHRT_MAX / 4 , USHRT_MAX / 8 } ;
2017-09-28 15:34:21 +02:00
# define MIMIC_FORBIDDEN_END 0xFFFE
2018-12-05 15:31:01 +01:00
# define METRONOME_FORBIDDEN_END 0xFFFF
# define ASSIST_FORBIDDEN_END 0xFFFF
2017-09-20 22:54:26 +02:00
2017-09-28 16:51:24 +02:00
static const u16 sMovesForbiddenToCopy [ ] =
2017-09-28 16:32:23 +02:00
{
2018-12-08 04:33:41 +01:00
MOVE_METRONOME ,
MOVE_STRUGGLE ,
MOVE_SKETCH ,
MOVE_MIMIC ,
MIMIC_FORBIDDEN_END ,
MOVE_COUNTER ,
MOVE_MIRROR_COAT ,
MOVE_PROTECT ,
MOVE_DETECT ,
MOVE_ENDURE ,
MOVE_DESTINY_BOND ,
MOVE_SLEEP_TALK ,
MOVE_THIEF ,
MOVE_FOLLOW_ME ,
MOVE_SNATCH ,
MOVE_HELPING_HAND ,
MOVE_COVET ,
MOVE_TRICK ,
MOVE_FOCUS_PUNCH ,
METRONOME_FORBIDDEN_END
2017-09-28 16:32:23 +02:00
} ;
static const u8 sFlailHpScaleToPowerTable [ ] =
{
1 , 200 ,
4 , 150 ,
9 , 100 ,
16 , 80 ,
32 , 40 ,
48 , 20
} ;
static const u16 sNaturePowerMoves [ ] =
{
2020-07-17 02:12:12 +02:00
[ BATTLE_TERRAIN_GRASS ] = MOVE_STUN_SPORE ,
[ BATTLE_TERRAIN_LONG_GRASS ] = MOVE_RAZOR_LEAF ,
[ BATTLE_TERRAIN_SAND ] = MOVE_EARTHQUAKE ,
[ BATTLE_TERRAIN_UNDERWATER ] = MOVE_HYDRO_PUMP ,
[ BATTLE_TERRAIN_WATER ] = MOVE_SURF ,
[ BATTLE_TERRAIN_POND ] = MOVE_BUBBLE_BEAM ,
[ BATTLE_TERRAIN_MOUNTAIN ] = MOVE_ROCK_SLIDE ,
[ BATTLE_TERRAIN_CAVE ] = MOVE_SHADOW_BALL ,
[ BATTLE_TERRAIN_BUILDING ] = MOVE_SWIFT ,
[ BATTLE_TERRAIN_PLAIN ] = MOVE_SWIFT
2017-09-28 16:32:23 +02:00
} ;
// format: min. weight (hectograms), base power
static const u16 sWeightToDamageTable [ ] =
{
100 , 20 ,
250 , 40 ,
500 , 60 ,
1000 , 80 ,
2000 , 100 ,
2018-12-05 15:31:01 +01:00
0xFFFF , 0xFFFF
2017-09-28 16:32:23 +02:00
} ;
2017-09-28 16:51:24 +02:00
static const u16 sPickupItems [ ] =
2017-09-28 16:32:23 +02:00
{
ITEM_POTION ,
2018-12-05 15:31:01 +01:00
ITEM_ANTIDOTE ,
ITEM_SUPER_POTION ,
ITEM_GREAT_BALL ,
ITEM_REPEL ,
ITEM_ESCAPE_ROPE ,
ITEM_X_ATTACK ,
ITEM_FULL_HEAL ,
ITEM_ULTRA_BALL ,
ITEM_HYPER_POTION ,
ITEM_RARE_CANDY ,
ITEM_PROTEIN ,
ITEM_REVIVE ,
ITEM_HP_UP ,
ITEM_FULL_RESTORE ,
ITEM_MAX_REVIVE ,
ITEM_PP_UP ,
ITEM_MAX_ELIXIR ,
2017-09-28 16:32:23 +02:00
} ;
2017-09-28 16:51:24 +02:00
static const u16 sRarePickupItems [ ] =
2017-09-28 16:32:23 +02:00
{
ITEM_HYPER_POTION ,
2018-12-05 15:31:01 +01:00
ITEM_NUGGET ,
ITEM_KINGS_ROCK ,
ITEM_FULL_RESTORE ,
ITEM_ETHER ,
ITEM_WHITE_HERB ,
ITEM_TM44_REST ,
ITEM_ELIXIR ,
ITEM_TM01_FOCUS_PUNCH ,
ITEM_LEFTOVERS ,
ITEM_TM26_EARTHQUAKE ,
2017-09-28 16:32:23 +02:00
} ;
2017-09-28 16:51:24 +02:00
static const u8 sPickupProbabilities [ ] =
2017-09-28 16:32:23 +02:00
{
30 , 40 , 50 , 60 , 70 , 80 , 90 , 94 , 98
} ;
static const u8 sTerrainToType [ ] =
{
2020-07-17 02:12:12 +02:00
[ BATTLE_TERRAIN_GRASS ] = TYPE_GRASS ,
[ BATTLE_TERRAIN_LONG_GRASS ] = TYPE_GRASS ,
[ BATTLE_TERRAIN_SAND ] = TYPE_GROUND ,
[ BATTLE_TERRAIN_UNDERWATER ] = TYPE_WATER ,
[ BATTLE_TERRAIN_WATER ] = TYPE_WATER ,
[ BATTLE_TERRAIN_POND ] = TYPE_WATER ,
[ BATTLE_TERRAIN_MOUNTAIN ] = TYPE_ROCK ,
[ BATTLE_TERRAIN_CAVE ] = TYPE_ROCK ,
[ BATTLE_TERRAIN_BUILDING ] = TYPE_NORMAL ,
[ BATTLE_TERRAIN_PLAIN ] = TYPE_NORMAL ,
2017-09-28 16:32:23 +02:00
} ;
2020-07-17 02:12:12 +02:00
// In Battle Palace, moves are chosen based on the pokemons nature rather than by the player
// Moves are grouped into "Attack", "Defense", or "Support" (see PALACE_MOVE_GROUP_*)
// Each nature has a certain percent chance of selecting a move from a particular group
// and a separate percent chance for each group when below 50% HP
// The table below doesn't list percentages for Support because you can subtract the other two
// Support percentages are listed in comments off to the side instead
# define PALACE_STYLE(atk, def, atkLow, defLow) {atk, atk + def, atkLow, atkLow + defLow}
const ALIGNED ( 4 ) u8 gBattlePalaceNatureToMoveGroupLikelihood [ NUM_NATURES ] [ 4 ] =
{
[ NATURE_HARDY ] = PALACE_STYLE ( 61 , 7 , 61 , 7 ) , // 32% support >= 50% HP, 32% support < 50% HP
[ NATURE_LONELY ] = PALACE_STYLE ( 20 , 25 , 84 , 8 ) , // 55%, 8%
[ NATURE_BRAVE ] = PALACE_STYLE ( 70 , 15 , 32 , 60 ) , // 15%, 8%
[ NATURE_ADAMANT ] = PALACE_STYLE ( 38 , 31 , 70 , 15 ) , // 31%, 15%
[ NATURE_NAUGHTY ] = PALACE_STYLE ( 20 , 70 , 70 , 22 ) , // 10%, 8%
[ NATURE_BOLD ] = PALACE_STYLE ( 30 , 20 , 32 , 58 ) , // 50%, 10%
[ NATURE_DOCILE ] = PALACE_STYLE ( 56 , 22 , 56 , 22 ) , // 22%, 22%
[ NATURE_RELAXED ] = PALACE_STYLE ( 25 , 15 , 75 , 15 ) , // 60%, 10%
[ NATURE_IMPISH ] = PALACE_STYLE ( 69 , 6 , 28 , 55 ) , // 25%, 17%
[ NATURE_LAX ] = PALACE_STYLE ( 35 , 10 , 29 , 6 ) , // 55%, 65%
[ NATURE_TIMID ] = PALACE_STYLE ( 62 , 10 , 30 , 20 ) , // 28%, 50%
[ NATURE_HASTY ] = PALACE_STYLE ( 58 , 37 , 88 , 6 ) , // 5%, 6%
[ NATURE_SERIOUS ] = PALACE_STYLE ( 34 , 11 , 29 , 11 ) , // 55%, 60%
[ NATURE_JOLLY ] = PALACE_STYLE ( 35 , 5 , 35 , 60 ) , // 60%, 5%
[ NATURE_NAIVE ] = PALACE_STYLE ( 56 , 22 , 56 , 22 ) , // 22%, 22%
[ NATURE_MODEST ] = PALACE_STYLE ( 35 , 45 , 34 , 60 ) , // 20%, 6%
[ NATURE_MILD ] = PALACE_STYLE ( 44 , 50 , 34 , 6 ) , // 6%, 60%
[ NATURE_QUIET ] = PALACE_STYLE ( 56 , 22 , 56 , 22 ) , // 22%, 22%
[ NATURE_BASHFUL ] = PALACE_STYLE ( 30 , 58 , 30 , 58 ) , // 12%, 12%
[ NATURE_RASH ] = PALACE_STYLE ( 30 , 13 , 27 , 6 ) , // 57%, 67%
[ NATURE_CALM ] = PALACE_STYLE ( 40 , 50 , 25 , 62 ) , // 10%, 13%
[ NATURE_GENTLE ] = PALACE_STYLE ( 18 , 70 , 90 , 5 ) , // 12%, 5%
[ NATURE_SASSY ] = PALACE_STYLE ( 88 , 6 , 22 , 20 ) , // 6%, 58%
[ NATURE_CAREFUL ] = PALACE_STYLE ( 42 , 50 , 42 , 5 ) , // 8%, 53%
[ NATURE_QUIRKY ] = PALACE_STYLE ( 56 , 22 , 56 , 22 ) // 22%, 22%
2017-09-28 16:51:24 +02:00
} ;
2020-07-17 02:12:12 +02:00
static const u8 sBattlePalaceNatureToFlavorTextId [ NUM_NATURES ] =
{
2021-04-02 08:27:12 +02:00
[ NATURE_HARDY ] = B_MSG_EAGER_FOR_MORE ,
[ NATURE_LONELY ] = B_MSG_GLINT_IN_EYE ,
[ NATURE_BRAVE ] = B_MSG_GETTING_IN_POS ,
[ NATURE_ADAMANT ] = B_MSG_GLINT_IN_EYE ,
[ NATURE_NAUGHTY ] = B_MSG_GLINT_IN_EYE ,
[ NATURE_BOLD ] = B_MSG_GETTING_IN_POS ,
[ NATURE_DOCILE ] = B_MSG_EAGER_FOR_MORE ,
[ NATURE_RELAXED ] = B_MSG_GLINT_IN_EYE ,
[ NATURE_IMPISH ] = B_MSG_GETTING_IN_POS ,
[ NATURE_LAX ] = B_MSG_GROWL_DEEPLY ,
[ NATURE_TIMID ] = B_MSG_GROWL_DEEPLY ,
[ NATURE_HASTY ] = B_MSG_GLINT_IN_EYE ,
[ NATURE_SERIOUS ] = B_MSG_EAGER_FOR_MORE ,
[ NATURE_JOLLY ] = B_MSG_GETTING_IN_POS ,
[ NATURE_NAIVE ] = B_MSG_EAGER_FOR_MORE ,
[ NATURE_MODEST ] = B_MSG_GETTING_IN_POS ,
[ NATURE_MILD ] = B_MSG_GROWL_DEEPLY ,
[ NATURE_QUIET ] = B_MSG_EAGER_FOR_MORE ,
[ NATURE_BASHFUL ] = B_MSG_EAGER_FOR_MORE ,
[ NATURE_RASH ] = B_MSG_GROWL_DEEPLY ,
[ NATURE_CALM ] = B_MSG_GETTING_IN_POS ,
[ NATURE_GENTLE ] = B_MSG_GLINT_IN_EYE ,
[ NATURE_SASSY ] = B_MSG_GROWL_DEEPLY ,
[ NATURE_CAREFUL ] = B_MSG_GROWL_DEEPLY ,
[ NATURE_QUIRKY ] = B_MSG_EAGER_FOR_MORE ,
2017-09-28 16:51:24 +02:00
} ;
2017-09-28 16:32:23 +02:00
2019-08-23 13:55:36 +02:00
static void Cmd_attackcanceler ( void )
2017-09-19 21:01:12 +02:00
{
s32 i ;
2017-10-06 00:12:01 +02:00
if ( gBattleOutcome ! = 0 )
2017-09-19 21:01:12 +02:00
{
2018-02-06 23:09:39 +01:00
gCurrentActionFuncId = B_ACTION_FINISHED ;
2017-09-19 21:01:12 +02:00
return ;
}
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . hp = = 0 & & ! ( gHitMarker & HITMARKER_NO_ATTACKSTRING ) )
2017-09-19 21:01:12 +02:00
{
gHitMarker | = HITMARKER_UNABLE_TO_USE_MOVE ;
gBattlescriptCurrInstr = BattleScript_MoveEnd ;
return ;
}
if ( AtkCanceller_UnableToUseMove ( ) )
return ;
2018-02-06 23:09:39 +01:00
if ( AbilityBattleEffects ( ABILITYEFFECT_MOVES_BLOCK , gBattlerTarget , 0 , 0 , 0 ) )
2017-09-19 21:01:12 +02:00
return ;
2021-09-24 20:30:15 +02:00
if ( ! gBattleMons [ gBattlerAttacker ] . pp [ gCurrMovePos ] & & gCurrentMove ! = MOVE_STRUGGLE & & ! ( gHitMarker & ( HITMARKER_ALLOW_NO_PP | 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 ;
}
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_ALLOW_NO_PP ;
2017-09-19 21:01:12 +02:00
2018-02-06 23:09:39 +01:00
if ( ! ( gHitMarker & HITMARKER_OBEYS ) & & ! ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_MULTIPLETURNS ) )
2017-09-19 21:01:12 +02:00
{
2017-12-02 14:08:55 +01:00
i = IsMonDisobedient ( ) ; // why use the 'i' variable...?
2017-09-19 21:01:12 +02:00
switch ( i )
{
case 0 :
break ;
case 2 :
gHitMarker | = HITMARKER_OBEYS ;
return ;
default :
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-19 21:01:12 +02:00
return ;
}
}
gHitMarker | = HITMARKER_OBEYS ;
2020-12-12 16:09:26 +01:00
if ( gProtectStructs [ gBattlerTarget ] . bounceMove & & gBattleMoves [ gCurrentMove ] . flags & FLAG_MAGIC_COAT_AFFECTED )
2017-09-19 21:01:12 +02:00
{
2018-02-06 23:09:39 +01:00
PressurePPLose ( gBattlerAttacker , gBattlerTarget , MOVE_MAGIC_COAT ) ;
gProtectStructs [ gBattlerTarget ] . bounceMove = 0 ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-19 21:01:12 +02:00
gBattlescriptCurrInstr = BattleScript_MagicCoatBounce ;
return ;
}
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-19 21:01:12 +02:00
{
2018-06-28 21:06:32 +02:00
if ( ( gProtectStructs [ gBattlerByTurnOrder [ i ] ] . stealMove ) & & gBattleMoves [ gCurrentMove ] . flags & FLAG_SNATCH_AFFECTED )
2017-09-19 21:01:12 +02:00
{
2018-06-28 21:06:32 +02:00
PressurePPLose ( gBattlerAttacker , gBattlerByTurnOrder [ i ] , MOVE_SNATCH ) ;
gProtectStructs [ gBattlerByTurnOrder [ i ] ] . stealMove = 0 ;
gBattleScripting . battler = gBattlerByTurnOrder [ i ] ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-19 21:01:12 +02:00
gBattlescriptCurrInstr = BattleScript_SnatchedMove ;
return ;
}
}
2018-02-06 23:09:39 +01:00
if ( gSpecialStatuses [ gBattlerTarget ] . lightningRodRedirected )
2017-09-19 21:01:12 +02:00
{
2018-02-06 23:09:39 +01:00
gSpecialStatuses [ gBattlerTarget ] . lightningRodRedirected = 0 ;
2017-09-19 21:01:12 +02:00
gLastUsedAbility = ABILITY_LIGHTNING_ROD ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-19 21:01:12 +02:00
gBattlescriptCurrInstr = BattleScript_TookAttack ;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle ( gBattlerTarget , gLastUsedAbility ) ;
2017-09-19 21:01:12 +02:00
}
2018-01-16 22:12:38 +01:00
else if ( DEFENDER_IS_PROTECTED
2018-03-01 00:59:52 +01:00
& & ( gCurrentMove ! = MOVE_CURSE | | IS_BATTLER_OF_TYPE ( gBattlerAttacker , TYPE_GHOST ) )
2018-02-06 23:09:39 +01:00
& & ( ( ! IsTwoTurnsMove ( gCurrentMove ) | | ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_MULTIPLETURNS ) ) ) )
2017-09-19 21:01:12 +02:00
{
2018-02-06 23:09:39 +01:00
CancelMultiTurnMoves ( gBattlerAttacker ) ;
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2018-02-06 23:09:39 +01:00
gLastLandedMoves [ gBattlerTarget ] = 0 ;
gLastHitByType [ gBattlerTarget ] = 0 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MISS_TYPE ] = B_MSG_PROTECTED ;
2017-09-19 21:01:12 +02:00
gBattlescriptCurrInstr + + ;
}
else
{
gBattlescriptCurrInstr + + ;
}
}
2017-09-28 15:34:21 +02:00
static void JumpIfMoveFailed ( u8 adder , u16 move )
2017-09-19 21:01:12 +02:00
{
2017-11-26 14:17:02 +01:00
const u8 * BS_ptr = gBattlescriptCurrInstr + adder ;
2018-01-16 22:12:38 +01:00
if ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2017-09-19 21:01:12 +02:00
{
2018-02-06 23:09:39 +01:00
gLastLandedMoves [ gBattlerTarget ] = 0 ;
gLastHitByType [ gBattlerTarget ] = 0 ;
2018-03-01 00:59:52 +01:00
BS_ptr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-19 21:01:12 +02:00
}
else
{
2017-11-25 18:42:31 +01:00
TrySetDestinyBondToHappen ( ) ;
2018-02-06 23:09:39 +01:00
if ( AbilityBattleEffects ( ABILITYEFFECT_ABSORBING , gBattlerTarget , 0 , 0 , move ) )
2017-09-19 21:01:12 +02:00
return ;
}
gBattlescriptCurrInstr = BS_ptr ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_jumpifaffectedbyprotect ( void )
2017-09-19 21:01:12 +02:00
{
2018-01-16 22:12:38 +01:00
if ( DEFENDER_IS_PROTECTED )
2017-09-19 21:01:12 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-19 21:01:12 +02:00
JumpIfMoveFailed ( 5 , 0 ) ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MISS_TYPE ] = B_MSG_PROTECTED ;
2017-09-19 21:01:12 +02:00
}
else
{
gBattlescriptCurrInstr + = 5 ;
}
}
bool8 JumpIfMoveAffectedByProtect ( u16 move )
{
bool8 affected = FALSE ;
2018-01-16 22:12:38 +01:00
if ( DEFENDER_IS_PROTECTED )
2017-09-19 21:01:12 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-19 21:01:12 +02:00
JumpIfMoveFailed ( 7 , move ) ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MISS_TYPE ] = B_MSG_PROTECTED ;
2017-09-19 21:01:12 +02:00
affected = TRUE ;
}
return affected ;
}
2017-11-11 20:01:04 +01:00
static bool8 AccuracyCalcHelper ( u16 move )
2017-09-19 21:01:12 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gStatuses3 [ gBattlerTarget ] & STATUS3_ALWAYS_HITS & & gDisableStructs [ gBattlerTarget ] . battlerWithSureHit = = gBattlerAttacker )
2017-09-19 21:01:12 +02:00
{
JumpIfMoveFailed ( 7 , move ) ;
return TRUE ;
}
2018-02-06 23:09:39 +01:00
if ( ! ( gHitMarker & HITMARKER_IGNORE_ON_AIR ) & & gStatuses3 [ gBattlerTarget ] & STATUS3_ON_AIR )
2017-09-19 21:01:12 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-19 21:01:12 +02:00
JumpIfMoveFailed ( 7 , move ) ;
return TRUE ;
}
gHitMarker & = ~ HITMARKER_IGNORE_ON_AIR ;
2018-02-06 23:09:39 +01:00
if ( ! ( gHitMarker & HITMARKER_IGNORE_UNDERGROUND ) & & gStatuses3 [ gBattlerTarget ] & STATUS3_UNDERGROUND )
2017-09-19 21:01:12 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-19 21:01:12 +02:00
JumpIfMoveFailed ( 7 , move ) ;
return TRUE ;
}
gHitMarker & = ~ HITMARKER_IGNORE_UNDERGROUND ;
2018-02-06 23:09:39 +01:00
if ( ! ( gHitMarker & HITMARKER_IGNORE_UNDERWATER ) & & gStatuses3 [ gBattlerTarget ] & STATUS3_UNDERWATER )
2017-09-19 21:01:12 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-19 21:01:12 +02:00
JumpIfMoveFailed ( 7 , move ) ;
return TRUE ;
}
gHitMarker & = ~ HITMARKER_IGNORE_UNDERWATER ;
2021-09-30 12:08:20 +02:00
if ( ( WEATHER_HAS_EFFECT & & ( gBattleWeather & B_WEATHER_RAIN ) & & gBattleMoves [ move ] . effect = = EFFECT_THUNDER )
2017-09-19 21:01:12 +02:00
| | ( gBattleMoves [ move ] . effect = = EFFECT_ALWAYS_HIT | | gBattleMoves [ move ] . effect = = EFFECT_VITAL_THROW ) )
{
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-03 00:13:44 +02:00
if ( move = = NO_ACC_CALC | | move = = NO_ACC_CALC_CHECK_LOCK_ON )
2017-09-19 21:01:12 +02:00
{
2018-08-03 00:13:44 +02:00
if ( gStatuses3 [ gBattlerTarget ] & STATUS3_ALWAYS_HITS & & move = = NO_ACC_CALC_CHECK_LOCK_ON & & gDisableStructs [ gBattlerTarget ] . battlerWithSureHit = = gBattlerAttacker )
2017-09-19 21:01:12 +02:00
gBattlescriptCurrInstr + = 7 ;
2018-02-06 23:09:39 +01:00
else if ( gStatuses3 [ gBattlerTarget ] & ( STATUS3_ON_AIR | STATUS3_UNDERGROUND | STATUS3_UNDERWATER ) )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-19 21:01:12 +02:00
else if ( ! JumpIfMoveAffectedByProtect ( 0 ) )
gBattlescriptCurrInstr + = 7 ;
}
else
{
2018-02-08 11:17:41 +01:00
u8 type , moveAcc , holdEffect , param ;
2017-09-19 21:01:12 +02:00
s8 buff ;
u16 calc ;
2021-10-13 22:39:21 +02:00
if ( move = = ACC_CURR_MOVE )
2017-09-19 21:01:12 +02:00
move = gCurrentMove ;
GET_MOVE_TYPE ( move , type ) ;
if ( JumpIfMoveAffectedByProtect ( move ) )
return ;
if ( AccuracyCalcHelper ( move ) )
return ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_FORESIGHT )
2017-09-19 21:01:12 +02:00
{
2018-02-08 12:13:29 +01:00
u8 acc = gBattleMons [ gBattlerAttacker ] . statStages [ STAT_ACC ] ;
2017-09-19 21:01:12 +02:00
buff = acc ;
}
else
{
2018-02-08 12:13:29 +01:00
u8 acc = gBattleMons [ gBattlerAttacker ] . statStages [ STAT_ACC ] ;
2020-08-05 02:33:05 +02:00
buff = acc + DEFAULT_STAT_STAGE - gBattleMons [ gBattlerTarget ] . statStages [ STAT_EVASION ] ;
2017-09-19 21:01:12 +02:00
}
2020-08-05 02:33:05 +02:00
if ( buff < MIN_STAT_STAGE )
buff = MIN_STAT_STAGE ;
if ( buff > MAX_STAT_STAGE )
buff = MAX_STAT_STAGE ;
2017-09-19 21:01:12 +02:00
moveAcc = gBattleMoves [ move ] . accuracy ;
// check Thunder on sunny weather
2021-09-30 12:08:20 +02:00
if ( WEATHER_HAS_EFFECT & & gBattleWeather & B_WEATHER_SUN & & gBattleMoves [ move ] . effect = = EFFECT_THUNDER )
2017-09-19 21:01:12 +02:00
moveAcc = 50 ;
2017-09-28 16:51:24 +02:00
calc = sAccuracyStageRatios [ buff ] . dividend * moveAcc ;
calc / = sAccuracyStageRatios [ buff ] . divisor ;
2017-09-19 21:01:12 +02:00
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . ability = = ABILITY_COMPOUND_EYES )
2017-09-19 21:01:12 +02:00
calc = ( calc * 130 ) / 100 ; // 1.3 compound eyes boost
2021-09-30 12:08:20 +02:00
if ( WEATHER_HAS_EFFECT & & gBattleMons [ gBattlerTarget ] . ability = = ABILITY_SAND_VEIL & & gBattleWeather & B_WEATHER_SANDSTORM )
2017-09-19 21:01:12 +02:00
calc = ( calc * 80 ) / 100 ; // 1.2 sand veil loss
2018-07-16 22:00:27 +02:00
if ( gBattleMons [ gBattlerAttacker ] . ability = = ABILITY_HUSTLE & & IS_TYPE_PHYSICAL ( type ) )
2017-09-19 21:01:12 +02:00
calc = ( calc * 80 ) / 100 ; // 1.2 hustle loss
2021-12-10 18:41:54 +01:00
if ( gBattleMons [ gBattlerTarget ] . item = = ITEM_ENIGMA_BERRY_E_READER )
2017-09-19 21:01:12 +02:00
{
2018-02-06 23:09:39 +01:00
holdEffect = gEnigmaBerries [ gBattlerTarget ] . holdEffect ;
2018-02-08 11:17:41 +01:00
param = gEnigmaBerries [ gBattlerTarget ] . holdEffectParam ;
2017-09-19 21:01:12 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ gBattlerTarget ] . item ) ;
2018-02-08 11:17:41 +01:00
param = ItemId_GetHoldEffectParam ( gBattleMons [ gBattlerTarget ] . item ) ;
2017-09-19 21:01:12 +02:00
}
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerTarget ;
2017-09-19 21:01:12 +02:00
if ( holdEffect = = HOLD_EFFECT_EVASION_UP )
2018-02-08 11:17:41 +01:00
calc = ( calc * ( 100 - param ) ) / 100 ;
2017-09-19 21:01:12 +02:00
// final calculation
if ( ( Random ( ) % 100 + 1 ) > calc )
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2017-09-19 21:01:12 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE & &
( gBattleMoves [ move ] . target = = MOVE_TARGET_BOTH | | gBattleMoves [ move ] . target = = MOVE_TARGET_FOES_AND_ALLY ) )
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MISS_TYPE ] = B_MSG_AVOIDED_ATK ;
2017-09-19 21:01:12 +02:00
else
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MISS_TYPE ] = B_MSG_MISSED ;
2017-09-19 21:01:12 +02:00
2017-09-20 00:28:00 +02:00
CheckWonderGuardAndLevitate ( ) ;
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
{
2017-09-27 23:43:45 +02:00
s32 ppToDeduct = 1 ;
2017-09-20 00:28:00 +02:00
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-09-20 00:28:00 +02:00
return ;
2018-10-14 18:10:54 +02:00
if ( ! gSpecialStatuses [ gBattlerAttacker ] . ppNotAffectedByPressure )
2017-09-20 00:28:00 +02:00
{
switch ( gBattleMoves [ gCurrentMove ] . target )
{
case MOVE_TARGET_FOES_AND_ALLY :
2018-02-06 23:09:39 +01:00
ppToDeduct + = AbilityBattleEffects ( ABILITYEFFECT_COUNT_ON_FIELD , gBattlerAttacker , ABILITY_PRESSURE , 0 , 0 ) ;
2017-09-20 00:28:00 +02:00
break ;
case MOVE_TARGET_BOTH :
case MOVE_TARGET_OPPONENTS_FIELD :
2018-02-06 23:09:39 +01:00
ppToDeduct + = AbilityBattleEffects ( ABILITYEFFECT_COUNT_OTHER_SIDE , gBattlerAttacker , ABILITY_PRESSURE , 0 , 0 ) ;
2017-09-20 00:28:00 +02:00
break ;
default :
2018-02-06 23:09:39 +01:00
if ( gBattlerAttacker ! = gBattlerTarget & & gBattleMons [ gBattlerTarget ] . ability = = ABILITY_PRESSURE )
2017-09-27 23:43:45 +02:00
ppToDeduct + + ;
2017-09-20 00:28:00 +02:00
break ;
}
}
2018-02-06 23:09:39 +01:00
if ( ! ( gHitMarker & ( HITMARKER_NO_PPDEDUCT | HITMARKER_NO_ATTACKSTRING ) ) & & gBattleMons [ gBattlerAttacker ] . pp [ gCurrMovePos ] )
2017-09-20 00:28:00 +02:00
{
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . notFirstStrike = 1 ;
2017-09-20 00:28:00 +02:00
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . pp [ gCurrMovePos ] > ppToDeduct )
gBattleMons [ gBattlerAttacker ] . pp [ gCurrMovePos ] - = ppToDeduct ;
2017-09-20 00:28:00 +02:00
else
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . pp [ gCurrMovePos ] = 0 ;
2017-09-20 00:28:00 +02:00
2021-10-12 02:49:56 +02:00
if ( MOVE_IS_PERMANENT ( gBattlerAttacker , gCurrMovePos ) )
2017-09-20 00:28:00 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2021-10-13 01:50:32 +02:00
BtlController_EmitSetMonData ( BUFFER_A , REQUEST_PPMOVE1_BATTLE + gCurrMovePos , 0 ,
sizeof ( gBattleMons [ gBattlerAttacker ] . pp [ gCurrMovePos ] ) ,
& gBattleMons [ gBattlerAttacker ] . pp [ gCurrMovePos ] ) ;
2018-02-06 23:09:39 +01:00
MarkBattlerForControllerExec ( gBattlerAttacker ) ;
2017-09-20 00:28:00 +02:00
}
}
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_NO_PPDEDUCT ;
2017-09-20 00:28:00 +02:00
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_critcalc ( void )
2017-09-20 00:28:00 +02:00
{
u8 holdEffect ;
u16 item , critChance ;
2018-02-06 23:09:39 +01:00
item = gBattleMons [ gBattlerAttacker ] . item ;
2017-09-20 00:28:00 +02:00
2021-12-10 18:41:54 +01:00
if ( item = = ITEM_ENIGMA_BERRY_E_READER )
2018-02-06 23:09:39 +01:00
holdEffect = gEnigmaBerries [ gBattlerAttacker ] . holdEffect ;
2017-09-20 00:28:00 +02:00
else
holdEffect = ItemId_GetHoldEffect ( item ) ;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerAttacker ;
2017-09-20 00:28:00 +02:00
2018-02-06 23:09:39 +01:00
critChance = 2 * ( ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_FOCUS_ENERGY ) ! = 0 )
2017-09-20 00:28:00 +02:00
+ ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_HIGH_CRITICAL )
+ ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_SKY_ATTACK )
+ ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_BLAZE_KICK )
+ ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_POISON_TAIL )
+ ( holdEffect = = HOLD_EFFECT_SCOPE_LENS )
2018-02-06 23:09:39 +01:00
+ 2 * ( holdEffect = = HOLD_EFFECT_LUCKY_PUNCH & & gBattleMons [ gBattlerAttacker ] . species = = SPECIES_CHANSEY )
2021-07-03 07:43:50 +02:00
+ 2 * ( holdEffect = = HOLD_EFFECT_LEEK & & gBattleMons [ gBattlerAttacker ] . species = = SPECIES_FARFETCHD ) ;
2017-09-20 00:28:00 +02:00
2019-05-03 14:56:44 +02:00
if ( critChance > = ARRAY_COUNT ( sCriticalHitChance ) )
2019-05-04 01:17:45 +02:00
critChance = ARRAY_COUNT ( sCriticalHitChance ) - 1 ;
2017-09-20 00:28:00 +02:00
2018-02-06 23:09:39 +01:00
if ( ( gBattleMons [ gBattlerTarget ] . ability ! = ABILITY_BATTLE_ARMOR & & gBattleMons [ gBattlerTarget ] . ability ! = ABILITY_SHELL_ARMOR )
& & ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_CANT_SCORE_A_CRIT )
2017-09-20 00:28:00 +02:00
& & ! ( gBattleTypeFlags & ( BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_FIRST_BATTLE ) )
2017-09-28 16:51:24 +02:00
& & ! ( Random ( ) % sCriticalHitChance [ critChance ] ) )
2017-09-20 00:28:00 +02:00
gCritMultiplier = 2 ;
else
gCritMultiplier = 1 ;
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_damagecalc ( void )
2017-09-20 00:28:00 +02:00
{
2018-02-06 23:09:39 +01:00
u16 sideStatus = gSideStatuses [ GET_BATTLER_SIDE ( gBattlerTarget ) ] ;
gBattleMoveDamage = CalculateBaseDamage ( & gBattleMons [ gBattlerAttacker ] , & gBattleMons [ gBattlerTarget ] , gCurrentMove ,
2017-09-20 00:28:00 +02:00
sideStatus , gDynamicBasePower ,
2018-02-06 23:09:39 +01:00
gBattleStruct - > dynamicMoveType , gBattlerAttacker , gBattlerTarget ) ;
2017-09-20 00:28:00 +02:00
gBattleMoveDamage = gBattleMoveDamage * gCritMultiplier * gBattleScripting . dmgMultiplier ;
2018-02-06 23:09:39 +01:00
if ( gStatuses3 [ gBattlerAttacker ] & STATUS3_CHARGED_UP & & gBattleMoves [ gCurrentMove ] . type = = TYPE_ELECTRIC )
2017-09-20 00:28:00 +02:00
gBattleMoveDamage * = 2 ;
2018-02-06 23:09:39 +01:00
if ( gProtectStructs [ gBattlerAttacker ] . helpingHand )
2017-09-20 00:28:00 +02:00
gBattleMoveDamage = gBattleMoveDamage * 15 / 10 ;
gBattlescriptCurrInstr + + ;
}
2018-02-06 02:46:59 +01:00
void AI_CalcDmg ( u8 attacker , u8 defender )
2017-09-20 00:28:00 +02:00
{
2018-02-06 02:46:59 +01:00
u16 sideStatus = gSideStatuses [ GET_BATTLER_SIDE ( defender ) ] ;
gBattleMoveDamage = CalculateBaseDamage ( & gBattleMons [ attacker ] , & gBattleMons [ defender ] , gCurrentMove ,
2017-09-20 00:28:00 +02:00
sideStatus , gDynamicBasePower ,
2018-02-06 02:46:59 +01:00
gBattleStruct - > dynamicMoveType , attacker , defender ) ;
2017-09-20 00:28:00 +02:00
gDynamicBasePower = 0 ;
gBattleMoveDamage = gBattleMoveDamage * gCritMultiplier * gBattleScripting . dmgMultiplier ;
2018-02-06 02:46:59 +01:00
if ( gStatuses3 [ attacker ] & STATUS3_CHARGED_UP & & gBattleMoves [ gCurrentMove ] . type = = TYPE_ELECTRIC )
2017-09-20 00:28:00 +02:00
gBattleMoveDamage * = 2 ;
2018-02-06 02:46:59 +01:00
if ( gProtectStructs [ attacker ] . helpingHand )
2017-09-20 00:28:00 +02:00
gBattleMoveDamage = gBattleMoveDamage * 15 / 10 ;
}
2017-09-28 15:34:21 +02:00
static void ModulateDmgByType ( u8 multiplier )
2017-09-20 00:28:00 +02:00
{
gBattleMoveDamage = gBattleMoveDamage * multiplier / 10 ;
if ( gBattleMoveDamage = = 0 & & multiplier ! = 0 )
gBattleMoveDamage = 1 ;
switch ( multiplier )
{
case TYPE_MUL_NO_EFFECT :
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_DOESNT_AFFECT_FOE ;
gMoveResultFlags & = ~ MOVE_RESULT_NOT_VERY_EFFECTIVE ;
gMoveResultFlags & = ~ MOVE_RESULT_SUPER_EFFECTIVE ;
2017-09-20 00:28:00 +02:00
break ;
case TYPE_MUL_NOT_EFFECTIVE :
2018-01-16 22:12:38 +01:00
if ( gBattleMoves [ gCurrentMove ] . power & & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
2017-09-20 00:28:00 +02:00
{
2018-01-16 22:12:38 +01:00
if ( gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE )
gMoveResultFlags & = ~ MOVE_RESULT_SUPER_EFFECTIVE ;
2017-09-20 00:28:00 +02:00
else
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_NOT_VERY_EFFECTIVE ;
2017-09-20 00:28:00 +02:00
}
break ;
case TYPE_MUL_SUPER_EFFECTIVE :
2018-01-16 22:12:38 +01:00
if ( gBattleMoves [ gCurrentMove ] . power & & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
2017-09-20 00:28:00 +02:00
{
2018-01-16 22:12:38 +01:00
if ( gMoveResultFlags & MOVE_RESULT_NOT_VERY_EFFECTIVE )
gMoveResultFlags & = ~ MOVE_RESULT_NOT_VERY_EFFECTIVE ;
2017-09-20 00:28:00 +02:00
else
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_SUPER_EFFECTIVE ;
2017-09-20 00:28:00 +02:00
}
break ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_typecalc ( void )
2017-09-20 00:28:00 +02:00
{
s32 i = 0 ;
u8 moveType ;
if ( gCurrentMove = = MOVE_STRUGGLE )
{
gBattlescriptCurrInstr + + ;
return ;
}
GET_MOVE_TYPE ( gCurrentMove , moveType ) ;
// check stab
2018-03-01 00:59:52 +01:00
if ( IS_BATTLER_OF_TYPE ( gBattlerAttacker , moveType ) )
2017-09-20 00:28:00 +02:00
{
gBattleMoveDamage = gBattleMoveDamage * 15 ;
gBattleMoveDamage = gBattleMoveDamage / 10 ;
}
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . ability = = ABILITY_LEVITATE & & moveType = = TYPE_GROUND )
2017-09-20 00:28:00 +02:00
{
2018-02-06 23:09:39 +01:00
gLastUsedAbility = gBattleMons [ gBattlerTarget ] . ability ;
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = ( MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE ) ;
2018-02-06 23:09:39 +01:00
gLastLandedMoves [ gBattlerTarget ] = 0 ;
gLastHitByType [ gBattlerTarget ] = 0 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MISS_TYPE ] = B_MSG_GROUND_MISS ;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle ( gBattlerTarget , gLastUsedAbility ) ;
2017-09-20 00:28:00 +02:00
}
else
{
2017-11-11 20:01:04 +01:00
while ( TYPE_EFFECT_ATK_TYPE ( i ) ! = TYPE_ENDTABLE )
2017-09-20 00:28:00 +02:00
{
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( i ) = = TYPE_FORESIGHT )
2017-09-20 00:28:00 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_FORESIGHT )
2017-09-20 00:28:00 +02:00
break ;
i + = 3 ;
continue ;
}
2017-11-11 20:01:04 +01:00
else if ( TYPE_EFFECT_ATK_TYPE ( i ) = = moveType )
2017-09-20 00:28:00 +02:00
{
// check type1
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type1 )
2017-11-11 20:01:04 +01:00
ModulateDmgByType ( TYPE_EFFECT_MULTIPLIER ( i ) ) ;
2017-09-20 00:28:00 +02:00
// check type2
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type2 & &
gBattleMons [ gBattlerTarget ] . type1 ! = gBattleMons [ gBattlerTarget ] . type2 )
2017-11-11 20:01:04 +01:00
ModulateDmgByType ( TYPE_EFFECT_MULTIPLIER ( i ) ) ;
2017-09-20 00:28:00 +02:00
}
i + = 3 ;
}
}
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . ability = = ABILITY_WONDER_GUARD & & AttacksThisTurn ( gBattlerAttacker , gCurrentMove ) = = 2
2018-01-16 22:12:38 +01:00
& & ( ! ( gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE ) | | ( ( gMoveResultFlags & ( MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE ) ) = = ( MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE ) ) )
2017-09-20 00:28:00 +02:00
& & gBattleMoves [ gCurrentMove ] . power )
{
gLastUsedAbility = ABILITY_WONDER_GUARD ;
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2018-02-06 23:09:39 +01:00
gLastLandedMoves [ gBattlerTarget ] = 0 ;
gLastHitByType [ gBattlerTarget ] = 0 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MISS_TYPE ] = B_MSG_AVOIDED_DMG ;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle ( gBattlerTarget , gLastUsedAbility ) ;
2017-09-20 00:28:00 +02:00
}
2018-01-16 22:12:38 +01:00
if ( gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE )
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . targetNotAffected = 1 ;
2017-09-20 00:28:00 +02:00
gBattlescriptCurrInstr + + ;
}
static void CheckWonderGuardAndLevitate ( void )
{
u8 flags = 0 ;
s32 i = 0 ;
u8 moveType ;
if ( gCurrentMove = = MOVE_STRUGGLE | | ! gBattleMoves [ gCurrentMove ] . power )
return ;
GET_MOVE_TYPE ( gCurrentMove , moveType ) ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . ability = = ABILITY_LEVITATE & & moveType = = TYPE_GROUND )
2017-09-20 00:28:00 +02:00
{
gLastUsedAbility = ABILITY_LEVITATE ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MISS_TYPE ] = B_MSG_GROUND_MISS ;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle ( gBattlerTarget , ABILITY_LEVITATE ) ;
2017-09-20 00:28:00 +02:00
return ;
}
2017-11-11 20:01:04 +01:00
while ( TYPE_EFFECT_ATK_TYPE ( i ) ! = TYPE_ENDTABLE )
2017-09-20 00:28:00 +02:00
{
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( i ) = = TYPE_FORESIGHT )
2017-09-20 00:28:00 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_FORESIGHT )
2017-09-20 00:28:00 +02:00
break ;
i + = 3 ;
continue ;
}
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( i ) = = moveType )
2017-09-20 00:28:00 +02:00
{
// check no effect
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type1
2017-11-11 20:01:04 +01:00
& & TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_NO_EFFECT )
2017-09-20 00:28:00 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_DOESNT_AFFECT_FOE ;
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . targetNotAffected = 1 ;
2017-09-20 00:28:00 +02:00
}
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type2 & &
gBattleMons [ gBattlerTarget ] . type1 ! = gBattleMons [ gBattlerTarget ] . type2 & &
2017-11-11 20:01:04 +01:00
TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_NO_EFFECT )
2017-09-20 00:28:00 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_DOESNT_AFFECT_FOE ;
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . targetNotAffected = 1 ;
2017-09-20 00:28:00 +02:00
}
// check super effective
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type1 & & TYPE_EFFECT_MULTIPLIER ( i ) = = 20 )
2017-09-20 00:28:00 +02:00
flags | = 1 ;
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type2
& & gBattleMons [ gBattlerTarget ] . type1 ! = gBattleMons [ gBattlerTarget ] . type2
2017-11-11 20:01:04 +01:00
& & TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_SUPER_EFFECTIVE )
2017-09-20 00:28:00 +02:00
flags | = 1 ;
// check not very effective
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type1 & & TYPE_EFFECT_MULTIPLIER ( i ) = = 5 )
2017-09-20 00:28:00 +02:00
flags | = 2 ;
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type2
& & gBattleMons [ gBattlerTarget ] . type1 ! = gBattleMons [ gBattlerTarget ] . type2
2017-11-11 20:01:04 +01:00
& & TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_NOT_EFFECTIVE )
2017-09-20 00:28:00 +02:00
flags | = 2 ;
}
i + = 3 ;
}
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . ability = = ABILITY_WONDER_GUARD & & AttacksThisTurn ( gBattlerAttacker , gCurrentMove ) = = 2 )
2017-09-20 00:28:00 +02:00
{
if ( ( ( flags & 2 ) | | ! ( flags & 1 ) ) & & gBattleMoves [ gCurrentMove ] . power )
{
gLastUsedAbility = ABILITY_WONDER_GUARD ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MISS_TYPE ] = B_MSG_AVOIDED_DMG ;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle ( gBattlerTarget , ABILITY_WONDER_GUARD ) ;
2017-09-20 00:28:00 +02:00
}
}
}
2017-09-28 15:34:21 +02:00
static void ModulateDmgByType2 ( u8 multiplier , u16 move , u8 * flags ) // same as ModulateDmgByType except different arguments
2017-09-20 00:28:00 +02:00
{
gBattleMoveDamage = gBattleMoveDamage * multiplier / 10 ;
if ( gBattleMoveDamage = = 0 & & multiplier ! = 0 )
gBattleMoveDamage = 1 ;
switch ( multiplier )
{
case TYPE_MUL_NO_EFFECT :
2018-01-16 22:12:38 +01:00
* flags | = MOVE_RESULT_DOESNT_AFFECT_FOE ;
* flags & = ~ MOVE_RESULT_NOT_VERY_EFFECTIVE ;
* flags & = ~ MOVE_RESULT_SUPER_EFFECTIVE ;
2017-09-20 00:28:00 +02:00
break ;
case TYPE_MUL_NOT_EFFECTIVE :
2018-01-16 22:12:38 +01:00
if ( gBattleMoves [ move ] . power & & ! ( * flags & MOVE_RESULT_NO_EFFECT ) )
2017-09-20 00:28:00 +02:00
{
2018-01-16 22:12:38 +01:00
if ( * flags & MOVE_RESULT_SUPER_EFFECTIVE )
* flags & = ~ MOVE_RESULT_SUPER_EFFECTIVE ;
2017-09-20 00:28:00 +02:00
else
2018-01-16 22:12:38 +01:00
* flags | = MOVE_RESULT_NOT_VERY_EFFECTIVE ;
2017-09-20 00:28:00 +02:00
}
break ;
case TYPE_MUL_SUPER_EFFECTIVE :
2018-01-16 22:12:38 +01:00
if ( gBattleMoves [ move ] . power & & ! ( * flags & MOVE_RESULT_NO_EFFECT ) )
2017-09-20 00:28:00 +02:00
{
2018-01-16 22:12:38 +01:00
if ( * flags & MOVE_RESULT_NOT_VERY_EFFECTIVE )
* flags & = ~ MOVE_RESULT_NOT_VERY_EFFECTIVE ;
2017-09-20 00:28:00 +02:00
else
2018-01-16 22:12:38 +01:00
* flags | = MOVE_RESULT_SUPER_EFFECTIVE ;
2017-09-20 00:28:00 +02:00
}
break ;
}
}
2018-02-06 02:46:59 +01:00
u8 TypeCalc ( u16 move , u8 attacker , u8 defender )
2017-09-20 00:28:00 +02:00
{
s32 i = 0 ;
u8 flags = 0 ;
u8 moveType ;
if ( move = = MOVE_STRUGGLE )
return 0 ;
moveType = gBattleMoves [ move ] . type ;
// check stab
2018-03-01 00:59:52 +01:00
if ( IS_BATTLER_OF_TYPE ( attacker , moveType ) )
2017-09-20 00:28:00 +02:00
{
gBattleMoveDamage = gBattleMoveDamage * 15 ;
gBattleMoveDamage = gBattleMoveDamage / 10 ;
}
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ defender ] . ability = = ABILITY_LEVITATE & & moveType = = TYPE_GROUND )
2017-09-20 00:28:00 +02:00
{
2018-01-16 22:12:38 +01:00
flags | = ( MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE ) ;
2017-09-20 00:28:00 +02:00
}
else
{
2017-11-11 20:01:04 +01:00
while ( TYPE_EFFECT_ATK_TYPE ( i ) ! = TYPE_ENDTABLE )
2017-09-20 00:28:00 +02:00
{
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( i ) = = TYPE_FORESIGHT )
2017-09-20 00:28:00 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ defender ] . status2 & STATUS2_FORESIGHT )
2017-09-20 00:28:00 +02:00
break ;
i + = 3 ;
continue ;
}
2017-11-11 20:01:04 +01:00
else if ( TYPE_EFFECT_ATK_TYPE ( i ) = = moveType )
2017-09-20 00:28:00 +02:00
{
// check type1
2018-02-06 02:46:59 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ defender ] . type1 )
2017-11-11 20:01:04 +01:00
ModulateDmgByType2 ( TYPE_EFFECT_MULTIPLIER ( i ) , move , & flags ) ;
2017-09-20 00:28:00 +02:00
// check type2
2018-02-06 02:46:59 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ defender ] . type2 & &
gBattleMons [ defender ] . type1 ! = gBattleMons [ defender ] . type2 )
2017-11-11 20:01:04 +01:00
ModulateDmgByType2 ( TYPE_EFFECT_MULTIPLIER ( i ) , move , & flags ) ;
2017-09-20 00:28:00 +02:00
}
i + = 3 ;
}
}
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ defender ] . ability = = ABILITY_WONDER_GUARD & & ! ( flags & MOVE_RESULT_MISSED )
& & AttacksThisTurn ( attacker , move ) = = 2
2018-01-16 22:12:38 +01:00
& & ( ! ( flags & MOVE_RESULT_SUPER_EFFECTIVE ) | | ( ( flags & ( MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE ) ) = = ( MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE ) ) )
2017-09-20 00:28:00 +02:00
& & gBattleMoves [ move ] . power )
{
2018-01-16 22:12:38 +01:00
flags | = MOVE_RESULT_MISSED ;
2017-09-20 00:28:00 +02:00
}
return flags ;
}
2017-10-10 18:01:45 +02:00
u8 AI_TypeCalc ( u16 move , u16 targetSpecies , u8 targetAbility )
2017-09-20 00:28:00 +02:00
{
s32 i = 0 ;
u8 flags = 0 ;
2017-10-10 18:01:45 +02:00
u8 type1 = gBaseStats [ targetSpecies ] . type1 , type2 = gBaseStats [ targetSpecies ] . type2 ;
2017-09-20 00:28:00 +02:00
u8 moveType ;
if ( move = = MOVE_STRUGGLE )
return 0 ;
moveType = gBattleMoves [ move ] . type ;
2017-10-10 18:01:45 +02:00
if ( targetAbility = = ABILITY_LEVITATE & & moveType = = TYPE_GROUND )
2017-09-20 00:28:00 +02:00
{
2018-01-16 22:12:38 +01:00
flags = MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE ;
2017-09-20 00:28:00 +02:00
}
else
{
2017-11-11 20:01:04 +01:00
while ( TYPE_EFFECT_ATK_TYPE ( i ) ! = TYPE_ENDTABLE )
2017-09-20 00:28:00 +02:00
{
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( i ) = = TYPE_FORESIGHT )
2017-09-20 00:28:00 +02:00
{
i + = 3 ;
continue ;
}
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( i ) = = moveType )
2017-09-20 00:28:00 +02:00
{
// check type1
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = type1 )
ModulateDmgByType2 ( TYPE_EFFECT_MULTIPLIER ( i ) , move , & flags ) ;
2017-09-20 00:28:00 +02:00
// check type2
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = type2 & & type1 ! = type2 )
ModulateDmgByType2 ( TYPE_EFFECT_MULTIPLIER ( i ) , move , & flags ) ;
2017-09-20 00:28:00 +02:00
}
i + = 3 ;
}
}
2017-10-10 18:01:45 +02:00
if ( targetAbility = = ABILITY_WONDER_GUARD
2018-01-16 22:12:38 +01:00
& & ( ! ( flags & MOVE_RESULT_SUPER_EFFECTIVE ) | | ( ( flags & ( MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE ) ) = = ( MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE ) ) )
2017-09-20 00:28:00 +02:00
& & gBattleMoves [ move ] . power )
2018-01-16 22:12:38 +01:00
flags | = MOVE_RESULT_DOESNT_AFFECT_FOE ;
2017-09-20 00:28:00 +02:00
return flags ;
}
// Multiplies the damage by a random factor between 85% to 100% inclusive
static inline void ApplyRandomDmgMultiplier ( void )
{
u16 rand = Random ( ) ;
u16 randPercent = 100 - ( rand % 16 ) ;
if ( gBattleMoveDamage ! = 0 )
{
gBattleMoveDamage * = randPercent ;
gBattleMoveDamage / = 100 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
}
}
2017-09-28 15:34:21 +02:00
static void Unused_ApplyRandomDmgMultiplier ( void )
2017-09-20 00:28:00 +02:00
{
ApplyRandomDmgMultiplier ( ) ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_adjustnormaldamage ( void )
2017-09-20 00:28:00 +02:00
{
2018-02-08 11:17:41 +01:00
u8 holdEffect , param ;
2017-09-20 00:28:00 +02:00
ApplyRandomDmgMultiplier ( ) ;
2021-12-10 18:41:54 +01:00
if ( gBattleMons [ gBattlerTarget ] . item = = ITEM_ENIGMA_BERRY_E_READER )
2017-09-20 00:28:00 +02:00
{
2018-02-08 11:17:41 +01:00
holdEffect = gEnigmaBerries [ gBattlerTarget ] . holdEffect ;
param = gEnigmaBerries [ gBattlerTarget ] . holdEffectParam ;
2017-09-20 00:28:00 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ gBattlerTarget ] . item ) ;
2018-02-08 11:17:41 +01:00
param = ItemId_GetHoldEffectParam ( gBattleMons [ gBattlerTarget ] . item ) ;
2017-09-20 00:28:00 +02:00
}
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerTarget ;
2017-09-20 00:28:00 +02:00
2018-02-08 11:17:41 +01:00
if ( holdEffect = = HOLD_EFFECT_FOCUS_BAND & & ( Random ( ) % 100 ) < param )
2017-09-20 00:28:00 +02:00
{
2018-02-06 23:09:39 +01:00
RecordItemEffectBattle ( gBattlerTarget , holdEffect ) ;
gSpecialStatuses [ gBattlerTarget ] . focusBanded = 1 ;
2017-09-20 00:28:00 +02:00
}
2019-08-28 00:06:17 +02:00
if ( ! ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_SUBSTITUTE )
& & ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_FALSE_SWIPE | | gProtectStructs [ gBattlerTarget ] . endured | | gSpecialStatuses [ gBattlerTarget ] . focusBanded )
& & gBattleMons [ gBattlerTarget ] . hp < = gBattleMoveDamage )
2017-09-20 00:28:00 +02:00
{
2019-08-28 00:06:17 +02:00
gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . hp - 1 ;
if ( gProtectStructs [ gBattlerTarget ] . endured )
{
gMoveResultFlags | = MOVE_RESULT_FOE_ENDURED ;
}
else if ( gSpecialStatuses [ gBattlerTarget ] . focusBanded )
{
gMoveResultFlags | = MOVE_RESULT_FOE_HUNG_ON ;
gLastUsedItem = gBattleMons [ gBattlerTarget ] . item ;
}
2017-09-20 00:28:00 +02:00
}
2019-08-28 00:06:17 +02:00
gBattlescriptCurrInstr + + ;
2017-09-20 00:28:00 +02:00
}
2019-08-23 14:46:21 +02:00
static void Cmd_adjustnormaldamage2 ( void ) // The same as adjustnormaldamage except it doesn't check for false swipe move effect.
2017-09-20 00:28:00 +02:00
{
2018-02-08 11:17:41 +01:00
u8 holdEffect , param ;
2017-09-20 00:28:00 +02:00
ApplyRandomDmgMultiplier ( ) ;
2021-12-10 18:41:54 +01:00
if ( gBattleMons [ gBattlerTarget ] . item = = ITEM_ENIGMA_BERRY_E_READER )
2017-09-20 00:28:00 +02:00
{
2018-02-08 11:17:41 +01:00
holdEffect = gEnigmaBerries [ gBattlerTarget ] . holdEffect ;
param = gEnigmaBerries [ gBattlerTarget ] . holdEffectParam ;
2017-09-20 00:28:00 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ gBattlerTarget ] . item ) ;
2018-02-08 11:17:41 +01:00
param = ItemId_GetHoldEffectParam ( gBattleMons [ gBattlerTarget ] . item ) ;
2017-09-20 00:28:00 +02:00
}
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerTarget ;
2017-09-20 00:28:00 +02:00
2018-02-08 11:17:41 +01:00
if ( holdEffect = = HOLD_EFFECT_FOCUS_BAND & & ( Random ( ) % 100 ) < param )
2017-09-20 00:28:00 +02:00
{
2018-02-06 23:09:39 +01:00
RecordItemEffectBattle ( gBattlerTarget , holdEffect ) ;
gSpecialStatuses [ gBattlerTarget ] . focusBanded = 1 ;
2017-09-20 00:28:00 +02:00
}
2019-08-28 00:06:17 +02:00
if ( ! ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_SUBSTITUTE )
& & ( gProtectStructs [ gBattlerTarget ] . endured | | gSpecialStatuses [ gBattlerTarget ] . focusBanded )
& & gBattleMons [ gBattlerTarget ] . hp < = gBattleMoveDamage )
2017-09-20 00:28:00 +02:00
{
2019-08-28 00:06:17 +02:00
gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . hp - 1 ;
if ( gProtectStructs [ gBattlerTarget ] . endured )
{
gMoveResultFlags | = MOVE_RESULT_FOE_ENDURED ;
}
else if ( gSpecialStatuses [ gBattlerTarget ] . focusBanded )
{
gMoveResultFlags | = MOVE_RESULT_FOE_HUNG_ON ;
gLastUsedItem = gBattleMons [ gBattlerTarget ] . item ;
}
2017-09-20 00:28:00 +02:00
}
2019-08-28 00:06:17 +02:00
gBattlescriptCurrInstr + + ;
2017-09-20 00:28:00 +02:00
}
2019-08-23 13:55:36 +02: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 ;
2021-10-13 01:50:32 +02:00
BtlController_EmitMoveAnimation ( BUFFER_A , 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-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_SUBSTITUTE & & gDisableStructs [ gActiveBattler ] . substituteHP & & ! ( gHitMarker & HITMARKER_IGNORE_SUBSTITUTE ) )
2017-09-20 12:56:45 +02:00
{
2018-02-06 02:46:59 +01:00
PrepareStringBattle ( STRINGID_SUBSTITUTEDAMAGED , gActiveBattler ) ;
2017-09-20 12:56:45 +02:00
}
else
{
s16 healthValue ;
s32 currDmg = gBattleMoveDamage ;
s32 maxPossibleDmgValue = 10000 ; // not present in R/S, ensures that huge damage values don't change sign
if ( currDmg < = maxPossibleDmgValue )
healthValue = currDmg ;
else
healthValue = maxPossibleDmgValue ;
2021-10-13 01:50:32 +02:00
BtlController_EmitHealthBarUpdate ( BUFFER_A , healthValue ) ;
2018-02-06 20:48:02 +01:00
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 ;
2021-10-04 16:21:03 +02:00
else if ( ! ( gBattleStruct - > dynamicMoveType & F_DYNAMIC_TYPE_1 ) )
moveType = gBattleStruct - > dynamicMoveType & DYNAMIC_TYPE_MASK ;
2017-09-20 12:56:45 +02:00
else
moveType = gBattleMoves [ gCurrentMove ] . type ;
2017-09-20 00:28:00 +02:00
2018-01-16 22:12:38 +01:00
if ( ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
2017-09-20 00:28:00 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_SUBSTITUTE & & gDisableStructs [ gActiveBattler ] . substituteHP & & ! ( gHitMarker & HITMARKER_IGNORE_SUBSTITUTE ) )
2017-09-20 12:56:45 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gDisableStructs [ gActiveBattler ] . substituteHP > = gBattleMoveDamage )
2017-09-20 12:56:45 +02:00
{
2018-02-07 22:53:40 +01:00
if ( gSpecialStatuses [ gActiveBattler ] . dmg = = 0 )
gSpecialStatuses [ gActiveBattler ] . dmg = gBattleMoveDamage ;
2018-02-06 02:46:59 +01:00
gDisableStructs [ gActiveBattler ] . substituteHP - = gBattleMoveDamage ;
2017-09-20 12:56:45 +02:00
gHpDealt = gBattleMoveDamage ;
}
else
{
2018-02-07 22:53:40 +01:00
if ( gSpecialStatuses [ gActiveBattler ] . dmg = = 0 )
gSpecialStatuses [ gActiveBattler ] . dmg = gDisableStructs [ gActiveBattler ] . substituteHP ;
2018-02-06 02:46:59 +01:00
gHpDealt = gDisableStructs [ gActiveBattler ] . substituteHP ;
gDisableStructs [ gActiveBattler ] . substituteHP = 0 ;
2017-09-20 12:56:45 +02:00
}
// check substitute fading
2018-02-06 02:46:59 +01:00
if ( gDisableStructs [ gActiveBattler ] . substituteHP = = 0 )
2017-09-20 12:56:45 +02:00
{
gBattlescriptCurrInstr + = 2 ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr = BattleScript_SubstituteFade ;
return ;
}
}
else
{
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_IGNORE_SUBSTITUTE ;
2017-09-20 12:56:45 +02:00
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
{
2021-09-24 20:30:15 +02:00
if ( gHitMarker & HITMARKER_SKIP_DMG_TRACK )
2017-09-20 12:56:45 +02:00
{
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_SKIP_DMG_TRACK ;
2017-09-20 12:56:45 +02:00
}
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
}
2021-09-24 20:30:15 +02:00
if ( ! gSpecialStatuses [ gActiveBattler ] . dmg & & ! ( gHitMarker & HITMARKER_PASSIVE_DAMAGE ) )
2018-02-07 22:53:40 +01:00
gSpecialStatuses [ gActiveBattler ] . dmg = gHpDealt ;
2017-09-20 12:56:45 +02:00
2021-09-24 20:30:15 +02:00
if ( IS_TYPE_PHYSICAL ( moveType ) & & ! ( gHitMarker & HITMARKER_PASSIVE_DAMAGE ) & & 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
}
}
2021-09-24 20:30:15 +02:00
else if ( ! IS_TYPE_PHYSICAL ( moveType ) & & ! ( gHitMarker & HITMARKER_PASSIVE_DAMAGE ) )
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
}
}
}
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_PASSIVE_DAMAGE ;
2021-10-13 01:50:32 +02:00
BtlController_EmitSetMonData ( BUFFER_A , REQUEST_HP_BATTLE , 0 , sizeof ( gBattleMons [ gActiveBattler ] . hp ) , & gBattleMons [ gActiveBattler ] . hp ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-20 12:56:45 +02:00
}
}
else
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-02-07 22:53:40 +01:00
if ( gSpecialStatuses [ gActiveBattler ] . dmg = = 0 )
2018-12-05 15:31:01 +01:00
gSpecialStatuses [ gActiveBattler ] . dmg = 0xFFFF ;
2017-09-20 12:56:45 +02:00
}
gBattlescriptCurrInstr + = 2 ;
}
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-01-16 22:12:38 +01:00
if ( gCritMultiplier = = 2 & & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
2017-09-20 12:56:45 +02:00
{
2018-02-06 23:09:39 +01:00
PrepareStringBattle ( STRINGID_CRITICALHIT , gBattlerAttacker ) ;
2017-09-20 12:56:45 +02:00
gBattleCommunication [ MSG_DISPLAY ] = 1 ;
}
gBattlescriptCurrInstr + + ;
}
}
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
{
2021-09-24 20:30:15 +02:00
switch ( gMoveResultFlags & ( u8 ) ( ~ MOVE_RESULT_MISSED ) )
2017-09-20 12:56:45 +02:00
{
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_SUPER_EFFECTIVE :
2021-10-13 01:50:32 +02:00
BtlController_EmitPlaySE ( BUFFER_A , SE_SUPER_EFFECTIVE ) ;
2018-02-06 20:48:02 +01:00
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 :
2021-10-13 01:50:32 +02:00
BtlController_EmitPlaySE ( BUFFER_A , SE_NOT_EFFECTIVE ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-20 12:56:45 +02:00
break ;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_DOESNT_AFFECT_FOE :
case MOVE_RESULT_FAILED :
2017-09-20 12:56:45 +02:00
// no sound
break ;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_FOE_ENDURED :
case MOVE_RESULT_ONE_HIT_KO :
case MOVE_RESULT_FOE_HUNG_ON :
2017-09-20 12:56:45 +02:00
default :
2018-01-16 22:12:38 +01:00
if ( gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE )
2017-09-20 12:56:45 +02:00
{
2021-10-13 01:50:32 +02:00
BtlController_EmitPlaySE ( BUFFER_A , SE_SUPER_EFFECTIVE ) ;
2018-02-06 20:48:02 +01:00
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
{
2021-10-13 01:50:32 +02:00
BtlController_EmitPlaySE ( BUFFER_A , SE_NOT_EFFECTIVE ) ;
2018-02-06 20:48:02 +01:00
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
{
2021-10-13 01:50:32 +02:00
BtlController_EmitPlaySE ( BUFFER_A , SE_EFFECTIVE ) ;
2018-02-06 20:48:02 +01:00
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 ;
2021-04-02 08:27:12 +02:00
if ( gMoveResultFlags & MOVE_RESULT_MISSED & & ( ! ( gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE ) | | gBattleCommunication [ MISS_TYPE ] > B_MSG_AVOIDED_ATK ) )
2017-09-20 12:56:45 +02:00
{
2021-04-02 08:27:12 +02:00
stringId = gMissStringIds [ gBattleCommunication [ MISS_TYPE ] ] ;
2017-09-20 12:56:45 +02:00
gBattleCommunication [ MSG_DISPLAY ] = 1 ;
}
else
{
gBattleCommunication [ MSG_DISPLAY ] = 1 ;
2021-09-24 20:30:15 +02:00
switch ( gMoveResultFlags & ( u8 ) ( ~ MOVE_RESULT_MISSED ) )
2017-09-20 12:56:45 +02:00
{
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_SUPER_EFFECTIVE :
2017-10-07 15:15:47 +02:00
stringId = STRINGID_SUPEREFFECTIVE ;
2017-09-20 12:56:45 +02:00
break ;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_NOT_VERY_EFFECTIVE :
2017-10-07 15:15:47 +02:00
stringId = STRINGID_NOTVERYEFFECTIVE ;
2017-09-20 12:56:45 +02:00
break ;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_ONE_HIT_KO :
2017-10-07 15:15:47 +02:00
stringId = STRINGID_ONEHITKO ;
2017-09-20 12:56:45 +02:00
break ;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_FOE_ENDURED :
2017-10-07 15:15:47 +02:00
stringId = STRINGID_PKMNENDUREDHIT ;
2017-09-20 12:56:45 +02:00
break ;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_FAILED :
2017-10-07 15:15:47 +02:00
stringId = STRINGID_BUTITFAILED ;
2017-09-20 12:56:45 +02:00
break ;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_DOESNT_AFFECT_FOE :
2017-10-07 15:15:47 +02:00
stringId = STRINGID_ITDOESNTAFFECT ;
2017-09-20 12:56:45 +02:00
break ;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_FOE_HUNG_ON :
2018-02-06 23:09:39 +01:00
gLastUsedItem = gBattleMons [ gBattlerTarget ] . item ;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerTarget ;
2018-01-16 22:12:38 +01:00
gMoveResultFlags & = ~ ( MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2020-02-20 05:13:54 +01:00
gBattlescriptCurrInstr = BattleScript_FocusBandActivates ;
2017-09-20 12:56:45 +02:00
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
{
2021-09-24 20:30:15 +02:00
gMoveResultFlags & = ~ MOVE_RESULT_ONE_HIT_KO ;
gMoveResultFlags & = ~ MOVE_RESULT_SUPER_EFFECTIVE ;
gMoveResultFlags & = ~ MOVE_RESULT_NOT_VERY_EFFECTIVE ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr = BattleScript_OneHitKOMsg ;
return ;
}
2018-01-16 22:12:38 +01:00
else if ( gMoveResultFlags & MOVE_RESULT_FOE_ENDURED )
2017-09-20 12:56:45 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags & = ~ ( MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr = BattleScript_EnduredMsg ;
return ;
}
2018-01-16 22:12:38 +01:00
else if ( gMoveResultFlags & MOVE_RESULT_FOE_HUNG_ON )
2017-09-20 12:56:45 +02:00
{
2018-02-06 23:09:39 +01:00
gLastUsedItem = gBattleMons [ gBattlerTarget ] . item ;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerTarget ;
2018-01-16 22:12:38 +01:00
gMoveResultFlags & = ~ ( MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2020-02-20 05:13:54 +01:00
gBattlescriptCurrInstr = BattleScript_FocusBandActivates ;
2017-09-20 12:56:45 +02:00
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-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 ) ;
2018-02-06 23:09:39 +01:00
PrepareStringBattle ( var , gBattlerAttacker ) ;
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr + = 3 ;
gBattleCommunication [ MSG_DISPLAY ] = 1 ;
2017-09-20 00:28:00 +02:00
}
2017-09-20 12:56:45 +02:00
}
2017-09-20 00:28:00 +02:00
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
2021-10-13 01:50:32 +02:00
BtlController_EmitPrintSelectionString ( BUFFER_A , 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 ] ;
2018-02-06 23:09:39 +01:00
PrepareStringBattle ( * ptr , gBattlerAttacker ) ;
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr + = 5 ;
gBattleCommunication [ MSG_DISPLAY ] = 1 ;
}
}
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 ;
2021-10-13 01:50:32 +02:00
BtlController_EmitPrintSelectionString ( BUFFER_A , * ptr ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr + = 5 ;
gBattleCommunication [ MSG_DISPLAY ] = 1 ;
}
}
2018-02-08 12:13:29 +01:00
u8 GetBattlerTurnOrderNum ( u8 battlerId )
2017-09-20 12:56:45 +02:00
{
s32 i ;
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-20 12:56:45 +02:00
{
2018-06-28 21:06:32 +02:00
if ( gBattlerByTurnOrder [ i ] = = battlerId )
2017-09-20 12:56:45 +02:00
break ;
}
return i ;
2017-09-20 00:28:00 +02:00
}
2017-09-20 22:54:26 +02:00
# define INCREMENT_RESET_RETURN \
{ \
gBattlescriptCurrInstr + + ; \
gBattleCommunication [ MOVE_EFFECT_BYTE ] = 0 ; \
return ; \
}
# define RESET_RETURN \
{ \
gBattleCommunication [ MOVE_EFFECT_BYTE ] = 0 ; \
return ; \
}
void SetMoveEffect ( bool8 primary , u8 certain )
{
bool32 statusChanged = FALSE ;
u8 affectsUser = 0 ; // 0x40 otherwise
bool32 noSunCanFreeze = TRUE ;
if ( gBattleCommunication [ MOVE_EFFECT_BYTE ] & MOVE_EFFECT_AFFECTS_USER )
{
2018-02-08 12:13:29 +01:00
gEffectBattler = gBattlerAttacker ; // battlerId that effects get applied on
2021-09-24 20:30:15 +02:00
gBattleCommunication [ MOVE_EFFECT_BYTE ] & = ~ 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
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_SHIELD_DUST & & ! ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
2017-09-20 22:54:26 +02:00
& & ! primary & & gBattleCommunication [ MOVE_EFFECT_BYTE ] < = 9 )
INCREMENT_RESET_RETURN
2018-02-08 11:17:41 +01:00
if ( gSideStatuses [ GET_BATTLER_SIDE ( gEffectBattler ) ] & SIDE_STATUS_SAFEGUARD & & ! ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
2017-09-20 22:54:26 +02:00
& & ! primary & & gBattleCommunication [ MOVE_EFFECT_BYTE ] < = 7 )
INCREMENT_RESET_RETURN
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . hp = = 0
2017-09-20 22:54:26 +02:00
& & gBattleCommunication [ MOVE_EFFECT_BYTE ] ! = MOVE_EFFECT_PAYDAY
& & gBattleCommunication [ MOVE_EFFECT_BYTE ] ! = MOVE_EFFECT_STEAL_ITEM )
INCREMENT_RESET_RETURN
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status2 & STATUS2_SUBSTITUTE & & affectsUser ! = MOVE_EFFECT_AFFECTS_USER )
2017-09-20 22:54:26 +02:00
INCREMENT_RESET_RETURN
2020-07-17 02:12:12 +02:00
if ( gBattleCommunication [ MOVE_EFFECT_BYTE ] < = PRIMARY_STATUS_MOVE_EFFECT )
2017-09-20 22:54:26 +02:00
{
2017-09-28 16:51:24 +02:00
switch ( sStatusFlagsForMoveEffects [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] )
2017-09-20 22:54:26 +02:00
{
2018-01-16 22:12:38 +01:00
case STATUS1_SLEEP :
2017-09-20 22:54:26 +02:00
// check active uproar
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability ! = ABILITY_SOUNDPROOF )
2017-09-20 22:54:26 +02:00
{
2018-02-06 02:46:59 +01:00
for ( gActiveBattler = 0 ;
gActiveBattler < gBattlersCount & & ! ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_UPROAR ) ;
gActiveBattler + + )
2017-09-20 22:54:26 +02:00
{ }
}
else
2018-02-06 02:46:59 +01:00
gActiveBattler = gBattlersCount ;
2017-09-20 22:54:26 +02:00
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status1 )
2017-09-20 22:54:26 +02:00
break ;
2018-02-06 02:46:59 +01:00
if ( gActiveBattler ! = gBattlersCount )
2017-09-20 22:54:26 +02:00
break ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_VITAL_SPIRIT )
2017-09-20 22:54:26 +02:00
break ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_INSOMNIA )
2017-09-20 22:54:26 +02:00
break ;
2018-02-08 11:17:41 +01:00
CancelMultiTurnMoves ( gEffectBattler ) ;
2017-09-20 22:54:26 +02:00
statusChanged = TRUE ;
break ;
2018-01-16 22:12:38 +01:00
case STATUS1_POISON :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_IMMUNITY
2017-09-22 21:33:49 +02:00
& & ( primary = = TRUE | | certain = = MOVE_EFFECT_CERTAIN ) )
2017-09-20 22:54:26 +02:00
{
gLastUsedAbility = ABILITY_IMMUNITY ;
2018-02-08 11:17:41 +01:00
RecordAbilityBattle ( gEffectBattler , ABILITY_IMMUNITY ) ;
2017-09-20 22:54:26 +02:00
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_PSNPrevention ;
if ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
{
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_ABILITY_PREVENTS_ABILITY_STATUS ;
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_IGNORE_SAFEGUARD ;
2017-09-20 22:54:26 +02:00
}
else
{
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_ABILITY_PREVENTS_MOVE_STATUS ;
2017-09-20 22:54:26 +02:00
}
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 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_STATUS_HAD_NO_EFFECT ;
2017-09-20 22:54:26 +02:00
RESET_RETURN
}
2018-03-01 00:59:52 +01:00
if ( IS_BATTLER_OF_TYPE ( gEffectBattler , TYPE_POISON ) )
2017-09-20 22:54:26 +02:00
break ;
2018-03-01 00:59:52 +01:00
if ( IS_BATTLER_OF_TYPE ( gEffectBattler , TYPE_STEEL ) )
2017-09-20 22:54:26 +02:00
break ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status1 )
2017-09-20 22:54:26 +02:00
break ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_IMMUNITY )
2017-09-20 22:54:26 +02:00
break ;
statusChanged = TRUE ;
break ;
2018-01-16 22:12:38 +01:00
case STATUS1_BURN :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_WATER_VEIL
2017-09-22 21:33:49 +02:00
& & ( primary = = TRUE | | certain = = MOVE_EFFECT_CERTAIN ) )
2017-09-20 22:54:26 +02:00
{
gLastUsedAbility = ABILITY_WATER_VEIL ;
2018-02-08 11:17:41 +01:00
RecordAbilityBattle ( gEffectBattler , ABILITY_WATER_VEIL ) ;
2017-09-20 22:54:26 +02:00
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_BRNPrevention ;
if ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
{
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_ABILITY_PREVENTS_ABILITY_STATUS ;
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_IGNORE_SAFEGUARD ;
2017-09-20 22:54:26 +02:00
}
else
{
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_ABILITY_PREVENTS_MOVE_STATUS ;
2017-09-20 22:54:26 +02:00
}
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 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_STATUS_HAD_NO_EFFECT ;
2017-09-20 22:54:26 +02:00
RESET_RETURN
}
2018-03-01 00:59:52 +01:00
if ( IS_BATTLER_OF_TYPE ( gEffectBattler , TYPE_FIRE ) )
2017-09-20 22:54:26 +02:00
break ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_WATER_VEIL )
2017-09-20 22:54:26 +02:00
break ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status1 )
2017-09-20 22:54:26 +02:00
break ;
statusChanged = TRUE ;
break ;
2018-01-16 22:12:38 +01:00
case STATUS1_FREEZE :
2021-09-30 12:08:20 +02:00
if ( WEATHER_HAS_EFFECT & & gBattleWeather & B_WEATHER_SUN )
2017-09-20 22:54:26 +02:00
noSunCanFreeze = FALSE ;
2018-03-01 00:59:52 +01:00
if ( IS_BATTLER_OF_TYPE ( gEffectBattler , TYPE_ICE ) )
2017-09-20 22:54:26 +02:00
break ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status1 )
2017-09-20 22:54:26 +02:00
break ;
if ( noSunCanFreeze = = 0 )
break ;
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_MAGMA_ARMOR )
2017-09-20 22:54:26 +02:00
break ;
2018-02-08 11:17:41 +01:00
CancelMultiTurnMoves ( gEffectBattler ) ;
2017-09-20 22:54:26 +02:00
statusChanged = TRUE ;
break ;
2018-01-16 22:12:38 +01:00
case STATUS1_PARALYSIS :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_LIMBER )
2017-09-20 22:54:26 +02:00
{
2017-09-22 21:33:49 +02:00
if ( primary = = TRUE | | certain = = MOVE_EFFECT_CERTAIN )
2017-09-20 22:54:26 +02:00
{
gLastUsedAbility = ABILITY_LIMBER ;
2018-02-08 11:17:41 +01:00
RecordAbilityBattle ( gEffectBattler , ABILITY_LIMBER ) ;
2017-09-20 22:54:26 +02:00
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_PRLZPrevention ;
if ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
{
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_ABILITY_PREVENTS_ABILITY_STATUS ;
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_IGNORE_SAFEGUARD ;
2017-09-20 22:54:26 +02:00
}
else
{
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_ABILITY_PREVENTS_MOVE_STATUS ;
2017-09-20 22:54:26 +02:00
}
RESET_RETURN
}
else
break ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status1 )
2017-09-20 22:54:26 +02:00
break ;
statusChanged = TRUE ;
break ;
2018-01-16 22:12:38 +01:00
case STATUS1_TOXIC_POISON :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_IMMUNITY & & ( primary = = TRUE | | certain = = MOVE_EFFECT_CERTAIN ) )
2017-09-20 22:54:26 +02:00
{
gLastUsedAbility = ABILITY_IMMUNITY ;
2018-02-08 11:17:41 +01:00
RecordAbilityBattle ( gEffectBattler , ABILITY_IMMUNITY ) ;
2017-09-20 22:54:26 +02:00
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_PSNPrevention ;
if ( gHitMarker & HITMARKER_IGNORE_SAFEGUARD )
{
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_ABILITY_PREVENTS_ABILITY_STATUS ;
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_IGNORE_SAFEGUARD ;
2017-09-20 22:54:26 +02:00
}
else
{
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_ABILITY_PREVENTS_MOVE_STATUS ;
2017-09-20 22:54:26 +02:00
}
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 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_STATUS_HAD_NO_EFFECT ;
2017-09-20 22:54:26 +02:00
RESET_RETURN
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status1 )
2017-09-20 22:54:26 +02:00
break ;
2018-03-01 00:59:52 +01:00
if ( ! IS_BATTLER_OF_TYPE ( gEffectBattler , TYPE_POISON ) & & ! IS_BATTLER_OF_TYPE ( gEffectBattler , TYPE_STEEL ) )
2017-09-20 22:54:26 +02:00
{
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_IMMUNITY )
2017-09-20 22:54:26 +02:00
break ;
// It's redundant, because at this point we know the status1 value is 0.
2021-09-24 20:30:15 +02:00
gBattleMons [ gEffectBattler ] . status1 & = ~ STATUS1_TOXIC_POISON ;
gBattleMons [ gEffectBattler ] . status1 & = ~ STATUS1_POISON ;
2017-09-20 22:54:26 +02:00
statusChanged = TRUE ;
break ;
}
else
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_DOESNT_AFFECT_FOE ;
2017-09-20 22:54:26 +02:00
}
break ;
}
if ( statusChanged = = TRUE )
{
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
2018-01-16 22:12:38 +01:00
if ( sStatusFlagsForMoveEffects [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] = = STATUS1_SLEEP )
2020-07-17 02:12:12 +02:00
gBattleMons [ gEffectBattler ] . status1 | = STATUS1_SLEEP_TURN ( ( Random ( ) & 3 ) + 2 ) ; // 2-5 turns
2017-09-20 22:54:26 +02:00
else
2018-02-08 11:17:41 +01:00
gBattleMons [ gEffectBattler ] . status1 | = sStatusFlagsForMoveEffects [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ;
2017-09-20 22:54:26 +02:00
2017-09-28 16:51:24 +02:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ;
2017-09-20 22:54:26 +02:00
2018-02-08 11:17:41 +01:00
gActiveBattler = gEffectBattler ;
2021-10-13 01:50:32 +02:00
BtlController_EmitSetMonData ( BUFFER_A , REQUEST_STATUS_BATTLE , 0 , sizeof ( gBattleMons [ gEffectBattler ] . status1 ) , & 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 )
{
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_STATUSED_BY_ABILITY ;
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_IGNORE_SAFEGUARD ;
2017-09-20 22:54:26 +02:00
}
else
{
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_STATUSED ;
2017-09-20 22:54:26 +02:00
}
// for synchronize
if ( gBattleCommunication [ MOVE_EFFECT_BYTE ] = = MOVE_EFFECT_POISON
| | gBattleCommunication [ MOVE_EFFECT_BYTE ] = = MOVE_EFFECT_TOXIC
| | gBattleCommunication [ MOVE_EFFECT_BYTE ] = = MOVE_EFFECT_PARALYSIS
| | gBattleCommunication [ MOVE_EFFECT_BYTE ] = = MOVE_EFFECT_BURN )
{
u8 * synchronizeEffect = & gBattleStruct - > synchronizeMoveEffect ;
* synchronizeEffect = gBattleCommunication [ MOVE_EFFECT_BYTE ] ;
gHitMarker | = HITMARKER_SYNCHRONISE_EFFECT ;
}
return ;
}
else if ( statusChanged = = FALSE )
{
gBattleCommunication [ MOVE_EFFECT_BYTE ] = 0 ;
gBattlescriptCurrInstr + + ;
return ;
}
2017-09-22 21:33:49 +02:00
return ;
2017-09-20 22:54:26 +02:00
}
else
{
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status2 & sStatusFlagsForMoveEffects [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
u8 side ;
2017-09-22 21:33:49 +02:00
switch ( gBattleCommunication [ MOVE_EFFECT_BYTE ] )
2017-09-20 22:54:26 +02:00
{
case MOVE_EFFECT_CONFUSION :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_OWN_TEMPO
| | gBattleMons [ gEffectBattler ] . status2 & STATUS2_CONFUSION )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2020-07-17 02:12:12 +02:00
gBattleMons [ gEffectBattler ] . status2 | = STATUS2_CONFUSION_TURN ( ( ( Random ( ) ) % 4 ) + 2 ) ; // 2-5 turns
2017-09-20 22:54:26 +02:00
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 16:51:24 +02:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ;
2017-09-20 22:54:26 +02:00
}
break ;
case MOVE_EFFECT_FLINCH :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_INNER_FOCUS )
2017-09-20 22:54:26 +02:00
{
2017-09-22 21:33:49 +02:00
if ( primary = = TRUE | | certain = = MOVE_EFFECT_CERTAIN )
2017-09-20 22:54:26 +02:00
{
gLastUsedAbility = ABILITY_INNER_FOCUS ;
2018-02-08 11:17:41 +01:00
RecordAbilityBattle ( gEffectBattler , ABILITY_INNER_FOCUS ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_FlinchPrevention ;
}
else
{
gBattlescriptCurrInstr + + ;
}
}
else
{
2018-02-08 11:17:41 +01:00
if ( GetBattlerTurnOrderNum ( gEffectBattler ) > gCurrentTurnActionNumber )
gBattleMons [ gEffectBattler ] . status2 | = sStatusFlagsForMoveEffects [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr + + ;
2017-09-20 22:54:26 +02:00
}
break ;
case MOVE_EFFECT_UPROAR :
2018-02-08 11:17:41 +01:00
if ( ! ( gBattleMons [ gEffectBattler ] . status2 & STATUS2_UPROAR ) )
2017-09-20 22:54:26 +02:00
{
2017-09-22 21:33:49 +02:00
2018-02-08 11:17:41 +01:00
gBattleMons [ gEffectBattler ] . status2 | = STATUS2_MULTIPLETURNS ;
gLockedMoves [ gEffectBattler ] = gCurrentMove ;
2020-07-17 02:12:12 +02:00
gBattleMons [ gEffectBattler ] . status2 | = STATUS2_UPROAR_TURN ( ( Random ( ) & 3 ) + 2 ) ; // 2-5 turns
2017-09-20 22:54:26 +02:00
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 16:51:24 +02:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ;
2017-09-20 22:54:26 +02:00
}
2017-09-22 21:33:49 +02:00
else
{
gBattlescriptCurrInstr + + ;
}
2017-09-20 22:54:26 +02:00
break ;
case MOVE_EFFECT_PAYDAY :
2018-02-06 23:09:39 +01:00
if ( GET_BATTLER_SIDE ( gBattlerAttacker ) = = B_SIDE_PLAYER )
2017-09-20 22:54:26 +02:00
{
u16 PayDay = gPaydayMoney ;
2018-02-06 23:09:39 +01:00
gPaydayMoney + = ( gBattleMons [ gBattlerAttacker ] . level * 5 ) ;
2017-09-20 22:54:26 +02:00
if ( PayDay > gPaydayMoney )
2018-12-05 15:31:01 +01:00
gPaydayMoney = 0xFFFF ;
2017-09-20 22:54:26 +02:00
}
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 16:51:24 +02:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ;
2017-09-20 22:54:26 +02:00
break ;
case MOVE_EFFECT_TRI_ATTACK :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status1 )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
gBattleCommunication [ MOVE_EFFECT_BYTE ] = Random ( ) % 3 + 3 ;
SetMoveEffect ( FALSE , 0 ) ;
}
break ;
case MOVE_EFFECT_CHARGING :
2018-02-08 11:17:41 +01:00
gBattleMons [ gEffectBattler ] . status2 | = STATUS2_MULTIPLETURNS ;
gLockedMoves [ gEffectBattler ] = gCurrentMove ;
gProtectStructs [ gEffectBattler ] . chargingTurn = 1 ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr + + ;
break ;
case MOVE_EFFECT_WRAP :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status2 & STATUS2_WRAPPED )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2020-07-17 02:12:12 +02:00
gBattleMons [ gEffectBattler ] . status2 | = STATUS2_WRAPPED_TURN ( ( Random ( ) & 3 ) + 3 ) ; // 3-6 turns
2017-09-20 22:54:26 +02:00
2018-02-08 11:17:41 +01:00
* ( gBattleStruct - > wrappedMove + gEffectBattler * 2 + 0 ) = gCurrentMove ;
* ( gBattleStruct - > wrappedMove + gEffectBattler * 2 + 1 ) = gCurrentMove > > 8 ;
* ( gBattleStruct - > wrappedBy + gEffectBattler ) = gBattlerAttacker ;
2017-09-20 22:54:26 +02:00
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 16:51:24 +02:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ;
2017-09-20 22:54:26 +02:00
2017-09-22 21:33:49 +02:00
for ( gBattleCommunication [ MULTISTRING_CHOOSER ] = 0 ; ; gBattleCommunication [ MULTISTRING_CHOOSER ] + + )
2017-09-20 22:54:26 +02:00
{
2017-09-22 21:33:49 +02:00
if ( gBattleCommunication [ MULTISTRING_CHOOSER ] > 4 )
break ;
if ( gTrappingMoves [ gBattleCommunication [ MULTISTRING_CHOOSER ] ] = = gCurrentMove )
2017-09-20 22:54:26 +02:00
break ;
}
}
break ;
case MOVE_EFFECT_RECOIL_25 : // 25% recoil
gBattleMoveDamage = ( gHpDealt ) / 4 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 16:51:24 +02:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ;
2017-09-20 22:54:26 +02:00
break ;
2017-09-22 21:33:49 +02:00
case MOVE_EFFECT_ATK_PLUS_1 :
case MOVE_EFFECT_DEF_PLUS_1 :
case MOVE_EFFECT_SPD_PLUS_1 :
case MOVE_EFFECT_SP_ATK_PLUS_1 :
case MOVE_EFFECT_SP_DEF_PLUS_1 :
case MOVE_EFFECT_ACC_PLUS_1 :
case MOVE_EFFECT_EVS_PLUS_1 :
if ( ChangeStatBuffs ( SET_STAT_BUFF_VALUE ( 1 ) ,
gBattleCommunication [ MOVE_EFFECT_BYTE ] - MOVE_EFFECT_ATK_PLUS_1 + 1 ,
affectsUser , 0 ) )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2017-09-22 21:33:49 +02:00
gBattleScripting . animArg1 = gBattleCommunication [ MOVE_EFFECT_BYTE ] & ~ ( MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN ) ;
2017-09-20 22:54:26 +02:00
gBattleScripting . animArg2 = 0 ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_StatUp ;
}
break ;
2017-09-22 21:33:49 +02:00
case MOVE_EFFECT_ATK_MINUS_1 :
case MOVE_EFFECT_DEF_MINUS_1 :
case MOVE_EFFECT_SPD_MINUS_1 :
case MOVE_EFFECT_SP_ATK_MINUS_1 :
case MOVE_EFFECT_SP_DEF_MINUS_1 :
case MOVE_EFFECT_ACC_MINUS_1 :
case MOVE_EFFECT_EVS_MINUS_1 :
if ( ChangeStatBuffs ( SET_STAT_BUFF_VALUE ( 1 ) | STAT_BUFF_NEGATIVE ,
gBattleCommunication [ MOVE_EFFECT_BYTE ] - MOVE_EFFECT_ATK_MINUS_1 + 1 ,
affectsUser , 0 ) )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2017-09-22 21:33:49 +02:00
gBattleScripting . animArg1 = gBattleCommunication [ MOVE_EFFECT_BYTE ] & ~ ( MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN ) ;
2017-09-20 22:54:26 +02:00
gBattleScripting . animArg2 = 0 ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_StatDown ;
}
break ;
2017-09-22 21:33:49 +02:00
case MOVE_EFFECT_ATK_PLUS_2 :
case MOVE_EFFECT_DEF_PLUS_2 :
case MOVE_EFFECT_SPD_PLUS_2 :
case MOVE_EFFECT_SP_ATK_PLUS_2 :
case MOVE_EFFECT_SP_DEF_PLUS_2 :
case MOVE_EFFECT_ACC_PLUS_2 :
case MOVE_EFFECT_EVS_PLUS_2 :
if ( ChangeStatBuffs ( SET_STAT_BUFF_VALUE ( 2 ) ,
gBattleCommunication [ MOVE_EFFECT_BYTE ] - MOVE_EFFECT_ATK_PLUS_2 + 1 ,
affectsUser , 0 ) )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2017-09-22 21:33:49 +02:00
gBattleScripting . animArg1 = gBattleCommunication [ MOVE_EFFECT_BYTE ] & ~ ( MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN ) ;
2017-09-20 22:54:26 +02:00
gBattleScripting . animArg2 = 0 ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_StatUp ;
}
break ;
2017-09-22 21:33:49 +02:00
case MOVE_EFFECT_ATK_MINUS_2 :
case MOVE_EFFECT_DEF_MINUS_2 :
case MOVE_EFFECT_SPD_MINUS_2 :
case MOVE_EFFECT_SP_ATK_MINUS_2 :
case MOVE_EFFECT_SP_DEF_MINUS_2 :
case MOVE_EFFECT_ACC_MINUS_2 :
case MOVE_EFFECT_EVS_MINUS_2 :
if ( ChangeStatBuffs ( SET_STAT_BUFF_VALUE ( 2 ) | STAT_BUFF_NEGATIVE ,
gBattleCommunication [ MOVE_EFFECT_BYTE ] - MOVE_EFFECT_ATK_MINUS_2 + 1 ,
affectsUser , 0 ) )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2017-09-22 21:33:49 +02:00
gBattleScripting . animArg1 = gBattleCommunication [ MOVE_EFFECT_BYTE ] & ~ ( MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN ) ;
2017-09-20 22:54:26 +02:00
gBattleScripting . animArg2 = 0 ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_StatDown ;
}
break ;
case MOVE_EFFECT_RECHARGE :
2018-02-08 11:17:41 +01:00
gBattleMons [ gEffectBattler ] . status2 | = STATUS2_RECHARGE ;
2018-10-14 18:10:54 +02:00
gDisableStructs [ gEffectBattler ] . rechargeTimer = 2 ;
2018-02-08 11:17:41 +01:00
gLockedMoves [ gEffectBattler ] = gCurrentMove ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr + + ;
break ;
case MOVE_EFFECT_RAGE :
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 | = STATUS2_RAGE ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr + + ;
break ;
case MOVE_EFFECT_STEAL_ITEM :
{
2018-09-20 22:00:00 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_TRAINER_HILL )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
break ;
}
2018-02-06 23:09:39 +01:00
side = GetBattlerSide ( gBattlerAttacker ) ;
if ( GetBattlerSide ( gBattlerAttacker ) = = B_SIDE_OPPONENT
2017-09-20 22:54:26 +02:00
& & ! ( gBattleTypeFlags &
( BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_FRONTIER
| BATTLE_TYPE_LINK
2021-01-13 21:17:32 +01:00
| BATTLE_TYPE_RECORDED_LINK
2017-09-20 22:54:26 +02:00
| 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
2021-01-13 21:17:32 +01:00
| BATTLE_TYPE_RECORDED_LINK
2017-09-20 22:54:26 +02:00
| 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
2021-12-10 18:41:54 +01:00
| | gBattleMons [ gBattlerTarget ] . item = = ITEM_ENIGMA_BERRY_E_READER
2018-02-06 23:09:39 +01:00
| | IS_ITEM_MAIL ( gBattleMons [ gBattlerTarget ] . item )
| | gBattleMons [ gBattlerTarget ] . item = = 0 )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
2017-09-22 21:33:49 +02:00
else
2017-09-20 22:54:26 +02:00
{
2018-02-06 23:09:39 +01:00
u16 * changedItem = & gBattleStruct - > changedItems [ gBattlerAttacker ] ;
gLastUsedItem = * changedItem = gBattleMons [ gBattlerTarget ] . item ;
gBattleMons [ gBattlerTarget ] . item = 0 ;
2017-09-20 22:54:26 +02:00
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2021-10-13 01:50:32 +02:00
BtlController_EmitSetMonData ( BUFFER_A , REQUEST_HELDITEM_BATTLE , 0 , sizeof ( gLastUsedItem ) , & 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 ;
2021-10-13 01:50:32 +02:00
BtlController_EmitSetMonData ( BUFFER_A , REQUEST_HELDITEM_BATTLE , 0 , sizeof ( gBattleMons [ gBattlerTarget ] . item ) , & gBattleMons [ gBattlerTarget ] . item ) ;
2018-02-06 23:09:39 +01:00
MarkBattlerForControllerExec ( gBattlerTarget ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
gBattlescriptCurrInstr = BattleScript_ItemSteal ;
2018-02-06 23:09:39 +01:00
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gBattlerTarget ] ) + 0 ) = 0 ;
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gBattlerTarget ] ) + 1 ) = 0 ;
2017-09-22 21:33:49 +02:00
}
2017-09-20 22:54:26 +02:00
}
break ;
case MOVE_EFFECT_PREVENT_ESCAPE :
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerTarget ] . status2 | = STATUS2_ESCAPE_PREVENTION ;
gDisableStructs [ gBattlerTarget ] . battlerPreventingEscape = gBattlerAttacker ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr + + ;
break ;
case MOVE_EFFECT_NIGHTMARE :
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerTarget ] . status2 | = STATUS2_NIGHTMARE ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr + + ;
break ;
case MOVE_EFFECT_ALL_STATS_UP :
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_AllStatsUp ;
break ;
case MOVE_EFFECT_RAPIDSPIN :
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_RapidSpinAway ;
break ;
case MOVE_EFFECT_REMOVE_PARALYSIS : // Smelling salts
2018-02-06 23:09:39 +01:00
if ( ! ( gBattleMons [ gBattlerTarget ] . status1 & STATUS1_PARALYSIS ) )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2021-09-24 20:30:15 +02:00
gBattleMons [ gBattlerTarget ] . status1 & = ~ STATUS1_PARALYSIS ;
2017-09-20 22:54:26 +02:00
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget ;
2021-10-13 01:50:32 +02:00
BtlController_EmitSetMonData ( BUFFER_A , REQUEST_STATUS_BATTLE , 0 , sizeof ( gBattleMons [ gActiveBattler ] . status1 ) , & gBattleMons [ gActiveBattler ] . status1 ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-20 22:54:26 +02:00
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_TargetPRLZHeal ;
}
break ;
case MOVE_EFFECT_ATK_DEF_DOWN : // SuperPower
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_AtkDefDown ;
break ;
2018-09-01 20:00:13 +02:00
case MOVE_EFFECT_RECOIL_33 : // Double Edge
2017-09-20 22:54:26 +02:00
gBattleMoveDamage = gHpDealt / 3 ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 16:51:24 +02:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ;
2017-09-20 22:54:26 +02:00
break ;
case MOVE_EFFECT_THRASH :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . status2 & STATUS2_LOCK_CONFUSE )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
2018-02-08 11:17:41 +01:00
gBattleMons [ gEffectBattler ] . status2 | = STATUS2_MULTIPLETURNS ;
gLockedMoves [ gEffectBattler ] = gCurrentMove ;
2020-07-17 02:12:12 +02:00
gBattleMons [ gEffectBattler ] . status2 | = STATUS2_LOCK_CONFUSE_TURN ( ( Random ( ) & 1 ) + 2 ) ; // thrash for 2-3 turns
2017-09-20 22:54:26 +02:00
}
break ;
case MOVE_EFFECT_KNOCK_OFF :
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . ability = = ABILITY_STICKY_HOLD )
2017-09-20 22:54:26 +02:00
{
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . item = = 0 )
2017-09-20 22:54:26 +02:00
{
gBattlescriptCurrInstr + + ;
}
else
{
gLastUsedAbility = ABILITY_STICKY_HOLD ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr = BattleScript_StickyHoldActivates ;
2018-02-08 11:17:41 +01:00
RecordAbilityBattle ( gEffectBattler , ABILITY_STICKY_HOLD ) ;
2017-09-20 22:54:26 +02:00
}
break ;
}
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ gEffectBattler ] . item )
2017-09-20 22:54:26 +02:00
{
2018-02-08 11:17:41 +01:00
side = GetBattlerSide ( gEffectBattler ) ;
2017-09-20 22:54:26 +02:00
2018-02-08 11:17:41 +01:00
gLastUsedItem = gBattleMons [ gEffectBattler ] . item ;
gBattleMons [ gEffectBattler ] . item = 0 ;
2018-10-14 18:37:52 +02:00
gWishFutureKnock . knockedOffMons [ side ] | = gBitTable [ gBattlerPartyIndexes [ gEffectBattler ] ] ;
2017-09-20 22:54:26 +02:00
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_KnockedOff ;
2018-02-08 11:17:41 +01:00
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gEffectBattler ] ) + 0 ) = 0 ;
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gEffectBattler ] ) + 1 ) = 0 ;
2017-09-20 22:54:26 +02:00
}
2017-09-22 21:33:49 +02:00
else
{
gBattlescriptCurrInstr + + ;
}
2017-09-20 22:54:26 +02:00
break ;
case MOVE_EFFECT_SP_ATK_TWO_DOWN : // Overheat
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 1 ) ;
2017-09-20 22:54:26 +02:00
gBattlescriptCurrInstr = BattleScript_SAtkDown2 ;
break ;
}
}
}
gBattleCommunication [ MOVE_EFFECT_BYTE ] = 0 ;
}
2017-09-22 21:33:49 +02:00
2019-08-23 13:55:36 +02:00
static void Cmd_seteffectwithchance ( void )
2017-09-22 21:33:49 +02:00
{
u32 percentChance ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . ability = = ABILITY_SERENE_GRACE )
2017-09-22 21:33:49 +02:00
percentChance = gBattleMoves [ gCurrentMove ] . secondaryEffectChance * 2 ;
else
percentChance = gBattleMoves [ gCurrentMove ] . secondaryEffectChance ;
if ( gBattleCommunication [ MOVE_EFFECT_BYTE ] & MOVE_EFFECT_CERTAIN
2018-01-16 22:12:38 +01:00
& & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
2017-09-22 21:33:49 +02:00
{
2021-09-24 20:30:15 +02:00
gBattleCommunication [ MOVE_EFFECT_BYTE ] & = ~ MOVE_EFFECT_CERTAIN ;
2020-03-07 23:36:09 +01:00
SetMoveEffect ( FALSE , MOVE_EFFECT_CERTAIN ) ;
2017-09-22 21:33:49 +02:00
}
else if ( Random ( ) % 100 < percentChance
& & gBattleCommunication [ MOVE_EFFECT_BYTE ]
2018-01-16 22:12:38 +01:00
& & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
2017-09-22 21:33:49 +02:00
{
if ( percentChance > = 100 )
2020-03-07 23:36:09 +01:00
SetMoveEffect ( FALSE , MOVE_EFFECT_CERTAIN ) ;
2017-09-22 21:33:49 +02:00
else
2020-03-07 23:36:09 +01:00
SetMoveEffect ( FALSE , 0 ) ;
2017-09-22 21:33:49 +02:00
}
else
{
gBattlescriptCurrInstr + + ;
}
gBattleCommunication [ MOVE_EFFECT_BYTE ] = 0 ;
2017-12-02 23:31:58 +01:00
gBattleScripting . multihitMoveEffect = 0 ;
2017-09-22 21:33:49 +02:00
}
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
2020-07-17 02:12:12 +02:00
if ( gBattleCommunication [ MOVE_EFFECT_BYTE ] < = PRIMARY_STATUS_MOVE_EFFECT )
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . status1 & = ( ~ sStatusFlagsForMoveEffects [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ) ;
2017-09-22 21:33:49 +02:00
else
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . status2 & = ( ~ sStatusFlagsForMoveEffects [ gBattleCommunication [ MOVE_EFFECT_BYTE ] ] ) ;
2017-09-22 21:33:49 +02:00
gBattleCommunication [ MOVE_EFFECT_BYTE ] = 0 ;
gBattlescriptCurrInstr + = 2 ;
2017-12-02 23:31:58 +01:00
gBattleScripting . multihitMoveEffect = 0 ;
2017-09-22 21:33:49 +02:00
}
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 ;
2021-09-24 20:30:15 +02:00
gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] & = ~ SIDE_STATUS_SPIKES_DAMAGED ;
2017-09-22 21:33:49 +02:00
}
else
{
gBattlescriptCurrInstr + = 7 ;
}
}
else
{
2018-02-08 12:13:29 +01:00
u8 battlerId ;
2017-09-22 21:33:49 +02:00
2018-02-08 11:17:41 +01:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_ATTACKER )
2017-09-22 21:33:49 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2018-02-08 12:13:29 +01:00
battlerId = gBattlerTarget ;
2017-09-22 21:33:49 +02:00
BS_ptr = BattleScript_FaintAttacker ;
}
else
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget ;
2018-02-08 12:13:29 +01:00
battlerId = gBattlerAttacker ;
2017-09-22 21:33:49 +02:00
BS_ptr = BattleScript_FaintTarget ;
}
2018-02-06 02:46:59 +01:00
if ( ! ( gAbsentBattlerFlags & gBitTable [ gActiveBattler ] )
& & gBattleMons [ gActiveBattler ] . hp = = 0 )
2017-09-22 21:33:49 +02:00
{
2018-02-06 02:46:59 +01:00
gHitMarker | = HITMARKER_FAINTED ( gActiveBattler ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPush ( gBattlescriptCurrInstr + 7 ) ;
gBattlescriptCurrInstr = BS_ptr ;
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_PLAYER )
2017-09-22 21:33:49 +02:00
{
2021-09-24 20:30:15 +02:00
gHitMarker | = HITMARKER_PLAYER_FAINTED ;
2021-10-08 22:50:52 +02:00
if ( gBattleResults . playerFaintCounter < 255 )
2017-09-22 21:33:49 +02:00
gBattleResults . playerFaintCounter + + ;
2018-02-06 02:46:59 +01:00
AdjustFriendshipOnBattleFaint ( gActiveBattler ) ;
2017-09-22 21:33:49 +02:00
}
else
{
2021-10-08 22:50:52 +02:00
if ( gBattleResults . opponentFaintCounter < 255 )
2017-09-22 21:33:49 +02:00
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
{
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_DESTINYBOND ;
2017-09-22 21:33:49 +02:00
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 ;
2021-10-13 01:50:32 +02:00
BtlController_EmitSetMonData ( BUFFER_A , moveIndex + REQUEST_PPMOVE1_BATTLE , 0 , sizeof ( gBattleMons [ gActiveBattler ] . pp [ moveIndex ] ) , & gBattleMons [ gActiveBattler ] . pp [ moveIndex ] ) ;
2018-02-06 20:48:02 +01:00
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 ] ) ;
2021-10-13 01:50:32 +02:00
BtlController_EmitFaintAnimation ( BUFFER_A ) ;
2018-02-06 20:48:02 +01:00
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 ;
2021-10-13 01:50:32 +02:00
BtlController_EmitSetMonData ( BUFFER_A , REQUEST_STATUS_BATTLE , 0 , sizeof ( gBattleMons [ gActiveBattler ] . status1 ) , & gBattleMons [ gActiveBattler ] . status1 ) ;
2018-02-06 20:48:02 +01:00
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
{
2018-02-08 12:13:29 +01:00
u8 battlerId ;
2017-09-28 15:34:21 +02:00
u8 ability = gBattlescriptCurrInstr [ 2 ] ;
2018-03-01 00:59:52 +01:00
const u8 * jumpPtr = T2_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
2017-09-22 21:33:49 +02:00
2018-02-08 11:17:41 +01:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_ATTACKER_SIDE )
2017-09-22 21:33:49 +02:00
{
2018-07-01 11:15:42 +02:00
battlerId = AbilityBattleEffects ( ABILITYEFFECT_CHECK_BATTLER_SIDE , gBattlerAttacker , ability , 0 , 0 ) ;
2018-02-08 12:13:29 +01:00
if ( battlerId )
2017-09-22 21:33:49 +02:00
{
gLastUsedAbility = ability ;
gBattlescriptCurrInstr = jumpPtr ;
2018-02-08 12:13:29 +01:00
RecordAbilityBattle ( battlerId - 1 , gLastUsedAbility ) ;
gBattleScripting . battlerWithAbility = battlerId - 1 ;
2017-09-22 21:33:49 +02:00
}
else
gBattlescriptCurrInstr + = 7 ;
}
2018-02-08 11:17:41 +01:00
else if ( gBattlescriptCurrInstr [ 1 ] = = BS_NOT_ATTACKER_SIDE )
2017-09-22 21:33:49 +02:00
{
2018-02-08 12:13:29 +01:00
battlerId = AbilityBattleEffects ( ABILITYEFFECT_CHECK_OTHER_SIDE , gBattlerAttacker , ability , 0 , 0 ) ;
if ( battlerId )
2017-09-22 21:33:49 +02:00
{
gLastUsedAbility = ability ;
gBattlescriptCurrInstr = jumpPtr ;
2018-02-08 12:13:29 +01:00
RecordAbilityBattle ( battlerId - 1 , gLastUsedAbility ) ;
gBattleScripting . battlerWithAbility = battlerId - 1 ;
2017-09-22 21:33:49 +02:00
}
else
gBattlescriptCurrInstr + = 7 ;
}
else
{
2018-02-08 12:13:29 +01:00
battlerId = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
if ( gBattleMons [ battlerId ] . ability = = ability )
2017-09-22 21:33:49 +02:00
{
gLastUsedAbility = ability ;
gBattlescriptCurrInstr = jumpPtr ;
2018-02-08 12:13:29 +01:00
RecordAbilityBattle ( battlerId , gLastUsedAbility ) ;
gBattleScripting . battlerWithAbility = battlerId ;
2017-09-22 21:33:49 +02:00
}
else
gBattlescriptCurrInstr + = 7 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_jumpifsideaffecting ( void )
2017-09-22 21:33:49 +02:00
{
u8 side ;
u16 flags ;
const u8 * jumpPtr ;
2018-02-08 11:17:41 +01:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_ATTACKER )
2018-02-06 23:09:39 +01:00
side = GET_BATTLER_SIDE ( gBattlerAttacker ) ;
2017-09-22 21:33:49 +02:00
else
2018-02-06 23:09:39 +01:00
side = GET_BATTLER_SIDE ( gBattlerTarget ) ;
2017-09-22 21:33:49 +02:00
2018-03-01 00:59:52 +01:00
flags = T2_READ_16 ( gBattlescriptCurrInstr + 2 ) ;
jumpPtr = T2_READ_PTR ( gBattlescriptCurrInstr + 4 ) ;
2017-09-22 21:33:49 +02:00
2018-01-16 22:12:38 +01:00
if ( gSideStatuses [ side ] & flags )
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr = jumpPtr ;
else
gBattlescriptCurrInstr + = 8 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_jumpifstat ( void )
2017-09-22 21:33:49 +02:00
{
u8 ret = 0 ;
2018-02-08 12:13:29 +01:00
u8 battlerId = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
u8 value = gBattleMons [ battlerId ] . statStages [ gBattlescriptCurrInstr [ 3 ] ] ;
2017-09-22 21:33:49 +02:00
2017-09-28 15:34:21 +02:00
switch ( gBattlescriptCurrInstr [ 2 ] )
2017-09-22 21:33:49 +02:00
{
case CMP_EQUAL :
2017-09-28 15:34:21 +02:00
if ( value = = gBattlescriptCurrInstr [ 4 ] )
2017-09-22 21:33:49 +02:00
ret + + ;
break ;
case CMP_NOT_EQUAL :
2017-09-28 15:34:21 +02:00
if ( value ! = gBattlescriptCurrInstr [ 4 ] )
2017-09-22 21:33:49 +02:00
ret + + ;
break ;
case CMP_GREATER_THAN :
2017-09-28 15:34:21 +02:00
if ( value > gBattlescriptCurrInstr [ 4 ] )
2017-09-22 21:33:49 +02:00
ret + + ;
break ;
case CMP_LESS_THAN :
2017-09-28 15:34:21 +02:00
if ( value < gBattlescriptCurrInstr [ 4 ] )
2017-09-22 21:33:49 +02:00
ret + + ;
break ;
case CMP_COMMON_BITS :
2017-09-28 15:34:21 +02:00
if ( value & gBattlescriptCurrInstr [ 4 ] )
2017-09-22 21:33:49 +02:00
ret + + ;
break ;
case CMP_NO_COMMON_BITS :
2017-09-28 15:34:21 +02:00
if ( ! ( value & gBattlescriptCurrInstr [ 4 ] ) )
2017-09-22 21:33:49 +02:00
ret + + ;
break ;
}
if ( ret )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T2_READ_PTR ( gBattlescriptCurrInstr + 5 ) ;
2017-09-22 21:33:49 +02:00
else
gBattlescriptCurrInstr + = 9 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_jumpifstatus3condition ( void )
2017-09-22 21:33:49 +02:00
{
2021-10-13 22:39:21 +02:00
u32 status ;
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 ] ) ;
2021-10-13 22:39:21 +02:00
status = T2_READ_32 ( gBattlescriptCurrInstr + 2 ) ;
2018-03-01 00:59:52 +01:00
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
{
2021-10-13 22:39:21 +02:00
if ( ( gStatuses3 [ gActiveBattler ] & status ) ! = 0 )
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr + = 11 ;
else
gBattlescriptCurrInstr = jumpPtr ;
}
else
{
2021-10-13 22:39:21 +02:00
if ( ( gStatuses3 [ gActiveBattler ] & status ) ! = 0 )
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr = jumpPtr ;
else
gBattlescriptCurrInstr + = 11 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_jumpiftype ( void )
2017-09-22 21:33:49 +02:00
{
2018-02-08 12:13:29 +01:00
u8 battlerId = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-28 15:34:21 +02:00
u8 type = gBattlescriptCurrInstr [ 2 ] ;
2018-03-01 00:59:52 +01:00
const u8 * jumpPtr = T2_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
2017-09-22 21:33:49 +02:00
2018-03-01 00:59:52 +01:00
if ( IS_BATTLER_OF_TYPE ( battlerId , type ) )
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr = jumpPtr ;
else
gBattlescriptCurrInstr + = 7 ;
}
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
2021-01-13 21:17:32 +01:00
| BATTLE_TYPE_RECORDED_LINK
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 ) ;
2021-12-10 18:41:54 +01:00
if ( item = = ITEM_ENIGMA_BERRY_E_READER )
2017-09-22 21:33:49 +02:00
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
{
2021-07-01 06:18:52 +02:00
* exp = SAFE_DIV ( calculatedExp / 2 , viaSentIn ) ;
2017-09-22 21:33:49 +02:00
if ( * exp = = 0 )
* exp = 1 ;
gExpShareExp = calculatedExp / 2 / viaExpShare ;
if ( gExpShareExp = = 0 )
gExpShareExp = 1 ;
}
else
{
2021-07-01 06:18:52 +02:00
* exp = SAFE_DIV ( calculatedExp , viaSentIn ) ;
2017-09-22 21:33:49 +02:00
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
2021-12-10 18:41:54 +01:00
if ( item = = ITEM_ENIGMA_BERRY_E_READER )
2017-09-22 21:33:49 +02:00
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
{
// music change in wild battle after fainting a poke
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_TRAINER ) & & gBattleMons [ 0 ] . hp & & ! gBattleStruct - > wildVictorySong )
{
2017-11-04 16:11:13 +01:00
BattleStopLowHpSound ( ) ;
2020-08-21 00:02:00 +02:00
PlayBGM ( MUS_VICTORY_WILD ) ;
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 )
{
2021-05-23 16:35:03 +02:00
if ( gBattlerPartyIndexes [ 2 ] = = gBattleStruct - > expGetterMonId & & ! ( gAbsentBattlerFlags & gBitTable [ 2 ] ) )
2018-02-07 22:53:40 +01:00
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
{
2018-02-07 22:53:40 +01:00
gBattleBufferB [ gBattleStruct - > expGetterBattlerId ] [ 0 ] = 0 ;
2018-10-17 04:47:08 +02:00
if ( GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_HP ) & & GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_LEVEL ) ! = MAX_LEVEL )
2017-09-22 21:33:49 +02:00
{
2019-04-04 21:24:21 +02:00
gBattleResources - > beforeLvlUp - > stats [ STAT_HP ] = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_MAX_HP ) ;
gBattleResources - > beforeLvlUp - > stats [ STAT_ATK ] = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_ATK ) ;
gBattleResources - > beforeLvlUp - > stats [ STAT_DEF ] = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_DEF ) ;
gBattleResources - > beforeLvlUp - > stats [ STAT_SPEED ] = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPEED ) ;
gBattleResources - > beforeLvlUp - > stats [ STAT_SPATK ] = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPATK ) ;
gBattleResources - > beforeLvlUp - > stats [ STAT_SPDEF ] = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPDEF ) ;
2017-09-22 21:33:49 +02:00
2018-02-07 22:53:40 +01:00
gActiveBattler = gBattleStruct - > expGetterBattlerId ;
2021-10-13 01:50:32 +02:00
BtlController_EmitExpUpdate ( BUFFER_A , 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 ;
2018-07-16 20:47:30 +02:00
if ( gBattleBufferB [ gActiveBattler ] [ 0 ] = = CONTROLLER_TWORETURNVALUES & & gBattleBufferB [ gActiveBattler ] [ 1 ] = = RET_VALUE_LEVELED_UP )
2017-09-22 21:33:49 +02:00
{
2018-02-07 22:53:40 +01:00
if ( gBattleTypeFlags & BATTLE_TYPE_TRAINER & & gBattlerPartyIndexes [ gActiveBattler ] = = gBattleStruct - > expGetterMonId )
2018-02-06 20:48:02 +01:00
HandleLowHpMusicChange ( & gPlayerParty [ gBattlerPartyIndexes [ gActiveBattler ] ] , gActiveBattler ) ;
2017-09-22 21:33:49 +02:00
2019-04-04 21:24:21 +02:00
PREPARE_MON_NICK_WITH_PREFIX_BUFFER ( gBattleTextBuff1 , gActiveBattler , gBattleStruct - > expGetterMonId ) ;
PREPARE_BYTE_NUMBER_BUFFER ( gBattleTextBuff2 , 3 , GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_LEVEL ) ) ;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor ( ) ;
2018-02-07 22:53:40 +01:00
gLeveledUpInBattle | = gBitTable [ gBattleStruct - > expGetterMonId ] ;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr = BattleScript_LevelUp ;
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = ( gBattleBufferB [ gActiveBattler ] [ 2 ] | ( gBattleBufferB [ gActiveBattler ] [ 3 ] < < 8 ) ) ;
2020-02-02 19:28:54 +01:00
AdjustFriendship ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , FRIENDSHIP_EVENT_GROW_LEVEL ) ;
2017-09-22 21:33:49 +02:00
// update battle mon structure after level up
2018-02-07 22:53:40 +01:00
if ( gBattlerPartyIndexes [ 0 ] = = gBattleStruct - > expGetterMonId & & gBattleMons [ 0 ] . hp )
2017-09-22 21:33:49 +02:00
{
2018-02-07 22:53:40 +01:00
gBattleMons [ 0 ] . level = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_LEVEL ) ;
gBattleMons [ 0 ] . hp = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_HP ) ;
gBattleMons [ 0 ] . maxHP = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_MAX_HP ) ;
gBattleMons [ 0 ] . attack = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_ATK ) ;
gBattleMons [ 0 ] . defense = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_DEF ) ;
2021-05-23 16:35:03 +02:00
// Speed is duplicated, likely due to a copy-paste error.
2018-02-07 22:53:40 +01:00
gBattleMons [ 0 ] . speed = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPEED ) ;
gBattleMons [ 0 ] . speed = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPEED ) ;
gBattleMons [ 0 ] . spAttack = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPATK ) ;
gBattleMons [ 0 ] . spDefense = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPDEF ) ;
2017-09-22 21:33:49 +02:00
}
2021-05-23 16:35:03 +02:00
2018-02-07 22:53:40 +01:00
if ( gBattlerPartyIndexes [ 2 ] = = gBattleStruct - > expGetterMonId & & gBattleMons [ 2 ] . hp & & ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE ) )
2017-09-22 21:33:49 +02:00
{
2018-02-07 22:53:40 +01:00
gBattleMons [ 2 ] . level = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_LEVEL ) ;
gBattleMons [ 2 ] . hp = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_HP ) ;
gBattleMons [ 2 ] . maxHP = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_MAX_HP ) ;
gBattleMons [ 2 ] . attack = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_ATK ) ;
gBattleMons [ 2 ] . defense = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_DEF ) ;
gBattleMons [ 2 ] . speed = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPEED ) ;
2021-05-23 16:35:03 +02:00
// Speed is duplicated again, but Special Defense is missing.
# ifdef BUGFIX
gBattleMons [ 2 ] . spDefense = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPDEF ) ;
# else
2018-02-07 22:53:40 +01:00
gBattleMons [ 2 ] . speed = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPEED ) ;
2021-05-23 16:35:03 +02:00
# endif
2018-02-07 22:53:40 +01:00
gBattleMons [ 2 ] . spAttack = GetMonData ( & gPlayerParty [ gBattleStruct - > expGetterMonId ] , MON_DATA_SPATK ) ;
2017-09-22 21:33:49 +02:00
}
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 + + ;
2020-07-17 02:12:12 +02:00
if ( gBattleStruct - > expGetterMonId < PARTY_SIZE )
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 ;
}
}
2021-10-04 16:21:03 +02:00
// For battles that aren't BATTLE_TYPE_LINK or BATTLE_TYPE_RECORDED_LINK, the only thing this
2021-10-13 01:50:32 +02:00
// command does is check whether the player has won/lost by totaling each team's HP. It then
// sets gBattleOutcome accordingly, if necessary.
static void Cmd_checkteamslost ( void )
2017-09-22 21:33:49 +02:00
{
u16 HP_count = 0 ;
s32 i ;
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-09-22 21:33:49 +02:00
return ;
2021-10-04 16:21:03 +02:00
// Get total HP for the player's party to determine if the player has lost
2018-06-30 18:55:34 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER & & gPartnerTrainerId = = TRAINER_STEVEN_PARTNER )
2017-09-22 21:33:49 +02:00
{
2021-10-04 16:21:03 +02:00
// In multi battle with Steven, skip his Pokémon
2020-08-05 02:33:05 +02:00
for ( i = 0 ; i < MULTI_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 ) )
HP_count + = GetMonData ( & gPlayerParty [ i ] , MON_DATA_HP ) ;
}
}
else
{
2018-11-18 20:00:36 +01:00
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2017-09-22 21:33:49 +02:00
{
if ( GetMonData ( & gPlayerParty [ i ] , MON_DATA_SPECIES ) & & ! GetMonData ( & gPlayerParty [ i ] , MON_DATA_IS_EGG )
2018-11-11 18:33:16 +01:00
& & ( ! ( gBattleTypeFlags & BATTLE_TYPE_ARENA ) | | ! ( gBattleStruct - > arenaLostPlayerMons & gBitTable [ i ] ) ) )
2017-09-22 21:33:49 +02:00
{
HP_count + = GetMonData ( & gPlayerParty [ i ] , MON_DATA_HP ) ;
}
}
}
if ( HP_count = = 0 )
2018-01-16 22:12:38 +01:00
gBattleOutcome | = B_OUTCOME_LOST ;
2020-08-16 19:14:35 +02:00
HP_count = 0 ;
2021-10-04 16:21:03 +02:00
// Get total HP for the enemy's party to determine if the player has won
2020-08-16 19:14:35 +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 )
2021-10-13 22:39:21 +02:00
& & ( ! ( gBattleTypeFlags & BATTLE_TYPE_ARENA ) | | ! ( gBattleStruct - > arenaLostOpponentMons & gBitTable [ i ] ) ) )
2017-09-22 21:33:49 +02:00
{
HP_count + = GetMonData ( & gEnemyParty [ i ] , MON_DATA_HP ) ;
}
}
if ( HP_count = = 0 )
2018-01-16 22:12:38 +01:00
gBattleOutcome | = B_OUTCOME_WON ;
2017-09-22 21:33:49 +02:00
2021-10-13 01:50:32 +02:00
// For link battles that haven't ended, count number of empty battler spots
// In link multi battles, jump to pointer if more than 1 spot empty
// In non-multi battles, jump to pointer if 1 spot is missing on both sides
2021-01-13 21:17:32 +01:00
if ( gBattleOutcome = = 0 & & ( gBattleTypeFlags & ( BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK ) ) )
2017-09-22 21:33:49 +02:00
{
2021-10-13 01:50:32 +02:00
s32 emptyPlayerSpots = 0 ;
s32 emptyOpponentSpots ;
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
2020-08-16 19:14:35 +02:00
for ( i = 0 ; i < gBattlersCount ; i + = 2 )
2017-09-22 21:33:49 +02:00
{
2021-10-13 01:50:32 +02:00
if ( ( gHitMarker & HITMARKER_FAINTED2 ( i ) ) & & ( ! gSpecialStatuses [ i ] . faintedHasReplacement ) )
emptyPlayerSpots + + ;
2017-09-22 21:33:49 +02:00
}
2021-10-13 01:50:32 +02:00
emptyOpponentSpots = 0 ;
2020-08-16 19:14:35 +02:00
for ( i = 1 ; i < gBattlersCount ; i + = 2 )
2017-09-22 21:33:49 +02:00
{
2021-10-13 01:50:32 +02:00
if ( ( gHitMarker & HITMARKER_FAINTED2 ( i ) ) & & ( ! gSpecialStatuses [ i ] . faintedHasReplacement ) )
emptyOpponentSpots + + ;
2017-09-22 21:33:49 +02:00
}
if ( gBattleTypeFlags & BATTLE_TYPE_MULTI )
{
2021-10-13 01:50:32 +02:00
if ( emptyOpponentSpots + emptyPlayerSpots > 1 )
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
gBattlescriptCurrInstr = T2_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-22 21:33:49 +02:00
else
gBattlescriptCurrInstr + = 5 ;
}
else
{
2021-10-13 01:50:32 +02:00
if ( emptyOpponentSpots ! = 0 & & emptyPlayerSpots ! = 0 )
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
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 ;
2017-09-22 21:33:49 +02:00
gBattleScripting . dmgMultiplier = 1 ;
gCritMultiplier = 1 ;
gBattleCommunication [ MOVE_EFFECT_BYTE ] = 0 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MISS_TYPE ] = 0 ;
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_DESTINYBOND ;
gHitMarker & = ~ HITMARKER_SYNCHRONISE_EFFECT ;
2017-09-22 21:33:49 +02:00
}
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-08-23 13:55:36 +02:00
static void Cmd_healthbar_update ( void )
2017-09-22 21:33:49 +02:00
{
2018-02-08 11:17:41 +01:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_TARGET )
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget ;
2017-09-22 21:33:49 +02:00
else
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2017-09-22 21:33:49 +02:00
2021-10-13 01:50:32 +02:00
BtlController_EmitHealthBarUpdate ( BUFFER_A , gBattleMoveDamage ) ;
2018-02-06 20:48:02 +01:00
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-08-23 13:55:36 +02:00
static void Cmd_jumpiftype2 ( void )
2017-09-22 21:33:49 +02:00
{
2018-02-08 12:13:29 +01:00
u8 battlerId = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-22 21:33:49 +02:00
2018-02-08 12:13:29 +01:00
if ( gBattlescriptCurrInstr [ 2 ] = = gBattleMons [ battlerId ] . type1 | | gBattlescriptCurrInstr [ 2 ] = = gBattleMons [ battlerId ] . type2 )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 3 ) ;
2017-09-22 21:33:49 +02:00
else
gBattlescriptCurrInstr + = 7 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_jumpifabilitypresent ( void )
2017-09-22 21:33:49 +02:00
{
2017-09-28 15:34:21 +02:00
if ( AbilityBattleEffects ( ABILITYEFFECT_CHECK_ON_FIELD , 0 , gBattlescriptCurrInstr [ 1 ] , 0 , 0 ) )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 2 ) ;
2017-09-22 21:33:49 +02:00
else
gBattlescriptCurrInstr + = 6 ;
}
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
2021-10-13 22:39:21 +02:00
| | gBattlescriptCurrInstr [ 2 ] = = B_ANIM_SNATCH_MOVE
| | gBattlescriptCurrInstr [ 2 ] = = B_ANIM_SUBSTITUTE_FADE )
2017-09-22 21:33:49 +02:00
{
2021-10-13 01:50:32 +02:00
BtlController_EmitBattleAnimation ( BUFFER_A , gBattlescriptCurrInstr [ 2 ] , * argumentPtr ) ;
2018-02-06 20:48:02 +01:00
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
2021-10-13 22:39:21 +02:00
| | gBattlescriptCurrInstr [ 2 ] = = B_ANIM_SUN_CONTINUES
| | gBattlescriptCurrInstr [ 2 ] = = B_ANIM_SANDSTORM_CONTINUES
| | gBattlescriptCurrInstr [ 2 ] = = B_ANIM_HAIL_CONTINUES )
2017-09-22 21:33:49 +02:00
{
2021-10-13 01:50:32 +02:00
BtlController_EmitBattleAnimation ( BUFFER_A , gBattlescriptCurrInstr [ 2 ] , * argumentPtr ) ;
2018-02-06 20:48:02 +01:00
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
{
2021-10-13 01:50:32 +02:00
BtlController_EmitBattleAnimation ( BUFFER_A , gBattlescriptCurrInstr [ 2 ] , * argumentPtr ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr + = 7 ;
}
}
2021-12-24 05:59:40 +01:00
// Same as playanimation, except it takes a pointer to some animation id, instead of taking the value directly
2021-10-13 22:39:21 +02:00
static void Cmd_playanimation_var ( void )
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
2021-10-13 22:39:21 +02:00
| | * animationIdPtr = = B_ANIM_SNATCH_MOVE
| | * animationIdPtr = = B_ANIM_SUBSTITUTE_FADE )
2017-09-22 21:33:49 +02:00
{
2021-10-13 01:50:32 +02:00
BtlController_EmitBattleAnimation ( BUFFER_A , * animationIdPtr , * argumentPtr ) ;
2018-02-06 20:48:02 +01:00
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
2021-10-13 22:39:21 +02:00
| | * animationIdPtr = = B_ANIM_SUN_CONTINUES
| | * animationIdPtr = = B_ANIM_SANDSTORM_CONTINUES
| | * animationIdPtr = = B_ANIM_HAIL_CONTINUES )
2017-09-22 21:33:49 +02:00
{
2021-10-13 01:50:32 +02:00
BtlController_EmitBattleAnimation ( BUFFER_A , * animationIdPtr , * argumentPtr ) ;
2018-02-06 20:48:02 +01:00
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
{
2021-10-13 01:50:32 +02:00
BtlController_EmitBattleAnimation ( BUFFER_A , * animationIdPtr , * argumentPtr ) ;
2018-02-06 20:48:02 +01:00
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
{
u8 value = 0 ;
2018-07-29 15:51:08 +02:00
switch ( GET_STAT_BUFF_VALUE2 ( gBattleScripting . statChanger ) )
2017-09-22 21:33:49 +02:00
{
2018-07-29 15:51:08 +02:00
case SET_STAT_BUFF_VALUE ( 1 ) : // +1
2018-10-07 15:39:46 +02:00
value = STAT_ANIM_PLUS1 ;
2017-09-22 21:33:49 +02:00
break ;
2018-07-29 15:51:08 +02:00
case SET_STAT_BUFF_VALUE ( 2 ) : // +2
2018-10-07 15:39:46 +02:00
value = STAT_ANIM_PLUS2 ;
2017-09-22 21:33:49 +02:00
break ;
2018-07-29 15:51:08 +02:00
case SET_STAT_BUFF_VALUE ( 1 ) | STAT_BUFF_NEGATIVE : // -1
2018-10-07 15:39:46 +02:00
value = STAT_ANIM_MINUS1 ;
2017-09-22 21:33:49 +02:00
break ;
2018-07-29 15:51:08 +02:00
case SET_STAT_BUFF_VALUE ( 2 ) | STAT_BUFF_NEGATIVE : // -2
2018-10-07 15:39:46 +02:00
value = STAT_ANIM_MINUS2 ;
2017-09-22 21:33:49 +02:00
break ;
}
2018-07-29 15:51:08 +02:00
gBattleScripting . animArg1 = GET_STAT_BUFF_ID ( gBattleScripting . statChanger ) + value - 1 ;
2017-09-22 21:33:49 +02:00
gBattleScripting . animArg2 = 0 ;
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_playstatchangeanimation ( void )
2017-09-22 21:33:49 +02:00
{
2017-09-23 00:06:52 +02:00
u32 currStat = 0 ;
2018-02-28 19:37:48 +01:00
u16 statAnimId = 0 ;
s32 changeableStatsCount = 0 ;
u8 statsToCheck = 0 ;
2017-09-22 21:33:49 +02:00
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-23 00:06:52 +02:00
statsToCheck = gBattlescriptCurrInstr [ 2 ] ;
2017-09-22 21:33:49 +02:00
2019-08-23 14:46:21 +02:00
if ( gBattlescriptCurrInstr [ 3 ] & STAT_CHANGE_NEGATIVE ) // goes down
2017-09-22 21:33:49 +02:00
{
2018-02-28 19:37:48 +01:00
s16 startingStatAnimId ;
2019-08-23 14:46:21 +02:00
if ( gBattlescriptCurrInstr [ 3 ] & 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-10-26 17:53:00 +02:00
if ( gBattlescriptCurrInstr [ 3 ] & STAT_CHANGE_CANT_PREVENT )
2017-09-22 21:33:49 +02:00
{
2020-08-05 02:33:05 +02:00
if ( gBattleMons [ gActiveBattler ] . statStages [ currStat ] > MIN_STAT_STAGE )
2017-09-23 00:06:52 +02:00
{
2018-02-28 19:37:48 +01:00
statAnimId = startingStatAnimId + currStat ;
changeableStatsCount + + ;
2017-09-23 00:06:52 +02:00
}
2017-09-22 21:33:49 +02:00
}
2018-02-06 02:46:59 +01:00
else if ( ! gSideTimers [ GET_BATTLER_SIDE ( gActiveBattler ) ] . mistTimer
& & gBattleMons [ gActiveBattler ] . ability ! = ABILITY_CLEAR_BODY
& & gBattleMons [ gActiveBattler ] . ability ! = ABILITY_WHITE_SMOKE
2018-02-08 12:13:29 +01:00
& & ! ( gBattleMons [ gActiveBattler ] . ability = = ABILITY_KEEN_EYE & & currStat = = STAT_ACC )
& & ! ( gBattleMons [ gActiveBattler ] . ability = = ABILITY_HYPER_CUTTER & & currStat = = STAT_ATK ) )
2017-09-22 21:33:49 +02:00
{
2020-08-05 02:33:05 +02:00
if ( gBattleMons [ gActiveBattler ] . statStages [ currStat ] > MIN_STAT_STAGE )
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-08-23 14:46:21 +02:00
if ( gBattlescriptCurrInstr [ 3 ] & 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
{
2018-02-28 19:37:48 +01:00
s16 startingStatAnimId ;
2019-08-23 14:46:21 +02:00
if ( gBattlescriptCurrInstr [ 3 ] & 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
{
2020-08-05 02:33:05 +02:00
if ( statsToCheck & 1 & & gBattleMons [ gActiveBattler ] . statStages [ currStat ] < MAX_STAT_STAGE )
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-08-23 14:46:21 +02:00
if ( gBattlescriptCurrInstr [ 3 ] & 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-10-26 17:53:00 +02:00
if ( gBattlescriptCurrInstr [ 3 ] & STAT_CHANGE_MULTIPLE_STATS & & 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
{
2021-10-13 01:50:32 +02:00
BtlController_EmitBattleAnimation ( BUFFER_A , B_ANIM_STATS_CHANGE , statAnimId ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2019-10-26 17:53:00 +02:00
if ( gBattlescriptCurrInstr [ 3 ] & STAT_CHANGE_MULTIPLE_STATS & & 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 ;
u8 moveType = 0 ;
u8 holdEffectAtk = 0 ;
u16 * choicedMoveAtk = NULL ;
2021-10-13 22:39:21 +02:00
u8 endMode , endState ;
2017-11-26 14:17:02 +01:00
u16 originallyUsedMove ;
2017-09-23 20:13:45 +02:00
2018-12-05 15:31:01 +01:00
if ( gChosenMove = = 0xFFFF )
2017-11-26 14:17:02 +01:00
originallyUsedMove = 0 ;
2017-09-23 20:13:45 +02:00
else
2017-11-26 18:07:00 +01:00
originallyUsedMove = gChosenMove ;
2017-09-23 20:13:45 +02:00
2021-10-13 22:39:21 +02:00
endMode = gBattlescriptCurrInstr [ 1 ] ;
endState = gBattlescriptCurrInstr [ 2 ] ;
2017-09-23 20:13:45 +02:00
2021-12-10 18:41:54 +01:00
if ( gBattleMons [ gBattlerAttacker ] . item = = ITEM_ENIGMA_BERRY_E_READER )
2018-02-06 23:09:39 +01:00
holdEffectAtk = gEnigmaBerries [ gBattlerAttacker ] . holdEffect ;
2017-09-23 20:13:45 +02:00
else
2018-02-06 23:09:39 +01:00
holdEffectAtk = ItemId_GetHoldEffect ( gBattleMons [ gBattlerAttacker ] . item ) ;
2017-09-23 20:13:45 +02:00
2018-02-06 23:09:39 +01:00
choicedMoveAtk = & gBattleStruct - > choicedMove [ gBattlerAttacker ] ;
2017-09-23 20:13:45 +02:00
GET_MOVE_TYPE ( gCurrentMove , moveType ) ;
do
{
2019-08-23 14:46:21 +02:00
switch ( gBattleScripting . moveendState )
2017-09-23 20:13:45 +02:00
{
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
2020-08-05 02:33:05 +02:00
& & gBattleMoves [ gCurrentMove ] . power & & gBattleMons [ gBattlerTarget ] . statStages [ STAT_ATK ] < MAX_STAT_STAGE )
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-01-16 22:12:38 +01:00
& & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) & & moveType = = TYPE_FIRE )
{
2021-09-24 20:30:15 +02:00
gBattleMons [ gBattlerTarget ] . status1 & = ~ STATUS1_FREEZE ;
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget ;
2021-10-13 01:50:32 +02:00
BtlController_EmitSetMonData ( BUFFER_A , REQUEST_STATUS_BATTLE , 0 , sizeof ( gBattleMons [ gBattlerTarget ] . status1 ) , & 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-09-27 18:27:36 +02:00
case MOVEEND_ON_DAMAGE_ABILITIES : // Contact abilities and Color Change
if ( AbilityBattleEffects ( ABILITYEFFECT_ON_DAMAGE , 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-09-15 23:58:12 +02:00
case MOVEEND_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
& & holdEffectAtk = = HOLD_EFFECT_CHOICE_BAND
2019-11-20 17:37:14 +01:00
& & gChosenMove ! = MOVE_STRUGGLE
2019-08-28 00:06:17 +02:00
& & ( * choicedMoveAtk = = 0 | | * choicedMoveAtk = = 0xFFFF ) )
2017-09-23 20:13:45 +02:00
{
2019-08-28 00:06:17 +02:00
if ( gChosenMove = = MOVE_BATON_PASS & & ! ( 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 ;
}
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
{
2017-09-27 23:43:45 +02:00
u16 * changedItem = & gBattleStruct - > changedItems [ i ] ;
2017-09-23 20:13:45 +02:00
if ( * changedItem ! = 0 )
{
gBattleMons [ i ] . item = * changedItem ;
* changedItem = 0 ;
}
}
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_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 ;
2021-10-13 01:50:32 +02:00
BtlController_EmitSpriteInvisibility ( BUFFER_A , TRUE ) ;
2018-02-06 20:48:02 +01:00
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 ;
2021-10-13 01:50:32 +02:00
BtlController_EmitSpriteInvisibility ( BUFFER_A , FALSE ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2021-09-24 20:30:15 +02: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 ;
2021-10-13 01:50:32 +02:00
BtlController_EmitSpriteInvisibility ( BUFFER_A , FALSE ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2021-09-24 20:30:15 +02: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 )
2021-09-24 20:30:15 +02:00
gBattleMons [ i ] . status2 & = ~ STATUS2_SUBSTITUTE ;
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_UPDATE_LAST_MOVES :
2018-06-30 14:12:17 +02:00
if ( gHitMarker & HITMARKER_SWAP_ATTACKER_TARGET )
2017-09-23 20:13:45 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
gBattlerAttacker = gBattlerTarget ;
gBattlerTarget = gActiveBattler ;
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_SWAP_ATTACKER_TARGET ;
2017-09-23 20:13:45 +02:00
}
if ( gHitMarker & HITMARKER_ATTACKSTRING_PRINTED )
{
2018-02-06 23:09:39 +01:00
gLastPrintedMoves [ gBattlerAttacker ] = gChosenMove ;
2017-09-23 20:13:45 +02:00
}
2018-02-06 23:09:39 +01:00
if ( ! ( gAbsentBattlerFlags & gBitTable [ gBattlerAttacker ] )
2021-10-13 01:50:32 +02:00
& & ! ( gBattleStruct - > absentBattlerFlags & gBitTable [ gBattlerAttacker ] )
2017-11-26 14:17:02 +01:00
& & gBattleMoves [ originallyUsedMove ] . effect ! = EFFECT_BATON_PASS )
2017-09-23 20:13:45 +02:00
{
if ( gHitMarker & HITMARKER_OBEYS )
{
2018-02-06 23:09:39 +01:00
gLastMoves [ gBattlerAttacker ] = gChosenMove ;
gLastResultingMoves [ gBattlerAttacker ] = gCurrentMove ;
2017-09-23 20:13:45 +02:00
}
else
{
2018-12-05 15:31:01 +01:00
gLastMoves [ gBattlerAttacker ] = 0xFFFF ;
gLastResultingMoves [ gBattlerAttacker ] = 0xFFFF ;
2017-09-23 20:13:45 +02:00
}
2018-02-06 23:09:39 +01:00
if ( ! ( gHitMarker & HITMARKER_FAINTED ( gBattlerTarget ) ) )
gLastHitBy [ gBattlerTarget ] = gBattlerAttacker ;
2017-09-23 20:13:45 +02:00
2018-01-16 22:12:38 +01:00
if ( gHitMarker & HITMARKER_OBEYS & & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
2017-09-23 20:13:45 +02:00
{
2018-12-05 15:31:01 +01:00
if ( gChosenMove = = 0xFFFF )
2017-09-23 20:13:45 +02:00
{
2018-02-06 23:09:39 +01:00
gLastLandedMoves [ gBattlerTarget ] = gChosenMove ;
2017-09-23 20:13:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gLastLandedMoves [ gBattlerTarget ] = gCurrentMove ;
GET_MOVE_TYPE ( gCurrentMove , gLastHitByType [ gBattlerTarget ] ) ;
2017-09-23 20:13:45 +02:00
}
}
else
{
2018-12-05 15:31:01 +01:00
gLastLandedMoves [ gBattlerTarget ] = 0xFFFF ;
2017-09-23 20:13:45 +02:00
}
}
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
2021-10-13 01:50:32 +02:00
if ( ! ( gAbsentBattlerFlags & gBitTable [ gBattlerAttacker ] ) & & ! ( gBattleStruct - > absentBattlerFlags & gBitTable [ gBattlerAttacker ] )
2017-11-26 14:17:02 +01:00
& & gBattleMoves [ originallyUsedMove ] . flags & FLAG_MIRROR_MOVE_AFFECTED & & gHitMarker & HITMARKER_OBEYS
2018-02-06 23:09:39 +01:00
& & gBattlerAttacker ! = gBattlerTarget & & ! ( gHitMarker & HITMARKER_FAINTED ( gBattlerTarget ) )
2018-01-16 22:12:38 +01:00
& & ! ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT ) )
2017-09-23 20:13:45 +02:00
{
u8 target , attacker ;
2018-10-14 18:10:54 +02:00
* ( gBattleStruct - > lastTakenMove + gBattlerTarget * 2 + 0 ) = gChosenMove ;
* ( gBattleStruct - > lastTakenMove + gBattlerTarget * 2 + 1 ) = gChosenMove > > 8 ;
2017-09-23 20:13:45 +02:00
2018-02-06 23:09:39 +01:00
target = gBattlerTarget ;
attacker = gBattlerAttacker ;
2018-10-14 18:10:54 +02:00
* ( attacker * 2 + target * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 0 ) = gChosenMove ;
2017-09-23 20:13:45 +02:00
2018-02-06 23:09:39 +01:00
target = gBattlerTarget ;
attacker = gBattlerAttacker ;
2018-10-14 18:10:54 +02:00
* ( attacker * 2 + target * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 1 ) = gChosenMove > > 8 ;
2017-09-23 20:13:45 +02:00
}
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.
2017-09-23 20:13:45 +02:00
if ( ! ( gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE ) & & gBattleTypeFlags & BATTLE_TYPE_DOUBLE
2018-02-06 23:09:39 +01:00
& & ! gProtectStructs [ gBattlerAttacker ] . chargingTurn & & gBattleMoves [ gCurrentMove ] . target = = MOVE_TARGET_BOTH
2017-09-23 20:13:45 +02:00
& & ! ( gHitMarker & HITMARKER_NO_ATTACKSTRING ) )
{
2018-02-08 12:13:29 +01:00
u8 battlerId = GetBattlerAtPosition ( BATTLE_PARTNER ( GetBattlerPosition ( gBattlerTarget ) ) ) ;
if ( gBattleMons [ battlerId ] . hp ! = 0 )
2017-09-23 20:13:45 +02:00
{
2018-02-08 12:13:29 +01:00
gBattlerTarget = battlerId ;
2017-09-23 20:13:45 +02:00
gHitMarker | = HITMARKER_NO_ATTACKSTRING ;
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState = 0 ;
2017-09-23 20:13:45 +02:00
MoveValuesCleanUp ( ) ;
BattleScriptPush ( gBattleScriptsForMoveEffects [ gBattleMoves [ gCurrentMove ] . effect ] ) ;
2018-09-01 20:00:13 +02:00
gBattlescriptCurrInstr = BattleScript_FlushMessageBox ;
2017-09-23 20:13:45 +02:00
return ;
}
else
{
gHitMarker | = HITMARKER_NO_ATTACKSTRING ;
}
}
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_COUNT :
2017-09-23 20:13:45 +02:00
break ;
}
2021-10-13 22:39:21 +02:00
if ( endMode = = 1 & & effect = = FALSE )
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState = MOVEEND_COUNT ;
2021-10-13 22:39:21 +02:00
if ( endMode = = 2 & & endState = = gBattleScripting . moveendState )
2019-08-23 14:46:21 +02:00
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-08-23 13:55:36 +02:00
static void Cmd_typecalc2 ( void )
2017-09-24 00:29:52 +02:00
{
u8 flags = 0 ;
s32 i = 0 ;
u8 moveType = gBattleMoves [ gCurrentMove ] . type ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . ability = = ABILITY_LEVITATE & & moveType = = TYPE_GROUND )
2017-09-24 00:29:52 +02:00
{
2018-02-06 23:09:39 +01:00
gLastUsedAbility = gBattleMons [ gBattlerTarget ] . ability ;
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = ( MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE ) ;
2018-02-06 23:09:39 +01:00
gLastLandedMoves [ gBattlerTarget ] = 0 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MISS_TYPE ] = B_MSG_GROUND_MISS ;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle ( gBattlerTarget , gLastUsedAbility ) ;
2017-09-24 00:29:52 +02:00
}
else
{
2017-11-11 20:01:04 +01:00
while ( TYPE_EFFECT_ATK_TYPE ( i ) ! = TYPE_ENDTABLE )
2017-09-24 00:29:52 +02:00
{
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( i ) = = TYPE_FORESIGHT )
2017-09-24 00:29:52 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_FORESIGHT )
2017-09-24 00:29:52 +02:00
{
break ;
}
else
{
i + = 3 ;
continue ;
}
}
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( i ) = = moveType )
2017-09-24 00:29:52 +02:00
{
// check type1
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type1 )
2017-09-24 00:29:52 +02:00
{
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_NO_EFFECT )
2017-09-24 00:29:52 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_DOESNT_AFFECT_FOE ;
2017-09-24 00:29:52 +02:00
break ;
}
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_NOT_EFFECTIVE )
2017-09-24 00:29:52 +02:00
{
2018-01-16 22:12:38 +01:00
flags | = MOVE_RESULT_NOT_VERY_EFFECTIVE ;
2017-09-24 00:29:52 +02:00
}
2017-11-11 20:01:04 +01:00
if ( TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_SUPER_EFFECTIVE )
2017-09-24 00:29:52 +02:00
{
2018-01-16 22:12:38 +01:00
flags | = MOVE_RESULT_SUPER_EFFECTIVE ;
2017-09-24 00:29:52 +02:00
}
}
// check type2
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type2 )
2017-09-24 00:29:52 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . type1 ! = gBattleMons [ gBattlerTarget ] . type2
2017-11-11 20:01:04 +01:00
& & TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_NO_EFFECT )
2017-09-24 00:29:52 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_DOESNT_AFFECT_FOE ;
2017-09-24 00:29:52 +02:00
break ;
}
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type2
& & gBattleMons [ gBattlerTarget ] . type1 ! = gBattleMons [ gBattlerTarget ] . type2
2017-11-11 20:01:04 +01:00
& & TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_NOT_EFFECTIVE )
2017-09-24 00:29:52 +02:00
{
2018-01-16 22:12:38 +01:00
flags | = MOVE_RESULT_NOT_VERY_EFFECTIVE ;
2017-09-24 00:29:52 +02:00
}
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_DEF_TYPE ( i ) = = gBattleMons [ gBattlerTarget ] . type2
& & gBattleMons [ gBattlerTarget ] . type1 ! = gBattleMons [ gBattlerTarget ] . type2
2017-11-11 20:01:04 +01:00
& & TYPE_EFFECT_MULTIPLIER ( i ) = = TYPE_MUL_SUPER_EFFECTIVE )
2017-09-24 00:29:52 +02:00
{
2018-01-16 22:12:38 +01:00
flags | = MOVE_RESULT_SUPER_EFFECTIVE ;
2017-09-24 00:29:52 +02:00
}
}
}
i + = 3 ;
}
}
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . ability = = ABILITY_WONDER_GUARD
2018-01-16 22:12:38 +01:00
& & ! ( flags & MOVE_RESULT_NO_EFFECT )
2018-02-06 23:09:39 +01:00
& & AttacksThisTurn ( gBattlerAttacker , gCurrentMove ) = = 2
2018-01-16 22:12:38 +01:00
& & ( ! ( flags & MOVE_RESULT_SUPER_EFFECTIVE ) | | ( ( flags & ( MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE ) ) = = ( MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE ) ) )
2017-09-24 00:29:52 +02:00
& & gBattleMoves [ gCurrentMove ] . power )
{
gLastUsedAbility = ABILITY_WONDER_GUARD ;
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2018-02-06 23:09:39 +01:00
gLastLandedMoves [ gBattlerTarget ] = 0 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MISS_TYPE ] = B_MSG_AVOIDED_DMG ;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle ( gBattlerTarget , gLastUsedAbility ) ;
2017-09-24 00:29:52 +02:00
}
2018-01-16 22:12:38 +01:00
if ( gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE )
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . targetNotAffected = 1 ;
2017-09-24 00:29:52 +02:00
gBattlescriptCurrInstr + + ;
}
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
{
2021-10-13 01:50:32 +02:00
BtlController_EmitReturnMonToBall ( BUFFER_A , FALSE ) ;
2018-02-06 20:48:02 +01:00
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
2021-10-13 01:50:32 +02:00
BtlController_EmitGetMonData ( BUFFER_A , REQUEST_ALL_BATTLE , gBitTable [ gBattlerPartyIndexes [ gActiveBattler ] ] ) ;
2018-02-06 20:48:02 +01:00
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 + + )
2018-02-06 02:46:59 +01:00
monData [ i ] = gBattleBufferB [ gActiveBattler ] [ 4 + i ] ;
2017-09-24 00:29:52 +02:00
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . type1 = gBaseStats [ gBattleMons [ gActiveBattler ] . species ] . type1 ;
gBattleMons [ gActiveBattler ] . type2 = gBaseStats [ gBattleMons [ gActiveBattler ] . species ] . type2 ;
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
2021-08-25 00:59:32 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_PALACE
2020-07-17 02:12:12 +02:00
& & gBattleMons [ gActiveBattler ] . maxHP / 2 > = gBattleMons [ gActiveBattler ] . hp
2021-08-25 00:59:32 +02:00
& & gBattleMons [ gActiveBattler ] . hp ! = 0
2020-07-17 02:12:12 +02:00
& & ! ( gBattleMons [ gActiveBattler ] . status1 & STATUS1_SLEEP ) )
2017-09-24 00:29:52 +02:00
{
2020-07-17 02:12:12 +02:00
gBattleStruct - > palaceFlags | = 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
2021-01-13 21:17:32 +01:00
| BATTLE_TYPE_RECORDED_LINK
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
2021-10-13 01:50:32 +02:00
BtlController_EmitSwitchInAnim ( BUFFER_A , gBattlerPartyIndexes [ gActiveBattler ] , gBattlescriptCurrInstr [ 2 ] ) ;
2018-02-06 20:48:02 +01:00
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
{
2020-09-11 00:07:46 +02:00
s32 i ;
s32 lastMonId ;
2018-02-28 19:37:48 +01:00
struct Pokemon * party ;
2017-09-24 00:29:52 +02:00
2021-09-24 20:30:15 +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
}
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
else if ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER )
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
party = gEnemyParty ;
else
party = gPlayerParty ;
2020-09-17 03:39:44 +02:00
lastMonId = 0 ;
2018-02-28 19:37:48 +01:00
if ( gActiveBattler & 2 )
2021-10-08 22:50:52 +02:00
lastMonId = MULTI_PARTY_SIZE ;
2017-09-24 00:29:52 +02:00
2021-10-08 22:50:52 +02:00
for ( i = lastMonId ; i < lastMonId + MULTI_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_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 ;
}
2021-10-08 22:50:52 +02:00
if ( i = = lastMonId + MULTI_PARTY_SIZE )
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 )
{
2021-01-13 21:17:32 +01:00
if ( gBattleTypeFlags & BATTLE_TYPE_TOWER_LINK_MULTI )
2017-09-24 00:29:52 +02:00
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_PLAYER )
2017-09-24 00:29:52 +02:00
{
party = gPlayerParty ;
2020-09-17 03:39:44 +02:00
lastMonId = 0 ;
2018-07-01 11:15:42 +02:00
if ( GetLinkTrainerFlankId ( GetBattlerMultiplayerId ( gActiveBattler ) ) = = TRUE )
2021-10-08 22:50:52 +02:00
lastMonId = MULTI_PARTY_SIZE ;
2017-09-24 00:29:52 +02:00
}
else
{
party = gEnemyParty ;
2018-02-06 02:46:59 +01:00
if ( gActiveBattler = = 1 )
2020-09-17 03:39:44 +02:00
lastMonId = 0 ;
2017-09-24 00:29:52 +02:00
else
2021-10-08 22:50:52 +02:00
lastMonId = MULTI_PARTY_SIZE ;
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 ;
2020-09-17 03:39:44 +02:00
lastMonId = 0 ;
2018-07-01 11:15:42 +02:00
if ( GetLinkTrainerFlankId ( GetBattlerMultiplayerId ( gActiveBattler ) ) = = TRUE )
2021-10-08 22:50:52 +02:00
lastMonId = MULTI_PARTY_SIZE ;
2017-09-24 00:29:52 +02:00
}
2021-10-08 22:50:52 +02:00
for ( i = lastMonId ; i < lastMonId + MULTI_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_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 ;
}
2021-10-08 22:50:52 +02:00
if ( i = = lastMonId + MULTI_PARTY_SIZE )
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 ;
2020-09-17 03:39:44 +02:00
lastMonId = 0 ;
2018-02-28 19:37:48 +01:00
if ( gActiveBattler = = B_POSITION_OPPONENT_RIGHT )
2021-10-08 22:50:52 +02:00
lastMonId = PARTY_SIZE / 2 ;
2017-09-24 00:29:52 +02:00
2021-10-08 22:50:52 +02:00
for ( i = lastMonId ; i < lastMonId + ( PARTY_SIZE / 2 ) ; 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 ;
}
2021-10-08 22:50:52 +02:00
if ( i = = lastMonId + ( PARTY_SIZE / 2 ) )
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 2 ) ;
2017-09-24 00:29:52 +02:00
else
gBattlescriptCurrInstr + = 6 ;
}
else
{
2018-02-28 19:37:48 +01:00
u8 battlerIn1 , battlerIn2 ;
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_OPPONENT )
2017-09-24 00:29:52 +02:00
{
2018-02-28 19:37:48 +01:00
battlerIn1 = GetBattlerAtPosition ( B_POSITION_OPPONENT_LEFT ) ;
2017-09-24 00:29:52 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
2018-02-28 19:37:48 +01:00
battlerIn2 = GetBattlerAtPosition ( B_POSITION_OPPONENT_RIGHT ) ;
2017-09-24 00:29:52 +02:00
else
2018-02-28 19:37:48 +01:00
battlerIn2 = battlerIn1 ;
2017-09-24 00:29:52 +02:00
party = gEnemyParty ;
}
else
{
2018-02-28 19:37:48 +01:00
battlerIn1 = GetBattlerAtPosition ( B_POSITION_PLAYER_LEFT ) ;
2017-09-24 00:29:52 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
2018-02-28 19:37:48 +01:00
battlerIn2 = GetBattlerAtPosition ( B_POSITION_PLAYER_RIGHT ) ;
2017-09-24 00:29:52 +02:00
else
2018-02-28 19:37:48 +01:00
battlerIn2 = battlerIn1 ;
2017-09-24 00:29:52 +02:00
party = gPlayerParty ;
}
2018-02-28 19:37:48 +01:00
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2017-09-24 00:29:52 +02:00
{
2018-02-28 19:37:48 +01:00
if ( GetMonData ( & party [ i ] , MON_DATA_HP ) ! = 0
& & GetMonData ( & party [ i ] , MON_DATA_SPECIES ) ! = SPECIES_NONE
& & ! GetMonData ( & party [ i ] , MON_DATA_IS_EGG )
& & i ! = gBattlerPartyIndexes [ battlerIn1 ] & & i ! = gBattlerPartyIndexes [ battlerIn2 ] )
2017-09-24 00:29:52 +02:00
break ;
}
2020-07-17 02:12:12 +02:00
if ( i = = PARTY_SIZE )
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 ;
}
}
2021-10-13 01:50:32 +02:00
// Opens the party screen to choose a new Pokémon to send out.
// slotId is the Pokémon to replace.
// Note that this is not used by the Switch action, only replacing fainted Pokémon or Baton Pass
2021-04-03 18:38:07 +02:00
static void ChooseMonToSendOut ( u8 slotId )
2017-09-24 00:29:52 +02:00
{
2021-10-13 01:50:32 +02:00
* ( gBattleStruct - > battlerPartyIndexes + 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
2021-10-13 01:50:32 +02:00
BtlController_EmitChoosePokemon ( BUFFER_A , PARTY_ACTION_SEND_OUT , slotId , ABILITY_NONE , gBattleStruct - > battlerPartyOrders [ 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
2021-10-13 01:50:32 +02:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_FAINTED_LINK_MULTIPLE_1 )
2017-09-25 00:09:13 +02:00
{
2021-10-13 01:50:32 +02:00
if ( ( gBattleTypeFlags & BATTLE_TYPE_MULTI ) | | ! ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE ) )
2017-09-25 00:09:13 +02:00
{
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
{
2021-04-03 18:38:07 +02:00
if ( HasNoMonsToSwitch ( gActiveBattler , PARTY_SIZE , PARTY_SIZE ) )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags | = gBitTable [ gActiveBattler ] ;
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_FAINTED ( gActiveBattler ) ;
2021-10-13 01:50:32 +02:00
BtlController_EmitLinkStandbyMsg ( BUFFER_A , LINK_STANDBY_MSG_ONLY , FALSE ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
2021-10-13 01:50:32 +02:00
else if ( ! gSpecialStatuses [ gActiveBattler ] . faintedHasReplacement )
2017-09-25 00:09:13 +02:00
{
2021-04-03 18:38:07 +02:00
ChooseMonToSendOut ( PARTY_SIZE ) ;
2021-10-13 01:50:32 +02:00
gSpecialStatuses [ gActiveBattler ] . faintedHasReplacement = TRUE ;
2017-09-25 00:09:13 +02:00
}
}
else
{
2021-10-13 01:50:32 +02:00
BtlController_EmitLinkStandbyMsg ( BUFFER_A , LINK_STANDBY_MSG_ONLY , FALSE ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
}
}
else if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
{
2021-10-13 01:50:32 +02:00
bool8 hasReplacement_0 , hasReplacement_1 , hasReplacement_2 , hasReplacement_3 ;
2017-09-25 00:09:13 +02:00
2021-03-30 23:38:09 +02:00
hitmarkerFaintBits = gHitMarker > > 28 ;
2017-09-25 00:09:13 +02:00
if ( gBitTable [ 0 ] & hitmarkerFaintBits )
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 0 ;
2021-10-13 01:50:32 +02:00
if ( HasNoMonsToSwitch ( gActiveBattler , PARTY_SIZE , PARTY_SIZE ) )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags | = gBitTable [ gActiveBattler ] ;
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_FAINTED ( gActiveBattler ) ;
2021-10-13 01:50:32 +02:00
BtlController_EmitCantSwitch ( BUFFER_A ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
2021-10-13 01:50:32 +02:00
else if ( ! gSpecialStatuses [ gActiveBattler ] . faintedHasReplacement )
2017-09-25 00:09:13 +02:00
{
2021-04-03 18:38:07 +02:00
ChooseMonToSendOut ( gBattleStruct - > monToSwitchIntoId [ 2 ] ) ;
2021-10-13 01:50:32 +02:00
gSpecialStatuses [ gActiveBattler ] . faintedHasReplacement = TRUE ;
2017-09-25 00:09:13 +02:00
}
else
{
2021-10-13 01:50:32 +02:00
BtlController_EmitLinkStandbyMsg ( BUFFER_A , LINK_STANDBY_MSG_ONLY , FALSE ) ;
2018-02-06 20:48:02 +01:00
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 ;
2021-10-13 01:50:32 +02:00
if ( HasNoMonsToSwitch ( gActiveBattler , PARTY_SIZE , PARTY_SIZE ) )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags | = gBitTable [ gActiveBattler ] ;
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_FAINTED ( gActiveBattler ) ;
2021-10-13 01:50:32 +02:00
BtlController_EmitCantSwitch ( BUFFER_A ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
2021-10-13 01:50:32 +02:00
else if ( ! gSpecialStatuses [ gActiveBattler ] . faintedHasReplacement )
2017-09-25 00:09:13 +02:00
{
2021-04-03 18:38:07 +02:00
ChooseMonToSendOut ( gBattleStruct - > monToSwitchIntoId [ 0 ] ) ;
2021-10-13 01:50:32 +02:00
gSpecialStatuses [ gActiveBattler ] . faintedHasReplacement = TRUE ;
2017-09-25 00:09:13 +02:00
}
else if ( ! ( flags & 1 ) )
{
2021-10-13 01:50:32 +02:00
BtlController_EmitLinkStandbyMsg ( BUFFER_A , LINK_STANDBY_MSG_ONLY , FALSE ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
}
if ( gBitTable [ 1 ] & hitmarkerFaintBits )
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 1 ;
2021-10-13 01:50:32 +02:00
if ( HasNoMonsToSwitch ( gActiveBattler , PARTY_SIZE , PARTY_SIZE ) )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags | = gBitTable [ gActiveBattler ] ;
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_FAINTED ( gActiveBattler ) ;
2021-10-13 01:50:32 +02:00
BtlController_EmitCantSwitch ( BUFFER_A ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
2021-10-13 01:50:32 +02:00
else if ( ! gSpecialStatuses [ gActiveBattler ] . faintedHasReplacement )
2017-09-25 00:09:13 +02:00
{
2021-04-03 18:38:07 +02:00
ChooseMonToSendOut ( gBattleStruct - > monToSwitchIntoId [ 3 ] ) ;
2021-10-13 01:50:32 +02:00
gSpecialStatuses [ gActiveBattler ] . faintedHasReplacement = TRUE ;
2017-09-25 00:09:13 +02:00
}
else
{
2021-10-13 01:50:32 +02:00
BtlController_EmitLinkStandbyMsg ( BUFFER_A , LINK_STANDBY_MSG_ONLY , FALSE ) ;
2018-02-06 20:48:02 +01:00
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 ;
2021-10-13 01:50:32 +02:00
if ( HasNoMonsToSwitch ( gActiveBattler , PARTY_SIZE , PARTY_SIZE ) )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags | = gBitTable [ gActiveBattler ] ;
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_FAINTED ( gActiveBattler ) ;
2021-10-13 01:50:32 +02:00
BtlController_EmitCantSwitch ( BUFFER_A ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
2021-10-13 01:50:32 +02:00
else if ( ! gSpecialStatuses [ gActiveBattler ] . faintedHasReplacement )
2017-09-25 00:09:13 +02:00
{
2021-04-03 18:38:07 +02:00
ChooseMonToSendOut ( gBattleStruct - > monToSwitchIntoId [ 1 ] ) ;
2021-10-13 01:50:32 +02:00
gSpecialStatuses [ gActiveBattler ] . faintedHasReplacement = TRUE ;
2017-09-25 00:09:13 +02:00
}
else if ( ! ( flags & 2 ) )
{
2021-10-13 01:50:32 +02:00
BtlController_EmitLinkStandbyMsg ( BUFFER_A , LINK_STANDBY_MSG_ONLY , FALSE ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
}
2021-10-13 01:50:32 +02:00
hasReplacement_0 = gSpecialStatuses [ 0 ] . faintedHasReplacement ;
if ( ! hasReplacement_0 )
2017-09-25 00:09:13 +02:00
{
2021-10-13 01:50:32 +02:00
hasReplacement_2 = gSpecialStatuses [ 2 ] . faintedHasReplacement ;
if ( ! hasReplacement_2 & & hitmarkerFaintBits ! = 0 )
2017-09-25 00:09:13 +02:00
{
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
2021-10-13 01:50:32 +02:00
BtlController_EmitLinkStandbyMsg ( BUFFER_A , LINK_STANDBY_MSG_ONLY , FALSE ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
}
2021-10-13 01:50:32 +02:00
hasReplacement_1 = gSpecialStatuses [ 1 ] . faintedHasReplacement ;
if ( ! hasReplacement_1 )
2017-09-25 00:09:13 +02:00
{
2021-10-13 01:50:32 +02:00
hasReplacement_3 = gSpecialStatuses [ 3 ] . faintedHasReplacement ;
if ( ! hasReplacement_3 & & hitmarkerFaintBits ! = 0 )
2017-09-25 00:09:13 +02:00
{
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
2021-10-13 01:50:32 +02:00
BtlController_EmitLinkStandbyMsg ( BUFFER_A , LINK_STANDBY_MSG_ONLY , FALSE ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
}
}
gBattlescriptCurrInstr + = 6 ;
}
2021-10-13 01:50:32 +02:00
else if ( gBattlescriptCurrInstr [ 1 ] = = BS_FAINTED_LINK_MULTIPLE_2 )
2017-09-25 00:09:13 +02:00
{
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_MULTI ) )
{
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
{
2021-03-30 23:38:09 +02:00
hitmarkerFaintBits = gHitMarker > > 28 ;
2017-09-25 00:09:13 +02:00
if ( gBitTable [ 2 ] & hitmarkerFaintBits & & gBitTable [ 0 ] & hitmarkerFaintBits )
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 2 ;
2021-10-13 01:50:32 +02:00
if ( HasNoMonsToSwitch ( gActiveBattler , gBattleBufferB [ 0 ] [ 1 ] , PARTY_SIZE ) )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags | = gBitTable [ gActiveBattler ] ;
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_FAINTED ( gActiveBattler ) ;
2021-10-13 01:50:32 +02:00
BtlController_EmitCantSwitch ( BUFFER_A ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
2021-10-13 01:50:32 +02:00
else if ( ! gSpecialStatuses [ gActiveBattler ] . faintedHasReplacement )
2017-09-25 00:09:13 +02:00
{
2021-04-03 18:38:07 +02:00
ChooseMonToSendOut ( gBattleStruct - > monToSwitchIntoId [ 0 ] ) ;
2021-10-13 01:50:32 +02:00
gSpecialStatuses [ gActiveBattler ] . faintedHasReplacement = TRUE ;
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 ;
2021-10-13 01:50:32 +02:00
if ( HasNoMonsToSwitch ( gActiveBattler , gBattleBufferB [ 1 ] [ 1 ] , PARTY_SIZE ) )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags | = gBitTable [ gActiveBattler ] ;
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_FAINTED ( gActiveBattler ) ;
2021-10-13 01:50:32 +02:00
BtlController_EmitCantSwitch ( BUFFER_A ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
}
2021-10-13 01:50:32 +02:00
else if ( ! gSpecialStatuses [ gActiveBattler ] . faintedHasReplacement )
2017-09-25 00:09:13 +02:00
{
2021-04-03 18:38:07 +02:00
ChooseMonToSendOut ( gBattleStruct - > monToSwitchIntoId [ 1 ] ) ;
2021-10-13 01:50:32 +02:00
gSpecialStatuses [ gActiveBattler ] . faintedHasReplacement = TRUE ;
2017-09-25 00:09:13 +02:00
}
}
gBattlescriptCurrInstr + = 6 ;
}
else
{
2021-10-13 01:50:32 +02:00
// Not multi or double battle
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + = 6 ;
}
}
else
{
2021-10-13 01:50:32 +02:00
// Multi battle
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + = 6 ;
}
2021-03-30 23:38:09 +02:00
hitmarkerFaintBits = gHitMarker > > 28 ;
2017-09-25 00:09:13 +02:00
2018-02-08 11:17:41 +01:00
gBattlerFainted = 0 ;
2020-09-17 01:27:55 +02:00
while ( ! ( gBitTable [ gBattlerFainted ] & hitmarkerFaintBits )
& & gBattlerFainted < gBattlersCount )
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
{
2021-04-03 18:38:07 +02:00
if ( gBattlescriptCurrInstr [ 1 ] & PARTY_SCREEN_OPTIONAL )
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
2021-09-24 20:30:15 +02:00
battlerId = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] & ~ PARTY_SCREEN_OPTIONAL ) ;
2021-10-13 01:50:32 +02:00
if ( gSpecialStatuses [ battlerId ] . faintedHasReplacement )
2017-09-25 00:09:13 +02:00
{
gBattlescriptCurrInstr + = 6 ;
}
2021-04-03 18:38:07 +02:00
else if ( HasNoMonsToSwitch ( battlerId , PARTY_SIZE , PARTY_SIZE ) )
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 ] ;
2021-09-24 20:30:15 +02:00
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 ;
2021-10-13 01:50:32 +02:00
* ( gBattleStruct - > battlerPartyIndexes + gActiveBattler ) = gBattlerPartyIndexes [ gActiveBattler ] ;
* ( gBattleStruct - > monToSwitchIntoId + gActiveBattler ) = PARTY_SIZE ;
2018-02-06 02:46:59 +01:00
gBattleStruct - > field_93 & = ~ ( gBitTable [ gActiveBattler ] ) ;
2017-09-25 00:09:13 +02:00
2021-10-13 01:50:32 +02:00
BtlController_EmitChoosePokemon ( BUFFER_A , hitmarkerFaintBits , * ( gBattleStruct - > monToSwitchIntoId + ( gActiveBattler ^ 2 ) ) , ABILITY_NONE , gBattleStruct - > battlerPartyOrders [ gActiveBattler ] ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + = 6 ;
2021-10-13 01:50:32 +02:00
if ( GetBattlerPosition ( gActiveBattler ) = = B_POSITION_PLAYER_LEFT & & gBattleResults . playerSwitchesCounter < 255 )
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
{
2021-10-13 01:50:32 +02:00
BtlController_EmitLinkStandbyMsg ( BUFFER_A , LINK_STANDBY_MSG_ONLY , FALSE ) ;
2018-02-06 20:48:02 +01:00
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
2021-10-13 01:50:32 +02:00
BtlController_EmitLinkStandbyMsg ( BUFFER_A , LINK_STANDBY_MSG_ONLY , FALSE ) ;
2018-02-06 20:48:02 +01:00
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
{
2021-10-08 22:50:52 +02:00
if ( gBattleBufferB [ i ] [ 0 ] = = CONTROLLER_CHOSENMONRETURNVALUE )
2017-09-25 00:09:13 +02:00
{
2017-11-12 17:06:31 +01:00
* ( gBattleStruct - > monToSwitchIntoId + i ) = gBattleBufferB [ i ] [ 1 ] ;
2017-09-25 00:09:13 +02:00
if ( ! ( gBattleStruct - > field_93 & gBitTable [ i ] ) )
{
2018-02-06 20:48:02 +01:00
RecordedBattle_SetBattlerAction ( i , gBattleBufferB [ i ] [ 1 ] ) ;
2017-09-25 00:09:13 +02:00
gBattleStruct - > field_93 | = gBitTable [ i ] ;
}
}
}
break ;
case 1 :
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_MULTI ) )
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
{
2018-02-06 20:48:02 +01:00
RecordedBattle_SetBattlerAction ( gActiveBattler , gBattleBufferB [ gActiveBattler ] [ 1 ] ) ;
2018-02-06 02:46:59 +01:00
gBattleStruct - > field_93 | = gBitTable [ gActiveBattler ] ;
2017-09-25 00:09:13 +02:00
}
// fall through
case 3 :
2018-02-06 02:46:59 +01:00
gBattleCommunication [ 0 ] = gBattleBufferB [ gActiveBattler ] [ 1 ] ;
* ( gBattleStruct - > monToSwitchIntoId + gActiveBattler ) = gBattleBufferB [ gActiveBattler ] [ 1 ] ;
2017-09-25 00:09:13 +02:00
2017-10-04 19:25:14 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_LINK & & gBattleTypeFlags & BATTLE_TYPE_MULTI )
2017-09-25 00:09:13 +02:00
{
2021-10-13 01:50:32 +02:00
* ( gActiveBattler * 3 + ( u8 * ) ( gBattleStruct - > battlerPartyOrders ) + 0 ) & = 0xF ;
* ( gActiveBattler * 3 + ( u8 * ) ( gBattleStruct - > battlerPartyOrders ) + 0 ) | = ( gBattleBufferB [ gActiveBattler ] [ 2 ] & 0xF0 ) ;
* ( gActiveBattler * 3 + ( u8 * ) ( gBattleStruct - > battlerPartyOrders ) + 1 ) = gBattleBufferB [ gActiveBattler ] [ 3 ] ;
2017-09-25 00:09:13 +02:00
2021-10-13 01:50:32 +02:00
* ( ( gActiveBattler ^ BIT_FLANK ) * 3 + ( u8 * ) ( gBattleStruct - > battlerPartyOrders ) + 0 ) & = ( 0xF0 ) ;
* ( ( gActiveBattler ^ BIT_FLANK ) * 3 + ( u8 * ) ( gBattleStruct - > battlerPartyOrders ) + 0 ) | = ( gBattleBufferB [ gActiveBattler ] [ 2 ] & 0xF0 ) > > 4 ;
* ( ( gActiveBattler ^ BIT_FLANK ) * 3 + ( u8 * ) ( gBattleStruct - > battlerPartyOrders ) + 2 ) = gBattleBufferB [ 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 )
2018-02-06 02:46:59 +01:00
PREPARE_MON_NICK_BUFFER ( gBattleTextBuff2 , gActiveBattler , gBattleBufferB [ gActiveBattler ] [ 1 ] )
2017-09-25 00:09:13 +02:00
break ;
}
gBattlescriptCurrInstr + = 3 ;
}
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 ] ) ;
2020-07-28 00:10:42 +02:00
UpdateSentPokesToOpponentValue ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_FAINTED ( gActiveBattler ) ;
2021-10-13 01:50:32 +02:00
gSpecialStatuses [ gActiveBattler ] . faintedHasReplacement = FALSE ;
2017-09-25 00:09:13 +02:00
2018-02-06 02:46:59 +01:00
if ( ! ( gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] & SIDE_STATUS_SPIKES_DAMAGED )
& & ( gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] & SIDE_STATUS_SPIKES )
2018-03-01 00:59:52 +01:00
& & ! IS_BATTLER_OF_TYPE ( gActiveBattler , TYPE_FLYING )
2018-02-06 02:46:59 +01:00
& & gBattleMons [ gActiveBattler ] . ability ! = ABILITY_LEVITATE )
2017-09-25 00:09:13 +02:00
{
u8 spikesDmg ;
2018-02-06 02:46:59 +01:00
gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] | = SIDE_STATUS_SPIKES_DAMAGED ;
2017-09-25 00:09:13 +02:00
2021-09-24 20:30:15 +02:00
gBattleMons [ gActiveBattler ] . status2 & = ~ STATUS2_DESTINY_BOND ;
gHitMarker & = ~ HITMARKER_DESTINYBOND ;
2017-09-25 00:09:13 +02:00
2018-02-06 02:46:59 +01:00
spikesDmg = ( 5 - gSideTimers [ GetBattlerSide ( gActiveBattler ) ] . spikesAmount ) * 2 ;
gBattleMoveDamage = gBattleMons [ gActiveBattler ] . maxHP / ( spikesDmg ) ;
2017-09-25 00:09:13 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = gActiveBattler ;
2017-09-25 00:09:13 +02:00
BattleScriptPushCursor ( ) ;
2018-02-08 11:17:41 +01:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_TARGET )
2017-11-25 18:42:31 +01:00
gBattlescriptCurrInstr = BattleScript_SpikesOnTarget ;
2018-02-08 11:17:41 +01:00
else if ( gBattlescriptCurrInstr [ 1 ] = = BS_ATTACKER )
2017-11-25 18:42:31 +01:00
gBattlescriptCurrInstr = BattleScript_SpikesOnAttacker ;
2017-09-25 00:09:13 +02:00
else
2018-02-08 11:17:41 +01:00
gBattlescriptCurrInstr = BattleScript_SpikesOnFaintedBattler ;
2017-09-25 00:09:13 +02:00
}
else
{
2019-01-19 22:32:25 +01:00
// There is a hack here to ensure the truant counter will be 0 when the battler's next turn starts.
// The truant counter is not updated in the case where a mon switches in after a lost judgement in the battle arena.
if ( gBattleMons [ gActiveBattler ] . ability = = ABILITY_TRUANT & & ! gDisableStructs [ gActiveBattler ] . truantSwitchInHack )
2018-02-06 02:46:59 +01:00
gDisableStructs [ gActiveBattler ] . truantCounter = 1 ;
2017-09-25 00:09:13 +02:00
2019-01-19 22:32:25 +01:00
gDisableStructs [ gActiveBattler ] . truantSwitchInHack = 0 ;
2017-09-25 00:09:13 +02:00
2018-09-01 20:00:13 +02:00
if ( ! AbilityBattleEffects ( ABILITYEFFECT_ON_SWITCHIN , gActiveBattler , 0 , 0 , 0 )
2018-12-05 15:31:01 +01:00
& & ! ItemBattleEffects ( ITEMEFFECT_ON_SWITCH_IN , gActiveBattler , FALSE ) )
2017-09-25 00:09:13 +02:00
{
2021-09-24 20:30:15 +02:00
gSideStatuses [ GetBattlerSide ( gActiveBattler ) ] & = ~ SIDE_STATUS_SPIKES_DAMAGED ;
2017-09-25 00:09:13 +02:00
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-25 00:09:13 +02:00
{
2018-06-28 21:06:32 +02:00
if ( gBattlerByTurnOrder [ i ] = = gActiveBattler )
2018-02-06 23:09:39 +01:00
gActionsByTurnOrder [ i ] = B_ACTION_CANCEL_PARTNER ;
2017-09-25 00:09:13 +02:00
}
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
u16 * hpOnSwitchout = & gBattleStruct - > hpOnSwitchout [ GetBattlerSide ( i ) ] ;
2017-09-25 00:09:13 +02:00
* hpOnSwitchout = gBattleMons [ i ] . hp ;
}
2021-10-13 01:50:32 +02:00
if ( gBattlescriptCurrInstr [ 1 ] = = BS_FAINTED_LINK_MULTIPLE_1 )
2017-09-25 00:09:13 +02:00
{
2021-03-30 23:38:09 +02:00
u32 hitmarkerFaintBits = gHitMarker > > 28 ;
2017-09-25 00:09:13 +02:00
2018-02-08 11:17:41 +01:00
gBattlerFainted + + ;
2017-09-25 00:09:13 +02:00
while ( 1 )
{
2018-02-08 11:17:41 +01:00
if ( hitmarkerFaintBits & gBitTable [ gBattlerFainted ] & & ! ( gAbsentBattlerFlags & gBitTable [ gBattlerFainted ] ) )
2017-09-25 00:09:13 +02:00
break ;
2018-02-08 11:17:41 +01:00
if ( gBattlerFainted > = gBattlersCount )
2017-09-25 00:09:13 +02:00
break ;
2018-02-08 11:17:41 +01:00
gBattlerFainted + + ;
2017-09-25 00:09:13 +02:00
}
}
gBattlescriptCurrInstr + = 2 ;
}
}
}
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 ] ) ;
2021-10-13 01:50:32 +02:00
BtlController_EmitTrainerSlide ( BUFFER_A ) ;
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_playse ( void )
2017-09-25 00:09:13 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2021-10-13 01:50:32 +02:00
BtlController_EmitPlaySE ( BUFFER_A , 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 ;
2021-10-13 01:50:32 +02:00
BtlController_EmitPlayFanfareOrBGM ( BUFFER_A , 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 ] ) ;
2021-10-13 01:50:32 +02:00
BtlController_EmitFaintingCry ( BUFFER_A ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + = 2 ;
}
2021-01-22 08:48:22 +01:00
static void Cmd_endlinkbattle ( void )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gActiveBattler = GetBattlerAtPosition ( B_POSITION_PLAYER_LEFT ) ;
2021-10-13 01:50:32 +02:00
BtlController_EmitEndLinkBattle ( BUFFER_A , gBattleOutcome ) ;
2018-02-06 20:48:02 +01:00
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 ] ) ;
2021-10-13 01:50:32 +02:00
BtlController_EmitReturnMonToBall ( BUFFER_A , TRUE ) ;
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_handlelearnnewmove ( void )
2017-09-25 00:09:13 +02:00
{
2021-10-13 22:39:21 +02:00
const u8 * learnedMovePtr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
const u8 * nothingToLearnPtr = 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
2021-10-13 22:39:21 +02:00
if ( learnMove = = MOVE_NONE )
2017-09-25 00:09:13 +02:00
{
2021-10-13 22:39:21 +02:00
gBattlescriptCurrInstr = nothingToLearnPtr ;
2017-09-25 00:09:13 +02:00
}
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
}
}
2021-10-13 22:39:21 +02:00
gBattlescriptCurrInstr = learnedMovePtr ;
2017-09-25 00:09:13 +02:00
}
}
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 :
2021-10-08 22:50:52 +02:00
HandleBattleWindow ( 24 , 8 , 29 , 13 , 0 ) ;
BattlePutTextOnWindow ( gText_BattleYesNoChoice , B_WIN_YESNO ) ;
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 :
2020-09-05 03:11:55 +02:00
if ( JOY_NEW ( DPAD_UP ) & & gBattleCommunication [ CURSOR_POSITION ] ! = 0 )
2017-09-25 00:09:13 +02:00
{
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
}
2020-09-05 03:11:55 +02:00
if ( JOY_NEW ( DPAD_DOWN ) & & gBattleCommunication [ CURSOR_POSITION ] = = 0 )
2017-09-25 00:09:13 +02:00
{
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
}
2020-09-05 03:11:55 +02:00
if ( JOY_NEW ( A_BUTTON ) )
2017-09-25 00:09:13 +02:00
{
PlaySE ( SE_SELECT ) ;
if ( gBattleCommunication [ 1 ] = = 0 )
{
2021-10-08 22:50:52 +02:00
HandleBattleWindow ( 24 , 8 , 29 , 13 , WINDOW_CLEAR ) ;
BeginNormalPaletteFade ( PALETTES_ALL , 0 , 0 , 16 , RGB_BLACK ) ;
2017-09-25 00:09:13 +02:00
gBattleScripting . learnMoveState + + ;
}
else
{
gBattleScripting . learnMoveState = 5 ;
}
}
2020-09-05 03:11:55 +02:00
else if ( JOY_NEW ( B_BUTTON ) )
2017-09-25 00:09:13 +02:00
{
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
2021-10-12 02:49:56 +02:00
if ( gBattlerPartyIndexes [ 0 ] = = gBattleStruct - > expGetterMonId & & MOVE_IS_PERMANENT ( 0 , 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
2021-10-12 02:49:56 +02:00
& & MOVE_IS_PERMANENT ( 2 , movePosition ) )
2017-09-25 00:09:13 +02:00
{
RemoveBattleMonPPBonus ( & gBattleMons [ 2 ] , movePosition ) ;
SetBattleMonMoveSlot ( & gBattleMons [ 2 ] , gMoveToLearn , movePosition ) ;
}
}
}
}
break ;
case 5 :
2021-10-08 22:50:52 +02:00
HandleBattleWindow ( 24 , 8 , 29 , 13 , 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 :
2021-10-08 22:50:52 +02:00
HandleBattleWindow ( 24 , 8 , 29 , 13 , 0 ) ;
BattlePutTextOnWindow ( gText_BattleYesNoChoice , B_WIN_YESNO ) ;
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 :
2020-09-05 03:11:55 +02:00
if ( JOY_NEW ( DPAD_UP ) & & gBattleCommunication [ CURSOR_POSITION ] ! = 0 )
2017-09-25 00:09:13 +02:00
{
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
}
2020-09-05 03:11:55 +02:00
if ( JOY_NEW ( DPAD_DOWN ) & & gBattleCommunication [ CURSOR_POSITION ] = = 0 )
2017-09-25 00:09:13 +02:00
{
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
}
2020-09-05 03:11:55 +02:00
if ( JOY_NEW ( A_BUTTON ) )
2017-09-25 00:09:13 +02:00
{
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 ;
2021-10-08 22:50:52 +02:00
HandleBattleWindow ( 24 , 8 , 29 , 13 , WINDOW_CLEAR ) ;
2017-09-25 00:09:13 +02:00
}
2020-09-05 03:11:55 +02:00
else if ( JOY_NEW ( B_BUTTON ) )
2017-09-25 00:09:13 +02:00
{
PlaySE ( SE_SELECT ) ;
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2021-10-08 22:50:52 +02:00
HandleBattleWindow ( 24 , 8 , 29 , 13 , 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-02-06 02:46:59 +01:00
else if ( ! ( gHitMarker & HITMARKER_IGNORE_SUBSTITUTE ) | | ! ( gBattleMons [ gActiveBattler ] . status2 & STATUS2_SUBSTITUTE ) | | gDisableStructs [ gActiveBattler ] . substituteHP = = 0 )
2017-09-25 00:09:13 +02:00
{
2021-10-13 01:50:32 +02:00
BtlController_EmitHitAnimation ( BUFFER_A ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + = 2 ;
}
else
{
gBattlescriptCurrInstr + = 2 ;
}
}
static u32 GetTrainerMoneyToGive ( u16 trainerId )
{
u32 i = 0 ;
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
u32 lastMonLevel = 0 ;
2020-08-16 19:14:35 +02:00
u32 moneyReward ;
2017-09-25 00:09:13 +02:00
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 + + ;
}
2021-10-13 01:50:32 +02:00
// Command is never used
static void Cmd_updatebattlermoves ( 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 :
2021-10-13 01:50:32 +02:00
BtlController_EmitGetMonData ( BUFFER_A , REQUEST_ALL_BATTLE , 0 ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-25 00:09:13 +02:00
gBattleCommunication [ 0 ] + + ;
break ;
case 1 :
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-09-25 00:09:13 +02:00
{
s32 i ;
2018-06-30 14:12:17 +02:00
struct BattlePokemon * bufferPoke = ( struct BattlePokemon * ) & gBattleBufferB [ gActiveBattler ] [ 4 ] ;
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . moves [ i ] = bufferPoke - > moves [ i ] ;
gBattleMons [ gActiveBattler ] . pp [ i ] = bufferPoke - > pp [ i ] ;
2017-09-25 00:09:13 +02:00
}
gBattlescriptCurrInstr + = 2 ;
}
break ;
}
}
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 )
2021-09-24 20:30:15 +02:00
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 )
{
2018-12-05 15:31:01 +01:00
hpStatuses [ i ] . hp = 0xFFFF ;
2017-09-25 00:09:13 +02:00
hpStatuses [ i ] . status = 0 ;
}
else
{
hpStatuses [ i ] . hp = GetMonData ( & party [ i ] , MON_DATA_HP ) ;
hpStatuses [ i ] . status = GetMonData ( & party [ i ] , MON_DATA_STATUS ) ;
}
}
2021-10-13 01:50:32 +02:00
BtlController_EmitDrawPartyStatusSummary ( BUFFER_A , hpStatuses , 1 ) ;
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_hidepartystatussummary ( void )
2017-09-25 00:09:13 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2021-10-13 01:50:32 +02:00
BtlController_EmitHidePartyStatusSummary ( BUFFER_A ) ;
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 ) )
{
2021-10-13 01:50:32 +02:00
BtlController_EmitStatusAnimation ( BUFFER_A , FALSE , gBattleMons [ gActiveBattler ] . status1 ) ;
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_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 ) )
{
2021-10-13 01:50:32 +02:00
BtlController_EmitStatusAnimation ( BUFFER_A , TRUE , gBattleMons [ gActiveBattler ] . status2 & wantedToAnimate ) ;
2018-02-06 20:48:02 +01:00
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 ) )
{
2021-10-13 01:50:32 +02:00
BtlController_EmitStatusAnimation ( BUFFER_A , gBattlescriptCurrInstr [ 2 ] , wantedStatus ) ;
2018-02-06 20:48:02 +01:00
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 :
2021-10-08 22:50:52 +02:00
HandleBattleWindow ( 24 , 8 , 29 , 13 , 0 ) ;
BattlePutTextOnWindow ( gText_BattleYesNoChoice , B_WIN_YESNO ) ;
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 :
2020-09-05 03:11:55 +02:00
if ( JOY_NEW ( DPAD_UP ) & & gBattleCommunication [ CURSOR_POSITION ] ! = 0 )
2017-09-25 00:09:13 +02:00
{
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
}
2020-09-05 03:11:55 +02:00
if ( JOY_NEW ( DPAD_DOWN ) & & gBattleCommunication [ CURSOR_POSITION ] = = 0 )
2017-09-25 00:09:13 +02:00
{
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
}
2020-09-05 03:11:55 +02:00
if ( JOY_NEW ( B_BUTTON ) )
2017-09-25 00:09:13 +02:00
{
gBattleCommunication [ CURSOR_POSITION ] = 1 ;
PlaySE ( SE_SELECT ) ;
2021-10-08 22:50:52 +02:00
HandleBattleWindow ( 24 , 8 , 29 , 13 , WINDOW_CLEAR ) ;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr + + ;
}
2020-09-05 03:11:55 +02:00
else if ( JOY_NEW ( A_BUTTON ) )
2017-09-25 00:09:13 +02:00
{
PlaySE ( SE_SELECT ) ;
2021-10-08 22:50:52 +02:00
HandleBattleWindow ( 24 , 8 , 29 , 13 , 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-08-23 14:46:21 +02:00
static void Cmd_adjustsetdamage ( void ) // The same as adjustnormaldamage, except there's no random damage multiplier.
2017-09-25 00:09:13 +02:00
{
2018-02-08 11:17:41 +01:00
u8 holdEffect , param ;
2017-09-25 00:09:13 +02:00
2021-12-10 18:41:54 +01:00
if ( gBattleMons [ gBattlerTarget ] . item = = ITEM_ENIGMA_BERRY_E_READER )
2017-09-25 00:09:13 +02:00
{
2018-02-08 11:17:41 +01:00
holdEffect = gEnigmaBerries [ gBattlerTarget ] . holdEffect ;
param = gEnigmaBerries [ gBattlerTarget ] . holdEffectParam ;
2017-09-25 00:09:13 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ gBattlerTarget ] . item ) ;
2018-02-08 11:17:41 +01:00
param = ItemId_GetHoldEffectParam ( gBattleMons [ gBattlerTarget ] . item ) ;
2017-09-25 00:09:13 +02:00
}
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerTarget ;
2017-09-25 00:09:13 +02:00
2018-02-08 11:17:41 +01:00
if ( holdEffect = = HOLD_EFFECT_FOCUS_BAND & & ( Random ( ) % 100 ) < param )
2017-09-25 00:09:13 +02:00
{
2018-02-06 23:09:39 +01:00
RecordItemEffectBattle ( gBattlerTarget , holdEffect ) ;
gSpecialStatuses [ gBattlerTarget ] . focusBanded = 1 ;
2017-09-25 00:09:13 +02:00
}
2019-08-28 00:06:17 +02:00
if ( ! ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_SUBSTITUTE )
& & ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_FALSE_SWIPE | | gProtectStructs [ gBattlerTarget ] . endured | | gSpecialStatuses [ gBattlerTarget ] . focusBanded )
& & gBattleMons [ gBattlerTarget ] . hp < = gBattleMoveDamage )
2017-09-25 00:09:13 +02:00
{
2019-08-28 00:06:17 +02:00
gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . hp - 1 ;
if ( gProtectStructs [ gBattlerTarget ] . endured )
{
gMoveResultFlags | = MOVE_RESULT_FOE_ENDURED ;
}
else if ( gSpecialStatuses [ gBattlerTarget ] . focusBanded )
{
gMoveResultFlags | = MOVE_RESULT_FOE_HUNG_ON ;
gLastUsedItem = gBattleMons [ gBattlerTarget ] . item ;
}
2017-09-25 00:09:13 +02:00
}
2019-08-28 00:06:17 +02:00
gBattlescriptCurrInstr + + ;
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
{
u16 * usedHeldItem ;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-26 22:39:59 +02:00
2018-02-06 02:46:59 +01:00
usedHeldItem = & gBattleStruct - > usedHeldItems [ gActiveBattler ] ;
* usedHeldItem = gBattleMons [ gActiveBattler ] . item ;
gBattleMons [ gActiveBattler ] . item = 0 ;
2017-09-26 22:39:59 +02:00
2021-10-13 01:50:32 +02:00
BtlController_EmitSetMonData ( BUFFER_A , REQUEST_HELDITEM_BATTLE , 0 , sizeof ( gBattleMons [ gActiveBattler ] . item ) , & gBattleMons [ gActiveBattler ] . item ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( 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
{
2018-02-06 23:09:39 +01:00
PREPARE_MON_NICK_BUFFER ( gBattleTextBuff1 , gBattlerAttacker , gBattlerPartyIndexes [ gBattlerAttacker ] )
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + + ;
}
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
{
2021-10-08 22:50:52 +02:00
// If the Pokémon getting exp is not in-battle then
// slide out a banner with their name and icon on it.
// Otherwise skip ahead.
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 :
2021-10-08 22:50:52 +02:00
// Start level up banner
gBattle_BG2_Y = 96 ;
2018-12-26 13:05:02 +01:00
SetBgAttribute ( 2 , BG_ATTR_PRIORITY , 0 ) ;
2017-09-26 22:39:59 +02:00
ShowBg ( 2 ) ;
2021-10-08 22:50:52 +02:00
InitLevelUpBanner ( ) ;
2019-08-23 14:46:21 +02:00
gBattleScripting . drawlvlupboxState = 2 ;
2017-09-26 22:39:59 +02:00
break ;
case 2 :
2021-10-08 22:50:52 +02:00
if ( ! SlideInLevelUpBanner ( ) )
2019-08-23 14:46:21 +02:00
gBattleScripting . drawlvlupboxState = 3 ;
2017-09-26 22:39:59 +02:00
break ;
case 3 :
2021-10-08 22:50:52 +02:00
// Init level up box
2017-09-26 22:39:59 +02:00
gBattle_BG1_X = 0 ;
2021-10-08 22:50:52 +02:00
gBattle_BG1_Y = 256 ;
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 ) ;
2021-10-08 22:50:52 +02:00
HandleBattleWindow ( 18 , 7 , 29 , 19 , WINDOW_BG1 ) ;
2019-08-23 14:46:21 +02:00
gBattleScripting . drawlvlupboxState = 4 ;
2017-09-26 22:39:59 +02:00
break ;
case 4 :
2021-10-08 22:50:52 +02:00
// Draw page 1 of level up box
2019-04-04 21:24:21 +02:00
DrawLevelUpWindow1 ( ) ;
2021-10-08 22:50:52 +02:00
PutWindowTilemap ( B_WIN_LEVEL_UP_BOX ) ;
2021-11-03 20:29:18 +01:00
CopyWindowToVram ( B_WIN_LEVEL_UP_BOX , COPYWIN_FULL ) ;
2019-08-23 14:46:21 +02:00
gBattleScripting . drawlvlupboxState + + ;
2017-09-26 22:39:59 +02:00
break ;
case 5 :
case 7 :
2021-10-08 22:50:52 +02:00
// Wait for draw after each page
2017-09-26 22:39:59 +02:00
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 )
{
2021-10-08 22:50:52 +02:00
// Draw page 2 of level up box
2017-09-26 22:39:59 +02:00
PlaySE ( SE_SELECT ) ;
2019-04-04 21:24:21 +02:00
DrawLevelUpWindow2 ( ) ;
2021-11-03 20:29:18 +01:00
CopyWindowToVram ( B_WIN_LEVEL_UP_BOX , COPYWIN_GFX ) ;
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 )
{
2021-10-08 22:50:52 +02:00
// Close level up box
2017-09-26 22:39:59 +02:00
PlaySE ( SE_SELECT ) ;
2021-10-08 22:50:52 +02:00
HandleBattleWindow ( 18 , 7 , 29 , 19 , WINDOW_BG1 | WINDOW_CLEAR ) ;
2019-08-23 14:46:21 +02:00
gBattleScripting . drawlvlupboxState + + ;
2017-09-26 22:39:59 +02:00
}
break ;
case 9 :
2021-10-08 22:50:52 +02:00
if ( ! SlideOutLevelUpBanner ( ) )
2017-09-26 22:39:59 +02:00
{
2021-10-08 22:50:52 +02:00
ClearWindowTilemap ( B_WIN_LEVEL_UP_BANNER ) ;
2021-11-03 20:29:18 +01:00
CopyWindowToVram ( B_WIN_LEVEL_UP_BANNER , COPYWIN_MAP ) ;
2017-09-26 22:39:59 +02:00
2021-10-08 22:50:52 +02:00
ClearWindowTilemap ( B_WIN_LEVEL_UP_BOX ) ;
2021-11-03 20:29:18 +01:00
CopyWindowToVram ( B_WIN_LEVEL_UP_BOX , COPYWIN_MAP ) ;
2017-09-26 22:39:59 +02:00
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 ) ;
2021-10-08 22:50:52 +02:00
DrawLevelUpWindowPg1 ( B_WIN_LEVEL_UP_BOX , 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 ) ;
2021-10-08 22:50:52 +02:00
DrawLevelUpWindowPg2 ( B_WIN_LEVEL_UP_BOX , currStats , TEXT_DYNAMIC_COLOR_5 , TEXT_DYNAMIC_COLOR_4 , TEXT_DYNAMIC_COLOR_6 ) ;
2017-09-26 22:39:59 +02:00
}
2021-10-08 22:50:52 +02:00
static void InitLevelUpBanner ( void )
2017-09-26 22:39:59 +02:00
{
gBattle_BG2_Y = 0 ;
2021-10-08 22:50:52 +02:00
gBattle_BG2_X = LEVEL_UP_BANNER_START ;
2017-09-26 22:39:59 +02:00
2021-10-08 22:50:52 +02:00
LoadPalette ( sLevelUpBanner_Pal , 0x60 , 0x20 ) ;
CopyToWindowPixelBuffer ( B_WIN_LEVEL_UP_BANNER , sLevelUpBanner_Gfx , 0 , 0 ) ;
PutWindowTilemap ( B_WIN_LEVEL_UP_BANNER ) ;
2021-11-03 20:29:18 +01:00
CopyWindowToVram ( B_WIN_LEVEL_UP_BANNER , COPYWIN_FULL ) ;
2017-09-26 22:39:59 +02:00
2021-10-08 22:50:52 +02:00
PutMonIconOnLvlUpBanner ( ) ;
2017-09-26 22:39:59 +02:00
}
2021-10-08 22:50:52 +02:00
static bool8 SlideInLevelUpBanner ( void )
2017-09-26 22:39:59 +02:00
{
if ( IsDma3ManagerBusyWithBgCopy ( ) )
return TRUE ;
2021-10-08 22:50:52 +02:00
if ( gBattle_BG2_X = = LEVEL_UP_BANNER_END )
2017-09-26 22:39:59 +02:00
return FALSE ;
2021-10-08 22:50:52 +02:00
if ( gBattle_BG2_X = = LEVEL_UP_BANNER_START )
DrawLevelUpBannerText ( ) ;
2017-09-26 22:39:59 +02:00
gBattle_BG2_X + = 8 ;
2021-10-08 22:50:52 +02:00
if ( gBattle_BG2_X > = LEVEL_UP_BANNER_END )
gBattle_BG2_X = LEVEL_UP_BANNER_END ;
2017-09-26 22:39:59 +02:00
2021-10-08 22:50:52 +02:00
return ( gBattle_BG2_X ! = LEVEL_UP_BANNER_END ) ;
2017-09-26 22:39:59 +02:00
}
2021-10-08 22:50:52 +02:00
static void DrawLevelUpBannerText ( 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 ;
2021-10-08 22:50:52 +02:00
printerTemplate . windowId = B_WIN_LEVEL_UP_BANNER ;
2021-10-30 22:47:37 +02:00
printerTemplate . fontId = FONT_SMALL ;
2018-11-06 17:44:48 +01:00
printerTemplate . x = 32 ;
printerTemplate . y = 0 ;
printerTemplate . currentX = 32 ;
printerTemplate . currentY = 0 ;
printerTemplate . letterSpacing = 0 ;
printerTemplate . lineSpacing = 0 ;
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
printerTemplate . unk = 0 ;
2018-11-06 17:44:48 +01:00
printerTemplate . fgColor = TEXT_COLOR_WHITE ;
printerTemplate . bgColor = TEXT_COLOR_TRANSPARENT ;
2021-04-10 04:39:34 +02:00
printerTemplate . shadowColor = TEXT_COLOR_DARK_GRAY ;
2018-11-06 17:44:48 +01:00
2021-11-03 23:29:18 +01:00
AddTextPrinter ( & printerTemplate , TEXT_SKIP_DRAW , NULL ) ;
2017-09-26 22:39:59 +02:00
txtPtr = gStringVar4 ;
2020-08-11 05:50:49 +02:00
* ( txtPtr ) + + = CHAR_EXTRA_SYMBOL ;
* ( txtPtr ) + + = CHAR_LV_2 ;
2017-09-26 22:39:59 +02:00
var = ( u32 ) ( txtPtr ) ;
txtPtr = ConvertIntToDecimalStringN ( txtPtr , monLevel , STR_CONV_MODE_LEFT_ALIGN , 3 ) ;
var = ( u32 ) ( txtPtr ) - var ;
2021-10-17 23:51:35 +02:00
txtPtr = StringFill ( txtPtr , CHAR_SPACER , 4 - var ) ;
2017-09-26 22:39:59 +02:00
if ( monGender ! = MON_GENDERLESS )
{
if ( monGender = = MON_MALE )
{
2021-10-08 22:50:52 +02:00
txtPtr = WriteColorChangeControlCode ( txtPtr , 0 , TEXT_DYNAMIC_COLOR_3 ) ;
txtPtr = WriteColorChangeControlCode ( txtPtr , 1 , TEXT_DYNAMIC_COLOR_4 ) ;
2017-09-26 22:39:59 +02:00
* ( txtPtr + + ) = CHAR_MALE ;
}
else
{
2021-10-08 22:50:52 +02:00
txtPtr = WriteColorChangeControlCode ( txtPtr , 0 , TEXT_DYNAMIC_COLOR_5 ) ;
txtPtr = WriteColorChangeControlCode ( txtPtr , 1 , TEXT_DYNAMIC_COLOR_6 ) ;
2017-09-26 22:39:59 +02:00
* ( txtPtr + + ) = CHAR_FEMALE ;
}
* ( txtPtr + + ) = EOS ;
}
2018-11-06 17:44:48 +01:00
printerTemplate . y = 10 ;
printerTemplate . currentY = 10 ;
2021-11-03 23:29:18 +01:00
AddTextPrinter ( & printerTemplate , TEXT_SKIP_DRAW , NULL ) ;
2017-09-26 22:39:59 +02:00
2021-11-03 20:29:18 +01:00
CopyWindowToVram ( B_WIN_LEVEL_UP_BANNER , COPYWIN_GFX ) ;
2017-09-26 22:39:59 +02:00
}
2021-10-08 22:50:52 +02:00
static bool8 SlideOutLevelUpBanner ( void )
2017-09-26 22:39:59 +02:00
{
2021-10-08 22:50:52 +02:00
if ( gBattle_BG2_X = = LEVEL_UP_BANNER_START )
2017-09-26 22:39:59 +02:00
return FALSE ;
2021-10-08 22:50:52 +02:00
if ( gBattle_BG2_X - 16 < LEVEL_UP_BANNER_START )
gBattle_BG2_X = LEVEL_UP_BANNER_START ;
2017-09-26 22:39:59 +02:00
else
gBattle_BG2_X - = 16 ;
2021-10-08 22:50:52 +02:00
return ( gBattle_BG2_X ! = LEVEL_UP_BANNER_START ) ;
2017-09-26 22:39:59 +02:00
}
2021-10-08 22:50:52 +02:00
# define sDestroy data[0]
# define sXOffset data[1]
2017-09-26 22:39:59 +02:00
2021-10-08 22:50:52 +02:00
static void PutMonIconOnLvlUpBanner ( 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 ;
2021-10-08 22:50:52 +02:00
iconSheet . tag = TAG_LVLUP_BANNER_MON_ICON ;
2017-09-26 22:39:59 +02:00
iconPal = GetValidMonIconPalettePtr ( species ) ;
iconPalSheet . data = iconPal ;
2021-10-08 22:50:52 +02:00
iconPalSheet . tag = TAG_LVLUP_BANNER_MON_ICON ;
2017-09-26 22:39:59 +02:00
LoadSpriteSheet ( & iconSheet ) ;
LoadSpritePalette ( & iconPalSheet ) ;
2021-10-08 22:50:52 +02:00
spriteId = CreateSprite ( & sSpriteTemplate_MonIconOnLvlUpBanner , 256 , 10 , 0 ) ;
2017-09-26 22:39:59 +02:00
gSprites [ spriteId ] . sDestroy = FALSE ;
2021-10-08 22:50:52 +02:00
gSprites [ spriteId ] . sXOffset = gBattle_BG2_X ;
2017-09-26 22:39:59 +02:00
}
2021-10-08 22:50:52 +02:00
static void SpriteCB_MonIconOnLvlUpBanner ( struct Sprite * sprite )
2017-09-26 22:39:59 +02:00
{
2021-10-08 22:50:52 +02:00
sprite - > x2 = sprite - > sXOffset - gBattle_BG2_X ;
2017-09-26 22:39:59 +02:00
2021-07-07 15:11:52 +02:00
if ( sprite - > x2 ! = 0 )
2017-09-26 22:39:59 +02:00
{
sprite - > sDestroy = TRUE ;
}
else if ( sprite - > sDestroy )
{
DestroySprite ( sprite ) ;
2021-10-08 22:50:52 +02:00
FreeSpriteTilesByTag ( TAG_LVLUP_BANNER_MON_ICON ) ;
FreeSpritePaletteByTag ( TAG_LVLUP_BANNER_MON_ICON ) ;
2017-09-26 22:39:59 +02:00
}
}
# undef sDestroy
2021-10-08 22:50:52 +02:00
# undef sXOffset
2017-09-26 22:39:59 +02:00
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-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2021-10-13 01:50:32 +02:00
BtlController_EmitSpriteInvisibility ( BUFFER_A , FALSE ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 2 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_recordlastability ( void )
2017-09-26 22:39:59 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2018-02-06 02:46:59 +01:00
RecordAbilityBattle ( gActiveBattler , gLastUsedAbility ) ;
2021-05-23 16:35:03 +02:00
# ifdef BUGFIX
// This command occupies two bytes (one for the command id, and one for the battler id parameter).
gBattlescriptCurrInstr + = 2 ;
# else
gBattlescriptCurrInstr + = 1 ;
# endif
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 ;
2021-02-12 20:54:11 +01:00
PokemonUseItemEffects ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ] ] , gLastUsedItem , gBattlerPartyIndexes [ gBattlerAttacker ] , 0 , TRUE ) ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 1 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_various ( void )
2017-09-26 22:39:59 +02:00
{
u8 side ;
s32 i ;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript ( gBattlescriptCurrInstr [ 1 ] ) ;
2017-09-26 22:39:59 +02:00
switch ( gBattlescriptCurrInstr [ 2 ] )
{
case VARIOUS_CANCEL_MULTI_TURN_MOVES :
2018-02-06 02:46:59 +01:00
CancelMultiTurnMoves ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
break ;
case VARIOUS_SET_MAGIC_COAT_TARGET :
2018-02-06 23:09:39 +01:00
gBattlerAttacker = gBattlerTarget ;
side = GetBattlerSide ( gBattlerAttacker ) ^ BIT_SIDE ;
2017-09-26 22:39:59 +02:00
if ( gSideTimers [ side ] . followmeTimer ! = 0 & & gBattleMons [ gSideTimers [ side ] . followmeTarget ] . hp ! = 0 )
2018-02-06 23:09:39 +01:00
gBattlerTarget = gSideTimers [ side ] . followmeTarget ;
2017-09-26 22:39:59 +02:00
else
2018-02-06 23:09:39 +01:00
gBattlerTarget = gActiveBattler ;
2017-09-26 22:39:59 +02:00
break ;
2017-11-25 18:42:31 +01:00
case VARIOUS_IS_RUNNING_IMPOSSIBLE :
2017-09-26 22:39:59 +02:00
gBattleCommunication [ 0 ] = IsRunningFromBattleImpossible ( ) ;
break ;
case VARIOUS_GET_MOVE_TARGET :
2021-10-04 16:21:03 +02:00
gBattlerTarget = GetMoveTarget ( gCurrentMove , NO_TARGET_OVERRIDE ) ;
2017-09-26 22:39:59 +02:00
break ;
2020-07-17 02:12:12 +02:00
case VARIOUS_GET_BATTLER_FAINTED :
2018-02-06 02:46:59 +01:00
if ( gHitMarker & HITMARKER_FAINTED ( gActiveBattler ) )
2020-07-17 02:12:12 +02:00
gBattleCommunication [ 0 ] = TRUE ;
2017-09-26 22:39:59 +02:00
else
2020-07-17 02:12:12 +02:00
gBattleCommunication [ 0 ] = FALSE ;
2017-09-26 22:39:59 +02:00
break ;
case VARIOUS_RESET_INTIMIDATE_TRACE_BITS :
2018-07-16 20:47:30 +02:00
gSpecialStatuses [ gActiveBattler ] . intimidatedMon = 0 ;
2018-02-06 02:46:59 +01:00
gSpecialStatuses [ gActiveBattler ] . traced = 0 ;
2017-09-26 22:39:59 +02:00
break ;
case VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP :
2018-02-07 22:53:40 +01:00
if ( gBattlerPartyIndexes [ 0 ] = = gBattleStruct - > expGetterMonId | | gBattlerPartyIndexes [ 2 ] = = gBattleStruct - > expGetterMonId )
2017-09-26 22:39:59 +02:00
{
u16 * choicedMove ;
2018-02-07 22:53:40 +01:00
if ( gBattlerPartyIndexes [ 0 ] = = gBattleStruct - > expGetterMonId )
2018-02-06 02:46:59 +01:00
gActiveBattler = 0 ;
2017-09-26 22:39:59 +02:00
else
2018-02-06 02:46:59 +01:00
gActiveBattler = 2 ;
2017-09-26 22:39:59 +02:00
2018-02-06 02:46:59 +01:00
choicedMove = & gBattleStruct - > choicedMove [ gActiveBattler ] ;
2017-09-26 22:39:59 +02:00
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-26 22:39:59 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gBattleMons [ gActiveBattler ] . moves [ i ] = = * choicedMove )
2017-09-26 22:39:59 +02:00
break ;
}
2018-12-25 18:50:15 +01:00
if ( i = = MAX_MON_MOVES )
2017-09-26 22:39:59 +02:00
* choicedMove = 0 ;
}
break ;
2021-09-24 20:30:15 +02:00
case VARIOUS_RESET_PLAYER_FAINTED :
2017-09-26 22:39:59 +02:00
if ( ! ( gBattleTypeFlags & ( BATTLE_TYPE_LINK | BATTLE_TYPE_DOUBLE ) )
& & gBattleTypeFlags & BATTLE_TYPE_TRAINER
& & gBattleMons [ 0 ] . hp ! = 0
& & gBattleMons [ 1 ] . hp ! = 0 )
{
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_PLAYER_FAINTED ;
2017-09-26 22:39:59 +02:00
}
break ;
2020-07-17 02:12:12 +02:00
case VARIOUS_PALACE_FLAVOR_TEXT :
// Try and print end-of-turn Battle Palace flavor text (e.g. "A glint appears in mon's eyes")
gBattleCommunication [ 0 ] = FALSE ; // whether or not msg should be printed
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = gActiveBattler = gBattleCommunication [ 1 ] ;
2020-07-17 02:12:12 +02:00
if ( ! ( gBattleStruct - > palaceFlags & gBitTable [ gActiveBattler ] )
2018-02-06 02:46:59 +01:00
& & gBattleMons [ gActiveBattler ] . maxHP / 2 > = gBattleMons [ gActiveBattler ] . hp
& & gBattleMons [ gActiveBattler ] . hp ! = 0
& & ! ( gBattleMons [ gActiveBattler ] . status1 & STATUS1_SLEEP ) )
2017-09-26 22:39:59 +02:00
{
2020-07-17 02:12:12 +02:00
gBattleStruct - > palaceFlags | = gBitTable [ gActiveBattler ] ;
gBattleCommunication [ 0 ] = TRUE ;
gBattleCommunication [ MULTISTRING_CHOOSER ] = sBattlePalaceNatureToFlavorTextId [ 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 ) ;
2021-09-24 20:30:15 +02:00
gHitMarker | = HITMARKER_PLAYER_FAINTED ;
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 ) ;
2021-09-24 20:30:15 +02:00
gHitMarker | = HITMARKER_PLAYER_FAINTED ;
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 :
2021-10-13 01:50:32 +02:00
BtlController_EmitYesNoBox ( BUFFER_A ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
break ;
2021-09-24 20:30:15 +02:00
case VARIOUS_DRAW_ARENA_REF_TEXT_BOX :
2019-02-08 16:41:36 +01:00
DrawArenaRefereeTextBox ( ) ;
2017-09-26 22:39:59 +02:00
break ;
2021-09-24 20:30:15 +02:00
case VARIOUS_ERASE_ARENA_REF_TEXT_BOX :
EraseArenaRefereeTextBox ( ) ;
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 ] ] ) ;
2021-10-08 22:50:52 +02:00
BattlePutTextOnWindow ( gDisplayedStringBattle , ARENA_WIN_JUDGEMENT_TEXT ) ;
2017-09-26 22:39:59 +02:00
break ;
2018-11-11 18:33:16 +01:00
case VARIOUS_ARENA_WAIT_STRING :
2021-10-08 22:50:52 +02:00
if ( IsTextPrinterActive ( ARENA_WIN_JUDGEMENT_TEXT ) )
2017-09-26 22:39:59 +02:00
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
{
2021-10-13 01:50:32 +02:00
BtlController_EmitReturnMonToBall ( BUFFER_A , FALSE ) ;
2018-02-06 20:48:02 +01:00
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
{
2021-10-13 01:50:32 +02:00
BtlController_EmitReturnMonToBall ( BUFFER_A , FALSE ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
}
}
break ;
2018-08-25 21:04:12 +02:00
case VARIOUS_VOLUME_DOWN :
2021-10-09 17:33:37 +02:00
m4aMPlayVolumeControl ( & gMPlayInfo_BGM , TRACKS_ALL , 0x55 ) ;
2017-09-26 22:39:59 +02:00
break ;
2018-08-25 21:04:12 +02:00
case VARIOUS_VOLUME_UP :
2021-10-09 17:33:37 +02:00
m4aMPlayVolumeControl ( & gMPlayInfo_BGM , TRACKS_ALL , 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 ;
2021-09-24 20:30:15 +02:00
case VARIOUS_PALACE_TRY_ESCAPE_STATUS :
if ( BattlePalace_TryEscapeStatus ( gActiveBattler ) )
2017-09-26 22:39:59 +02:00
return ;
break ;
case VARIOUS_SET_TELEPORT_OUTCOME :
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_PLAYER )
2018-01-16 22:12:38 +01:00
gBattleOutcome = B_OUTCOME_PLAYER_TELEPORTED ;
2017-09-26 22:39:59 +02:00
else
2018-02-08 00:35:13 +01:00
gBattleOutcome = B_OUTCOME_MON_TELEPORTED ;
2017-09-26 22:39:59 +02:00
break ;
case VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC :
2021-10-13 01:50:32 +02:00
BtlController_EmitPlayFanfareOrBGM ( BUFFER_A , MUS_VICTORY_TRAINER , TRUE ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
break ;
}
gBattlescriptCurrInstr + = 3 ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_setprotectlike ( void ) // protect and endure
2017-09-26 22:39:59 +02:00
{
bool8 notLastTurn = TRUE ;
2018-02-06 23:09:39 +01:00
u16 lastMove = gLastResultingMoves [ gBattlerAttacker ] ;
2017-09-26 22:39:59 +02:00
if ( lastMove ! = MOVE_PROTECT & & lastMove ! = MOVE_DETECT & & lastMove ! = MOVE_ENDURE )
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerAttacker ] . protectUses = 0 ;
2017-09-26 22:39:59 +02:00
2018-02-06 02:46:59 +01:00
if ( gCurrentTurnActionNumber = = ( gBattlersCount - 1 ) )
2017-09-26 22:39:59 +02:00
notLastTurn = FALSE ;
2018-02-06 23:09:39 +01:00
if ( sProtectSuccessRates [ gDisableStructs [ gBattlerAttacker ] . protectUses ] > = Random ( ) & & notLastTurn )
2017-09-26 22:39:59 +02:00
{
if ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_PROTECT )
{
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . protected = 1 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_PROTECTED_ITSELF ;
2017-09-26 22:39:59 +02:00
}
if ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_ENDURE )
{
2018-02-06 23:09:39 +01:00
gProtectStructs [ gBattlerAttacker ] . endured = 1 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_BRACED_ITSELF ;
2017-09-26 22:39:59 +02:00
}
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerAttacker ] . protectUses + + ;
2017-09-26 22:39:59 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerAttacker ] . protectUses = 0 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_PROTECT_FAILED ;
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 ;
2021-10-13 01:50:32 +02:00
BtlController_EmitHealthBarUpdate ( BUFFER_A , INSTANT_HP_BAR_DROP ) ;
2018-02-06 20:48:02 +01:00
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 ;
2021-10-13 01:50:32 +02:00
BtlController_EmitSetMonData ( BUFFER_A , REQUEST_HP_BATTLE , 0 , sizeof ( gBattleMons [ gActiveBattler ] . hp ) , & gBattleMons [ gActiveBattler ] . hp ) ;
2018-02-06 20:48:02 +01:00
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
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
{
2018-02-06 23:09:39 +01:00
for ( gBattlerTarget + + ; ; gBattlerTarget + + )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattlerTarget = = gBattlerAttacker )
2017-09-26 22:39:59 +02:00
continue ;
2018-02-06 23:09:39 +01:00
if ( ! ( gAbsentBattlerFlags & gBitTable [ gBattlerTarget ] ) )
2017-09-26 22:39:59 +02:00
break ;
}
2018-02-06 23:09:39 +01:00
if ( gBattlerTarget > = gBattlersCount )
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
else
gBattlescriptCurrInstr = jumpPtr ;
}
else
2017-11-25 18:42:31 +01:00
{
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
2017-11-25 18:42:31 +01:00
}
2017-09-26 22:39:59 +02:00
}
2019-08-23 13:55:36 +02:00
static void Cmd_tryhealhalfhealth ( void )
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
const u8 * failPtr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
2018-02-08 11:17:41 +01:00
if ( gBattlescriptCurrInstr [ 5 ] = = BS_ATTACKER )
2018-02-06 23:09:39 +01:00
gBattlerTarget = gBattlerAttacker ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . maxHP / 2 ;
2017-09-26 22:39:59 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleMoveDamage * = - 1 ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . hp = = gBattleMons [ gBattlerTarget ] . maxHP )
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = failPtr ;
else
gBattlescriptCurrInstr + = 6 ;
}
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 ;
u16 movesArray [ 4 ] ;
for ( i = 0 ; i < 3 ; i + + )
movesArray [ i ] = 0 ;
2018-02-06 02:46:59 +01:00
for ( validMovesCount = 0 , i = 0 ; i < gBattlersCount ; i + + )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( i ! = gBattlerAttacker )
2017-09-26 22:39:59 +02:00
{
2018-10-14 18:10:54 +02:00
move = * ( i * 2 + gBattlerAttacker * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 0 )
| ( * ( i * 2 + gBattlerAttacker * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 1 ) < < 8 ) ;
2017-09-26 22:39:59 +02:00
2018-12-05 15:31:01 +01:00
if ( move ! = 0 & & move ! = 0xFFFF )
2017-09-26 22:39:59 +02:00
{
movesArray [ validMovesCount ] = move ;
validMovesCount + + ;
}
}
}
2018-10-14 18:10:54 +02:00
move = * ( gBattleStruct - > lastTakenMove + gBattlerAttacker * 2 + 0 )
| ( * ( gBattleStruct - > lastTakenMove + gBattlerAttacker * 2 + 1 ) < < 8 ) ;
2017-09-26 22:39:59 +02:00
2018-12-05 15:31:01 +01:00
if ( move ! = 0 & & move ! = 0xFFFF )
2017-09-26 22:39:59 +02:00
{
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_ATTACKSTRING_PRINTED ;
2017-09-26 22:39:59 +02:00
gCurrentMove = move ;
2021-10-04 16:21:03 +02:00
gBattlerTarget = GetMoveTarget ( gCurrentMove , NO_TARGET_OVERRIDE ) ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = gBattleScriptsForMoveEffects [ gBattleMoves [ gCurrentMove ] . effect ] ;
}
else if ( validMovesCount )
{
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_ATTACKSTRING_PRINTED ;
2017-09-26 22:39:59 +02:00
i = Random ( ) % validMovesCount ;
gCurrentMove = movesArray [ i ] ;
2021-10-04 16:21:03 +02:00
gBattlerTarget = GetMoveTarget ( gCurrentMove , NO_TARGET_OVERRIDE ) ;
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
{
2021-09-30 12:08:20 +02:00
if ( gBattleWeather & B_WEATHER_RAIN )
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_WEATHER_FAILED ;
2017-09-26 22:39:59 +02:00
}
else
{
2021-09-30 12:08:20 +02:00
gBattleWeather = B_WEATHER_RAIN_TEMPORARY ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_STARTED_RAIN ;
2017-09-26 22:39:59 +02:00
gWishFutureKnock . weatherDuration = 5 ;
}
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 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_SIDE_STATUS_FAILED ;
2017-09-26 22:39:59 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gSideStatuses [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] | = SIDE_STATUS_REFLECT ;
gSideTimers [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] . reflectTimer = 5 ;
2018-02-07 22:53:40 +01:00
gSideTimers [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] . reflectBattlerId = gBattlerAttacker ;
2017-09-26 22:39:59 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE & & CountAliveMonsInBattle ( BATTLE_ALIVE_ATK_SIDE ) = = 2 )
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_SET_REFLECT_DOUBLE ;
2017-09-26 22:39:59 +02:00
else
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_SET_REFLECT_SINGLE ;
2017-09-26 22:39:59 +02:00
}
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 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_LEECH_SEED_MISS ;
2017-09-26 22:39:59 +02:00
}
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 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_LEECH_SEED_FAIL ;
2017-09-26 22:39:59 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerTarget ] | = gBattlerAttacker ;
gStatuses3 [ gBattlerTarget ] | = STATUS3_LEECHSEED ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_LEECH_SEED_SET ;
2017-09-26 22:39:59 +02:00
}
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 ;
}
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 ) ) )
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_REST_STATUSED ;
2017-09-26 22:39:59 +02:00
else
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_REST ;
2017-09-26 22:39:59 +02:00
2021-04-02 08:27:12 +02:00
gBattleMons [ gBattlerTarget ] . status1 = STATUS1_SLEEP_TURN ( 3 ) ;
2021-10-13 01:50:32 +02:00
BtlController_EmitSetMonData ( BUFFER_A , REQUEST_STATUS_BATTLE , 0 , sizeof ( gBattleMons [ gActiveBattler ] . status1 ) , & gBattleMons [ gActiveBattler ] . status1 ) ;
2018-02-06 20:48:02 +01:00
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-08-23 13:55:36 +02:00
static void Cmd_nop ( void )
2017-09-26 22:39:59 +02:00
{
gBattlescriptCurrInstr + + ;
}
2018-02-08 12:13:29 +01:00
bool8 UproarWakeUpCheck ( u8 battlerId )
2017-09-26 22:39:59 +02:00
{
s32 i ;
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-09-26 22:39:59 +02:00
{
2018-02-08 12:13:29 +01:00
if ( ! ( gBattleMons [ i ] . status2 & STATUS2_UPROAR ) | | gBattleMons [ battlerId ] . ability = = ABILITY_SOUNDPROOF )
2017-09-26 22:39:59 +02:00
continue ;
2018-02-06 02:46:59 +01:00
gBattleScripting . battler = i ;
2017-09-26 22:39:59 +02:00
2018-12-05 15:31:01 +01:00
if ( gBattlerTarget = = 0xFF )
2018-02-06 23:09:39 +01:00
gBattlerTarget = i ;
else if ( gBattlerTarget = = i )
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_CANT_SLEEP_UPROAR ;
2017-09-26 22:39:59 +02:00
else
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_UPROAR_KEPT_AWAKE ;
2017-09-26 22:39:59 +02:00
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 ) ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if ( UproarWakeUpCheck ( gBattlerTarget ) )
2017-09-26 22:39:59 +02:00
{
gBattlescriptCurrInstr = jumpPtr ;
}
2018-02-06 23:09:39 +01:00
else if ( gBattleMons [ gBattlerTarget ] . ability = = ABILITY_INSOMNIA
| | gBattleMons [ gBattlerTarget ] . ability = = ABILITY_VITAL_SPIRIT )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gLastUsedAbility = gBattleMons [ gBattlerTarget ] . ability ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_STAYED_AWAKE_USING ;
2017-09-26 22:39:59 +02:00
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
{
2018-02-06 23:09:39 +01:00
if ( gDisableStructs [ gBattlerAttacker ] . stockpileCounter = = 3 )
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_CANT_STOCKPILE ;
2017-09-26 22:39:59 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerAttacker ] . stockpileCounter + + ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
PREPARE_BYTE_NUMBER_BUFFER ( gBattleTextBuff1 , 1 , gDisableStructs [ gBattlerAttacker ] . stockpileCounter )
2017-09-26 22:39:59 +02:00
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_STOCKPILED ;
2017-09-26 22:39:59 +02:00
}
gBattlescriptCurrInstr + + ;
}
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
{
2021-04-02 08:27:12 +02:00
if ( gBattleCommunication [ MISS_TYPE ] ! = B_MSG_PROTECTED )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = CalculateBaseDamage ( & gBattleMons [ gBattlerAttacker ] , & gBattleMons [ gBattlerTarget ] , gCurrentMove ,
gSideStatuses [ GET_BATTLER_SIDE ( gBattlerTarget ) ] , 0 ,
0 , gBattlerAttacker , gBattlerTarget )
* gDisableStructs [ gBattlerAttacker ] . stockpileCounter ;
gBattleScripting . animTurn = gDisableStructs [ gBattlerAttacker ] . stockpileCounter ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if ( gProtectStructs [ gBattlerAttacker ] . helpingHand )
2017-09-26 22:39:59 +02:00
gBattleMoveDamage = gBattleMoveDamage * 15 / 10 ;
}
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerAttacker ] . stockpileCounter = 0 ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
}
}
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 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_SWALLOW_FAILED ;
2017-09-26 22:39:59 +02:00
}
2018-02-06 23:09:39 +01:00
else if ( gBattleMons [ gBattlerAttacker ] . maxHP = = gBattleMons [ gBattlerAttacker ] . hp )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerAttacker ] . stockpileCounter = 0 ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = jumpPtr ;
2018-02-06 23:09:39 +01:00
gBattlerTarget = gBattlerAttacker ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_SWALLOW_FULL_HP ;
2017-09-26 22:39:59 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . maxHP / ( 1 < < ( 3 - gDisableStructs [ gBattlerAttacker ] . stockpileCounter ) ) ;
2017-09-26 22:39:59 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleMoveDamage * = - 1 ;
2018-02-06 23:09:39 +01:00
gBattleScripting . animTurn = gDisableStructs [ gBattlerAttacker ] . stockpileCounter ;
gDisableStructs [ gBattlerAttacker ] . stockpileCounter = 0 ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
2018-02-06 23:09:39 +01:00
gBattlerTarget = gBattlerAttacker ;
2017-09-26 22:39:59 +02:00
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_negativedamage ( void )
2017-09-26 22:39:59 +02:00
{
gBattleMoveDamage = - ( gHpDealt / 2 ) ;
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = - 1 ;
gBattlescriptCurrInstr + + ;
}
2019-09-27 08:46:33 +02:00
# define STAT_BUFF_WORKED 0
# define STAT_BUFF_DIDNT_WORK 1
2019-03-30 12:37:18 +01:00
2017-11-26 11:55:17 +01:00
static u8 ChangeStatBuffs ( s8 statValue , u8 statId , u8 flags , const u8 * BS_ptr )
2017-09-26 22:39:59 +02:00
{
2017-11-26 11:55:17 +01:00
bool8 certain = FALSE ;
2017-09-26 22:39:59 +02:00
bool8 notProtectAffected = FALSE ;
u32 index ;
if ( flags & MOVE_EFFECT_AFFECTS_USER )
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2017-09-26 22:39:59 +02:00
else
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget ;
2017-09-26 22:39:59 +02:00
2021-09-24 20:30:15 +02:00
flags & = ~ MOVE_EFFECT_AFFECTS_USER ;
2017-09-26 22:39:59 +02:00
if ( flags & MOVE_EFFECT_CERTAIN )
certain + + ;
2021-09-24 20:30:15 +02:00
flags & = ~ MOVE_EFFECT_CERTAIN ;
2017-09-26 22:39:59 +02:00
2019-09-27 08:46:33 +02:00
if ( flags & STAT_BUFF_NOT_PROTECT_AFFECTED )
2017-09-26 22:39:59 +02:00
notProtectAffected + + ;
2021-09-24 20:30:15 +02:00
flags & = ~ STAT_BUFF_NOT_PROTECT_AFFECTED ;
2017-09-26 22:39:59 +02:00
PREPARE_STAT_BUFFER ( gBattleTextBuff1 , statId )
2018-08-11 23:00:16 +02:00
if ( statValue < = - 1 ) // Stat decrease.
2017-09-26 22:39:59 +02:00
{
2018-02-06 02:46:59 +01:00
if ( gSideTimers [ GET_BATTLER_SIDE ( gActiveBattler ) ] . mistTimer
2017-09-26 22:39:59 +02:00
& & ! certain & & gCurrentMove ! = MOVE_CURSE )
{
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
}
}
2019-09-27 08:46:33 +02:00
return STAT_BUFF_DIDNT_WORK ;
2017-09-26 22:39:59 +02:00
}
else if ( gCurrentMove ! = MOVE_CURSE
& & notProtectAffected ! = TRUE & & JumpIfMoveAffectedByProtect ( 0 ) )
{
gBattlescriptCurrInstr = BattleScript_ButItFailed ;
2019-09-27 08:46:33 +02:00
return STAT_BUFF_DIDNT_WORK ;
2017-09-26 22:39:59 +02:00
}
2018-02-06 02:46:59 +01:00
else if ( ( gBattleMons [ gActiveBattler ] . ability = = ABILITY_CLEAR_BODY
| | gBattleMons [ gActiveBattler ] . ability = = ABILITY_WHITE_SMOKE )
2017-09-26 22:39:59 +02:00
& & ! certain & & gCurrentMove ! = MOVE_CURSE )
{
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_AbilityNoStatLoss ;
2018-02-06 02:46:59 +01:00
gLastUsedAbility = gBattleMons [ gActiveBattler ] . ability ;
RecordAbilityBattle ( gActiveBattler , gLastUsedAbility ) ;
gSpecialStatuses [ gActiveBattler ] . statLowered = 1 ;
2017-09-26 22:39:59 +02:00
}
}
2019-09-27 08:46:33 +02:00
return STAT_BUFF_DIDNT_WORK ;
2017-09-26 22:39:59 +02:00
}
2018-02-06 02:46:59 +01:00
else if ( gBattleMons [ gActiveBattler ] . ability = = ABILITY_KEEN_EYE
2018-02-08 12:13:29 +01:00
& & ! certain & & statId = = STAT_ACC )
2017-09-26 22:39:59 +02:00
{
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 ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss ;
2018-02-06 02:46:59 +01:00
gLastUsedAbility = gBattleMons [ gActiveBattler ] . ability ;
RecordAbilityBattle ( gActiveBattler , gLastUsedAbility ) ;
2017-09-26 22:39:59 +02:00
}
2019-09-27 08:46:33 +02:00
return STAT_BUFF_DIDNT_WORK ;
2017-09-26 22:39:59 +02:00
}
2018-02-06 02:46:59 +01:00
else if ( gBattleMons [ gActiveBattler ] . ability = = ABILITY_HYPER_CUTTER
2018-02-08 12:13:29 +01:00
& & ! certain & & statId = = STAT_ATK )
2017-09-26 22:39:59 +02:00
{
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 ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss ;
2018-02-06 02:46:59 +01:00
gLastUsedAbility = gBattleMons [ gActiveBattler ] . ability ;
RecordAbilityBattle ( gActiveBattler , gLastUsedAbility ) ;
2017-09-26 22:39:59 +02:00
}
2019-09-27 08:46:33 +02:00
return STAT_BUFF_DIDNT_WORK ;
2017-09-26 22:39:59 +02:00
}
2018-02-06 02:46:59 +01:00
else if ( gBattleMons [ gActiveBattler ] . ability = = ABILITY_SHIELD_DUST & & flags = = 0 )
2017-09-26 22:39:59 +02:00
{
2019-09-27 08:46:33 +02:00
return STAT_BUFF_DIDNT_WORK ;
2017-09-26 22:39:59 +02:00
}
else // try to decrease
{
statValue = - GET_STAT_BUFF_VALUE ( statValue ) ;
gBattleTextBuff2 [ 0 ] = B_BUFF_PLACEHOLDER_BEGIN ;
index = 1 ;
if ( statValue = = - 2 )
{
gBattleTextBuff2 [ 1 ] = B_BUFF_STRING ;
2017-11-26 11:55:17 +01:00
gBattleTextBuff2 [ 2 ] = STRINGID_STATHARSHLY ;
gBattleTextBuff2 [ 3 ] = STRINGID_STATHARSHLY > > 8 ;
2017-09-26 22:39:59 +02:00
index = 4 ;
}
gBattleTextBuff2 [ index ] = B_BUFF_STRING ;
index + + ;
2017-11-26 11:55:17 +01:00
gBattleTextBuff2 [ index ] = STRINGID_STATFELL ;
2017-09-26 22:39:59 +02:00
index + + ;
2017-11-26 11:55:17 +01:00
gBattleTextBuff2 [ index ] = STRINGID_STATFELL > > 8 ;
2017-09-26 22:39:59 +02:00
index + + ;
gBattleTextBuff2 [ index ] = B_BUFF_EOS ;
2020-08-05 02:33:05 +02:00
if ( gBattleMons [ gActiveBattler ] . statStages [ statId ] = = MIN_STAT_STAGE )
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_STAT_WONT_DECREASE ;
2017-09-26 22:39:59 +02:00
else
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = ( gBattlerTarget = = gActiveBattler ) ; // B_MSG_ATTACKER_STAT_FELL or B_MSG_DEFENDER_STAT_FELL
2017-09-26 22:39:59 +02:00
}
}
else // stat increase
{
statValue = GET_STAT_BUFF_VALUE ( statValue ) ;
gBattleTextBuff2 [ 0 ] = B_BUFF_PLACEHOLDER_BEGIN ;
index = 1 ;
if ( statValue = = 2 )
{
gBattleTextBuff2 [ 1 ] = B_BUFF_STRING ;
2017-11-26 11:55:17 +01:00
gBattleTextBuff2 [ 2 ] = STRINGID_STATSHARPLY ;
gBattleTextBuff2 [ 3 ] = STRINGID_STATSHARPLY > > 8 ;
2017-09-26 22:39:59 +02:00
index = 4 ;
}
gBattleTextBuff2 [ index ] = B_BUFF_STRING ;
index + + ;
2017-11-26 11:55:17 +01:00
gBattleTextBuff2 [ index ] = STRINGID_STATROSE ;
2017-09-26 22:39:59 +02:00
index + + ;
2017-11-26 11:55:17 +01:00
gBattleTextBuff2 [ index ] = STRINGID_STATROSE > > 8 ;
2017-09-26 22:39:59 +02:00
index + + ;
gBattleTextBuff2 [ index ] = B_BUFF_EOS ;
2020-08-05 02:33:05 +02:00
if ( gBattleMons [ gActiveBattler ] . statStages [ statId ] = = MAX_STAT_STAGE )
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_STAT_WONT_INCREASE ;
2017-09-26 22:39:59 +02:00
else
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = ( gBattlerTarget = = gActiveBattler ) ; // B_MSG_ATTACKER_STAT_ROSE or B_MSG_DEFENDER_STAT_ROSE
2017-09-26 22:39:59 +02:00
}
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . statStages [ statId ] + = statValue ;
2020-08-05 02:33:05 +02:00
if ( gBattleMons [ gActiveBattler ] . statStages [ statId ] < MIN_STAT_STAGE )
gBattleMons [ gActiveBattler ] . statStages [ statId ] = MIN_STAT_STAGE ;
if ( gBattleMons [ gActiveBattler ] . statStages [ statId ] > MAX_STAT_STAGE )
gBattleMons [ gActiveBattler ] . statStages [ statId ] = MAX_STAT_STAGE ;
2017-09-26 22:39:59 +02:00
2021-04-02 08:27:12 +02:00
if ( gBattleCommunication [ MULTISTRING_CHOOSER ] = = B_MSG_STAT_WONT_INCREASE & & 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
2021-04-02 08:27:12 +02:00
if ( gBattleCommunication [ MULTISTRING_CHOOSER ] = = B_MSG_STAT_WONT_INCREASE & & ! ( flags & STAT_BUFF_ALLOW_PTR ) )
2019-09-27 08:46:33 +02:00
return STAT_BUFF_DIDNT_WORK ;
2017-09-26 22:39:59 +02:00
2019-09-27 08:46:33 +02:00
return STAT_BUFF_WORKED ;
2017-09-26 22:39:59 +02:00
}
2019-08-23 13:55:36 +02:00
static void Cmd_statbuffchange ( void )
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
const u8 * jumpPtr = T1_READ_PTR ( gBattlescriptCurrInstr + 2 ) ;
2019-09-27 08:46:33 +02:00
if ( ChangeStatBuffs ( gBattleScripting . statChanger & 0xF0 , GET_STAT_BUFF_ID ( gBattleScripting . statChanger ) , gBattlescriptCurrInstr [ 1 ] , jumpPtr ) = = STAT_BUFF_WORKED )
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 6 ;
}
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
{
2018-11-18 20:00:36 +01:00
for ( j = 0 ; j < NUM_BATTLE_STATS ; j + + )
2020-08-05 02:33:05 +02:00
gBattleMons [ i ] . statStages [ j ] = DEFAULT_STAT_STAGE ;
2017-09-26 22:39:59 +02:00
}
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 ;
2020-07-17 02:12:12 +02:00
gBattleMons [ gBattlerAttacker ] . status2 | = STATUS2_BIDE_TURN ( 2 ) ;
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
{
2018-02-06 23:09:39 +01:00
if ( ! ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_LOCK_CONFUSE ) )
2017-09-26 22:39:59 +02:00
gBattleCommunication [ MOVE_EFFECT_BYTE ] = ( MOVE_EFFECT_THRASH | MOVE_EFFECT_AFFECTS_USER ) ;
gBattlescriptCurrInstr + + ;
}
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 ;
}
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 + + ;
}
2017-12-02 00:03:46 +01:00
static bool8 TryDoForceSwitchOut ( void )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . level > = gBattleMons [ gBattlerTarget ] . level )
2017-09-26 22:39:59 +02:00
{
2021-10-13 01:50:32 +02:00
* ( gBattleStruct - > battlerPartyIndexes + gBattlerTarget ) = gBattlerPartyIndexes [ gBattlerTarget ] ;
2017-09-26 22:39:59 +02:00
}
else
{
u16 random = Random ( ) & 0xFF ;
2018-02-06 23:09:39 +01:00
if ( ( u32 ) ( ( random * ( gBattleMons [ gBattlerAttacker ] . level + gBattleMons [ gBattlerTarget ] . level ) > > 8 ) + 1 ) < = ( gBattleMons [ gBattlerTarget ] . level / 4 ) )
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
return FALSE ;
}
2021-10-13 01:50:32 +02:00
* ( gBattleStruct - > battlerPartyIndexes + gBattlerTarget ) = gBattlerPartyIndexes [ gBattlerTarget ] ;
2017-09-26 22:39:59 +02:00
}
2017-12-02 00:03:46 +01:00
gBattlescriptCurrInstr = BattleScript_SuccessForceOut ;
2017-09-26 22:39:59 +02:00
return TRUE ;
}
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 ;
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
2020-09-09 16:35:40 +02:00
s32 firstMonId ;
2020-09-09 20:38:04 +02:00
s32 lastMonId = 0 ; // + 1
2020-09-09 16:35:40 +02:00
s32 monsCount ;
2017-09-26 22:39:59 +02:00
struct Pokemon * party = NULL ;
s32 validMons = 0 ;
2020-09-09 16:35:40 +02:00
s32 minNeeded ;
2017-09-26 22:39:59 +02:00
if ( ( gBattleTypeFlags & BATTLE_TYPE_TRAINER ) )
{
2018-02-06 23:09:39 +01:00
if ( GetBattlerSide ( gBattlerTarget ) = = B_SIDE_PLAYER )
2017-09-26 22:39:59 +02:00
party = gPlayerParty ;
else
party = gEnemyParty ;
if ( ( gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER & & gBattleTypeFlags & BATTLE_TYPE_LINK )
2021-01-13 21:17:32 +01:00
| | ( gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER & & gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK )
2017-09-26 22:39:59 +02:00
| | ( 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 )
2021-01-13 21:17:32 +01:00
| | ( gBattleTypeFlags & BATTLE_TYPE_MULTI & & gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK ) )
2017-09-26 22:39:59 +02:00
{
2018-07-01 11:15:42 +02:00
if ( GetLinkTrainerFlankId ( GetBattlerMultiplayerId ( gBattlerTarget ) ) = = 1 )
2017-09-26 22:39:59 +02:00
{
firstMonId = 3 ;
lastMonId = 6 ;
}
else
{
firstMonId = 0 ;
lastMonId = 3 ;
}
monsCount = 3 ;
minNeeded = 1 ;
2018-02-08 12:13:29 +01:00
battler2PartyId = gBattlerPartyIndexes [ gBattlerTarget ] ;
battler1PartyId = gBattlerPartyIndexes [ gBattlerTarget ^ BIT_FLANK ] ;
2017-09-26 22:39:59 +02:00
}
else if ( gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS )
{
2018-02-06 23:09:39 +01:00
if ( GetBattlerSide ( gBattlerTarget ) = = B_SIDE_PLAYER )
2017-09-26 22:39:59 +02:00
{
firstMonId = 0 ;
lastMonId = 6 ;
monsCount = 6 ;
minNeeded = 2 ; // since there are two opponents, it has to be a double battle
}
else
{
2018-02-06 23:09:39 +01:00
if ( ( gBattlerTarget & BIT_FLANK ) ! = 0 )
2017-09-26 22:39:59 +02:00
{
firstMonId = 3 ;
lastMonId = 6 ;
}
else
{
firstMonId = 0 ;
lastMonId = 3 ;
}
monsCount = 3 ;
minNeeded = 1 ;
}
2018-02-08 12:13:29 +01:00
battler2PartyId = gBattlerPartyIndexes [ gBattlerTarget ] ;
battler1PartyId = gBattlerPartyIndexes [ gBattlerTarget ^ BIT_FLANK ] ;
2017-09-26 22:39:59 +02:00
}
else if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
{
firstMonId = 0 ;
lastMonId = 6 ;
monsCount = 6 ;
minNeeded = 2 ;
2018-02-08 12:13:29 +01:00
battler2PartyId = gBattlerPartyIndexes [ gBattlerTarget ] ;
battler1PartyId = gBattlerPartyIndexes [ gBattlerTarget ^ BIT_FLANK ] ;
2017-09-26 22:39:59 +02:00
}
else
{
firstMonId = 0 ;
lastMonId = 6 ;
monsCount = 6 ;
minNeeded = 1 ;
2018-02-08 12:13:29 +01:00
battler2PartyId = gBattlerPartyIndexes [ gBattlerTarget ] ; // there is only one pokemon out in single battles
battler1PartyId = gBattlerPartyIndexes [ gBattlerTarget ] ;
2017-09-26 22:39:59 +02:00
}
for ( i = firstMonId ; i < lastMonId ; i + + )
{
if ( GetMonData ( & party [ i ] , MON_DATA_SPECIES ) ! = SPECIES_NONE
& & ! GetMonData ( & party [ i ] , MON_DATA_IS_EGG )
& & GetMonData ( & party [ i ] , MON_DATA_HP ) ! = 0 )
{
validMons + + ;
}
}
if ( validMons < = minNeeded )
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
else
{
2017-12-02 00:03:46 +01:00
if ( TryDoForceSwitchOut ( ) )
2017-09-26 22:39:59 +02:00
{
do
{
2020-09-09 20:38:04 +02:00
do
{
i = Random ( ) % monsCount ;
i + = firstMonId ;
2020-10-26 05:17:26 +01:00
}
while ( i = = battler2PartyId | | i = = battler1PartyId ) ;
2020-09-09 20:38:04 +02:00
} while ( GetMonData ( & party [ i ] , MON_DATA_SPECIES ) = = SPECIES_NONE
2017-09-26 22:39:59 +02:00
| | GetMonData ( & party [ i ] , MON_DATA_IS_EGG ) = = TRUE
2020-10-26 05:17:26 +01:00
| | GetMonData ( & party [ i ] , MON_DATA_HP ) = = 0 ) ; //should be one while loop, but that doesn't match.
2017-09-26 22:39:59 +02:00
}
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 )
2021-01-13 21:17:32 +01:00
| | ( gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK & & gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER )
| | ( gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK & & gBattleTypeFlags & BATTLE_TYPE_MULTI ) )
2017-09-26 22:39:59 +02:00
{
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
{
2017-12-02 00:03:46 +01:00
TryDoForceSwitchOut ( ) ;
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
& & moveType ! = gBattleMons [ gBattlerAttacker ] . type2 )
2017-09-26 22:39:59 +02:00
{
break ;
}
}
if ( moveChecked = = validMoves )
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
else
{
do
{
2021-04-03 18:38:07 +02:00
while ( ( moveChecked = Random ( ) & ( MAX_MON_MOVES - 1 ) ) > = validMoves ) ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
moveType = gBattleMoves [ gBattleMons [ gBattlerAttacker ] . moves [ moveChecked ] ] . type ;
2017-09-26 22:39:59 +02:00
if ( moveType = = TYPE_MYSTERY )
{
2018-03-01 00:59:52 +01:00
if ( IS_BATTLER_OF_TYPE ( gBattlerAttacker , TYPE_GHOST ) )
2017-09-26 22:39:59 +02:00
moveType = TYPE_GHOST ;
else
moveType = TYPE_NORMAL ;
}
}
2018-02-06 23:09:39 +01:00
while ( moveType = = gBattleMons [ gBattlerAttacker ] . type1 | | moveType = = gBattleMons [ gBattlerAttacker ] . type2 ) ;
2017-09-26 22:39:59 +02:00
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE ( gBattlerAttacker , moveType ) ;
PREPARE_TYPE_BUFFER ( gBattleTextBuff1 , moveType ) ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_givepaydaymoney ( void )
2017-09-26 22:39:59 +02:00
{
2021-01-13 21:17:32 +01:00
if ( ! ( gBattleTypeFlags & ( BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK ) ) & & gPaydayMoney ! = 0 )
2017-09-26 22:39:59 +02:00
{
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 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_SIDE_STATUS_FAILED ;
2017-09-26 22:39:59 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gSideStatuses [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] | = SIDE_STATUS_LIGHTSCREEN ;
gSideTimers [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] . lightscreenTimer = 5 ;
2018-02-07 22:53:40 +01:00
gSideTimers [ GET_BATTLER_SIDE ( gBattlerAttacker ) ] . lightscreenBattlerId = gBattlerAttacker ;
2017-09-26 22:39:59 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE & & CountAliveMonsInBattle ( BATTLE_ALIVE_ATK_SIDE ) = = 2 )
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_SET_LIGHTSCREEN_DOUBLE ;
2017-09-26 22:39:59 +02:00
else
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_SET_LIGHTSCREEN_SINGLE ;
2017-09-26 22:39:59 +02:00
}
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 ;
2021-12-10 18:41:54 +01:00
if ( gBattleMons [ gBattlerTarget ] . item = = ITEM_ENIGMA_BERRY_E_READER )
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 )
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_KO_MISS ;
2017-09-26 22:39:59 +02:00
else
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_KO_UNAFFECTED ;
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
{
2021-09-30 12:08:20 +02:00
if ( gBattleWeather & B_WEATHER_SANDSTORM )
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_WEATHER_FAILED ;
2017-09-26 22:39:59 +02:00
}
else
{
2021-09-30 12:08:20 +02:00
gBattleWeather = B_WEATHER_SANDSTORM_TEMPORARY ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_STARTED_SANDSTORM ;
2017-09-26 22:39:59 +02:00
gWishFutureKnock . weatherDuration = 5 ;
}
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_weatherdamage ( void )
2017-09-26 22:39:59 +02:00
{
if ( WEATHER_HAS_EFFECT )
{
2021-09-30 12:08:20 +02:00
if ( gBattleWeather & B_WEATHER_SANDSTORM )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . type1 ! = TYPE_ROCK
& & gBattleMons [ gBattlerAttacker ] . type1 ! = TYPE_STEEL
& & gBattleMons [ gBattlerAttacker ] . type1 ! = TYPE_GROUND
& & gBattleMons [ gBattlerAttacker ] . type2 ! = TYPE_ROCK
& & gBattleMons [ gBattlerAttacker ] . type2 ! = TYPE_STEEL
& & gBattleMons [ gBattlerAttacker ] . type2 ! = TYPE_GROUND
& & gBattleMons [ gBattlerAttacker ] . ability ! = ABILITY_SAND_VEIL
& & ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_UNDERGROUND )
& & ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_UNDERWATER ) )
{
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . maxHP / 16 ;
2017-09-26 22:39:59 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
}
else
{
gBattleMoveDamage = 0 ;
}
}
2021-09-30 12:08:20 +02:00
if ( gBattleWeather & B_WEATHER_HAIL )
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
if ( ! IS_BATTLER_OF_TYPE ( gBattlerAttacker , TYPE_ICE )
2018-02-06 23:09:39 +01:00
& & ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_UNDERGROUND )
& & ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_UNDERWATER ) )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . maxHP / 16 ;
2017-09-26 22:39:59 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
}
else
{
gBattleMoveDamage = 0 ;
}
}
}
else
{
gBattleMoveDamage = 0 ;
}
2018-02-06 23:09:39 +01:00
if ( gAbsentBattlerFlags & gBitTable [ gBattlerAttacker ] )
2017-09-26 22:39:59 +02:00
gBattleMoveDamage = 0 ;
gBattlescriptCurrInstr + + ;
}
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 ] ) ;
2021-10-13 01:50:32 +02:00
BtlController_EmitStatusIconUpdate ( BUFFER_A , gBattleMons [ gActiveBattler ] . status1 , gBattleMons [ gActiveBattler ] . status2 ) ;
2018-02-06 20:48:02 +01:00
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
{
2021-10-13 01:50:32 +02:00
BtlController_EmitStatusIconUpdate ( BUFFER_A , gBattleMons [ gActiveBattler ] . status1 , gBattleMons [ gActiveBattler ] . status2 ) ;
2018-02-06 20:48:02 +01:00
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
{
2021-10-13 01:50:32 +02:00
BtlController_EmitStatusIconUpdate ( BUFFER_A , gBattleMons [ gActiveBattler ] . status1 , gBattleMons [ gActiveBattler ] . status2 ) ;
2018-02-06 20:48:02 +01:00
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 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_MIST_FAILED ;
2017-09-26 22:39:59 +02:00
}
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 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_SET_MIST ;
2017-09-26 22:39:59 +02:00
}
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 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_FOCUS_ENERGY_FAILED ;
2017-09-26 22:39:59 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 | = STATUS2_FOCUS_ENERGY ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_GETTING_PUMPED ;
2017-09-26 22:39:59 +02:00
}
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_transformdataexecution ( void )
2017-09-26 22:39:59 +02:00
{
2018-12-05 15:31:01 +01:00
gChosenMove = 0xFFFF ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + + ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_TRANSFORMED
| | gStatuses3 [ gBattlerTarget ] & STATUS3_SEMI_INVULNERABLE )
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_FAILED ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_TRANSFORM_FAILED ;
2017-09-26 22:39:59 +02:00
}
else
{
s32 i ;
u8 * battleMonAttacker , * battleMonTarget ;
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 | = STATUS2_TRANSFORMED ;
gDisableStructs [ gBattlerAttacker ] . disabledMove = 0 ;
2018-10-14 18:10:54 +02:00
gDisableStructs [ gBattlerAttacker ] . disableTimer = 0 ;
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerAttacker ] . transformedMonPersonality = gBattleMons [ gBattlerTarget ] . personality ;
2019-01-19 22:32:25 +01:00
gDisableStructs [ gBattlerAttacker ] . mimickedMoves = 0 ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
PREPARE_SPECIES_BUFFER ( gBattleTextBuff1 , gBattleMons [ gBattlerTarget ] . species )
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
battleMonAttacker = ( u8 * ) ( & gBattleMons [ gBattlerAttacker ] ) ;
battleMonTarget = ( u8 * ) ( & gBattleMons [ gBattlerTarget ] ) ;
2017-09-26 22:39:59 +02:00
for ( i = 0 ; i < offsetof ( struct BattlePokemon , pp ) ; i + + )
battleMonAttacker [ i ] = battleMonTarget [ i ] ;
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMoves [ gBattleMons [ gBattlerAttacker ] . moves [ i ] ] . pp < 5 )
gBattleMons [ gBattlerAttacker ] . pp [ i ] = gBattleMoves [ gBattleMons [ gBattlerAttacker ] . moves [ i ] ] . pp ;
2017-09-26 22:39:59 +02:00
else
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . pp [ i ] = 5 ;
2017-09-26 22:39:59 +02:00
}
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2021-10-13 01:50:32 +02:00
BtlController_EmitResetActionMoveSelection ( BUFFER_A , RESET_MOVE_SELECTION ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_TRANSFORMED ;
2017-09-26 22:39:59 +02:00
}
}
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 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_SUBSTITUTE_FAILED ;
2017-09-26 22:39:59 +02:00
}
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 ;
2021-09-24 20:30:15 +02:00
gBattleMons [ gBattlerAttacker ] . status2 & = ~ STATUS2_WRAPPED ;
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerAttacker ] . substituteHP = gBattleMoveDamage ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_SET_SUBSTITUTE ;
2017-09-26 22:39:59 +02:00
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
{
2018-12-05 15:31:01 +01:00
gChosenMove = 0xFFFF ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if ( IsMoveUncopyableByMimic ( gLastMoves [ gBattlerTarget ] )
| | gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_TRANSFORMED
| | gLastMoves [ gBattlerTarget ] = = 0
2018-12-05 15:31:01 +01:00
| | gLastMoves [ gBattlerTarget ] = = 0xFFFF )
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
else
{
2019-01-19 22:32:25 +01:00
int i ;
2017-09-26 22:39:59 +02:00
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . moves [ i ] = = gLastMoves [ gBattlerTarget ] )
2017-09-26 22:39:59 +02:00
break ;
}
2018-12-25 18:50:15 +01:00
if ( i = = MAX_MON_MOVES )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . moves [ gCurrMovePos ] = gLastMoves [ gBattlerTarget ] ;
if ( gBattleMoves [ gLastMoves [ gBattlerTarget ] ] . pp < 5 )
gBattleMons [ gBattlerAttacker ] . pp [ gCurrMovePos ] = gBattleMoves [ gLastMoves [ gBattlerTarget ] ] . pp ;
2017-09-26 22:39:59 +02:00
else
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . pp [ gCurrMovePos ] = 5 ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , gLastMoves [ gBattlerTarget ] )
2017-09-26 22:39:59 +02:00
2019-01-19 22:32:25 +01:00
gDisableStructs [ gBattlerAttacker ] . mimickedMoves | = gBitTable [ gCurrMovePos ] ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
}
}
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
gCurrentMove = ( Random ( ) & 0x1FF ) + 1 ;
2018-06-30 18:55:34 +02:00
if ( gCurrentMove > = MOVES_COUNT )
2017-09-26 22:39:59 +02:00
continue ;
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + ) ; // ?
2017-09-26 22:39:59 +02:00
2017-11-11 22:58:23 +01:00
i = - 1 ;
while ( 1 )
2017-09-26 22:39:59 +02:00
{
2017-11-11 22:58:23 +01:00
i + + ;
if ( sMovesForbiddenToCopy [ i ] = = gCurrentMove )
2017-09-26 22:39:59 +02:00
break ;
2017-11-11 22:58:23 +01:00
if ( sMovesForbiddenToCopy [ i ] = = METRONOME_FORBIDDEN_END )
2017-09-26 22:39:59 +02:00
break ;
}
2017-11-11 22:58:23 +01:00
if ( sMovesForbiddenToCopy [ i ] = = METRONOME_FORBIDDEN_END )
{
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_ATTACKSTRING_PRINTED ;
2017-11-11 22:58:23 +01:00
gBattlescriptCurrInstr = gBattleScriptsForMoveEffects [ gBattleMoves [ gCurrentMove ] . effect ] ;
2021-10-04 16:21:03 +02:00
gBattlerTarget = GetMoveTarget ( gCurrentMove , NO_TARGET_OVERRIDE ) ;
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 ;
2021-10-08 22:50:52 +02:00
while ( ( randDamage = Random ( ) % 16 ) > 10 ) ;
2017-09-26 22:39:59 +02:00
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-08-23 13:55:36 +02:00
static void Cmd_mirrorcoatdamagecalculator ( void ) // a copy of Cmd 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 ;
2018-10-14 18:10:54 +02:00
gDisableStructs [ gBattlerTarget ] . encoreTimer = ( Random ( ) & 3 ) + 3 ;
gDisableStructs [ gBattlerTarget ] . encoreTimerStartValue = gDisableStructs [ gBattlerTarget ] . encoreTimer ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_painsplitdmgcalc ( void )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( ! ( gBattleMons [ gBattlerTarget ] . status2 & STATUS2_SUBSTITUTE ) )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
s32 hpDiff = ( gBattleMons [ gBattlerAttacker ] . hp + gBattleMons [ gBattlerTarget ] . hp ) / 2 ;
s32 painSplitHp = gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . hp - hpDiff ;
2017-09-26 22:39:59 +02:00
u8 * storeLoc = ( void * ) ( & gBattleScripting . painSplitHp ) ;
storeLoc [ 0 ] = ( painSplitHp ) ;
storeLoc [ 1 ] = ( painSplitHp & 0x0000FF00 ) > > 8 ;
storeLoc [ 2 ] = ( painSplitHp & 0x00FF0000 ) > > 16 ;
storeLoc [ 3 ] = ( painSplitHp & 0xFF000000 ) > > 24 ;
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerAttacker ] . hp - hpDiff ;
2018-12-05 15:31:01 +01:00
gSpecialStatuses [ gBattlerTarget ] . dmg = 0xFFFF ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_settypetorandomresistance ( void ) // conversion 2
2017-09-26 22:39:59 +02:00
{
2021-10-08 22:50:52 +02:00
if ( gLastLandedMoves [ gBattlerAttacker ] = = MOVE_NONE
| | gLastLandedMoves [ gBattlerAttacker ] = = 0xFFFF )
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
2018-02-06 23:09:39 +01:00
else if ( IsTwoTurnsMove ( gLastLandedMoves [ gBattlerAttacker ] )
& & gBattleMons [ gLastHitBy [ gBattlerAttacker ] ] . status2 & STATUS2_MULTIPLETURNS )
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
else
{
2017-11-11 20:01:04 +01:00
s32 i , j , rands ;
for ( rands = 0 ; rands < 1000 ; rands + + )
2017-09-26 22:39:59 +02:00
{
2021-10-08 22:50:52 +02:00
while ( ( ( i = Random ( ) % 128 ) > sizeof ( gTypeEffectiveness ) / 3 ) ) ;
2017-09-26 22:39:59 +02:00
2017-11-11 20:01:04 +01:00
i * = 3 ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( i ) = = gLastHitByType [ gBattlerAttacker ]
2017-11-11 20:01:04 +01:00
& & TYPE_EFFECT_MULTIPLIER ( i ) < = TYPE_MUL_NOT_EFFECTIVE
2018-03-01 00:59:52 +01:00
& & ! IS_BATTLER_OF_TYPE ( gBattlerAttacker , TYPE_EFFECT_DEF_TYPE ( i ) ) )
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE ( gBattlerAttacker , TYPE_EFFECT_DEF_TYPE ( i ) ) ;
PREPARE_TYPE_BUFFER ( gBattleTextBuff1 , TYPE_EFFECT_DEF_TYPE ( i ) ) ;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
return ;
}
2017-11-11 20:01:04 +01:00
}
2017-09-26 22:39:59 +02:00
2017-11-11 20:01:04 +01:00
for ( j = 0 , rands = 0 ; rands < sizeof ( gTypeEffectiveness ) ; j + = 3 , rands + = 3 )
2017-09-26 22:39:59 +02:00
{
2017-11-11 20:01:04 +01:00
switch ( TYPE_EFFECT_ATK_TYPE ( j ) )
2017-09-26 22:39:59 +02:00
{
2017-11-11 20:01:04 +01:00
case TYPE_ENDTABLE :
case TYPE_FORESIGHT :
break ;
default :
2018-02-06 23:09:39 +01:00
if ( TYPE_EFFECT_ATK_TYPE ( j ) = = gLastHitByType [ gBattlerAttacker ]
& & TYPE_EFFECT_MULTIPLIER ( j ) < = 5
2018-03-01 00:59:52 +01:00
& & ! IS_BATTLER_OF_TYPE ( gBattlerAttacker , TYPE_EFFECT_DEF_TYPE ( i ) ) )
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE ( gBattlerAttacker , TYPE_EFFECT_DEF_TYPE ( rands ) ) ;
2017-11-11 20:01:04 +01:00
PREPARE_TYPE_BUFFER ( gBattleTextBuff1 , TYPE_EFFECT_DEF_TYPE ( rands ) )
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
return ;
}
2017-11-11 20:01:04 +01:00
break ;
2017-09-26 22:39:59 +02:00
}
2017-11-11 20:01:04 +01:00
}
2017-09-26 22:39:59 +02:00
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_setalwayshitflag ( void )
2017-09-26 22:39:59 +02:00
{
2021-09-24 20:30:15 +02:00
gStatuses3 [ gBattlerTarget ] & = ~ STATUS3_ALWAYS_HITS ;
2020-07-17 02:12:12 +02:00
gStatuses3 [ gBattlerTarget ] | = STATUS3_ALWAYS_HITS_TURN ( 2 ) ;
2018-02-06 23:09:39 +01:00
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
{
2018-12-05 15:31:01 +01:00
gChosenMove = 0xFFFF ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if ( ! ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_TRANSFORMED )
& & gLastPrintedMoves [ gBattlerTarget ] ! = MOVE_STRUGGLE
& & gLastPrintedMoves [ gBattlerTarget ] ! = 0
2018-12-05 15:31:01 +01:00
& & gLastPrintedMoves [ gBattlerTarget ] ! = 0xFFFF
2018-02-06 23:09:39 +01:00
& & gLastPrintedMoves [ gBattlerTarget ] ! = MOVE_SKETCH )
2017-09-26 22:39:59 +02:00
{
s32 i ;
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . moves [ i ] = = MOVE_SKETCH )
2017-09-26 22:39:59 +02:00
continue ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . moves [ i ] = = gLastPrintedMoves [ gBattlerTarget ] )
2017-09-26 22:39:59 +02:00
break ;
}
2018-12-25 18:50:15 +01:00
if ( i ! = MAX_MON_MOVES )
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
else // sketch worked
{
struct MovePpInfo movePpData ;
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . moves [ gCurrMovePos ] = gLastPrintedMoves [ gBattlerTarget ] ;
gBattleMons [ gBattlerAttacker ] . pp [ gCurrMovePos ] = gBattleMoves [ gLastPrintedMoves [ gBattlerTarget ] ] . pp ;
gActiveBattler = gBattlerAttacker ;
2017-09-26 22:39:59 +02:00
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
movePpData . moves [ i ] = gBattleMons [ gBattlerAttacker ] . moves [ i ] ;
movePpData . pp [ i ] = gBattleMons [ gBattlerAttacker ] . pp [ i ] ;
2017-09-26 22:39:59 +02:00
}
2018-02-06 23:09:39 +01:00
movePpData . ppBonuses = gBattleMons [ gBattlerAttacker ] . ppBonuses ;
2017-09-26 22:39:59 +02:00
2021-10-13 01:50:32 +02:00
BtlController_EmitSetMonData ( BUFFER_A , REQUEST_MOVES_PP_BATTLE , 0 , sizeof ( movePpData ) , & movePpData ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , gLastPrintedMoves [ gBattlerTarget ] )
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr + = 5 ;
}
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-26 22:39:59 +02:00
}
}
2017-09-28 15:34:21 +02:00
static bool8 IsTwoTurnsMove ( u16 move )
2017-09-27 23:43:45 +02:00
{
if ( gBattleMoves [ move ] . effect = = EFFECT_SKULL_BASH
| | gBattleMoves [ move ] . effect = = EFFECT_RAZOR_WIND
| | gBattleMoves [ move ] . effect = = EFFECT_SKY_ATTACK
2021-11-01 22:36:35 +01:00
| | gBattleMoves [ move ] . effect = = EFFECT_SOLAR_BEAM
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
2021-11-01 22:36:35 +01:00
if ( gBattleMoves [ move ] . effect = = EFFECT_SOLAR_BEAM
2021-09-30 12:08:20 +02:00
& & ( gBattleWeather & B_WEATHER_SUN ) )
2017-09-27 23:43:45 +02:00
return 2 ;
if ( gBattleMoves [ move ] . effect = = EFFECT_SKULL_BASH
| | gBattleMoves [ move ] . effect = = EFFECT_RAZOR_WIND
| | gBattleMoves [ move ] . effect = = EFFECT_SKY_ATTACK
2021-11-01 22:36:35 +01:00
| | gBattleMoves [ move ] . effect = = EFFECT_SOLAR_BEAM
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 ] ;
}
}
2021-09-24 20:30:15 +02:00
unusableMovesBits = CheckMoveLimitations ( gBattlerAttacker , unusableMovesBits , ~ MOVE_LIMITATION_PP ) ;
2021-10-08 22:50:52 +02:00
if ( unusableMovesBits = = ( 1 < < MAX_MON_MOVES ) - 1 ) // all 4 moves cannot be chosen
2017-09-27 23:43:45 +02:00
{
gBattlescriptCurrInstr + = 5 ;
}
else // at least one move can be chosen
{
u32 movePosition ;
do
{
2021-04-03 18:38:07 +02:00
movePosition = Random ( ) & ( MAX_MON_MOVES - 1 ) ;
2017-09-27 23:43:45 +02:00
} 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 ;
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_ATTACKSTRING_PRINTED ;
2021-10-04 16:21:03 +02:00
gBattlerTarget = GetMoveTarget ( gCalledMove , NO_TARGET_OVERRIDE ) ;
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-08-23 13:55:36 +02:00
static void Cmd_remaininghptopower ( void )
2017-09-27 23:43:45 +02:00
{
s32 i ;
2018-02-06 23:09:39 +01:00
s32 hpFraction = GetScaledHPFraction ( gBattleMons [ gBattlerAttacker ] . hp , gBattleMons [ gBattlerAttacker ] . maxHP , 48 ) ;
2017-09-27 23:43:45 +02:00
for ( i = 0 ; i < ( s32 ) sizeof ( sFlailHpScaleToPowerTable ) ; i + = 2 )
{
if ( hpFraction < = sFlailHpScaleToPowerTable [ i ] )
break ;
}
gDynamicBasePower = sFlailHpScaleToPowerTable [ i + 1 ] ;
gBattlescriptCurrInstr + + ;
}
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
2018-12-05 15:31:01 +01:00
& & gLastMoves [ gBattlerTarget ] ! = 0xFFFF )
2017-09-27 23:43:45 +02:00
{
s32 i ;
2018-12-25 18:50:15 +01:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gLastMoves [ gBattlerTarget ] = = gBattleMons [ gBattlerTarget ] . moves [ i ] )
2017-09-27 23:43:45 +02:00
break ;
}
2018-12-25 18:50:15 +01:00
if ( i ! = MAX_MON_MOVES & & gBattleMons [ gBattlerTarget ] . pp [ i ] > 1 )
2017-09-27 23:43:45 +02:00
{
s32 ppToDeduct = ( Random ( ) & 3 ) + 2 ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerTarget ] . pp [ i ] < ppToDeduct )
ppToDeduct = gBattleMons [ gBattlerTarget ] . pp [ i ] ;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
PREPARE_MOVE_BUFFER ( gBattleTextBuff1 , gLastMoves [ gBattlerTarget ] )
2017-09-27 23:43:45 +02:00
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
2021-10-12 02:49:56 +02:00
// if (MOVE_IS_PERMANENT(gActiveBattler, i)), but backwards
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
{
2021-10-13 01:50:32 +02:00
BtlController_EmitSetMonData ( BUFFER_A , REQUEST_PPMOVE1_BATTLE + i , 0 , sizeof ( gBattleMons [ gActiveBattler ] . pp [ i ] ) , & gBattleMons [ gActiveBattler ] . pp [ i ] ) ;
2018-02-06 20:48:02 +01:00
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 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_BELL ;
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 [ gBattlerAttacker ] . ability ! = ABILITY_SOUNDPROOF )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status1 = 0 ;
2021-09-24 20:30:15 +02:00
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 ) ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] | = B_MSG_BELL_SOUNDPROOF_ATTACKER ;
2017-09-27 23:43:45 +02:00
}
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 ;
2021-09-24 20:30:15 +02:00
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 ) ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] | = B_MSG_BELL_SOUNDPROOF_PARTNER ;
2017-09-27 23:43:45 +02:00
}
}
2021-04-02 08:27:12 +02:00
// Because the above MULTISTRING_CHOOSER are ORd, if both are set then it will be B_MSG_BELL_BOTH_SOUNDPROOF
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
{
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_SOOTHING_AROMA ;
2021-10-08 22:50:52 +02:00
toHeal = ( 1 < < PARTY_SIZE ) - 1 ;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status1 = 0 ;
2021-09-24 20:30:15 +02:00
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 ;
2021-09-24 20:30:15 +02:00
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 ;
2021-10-13 01:50:32 +02:00
BtlController_EmitSetMonData ( BUFFER_A , REQUEST_STATUS_BATTLE , toHeal , sizeof ( zero ) , & zero ) ;
2018-02-06 20:48:02 +01:00
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-08-23 13:55:36 +02:00
static void Cmd_rolloutdamagecalculation ( void )
2017-09-27 23:43:45 +02:00
{
2018-01-16 22:12:38 +01:00
if ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
CancelMultiTurnMoves ( gBattlerAttacker ) ;
2017-11-25 18:42:31 +01:00
gBattlescriptCurrInstr = BattleScript_MoveMissedPause ;
2017-09-27 23:43:45 +02:00
}
else
{
s32 i ;
2018-02-06 23:09:39 +01:00
if ( ! ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_MULTIPLETURNS ) ) // first hit
2017-09-27 23:43:45 +02:00
{
2018-10-14 18:10:54 +02:00
gDisableStructs [ gBattlerAttacker ] . rolloutTimer = 5 ;
gDisableStructs [ gBattlerAttacker ] . rolloutTimerStartValue = 5 ;
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerAttacker ] . status2 | = STATUS2_MULTIPLETURNS ;
gLockedMoves [ gBattlerAttacker ] = gCurrentMove ;
2017-09-27 23:43:45 +02:00
}
2018-10-14 18:10:54 +02:00
if ( - - gDisableStructs [ gBattlerAttacker ] . rolloutTimer = = 0 ) // last hit
2017-09-27 23:43:45 +02:00
{
2021-09-24 20:30:15 +02:00
gBattleMons [ gBattlerAttacker ] . status2 & = ~ STATUS2_MULTIPLETURNS ;
2017-09-27 23:43:45 +02:00
}
gDynamicBasePower = gBattleMoves [ gCurrentMove ] . power ;
2018-10-14 18:10:54 +02:00
for ( i = 1 ; i < ( 5 - gDisableStructs [ gBattlerAttacker ] . rolloutTimer ) ; i + + )
2017-09-27 23:43:45 +02:00
gDynamicBasePower * = 2 ;
2018-02-06 23:09:39 +01:00
if ( gBattleMons [ gBattlerAttacker ] . status2 & STATUS2_DEFENSE_CURL )
2017-09-27 23:43:45 +02:00
gDynamicBasePower * = 2 ;
gBattlescriptCurrInstr + + ;
}
}
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
2020-08-05 02:33:05 +02:00
& & gBattleMons [ gBattlerTarget ] . statStages [ gBattlescriptCurrInstr [ 1 ] ] = = MAX_STAT_STAGE )
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_furycuttercalc ( void )
2017-09-27 23:43:45 +02:00
{
2018-01-16 22:12:38 +01:00
if ( gMoveResultFlags & MOVE_RESULT_NO_EFFECT )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerAttacker ] . furyCutterCounter = 0 ;
2017-11-25 18:42:31 +01:00
gBattlescriptCurrInstr = BattleScript_MoveMissedPause ;
2017-09-27 23:43:45 +02:00
}
else
{
s32 i ;
2018-02-06 23:09:39 +01:00
if ( gDisableStructs [ gBattlerAttacker ] . furyCutterCounter ! = 5 )
gDisableStructs [ gBattlerAttacker ] . furyCutterCounter + + ;
2017-09-27 23:43:45 +02:00
gDynamicBasePower = gBattleMoves [ gCurrentMove ] . power ;
2018-02-06 23:09:39 +01:00
for ( i = 1 ; i < gDisableStructs [ gBattlerAttacker ] . furyCutterCounter ; i + + )
2017-09-27 23:43:45 +02:00
gDynamicBasePower * = 2 ;
gBattlescriptCurrInstr + + ;
}
}
2021-03-25 18:26:22 +01:00
static void Cmd_friendshiptodamagecalculation ( void )
2017-09-27 23:43:45 +02:00
{
if ( gBattleMoves [ gCurrentMove ] . effect = = EFFECT_RETURN )
2018-02-06 23:09:39 +01:00
gDynamicBasePower = 10 * ( gBattleMons [ gBattlerAttacker ] . friendship ) / 25 ;
2017-09-27 23:43:45 +02:00
else // EFFECT_FRUSTRATION
2018-02-06 23:09:39 +01:00
gDynamicBasePower = 10 * ( 255 - gBattleMons [ gBattlerAttacker ] . friendship ) / 25 ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_presentdamagecalculation ( void )
2017-09-27 23:43:45 +02:00
{
s32 rand = Random ( ) & 0xFF ;
if ( rand < 102 )
gDynamicBasePower = 40 ;
else if ( rand < 178 )
gDynamicBasePower = 80 ;
else if ( rand < 204 )
gDynamicBasePower = 120 ;
else
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons [ gBattlerTarget ] . maxHP / 4 ;
2017-09-27 23:43:45 +02:00
if ( gBattleMoveDamage = = 0 )
gBattleMoveDamage = 1 ;
gBattleMoveDamage * = - 1 ;
}
if ( rand < 204 )
2017-11-25 18:42:31 +01:00
gBattlescriptCurrInstr = BattleScript_HitFromCritCalc ;
2018-02-06 23:09:39 +01:00
else if ( gBattleMons [ gBattlerTarget ] . maxHP = = gBattleMons [ gBattlerTarget ] . hp )
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr = BattleScript_AlreadyAtFullHp ;
else
{
2021-09-24 20:30:15 +02: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 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_SIDE_STATUS_FAILED ;
2017-09-27 23:43:45 +02:00
}
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 ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_SET_SAFEGUARD ;
2017-09-27 23:43:45 +02:00
}
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_magnitudedamagecalculation ( void )
2017-09-27 23:43:45 +02:00
{
s32 magnitude = Random ( ) % 100 ;
if ( magnitude < 5 )
{
gDynamicBasePower = 10 ;
magnitude = 4 ;
}
else if ( magnitude < 15 )
{
gDynamicBasePower = 30 ;
magnitude = 5 ;
}
else if ( magnitude < 35 )
{
gDynamicBasePower = 50 ;
magnitude = 6 ;
}
else if ( magnitude < 65 )
{
gDynamicBasePower = 70 ;
magnitude = 7 ;
}
else if ( magnitude < 85 )
{
gDynamicBasePower = 90 ;
magnitude = 8 ;
}
else if ( magnitude < 95 )
{
gDynamicBasePower = 110 ;
magnitude = 9 ;
}
else
{
gDynamicBasePower = 150 ;
magnitude = 10 ;
}
PREPARE_BYTE_NUMBER_BUFFER ( gBattleTextBuff1 , 2 , magnitude )
2018-02-06 23:09:39 +01:00
for ( gBattlerTarget = 0 ; gBattlerTarget < gBattlersCount ; gBattlerTarget + + )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gBattlerTarget = = gBattlerAttacker )
2017-09-27 23:43:45 +02:00
continue ;
2018-02-06 23:09:39 +01:00
if ( ! ( gAbsentBattlerFlags & gBitTable [ gBattlerTarget ] ) ) // a valid target was found
2017-09-27 23:43:45 +02:00
break ;
}
gBattlescriptCurrInstr + + ;
}
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 )
2020-03-18 02:11:14 +01:00
gActionsByTurnOrder [ i ] = B_ACTION_TRY_FINISH ;
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 ;
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_ATTACKSTRING_PRINTED ;
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_setsunny ( void )
2017-09-27 23:43:45 +02:00
{
2021-09-30 12:08:20 +02:00
if ( gBattleWeather & B_WEATHER_SUN )
2017-09-27 23:43:45 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_WEATHER_FAILED ;
2017-09-27 23:43:45 +02:00
}
else
{
2021-09-30 12:08:20 +02:00
gBattleWeather = B_WEATHER_SUN_TEMPORARY ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_STARTED_SUNLIGHT ;
2017-09-27 23:43:45 +02:00
gWishFutureKnock . weatherDuration = 5 ;
}
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 ;
2020-08-05 02:33:05 +02:00
if ( gBattleMons [ gBattlerAttacker ] . statStages [ STAT_ATK ] < MAX_STAT_STAGE
2018-02-06 23:09:39 +01:00
& & gBattleMons [ gBattlerAttacker ] . hp > halfHp )
2017-09-27 23:43:45 +02:00
{
2020-08-05 02:33:05 +02:00
gBattleMons [ gBattlerAttacker ] . statStages [ STAT_ATK ] = MAX_STAT_STAGE ;
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-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 ;
2021-09-24 20:30:15 +02:00
gBattleMons [ gBattlerAttacker ] . status2 & = ~ STATUS2_WRAPPED ;
2018-02-06 23:09:39 +01:00
gBattlerTarget = * ( gBattleStruct - > wrappedBy + gBattlerAttacker ) ;
2017-09-27 23:43:45 +02:00
gBattleTextBuff1 [ 0 ] = B_BUFF_PLACEHOLDER_BEGIN ;
gBattleTextBuff1 [ 1 ] = B_BUFF_MOVE ;
2018-02-06 23:09:39 +01:00
gBattleTextBuff1 [ 2 ] = * ( gBattleStruct - > wrappedMove + gBattlerAttacker * 2 + 0 ) ;
gBattleTextBuff1 [ 3 ] = * ( gBattleStruct - > wrappedMove + gBattlerAttacker * 2 + 1 ) ;
2017-09-27 23:43:45 +02:00
gBattleTextBuff1 [ 4 ] = B_BUFF_EOS ;
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_WrapFree ;
}
2018-02-06 23:09:39 +01:00
else if ( gStatuses3 [ gBattlerAttacker ] & STATUS3_LEECHSEED )
2017-09-27 23:43:45 +02:00
{
2021-09-24 20:30:15 +02:00
gStatuses3 [ gBattlerAttacker ] & = ~ STATUS3_LEECHSEED ;
gStatuses3 [ gBattlerAttacker ] & = ~ STATUS3_LEECHSEED_BATTLER ;
2017-09-27 23:43:45 +02:00
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_LeechSeedFree ;
}
2018-02-06 23:09:39 +01:00
else if ( gSideStatuses [ GetBattlerSide ( gBattlerAttacker ) ] & SIDE_STATUS_SPIKES )
2017-09-27 23:43:45 +02:00
{
2021-09-24 20:30:15 +02:00
gSideStatuses [ GetBattlerSide ( gBattlerAttacker ) ] & = ~ SIDE_STATUS_SPIKES ;
2018-02-06 23:09:39 +01:00
gSideTimers [ GetBattlerSide ( gBattlerAttacker ) ] . spikesAmount = 0 ;
2017-09-27 23:43:45 +02:00
BattleScriptPushCursor ( ) ;
gBattlescriptCurrInstr = BattleScript_SpikesFree ;
}
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 ;
2021-09-30 12:08:20 +02:00
else if ( gBattleWeather & B_WEATHER_SUN )
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-08-23 13:55:36 +02:00
static void Cmd_hiddenpowercalc ( void )
2017-09-27 23:43:45 +02:00
{
2021-10-04 16:21:03 +02:00
u8 powerBits = ( ( gBattleMons [ gBattlerAttacker ] . hpIV & 2 ) > > 1 )
| ( ( gBattleMons [ gBattlerAttacker ] . attackIV & 2 ) < < 0 )
| ( ( gBattleMons [ gBattlerAttacker ] . defenseIV & 2 ) < < 1 )
| ( ( gBattleMons [ gBattlerAttacker ] . speedIV & 2 ) < < 2 )
| ( ( gBattleMons [ gBattlerAttacker ] . spAttackIV & 2 ) < < 3 )
| ( ( gBattleMons [ gBattlerAttacker ] . spDefenseIV & 2 ) < < 4 ) ;
2017-09-27 23:43:45 +02:00
2021-10-04 16:21:03 +02:00
u8 typeBits = ( ( gBattleMons [ gBattlerAttacker ] . hpIV & 1 ) < < 0 )
| ( ( gBattleMons [ gBattlerAttacker ] . attackIV & 1 ) < < 1 )
| ( ( gBattleMons [ gBattlerAttacker ] . defenseIV & 1 ) < < 2 )
| ( ( gBattleMons [ gBattlerAttacker ] . speedIV & 1 ) < < 3 )
| ( ( gBattleMons [ gBattlerAttacker ] . spAttackIV & 1 ) < < 4 )
| ( ( gBattleMons [ gBattlerAttacker ] . spDefenseIV & 1 ) < < 5 ) ;
2017-09-27 23:43:45 +02:00
gDynamicBasePower = ( 40 * powerBits ) / 63 + 30 ;
2021-10-04 16:21:03 +02:00
// Subtract 3 instead of 1 below because 2 types are excluded (TYPE_NORMAL and TYPE_MYSTERY)
// The final + 1 skips past Normal, and the following conditional skips TYPE_MYSTERY
gBattleStruct - > dynamicMoveType = ( ( NUMBER_OF_MON_TYPES - 3 ) * typeBits ) / 63 + 1 ;
2018-03-01 15:02:44 +01:00
if ( gBattleStruct - > dynamicMoveType > = TYPE_MYSTERY )
2017-09-27 23:43:45 +02:00
gBattleStruct - > dynamicMoveType + + ;
2021-10-04 16:21:03 +02:00
gBattleStruct - > dynamicMoveType | = F_DYNAMIC_TYPE_1 | F_DYNAMIC_TYPE_2 ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + + ;
}
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-02-06 23:09:39 +01:00
if ( gBattlerTarget = = gBattlerAttacker )
2017-09-27 23:43:45 +02:00
continue ;
2018-02-06 23:09:39 +01:00
if ( ! ( gAbsentBattlerFlags & gBitTable [ gBattlerTarget ] ) )
2017-09-27 23:43:45 +02:00
break ;
}
gBattlescriptCurrInstr + + ;
}
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 ;
gWishFutureKnock . futureSightDmg [ gBattlerTarget ] = CalculateBaseDamage ( & gBattleMons [ gBattlerAttacker ] , & gBattleMons [ gBattlerTarget ] , gCurrentMove ,
gSideStatuses [ GET_BATTLER_SIDE ( gBattlerTarget ) ] , 0 ,
0 , gBattlerAttacker , gBattlerTarget ) ;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
if ( gProtectStructs [ gBattlerAttacker ] . helpingHand )
gWishFutureKnock . futureSightDmg [ gBattlerTarget ] = gWishFutureKnock . futureSightDmg [ gBattlerTarget ] * 15 / 10 ;
2017-09-27 23:43:45 +02:00
if ( gCurrentMove = = MOVE_DOOM_DESIRE )
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_DOOM_DESIRE ;
2017-09-27 23:43:45 +02:00
else
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_FUTURE_SIGHT ;
2017-09-27 23:43:45 +02:00
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 ] ;
2020-07-17 02:12:12 +02:00
for ( ; gBattleCommunication [ 0 ] < PARTY_SIZE ; gBattleCommunication [ 0 ] + + )
2017-09-27 23:43:45 +02:00
{
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 ;
}
2020-07-17 02:12:12 +02:00
if ( gBattleCommunication [ 0 ] < PARTY_SIZE )
2017-09-27 23:43:45 +02:00
{
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 ;
}
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_clearsemiinvulnerablebit ( void )
2017-09-27 23:43:45 +02:00
{
switch ( gCurrentMove )
{
case MOVE_FLY :
case MOVE_BOUNCE :
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] & = ~ STATUS3_ON_AIR ;
2017-09-27 23:43:45 +02:00
break ;
case MOVE_DIG :
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] & = ~ STATUS3_UNDERGROUND ;
2017-09-27 23:43:45 +02:00
break ;
case MOVE_DIVE :
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] & = ~ STATUS3_UNDERWATER ;
2017-09-27 23:43:45 +02:00
break ;
}
gBattlescriptCurrInstr + + ;
}
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
{
2021-09-30 12:08:20 +02:00
if ( gBattleWeather & B_WEATHER_HAIL )
2017-09-27 23:43:45 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags | = MOVE_RESULT_MISSED ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_WEATHER_FAILED ;
2017-09-27 23:43:45 +02:00
}
else
{
2021-09-30 12:08:20 +02:00
gBattleWeather = B_WEATHER_HAIL_TEMPORARY ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_STARTED_HAIL ;
2017-09-27 23:43:45 +02:00
gWishFutureKnock . weatherDuration = 5 ;
}
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_jumpifattackandspecialattackcannotfall ( void ) // memento
2017-09-27 23:43:45 +02:00
{
2020-08-05 02:33:05 +02:00
if ( gBattleMons [ gBattlerTarget ] . statStages [ STAT_ATK ] = = MIN_STAT_STAGE
& & gBattleMons [ gBattlerTarget ] . statStages [ STAT_SPATK ] = = MIN_STAT_STAGE
2021-04-02 08:27:12 +02:00
& & gBattleCommunication [ MISS_TYPE ] ! = B_MSG_PROTECTED )
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
gActiveBattler = gBattlerAttacker ;
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gBattleMons [ gActiveBattler ] . hp ;
2021-10-13 01:50:32 +02:00
BtlController_EmitHealthBarUpdate ( BUFFER_A , INSTANT_HP_BAR_DROP ) ;
2018-02-06 20:48:02 +01:00
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
{
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_ATTACKSTRING_PRINTED ;
2017-09-27 23:43:45 +02:00
gCurrentMove = sNaturePowerMoves [ gBattleTerrain ] ;
2021-10-04 16:21:03 +02:00
gBattlerTarget = GetMoveTarget ( gCurrentMove , NO_TARGET_OVERRIDE ) ;
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 ;
2021-10-13 01:50:32 +02:00
BtlController_EmitSetMonData ( BUFFER_A , REQUEST_STATUS_BATTLE , 0 , sizeof ( gBattleMons [ gActiveBattler ] . status1 ) , & gBattleMons [ gActiveBattler ] . status1 ) ;
2018-02-06 20:48:02 +01:00
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
{
2018-10-14 18:10:54 +02:00
gDisableStructs [ gBattlerTarget ] . tauntTimer = 2 ;
2018-02-06 23:09:39 +01:00
gDisableStructs [ gBattlerTarget ] . tauntTimer2 = 2 ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 5 ;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
}
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
2021-01-13 21:17:32 +01:00
| BATTLE_TYPE_RECORDED_LINK ) ) ) )
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 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
2021-01-13 21:17:32 +01:00
| BATTLE_TYPE_RECORDED_LINK ) )
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 )
2021-12-10 18:41:54 +01:00
| | gBattleMons [ gBattlerAttacker ] . item = = ITEM_ENIGMA_BERRY_E_READER
| | gBattleMons [ gBattlerTarget ] . item = = ITEM_ENIGMA_BERRY_E_READER
2018-02-06 23:09:39 +01:00
| | IS_ITEM_MAIL ( gBattleMons [ gBattlerAttacker ] . item )
| | IS_ITEM_MAIL ( gBattleMons [ gBattlerTarget ] . item ) )
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
// check if ability prevents swapping
2018-02-06 23:09:39 +01:00
else if ( gBattleMons [ gBattlerTarget ] . ability = = ABILITY_STICKY_HOLD )
2017-09-27 23:43:45 +02:00
{
gBattlescriptCurrInstr = BattleScript_StickyHoldActivates ;
2018-02-06 23:09:39 +01:00
gLastUsedAbility = gBattleMons [ gBattlerTarget ] . ability ;
RecordAbilityBattle ( gBattlerTarget , gLastUsedAbility ) ;
2017-09-27 23:43:45 +02:00
}
// took a while, but all checks passed and items can be safely swapped
else
{
u16 oldItemAtk , * newItemAtk ;
2018-02-06 23:09:39 +01:00
newItemAtk = & gBattleStruct - > changedItems [ gBattlerAttacker ] ;
oldItemAtk = gBattleMons [ gBattlerAttacker ] . item ;
* newItemAtk = gBattleMons [ gBattlerTarget ] . item ;
2017-09-27 23:43:45 +02:00
2021-10-13 01:50:32 +02:00
gBattleMons [ gBattlerAttacker ] . item = ITEM_NONE ;
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerTarget ] . item = oldItemAtk ;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
2021-10-13 01:50:32 +02:00
BtlController_EmitSetMonData ( BUFFER_A , REQUEST_HELDITEM_BATTLE , 0 , sizeof ( * newItemAtk ) , 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 ;
2021-10-13 01:50:32 +02:00
BtlController_EmitSetMonData ( BUFFER_A , REQUEST_HELDITEM_BATTLE , 0 , sizeof ( gBattleMons [ gBattlerTarget ] . item ) , & gBattleMons [ gBattlerTarget ] . item ) ;
2018-02-06 23:09:39 +01:00
MarkBattlerForControllerExec ( gBattlerTarget ) ;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gBattlerTarget ] ) + 0 ) = 0 ;
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gBattlerTarget ] ) + 1 ) = 0 ;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gBattlerAttacker ] ) + 0 ) = 0 ;
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gBattlerAttacker ] ) + 1 ) = 0 ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 5 ;
PREPARE_ITEM_BUFFER ( gBattleTextBuff1 , * newItemAtk )
PREPARE_ITEM_BUFFER ( gBattleTextBuff2 , oldItemAtk )
2021-10-13 01:50:32 +02:00
if ( oldItemAtk ! = ITEM_NONE & & * newItemAtk ! = ITEM_NONE )
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_ITEM_SWAP_BOTH ; // attacker's item -> <- target's item
2021-10-13 01:50:32 +02:00
else if ( oldItemAtk = = ITEM_NONE & & * newItemAtk ! = ITEM_NONE )
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_ITEM_SWAP_TAKEN ; // nothing -> <- target's item
2017-09-27 23:43:45 +02:00
else
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_ITEM_SWAP_GIVEN ; // attacker's item -> <- nothing
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-08-23 13:55:36 +02:00
static void Cmd_trysetroots ( void ) // ingrain
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gStatuses3 [ gBattlerAttacker ] & STATUS3_ROOTED )
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] | = STATUS3_ROOTED ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 5 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_doubledamagedealtifdamaged ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( ( gProtectStructs [ gBattlerAttacker ] . physicalDmg
2018-02-07 22:53:40 +01:00
& & gProtectStructs [ gBattlerAttacker ] . physicalBattlerId = = gBattlerTarget )
2018-02-06 23:09:39 +01:00
| | ( gProtectStructs [ gBattlerAttacker ] . specialDmg
2018-02-07 22:53:40 +01:00
& & gProtectStructs [ gBattlerAttacker ] . specialBattlerId = = gBattlerTarget ) )
2017-09-27 23:43:45 +02:00
{
gBattleScripting . dmgMultiplier = 2 ;
}
gBattlescriptCurrInstr + + ;
}
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
{
2020-07-17 02:12:12 +02:00
gStatuses3 [ gBattlerTarget ] | = STATUS3_YAWN_TURN ( 2 ) ;
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 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_scaledamagebyhealthratio ( void )
2017-09-27 23:43:45 +02:00
{
if ( gDynamicBasePower = = 0 )
{
u8 power = gBattleMoves [ gCurrentMove ] . power ;
2018-02-06 23:09:39 +01:00
gDynamicBasePower = gBattleMons [ gBattlerAttacker ] . hp * power / gBattleMons [ gBattlerAttacker ] . maxHP ;
2017-09-27 23:43:45 +02:00
if ( gDynamicBasePower = = 0 )
gDynamicBasePower = 1 ;
}
gBattlescriptCurrInstr + + ;
}
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
gBattlescriptCurrInstr + = 5 ;
}
}
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-02-08 12:13:29 +01:00
if ( battlerId = = gBattlersCount ) // In Generation 3 games, Imprison fails if the user doesn't share any moves with any of the foes
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_trysetgrudge ( void )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( gStatuses3 [ gBattlerAttacker ] & STATUS3_GRUDGE )
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] | = STATUS3_GRUDGE ;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr + = 5 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_weightdamagecalculation ( void )
2017-09-27 23:43:45 +02:00
{
s32 i ;
2018-12-05 15:31:01 +01:00
for ( i = 0 ; sWeightToDamageTable [ i ] ! = 0xFFFF ; i + = 2 )
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ( sWeightToDamageTable [ i ] > GetPokedexHeightWeight ( SpeciesToNationalPokedexNum ( gBattleMons [ gBattlerTarget ] . species ) , 1 ) )
2017-09-27 23:43:45 +02:00
break ;
}
2018-12-05 15:31:01 +01:00
if ( sWeightToDamageTable [ i ] ! = 0xFFFF )
2017-09-27 23:43:45 +02:00
gDynamicBasePower = sWeightToDamageTable [ i + 1 ] ;
else
gDynamicBasePower = 120 ;
gBattlescriptCurrInstr + + ;
}
2019-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 ;
2020-07-17 02:12:12 +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 )
{
2021-09-24 20:30:15 +02:00
gHitMarker & = ~ HITMARKER_ATTACKSTRING_PRINTED ;
2018-09-22 18:41:00 +02:00
gCalledMove = movesArray [ ( ( Random ( ) & 0xFF ) * chooseableMovesNo ) > > 8 ] ;
2021-10-04 16:21:03 +02:00
gBattlerTarget = GetMoveTarget ( gCalledMove , NO_TARGET_OVERRIDE ) ;
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-02-06 02:46:59 +01:00
switch ( gBattleMons [ gActiveBattler ] . ability )
2017-09-27 23:43:45 +02:00
{
case ABILITY_NATURAL_CURE :
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . status1 = 0 ;
2021-10-13 01:50:32 +02:00
BtlController_EmitSetMonData ( BUFFER_A , REQUEST_STATUS_BATTLE ,
gBitTable [ * ( gBattleStruct - > battlerPartyIndexes + gActiveBattler ) ] ,
sizeof ( gBattleMons [ gActiveBattler ] . status1 ) ,
& gBattleMons [ gActiveBattler ] . status1 ) ;
2018-02-06 20:48:02 +01:00
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 :
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_POISON ;
break ;
case BATTLE_TERRAIN_LONG_GRASS :
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_SLEEP ;
break ;
case BATTLE_TERRAIN_SAND :
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_ACC_MINUS_1 ;
break ;
case BATTLE_TERRAIN_UNDERWATER :
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_DEF_MINUS_1 ;
break ;
case BATTLE_TERRAIN_WATER :
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_ATK_MINUS_1 ;
break ;
case BATTLE_TERRAIN_POND :
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_SPD_MINUS_1 ;
break ;
2017-12-16 01:08:55 +01:00
case BATTLE_TERRAIN_MOUNTAIN :
2017-09-27 23:43:45 +02:00
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_CONFUSION ;
break ;
case BATTLE_TERRAIN_CAVE :
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_FLINCH ;
break ;
default :
gBattleCommunication [ MOVE_EFFECT_BYTE ] = MOVE_EFFECT_PARALYSIS ;
break ;
}
gBattlescriptCurrInstr + + ;
}
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 ;
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
2021-10-04 16:21:03 +02:00
& & species ! = SPECIES_NONE
2018-11-17 15:30:34 +01:00
& & species ! = SPECIES_EGG
& & heldItem = = ITEM_NONE
& & ( Random ( ) % 10 ) = = 0 )
{
heldItem = GetBattlePyramidPickupItemId ( ) ;
SetMonData ( & gPlayerParty [ i ] , MON_DATA_HELD_ITEM , & heldItem ) ;
2017-09-27 23:43:45 +02:00
}
}
2018-11-17 15:30:34 +01:00
}
else
{
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2017-09-27 23:43:45 +02:00
{
2018-11-17 15:30:34 +01:00
species = GetMonData ( & gPlayerParty [ i ] , MON_DATA_SPECIES2 ) ;
heldItem = GetMonData ( & gPlayerParty [ i ] , MON_DATA_HELD_ITEM ) ;
2017-09-27 23:43:45 +02:00
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
2021-10-04 16:21:03 +02:00
& & species ! = SPECIES_NONE
2018-11-17 15:30:34 +01:00
& & species ! = SPECIES_EGG
& & heldItem = = ITEM_NONE
& & ( Random ( ) % 10 ) = = 0 )
{
s32 j ;
s32 rand = Random ( ) % 100 ;
u8 lvlDivBy10 = ( GetMonData ( & gPlayerParty [ i ] , MON_DATA_LEVEL ) - 1 ) / 10 ;
if ( lvlDivBy10 > 9 )
lvlDivBy10 = 9 ;
2017-09-27 23:43:45 +02:00
2020-07-17 02:12:12 +02:00
for ( j = 0 ; j < ( int ) ARRAY_COUNT ( sPickupProbabilities ) ; j + + )
2018-11-17 15:30:34 +01:00
{
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 )
2021-10-04 16:21:03 +02:00
* ( & gBattleStruct - > formToChangeInto ) | = CASTFORM_SUBSTITUTE ;
2017-09-28 15:34:21 +02:00
2021-10-13 01:50:32 +02:00
BtlController_EmitBattleAnimation ( BUFFER_A , B_ANIM_CASTFORM_CHANGE , gBattleStruct - > formToChangeInto ) ;
2018-02-06 20:48:02 +01:00
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 + + ;
2018-02-06 02:46:59 +01:00
form = CastformDataTypeChange ( gBattleScripting . battler ) ;
2017-09-28 15:34:21 +02:00
if ( form )
{
BattleScriptPushCursorAndCallback ( BattleScript_CastformChange ) ;
* ( & gBattleStruct - > formToChangeInto ) = form - 1 ;
}
}
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-02-06 23:09:39 +01:00
if ( ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_MUDSPORT ) )
2017-09-28 15:34:21 +02:00
{
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] | = STATUS3_MUDSPORT ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_WEAKEN_ELECTRIC ;
2017-09-28 15:34:21 +02:00
worked = TRUE ;
}
}
else // water sport
{
2018-02-06 23:09:39 +01:00
if ( ! ( gStatuses3 [ gBattlerAttacker ] & STATUS3_WATERSPORT ) )
2017-09-28 15:34:21 +02:00
{
2018-02-06 23:09:39 +01:00
gStatuses3 [ gBattlerAttacker ] | = STATUS3_WATERSPORT ;
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_WEAKEN_FIRE ;
2017-09-28 15:34:21 +02:00
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
}
2019-08-23 13:55:36 +02:00
static void Cmd_setweatherballtype ( void )
2017-09-28 15:34:21 +02:00
{
if ( WEATHER_HAS_EFFECT )
{
2021-09-30 12:08:20 +02:00
if ( gBattleWeather & B_WEATHER_ANY )
2017-09-28 15:34:21 +02:00
gBattleScripting . dmgMultiplier = 2 ;
2021-09-30 12:08:20 +02:00
if ( gBattleWeather & B_WEATHER_RAIN )
2021-10-04 16:21:03 +02:00
* ( & gBattleStruct - > dynamicMoveType ) = TYPE_WATER | F_DYNAMIC_TYPE_2 ;
2021-09-30 12:08:20 +02:00
else if ( gBattleWeather & B_WEATHER_SANDSTORM )
2021-10-04 16:21:03 +02:00
* ( & gBattleStruct - > dynamicMoveType ) = TYPE_ROCK | F_DYNAMIC_TYPE_2 ;
2021-09-30 12:08:20 +02:00
else if ( gBattleWeather & B_WEATHER_SUN )
2021-10-04 16:21:03 +02:00
* ( & gBattleStruct - > dynamicMoveType ) = TYPE_FIRE | F_DYNAMIC_TYPE_2 ;
2021-09-30 12:08:20 +02:00
else if ( gBattleWeather & B_WEATHER_HAIL )
2021-10-04 16:21:03 +02:00
* ( & gBattleStruct - > dynamicMoveType ) = TYPE_ICE | F_DYNAMIC_TYPE_2 ;
2017-09-28 15:34:21 +02:00
else
2021-10-04 16:21:03 +02:00
* ( & gBattleStruct - > dynamicMoveType ) = TYPE_NORMAL | F_DYNAMIC_TYPE_2 ;
2017-09-28 15:34:21 +02:00
}
gBattlescriptCurrInstr + + ;
}
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 ] ;
2021-10-04 16:21:03 +02:00
if ( * usedHeldItem ! = ITEM_NONE & & gBattleMons [ gActiveBattler ] . item = = ITEM_NONE )
2017-09-28 15:34:21 +02:00
{
gLastUsedItem = * usedHeldItem ;
2021-10-04 16:21:03 +02:00
* usedHeldItem = ITEM_NONE ;
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . item = gLastUsedItem ;
2017-09-28 15:34:21 +02:00
2021-10-13 01:50:32 +02:00
BtlController_EmitSetMonData ( BUFFER_A , REQUEST_HELDITEM_BATTLE , 0 , sizeof ( gBattleMons [ gActiveBattler ] . item ) , & gBattleMons [ gActiveBattler ] . item ) ;
2018-02-06 20:48:02 +01:00
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
}
}
2021-10-13 22:39:21 +02:00
// Unused
static void Cmd_pursuitdoubles ( 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 ] )
2020-03-18 02:11:14 +01:00
& & gChosenActionByBattler [ gActiveBattler ] = = B_ACTION_USE_MOVE
2018-02-06 23:09:39 +01:00
& & gChosenMoveByBattler [ gActiveBattler ] = = MOVE_PURSUIT )
2017-09-28 15:34:21 +02:00
{
2021-10-04 16:21:03 +02:00
gActionsByTurnOrder [ gActiveBattler ] = B_ACTION_TRY_FINISH ;
2017-09-28 15:34:21 +02:00
gCurrentMove = MOVE_PURSUIT ;
gBattlescriptCurrInstr + = 5 ;
gBattleScripting . animTurn = 1 ;
2021-10-13 22:39:21 +02:00
gBattleScripting . pursuitDoublesAttacker = 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 )
{
2021-09-24 20:30:15 +02: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 + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_handleballthrow ( void )
2017-09-28 15:34:21 +02:00
{
2021-06-12 03:22:50 +02:00
u8 ballMultiplier = 10 ;
2017-09-28 15:34:21 +02:00
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-09-28 15:34:21 +02:00
return ;
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker ;
gBattlerTarget = gBattlerAttacker ^ BIT_SIDE ;
2017-09-28 15:34:21 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_TRAINER )
{
2021-10-13 01:50:32 +02:00
BtlController_EmitBallThrowAnim ( BUFFER_A , BALL_TRAINER_BLOCK ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr = BattleScript_TrainerBallBlock ;
}
else if ( gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL )
{
2021-10-13 01:50:32 +02:00
BtlController_EmitBallThrowAnim ( BUFFER_A , BALL_3_SHAKES_SUCCESS ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr = BattleScript_WallyBallThrow ;
}
else
{
2021-06-11 06:59:13 +02:00
u32 odds ;
2017-09-28 15:34:21 +02:00
u8 catchRate ;
2021-06-12 03:22:50 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_SAFARI )
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
2021-06-12 03:22:50 +02:00
switch ( gLastUsedItem )
2017-09-28 15:34:21 +02:00
{
2021-06-12 03:22:50 +02:00
case ITEM_ULTRA_BALL :
ballMultiplier = 20 ;
case ITEM_GREAT_BALL :
case ITEM_SAFARI_BALL :
ballMultiplier = 15 ;
case ITEM_NET_BALL :
if ( IS_BATTLER_OF_TYPE ( gBattlerTarget , TYPE_WATER ) | | IS_BATTLER_OF_TYPE ( gBattlerTarget , TYPE_BUG ) )
ballMultiplier = 30 ;
break ;
case ITEM_DIVE_BALL :
if ( GetCurrentMapType ( ) = = MAP_TYPE_UNDERWATER )
ballMultiplier = 35 ;
break ;
case ITEM_NEST_BALL :
if ( gBattleMons [ gBattlerTarget ] . level < 40 )
2017-09-28 15:34:21 +02:00
{
2021-06-12 03:22:50 +02:00
ballMultiplier = 40 - gBattleMons [ gBattlerTarget ] . level ;
if ( ballMultiplier < = 9 )
2021-06-11 06:59:13 +02:00
ballMultiplier = 10 ;
2017-09-28 15:34:21 +02:00
}
2021-06-12 03:22:50 +02:00
break ;
case ITEM_REPEAT_BALL :
if ( GetSetPokedexFlag ( SpeciesToNationalPokedexNum ( gBattleMons [ gBattlerTarget ] . species ) , FLAG_GET_CAUGHT ) )
ballMultiplier = 30 ;
break ;
case ITEM_TIMER_BALL :
ballMultiplier = gBattleResults . battleTurnCounter + 10 ;
if ( ballMultiplier > 40 )
ballMultiplier = 40 ;
break ;
2017-09-28 15:34:21 +02:00
}
2021-06-11 06:59:13 +02:00
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 ;
2021-11-21 19:41:32 +01:00
if ( gBattleResults . catchAttempts [ gLastUsedItem - FIRST_BALL ] < 255 )
2021-06-12 03:22:50 +02:00
gBattleResults . catchAttempts [ gLastUsedItem - FIRST_BALL ] + + ;
2017-09-28 15:34:21 +02:00
if ( odds > 254 ) // mon caught
{
2021-10-13 01:50:32 +02:00
BtlController_EmitBallThrowAnim ( BUFFER_A , BALL_3_SHAKES_SUCCESS ) ;
2018-02-06 20:48:02 +01:00
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?
2021-10-13 01:50:32 +02:00
BtlController_EmitBallThrowAnim ( BUFFER_A , shakes ) ;
2018-02-06 20:48:02 +01:00
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-02-06 23:09:39 +01:00
if ( GiveMonToPlayer ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] ) ! = MON_GIVEN_TO_PARTY )
2017-09-28 15:34:21 +02:00
{
2019-09-17 07:49:07 +02:00
if ( ! ShouldShowBoxWasFullMessage ( ) )
2017-09-28 15:34:21 +02:00
{
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_SENT_SOMEONES_PC ;
2019-09-17 07:49:07 +02:00
StringCopy ( gStringVar1 , GetBoxNamePtr ( VarGet ( VAR_PC_BOX_TO_SEND_MON ) ) ) ;
2018-02-06 23:09:39 +01:00
GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] , MON_DATA_NICKNAME , gStringVar2 ) ;
2017-09-28 15:34:21 +02:00
}
else
{
2019-09-17 07:49:07 +02:00
StringCopy ( gStringVar1 , GetBoxNamePtr ( VarGet ( VAR_PC_BOX_TO_SEND_MON ) ) ) ; // box the mon was sent to
2018-02-06 23:09:39 +01:00
GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] , MON_DATA_NICKNAME , gStringVar2 ) ;
2019-09-17 07:49:07 +02:00
StringCopy ( gStringVar3 , GetBoxNamePtr ( GetPCBoxToSendMon ( ) ) ) ; //box the mon was going to be sent to
2021-04-02 08:27:12 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = B_MSG_SOMEONES_BOX_FULL ;
2017-09-28 15:34:21 +02:00
}
2021-04-02 08:27:12 +02:00
// Change to B_MSG_SENT_LANETTES_PC or B_MSG_LANETTES_BOX_FULL
2017-11-08 22:20:10 +01:00
if ( FlagGet ( FLAG_SYS_PC_LANETTE ) )
2017-09-28 15:34:21 +02:00
gBattleCommunication [ MULTISTRING_CHOOSER ] + + ;
}
2018-02-06 23:09:39 +01:00
gBattleResults . caughtMonSpecies = GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] , MON_DATA_SPECIES , NULL ) ;
GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] , MON_DATA_NICKNAME , gBattleResults . caughtMonNick ) ;
gBattleResults . caughtMonBall = GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] , MON_DATA_POKEBALL , NULL ) ;
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr + + ;
}
2019-08-23 13:55:36 +02:00
static void Cmd_trysetcaughtmondexflags ( void )
2017-09-28 15:34:21 +02:00
{
u16 species = GetMonData ( & gEnemyParty [ 0 ] , MON_DATA_SPECIES , NULL ) ;
u32 personality = GetMonData ( & gEnemyParty [ 0 ] , MON_DATA_PERSONALITY , NULL ) ;
if ( GetSetPokedexFlag ( SpeciesToNationalPokedexNum ( species ) , FLAG_GET_CAUGHT ) )
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 15:34:21 +02:00
}
else
{
HandleSetPokedexFlag ( SpeciesToNationalPokedexNum ( species ) , FLAG_SET_CAUGHT , personality ) ;
gBattlescriptCurrInstr + = 5 ;
}
}
2019-08-23 13:55:36 +02:00
static void Cmd_displaydexinfo ( void )
2017-09-28 15:34:21 +02:00
{
u16 species = GetMonData ( & gEnemyParty [ 0 ] , MON_DATA_SPECIES , NULL ) ;
switch ( gBattleCommunication [ 0 ] )
{
case 0 :
2021-10-08 22:50:52 +02:00
BeginNormalPaletteFade ( PALETTES_ALL , 0 , 0 , 16 , RGB_BLACK ) ;
2017-09-28 15:34:21 +02:00
gBattleCommunication [ 0 ] + + ;
break ;
case 1 :
if ( ! gPaletteFade . active )
{
FreeAllWindowBuffers ( ) ;
2020-03-08 18:24:22 +01:00
gBattleCommunication [ TASK_ID ] = DisplayCaughtMonDexPage ( SpeciesToNationalPokedexNum ( species ) ,
2018-02-06 23:09:39 +01:00
gBattleMons [ gBattlerTarget ] . otId ,
gBattleMons [ gBattlerTarget ] . personality ) ;
2017-09-28 15:34:21 +02:00
gBattleCommunication [ 0 ] + + ;
}
break ;
case 2 :
if ( ! gPaletteFade . active
& & gMain . callback2 = = BattleMainCB2
& & ! gTasks [ gBattleCommunication [ TASK_ID ] ] . isActive )
{
SetVBlankCallback ( VBlankCB_Battle ) ;
gBattleCommunication [ 0 ] + + ;
}
break ;
case 3 :
2019-11-07 01:18:11 +01:00
InitBattleBgsVideo ( ) ;
2017-10-01 01:12:42 +02:00
LoadBattleTextboxAndBackground ( ) ;
2021-10-08 22:50:52 +02:00
gBattle_BG3_X = 256 ;
2017-09-28 15:34:21 +02:00
gBattleCommunication [ 0 ] + + ;
break ;
case 4 :
if ( ! IsDma3ManagerBusyWithBgCopy ( ) )
{
2021-10-08 22:50:52 +02:00
BeginNormalPaletteFade ( PALETTES_BG , 0 , 16 , 0 , RGB_BLACK ) ;
2017-09-28 15:34:21 +02:00
ShowBg ( 0 ) ;
ShowBg ( 3 ) ;
gBattleCommunication [ 0 ] + + ;
}
break ;
case 5 :
if ( ! gPaletteFade . active )
gBattlescriptCurrInstr + + ;
break ;
}
}
2017-10-22 01:04:02 +02:00
void HandleBattleWindow ( u8 xStart , u8 yStart , u8 xEnd , u8 yEnd , u8 flags )
2017-09-28 15:34:21 +02:00
{
s32 destY , destX ;
u16 var = 0 ;
for ( destY = yStart ; destY < = yEnd ; destY + + )
{
for ( destX = xStart ; destX < = xEnd ; destX + + )
{
if ( destY = = yStart )
{
if ( destX = = xStart )
var = 0x1022 ;
else if ( destX = = xEnd )
var = 0x1024 ;
else
var = 0x1023 ;
}
else if ( destY = = yEnd )
{
if ( destX = = xStart )
var = 0x1028 ;
else if ( destX = = xEnd )
var = 0x102A ;
else
var = 0x1029 ;
}
else
{
if ( destX = = xStart )
var = 0x1025 ;
else if ( destX = = xEnd )
var = 0x1027 ;
else
var = 0x1026 ;
}
2017-10-22 01:04:02 +02:00
if ( flags & WINDOW_CLEAR )
2017-09-28 15:34:21 +02:00
var = 0 ;
2021-10-08 22:50:52 +02:00
if ( flags & WINDOW_BG1 )
2017-09-28 15:34:21 +02:00
CopyToBgTilemapBufferRect_ChangePalette ( 1 , & var , destX , destY , 1 , 1 , 0x11 ) ;
else
CopyToBgTilemapBufferRect_ChangePalette ( 0 , & var , destX , destY , 1 , 1 , 0x11 ) ;
}
}
}
2017-10-21 17:32:35 +02:00
void BattleCreateYesNoCursorAt ( u8 cursorPosition )
2017-09-28 15:34:21 +02:00
{
u16 src [ 2 ] ;
src [ 0 ] = 1 ;
src [ 1 ] = 2 ;
CopyToBgTilemapBufferRect_ChangePalette ( 0 , src , 0x19 , 9 + ( 2 * cursorPosition ) , 1 , 2 , 0x11 ) ;
CopyBgTilemapBufferToVram ( 0 ) ;
}
2017-10-21 17:32:35 +02:00
void BattleDestroyYesNoCursorAt ( u8 cursorPosition )
2017-09-28 15:34:21 +02:00
{
u16 src [ 2 ] ;
src [ 0 ] = 0x1016 ;
src [ 1 ] = 0x1016 ;
CopyToBgTilemapBufferRect_ChangePalette ( 0 , src , 0x19 , 9 + ( 2 * cursorPosition ) , 1 , 2 , 0x11 ) ;
CopyBgTilemapBufferToVram ( 0 ) ;
}
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 :
2021-10-08 22:50:52 +02:00
HandleBattleWindow ( 24 , 8 , 29 , 13 , 0 ) ;
BattlePutTextOnWindow ( gText_BattleYesNoChoice , B_WIN_YESNO ) ;
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 :
2020-09-05 03:11:55 +02:00
if ( JOY_NEW ( DPAD_UP ) & & gBattleCommunication [ CURSOR_POSITION ] ! = 0 )
2017-09-28 15:34:21 +02:00
{
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
}
2020-09-05 03:11:55 +02:00
if ( JOY_NEW ( DPAD_DOWN ) & & gBattleCommunication [ CURSOR_POSITION ] = = 0 )
2017-09-28 15:34:21 +02:00
{
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
}
2020-09-05 03:11:55 +02:00
if ( JOY_NEW ( A_BUTTON ) )
2017-09-28 15:34:21 +02:00
{
PlaySE ( SE_SELECT ) ;
if ( gBattleCommunication [ CURSOR_POSITION ] = = 0 )
{
gBattleCommunication [ MULTIUSE_STATE ] + + ;
BeginFastPaletteFade ( 3 ) ;
}
else
{
gBattleCommunication [ MULTIUSE_STATE ] = 4 ;
}
}
2020-09-05 03:11:55 +02:00
else if ( JOY_NEW ( B_BUTTON ) )
2017-09-28 15:34:21 +02:00
{
PlaySE ( SE_SELECT ) ;
gBattleCommunication [ MULTIUSE_STATE ] = 4 ;
}
break ;
case 2 :
if ( ! gPaletteFade . active )
{
2018-02-06 23:09:39 +01:00
GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] , MON_DATA_NICKNAME , gBattleStruct - > caughtMonNick ) ;
2017-09-28 15:34:21 +02:00
FreeAllWindowBuffers ( ) ;
DoNamingScreen ( NAMING_SCREEN_CAUGHT_MON , gBattleStruct - > caughtMonNick ,
2018-02-06 23:09:39 +01:00
GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] , MON_DATA_SPECIES ) ,
GetMonGender ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] ) ,
GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] , MON_DATA_PERSONALITY , NULL ) ,
2017-09-28 15:34:21 +02:00
BattleMainCB2 ) ;
gBattleCommunication [ MULTIUSE_STATE ] + + ;
}
break ;
case 3 :
if ( gMain . callback2 = = BattleMainCB2 & & ! gPaletteFade . active )
{
2018-02-06 23:09:39 +01:00
SetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gBattlerAttacker ^ BIT_SIDE ] ] , MON_DATA_NICKNAME , gBattleStruct - > caughtMonNick ) ;
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR ( gBattlescriptCurrInstr + 1 ) ;
2017-09-28 15:34:21 +02:00
}
break ;
case 4 :
2020-07-17 02:12:12 +02:00
if ( CalculatePlayerPartyCount ( ) = = PARTY_SIZE )
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
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 ] ) ;
2021-10-13 01:50:32 +02:00
BtlController_EmitTrainerSlideBack ( BUFFER_A ) ;
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr + = 2 ;
}