pokeemerald/src/battle_script_commands.c

10976 lines
373 KiB
C
Raw Normal View History

2017-09-04 15:05:11 +02:00
#include "global.h"
#include "battle.h"
2017-12-05 18:55:48 +01:00
#include "constants/battle_move_effects.h"
2018-02-08 11:17:41 +01:00
#include "constants/battle_script_commands.h"
#include "battle_message.h"
2017-09-28 17:38:07 +02:00
#include "battle_ai_script_commands.h"
#include "battle_scripts.h"
2017-12-11 19:27:51 +01:00
#include "constants/moves.h"
2017-12-05 18:55:48 +01:00
#include "constants/abilities.h"
2017-09-08 16:46:37 +02:00
#include "item.h"
2017-12-05 18:55:48 +01:00
#include "constants/items.h"
#include "constants/hold_effects.h"
#include "util.h"
#include "pokemon.h"
#include "random.h"
2017-09-20 00:28:00 +02:00
#include "battle_controllers.h"
#include "battle_interface.h"
2017-12-11 19:27:51 +01:00
#include "constants/species.h"
#include "constants/songs.h"
2017-12-17 21:19:08 +01:00
#include "constants/trainers.h"
2017-12-31 16:28:57 +01:00
#include "constants/battle_anim.h"
2018-07-16 20:23:05 +02:00
#include "constants/map_types.h"
2017-09-22 21:33:49 +02:00
#include "text.h"
#include "sound.h"
2017-09-24 00:29:52 +02:00
#include "pokedex.h"
2017-09-25 00:09:13 +02:00
#include "recorded_battle.h"
#include "window.h"
#include "reshow_battle_screen.h"
#include "main.h"
#include "palette.h"
#include "money.h"
2017-09-26 22:39:59 +02:00
#include "bg.h"
#include "string_util.h"
#include "pokemon_icon.h"
#include "m4a.h"
2017-09-27 23:43:45 +02:00
#include "mail.h"
2017-09-28 15:34:21 +02:00
#include "event_data.h"
#include "pokemon_storage_system.h"
#include "task.h"
#include "naming_screen.h"
2018-02-08 00:35:13 +01:00
#include "constants/battle_string_ids.h"
2018-02-07 23:21:51 +01:00
#include "battle_setup.h"
#include "overworld.h"
2018-07-07 19:57:09 +02:00
#include "party_menu.h"
#include "constants/battle_config.h"
2017-09-28 15:34:21 +02:00
extern u16 gBattle_BG1_X;
extern u16 gBattle_BG1_Y;
extern u16 gBattle_BG2_X;
extern u16 gBattle_BG2_Y;
extern u16 gBattle_BG3_X;
extern struct MusicPlayerInfo gMPlayInfo_BGM;
2017-09-25 00:09:13 +02:00
2017-09-23 20:13:45 +02:00
extern const u8* const gBattleScriptsForMoveEffects[];
// functions
2018-02-08 12:13:29 +01:00
extern void sub_81A5718(u8 battlerId); // battle frontier 2
2017-09-24 00:29:52 +02:00
extern void sub_81A56B4(void); // battle frontier 2
2018-08-12 21:54:07 +02:00
extern void ShowSelectMovePokemonSummaryScreen(struct Pokemon* party, u8 monPartyId, u8 monCount, void (*callback)(void), u16 move); // pokemon summary screen
2017-09-25 00:09:13 +02:00
extern u8 sub_81C1B94(void); // pokemon summary screen
2017-09-26 22:39:59 +02:00
extern void sub_81D388C(struct Pokemon* mon, void* statStoreLocation); // pokenav.s
extern void sub_81D3640(u8 arg0, void* statStoreLocation1, void* statStoreLocation2, u8 arg3, u8 arg4, u8 arg5); // pokenav.s
extern void sub_81D3784(u8 arg0, void* statStoreLocation1, u8 arg2, u8 arg3, u8 arg4); // pokenav.s
extern u8* GetMonNickname(struct Pokemon* mon, u8* dst); // party_menu
extern u8 sub_81A5258(u8* arg0); // battle frontier 2
extern void sub_81A5BF8(void); // battle frontier 2
extern void sub_81A5D44(void); // battle frontier 2
2018-02-08 12:13:29 +01:00
extern void sub_81B8E80(u8 battlerId, u8, u8); // party menu
2017-09-26 22:39:59 +02:00
extern bool8 sub_81B1250(void); // ?
2017-09-28 15:34:21 +02:00
extern bool8 InBattlePike(void);
extern bool8 InBattlePyramid(void);
extern u16 GetBattlePyramidPickupItemId(void);
extern u8 sub_813B21C(void);
extern u16 get_unknown_box_id(void);
2018-02-06 23:09:39 +01:00
#define DEFENDER_IS_PROTECTED ((gProtectStructs[gBattlerTarget].protected) && (gBattleMoves[gCurrentMove].flags & FLAG_PROTECT_AFFECTED))
// this file's functions
2017-09-28 15:34:21 +02:00
static bool8 IsTwoTurnsMove(u16 move);
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-28 15:34:21 +02:00
static u8 ChangeStatBuffs(s8 statValue, u8 statId, u8, const u8* BS_ptr);
static bool32 IsMonGettingExpSentOut(void);
static void sub_804F17C(void);
static bool8 sub_804F1CC(void);
static void sub_804F100(void);
static void sub_804F144(void);
static bool8 sub_804F344(void);
static void PutMonIconOnLvlUpBox(void);
static void PutLevelAndGenderOnLvlUpBox(void);
2017-09-28 16:32:23 +02:00
static void SpriteCB_MonIconOnLvlUpBox(struct Sprite* sprite);
2017-09-28 15:34:21 +02:00
static void atk00_attackcanceler(void);
static void atk01_accuracycheck(void);
static void atk02_attackstring(void);
static void atk03_ppreduce(void);
static void atk04_critcalc(void);
static void atk05_damagecalc(void);
2017-09-28 15:34:21 +02:00
static void atk06_typecalc(void);
2018-07-14 22:56:03 +02:00
static void atk07_adjustdamage(void);
2018-07-21 15:11:13 +02:00
static void atk08_multihitresultmessage(void);
2017-09-28 15:34:21 +02:00
static void atk09_attackanimation(void);
static void atk0A_waitanimation(void);
static void atk0B_healthbarupdate(void);
static void atk0C_datahpupdate(void);
static void atk0D_critmessage(void);
static void atk0E_effectivenesssound(void);
2017-09-28 15:34:21 +02:00
static void atk0F_resultmessage(void);
static void atk10_printstring(void);
static void atk11_printselectionstring(void);
2017-09-28 15:34:21 +02:00
static void atk12_waitmessage(void);
static void atk13_printfromtable(void);
static void atk14_printselectionstringfromtable(void);
2017-09-28 15:34:21 +02:00
static void atk15_seteffectwithchance(void);
static void atk16_seteffectprimary(void);
static void atk17_seteffectsecondary(void);
static void atk18_clearstatusfromeffect(void);
static void atk19_tryfaintmon(void);
static void atk1A_dofaintanimation(void);
static void atk1B_cleareffectsonfaint(void);
2017-09-28 15:34:21 +02:00
static void atk1C_jumpifstatus(void);
static void atk1D_jumpifstatus2(void);
static void atk1E_jumpifability(void);
static void atk1F_jumpifsideaffecting(void);
static void atk20_jumpifstat(void);
2017-11-26 11:55:17 +01:00
static void atk21_jumpifstatus3condition(void);
2017-09-28 15:34:21 +02:00
static void atk22_jumpiftype(void);
static void atk23_getexp(void);
static void atk24(void);
static void atk25_movevaluescleanup(void);
static void atk26_setmultihit(void);
static void atk27_decrementmultihit(void);
2017-09-28 15:34:21 +02:00
static void atk28_goto(void);
static void atk29_jumpifbyte(void);
static void atk2A_jumpifhalfword(void);
static void atk2B_jumpifword(void);
static void atk2C_jumpifarrayequal(void);
static void atk2D_jumpifarraynotequal(void);
static void atk2E_setbyte(void);
static void atk2F_addbyte(void);
static void atk30_subbyte(void);
static void atk31_copyarray(void);
static void atk32_copyarraywithindex(void);
2017-09-28 15:34:21 +02:00
static void atk33_orbyte(void);
static void atk34_orhalfword(void);
static void atk35_orword(void);
static void atk36_bicbyte(void);
static void atk37_bichalfword(void);
static void atk38_bicword(void);
static void atk39_pause(void);
static void atk3A_waitstate(void);
static void atk3B_healthbar_update(void);
static void atk3C_return(void);
static void atk3D_end(void);
static void atk3E_end2(void);
static void atk3F_end3(void);
static void atk40_jumpifaffectedbyprotect(void);
2017-09-28 15:34:21 +02:00
static void atk41_call(void);
static void atk42_setroost(void);
2017-09-28 15:34:21 +02:00
static void atk43_jumpifabilitypresent(void);
static void atk44_endselectionscript(void);
2017-09-28 15:34:21 +02:00
static void atk45_playanimation(void);
static void atk46_playanimation2(void);
static void atk47_setgraphicalstatchangevalues(void);
static void atk48_playstatchangeanimation(void);
static void atk49_moveend(void);
static void atk4A_sethealblock(void);
static void atk4B_returnatktoball(void);
static void atk4C_getswitchedmondata(void);
static void atk4D_switchindataupdate(void);
static void atk4E_switchinanim(void);
static void atk4F_jumpifcantswitch(void);
2017-09-28 15:34:21 +02:00
static void atk50_openpartyscreen(void);
static void atk51_switchhandleorder(void);
static void atk52_switchineffects(void);
static void atk53_trainerslidein(void);
static void atk54_playse(void);
static void atk55_fanfare(void);
static void atk56_playfaintcry(void);
2017-09-28 15:34:21 +02:00
static void atk57(void);
static void atk58_returntoball(void);
static void atk59_handlelearnnewmove(void);
2017-09-28 15:34:21 +02:00
static void atk5A_yesnoboxlearnmove(void);
static void atk5B_yesnoboxstoplearningmove(void);
static void atk5C_hitanimation(void);
static void atk5D_getmoneyreward(void);
static void atk5E(void);
2018-06-30 14:12:17 +02:00
static void atk5F_swapattackerwithtarget(void);
static void atk60_incrementgamestat(void);
static void atk61_drawpartystatussummary(void);
2018-06-28 21:06:32 +02:00
static void atk62_hidepartystatussummary(void);
2018-09-22 19:08:41 +02:00
static void atk63_jumptocalledmove(void);
2017-09-28 15:34:21 +02:00
static void atk64_statusanimation(void);
static void atk65_status2animation(void);
static void atk66_chosenstatusanimation(void);
static void atk67_yesnobox(void);
static void atk68_cancelallactions(void);
static void atk69_setgravity(void);
2017-09-28 15:34:21 +02:00
static void atk6A_removeitem(void);
static void atk6B_atknameinbuff1(void);
static void atk6C_drawlvlupbox(void);
static void atk6D_resetsentmonsvalue(void);
static void atk6E_setatktoplayer0(void);
static void atk6F_makevisible(void);
2018-07-22 18:40:18 +02:00
static void atk70_recordability(void);
static void atk71_buffermovetolearn(void);
static void atk72_jumpifplayerran(void);
static void atk73_hpthresholds(void);
static void atk74_hpthresholds2(void);
static void atk75_useitemonopponent(void);
2017-09-28 15:34:21 +02:00
static void atk76_various(void);
static void atk77_setprotectlike(void);
2017-09-28 15:34:21 +02:00
static void atk78_faintifabilitynotdamp(void);
static void atk79_setatkhptozero(void);
static void atk7A_jumpifnexttargetvalid(void);
static void atk7B_tryhealhalfhealth(void);
2017-09-28 15:34:21 +02:00
static void atk7C_trymirrormove(void);
static void atk7D_setrain(void);
2017-09-28 15:34:21 +02:00
static void atk7E_setreflect(void);
static void atk7F_setseeded(void);
static void atk80_manipulatedamage(void);
static void atk81_trysetrest(void);
2017-09-28 15:34:21 +02:00
static void atk82_jumpifnotfirstturn(void);
static void atk83_setmiracleeye(void);
static void atk84_jumpifcantmakeasleep(void);
2017-09-28 15:34:21 +02:00
static void atk85_stockpile(void);
static void atk86_stockpiletobasedamage(void);
static void atk87_stockpiletohpheal(void);
static void atk88_setdrainedhp(void);
2017-09-28 15:34:21 +02:00
static void atk89_statbuffchange(void);
static void atk8A_normalisebuffs(void);
static void atk8B_setbide(void);
static void atk8C_confuseifrepeatingattackends(void);
static void atk8D_setmultihitcounter(void);
static void atk8E_initmultihitstring(void);
2017-09-28 15:34:21 +02:00
static void atk8F_forcerandomswitch(void);
static void atk90_tryconversiontypechange(void);
2017-09-28 15:34:21 +02:00
static void atk91_givepaydaymoney(void);
static void atk92_setlightscreen(void);
static void atk93_tryKO(void);
2017-09-28 15:34:21 +02:00
static void atk94_damagetohalftargethp(void);
static void atk95_setsandstorm(void);
static void atk96_weatherdamage(void);
static void atk97_tryinfatuating(void);
static void atk98_updatestatusicon(void);
2017-09-28 15:34:21 +02:00
static void atk99_setmist(void);
static void atk9A_setfocusenergy(void);
2017-09-28 15:34:21 +02:00
static void atk9B_transformdataexecution(void);
static void atk9C_setsubstitute(void);
2017-09-28 15:34:21 +02:00
static void atk9D_mimicattackcopy(void);
static void atk9E_metronome(void);
static void atk9F_dmgtolevel(void);
static void atkA0_psywavedamageeffect(void);
static void atkA1_counterdamagecalculator(void);
static void atkA2_mirrorcoatdamagecalculator(void);
static void atkA3_disablelastusedattack(void);
static void atkA4_trysetencore(void);
2017-09-28 15:34:21 +02:00
static void atkA5_painsplitdmgcalc(void);
static void atkA6_settypetorandomresistance(void);
static void atkA7_setalwayshitflag(void);
static void atkA8_copymovepermanently(void);
2017-11-26 01:19:57 +01:00
static void atkA9_trychoosesleeptalkmove(void);
static void atkAA_setdestinybond(void);
static void atkAB_trysetdestinybondtohappen(void);
static void atkAC_settailwind(void);
static void atkAD_tryspiteppreduce(void);
static void atkAE_healpartystatus(void);
2017-09-28 15:34:21 +02:00
static void atkAF_cursetarget(void);
static void atkB0_trysetspikes(void);
static void atkB1_setforesight(void);
static void atkB2_trysetperishsong(void);
static void atkB3_handlerollout(void);
2017-09-28 15:34:21 +02:00
static void atkB4_jumpifconfusedandstatmaxed(void);
static void atkB5_handlefurycutter(void);
static void atkB6_setembargo(void);
2017-09-28 15:34:21 +02:00
static void atkB7_presentdamagecalculation(void);
static void atkB8_setsafeguard(void);
2017-09-28 15:34:21 +02:00
static void atkB9_magnitudedamagecalculation(void);
static void atkBA_jumpifnopursuitswitchdmg(void);
static void atkBB_setsunny(void);
static void atkBC_maxattackhalvehp(void);
static void atkBD_copyfoestats(void);
static void atkBE_rapidspinfree(void);
static void atkBF_setdefensecurlbit(void);
2017-09-28 15:34:21 +02:00
static void atkC0_recoverbasedonsunlight(void);
static void atkC1_setstickyweb(void);
static void atkC2_selectfirstvalidtarget(void);
static void atkC3_trysetfutureattack(void);
static void atkC4_trydobeatup(void);
2017-09-28 15:34:21 +02:00
static void atkC5_setsemiinvulnerablebit(void);
static void atkC6_clearsemiinvulnerablebit(void);
static void atkC7_setminimize(void);
static void atkC8_sethail(void);
static void atkC9_jumpifattackandspecialattackcannotfall(void);
static void atkCA_setforcedtarget(void);
static void atkCB_setcharge(void);
static void atkCC_callterrainattack(void);
static void atkCD_cureifburnedparalysedorpoisoned(void);
static void atkCE_settorment(void);
static void atkCF_jumpifnodamage(void);
static void atkD0_settaunt(void);
static void atkD1_trysethelpinghand(void);
static void atkD2_tryswapitems(void);
static void atkD3_trycopyability(void);
static void atkD4_trywish(void);
2018-07-21 21:58:07 +02:00
static void atkD5_settoxicspikes(void);
static void atkD6_setgastroacid(void);
2017-09-28 15:34:21 +02:00
static void atkD7_setyawn(void);
static void atkD8_setdamagetohealthdifference(void);
2018-07-21 21:58:07 +02:00
static void atkD9_setroom(void);
static void atkDA_tryswapabilities(void);
static void atkDB_tryimprision(void);
2018-07-21 21:58:07 +02:00
static void atkDC_setstealthrock(void);
static void atkDD_setuserstatus3(void);
2017-09-28 15:34:21 +02:00
static void atkDE_asistattackselect(void);
static void atkDF_trysetmagiccoat(void);
static void atkE0_trysetsnatch(void);
static void atkE1_trygetintimidatetarget(void);
static void atkE2_switchoutabilities(void);
2017-09-28 15:34:21 +02:00
static void atkE3_jumpifhasnohp(void);
static void atkE4_getsecretpowereffect(void);
static void atkE5_pickup(void);
static void atkE6_docastformchangeanimation(void);
static void atkE7_trycastformdatachange(void);
2017-09-28 15:34:21 +02:00
static void atkE8_settypebasedhalvers(void);
2018-08-02 20:24:18 +02:00
static void atkE9_jumpifsubstituteblocks(void);
static void atkEA_tryrecycleitem(void);
2017-09-28 15:34:21 +02:00
static void atkEB_settypetoterrain(void);
static void atkEC_pursuitrelated(void);
2018-06-30 14:12:17 +02:00
static void atkEF_snatchsetbattlers(void);
2017-09-28 15:34:21 +02:00
static void atkEE_removelightscreenreflect(void);
2017-11-26 01:19:57 +01:00
static void atkEF_handleballthrow(void);
static void atkF0_givecaughtmon(void);
static void atkF1_trysetcaughtmondexflags(void);
static void atkF2_displaydexinfo(void);
static void atkF3_trygivecaughtmonnick(void);
2017-09-28 15:34:21 +02:00
static void atkF4_subattackerhpbydmg(void);
static void atkF5_removeattackerstatus1(void);
static void atkF6_finishaction(void);
static void atkF7_finishturn(void);
static void atkF8_trainerslideout(void);
2018-07-21 21:58:07 +02:00
static void atkF9_settelekinesis(void);
static void atkFA_swapstatstages(void);
static void atkFB_averagestats(void);
2018-07-22 15:08:32 +02:00
static void atkFC_jumpifoppositegenders(void);
2018-07-22 21:05:12 +02:00
static void atkFD_trygetbaddreamstarget(void);
2018-07-23 22:18:56 +02:00
static void atkFE_tryworryseed(void);
static void atkFF_metalburstdamagecalculator(void);
2017-09-04 15:05:11 +02:00
void (* const gBattleScriptingCommandsTable[])(void) =
{
atk00_attackcanceler,
atk01_accuracycheck,
atk02_attackstring,
atk03_ppreduce,
atk04_critcalc,
atk05_damagecalc,
2017-09-04 15:05:11 +02:00
atk06_typecalc,
2018-07-14 22:56:03 +02:00
atk07_adjustdamage,
2018-07-21 15:11:13 +02:00
atk08_multihitresultmessage,
2017-09-04 15:05:11 +02:00
atk09_attackanimation,
atk0A_waitanimation,
atk0B_healthbarupdate,
atk0C_datahpupdate,
atk0D_critmessage,
atk0E_effectivenesssound,
2017-09-04 15:05:11 +02:00
atk0F_resultmessage,
atk10_printstring,
atk11_printselectionstring,
2017-09-04 15:05:11 +02:00
atk12_waitmessage,
atk13_printfromtable,
atk14_printselectionstringfromtable,
2017-09-27 23:43:45 +02:00
atk15_seteffectwithchance,
2017-09-04 15:05:11 +02:00
atk16_seteffectprimary,
atk17_seteffectsecondary,
atk18_clearstatusfromeffect,
atk19_tryfaintmon,
atk1A_dofaintanimation,
atk1B_cleareffectsonfaint,
2017-09-04 15:05:11 +02:00
atk1C_jumpifstatus,
atk1D_jumpifstatus2,
atk1E_jumpifability,
atk1F_jumpifsideaffecting,
atk20_jumpifstat,
2017-11-26 11:55:17 +01:00
atk21_jumpifstatus3condition,
2017-09-04 15:05:11 +02:00
atk22_jumpiftype,
atk23_getexp,
atk24,
atk25_movevaluescleanup,
atk26_setmultihit,
atk27_decrementmultihit,
2017-09-04 15:05:11 +02:00
atk28_goto,
atk29_jumpifbyte,
atk2A_jumpifhalfword,
atk2B_jumpifword,
atk2C_jumpifarrayequal,
atk2D_jumpifarraynotequal,
atk2E_setbyte,
atk2F_addbyte,
atk30_subbyte,
atk31_copyarray,
atk32_copyarraywithindex,
2017-09-04 15:05:11 +02:00
atk33_orbyte,
atk34_orhalfword,
atk35_orword,
atk36_bicbyte,
atk37_bichalfword,
atk38_bicword,
atk39_pause,
atk3A_waitstate,
atk3B_healthbar_update,
atk3C_return,
atk3D_end,
atk3E_end2,
atk3F_end3,
atk40_jumpifaffectedbyprotect,
2017-09-04 15:05:11 +02:00
atk41_call,
atk42_setroost,
2017-09-04 15:05:11 +02:00
atk43_jumpifabilitypresent,
atk44_endselectionscript,
2017-09-04 15:05:11 +02:00
atk45_playanimation,
atk46_playanimation2,
atk47_setgraphicalstatchangevalues,
atk48_playstatchangeanimation,
2017-09-23 20:13:45 +02:00
atk49_moveend,
atk4A_sethealblock,
atk4B_returnatktoball,
atk4C_getswitchedmondata,
atk4D_switchindataupdate,
atk4E_switchinanim,
atk4F_jumpifcantswitch,
2017-09-04 15:05:11 +02:00
atk50_openpartyscreen,
atk51_switchhandleorder,
atk52_switchineffects,
atk53_trainerslidein,
atk54_playse,
atk55_fanfare,
atk56_playfaintcry,
2017-09-04 15:05:11 +02:00
atk57,
atk58_returntoball,
atk59_handlelearnnewmove,
2017-09-25 00:09:13 +02:00
atk5A_yesnoboxlearnmove,
atk5B_yesnoboxstoplearningmove,
2017-09-04 15:05:11 +02:00
atk5C_hitanimation,
atk5D_getmoneyreward,
atk5E,
2018-06-30 14:12:17 +02:00
atk5F_swapattackerwithtarget,
atk60_incrementgamestat,
atk61_drawpartystatussummary,
2018-06-28 21:06:32 +02:00
atk62_hidepartystatussummary,
2018-09-22 19:08:41 +02:00
atk63_jumptocalledmove,
2017-09-04 15:05:11 +02:00
atk64_statusanimation,
atk65_status2animation,
atk66_chosenstatusanimation,
2017-09-25 00:09:13 +02:00
atk67_yesnobox,
atk68_cancelallactions,
atk69_setgravity,
2017-09-04 15:05:11 +02:00
atk6A_removeitem,
atk6B_atknameinbuff1,
atk6C_drawlvlupbox,
atk6D_resetsentmonsvalue,
atk6E_setatktoplayer0,
atk6F_makevisible,
2018-07-22 18:40:18 +02:00
atk70_recordability,
atk71_buffermovetolearn,
atk72_jumpifplayerran,
atk73_hpthresholds,
atk74_hpthresholds2,
atk75_useitemonopponent,
2017-09-04 15:05:11 +02:00
atk76_various,
atk77_setprotectlike,
2017-09-04 15:05:11 +02:00
atk78_faintifabilitynotdamp,
atk79_setatkhptozero,
atk7A_jumpifnexttargetvalid,
atk7B_tryhealhalfhealth,
2017-09-26 22:39:59 +02:00
atk7C_trymirrormove,
atk7D_setrain,
2017-09-04 15:05:11 +02:00
atk7E_setreflect,
atk7F_setseeded,
atk80_manipulatedamage,
atk81_trysetrest,
2017-09-04 15:05:11 +02:00
atk82_jumpifnotfirstturn,
atk83_setmiracleeye,
atk84_jumpifcantmakeasleep,
2017-09-04 15:05:11 +02:00
atk85_stockpile,
atk86_stockpiletobasedamage,
atk87_stockpiletohpheal,
atk88_setdrainedhp,
2017-09-04 15:05:11 +02:00
atk89_statbuffchange,
atk8A_normalisebuffs,
atk8B_setbide,
atk8C_confuseifrepeatingattackends,
atk8D_setmultihitcounter,
atk8E_initmultihitstring,
2017-09-04 15:05:11 +02:00
atk8F_forcerandomswitch,
atk90_tryconversiontypechange,
2017-09-04 15:05:11 +02:00
atk91_givepaydaymoney,
atk92_setlightscreen,
atk93_tryKO,
2017-09-26 22:39:59 +02:00
atk94_damagetohalftargethp,
2017-09-04 15:05:11 +02:00
atk95_setsandstorm,
atk96_weatherdamage,
atk97_tryinfatuating,
atk98_updatestatusicon,
2017-09-04 15:05:11 +02:00
atk99_setmist,
atk9A_setfocusenergy,
2017-09-04 15:05:11 +02:00
atk9B_transformdataexecution,
atk9C_setsubstitute,
2017-09-26 22:39:59 +02:00
atk9D_mimicattackcopy,
2017-09-04 15:05:11 +02:00
atk9E_metronome,
atk9F_dmgtolevel,
atkA0_psywavedamageeffect,
atkA1_counterdamagecalculator,
atkA2_mirrorcoatdamagecalculator,
atkA3_disablelastusedattack,
atkA4_trysetencore,
2017-09-04 15:05:11 +02:00
atkA5_painsplitdmgcalc,
atkA6_settypetorandomresistance,
atkA7_setalwayshitflag,
atkA8_copymovepermanently,
2017-11-26 01:19:57 +01:00
atkA9_trychoosesleeptalkmove,
atkAA_setdestinybond,
atkAB_trysetdestinybondtohappen,
atkAC_settailwind,
atkAD_tryspiteppreduce,
atkAE_healpartystatus,
2017-09-04 15:05:11 +02:00
atkAF_cursetarget,
atkB0_trysetspikes,
atkB1_setforesight,
atkB2_trysetperishsong,
atkB3_handlerollout,
2017-09-04 15:05:11 +02:00
atkB4_jumpifconfusedandstatmaxed,
atkB5_handlefurycutter,
atkB6_setembargo,
2017-09-04 15:05:11 +02:00
atkB7_presentdamagecalculation,
atkB8_setsafeguard,
2017-09-04 15:05:11 +02:00
atkB9_magnitudedamagecalculation,
atkBA_jumpifnopursuitswitchdmg,
atkBB_setsunny,
atkBC_maxattackhalvehp,
atkBD_copyfoestats,
2017-09-27 23:43:45 +02:00
atkBE_rapidspinfree,
atkBF_setdefensecurlbit,
2017-09-04 15:05:11 +02:00
atkC0_recoverbasedonsunlight,
atkC1_setstickyweb,
atkC2_selectfirstvalidtarget,
atkC3_trysetfutureattack,
atkC4_trydobeatup,
2017-09-27 23:43:45 +02:00
atkC5_setsemiinvulnerablebit,
atkC6_clearsemiinvulnerablebit,
2017-09-04 15:05:11 +02:00
atkC7_setminimize,
atkC8_sethail,
atkC9_jumpifattackandspecialattackcannotfall,
atkCA_setforcedtarget,
atkCB_setcharge,
atkCC_callterrainattack,
atkCD_cureifburnedparalysedorpoisoned,
atkCE_settorment,
atkCF_jumpifnodamage,
atkD0_settaunt,
atkD1_trysethelpinghand,
atkD2_tryswapitems,
atkD3_trycopyability,
atkD4_trywish,
2018-07-21 21:58:07 +02:00
atkD5_settoxicspikes,
atkD6_setgastroacid,
2017-09-04 15:05:11 +02:00
atkD7_setyawn,
atkD8_setdamagetohealthdifference,
2018-07-21 21:58:07 +02:00
atkD9_setroom,
atkDA_tryswapabilities,
atkDB_tryimprision,
2018-07-21 21:58:07 +02:00
atkDC_setstealthrock,
atkDD_setuserstatus3,
2017-09-04 15:05:11 +02:00
atkDE_asistattackselect,
atkDF_trysetmagiccoat,
atkE0_trysetsnatch,
atkE1_trygetintimidatetarget,
atkE2_switchoutabilities,
2017-09-27 23:43:45 +02:00
atkE3_jumpifhasnohp,
2017-09-04 15:05:11 +02:00
atkE4_getsecretpowereffect,
atkE5_pickup,
atkE6_docastformchangeanimation,
atkE7_trycastformdatachange,
2017-09-04 15:05:11 +02:00
atkE8_settypebasedhalvers,
2018-08-02 20:24:18 +02:00
atkE9_jumpifsubstituteblocks,
atkEA_tryrecycleitem,
2017-09-04 15:05:11 +02:00
atkEB_settypetoterrain,
atkEC_pursuitrelated,
2018-06-30 14:12:17 +02:00
atkEF_snatchsetbattlers,
2017-09-04 15:05:11 +02:00
atkEE_removelightscreenreflect,
2017-11-26 01:19:57 +01:00
atkEF_handleballthrow,
atkF0_givecaughtmon,
atkF1_trysetcaughtmondexflags,
atkF2_displaydexinfo,
atkF3_trygivecaughtmonnick,
2017-09-28 15:34:21 +02:00
atkF4_subattackerhpbydmg,
2017-09-04 15:05:11 +02:00
atkF5_removeattackerstatus1,
atkF6_finishaction,
atkF7_finishturn,
2018-07-21 21:58:07 +02:00
atkF8_trainerslideout,
atkF9_settelekinesis,
atkFA_swapstatstages,
atkFB_averagestats,
2018-07-22 15:08:32 +02:00
atkFC_jumpifoppositegenders,
2018-07-22 21:05:12 +02:00
atkFD_trygetbaddreamstarget,
2018-07-23 22:18:56 +02:00
atkFE_tryworryseed,
atkFF_metalburstdamagecalculator,
2017-09-04 15:05:11 +02:00
};
struct StatFractions
2017-09-04 15:05:11 +02:00
{
u8 dividend;
u8 divisor;
};
2017-09-28 16:51:24 +02:00
static const struct StatFractions sAccuracyStageRatios[] =
2017-09-04 15:05:11 +02:00
{
{ 33, 100}, // -6
{ 36, 100}, // -5
{ 43, 100}, // -4
{ 50, 100}, // -3
{ 60, 100}, // -2
{ 75, 100}, // -1
{ 1, 1}, // 0
{133, 100}, // +1
{166, 100}, // +2
{ 2, 1}, // +3
{233, 100}, // +4
{133, 50}, // +5
{ 3, 1}, // +6
};
2017-09-28 16:51:24 +02:00
static const u32 sStatusFlagsForMoveEffects[] =
2017-09-04 15:05:11 +02:00
{
0x00000000,
2018-01-16 22:12:38 +01:00
STATUS1_SLEEP,
STATUS1_POISON,
STATUS1_BURN,
STATUS1_FREEZE,
STATUS1_PARALYSIS,
STATUS1_TOXIC_POISON,
STATUS2_CONFUSION,
STATUS2_FLINCHED,
2017-09-04 15:05:11 +02:00
0x00000000,
2017-09-22 21:33:49 +02:00
STATUS2_UPROAR,
2017-09-04 15:05:11 +02:00
0x00000000,
2017-09-22 21:33:49 +02:00
STATUS2_MULTIPLETURNS,
STATUS2_WRAPPED,
2017-09-04 15:05:11 +02:00
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
2017-09-22 21:33:49 +02:00
STATUS2_RECHARGE,
2017-09-04 15:05:11 +02:00
0x00000000,
0x00000000,
2017-09-22 21:33:49 +02:00
STATUS2_ESCAPE_PREVENTION,
STATUS2_NIGHTMARE,
2017-09-04 15:05:11 +02:00
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
2017-09-22 21:33:49 +02:00
STATUS2_LOCK_CONFUSE,
2017-09-04 15:05:11 +02:00
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000
};
2017-09-28 16:51:24 +02:00
static const u8* const sMoveEffectBS_Ptrs[] =
2017-09-26 22:39:59 +02:00
{
BattleScript_MoveEffectSleep, // 0
BattleScript_MoveEffectSleep, // MOVE_EFFECT_SLEEP
BattleScript_MoveEffectPoison, // MOVE_EFFECT_POISON
BattleScript_MoveEffectBurn, // MOVE_EFFECT_BURN
BattleScript_MoveEffectFreeze, // MOVE_EFFECT_FREEZE
BattleScript_MoveEffectParalysis, // MOVE_EFFECT_PARALYSIS
BattleScript_MoveEffectToxic, // MOVE_EFFECT_TOXIC
BattleScript_MoveEffectConfusion, // MOVE_EFFECT_CONFUSION
BattleScript_MoveEffectSleep, // MOVE_EFFECT_FLINCH
BattleScript_MoveEffectSleep, // MOVE_EFFECT_TRI_ATTACK
BattleScript_MoveEffectUproar, // MOVE_EFFECT_UPROAR
BattleScript_MoveEffectPayDay, // MOVE_EFFECT_PAYDAY
BattleScript_MoveEffectSleep, // MOVE_EFFECT_CHARGING
BattleScript_MoveEffectWrap, // MOVE_EFFECT_WRAP
2018-09-01 20:00:13 +02:00
BattleScript_MoveEffectRecoil, // MOVE_EFFECT_RECOIL_25
2017-09-26 22:39:59 +02:00
BattleScript_MoveEffectSleep, // MOVE_EFFECT_ATK_PLUS_1
BattleScript_MoveEffectSleep, // MOVE_EFFECT_DEF_PLUS_1
BattleScript_MoveEffectSleep, // MOVE_EFFECT_SPD_PLUS_1
BattleScript_MoveEffectSleep, // MOVE_EFFECT_SP_ATK_PLUS_1
BattleScript_MoveEffectSleep, // MOVE_EFFECT_SP_DEF_PLUS_1
BattleScript_MoveEffectSleep, // MOVE_EFFECT_ACC_PLUS_1
BattleScript_MoveEffectSleep, // MOVE_EFFECT_EVS_PLUS_1
BattleScript_MoveEffectSleep, // MOVE_EFFECT_ATK_MINUS_1
BattleScript_MoveEffectSleep, // MOVE_EFFECT_DEF_MINUS_1
BattleScript_MoveEffectSleep, // MOVE_EFFECT_SPD_MINUS_1
BattleScript_MoveEffectSleep, // MOVE_EFFECT_SP_ATK_MINUS_1
BattleScript_MoveEffectSleep, // MOVE_EFFECT_SP_DEF_MINUS_1
BattleScript_MoveEffectSleep, // MOVE_EFFECT_ACC_MINUS_1
BattleScript_MoveEffectSleep, // MOVE_EFFECT_EVS_MINUS_1
BattleScript_MoveEffectSleep, // MOVE_EFFECT_RECHARGE
BattleScript_MoveEffectSleep, // MOVE_EFFECT_RAGE
BattleScript_MoveEffectSleep, // MOVE_EFFECT_STEAL_ITEM
BattleScript_MoveEffectSleep, // MOVE_EFFECT_PREVENT_ESCAPE
BattleScript_MoveEffectSleep, // MOVE_EFFECT_NIGHTMARE
BattleScript_MoveEffectSleep, // MOVE_EFFECT_ALL_STATS_UP
BattleScript_MoveEffectSleep, // MOVE_EFFECT_RAPIDSPIN
BattleScript_MoveEffectSleep, // MOVE_EFFECT_REMOVE_PARALYSIS
BattleScript_MoveEffectSleep, // MOVE_EFFECT_ATK_DEF_DOWN
2018-09-01 20:00:13 +02:00
BattleScript_MoveEffectRecoil, // MOVE_EFFECT_RECOIL_33
2017-09-26 22:39:59 +02:00
};
static const struct WindowTemplate sUnusedWinTemplate = {0, 1, 3, 7, 0xF, 0x1F, 0x3F};
2017-09-28 16:51:24 +02:00
static const u16 sUnknown_0831C2C8[] = INCBIN_U16("graphics/battle_interface/unk_battlebox.gbapal");
static const u8 sUnknown_0831C2E8[] = INCBIN_U8("graphics/battle_interface/unk_battlebox.4bpp.lz");
2017-09-28 16:32:23 +02:00
// unused
static const u8 sRubyLevelUpStatBoxStats[] =
{
MON_DATA_MAX_HP, MON_DATA_SPATK, MON_DATA_ATK,
MON_DATA_SPDEF, MON_DATA_DEF, MON_DATA_SPEED
2017-09-28 16:32:23 +02:00
};
#define MON_ICON_LVLUP_BOX_TAG 0xD75A
2017-09-28 16:51:24 +02:00
static const struct OamData sOamData_MonIconOnLvlUpBox =
2017-09-28 16:32:23 +02:00
{
.y = 0,
.affineMode = 0,
.objMode = 0,
.mosaic = 0,
.bpp = 0,
.shape = 0,
.x = 0,
.matrixNum = 0,
.size = 2,
.tileNum = 0,
.priority = 0,
.paletteNum = 0,
.affineParam = 0,
};
2017-09-28 16:51:24 +02:00
static const struct SpriteTemplate sSpriteTemplate_MonIconOnLvlUpBox =
2017-09-28 16:32:23 +02:00
{
.tileTag = MON_ICON_LVLUP_BOX_TAG,
.paletteTag = MON_ICON_LVLUP_BOX_TAG,
2017-09-28 16:51:24 +02:00
.oam = &sOamData_MonIconOnLvlUpBox,
2017-09-28 16:32:23 +02:00
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCB_MonIconOnLvlUpBox
};
2017-09-28 16:51:24 +02:00
static const u16 sProtectSuccessRates[] = {USHRT_MAX, USHRT_MAX / 2, USHRT_MAX / 4, USHRT_MAX / 8};
2017-09-28 15:34:21 +02:00
#define MIMIC_FORBIDDEN_END 0xFFFE
#define METRONOME_FORBIDDEN_END 0xFFFF
#define ASSIST_FORBIDDEN_END 0xFFFF
2018-09-22 18:37:03 +02:00
#define COPYCAT_FORBIDDEN_END 0xFFFF
2017-09-28 16:51:24 +02:00
static const u16 sMovesForbiddenToCopy[] =
2017-09-28 16:32:23 +02:00
{
2018-09-22 18:37:03 +02:00
MOVE_TRANSFORM,
2017-09-28 16:32:23 +02:00
MOVE_METRONOME,
MOVE_STRUGGLE,
MOVE_SKETCH,
MOVE_MIMIC,
MIMIC_FORBIDDEN_END,
MOVE_COUNTER,
MOVE_MIRROR_COAT,
MOVE_PROTECT,
MOVE_DETECT,
MOVE_ENDURE,
MOVE_DESTINY_BOND,
MOVE_SLEEP_TALK,
MOVE_THIEF,
MOVE_FOLLOW_ME,
MOVE_SNATCH,
MOVE_HELPING_HAND,
MOVE_COVET,
MOVE_TRICK,
MOVE_FOCUS_PUNCH,
2018-09-22 18:37:03 +02:00
MOVE_CIRCLE_THROW,
MOVE_DRAGON_TAIL,
MOVE_RAGE_POWDER,
MOVE_MAT_BLOCK,
MOVE_SPIKY_SHIELD,
MOVE_SHELL_TRAP,
MOVE_SPOTLIGHT,
MOVE_FEINT,
MOVE_KING_S_SHIELD,
2017-09-28 16:32:23 +02:00
METRONOME_FORBIDDEN_END
};
static const u16 sNaturePowerMoves[] =
{
MOVE_STUN_SPORE,
MOVE_RAZOR_LEAF,
MOVE_EARTHQUAKE,
MOVE_HYDRO_PUMP,
MOVE_SURF,
MOVE_BUBBLE_BEAM,
MOVE_ROCK_SLIDE,
MOVE_SHADOW_BALL,
MOVE_SWIFT,
MOVE_SWIFT
};
2017-09-28 16:51:24 +02:00
static const u16 sPickupItems[] =
2017-09-28 16:32:23 +02:00
{
ITEM_POTION,
ITEM_ANTIDOTE,
ITEM_SUPER_POTION,
ITEM_GREAT_BALL,
ITEM_REPEL,
ITEM_ESCAPE_ROPE,
ITEM_X_ATTACK,
ITEM_FULL_HEAL,
ITEM_ULTRA_BALL,
ITEM_HYPER_POTION,
ITEM_RARE_CANDY,
ITEM_PROTEIN,
ITEM_REVIVE,
ITEM_HP_UP,
ITEM_FULL_RESTORE,
ITEM_MAX_REVIVE,
ITEM_PP_UP,
ITEM_MAX_ELIXIR,
};
2017-09-28 16:51:24 +02:00
static const u16 sRarePickupItems[] =
2017-09-28 16:32:23 +02:00
{
ITEM_HYPER_POTION,
ITEM_NUGGET,
ITEM_KINGS_ROCK,
ITEM_FULL_RESTORE,
ITEM_ETHER,
ITEM_WHITE_HERB,
2018-02-05 17:39:26 +01:00
ITEM_TM44_REST,
2017-09-28 16:32:23 +02:00
ITEM_ELIXIR,
2018-02-05 17:39:26 +01:00
ITEM_TM01_FOCUS_PUNCH,
2017-09-28 16:32:23 +02:00
ITEM_LEFTOVERS,
2018-02-05 17:39:26 +01:00
ITEM_TM26_EARTHQUAKE,
2017-09-28 16:32:23 +02:00
};
2017-09-28 16:51:24 +02:00
static const u8 sPickupProbabilities[] =
2017-09-28 16:32:23 +02:00
{
30, 40, 50, 60, 70, 80, 90, 94, 98
};
static const u8 sTerrainToType[] =
{
TYPE_GRASS, // tall grass
TYPE_GRASS, // long grass
TYPE_GROUND, // sand
TYPE_WATER, // underwater
TYPE_WATER, // water
TYPE_WATER, // pond water
2017-09-28 16:51:24 +02:00
TYPE_ROCK, // rock
TYPE_ROCK, // cave
2017-09-28 16:32:23 +02:00
TYPE_NORMAL, // building
TYPE_NORMAL, // plain
};
static const u8 sBallCatchBonuses[] =
{
20, 15, 10, 15 // Ultra, Great, Poke, Safari
};
2017-11-04 16:11:13 +01:00
const ALIGNED(4) u8 gUnknown_0831C494[][4] =
{
{0x3d, 0x44, 0x3d, 0x44},
{0x14, 0x2d, 0x54, 0x5c},
{0x46, 0x55, 0x20, 0x5c},
{0x26, 0x45, 0x46, 0x55},
{0x14, 0x5a, 0x46, 0x5c},
{0x1e, 0x32, 0x20, 0x5a},
{0x38, 0x4e, 0x38, 0x4e},
{0x19, 0x28, 0x4b, 0x5a},
{0x45, 0x4b, 0x1c, 0x53},
{0x23, 0x2d, 0x1d, 0x23},
{0x3e, 0x48, 0x1e, 0x32},
{0x3a, 0x5f, 0x58, 0x5e},
{0x22, 0x2d, 0x1d, 0x28},
{0x23, 0x28, 0x23, 0x5f},
{0x38, 0x4e, 0x38, 0x4e},
{0x23, 0x50, 0x22, 0x5e},
{0x2c, 0x5e, 0x22, 0x28},
{0x38, 0x4e, 0x38, 0x4e},
{0x1e, 0x58, 0x1e, 0x58},
{0x1e, 0x2b, 0x1b, 0x21},
{0x28, 0x5a, 0x19, 0x57},
{0x12, 0x58, 0x5a, 0x5f},
{0x58, 0x5e, 0x16, 0x2a},
{0x2a, 0x5c, 0x2a, 0x2f},
{0x38, 0x4e, 0x38, 0x4e}
2017-09-28 16:51:24 +02:00
};
static const u8 sUnknown_0831C4F8[] =
{
0x03, 0x00, 0x01, 0x00, 0x00, 0x01, 0x03, 0x00,
0x01, 0x02, 0x02, 0x00, 0x03, 0x01, 0x03, 0x01,
0x02, 0x03, 0x03, 0x02, 0x01, 0x00, 0x02, 0x02,
0x03, 0x00, 0x00, 0x00
};
2017-09-28 16:32:23 +02:00
2017-09-28 15:34:21 +02:00
static void atk00_attackcanceler(void)
{
s32 i;
2017-10-06 00:12:01 +02:00
if (gBattleOutcome != 0)
{
2018-02-06 23:09:39 +01:00
gCurrentActionFuncId = B_ACTION_FINISHED;
return;
}
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerAttacker].hp == 0 && !(gHitMarker & HITMARKER_NO_ATTACKSTRING))
{
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))
return;
2018-02-06 23:09:39 +01:00
if (!gBattleMons[gBattlerAttacker].pp[gCurrMovePos] && gCurrentMove != MOVE_STRUGGLE && !(gHitMarker & 0x800200)
&& !(gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
{
gBattlescriptCurrInstr = BattleScript_NoPPForMove;
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
return;
}
gHitMarker &= ~(HITMARKER_x800000);
2018-02-06 23:09:39 +01:00
if (!(gHitMarker & HITMARKER_OBEYS) && !(gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
{
2017-12-02 14:08:55 +01:00
i = IsMonDisobedient(); // why use the 'i' variable...?
switch (i)
{
case 0:
break;
case 2:
gHitMarker |= HITMARKER_OBEYS;
return;
default:
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
return;
}
}
gHitMarker |= HITMARKER_OBEYS;
2018-07-28 10:41:20 +02:00
if (gProtectStructs[gBattlerTarget].bounceMove
&& gBattleMoves[gCurrentMove].flags & FLAG_MAGICCOAT_AFFECTED
&& !gProtectStructs[gBattlerAttacker].usesBouncedMove)
{
2018-02-06 23:09:39 +01:00
PressurePPLose(gBattlerAttacker, gBattlerTarget, MOVE_MAGIC_COAT);
gProtectStructs[gBattlerTarget].bounceMove = 0;
2018-07-28 10:41:20 +02:00
gProtectStructs[gBattlerTarget].usesBouncedMove = 1;
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MagicCoatBounce;
return;
}
else if (GetBattlerAbility(gBattlerTarget) == ABILITY_MAGIC_BOUNCE
&& gBattleMoves[gCurrentMove].flags & FLAG_MAGICCOAT_AFFECTED
&& !gProtectStructs[gBattlerAttacker].usesBouncedMove)
{
RecordAbilityBattle(gBattlerTarget, ABILITY_MAGIC_BOUNCE);
gProtectStructs[gBattlerTarget].usesBouncedMove = 1;
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MagicCoatBounce;
return;
}
2018-02-06 02:46:59 +01:00
for (i = 0; i < gBattlersCount; i++)
{
2018-06-28 21:06:32 +02:00
if ((gProtectStructs[gBattlerByTurnOrder[i]].stealMove) && gBattleMoves[gCurrentMove].flags & FLAG_SNATCH_AFFECTED)
{
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();
gBattlescriptCurrInstr = BattleScript_SnatchedMove;
return;
}
}
2018-02-06 23:09:39 +01:00
if (gSpecialStatuses[gBattlerTarget].lightningRodRedirected)
{
2018-02-06 23:09:39 +01:00
gSpecialStatuses[gBattlerTarget].lightningRodRedirected = 0;
gLastUsedAbility = ABILITY_LIGHTNING_ROD;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_TookAttack;
2018-07-22 19:34:13 +02:00
RecordAbilityBattle(gBattlerTarget, gLastUsedAbility);
}
else if (gSpecialStatuses[gBattlerTarget].stormDrainRedirected)
{
gSpecialStatuses[gBattlerTarget].stormDrainRedirected = 0;
gLastUsedAbility = ABILITY_STORM_DRAIN;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_TookAttack;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle(gBattlerTarget, gLastUsedAbility);
}
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))))
{
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;
gBattleCommunication[6] = 1;
gBattlescriptCurrInstr++;
}
else
{
gBattlescriptCurrInstr++;
}
}
2018-07-22 18:40:18 +02:00
static bool32 JumpIfMoveFailed(u8 adder, u16 move)
{
2018-01-16 22:12:38 +01:00
if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
{
2018-02-06 23:09:39 +01:00
gLastLandedMoves[gBattlerTarget] = 0;
gLastHitByType[gBattlerTarget] = 0;
2018-07-22 18:40:18 +02:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
return TRUE;
}
else
{
TrySetDestinyBondToHappen();
2018-02-06 23:09:39 +01:00
if (AbilityBattleEffects(ABILITYEFFECT_ABSORBING, gBattlerTarget, 0, 0, move))
2018-07-22 18:40:18 +02:00
return TRUE;
}
2018-07-22 18:40:18 +02:00
gBattlescriptCurrInstr += adder;
return FALSE;
}
static void atk40_jumpifaffectedbyprotect(void)
{
2018-01-16 22:12:38 +01:00
if (DEFENDER_IS_PROTECTED)
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
JumpIfMoveFailed(5, 0);
gBattleCommunication[6] = 1;
}
else
{
gBattlescriptCurrInstr += 5;
}
}
bool8 JumpIfMoveAffectedByProtect(u16 move)
{
bool8 affected = FALSE;
2018-01-16 22:12:38 +01:00
if (DEFENDER_IS_PROTECTED)
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
JumpIfMoveFailed(7, move);
gBattleCommunication[6] = 1;
affected = TRUE;
}
return affected;
}
2018-07-22 18:40:18 +02:00
static bool32 AccuracyCalcHelper(u16 move)
{
2018-02-06 23:09:39 +01:00
if (gStatuses3[gBattlerTarget] & STATUS3_ALWAYS_HITS && gDisableStructs[gBattlerTarget].battlerWithSureHit == gBattlerAttacker)
{
JumpIfMoveFailed(7, move);
return TRUE;
}
2018-07-22 15:08:32 +02:00
else if (gBattleMoves[move].effect == EFFECT_TOXIC && IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_POISON))
{
JumpIfMoveFailed(7, move);
return TRUE;
}
2018-07-22 18:40:18 +02:00
else if (GetBattlerAbility(gBattlerAttacker) == ABILITY_NO_GUARD)
{
if (!JumpIfMoveFailed(7, move))
RecordAbilityBattle(gBattlerAttacker, ABILITY_NO_GUARD);
return TRUE;
}
else if (GetBattlerAbility(gBattlerTarget) == ABILITY_NO_GUARD)
{
if (!JumpIfMoveFailed(7, move))
RecordAbilityBattle(gBattlerTarget, ABILITY_NO_GUARD);
return TRUE;
}
2018-02-06 23:09:39 +01:00
if (!(gHitMarker & HITMARKER_IGNORE_ON_AIR) && gStatuses3[gBattlerTarget] & STATUS3_ON_AIR)
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
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)
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
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)
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
JumpIfMoveFailed(7, move);
return TRUE;
}
gHitMarker &= ~HITMARKER_IGNORE_UNDERWATER;
2018-08-05 13:39:22 +02:00
if ((WEATHER_HAS_EFFECT && (gBattleWeather & WEATHER_RAIN_ANY) && (gBattleMoves[move].effect == EFFECT_THUNDER || gBattleMoves[move].effect == EFFECT_HURRICANE))
2018-08-11 12:16:00 +02:00
|| (gBattleMoves[move].effect == EFFECT_VITAL_THROW)
|| (gBattleMoves[move].accuracy == 0))
{
JumpIfMoveFailed(7, move);
return TRUE;
}
return FALSE;
}
2017-09-28 15:34:21 +02:00
static void atk01_accuracycheck(void)
{
2018-03-01 00:59:52 +01:00
u16 move = T2_READ_16(gBattlescriptCurrInstr + 5);
2018-08-01 22:39:42 +02:00
if (move == ACC_CURR_MOVE)
move = gCurrentMove;
2018-08-11 12:16:00 +02:00
if (move == NO_ACC_CALC_CHECK_LOCK_ON)
{
if (gStatuses3[gBattlerTarget] & STATUS3_ALWAYS_HITS && gDisableStructs[gBattlerTarget].battlerWithSureHit == gBattlerAttacker)
gBattlescriptCurrInstr += 7;
else if (gStatuses3[gBattlerTarget] & (STATUS3_SEMI_INVULNERABLE))
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
else if (!JumpIfMoveAffectedByProtect(0))
gBattlescriptCurrInstr += 7;
}
else
{
2018-07-22 15:08:32 +02:00
u8 type, moveAcc, atkHoldEffect, atkParam, defHoldEffect, defParam, atkAbility, defAbility;
s8 buff, accStage, evasionStage;
u32 calc;
GET_MOVE_TYPE(move, type);
if (JumpIfMoveAffectedByProtect(move))
return;
if (AccuracyCalcHelper(move))
return;
2018-07-22 15:08:32 +02:00
atkAbility = GetBattlerAbility(gBattlerAttacker);
defAbility = GetBattlerAbility(gBattlerTarget);
accStage = gBattleMons[gBattlerAttacker].statStages[STAT_ACC];
evasionStage = gBattleMons[gBattlerTarget].statStages[STAT_EVASION];
if (atkAbility == ABILITY_UNAWARE)
evasionStage = 6;
if (gBattleMoves[move].flags & FLAG_STAT_STAGES_IGNORED)
evasionStage = 6;
if (defAbility == ABILITY_UNAWARE)
accStage = 6;
if (gBattleMons[gBattlerTarget].status2 & STATUS2_FORESIGHT || gStatuses3[gBattlerTarget] & STATUS3_MIRACLE_EYED)
buff = accStage;
else
2018-07-22 15:08:32 +02:00
buff = accStage + 6 - evasionStage;
if (buff < 0)
buff = 0;
if (buff > 0xC)
buff = 0xC;
moveAcc = gBattleMoves[move].accuracy;
2018-08-05 13:39:22 +02:00
// Check Thunder and Hurricane on sunny weather.
if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SUN_ANY && (gBattleMoves[move].effect == EFFECT_THUNDER || gBattleMoves[move].effect == EFFECT_HURRICANE))
moveAcc = 50;
2018-07-26 21:56:23 +02:00
// Check Wonder Skin.
if (defAbility == ABILITY_WONDER_SKIN && gBattleMoves[move].power == 0)
moveAcc = 50;
2017-09-28 16:51:24 +02:00
calc = sAccuracyStageRatios[buff].dividend * moveAcc;
calc /= sAccuracyStageRatios[buff].divisor;
2018-07-22 15:08:32 +02:00
if (atkAbility == ABILITY_COMPOUND_EYES)
calc = (calc * 130) / 100; // 1.3 compound eyes boost
2018-07-22 15:08:32 +02:00
else if (atkAbility == ABILITY_VICTORY_STAR)
calc = (calc * 110) / 100; // 1.1 victory star boost
if (IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker)) && GetBattlerAbility(BATTLE_PARTNER(gBattlerAttacker)) == ABILITY_VICTORY_STAR)
calc = (calc * 110) / 100; // 1.1 ally's victory star boost
if (defAbility == ABILITY_SAND_VEIL && WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SANDSTORM_ANY)
calc = (calc * 80) / 100; // 1.2 sand veil loss
2018-07-22 15:08:32 +02:00
else if (defAbility == ABILITY_SNOW_CLOAK && WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_HAIL_ANY)
calc = (calc * 80) / 100; // 1.2 snow cloak loss
else if (defAbility == ABILITY_TANGLED_FEET && gBattleMons[gBattlerTarget].status2 & STATUS2_CONFUSION)
calc = (calc * 50) / 100; // 1.5 tangled feet loss
2018-07-16 22:45:06 +02:00
2018-07-22 15:08:32 +02:00
if (atkAbility == ABILITY_HUSTLE && IS_MOVE_PHYSICAL(move))
calc = (calc * 80) / 100; // 1.2 hustle loss
2018-07-22 15:08:32 +02:00
defHoldEffect = GetBattlerHoldEffect(gBattlerTarget, TRUE);
defParam = GetBattlerHoldEffectParam(gBattlerTarget);
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerTarget;
2018-07-22 15:08:32 +02:00
atkHoldEffect = GetBattlerHoldEffect(gBattlerAttacker, TRUE);
atkParam = GetBattlerHoldEffectParam(gBattlerAttacker);
if (defHoldEffect == HOLD_EFFECT_EVASION_UP)
calc = (calc * (100 - defParam)) / 100;
if (atkHoldEffect == HOLD_EFFECT_WIDE_LENS)
calc = (calc * (100 + atkParam)) / 100;
else if (atkHoldEffect == HOLD_EFFECT_ZOOM_LENS && GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget));
calc = (calc * (100 + atkParam)) / 100;
// final calculation
if ((Random() % 100 + 1) > calc)
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE &&
(gBattleMoves[move].target == MOVE_TARGET_BOTH || gBattleMoves[move].target == MOVE_TARGET_FOES_AND_ALLY))
gBattleCommunication[6] = 2;
else
gBattleCommunication[6] = 0;
2018-08-01 22:39:42 +02:00
CalcTypeEffectivenessMultiplier(move, type, gBattlerAttacker, gBattlerTarget, TRUE);
}
JumpIfMoveFailed(7, move);
}
}
2017-09-28 15:34:21 +02:00
static void atk02_attackstring(void)
{
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags)
return;
if (!(gHitMarker & (HITMARKER_NO_ATTACKSTRING | HITMARKER_ATTACKSTRING_PRINTED)))
{
2018-02-06 23:09:39 +01:00
PrepareStringBattle(STRINGID_USEDMOVE, gBattlerAttacker);
gHitMarker |= HITMARKER_ATTACKSTRING_PRINTED;
}
gBattlescriptCurrInstr++;
gBattleCommunication[MSG_DISPLAY] = 0;
}
2017-09-20 00:28:00 +02:00
2017-09-28 15:34:21 +02:00
static void atk03_ppreduce(void)
2017-09-20 00:28:00 +02:00
{
2017-09-27 23:43:45 +02:00
s32 ppToDeduct = 1;
2017-09-20 00:28:00 +02:00
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags)
2017-09-20 00:28:00 +02:00
return;
2018-02-06 23:09:39 +01:00
if (!gSpecialStatuses[gBattlerAttacker].flag20)
2017-09-20 00:28:00 +02:00
{
switch (gBattleMoves[gCurrentMove].target)
{
case MOVE_TARGET_FOES_AND_ALLY:
2018-02-06 23:09:39 +01:00
ppToDeduct += AbilityBattleEffects(ABILITYEFFECT_COUNT_ON_FIELD, gBattlerAttacker, ABILITY_PRESSURE, 0, 0);
2017-09-20 00:28:00 +02:00
break;
case MOVE_TARGET_BOTH:
case MOVE_TARGET_OPPONENTS_FIELD:
2018-02-06 23:09:39 +01:00
ppToDeduct += AbilityBattleEffects(ABILITYEFFECT_COUNT_OTHER_SIDE, gBattlerAttacker, ABILITY_PRESSURE, 0, 0);
2017-09-20 00:28:00 +02:00
break;
default:
2018-02-06 23:09:39 +01:00
if (gBattlerAttacker != gBattlerTarget && gBattleMons[gBattlerTarget].ability == ABILITY_PRESSURE)
2017-09-27 23:43:45 +02:00
ppToDeduct++;
2017-09-20 00:28:00 +02:00
break;
}
}
2018-02-06 23:09:39 +01:00
if (!(gHitMarker & (HITMARKER_NO_PPDEDUCT | HITMARKER_NO_ATTACKSTRING)) && gBattleMons[gBattlerAttacker].pp[gCurrMovePos])
2017-09-20 00:28:00 +02:00
{
2018-02-06 23:09:39 +01:00
gProtectStructs[gBattlerAttacker].notFirstStrike = 1;
2017-09-20 00:28:00 +02:00
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerAttacker].pp[gCurrMovePos] > ppToDeduct)
gBattleMons[gBattlerAttacker].pp[gCurrMovePos] -= ppToDeduct;
2017-09-20 00:28:00 +02:00
else
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerAttacker].pp[gCurrMovePos] = 0;
2017-09-20 00:28:00 +02:00
2018-02-06 23:09:39 +01:00
if (!(gBattleMons[gBattlerAttacker].status2 & STATUS2_TRANSFORMED)
&& !((gDisableStructs[gBattlerAttacker].unk18_b) & gBitTable[gCurrMovePos]))
2017-09-20 00:28:00 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
BtlController_EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + gCurrMovePos, 0, 1, &gBattleMons[gBattlerAttacker].pp[gCurrMovePos]);
MarkBattlerForControllerExec(gBattlerAttacker);
2017-09-20 00:28:00 +02:00
}
}
gHitMarker &= ~(HITMARKER_NO_PPDEDUCT);
gBattlescriptCurrInstr++;
}
2018-07-23 21:36:05 +02:00
s32 CalcCritChanceStage(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbility)
2017-09-20 00:28:00 +02:00
{
2018-07-23 21:36:05 +02:00
s32 critChance = 0;
u32 abilityAtk = GetBattlerAbility(gBattlerAttacker);
u32 abilityDef = GetBattlerAbility(gBattlerTarget);
2017-09-20 00:28:00 +02:00
2018-07-23 21:36:05 +02:00
if (gSideStatuses[battlerDef] & SIDE_STATUS_LUCKY_CHANT
|| gStatuses3[gBattlerAttacker] & STATUS3_CANT_SCORE_A_CRIT)
{
critChance = -1;
}
else if (abilityDef == ABILITY_BATTLE_ARMOR || abilityDef == ABILITY_SHELL_ARMOR)
{
if (recordAbility)
RecordAbilityBattle(battlerDef, abilityDef);
critChance = -1;
}
else if (gStatuses3[battlerAtk] & STATUS3_LASER_FOCUS
|| gBattleMoves[move].effect == EFFECT_ALWAYS_CRIT
|| (abilityAtk == ABILITY_MERCILESS && gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY))
{
2018-07-23 22:18:56 +02:00
critChance = -2;
2018-07-23 21:36:05 +02:00
}
2017-09-20 00:28:00 +02:00
else
2018-07-23 21:36:05 +02:00
{
u32 holdEffectAtk = GetBattlerHoldEffect(battlerAtk, TRUE);
critChance = 2 * ((gBattleMons[gBattlerAttacker].status2 & STATUS2_FOCUS_ENERGY) != 0)
+ ((gBattleMoves[gCurrentMove].flags & FLAG_HIGH_CRIT) != 0)
+ (holdEffectAtk == HOLD_EFFECT_SCOPE_LENS)
+ 2 * (holdEffectAtk == HOLD_EFFECT_LUCKY_PUNCH && gBattleMons[gBattlerAttacker].species == SPECIES_CHANSEY)
+ 2 * (holdEffectAtk == HOLD_EFFECT_STICK && gBattleMons[gBattlerAttacker].species == SPECIES_FARFETCHD)
+ (abilityAtk == ABILITY_SUPER_LUCK);
}
2017-09-20 00:28:00 +02:00
if (critChance > 4)
critChance = 4;
2018-07-23 21:36:05 +02:00
return critChance;
}
// The chance is 1/N for each stage.
#if B_CRIT_CHANCE == GEN_7
static const u8 sCriticalHitChance[] = {24, 8, 2, 1, 1};
#elif B_CRIT_CHANCE == GEN_6
static const u8 sCriticalHitChance[] = {16, 8, 2, 1, 1};
#else
static const u8 sCriticalHitChance[] = {16, 8, 4, 3, 2}; // Gens 2,3,4,5
#endif // B_CRIT_CHANCE
2018-07-23 21:36:05 +02:00
static void atk04_critcalc(void)
{
s32 critChance = CalcCritChanceStage(gBattlerAttacker, gBattlerTarget, gCurrentMove, TRUE);
gPotentialItemEffectBattler = gBattlerAttacker;
if (gBattleTypeFlags & (BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_FIRST_BATTLE))
gIsCriticalHit = FALSE;
else if (critChance == -1)
gIsCriticalHit = FALSE;
2018-07-23 22:18:56 +02:00
else if (critChance == -2)
gIsCriticalHit = TRUE;
else if (Random() % sCriticalHitChance[critChance] == 0)
2018-07-14 22:56:03 +02:00
gIsCriticalHit = TRUE;
2017-09-20 00:28:00 +02:00
else
2018-07-14 22:56:03 +02:00
gIsCriticalHit = FALSE;
2017-09-20 00:28:00 +02:00
gBattlescriptCurrInstr++;
}
static void atk05_damagecalc(void)
2017-09-20 00:28:00 +02:00
{
2018-07-14 19:29:25 +02:00
u8 moveType;
2017-09-20 00:28:00 +02:00
2018-07-14 19:29:25 +02:00
GET_MOVE_TYPE(gCurrentMove, moveType);
2018-07-14 22:56:03 +02:00
gBattleMoveDamage = CalculateMoveDamage(gCurrentMove, gBattlerAttacker, gBattlerTarget, moveType, 0, gIsCriticalHit, TRUE);
2017-09-20 00:28:00 +02:00
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atk06_typecalc(void)
2017-09-20 00:28:00 +02:00
{
u8 moveType;
GET_MOVE_TYPE(gCurrentMove, moveType);
2018-07-15 12:39:07 +02:00
CalcTypeEffectivenessMultiplier(gCurrentMove, moveType, gBattlerAttacker, gBattlerTarget, TRUE);
2017-09-20 00:28:00 +02:00
gBattlescriptCurrInstr++;
}
2018-07-14 22:56:03 +02:00
static void atk07_adjustdamage(void)
2017-09-20 00:28:00 +02:00
{
2018-02-08 11:17:41 +01:00
u8 holdEffect, param;
2017-09-20 00:28:00 +02:00
2018-08-02 20:24:18 +02:00
if (DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove))
2017-09-20 00:28:00 +02:00
goto END;
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].hp > gBattleMoveDamage)
2017-09-20 00:28:00 +02:00
goto END;
2018-07-21 15:11:13 +02:00
holdEffect = GetBattlerHoldEffect(gBattlerTarget, TRUE);
param = GetBattlerHoldEffectParam(gBattlerTarget);
gPotentialItemEffectBattler = gBattlerTarget;
2018-02-08 11:17:41 +01:00
if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < param)
2017-09-20 00:28:00 +02:00
{
2018-02-06 23:09:39 +01:00
RecordItemEffectBattle(gBattlerTarget, holdEffect);
gSpecialStatuses[gBattlerTarget].focusBanded = 1;
2017-09-20 00:28:00 +02:00
}
2018-07-14 22:56:03 +02:00
else if (holdEffect == HOLD_EFFECT_FOCUS_SASH && BATTLER_MAX_HP(gBattlerTarget))
{
RecordItemEffectBattle(gBattlerTarget, holdEffect);
gSpecialStatuses[gBattlerTarget].focusSashed = 1;
}
2018-07-21 15:11:13 +02:00
else if (GetBattlerAbility(gBattlerTarget) == ABILITY_STURDY && BATTLER_MAX_HP(gBattlerTarget))
{
RecordAbilityBattle(gBattlerTarget, ABILITY_STURDY);
gSpecialStatuses[gBattlerTarget].sturdied = 1;
}
2018-07-14 22:56:03 +02:00
if (gBattleMoves[gCurrentMove].effect != EFFECT_FALSE_SWIPE
&& !gProtectStructs[gBattlerTarget].endured
&& !gSpecialStatuses[gBattlerTarget].focusBanded
2018-07-21 15:11:13 +02:00
&& !gSpecialStatuses[gBattlerTarget].focusSashed
&& !gSpecialStatuses[gBattlerTarget].sturdied)
2017-09-20 00:28:00 +02:00
goto END;
2018-07-21 15:11:13 +02:00
// Handle reducing the dmg to 1 hp.
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - 1;
2017-09-20 00:28:00 +02:00
2018-02-06 23:09:39 +01:00
if (gProtectStructs[gBattlerTarget].endured)
2017-09-20 00:28:00 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_FOE_ENDURED;
2017-09-20 00:28:00 +02:00
}
2018-07-14 22:56:03 +02:00
else if (gSpecialStatuses[gBattlerTarget].focusBanded || gSpecialStatuses[gBattlerTarget].focusSashed)
2017-09-20 00:28:00 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_FOE_HUNG_ON;
2018-02-06 23:09:39 +01:00
gLastUsedItem = gBattleMons[gBattlerTarget].item;
2017-09-20 00:28:00 +02:00
}
2018-07-21 15:11:13 +02:00
else if (gSpecialStatuses[gBattlerTarget].sturdied)
{
gMoveResultFlags |= MOVE_RESULT_STURDIED;
gLastUsedAbility = ABILITY_STURDY;
}
2017-09-20 00:28:00 +02:00
2018-07-14 22:56:03 +02:00
END:
gBattlescriptCurrInstr++;
}
2018-07-21 15:11:13 +02:00
static void atk08_multihitresultmessage(void)
2018-07-14 22:56:03 +02:00
{
2018-07-21 15:11:13 +02:00
if (gBattleControllerExecFlags)
return;
2018-07-14 22:56:03 +02:00
2018-07-21 15:11:13 +02:00
if (!(gMoveResultFlags & MOVE_RESULT_FAILED) && !(gMoveResultFlags & MOVE_RESULT_FOE_ENDURED))
{
if (gMoveResultFlags & MOVE_RESULT_STURDIED)
{
gMoveResultFlags &= ~(MOVE_RESULT_STURDIED | MOVE_RESULT_FOE_HUNG_ON);
gSpecialStatuses[gBattlerTarget].sturdied = 0; // Delete this line to make Sturdy last for the duration of the whole move turn.
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_SturdiedMsg;
return;
}
else if (gMoveResultFlags & MOVE_RESULT_FOE_HUNG_ON)
{
gLastUsedItem = gBattleMons[gBattlerTarget].item;
gPotentialItemEffectBattler = gBattlerTarget;
gMoveResultFlags &= ~(MOVE_RESULT_STURDIED | MOVE_RESULT_FOE_HUNG_ON);
gSpecialStatuses[gBattlerTarget].focusBanded = 0; // Delete this line to make Focus Band last for the duration of the whole move turn.
gSpecialStatuses[gBattlerTarget].focusSashed = 0; // Delete this line to make Focus Sash last for the duration of the whole move turn.
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_HangedOnMsg;
return;
}
}
gBattlescriptCurrInstr++;
2017-09-20 00:28:00 +02:00
}
2017-09-28 15:34:21 +02:00
static void atk09_attackanimation(void)
2017-09-20 00:28:00 +02:00
{
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags)
2017-09-20 00:28:00 +02:00
return;
if ((gHitMarker & HITMARKER_NO_ANIMATIONS) && (gCurrentMove != MOVE_TRANSFORM && gCurrentMove != MOVE_SUBSTITUTE))
{
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
2017-09-20 00:28:00 +02:00
gBattlescriptCurrInstr = BattleScript_Pausex20;
gBattleScripting.animTurn++;
gBattleScripting.animTargetsHit++;
}
else
{
if ((gBattleMoves[gCurrentMove].target & MOVE_TARGET_BOTH
|| gBattleMoves[gCurrentMove].target & MOVE_TARGET_FOES_AND_ALLY
|| gBattleMoves[gCurrentMove].target & MOVE_TARGET_DEPENDS)
&& gBattleScripting.animTargetsHit)
{
gBattlescriptCurrInstr++;
return;
}
2018-01-16 22:12:38 +01:00
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
2017-09-20 00:28:00 +02:00
{
u8 multihit;
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2017-09-20 00:28:00 +02:00
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].status2 & STATUS2_SUBSTITUTE)
2017-09-20 00:28:00 +02:00
multihit = gMultiHitCounter;
else if (gMultiHitCounter != 0 && gMultiHitCounter != 1)
{
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].hp <= gBattleMoveDamage)
2017-09-20 00:28:00 +02:00
multihit = 1;
else
multihit = gMultiHitCounter;
}
else
multihit = gMultiHitCounter;
2018-02-06 23:09:39 +01:00
BtlController_EmitMoveAnimation(0, gCurrentMove, gBattleScripting.animTurn, gBattleMovePower, gBattleMoveDamage, gBattleMons[gBattlerAttacker].friendship, &gDisableStructs[gBattlerAttacker], multihit);
2017-09-20 00:28:00 +02:00
gBattleScripting.animTurn += 1;
gBattleScripting.animTargetsHit += 1;
2018-02-06 23:09:39 +01:00
MarkBattlerForControllerExec(gBattlerAttacker);
2017-09-20 00:28:00 +02:00
gBattlescriptCurrInstr++;
}
else
{
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
2017-09-20 00:28:00 +02:00
gBattlescriptCurrInstr = BattleScript_Pausex20;
}
}
}
2017-09-28 15:34:21 +02:00
static void atk0A_waitanimation(void)
2017-09-20 00:28:00 +02:00
{
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags == 0)
2017-09-20 00:28:00 +02:00
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atk0B_healthbarupdate(void)
2017-09-20 00:28:00 +02:00
{
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags)
2017-09-20 12:56:45 +02:00
return;
2018-01-16 22:12:38 +01:00
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
2017-09-20 12:56:45 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2017-09-20 12:56:45 +02:00
2018-08-02 20:24:18 +02:00
if (DoesSubstituteBlockMove(gBattlerAttacker, gActiveBattler, gCurrentMove) && gDisableStructs[gActiveBattler].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE))
2017-09-20 12:56:45 +02:00
{
2018-02-06 02:46:59 +01:00
PrepareStringBattle(STRINGID_SUBSTITUTEDAMAGED, gActiveBattler);
2017-09-20 12:56:45 +02:00
}
else
{
s16 healthValue;
s32 currDmg = gBattleMoveDamage;
s32 maxPossibleDmgValue = 10000; // not present in R/S, ensures that huge damage values don't change sign
if (currDmg <= maxPossibleDmgValue)
healthValue = currDmg;
else
healthValue = maxPossibleDmgValue;
2018-02-06 20:48:02 +01:00
BtlController_EmitHealthBarUpdate(0, healthValue);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-20 12:56:45 +02:00
2018-02-06 02:46:59 +01:00
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER && gBattleMoveDamage > 0)
2017-09-20 12:56:45 +02:00
gBattleResults.unk5_0 = 1;
}
}
gBattlescriptCurrInstr += 2;
}
2017-09-28 15:34:21 +02:00
static void atk0C_datahpupdate(void)
2017-09-20 12:56:45 +02:00
{
u32 moveType;
2017-09-20 00:28:00 +02:00
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags)
2017-09-20 00:28:00 +02:00
return;
2017-09-20 12:56:45 +02:00
if (gBattleStruct->dynamicMoveType == 0)
moveType = gBattleMoves[gCurrentMove].type;
else if (!(gBattleStruct->dynamicMoveType & 0x40))
moveType = gBattleStruct->dynamicMoveType & 0x3F;
else
moveType = gBattleMoves[gCurrentMove].type;
2017-09-20 00:28:00 +02:00
2018-01-16 22:12:38 +01:00
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
2017-09-20 00:28:00 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-08-02 20:24:18 +02:00
if (DoesSubstituteBlockMove(gBattlerAttacker, gActiveBattler, gCurrentMove) && gDisableStructs[gActiveBattler].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE))
2017-09-20 12:56:45 +02:00
{
2018-02-06 02:46:59 +01:00
if (gDisableStructs[gActiveBattler].substituteHP >= gBattleMoveDamage)
2017-09-20 12:56:45 +02:00
{
2018-02-07 22:53:40 +01:00
if (gSpecialStatuses[gActiveBattler].dmg == 0)
gSpecialStatuses[gActiveBattler].dmg = gBattleMoveDamage;
2018-02-06 02:46:59 +01:00
gDisableStructs[gActiveBattler].substituteHP -= gBattleMoveDamage;
2017-09-20 12:56:45 +02:00
gHpDealt = gBattleMoveDamage;
}
else
{
2018-02-07 22:53:40 +01:00
if (gSpecialStatuses[gActiveBattler].dmg == 0)
gSpecialStatuses[gActiveBattler].dmg = gDisableStructs[gActiveBattler].substituteHP;
2018-02-06 02:46:59 +01:00
gHpDealt = gDisableStructs[gActiveBattler].substituteHP;
gDisableStructs[gActiveBattler].substituteHP = 0;
2017-09-20 12:56:45 +02:00
}
// check substitute fading
2018-02-06 02:46:59 +01:00
if (gDisableStructs[gActiveBattler].substituteHP == 0)
2017-09-20 12:56:45 +02:00
{
gBattlescriptCurrInstr += 2;
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor();
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr = BattleScript_SubstituteFade;
return;
}
}
else
{
gHitMarker &= ~(HITMARKER_IGNORE_SUBSTITUTE);
if (gBattleMoveDamage < 0) // hp goes up
{
2018-02-06 02:46:59 +01:00
gBattleMons[gActiveBattler].hp -= gBattleMoveDamage;
if (gBattleMons[gActiveBattler].hp > gBattleMons[gActiveBattler].maxHP)
gBattleMons[gActiveBattler].hp = gBattleMons[gActiveBattler].maxHP;
2017-09-20 12:56:45 +02:00
}
else // hp goes down
{
if (gHitMarker & HITMARKER_x20)
{
gHitMarker &= ~(HITMARKER_x20);
}
else
{
2018-02-06 02:46:59 +01:00
gTakenDmg[gActiveBattler] += gBattleMoveDamage;
2018-02-08 11:17:41 +01:00
if (gBattlescriptCurrInstr[1] == BS_TARGET)
2018-02-07 22:53:40 +01:00
gTakenDmgByBattler[gActiveBattler] = gBattlerAttacker;
2017-09-20 12:56:45 +02:00
else
2018-02-07 22:53:40 +01:00
gTakenDmgByBattler[gActiveBattler] = gBattlerTarget;
2017-09-20 12:56:45 +02:00
}
2018-02-06 02:46:59 +01:00
if (gBattleMons[gActiveBattler].hp > gBattleMoveDamage)
2017-09-20 12:56:45 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons[gActiveBattler].hp -= gBattleMoveDamage;
2017-09-20 12:56:45 +02:00
gHpDealt = gBattleMoveDamage;
}
else
{
2018-02-06 02:46:59 +01:00
gHpDealt = gBattleMons[gActiveBattler].hp;
gBattleMons[gActiveBattler].hp = 0;
2017-09-20 12:56:45 +02:00
}
2018-02-07 22:53:40 +01:00
if (!gSpecialStatuses[gActiveBattler].dmg && !(gHitMarker & HITMARKER_x100000))
gSpecialStatuses[gActiveBattler].dmg = gHpDealt;
2017-09-20 12:56:45 +02:00
2018-07-16 21:04:56 +02:00
if (IS_MOVE_PHYSICAL(gCurrentMove) && !(gHitMarker & HITMARKER_x100000) && gCurrentMove != MOVE_PAIN_SPLIT)
2017-09-20 12:56:45 +02:00
{
2018-02-06 02:46:59 +01:00
gProtectStructs[gActiveBattler].physicalDmg = gHpDealt;
2018-02-07 22:53:40 +01:00
gSpecialStatuses[gActiveBattler].physicalDmg = gHpDealt;
2018-02-08 11:17:41 +01:00
if (gBattlescriptCurrInstr[1] == BS_TARGET)
2017-09-20 12:56:45 +02:00
{
2018-02-07 22:53:40 +01:00
gProtectStructs[gActiveBattler].physicalBattlerId = gBattlerAttacker;
gSpecialStatuses[gActiveBattler].physicalBattlerId = gBattlerAttacker;
2017-09-20 12:56:45 +02:00
}
else
{
2018-02-07 22:53:40 +01:00
gProtectStructs[gActiveBattler].physicalBattlerId = gBattlerTarget;
gSpecialStatuses[gActiveBattler].physicalBattlerId = gBattlerTarget;
2017-09-20 12:56:45 +02:00
}
}
2018-07-16 21:04:56 +02:00
else if (!IS_MOVE_PHYSICAL(gCurrentMove) && !(gHitMarker & HITMARKER_x100000))
2017-09-20 12:56:45 +02:00
{
2018-02-06 02:46:59 +01:00
gProtectStructs[gActiveBattler].specialDmg = gHpDealt;
2018-02-07 22:53:40 +01:00
gSpecialStatuses[gActiveBattler].specialDmg = gHpDealt;
2018-02-08 11:17:41 +01:00
if (gBattlescriptCurrInstr[1] == BS_TARGET)
2017-09-20 12:56:45 +02:00
{
2018-02-07 22:53:40 +01:00
gProtectStructs[gActiveBattler].specialBattlerId = gBattlerAttacker;
gSpecialStatuses[gActiveBattler].specialBattlerId = gBattlerAttacker;
2017-09-20 12:56:45 +02:00
}
else
{
2018-02-07 22:53:40 +01:00
gProtectStructs[gActiveBattler].specialBattlerId = gBattlerTarget;
gSpecialStatuses[gActiveBattler].specialBattlerId = gBattlerTarget;
2017-09-20 12:56:45 +02:00
}
}
}
gHitMarker &= ~(HITMARKER_x100000);
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData(0, REQUEST_HP_BATTLE, 0, 2, &gBattleMons[gActiveBattler].hp);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-20 12:56:45 +02:00
}
}
else
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-02-07 22:53:40 +01:00
if (gSpecialStatuses[gActiveBattler].dmg == 0)
gSpecialStatuses[gActiveBattler].dmg = 0xFFFF;
2017-09-20 12:56:45 +02:00
}
gBattlescriptCurrInstr += 2;
}
2017-09-28 15:34:21 +02:00
static void atk0D_critmessage(void)
2017-09-20 12:56:45 +02:00
{
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags == 0)
2017-09-20 12:56:45 +02:00
{
2018-07-14 22:56:03 +02:00
if (gIsCriticalHit == TRUE && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
2017-09-20 12:56:45 +02:00
{
2018-02-06 23:09:39 +01:00
PrepareStringBattle(STRINGID_CRITICALHIT, gBattlerAttacker);
2017-09-20 12:56:45 +02:00
gBattleCommunication[MSG_DISPLAY] = 1;
}
gBattlescriptCurrInstr++;
}
}
static void atk0E_effectivenesssound(void)
2017-09-20 12:56:45 +02:00
{
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags)
2017-09-20 12:56:45 +02:00
return;
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget;
2018-01-16 22:12:38 +01:00
if (!(gMoveResultFlags & MOVE_RESULT_MISSED))
2017-09-20 12:56:45 +02:00
{
2018-08-01 22:39:42 +02:00
switch (gMoveResultFlags & (~(MOVE_RESULT_MISSED)))
2017-09-20 12:56:45 +02:00
{
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_SUPER_EFFECTIVE:
2018-02-06 20:48:02 +01:00
BtlController_EmitPlaySE(0, SE_KOUKA_H);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-20 12:56:45 +02:00
break;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_NOT_VERY_EFFECTIVE:
2018-02-06 20:48:02 +01:00
BtlController_EmitPlaySE(0, SE_KOUKA_L);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-20 12:56:45 +02:00
break;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_DOESNT_AFFECT_FOE:
case MOVE_RESULT_FAILED:
2017-09-20 12:56:45 +02:00
// no sound
break;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_FOE_ENDURED:
case MOVE_RESULT_ONE_HIT_KO:
case MOVE_RESULT_FOE_HUNG_ON:
2018-07-21 15:11:13 +02:00
case MOVE_RESULT_STURDIED:
2017-09-20 12:56:45 +02:00
default:
2018-01-16 22:12:38 +01:00
if (gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE)
2017-09-20 12:56:45 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitPlaySE(0, SE_KOUKA_H);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-20 12:56:45 +02:00
}
2018-01-16 22:12:38 +01:00
else if (gMoveResultFlags & MOVE_RESULT_NOT_VERY_EFFECTIVE)
2017-09-20 12:56:45 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitPlaySE(0, SE_KOUKA_L);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-20 12:56:45 +02:00
}
2018-01-16 22:12:38 +01:00
else if (!(gMoveResultFlags & (MOVE_RESULT_DOESNT_AFFECT_FOE | MOVE_RESULT_FAILED)))
2017-09-20 12:56:45 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitPlaySE(0, SE_KOUKA_M);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-20 12:56:45 +02:00
}
break;
}
}
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atk0F_resultmessage(void)
2017-09-20 12:56:45 +02:00
{
u32 stringId = 0;
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags)
2017-09-20 12:56:45 +02:00
return;
2018-01-16 22:12:38 +01:00
if (gMoveResultFlags & MOVE_RESULT_MISSED && (!(gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE) || gBattleCommunication[6] > 2))
2017-09-20 12:56:45 +02:00
{
stringId = gMissStringIds[gBattleCommunication[6]];
gBattleCommunication[MSG_DISPLAY] = 1;
}
else
{
gBattleCommunication[MSG_DISPLAY] = 1;
2018-07-21 15:11:13 +02:00
switch (gMoveResultFlags & (~MOVE_RESULT_MISSED))
2017-09-20 12:56:45 +02:00
{
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_SUPER_EFFECTIVE:
2017-10-07 15:15:47 +02:00
stringId = STRINGID_SUPEREFFECTIVE;
2017-09-20 12:56:45 +02:00
break;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_NOT_VERY_EFFECTIVE:
2017-10-07 15:15:47 +02:00
stringId = STRINGID_NOTVERYEFFECTIVE;
2017-09-20 12:56:45 +02:00
break;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_ONE_HIT_KO:
2017-10-07 15:15:47 +02:00
stringId = STRINGID_ONEHITKO;
2017-09-20 12:56:45 +02:00
break;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_FOE_ENDURED:
2017-10-07 15:15:47 +02:00
stringId = STRINGID_PKMNENDUREDHIT;
2017-09-20 12:56:45 +02:00
break;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_FAILED:
2017-10-07 15:15:47 +02:00
stringId = STRINGID_BUTITFAILED;
2017-09-20 12:56:45 +02:00
break;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_DOESNT_AFFECT_FOE:
2017-10-07 15:15:47 +02:00
stringId = STRINGID_ITDOESNTAFFECT;
2017-09-20 12:56:45 +02:00
break;
2018-01-16 22:12:38 +01:00
case MOVE_RESULT_FOE_HUNG_ON:
2018-02-06 23:09:39 +01:00
gLastUsedItem = gBattleMons[gBattlerTarget].item;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerTarget;
2018-01-16 22:12:38 +01:00
gMoveResultFlags &= ~(MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON);
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor();
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr = BattleScript_HangedOnMsg;
return;
default:
2018-01-16 22:12:38 +01:00
if (gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE)
2017-09-20 12:56:45 +02:00
{
2017-10-07 15:15:47 +02:00
stringId = STRINGID_ITDOESNTAFFECT;
2017-09-20 12:56:45 +02:00
}
2018-01-16 22:12:38 +01:00
else if (gMoveResultFlags & MOVE_RESULT_ONE_HIT_KO)
2017-09-20 12:56:45 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags &= ~(MOVE_RESULT_ONE_HIT_KO);
gMoveResultFlags &= ~(MOVE_RESULT_SUPER_EFFECTIVE);
gMoveResultFlags &= ~(MOVE_RESULT_NOT_VERY_EFFECTIVE);
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor();
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr = BattleScript_OneHitKOMsg;
return;
}
2018-07-21 15:11:13 +02:00
else if (gMoveResultFlags & MOVE_RESULT_STURDIED)
{
gMoveResultFlags &= ~(MOVE_RESULT_STURDIED | MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON);
gSpecialStatuses[gBattlerTarget].sturdied = 0;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_SturdiedMsg;
return;
}
2018-01-16 22:12:38 +01:00
else if (gMoveResultFlags & MOVE_RESULT_FOE_ENDURED)
2017-09-20 12:56:45 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags &= ~(MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON);
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor();
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr = BattleScript_EnduredMsg;
return;
}
2018-01-16 22:12:38 +01:00
else if (gMoveResultFlags & MOVE_RESULT_FOE_HUNG_ON)
2017-09-20 12:56:45 +02:00
{
2018-02-06 23:09:39 +01:00
gLastUsedItem = gBattleMons[gBattlerTarget].item;
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerTarget;
2018-01-16 22:12:38 +01:00
gMoveResultFlags &= ~(MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON);
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor();
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr = BattleScript_HangedOnMsg;
return;
}
2018-01-16 22:12:38 +01:00
else if (gMoveResultFlags & MOVE_RESULT_FAILED)
2017-09-20 12:56:45 +02:00
{
2017-10-07 15:15:47 +02:00
stringId = STRINGID_BUTITFAILED;
2017-09-20 12:56:45 +02:00
}
else
{
gBattleCommunication[MSG_DISPLAY] = 0;
}
}
}
if (stringId)
2018-02-06 23:09:39 +01:00
PrepareStringBattle(stringId, gBattlerAttacker);
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atk10_printstring(void)
2017-09-20 12:56:45 +02:00
{
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags == 0)
2017-09-20 12:56:45 +02:00
{
2018-03-01 00:59:52 +01:00
u16 var = T2_READ_16(gBattlescriptCurrInstr + 1);
2018-02-06 23:09:39 +01:00
PrepareStringBattle(var, gBattlerAttacker);
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr += 3;
gBattleCommunication[MSG_DISPLAY] = 1;
2017-09-20 00:28:00 +02:00
}
2017-09-20 12:56:45 +02:00
}
2017-09-20 00:28:00 +02:00
static void atk11_printselectionstring(void)
2017-09-20 12:56:45 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2017-09-20 00:28:00 +02:00
2018-03-01 00:59:52 +01:00
BtlController_EmitPrintSelectionString(0, T2_READ_16(gBattlescriptCurrInstr + 1));
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec(gActiveBattler);
2017-09-20 00:28:00 +02:00
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr += 3;
gBattleCommunication[MSG_DISPLAY] = 1;
}
2017-09-20 00:28:00 +02:00
2017-09-28 15:34:21 +02:00
static void atk12_waitmessage(void)
2017-09-20 12:56:45 +02:00
{
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags == 0)
2017-09-20 12:56:45 +02:00
{
if (!gBattleCommunication[MSG_DISPLAY])
{
gBattlescriptCurrInstr += 3;
}
else
{
2018-03-01 00:59:52 +01:00
u16 toWait = T2_READ_16(gBattlescriptCurrInstr + 1);
2017-09-20 12:56:45 +02:00
if (++gPauseCounterBattle >= toWait)
{
gPauseCounterBattle = 0;
gBattlescriptCurrInstr += 3;
gBattleCommunication[MSG_DISPLAY] = 0;
}
}
}
}
2017-09-28 15:34:21 +02:00
static void atk13_printfromtable(void)
2017-09-20 12:56:45 +02:00
{
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags == 0)
2017-09-20 12:56:45 +02:00
{
2018-03-01 00:59:52 +01:00
const u16 *ptr = (const u16*) T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-20 12:56:45 +02:00
ptr += gBattleCommunication[MULTISTRING_CHOOSER];
2018-02-06 23:09:39 +01:00
PrepareStringBattle(*ptr, gBattlerAttacker);
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr += 5;
gBattleCommunication[MSG_DISPLAY] = 1;
}
}
static void atk14_printselectionstringfromtable(void)
2017-09-20 12:56:45 +02:00
{
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags == 0)
2017-09-20 12:56:45 +02:00
{
2018-03-01 00:59:52 +01:00
const u16 *ptr = (const u16*) T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-20 12:56:45 +02:00
ptr += gBattleCommunication[MULTISTRING_CHOOSER];
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2018-02-06 20:48:02 +01:00
BtlController_EmitPrintSelectionString(0, *ptr);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-20 12:56:45 +02:00
gBattlescriptCurrInstr += 5;
gBattleCommunication[MSG_DISPLAY] = 1;
}
}
2018-02-08 12:13:29 +01:00
u8 GetBattlerTurnOrderNum(u8 battlerId)
2017-09-20 12:56:45 +02:00
{
s32 i;
2018-02-06 02:46:59 +01:00
for (i = 0; i < gBattlersCount; i++)
2017-09-20 12:56:45 +02:00
{
2018-06-28 21:06:32 +02:00
if (gBattlerByTurnOrder[i] == battlerId)
2017-09-20 12:56:45 +02:00
break;
}
return i;
2017-09-20 00:28:00 +02:00
}
#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)
{
2018-09-22 16:15:00 +02:00
s32 i;
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
gBattleCommunication[MOVE_EFFECT_BYTE] &= ~(MOVE_EFFECT_AFFECTS_USER);
affectsUser = MOVE_EFFECT_AFFECTS_USER;
2018-02-06 23:09:39 +01:00
gBattleScripting.battler = gBattlerTarget; // theoretically the attacker
}
else
{
2018-02-08 11:17:41 +01:00
gEffectBattler = gBattlerTarget;
2018-02-06 23:09:39 +01:00
gBattleScripting.battler = gBattlerAttacker;
}
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].ability == ABILITY_SHIELD_DUST && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD)
&& !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)
&& !primary && gBattleCommunication[MOVE_EFFECT_BYTE] <= 7)
INCREMENT_RESET_RETURN
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].hp == 0
&& gBattleCommunication[MOVE_EFFECT_BYTE] != MOVE_EFFECT_PAYDAY
&& gBattleCommunication[MOVE_EFFECT_BYTE] != MOVE_EFFECT_STEAL_ITEM)
INCREMENT_RESET_RETURN
2018-08-02 20:24:18 +02:00
if (DoesSubstituteBlockMove(gBattlerAttacker, gEffectBattler, gCurrentMove) && affectsUser != MOVE_EFFECT_AFFECTS_USER)
INCREMENT_RESET_RETURN
if (gBattleCommunication[MOVE_EFFECT_BYTE] <= 6) // status change
{
2017-09-28 16:51:24 +02:00
switch (sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]])
{
2018-01-16 22:12:38 +01:00
case STATUS1_SLEEP:
// check active uproar
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].ability != ABILITY_SOUNDPROOF)
{
2018-02-06 02:46:59 +01:00
for (gActiveBattler = 0;
gActiveBattler < gBattlersCount && !(gBattleMons[gActiveBattler].status2 & STATUS2_UPROAR);
gActiveBattler++)
{}
}
else
2018-02-06 02:46:59 +01:00
gActiveBattler = gBattlersCount;
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].status1)
break;
2018-02-06 02:46:59 +01:00
if (gActiveBattler != gBattlersCount)
break;
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].ability == ABILITY_VITAL_SPIRIT)
break;
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].ability == ABILITY_INSOMNIA)
break;
2018-02-08 11:17:41 +01:00
CancelMultiTurnMoves(gEffectBattler);
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))
{
gLastUsedAbility = ABILITY_IMMUNITY;
2018-02-08 11:17:41 +01:00
RecordAbilityBattle(gEffectBattler, ABILITY_IMMUNITY);
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_PSNPrevention;
if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD)
{
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD);
}
else
{
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
}
RESET_RETURN
}
2018-03-01 00:59:52 +01:00
if ((IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_POISON) || IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_STEEL))
&& (gHitMarker & HITMARKER_IGNORE_SAFEGUARD)
2017-09-22 21:33:49 +02:00
&& (primary == TRUE || certain == MOVE_EFFECT_CERTAIN))
{
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_PSNPrevention;
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
RESET_RETURN
}
2018-03-01 00:59:52 +01:00
if (IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_POISON))
break;
2018-03-01 00:59:52 +01:00
if (IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_STEEL))
break;
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].status1)
break;
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].ability == ABILITY_IMMUNITY)
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))
{
gLastUsedAbility = ABILITY_WATER_VEIL;
2018-02-08 11:17:41 +01:00
RecordAbilityBattle(gEffectBattler, ABILITY_WATER_VEIL);
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_BRNPrevention;
if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD)
{
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD);
}
else
{
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
}
RESET_RETURN
}
2018-03-01 00:59:52 +01:00
if (IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_FIRE)
&& (gHitMarker & HITMARKER_IGNORE_SAFEGUARD)
2017-09-22 21:33:49 +02:00
&& (primary == TRUE || certain == MOVE_EFFECT_CERTAIN))
{
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_BRNPrevention;
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
RESET_RETURN
}
2018-03-01 00:59:52 +01:00
if (IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_FIRE))
break;
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].ability == ABILITY_WATER_VEIL)
break;
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].status1)
break;
statusChanged = TRUE;
break;
2018-01-16 22:12:38 +01:00
case STATUS1_FREEZE:
if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SUN_ANY)
noSunCanFreeze = FALSE;
2018-03-01 00:59:52 +01:00
if (IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_ICE))
break;
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].status1)
break;
if (noSunCanFreeze == 0)
break;
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].ability == ABILITY_MAGMA_ARMOR)
break;
2018-02-08 11:17:41 +01:00
CancelMultiTurnMoves(gEffectBattler);
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-22 21:33:49 +02:00
if (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)
{
gLastUsedAbility = ABILITY_LIMBER;
2018-02-08 11:17:41 +01:00
RecordAbilityBattle(gEffectBattler, ABILITY_LIMBER);
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_PRLZPrevention;
if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD)
{
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD);
}
else
{
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
}
RESET_RETURN
}
else
break;
}
2018-07-29 12:45:08 +02:00
if ((IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_ELECTRIC))
&& (gHitMarker & HITMARKER_IGNORE_SAFEGUARD)
&& (primary == TRUE || certain == MOVE_EFFECT_CERTAIN))
{
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_PRLZPrevention;
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
RESET_RETURN
}
if (IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_ELECTRIC))
break;
if (gBattleMons[gEffectBattler].ability == ABILITY_LIMBER)
break;
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].status1)
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))
{
gLastUsedAbility = ABILITY_IMMUNITY;
2018-02-08 11:17:41 +01:00
RecordAbilityBattle(gEffectBattler, ABILITY_IMMUNITY);
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_PSNPrevention;
if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD)
{
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD);
}
else
{
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
}
RESET_RETURN
}
2018-03-01 00:59:52 +01:00
if ((IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_POISON) || IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_STEEL))
&& (gHitMarker & HITMARKER_IGNORE_SAFEGUARD)
2017-09-22 21:33:49 +02:00
&& (primary == TRUE || certain == MOVE_EFFECT_CERTAIN))
{
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_PSNPrevention;
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
RESET_RETURN
}
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].status1)
break;
2018-03-01 00:59:52 +01:00
if (!IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_POISON) && !IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_STEEL))
{
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].ability == ABILITY_IMMUNITY)
break;
// It's redundant, because at this point we know the status1 value is 0.
2018-02-08 11:17:41 +01:00
gBattleMons[gEffectBattler].status1 &= ~(STATUS1_TOXIC_POISON);
gBattleMons[gEffectBattler].status1 &= ~(STATUS1_POISON);
statusChanged = TRUE;
break;
}
else
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_DOESNT_AFFECT_FOE;
}
break;
}
if (statusChanged == TRUE)
{
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
2018-01-16 22:12:38 +01:00
if (sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]] == STATUS1_SLEEP)
2018-02-08 11:17:41 +01:00
gBattleMons[gEffectBattler].status1 |= ((Random() & 3) + 2);
else
2018-02-08 11:17:41 +01:00
gBattleMons[gEffectBattler].status1 |= sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]];
2017-09-28 16:51:24 +02:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]];
2018-02-08 11:17:41 +01:00
gActiveBattler = gEffectBattler;
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gEffectBattler].status1);
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec(gActiveBattler);
if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD)
{
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD);
}
else
{
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
}
// for synchronize
if (gBattleCommunication[MOVE_EFFECT_BYTE] == MOVE_EFFECT_POISON
|| gBattleCommunication[MOVE_EFFECT_BYTE] == MOVE_EFFECT_TOXIC
|| gBattleCommunication[MOVE_EFFECT_BYTE] == MOVE_EFFECT_PARALYSIS
|| gBattleCommunication[MOVE_EFFECT_BYTE] == MOVE_EFFECT_BURN)
{
u8* synchronizeEffect = &gBattleStruct->synchronizeMoveEffect;
*synchronizeEffect = gBattleCommunication[MOVE_EFFECT_BYTE];
gHitMarker |= HITMARKER_SYNCHRONISE_EFFECT;
}
return;
}
else if (statusChanged == FALSE)
{
gBattleCommunication[MOVE_EFFECT_BYTE] = 0;
gBattlescriptCurrInstr++;
return;
}
2017-09-22 21:33:49 +02:00
return;
}
else
{
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].status2 & sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]])
{
gBattlescriptCurrInstr++;
}
else
{
u8 side;
2017-09-22 21:33:49 +02:00
switch (gBattleCommunication[MOVE_EFFECT_BYTE])
{
case MOVE_EFFECT_CONFUSION:
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].ability == ABILITY_OWN_TEMPO
|| gBattleMons[gEffectBattler].status2 & STATUS2_CONFUSION)
{
gBattlescriptCurrInstr++;
}
else
{
2018-02-08 11:17:41 +01:00
gBattleMons[gEffectBattler].status2 |= (((Random()) % 0x4)) + 2;
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
2017-09-28 16:51:24 +02:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]];
}
break;
case MOVE_EFFECT_FLINCH:
if (GetBattlerAbility(gEffectBattler) == ABILITY_INNER_FOCUS)
{
2017-09-22 21:33:49 +02:00
if (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)
{
gLastUsedAbility = ABILITY_INNER_FOCUS;
2018-02-08 11:17:41 +01:00
RecordAbilityBattle(gEffectBattler, ABILITY_INNER_FOCUS);
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++;
}
break;
case MOVE_EFFECT_UPROAR:
2018-02-08 11:17:41 +01:00
if (!(gBattleMons[gEffectBattler].status2 & STATUS2_UPROAR))
{
2017-09-22 21:33:49 +02:00
2018-02-08 11:17:41 +01:00
gBattleMons[gEffectBattler].status2 |= STATUS2_MULTIPLETURNS;
gLockedMoves[gEffectBattler] = gCurrentMove;
gBattleMons[gEffectBattler].status2 |= ((Random() & 3) + 2) << 4;
2017-09-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-22 21:33:49 +02:00
else
{
gBattlescriptCurrInstr++;
}
break;
case MOVE_EFFECT_PAYDAY:
2018-02-06 23:09:39 +01:00
if (GET_BATTLER_SIDE(gBattlerAttacker) == B_SIDE_PLAYER)
{
u16 PayDay = gPaydayMoney;
2018-02-06 23:09:39 +01:00
gPaydayMoney += (gBattleMons[gBattlerAttacker].level * 5);
if (PayDay > gPaydayMoney)
gPaydayMoney = 0xFFFF;
}
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
2017-09-28 16:51:24 +02:00
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]];
break;
case MOVE_EFFECT_TRI_ATTACK:
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].status1)
{
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;
gBattlescriptCurrInstr++;
break;
case MOVE_EFFECT_WRAP:
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].status2 & STATUS2_WRAPPED)
{
gBattlescriptCurrInstr++;
}
else
{
gBattleMons[gEffectBattler].status2 |= STATUS2_WRAPPED;
if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_GRIP_CLAW)
gDisableStructs[gEffectBattler].wrapTurns = 7;
else
gDisableStructs[gEffectBattler].wrapTurns = ((Random() % 2) + 4);
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-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-22 21:33:49 +02:00
for (gBattleCommunication[MULTISTRING_CHOOSER] = 0; ; gBattleCommunication[MULTISTRING_CHOOSER]++)
{
if (gBattleCommunication[MULTISTRING_CHOOSER] > 5)
2017-09-22 21:33:49 +02:00
break;
if (gTrappingMoves[gBattleCommunication[MULTISTRING_CHOOSER]] == gCurrentMove)
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]];
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))
{
gBattlescriptCurrInstr++;
}
else
{
2017-09-22 21:33:49 +02:00
gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN);
gBattleScripting.animArg2 = 0;
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
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))
{
gBattlescriptCurrInstr++;
}
else
{
2017-09-22 21:33:49 +02:00
gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN);
gBattleScripting.animArg2 = 0;
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
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))
{
gBattlescriptCurrInstr++;
}
else
{
2017-09-22 21:33:49 +02:00
gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN);
gBattleScripting.animArg2 = 0;
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
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))
{
gBattlescriptCurrInstr++;
}
else
{
2017-09-22 21:33:49 +02:00
gBattleScripting.animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & ~(MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN);
gBattleScripting.animArg2 = 0;
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_StatDown;
}
break;
case MOVE_EFFECT_RECHARGE:
2018-02-08 11:17:41 +01:00
gBattleMons[gEffectBattler].status2 |= STATUS2_RECHARGE;
gDisableStructs[gEffectBattler].rechargeCounter = 2;
gLockedMoves[gEffectBattler] = gCurrentMove;
gBattlescriptCurrInstr++;
break;
case MOVE_EFFECT_RAGE:
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerAttacker].status2 |= STATUS2_RAGE;
gBattlescriptCurrInstr++;
break;
case MOVE_EFFECT_STEAL_ITEM:
{
2018-09-20 22:00:00 +02:00
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_HILL)
{
gBattlescriptCurrInstr++;
break;
}
2018-02-06 23:09:39 +01:00
side = GetBattlerSide(gBattlerAttacker);
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT
&& !(gBattleTypeFlags &
(BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_FRONTIER
| BATTLE_TYPE_LINK
| BATTLE_TYPE_x2000000
| BATTLE_TYPE_SECRET_BASE)))
{
gBattlescriptCurrInstr++;
}
2017-09-22 21:33:49 +02:00
else if (!(gBattleTypeFlags &
(BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_FRONTIER
| BATTLE_TYPE_LINK
| BATTLE_TYPE_x2000000
| BATTLE_TYPE_SECRET_BASE))
2018-02-06 23:09:39 +01:00
&& (gWishFutureKnock.knockedOffPokes[side] & gBitTable[gBattlerPartyIndexes[gBattlerAttacker]]))
{
gBattlescriptCurrInstr++;
}
2018-02-06 23:09:39 +01:00
else if (gBattleMons[gBattlerTarget].item
&& gBattleMons[gBattlerTarget].ability == ABILITY_STICKY_HOLD)
{
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_NoItemSteal;
2018-02-06 23:09:39 +01:00
gLastUsedAbility = gBattleMons[gBattlerTarget].ability;
RecordAbilityBattle(gBattlerTarget, gLastUsedAbility);
}
2018-02-06 23:09:39 +01:00
else if (gBattleMons[gBattlerAttacker].item != 0
|| gBattleMons[gBattlerTarget].item == ITEM_ENIGMA_BERRY
|| IS_ITEM_MAIL(gBattleMons[gBattlerTarget].item)
|| gBattleMons[gBattlerTarget].item == 0)
{
gBattlescriptCurrInstr++;
}
2017-09-22 21:33:49 +02:00
else
{
2018-02-06 23:09:39 +01:00
u16* changedItem = &gBattleStruct->changedItems[gBattlerAttacker];
gLastUsedItem = *changedItem = gBattleMons[gBattlerTarget].item;
gBattleMons[gBattlerTarget].item = 0;
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gLastUsedItem);
2018-02-06 23:09:39 +01:00
MarkBattlerForControllerExec(gBattlerAttacker);
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget;
BtlController_EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gBattlerTarget].item);
MarkBattlerForControllerExec(gBattlerTarget);
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_ItemSteal;
2018-02-06 23:09:39 +01:00
*(u8*)((u8*)(&gBattleStruct->choicedMove[gBattlerTarget]) + 0) = 0;
*(u8*)((u8*)(&gBattleStruct->choicedMove[gBattlerTarget]) + 1) = 0;
2017-09-22 21:33:49 +02:00
}
}
break;
case MOVE_EFFECT_PREVENT_ESCAPE:
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerTarget].status2 |= STATUS2_ESCAPE_PREVENTION;
gDisableStructs[gBattlerTarget].battlerPreventingEscape = gBattlerAttacker;
gBattlescriptCurrInstr++;
break;
case MOVE_EFFECT_NIGHTMARE:
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerTarget].status2 |= STATUS2_NIGHTMARE;
gBattlescriptCurrInstr++;
break;
case MOVE_EFFECT_ALL_STATS_UP:
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_AllStatsUp;
break;
case MOVE_EFFECT_RAPIDSPIN:
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
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))
{
gBattlescriptCurrInstr++;
}
else
{
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerTarget].status1 &= ~(STATUS1_PARALYSIS);
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_TargetPRLZHeal;
}
break;
case MOVE_EFFECT_ATK_DEF_DOWN: // SuperPower
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_AtkDefDown;
break;
2018-09-22 01:12:27 +02:00
case MOVE_EFFECT_DEF_SPDEF_DOWN: // Close Combat
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_DefSpDefDown;
break;
2018-09-01 20:00:13 +02:00
case MOVE_EFFECT_RECOIL_33: // Double Edge
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]];
break;
2018-09-22 11:13:17 +02:00
case MOVE_EFFECT_RECOIL_50: // Head Smash
gBattleMoveDamage = gHpDealt / 2;
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_MoveEffectRecoil;
break;
case MOVE_EFFECT_RECOIL_33_STATUS: // Flare Blitz - can burn, Volt Tackle - can paralyze
gBattleScripting.savedDmg = gHpDealt / 3;
if (gBattleScripting.savedDmg == 0)
gBattleScripting.savedDmg = 1;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_MoveEffectRecoilWithStatus;
break;
case MOVE_EFFECT_THRASH:
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].status2 & STATUS2_LOCK_CONFUSE)
{
gBattlescriptCurrInstr++;
}
else
{
2018-02-08 11:17:41 +01:00
gBattleMons[gEffectBattler].status2 |= STATUS2_MULTIPLETURNS;
gLockedMoves[gEffectBattler] = gCurrentMove;
gBattleMons[gEffectBattler].status2 |= (((Random() & 1) + 2) << 0xA);
}
break;
case MOVE_EFFECT_KNOCK_OFF:
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].ability == ABILITY_STICKY_HOLD)
{
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].item == 0)
{
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);
}
break;
}
2018-02-08 11:17:41 +01:00
if (gBattleMons[gEffectBattler].item)
{
2018-02-08 11:17:41 +01:00
side = GetBattlerSide(gEffectBattler);
2018-02-08 11:17:41 +01:00
gLastUsedItem = gBattleMons[gEffectBattler].item;
gBattleMons[gEffectBattler].item = 0;
gWishFutureKnock.knockedOffPokes[side] |= gBitTable[gBattlerPartyIndexes[gEffectBattler]];
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
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-22 21:33:49 +02:00
else
{
gBattlescriptCurrInstr++;
}
break;
case MOVE_EFFECT_SP_ATK_TWO_DOWN: // Overheat
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_SAtkDown2;
break;
2018-09-22 16:15:00 +02:00
case MOVE_EFFECT_CLEAR_SMOG:
for (i = 0; i < BATTLE_STATS_NO; i++)
{
if (gBattleMons[gEffectBattler].statStages[i] != 6)
break;
}
if ((gSpecialStatuses[gEffectBattler].physicalDmg || gSpecialStatuses[gEffectBattler].specialDmg) && i != BATTLE_STATS_NO)
{
for (i = 0; i < BATTLE_STATS_NO; i++)
gBattleMons[gEffectBattler].statStages[i] = 6;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_MoveEffectClearSmog;
}
break;
2018-09-29 15:43:56 +02:00
case MOVE_EFFECT_SMACK_DOWN:
if (!IsBattlerGrounded(gBattlerTarget))
{
gStatuses3[gBattlerTarget] |= STATUS3_SMACKED_DOWN;
gStatuses3[gBattlerTarget] &= ~(STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS | STATUS3_ON_AIR);
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_MoveEffectSmackDown;
}
break;
2018-09-29 18:40:14 +02:00
case MOVE_EFFECT_FLAME_BURST:
if (IsBattlerAlive(BATTLE_PARTNER(gBattlerTarget)) && GetBattlerAbility(BATTLE_PARTNER(gBattlerTarget)) != ABILITY_MAGIC_GUARD)
{
gBattleScripting.battler = BATTLE_PARTNER(gBattlerTarget);
gBattleMoveDamage = gBattleMons[BATTLE_PARTNER(gBattlerTarget)].hp / 16;
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_MoveEffectFlameBurst;
}
break;
}
}
}
gBattleCommunication[MOVE_EFFECT_BYTE] = 0;
}
2017-09-22 21:33:49 +02:00
2017-09-28 15:34:21 +02:00
static void atk15_seteffectwithchance(void)
2017-09-22 21:33:49 +02:00
{
u32 percentChance;
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SERENE_GRACE)
2017-09-22 21:33:49 +02:00
percentChance = gBattleMoves[gCurrentMove].secondaryEffectChance * 2;
else
percentChance = gBattleMoves[gCurrentMove].secondaryEffectChance;
if (gBattleCommunication[MOVE_EFFECT_BYTE] & MOVE_EFFECT_CERTAIN
2018-01-16 22:12:38 +01:00
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
2017-09-22 21:33:49 +02:00
{
gBattleCommunication[MOVE_EFFECT_BYTE] &= ~(MOVE_EFFECT_CERTAIN);
SetMoveEffect(0, MOVE_EFFECT_CERTAIN);
}
else if (Random() % 100 < percentChance
&& gBattleCommunication[MOVE_EFFECT_BYTE]
2018-01-16 22:12:38 +01:00
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
2017-09-22 21:33:49 +02:00
{
if (percentChance >= 100)
SetMoveEffect(0, MOVE_EFFECT_CERTAIN);
else
SetMoveEffect(0, 0);
}
else
{
gBattlescriptCurrInstr++;
}
gBattleCommunication[MOVE_EFFECT_BYTE] = 0;
gBattleScripting.multihitMoveEffect = 0;
2017-09-22 21:33:49 +02:00
}
2017-09-28 15:34:21 +02:00
static void atk16_seteffectprimary(void)
2017-09-22 21:33:49 +02:00
{
SetMoveEffect(TRUE, 0);
}
2017-09-28 15:34:21 +02:00
static void atk17_seteffectsecondary(void)
2017-09-22 21:33:49 +02:00
{
SetMoveEffect(FALSE, 0);
}
static void atk18_clearstatusfromeffect(void)
2017-09-22 21:33:49 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2017-09-22 21:33:49 +02:00
if (gBattleCommunication[MOVE_EFFECT_BYTE] <= MOVE_EFFECT_TOXIC)
2018-02-06 02:46:59 +01:00
gBattleMons[gActiveBattler].status1 &= (~sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]);
2017-09-22 21:33:49 +02:00
else
2018-02-06 02:46:59 +01:00
gBattleMons[gActiveBattler].status2 &= (~sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]);
2017-09-22 21:33:49 +02:00
gBattleCommunication[MOVE_EFFECT_BYTE] = 0;
gBattlescriptCurrInstr += 2;
gBattleScripting.multihitMoveEffect = 0;
2017-09-22 21:33:49 +02:00
}
static void atk19_tryfaintmon(void)
2017-09-22 21:33:49 +02:00
{
const u8 *BS_ptr;
if (gBattlescriptCurrInstr[2] != 0)
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-02-06 02:46:59 +01:00
if (gHitMarker & HITMARKER_FAINTED(gActiveBattler))
2017-09-22 21:33:49 +02:00
{
2018-03-01 00:59:52 +01:00
BS_ptr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
2017-09-22 21:33:49 +02:00
BattleScriptPop();
gBattlescriptCurrInstr = BS_ptr;
2018-07-24 21:47:00 +02:00
gSideStatuses[GetBattlerSide(gActiveBattler)] &= ~(SIDE_STATUS_SPIKES_DAMAGED | SIDE_STATUS_TOXIC_SPIKES_DAMAGED | SIDE_STATUS_STEALTH_ROCK_DAMAGED | SIDE_STATUS_STICKY_WEB_DAMAGED);
2017-09-22 21:33:49 +02:00
}
else
{
gBattlescriptCurrInstr += 7;
}
}
else
{
2018-02-08 12:13:29 +01:00
u8 battlerId;
2017-09-22 21:33:49 +02:00
2018-02-08 11:17:41 +01:00
if (gBattlescriptCurrInstr[1] == BS_ATTACKER)
2017-09-22 21:33:49 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2018-02-08 12:13:29 +01:00
battlerId = gBattlerTarget;
2017-09-22 21:33:49 +02:00
BS_ptr = BattleScript_FaintAttacker;
}
else
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget;
2018-02-08 12:13:29 +01:00
battlerId = gBattlerAttacker;
2017-09-22 21:33:49 +02:00
BS_ptr = BattleScript_FaintTarget;
}
2018-02-06 02:46:59 +01:00
if (!(gAbsentBattlerFlags & gBitTable[gActiveBattler])
&& gBattleMons[gActiveBattler].hp == 0)
2017-09-22 21:33:49 +02:00
{
2018-02-06 02:46:59 +01:00
gHitMarker |= HITMARKER_FAINTED(gActiveBattler);
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr + 7);
gBattlescriptCurrInstr = BS_ptr;
2018-02-06 02:46:59 +01:00
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
2017-09-22 21:33:49 +02:00
{
gHitMarker |= HITMARKER_x400000;
if (gBattleResults.playerFaintCounter < 0xFF)
gBattleResults.playerFaintCounter++;
2018-02-06 02:46:59 +01:00
AdjustFriendshipOnBattleFaint(gActiveBattler);
2017-09-22 21:33:49 +02:00
}
else
{
if (gBattleResults.opponentFaintCounter < 0xFF)
gBattleResults.opponentFaintCounter++;
2018-02-06 20:48:02 +01:00
gBattleResults.lastOpponentSpecies = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES, NULL);
2017-09-22 21:33:49 +02:00
}
2018-02-06 23:09:39 +01:00
if ((gHitMarker & HITMARKER_DESTINYBOND) && gBattleMons[gBattlerAttacker].hp != 0)
2017-09-22 21:33:49 +02:00
{
gHitMarker &= ~(HITMARKER_DESTINYBOND);
BattleScriptPush(gBattlescriptCurrInstr);
2018-02-08 12:13:29 +01:00
gBattleMoveDamage = gBattleMons[battlerId].hp;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr = BattleScript_DestinyBondTakesLife;
}
2018-02-06 23:09:39 +01:00
if ((gStatuses3[gBattlerTarget] & STATUS3_GRUDGE)
2017-09-22 21:33:49 +02:00
&& !(gHitMarker & HITMARKER_GRUDGE)
2018-02-06 23:09:39 +01:00
&& GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)
&& gBattleMons[gBattlerAttacker].hp != 0
2017-09-22 21:33:49 +02:00
&& gCurrentMove != MOVE_STRUGGLE)
{
2018-02-06 23:09:39 +01:00
u8 moveIndex = *(gBattleStruct->chosenMovePositions + gBattlerAttacker);
2017-09-22 21:33:49 +02:00
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerAttacker].pp[moveIndex] = 0;
2017-09-22 21:33:49 +02:00
BattleScriptPush(gBattlescriptCurrInstr);
gBattlescriptCurrInstr = BattleScript_GrudgeTakesPp;
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData(0, moveIndex + REQUEST_PPMOVE1_BATTLE, 0, 1, &gBattleMons[gActiveBattler].pp[moveIndex]);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-22 21:33:49 +02:00
2018-02-06 23:09:39 +01:00
PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].moves[moveIndex])
2017-09-22 21:33:49 +02:00
}
}
else
{
gBattlescriptCurrInstr += 7;
}
}
}
static void atk1A_dofaintanimation(void)
2017-09-22 21:33:49 +02:00
{
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags == 0)
2017-09-22 21:33:49 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-02-06 20:48:02 +01:00
BtlController_EmitFaintAnimation(0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 2;
}
}
static void atk1B_cleareffectsonfaint(void)
2017-09-22 21:33:49 +02:00
{
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags == 0)
2017-09-22 21:33:49 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2017-09-22 21:33:49 +02:00
2018-02-06 02:46:59 +01:00
if (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || gBattleMons[gActiveBattler].hp == 0)
2017-09-22 21:33:49 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons[gActiveBattler].status1 = 0;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 0x4, &gBattleMons[gActiveBattler].status1);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-22 21:33:49 +02:00
}
2017-10-02 23:32:39 +02:00
FaintClearSetData(); // Effects like attractions, trapping, etc.
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 2;
}
}
2017-09-28 15:34:21 +02:00
static void atk1C_jumpifstatus(void)
2017-09-22 21:33:49 +02:00
{
2018-02-08 12:13:29 +01:00
u8 battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-03-01 00:59:52 +01:00
u32 flags = T2_READ_32(gBattlescriptCurrInstr + 2);
const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 6);
2017-09-22 21:33:49 +02:00
2018-02-08 12:13:29 +01:00
if (gBattleMons[battlerId].status1 & flags && gBattleMons[battlerId].hp)
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr = jumpPtr;
else
gBattlescriptCurrInstr += 10;
}
2017-09-28 15:34:21 +02:00
static void atk1D_jumpifstatus2(void)
2017-09-22 21:33:49 +02:00
{
2018-02-08 12:13:29 +01:00
u8 battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-03-01 00:59:52 +01:00
u32 flags = T2_READ_32(gBattlescriptCurrInstr + 2);
const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 6);
2017-09-22 21:33:49 +02:00
2018-02-08 12:13:29 +01:00
if (gBattleMons[battlerId].status2 & flags && gBattleMons[battlerId].hp)
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr = jumpPtr;
else
gBattlescriptCurrInstr += 10;
}
2017-09-28 15:34:21 +02:00
static void atk1E_jumpifability(void)
2017-09-22 21:33:49 +02:00
{
2018-02-08 12:13:29 +01:00
u8 battlerId;
2017-09-28 15:34:21 +02:00
u8 ability = gBattlescriptCurrInstr[2];
2018-03-01 00:59:52 +01:00
const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 3);
2017-09-22 21:33:49 +02:00
2018-02-08 11:17:41 +01:00
if (gBattlescriptCurrInstr[1] == BS_ATTACKER_SIDE)
2017-09-22 21:33:49 +02:00
{
2018-07-01 11:15:42 +02:00
battlerId = AbilityBattleEffects(ABILITYEFFECT_CHECK_BATTLER_SIDE, gBattlerAttacker, ability, 0, 0);
2018-02-08 12:13:29 +01:00
if (battlerId)
2017-09-22 21:33:49 +02:00
{
gLastUsedAbility = ability;
gBattlescriptCurrInstr = jumpPtr;
2018-02-08 12:13:29 +01:00
RecordAbilityBattle(battlerId - 1, gLastUsedAbility);
gBattleScripting.battlerWithAbility = battlerId - 1;
2017-09-22 21:33:49 +02:00
}
else
gBattlescriptCurrInstr += 7;
}
2018-02-08 11:17:41 +01:00
else if (gBattlescriptCurrInstr[1] == BS_NOT_ATTACKER_SIDE)
2017-09-22 21:33:49 +02:00
{
2018-02-08 12:13:29 +01:00
battlerId = AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gBattlerAttacker, ability, 0, 0);
if (battlerId)
2017-09-22 21:33:49 +02:00
{
gLastUsedAbility = ability;
gBattlescriptCurrInstr = jumpPtr;
2018-02-08 12:13:29 +01:00
RecordAbilityBattle(battlerId - 1, gLastUsedAbility);
gBattleScripting.battlerWithAbility = battlerId - 1;
2017-09-22 21:33:49 +02:00
}
else
gBattlescriptCurrInstr += 7;
}
else
{
2018-02-08 12:13:29 +01:00
battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
if (gBattleMons[battlerId].ability == ability)
2017-09-22 21:33:49 +02:00
{
gLastUsedAbility = ability;
gBattlescriptCurrInstr = jumpPtr;
2018-02-08 12:13:29 +01:00
RecordAbilityBattle(battlerId, gLastUsedAbility);
gBattleScripting.battlerWithAbility = battlerId;
2017-09-22 21:33:49 +02:00
}
else
gBattlescriptCurrInstr += 7;
}
}
2017-09-28 15:34:21 +02:00
static void atk1F_jumpifsideaffecting(void)
2017-09-22 21:33:49 +02:00
{
u8 side;
2018-07-24 20:13:02 +02:00
u32 flags;
const u8 *jumpPtr;
2017-09-22 21:33:49 +02:00
2018-02-08 11:17:41 +01:00
if (gBattlescriptCurrInstr[1] == BS_ATTACKER)
2018-02-06 23:09:39 +01:00
side = GET_BATTLER_SIDE(gBattlerAttacker);
2017-09-22 21:33:49 +02:00
else
2018-02-06 23:09:39 +01:00
side = GET_BATTLER_SIDE(gBattlerTarget);
2017-09-22 21:33:49 +02:00
2018-07-24 20:13:02 +02:00
flags = T2_READ_32(gBattlescriptCurrInstr + 2);
jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 6);
2017-09-22 21:33:49 +02:00
2018-01-16 22:12:38 +01:00
if (gSideStatuses[side] & flags)
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr = jumpPtr;
else
2018-07-24 20:13:02 +02:00
gBattlescriptCurrInstr += 10;
2017-09-22 21:33:49 +02:00
}
2017-09-28 15:34:21 +02:00
static void atk20_jumpifstat(void)
2017-09-22 21:33:49 +02:00
{
u8 ret = 0;
2018-02-08 12:13:29 +01:00
u8 battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
u8 value = gBattleMons[battlerId].statStages[gBattlescriptCurrInstr[3]];
2017-09-22 21:33:49 +02:00
2017-09-28 15:34:21 +02:00
switch (gBattlescriptCurrInstr[2])
2017-09-22 21:33:49 +02:00
{
case CMP_EQUAL:
2017-09-28 15:34:21 +02:00
if (value == gBattlescriptCurrInstr[4])
2017-09-22 21:33:49 +02:00
ret++;
break;
case CMP_NOT_EQUAL:
2017-09-28 15:34:21 +02:00
if (value != gBattlescriptCurrInstr[4])
2017-09-22 21:33:49 +02:00
ret++;
break;
case CMP_GREATER_THAN:
2017-09-28 15:34:21 +02:00
if (value > gBattlescriptCurrInstr[4])
2017-09-22 21:33:49 +02:00
ret++;
break;
case CMP_LESS_THAN:
2017-09-28 15:34:21 +02:00
if (value < gBattlescriptCurrInstr[4])
2017-09-22 21:33:49 +02:00
ret++;
break;
case CMP_COMMON_BITS:
2017-09-28 15:34:21 +02:00
if (value & gBattlescriptCurrInstr[4])
2017-09-22 21:33:49 +02:00
ret++;
break;
case CMP_NO_COMMON_BITS:
2017-09-28 15:34:21 +02:00
if (!(value & gBattlescriptCurrInstr[4]))
2017-09-22 21:33:49 +02:00
ret++;
break;
}
if (ret)
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 5);
2017-09-22 21:33:49 +02:00
else
gBattlescriptCurrInstr += 9;
}
2017-11-26 11:55:17 +01:00
static void atk21_jumpifstatus3condition(void)
2017-09-22 21:33:49 +02:00
{
u32 flags;
2017-11-26 11:55:17 +01:00
const u8 *jumpPtr;
2017-09-22 21:33:49 +02:00
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-03-01 00:59:52 +01:00
flags = T2_READ_32(gBattlescriptCurrInstr + 2);
jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 7);
2017-09-22 21:33:49 +02:00
2017-09-28 15:34:21 +02:00
if (gBattlescriptCurrInstr[6])
2017-09-22 21:33:49 +02:00
{
2018-02-06 02:46:59 +01:00
if ((gStatuses3[gActiveBattler] & flags) != 0)
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 11;
else
gBattlescriptCurrInstr = jumpPtr;
}
else
{
2018-02-06 02:46:59 +01:00
if ((gStatuses3[gActiveBattler] & flags) != 0)
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr = jumpPtr;
else
gBattlescriptCurrInstr += 11;
}
}
2017-09-28 15:34:21 +02:00
static void atk22_jumpiftype(void)
2017-09-22 21:33:49 +02:00
{
2018-02-08 12:13:29 +01:00
u8 battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2017-09-28 15:34:21 +02:00
u8 type = gBattlescriptCurrInstr[2];
2018-03-01 00:59:52 +01:00
const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 3);
2017-09-22 21:33:49 +02:00
2018-03-01 00:59:52 +01:00
if (IS_BATTLER_OF_TYPE(battlerId, type))
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr = jumpPtr;
else
gBattlescriptCurrInstr += 7;
}
2017-09-28 15:34:21 +02:00
static void atk23_getexp(void)
2017-09-22 21:33:49 +02:00
{
u16 item;
s32 i; // also used as stringId
u8 holdEffect;
s32 sentIn;
s32 viaExpShare = 0;
u16* exp = &gBattleStruct->expValue;
2018-02-08 11:17:41 +01:00
gBattlerFainted = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
sentIn = gSentPokesToOpponent[(gBattlerFainted & 2) >> 1];
2017-09-22 21:33:49 +02:00
switch (gBattleScripting.atk23_state)
{
case 0: // check if should receive exp at all
2018-02-08 11:17:41 +01:00
if (GetBattlerSide(gBattlerFainted) != B_SIDE_OPPONENT || (gBattleTypeFlags &
2017-09-22 21:33:49 +02:00
(BATTLE_TYPE_LINK
| BATTLE_TYPE_x2000000
2018-09-20 22:00:00 +02:00
| BATTLE_TYPE_TRAINER_HILL
2017-09-22 21:33:49 +02:00
| BATTLE_TYPE_FRONTIER
| BATTLE_TYPE_SAFARI
| BATTLE_TYPE_BATTLE_TOWER
| BATTLE_TYPE_EREADER_TRAINER)))
{
gBattleScripting.atk23_state = 6; // goto last case
}
else
{
gBattleScripting.atk23_state++;
2018-02-08 11:17:41 +01:00
gBattleStruct->field_DF |= gBitTable[gBattlerPartyIndexes[gBattlerFainted]];
2017-09-22 21:33:49 +02:00
}
break;
case 1: // calculate experience points to redistribute
{
u16 calculatedExp;
s32 viaSentIn;
for (viaSentIn = 0, i = 0; i < 6; i++)
{
if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) == SPECIES_NONE || GetMonData(&gPlayerParty[i], MON_DATA_HP) == 0)
continue;
if (gBitTable[i] & sentIn)
viaSentIn++;
item = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM);
if (item == ITEM_ENIGMA_BERRY)
holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect;
else
holdEffect = ItemId_GetHoldEffect(item);
if (holdEffect == HOLD_EFFECT_EXP_SHARE)
viaExpShare++;
}
2018-02-08 11:17:41 +01:00
calculatedExp = gBaseStats[gBattleMons[gBattlerFainted].species].expYield * gBattleMons[gBattlerFainted].level / 7;
2017-09-22 21:33:49 +02:00
if (viaExpShare) // at least one mon is getting exp via exp share
{
*exp = calculatedExp / 2 / viaSentIn;
if (*exp == 0)
*exp = 1;
gExpShareExp = calculatedExp / 2 / viaExpShare;
if (gExpShareExp == 0)
gExpShareExp = 1;
}
else
{
*exp = calculatedExp / viaSentIn;
if (*exp == 0)
*exp = 1;
gExpShareExp = 0;
}
gBattleScripting.atk23_state++;
2018-02-07 22:53:40 +01:00
gBattleStruct->expGetterMonId = 0;
2017-09-22 21:33:49 +02:00
gBattleStruct->sentInPokes = sentIn;
}
// fall through
case 2: // set exp value to the poke in expgetter_id and print message
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags == 0)
2017-09-22 21:33:49 +02:00
{
2018-02-07 22:53:40 +01:00
item = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_HELD_ITEM);
2017-09-22 21:33:49 +02:00
if (item == ITEM_ENIGMA_BERRY)
holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect;
else
holdEffect = ItemId_GetHoldEffect(item);
if (holdEffect != HOLD_EFFECT_EXP_SHARE && !(gBattleStruct->sentInPokes & 1))
{
*(&gBattleStruct->sentInPokes) >>= 1;
gBattleScripting.atk23_state = 5;
gBattleMoveDamage = 0; // used for exp
}
2018-02-07 22:53:40 +01:00
else if (GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_LEVEL) == MAX_MON_LEVEL)
2017-09-22 21:33:49 +02:00
{
*(&gBattleStruct->sentInPokes) >>= 1;
gBattleScripting.atk23_state = 5;
gBattleMoveDamage = 0; // used for exp
}
else
{
// music change in wild battle after fainting a poke
if (!(gBattleTypeFlags & BATTLE_TYPE_TRAINER) && gBattleMons[0].hp && !gBattleStruct->wildVictorySong)
{
2017-11-04 16:11:13 +01:00
BattleStopLowHpSound();
2018-05-11 07:33:32 +02:00
PlayBGM(MUS_KACHI2);
2017-09-22 21:33:49 +02:00
gBattleStruct->wildVictorySong++;
}
2018-02-07 22:53:40 +01:00
if (GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_HP))
2017-09-22 21:33:49 +02:00
{
if (gBattleStruct->sentInPokes & 1)
gBattleMoveDamage = *exp;
else
gBattleMoveDamage = 0;
if (holdEffect == HOLD_EFFECT_EXP_SHARE)
gBattleMoveDamage += gExpShareExp;
if (holdEffect == HOLD_EFFECT_LUCKY_EGG)
gBattleMoveDamage = (gBattleMoveDamage * 150) / 100;
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
gBattleMoveDamage = (gBattleMoveDamage * 150) / 100;
2018-02-07 22:53:40 +01:00
if (IsTradedMon(&gPlayerParty[gBattleStruct->expGetterMonId]))
2017-09-22 21:33:49 +02:00
{
// check if the pokemon doesn't belong to the player
2018-02-07 22:53:40 +01:00
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gBattleStruct->expGetterMonId >= 3)
2017-09-22 21:33:49 +02:00
{
i = 0x149;
}
else
{
gBattleMoveDamage = (gBattleMoveDamage * 150) / 100;
i = 0x14A;
}
}
else
{
2017-09-27 23:43:45 +02:00
i = 0x149;
}
2017-09-22 21:33:49 +02:00
2018-02-08 12:13:29 +01:00
// get exp getter battlerId
2017-09-22 21:33:49 +02:00
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
2018-02-07 22:53:40 +01:00
if (!(gBattlerPartyIndexes[2] != gBattleStruct->expGetterMonId) && !(gAbsentBattlerFlags & gBitTable[2]))
gBattleStruct->expGetterBattlerId = 2;
2017-09-22 21:33:49 +02:00
else
{
2018-02-06 02:46:59 +01:00
if (!(gAbsentBattlerFlags & gBitTable[0]))
2018-02-07 22:53:40 +01:00
gBattleStruct->expGetterBattlerId = 0;
2017-09-22 21:33:49 +02:00
else
2018-02-07 22:53:40 +01:00
gBattleStruct->expGetterBattlerId = 2;
2017-09-22 21:33:49 +02:00
}
}
else
2018-02-07 22:53:40 +01:00
gBattleStruct->expGetterBattlerId = 0;
2017-09-22 21:33:49 +02:00
2018-02-07 22:53:40 +01:00
PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattleStruct->expGetterBattlerId, gBattleStruct->expGetterMonId)
2017-09-22 21:33:49 +02:00
// buffer 'gained' or 'gained a boosted'
2017-09-25 00:09:13 +02:00
PREPARE_STRING_BUFFER(gBattleTextBuff2, i)
PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff3, 5, gBattleMoveDamage)
2017-09-22 21:33:49 +02:00
2018-02-07 22:53:40 +01:00
PrepareStringBattle(STRINGID_PKMNGAINEDEXP, gBattleStruct->expGetterBattlerId);
2018-02-08 11:17:41 +01:00
MonGainEVs(&gPlayerParty[gBattleStruct->expGetterMonId], gBattleMons[gBattlerFainted].species);
2017-09-22 21:33:49 +02:00
}
gBattleStruct->sentInPokes >>= 1;
gBattleScripting.atk23_state++;
}
}
break;
case 3: // Set stats and give exp
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags == 0)
2017-09-22 21:33:49 +02:00
{
2018-02-07 22:53:40 +01:00
gBattleBufferB[gBattleStruct->expGetterBattlerId][0] = 0;
if (GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_HP) && GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_LEVEL) != MAX_MON_LEVEL)
2017-09-22 21:33:49 +02:00
{
2018-02-07 22:53:40 +01:00
gBattleResources->statsBeforeLvlUp->hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_MAX_HP);
gBattleResources->statsBeforeLvlUp->atk = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_ATK);
gBattleResources->statsBeforeLvlUp->def = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_DEF);
gBattleResources->statsBeforeLvlUp->spd = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPEED);
gBattleResources->statsBeforeLvlUp->spAtk = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPATK);
gBattleResources->statsBeforeLvlUp->spDef = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPDEF);
2017-09-22 21:33:49 +02:00
2018-02-07 22:53:40 +01:00
gActiveBattler = gBattleStruct->expGetterBattlerId;
BtlController_EmitExpUpdate(0, gBattleStruct->expGetterMonId, gBattleMoveDamage);
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec(gActiveBattler);
2017-09-22 21:33:49 +02:00
}
gBattleScripting.atk23_state++;
}
break;
case 4: // lvl up if necessary
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags == 0)
2017-09-22 21:33:49 +02:00
{
2018-02-07 22:53:40 +01:00
gActiveBattler = gBattleStruct->expGetterBattlerId;
2018-07-16 20:47:30 +02:00
if (gBattleBufferB[gActiveBattler][0] == CONTROLLER_TWORETURNVALUES && gBattleBufferB[gActiveBattler][1] == RET_VALUE_LEVELED_UP)
2017-09-22 21:33:49 +02:00
{
2018-09-29 18:40:14 +02:00
u16 temp, battlerId = 0xFF;
2018-02-07 22:53:40 +01:00
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && gBattlerPartyIndexes[gActiveBattler] == gBattleStruct->expGetterMonId)
2018-02-06 20:48:02 +01:00
HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler);
2017-09-22 21:33:49 +02:00
2018-02-07 22:53:40 +01:00
PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gActiveBattler, gBattleStruct->expGetterMonId)
2017-09-25 00:09:13 +02:00
2018-02-07 22:53:40 +01:00
PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 3, GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_LEVEL))
2017-09-22 21:33:49 +02:00
BattleScriptPushCursor();
2018-02-07 22:53:40 +01:00
gLeveledUpInBattle |= gBitTable[gBattleStruct->expGetterMonId];
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr = BattleScript_LevelUp;
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = (gBattleBufferB[gActiveBattler][2] | (gBattleBufferB[gActiveBattler][3] << 8));
2018-02-07 22:53:40 +01:00
AdjustFriendship(&gPlayerParty[gBattleStruct->expGetterMonId], 0);
2017-09-22 21:33:49 +02:00
// update battle mon structure after level up
2018-02-07 22:53:40 +01:00
if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterMonId && gBattleMons[0].hp)
2018-09-29 18:40:14 +02:00
battlerId = 0;
else if (gBattlerPartyIndexes[2] == gBattleStruct->expGetterMonId && gBattleMons[2].hp && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
battlerId = 2;
if (battlerId != 0xFF)
2017-09-22 21:33:49 +02:00
{
2018-09-29 18:40:14 +02:00
gBattleMons[battlerId].level = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_LEVEL);
gBattleMons[battlerId].hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_HP);
gBattleMons[battlerId].maxHP = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_MAX_HP);
gBattleMons[battlerId].attack = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_ATK);
gBattleMons[battlerId].defense = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_DEF);
gBattleMons[battlerId].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPEED);
gBattleMons[battlerId].spAttack = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPATK);
gBattleMons[battlerId].spDefense = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPDEF);
if (gStatuses3[battlerId] & STATUS3_POWER_TRICK)
SWAP(gBattleMons[battlerId].attack, gBattleMons[battlerId].defense, temp);
2017-09-22 21:33:49 +02:00
}
2018-09-29 18:40:14 +02:00
2017-09-22 21:33:49 +02:00
gBattleScripting.atk23_state = 5;
}
else
{
gBattleMoveDamage = 0;
gBattleScripting.atk23_state = 5;
}
}
break;
case 5: // looper increment
if (gBattleMoveDamage) // there is exp to give, goto case 3 that gives exp
gBattleScripting.atk23_state = 3;
else
{
2018-02-07 22:53:40 +01:00
gBattleStruct->expGetterMonId++;
if (gBattleStruct->expGetterMonId <= 5)
2017-09-22 21:33:49 +02:00
gBattleScripting.atk23_state = 2; // loop again
else
gBattleScripting.atk23_state = 6; // we're done
}
break;
case 6: // increment instruction
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags == 0)
2017-09-22 21:33:49 +02:00
{
// not sure why gf clears the item and ability here
2018-02-08 11:17:41 +01:00
gBattleMons[gBattlerFainted].item = 0;
gBattleMons[gBattlerFainted].ability = 0;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 2;
}
break;
}
}
2018-07-26 22:52:13 +02:00
static bool32 IsBattleLostForPlayer(void)
2017-09-22 21:33:49 +02:00
{
2018-07-26 22:52:13 +02:00
u32 i;
u32 HP_count = 0;
2017-09-22 21:33:49 +02:00
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gPartnerTrainerId == TRAINER_STEVEN_PARTNER)
2017-09-22 21:33:49 +02:00
{
for (i = 0; i < 3; i++)
{
if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG))
HP_count += GetMonData(&gPlayerParty[i], MON_DATA_HP);
}
}
else
{
2018-07-26 22:52:13 +02:00
for (i = 0; i < PARTY_SIZE; i++)
2017-09-22 21:33:49 +02:00
{
if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG)
2018-02-06 23:09:39 +01:00
&& (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || !(gBattleStruct->field_2A0 & gBitTable[i])))
2017-09-22 21:33:49 +02:00
{
HP_count += GetMonData(&gPlayerParty[i], MON_DATA_HP);
}
}
}
2018-07-26 22:52:13 +02:00
return (HP_count == 0);
}
static bool32 IsBattleWonForPlayer(void)
{
u32 i;
u32 HP_count = 0;
2017-09-22 21:33:49 +02:00
2018-07-26 22:52:13 +02:00
for (i = 0; i < PARTY_SIZE; i++)
2017-09-22 21:33:49 +02:00
{
if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES) && !GetMonData(&gEnemyParty[i], MON_DATA_IS_EGG)
&& (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || !(gBattleStruct->field_2A1 & gBitTable[i])))
{
HP_count += GetMonData(&gEnemyParty[i], MON_DATA_HP);
}
}
2018-07-26 22:52:13 +02:00
return (HP_count == 0);
}
static void atk24(void)
{
if (gBattleControllerExecFlags)
return;
if (IsBattleLostForPlayer())
gBattleOutcome |= B_OUTCOME_LOST;
if (IsBattleWonForPlayer())
2018-01-16 22:12:38 +01:00
gBattleOutcome |= B_OUTCOME_WON;
2017-09-22 21:33:49 +02:00
if (gBattleOutcome == 0 && (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)))
{
2018-07-26 22:52:13 +02:00
s32 i;
2017-09-22 21:33:49 +02:00
s32 foundPlayer;
s32 foundOpponent;
// Impossible to decompile loops.
2018-02-06 02:46:59 +01:00
for (foundPlayer = 0, i = 0; i < gBattlersCount; i += 2)
2017-09-22 21:33:49 +02:00
{
if (HITMARKER_UNK(i) & gHitMarker && !gSpecialStatuses[i].flag40)
foundPlayer++;
}
2018-02-06 02:46:59 +01:00
for (foundOpponent = 0, i = 1; i < gBattlersCount; i += 2)
2017-09-22 21:33:49 +02:00
{
if (HITMARKER_UNK(i) & gHitMarker && !gSpecialStatuses[i].flag40)
foundOpponent++;
}
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
{
if (foundOpponent + foundPlayer > 1)
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-22 21:33:49 +02:00
else
gBattlescriptCurrInstr += 5;
}
else
{
if (foundOpponent != 0 && foundPlayer != 0)
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-22 21:33:49 +02:00
else
gBattlescriptCurrInstr += 5;
}
}
else
{
gBattlescriptCurrInstr += 5;
}
}
2017-09-28 15:34:21 +02:00
static void MoveValuesCleanUp(void)
2017-09-22 21:33:49 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags = 0;
2018-07-14 22:56:03 +02:00
gIsCriticalHit = FALSE;
2017-09-22 21:33:49 +02:00
gBattleCommunication[MOVE_EFFECT_BYTE] = 0;
gBattleCommunication[6] = 0;
gHitMarker &= ~(HITMARKER_DESTINYBOND);
gHitMarker &= ~(HITMARKER_SYNCHRONISE_EFFECT);
}
static void atk25_movevaluescleanup(void)
2017-09-22 21:33:49 +02:00
{
MoveValuesCleanUp();
gBattlescriptCurrInstr += 1;
}
static void atk26_setmultihit(void)
2017-09-22 21:33:49 +02:00
{
2017-09-28 15:34:21 +02:00
gMultiHitCounter = gBattlescriptCurrInstr[1];
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 2;
}
static void atk27_decrementmultihit(void)
2017-09-22 21:33:49 +02:00
{
if (--gMultiHitCounter == 0)
gBattlescriptCurrInstr += 5;
else
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-22 21:33:49 +02:00
}
2017-09-28 15:34:21 +02:00
static void atk28_goto(void)
2017-09-22 21:33:49 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-22 21:33:49 +02:00
}
2017-09-28 15:34:21 +02:00
static void atk29_jumpifbyte(void)
2017-09-22 21:33:49 +02:00
{
2017-09-28 15:34:21 +02:00
u8 caseID = gBattlescriptCurrInstr[1];
2018-03-01 00:59:52 +01:00
const u8* memByte = T2_READ_PTR(gBattlescriptCurrInstr + 2);
2017-09-28 15:34:21 +02:00
u8 value = gBattlescriptCurrInstr[6];
2018-03-01 00:59:52 +01:00
const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 7);
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 11;
switch (caseID)
{
case CMP_EQUAL:
if (*memByte == value)
gBattlescriptCurrInstr = jumpPtr;
break;
case CMP_NOT_EQUAL:
if (*memByte != value)
gBattlescriptCurrInstr = jumpPtr;
break;
case CMP_GREATER_THAN:
if (*memByte > value)
gBattlescriptCurrInstr = jumpPtr;
break;
case CMP_LESS_THAN:
if (*memByte < value)
gBattlescriptCurrInstr = jumpPtr;
break;
case CMP_COMMON_BITS:
if (*memByte & value)
gBattlescriptCurrInstr = jumpPtr;
break;
case CMP_NO_COMMON_BITS:
if (!(*memByte & value))
gBattlescriptCurrInstr = jumpPtr;
break;
}
}
2017-09-28 15:34:21 +02:00
static void atk2A_jumpifhalfword(void)
2017-09-22 21:33:49 +02:00
{
2017-09-28 15:34:21 +02:00
u8 caseID = gBattlescriptCurrInstr[1];
2018-03-01 00:59:52 +01:00
const u16* memHword = T2_READ_PTR(gBattlescriptCurrInstr + 2);
u16 value = T2_READ_16(gBattlescriptCurrInstr + 6);
const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 8);
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 12;
switch (caseID)
{
case CMP_EQUAL:
if (*memHword == value)
gBattlescriptCurrInstr = jumpPtr;
break;
case CMP_NOT_EQUAL:
if (*memHword != value)
gBattlescriptCurrInstr = jumpPtr;
break;
case CMP_GREATER_THAN:
if (*memHword > value)
gBattlescriptCurrInstr = jumpPtr;
break;
case CMP_LESS_THAN:
if (*memHword < value)
gBattlescriptCurrInstr = jumpPtr;
break;
case CMP_COMMON_BITS:
if (*memHword & value)
gBattlescriptCurrInstr = jumpPtr;
break;
case CMP_NO_COMMON_BITS:
if (!(*memHword & value))
gBattlescriptCurrInstr = jumpPtr;
break;
}
}
2017-09-28 15:34:21 +02:00
static void atk2B_jumpifword(void)
2017-09-22 21:33:49 +02:00
{
2017-09-28 15:34:21 +02:00
u8 caseID = gBattlescriptCurrInstr[1];
2018-03-01 00:59:52 +01:00
const u32* memWord = T2_READ_PTR(gBattlescriptCurrInstr + 2);
u32 value = T1_READ_32(gBattlescriptCurrInstr + 6);
const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 10);
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 14;
switch (caseID)
{
case CMP_EQUAL:
if (*memWord == value)
gBattlescriptCurrInstr = jumpPtr;
break;
case CMP_NOT_EQUAL:
if (*memWord != value)
gBattlescriptCurrInstr = jumpPtr;
break;
case CMP_GREATER_THAN:
if (*memWord > value)
gBattlescriptCurrInstr = jumpPtr;
break;
case CMP_LESS_THAN:
if (*memWord < value)
gBattlescriptCurrInstr = jumpPtr;
break;
case CMP_COMMON_BITS:
if (*memWord & value)
gBattlescriptCurrInstr = jumpPtr;
break;
case CMP_NO_COMMON_BITS:
if (!(*memWord & value))
gBattlescriptCurrInstr = jumpPtr;
break;
}
}
2017-09-28 15:34:21 +02:00
static void atk2C_jumpifarrayequal(void)
2017-09-22 21:33:49 +02:00
{
2018-03-01 00:59:52 +01:00
const u8* mem1 = T2_READ_PTR(gBattlescriptCurrInstr + 1);
const u8* mem2 = T2_READ_PTR(gBattlescriptCurrInstr + 5);
2017-09-28 15:34:21 +02:00
u32 size = gBattlescriptCurrInstr[9];
2018-03-01 00:59:52 +01:00
const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 10);
2017-09-22 21:33:49 +02:00
u8 i;
for (i = 0; i < size; i++)
{
if (*mem1 != *mem2)
{
gBattlescriptCurrInstr += 14;
break;
}
mem1++, mem2++;
}
if (i == size)
gBattlescriptCurrInstr = jumpPtr;
}
2017-09-28 15:34:21 +02:00
static void atk2D_jumpifarraynotequal(void)
2017-09-22 21:33:49 +02:00
{
u8 equalBytes = 0;
2018-03-01 00:59:52 +01:00
const u8* mem1 = T2_READ_PTR(gBattlescriptCurrInstr + 1);
const u8* mem2 = T2_READ_PTR(gBattlescriptCurrInstr + 5);
2017-09-28 15:34:21 +02:00
u32 size = gBattlescriptCurrInstr[9];
2018-03-01 00:59:52 +01:00
const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 10);
2017-09-22 21:33:49 +02:00
u8 i;
for (i = 0; i < size; i++)
{
if (*mem1 == *mem2)
{
equalBytes++;
}
mem1++, mem2++;
}
if (equalBytes != size)
gBattlescriptCurrInstr = jumpPtr;
else
gBattlescriptCurrInstr += 14;
}
2017-09-28 15:34:21 +02:00
static void atk2E_setbyte(void)
2017-09-22 21:33:49 +02:00
{
2018-03-01 00:59:52 +01:00
u8* memByte = T2_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-28 15:34:21 +02:00
*memByte = gBattlescriptCurrInstr[5];
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 6;
}
2017-09-28 15:34:21 +02:00
static void atk2F_addbyte(void)
2017-09-22 21:33:49 +02:00
{
2018-03-01 00:59:52 +01:00
u8* memByte = T2_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-28 15:34:21 +02:00
*memByte += gBattlescriptCurrInstr[5];
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 6;
}
2017-09-28 15:34:21 +02:00
static void atk30_subbyte(void)
2017-09-22 21:33:49 +02:00
{
2018-03-01 00:59:52 +01:00
u8* memByte = T2_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-28 15:34:21 +02:00
*memByte -= gBattlescriptCurrInstr[5];
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 6;
}
2017-09-28 15:34:21 +02:00
static void atk31_copyarray(void)
2017-09-22 21:33:49 +02:00
{
2018-03-01 00:59:52 +01:00
u8* dest = T2_READ_PTR(gBattlescriptCurrInstr + 1);
const u8* src = T2_READ_PTR(gBattlescriptCurrInstr + 5);
2017-09-28 15:34:21 +02:00
s32 size = gBattlescriptCurrInstr[9];
2017-09-22 21:33:49 +02:00
s32 i;
for (i = 0; i < size; i++)
{
dest[i] = src[i];
}
gBattlescriptCurrInstr += 10;
}
static void atk32_copyarraywithindex(void)
2017-09-22 21:33:49 +02:00
{
2018-03-01 00:59:52 +01:00
u8* dest = T2_READ_PTR(gBattlescriptCurrInstr + 1);
const u8* src = T2_READ_PTR(gBattlescriptCurrInstr + 5);
const u8* index = T2_READ_PTR(gBattlescriptCurrInstr + 9);
2017-09-28 15:34:21 +02:00
s32 size = gBattlescriptCurrInstr[13];
2017-09-22 21:33:49 +02:00
s32 i;
for (i = 0; i < size; i++)
{
dest[i] = src[i + *index];
}
gBattlescriptCurrInstr += 14;
}
2017-09-28 15:34:21 +02:00
static void atk33_orbyte(void)
2017-09-22 21:33:49 +02:00
{
2018-03-01 00:59:52 +01:00
u8* memByte = T2_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-28 15:34:21 +02:00
*memByte |= gBattlescriptCurrInstr[5];
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 6;
}
2017-09-28 15:34:21 +02:00
static void atk34_orhalfword(void)
2017-09-22 21:33:49 +02:00
{
2018-03-01 00:59:52 +01:00
u16* memHword = T2_READ_PTR(gBattlescriptCurrInstr + 1);
u16 val = T2_READ_16(gBattlescriptCurrInstr + 5);
2017-09-22 21:33:49 +02:00
*memHword |= val;
gBattlescriptCurrInstr += 7;
}
2017-09-28 15:34:21 +02:00
static void atk35_orword(void)
2017-09-22 21:33:49 +02:00
{
2018-03-01 00:59:52 +01:00
u32* memWord = T2_READ_PTR(gBattlescriptCurrInstr + 1);
u32 val = T2_READ_32(gBattlescriptCurrInstr + 5);
2017-09-22 21:33:49 +02:00
*memWord |= val;
gBattlescriptCurrInstr += 9;
}
2017-09-28 15:34:21 +02:00
static void atk36_bicbyte(void)
2017-09-22 21:33:49 +02:00
{
2018-03-01 00:59:52 +01:00
u8* memByte = T2_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-28 15:34:21 +02:00
*memByte &= ~(gBattlescriptCurrInstr[5]);
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 6;
}
2017-09-28 15:34:21 +02:00
static void atk37_bichalfword(void)
2017-09-22 21:33:49 +02:00
{
2018-03-01 00:59:52 +01:00
u16* memHword = T2_READ_PTR(gBattlescriptCurrInstr + 1);
u16 val = T2_READ_16(gBattlescriptCurrInstr + 5);
2017-09-22 21:33:49 +02:00
*memHword &= ~val;
gBattlescriptCurrInstr += 7;
}
2017-09-28 15:34:21 +02:00
static void atk38_bicword(void)
2017-09-22 21:33:49 +02:00
{
2018-03-01 00:59:52 +01:00
u32* memWord = T2_READ_PTR(gBattlescriptCurrInstr + 1);
u32 val = T2_READ_32(gBattlescriptCurrInstr + 5);
2017-09-22 21:33:49 +02:00
*memWord &= ~val;
gBattlescriptCurrInstr += 9;
}
2017-09-28 15:34:21 +02:00
static void atk39_pause(void)
2017-09-22 21:33:49 +02:00
{
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags == 0)
2017-09-22 21:33:49 +02:00
{
2018-03-01 00:59:52 +01:00
u16 value = T2_READ_16(gBattlescriptCurrInstr + 1);
2017-09-22 21:33:49 +02:00
if (++gPauseCounterBattle >= value)
{
gPauseCounterBattle = 0;
gBattlescriptCurrInstr += 3;
}
}
}
2017-09-28 15:34:21 +02:00
static void atk3A_waitstate(void)
2017-09-22 21:33:49 +02:00
{
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags == 0)
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atk3B_healthbar_update(void)
2017-09-22 21:33:49 +02:00
{
2018-02-08 11:17:41 +01:00
if (gBattlescriptCurrInstr[1] == BS_TARGET)
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget;
2017-09-22 21:33:49 +02:00
else
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2017-09-22 21:33:49 +02:00
2018-02-06 20:48:02 +01:00
BtlController_EmitHealthBarUpdate(0, gBattleMoveDamage);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 2;
}
2017-09-28 15:34:21 +02:00
static void atk3C_return(void)
2017-09-22 21:33:49 +02:00
{
BattleScriptPop();
}
2017-09-28 15:34:21 +02:00
static void atk3D_end(void)
2017-09-22 21:33:49 +02:00
{
if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
2018-02-06 23:09:39 +01:00
sub_81A5718(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;
2017-10-06 00:12:01 +02:00
gCurrentActionFuncId = 0xB;
2017-09-22 21:33:49 +02:00
}
2017-09-28 15:34:21 +02:00
static void atk3E_end2(void)
2017-09-22 21:33:49 +02:00
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 0;
2017-10-06 00:12:01 +02:00
gCurrentActionFuncId = 0xB;
2017-09-22 21:33:49 +02:00
}
2017-09-28 15:34:21 +02:00
static void atk3F_end3(void) // pops the main function stack
2017-09-22 21:33:49 +02:00
{
BattleScriptPop();
2018-02-06 23:09:39 +01:00
if (gBattleResources->battleCallbackStack->size != 0)
gBattleResources->battleCallbackStack->size--;
gBattleMainFunc = gBattleResources->battleCallbackStack->function[gBattleResources->battleCallbackStack->size];
2017-09-22 21:33:49 +02:00
}
2017-09-28 15:34:21 +02:00
static void atk41_call(void)
2017-09-22 21:33:49 +02:00
{
BattleScriptPush(gBattlescriptCurrInstr + 5);
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-22 21:33:49 +02:00
}
static void atk42_setroost(void)
2017-09-22 21:33:49 +02:00
{
gBattleResources->flags->flags[gBattlerAttacker] |= RESOURCE_FLAG_ROOST;
// Pure flying type.
if (gBattleMons[gBattlerAttacker].type1 == TYPE_FLYING && gBattleMons[gBattlerAttacker].type2 == TYPE_FLYING)
{
gBattleStruct->roostTypes[gBattlerAttacker][0] = TYPE_FLYING;
gBattleStruct->roostTypes[gBattlerAttacker][1] = TYPE_FLYING;
gBattleStruct->roostTypes[gBattlerAttacker][2] = TYPE_FLYING;
SET_BATTLER_TYPE(gBattlerAttacker, TYPE_NORMAL);
}
// Dual Type with Flying Type.
else if ((gBattleMons[gBattlerAttacker].type1 == TYPE_FLYING && gBattleMons[gBattlerAttacker].type2 != TYPE_FLYING)
||(gBattleMons[gBattlerAttacker].type2 == TYPE_FLYING && gBattleMons[gBattlerAttacker].type1 != TYPE_FLYING))
{
gBattleStruct->roostTypes[gBattlerAttacker][0] = gBattleMons[gBattlerAttacker].type1;
gBattleStruct->roostTypes[gBattlerAttacker][1] = gBattleMons[gBattlerAttacker].type2;
if (gBattleMons[gBattlerAttacker].type1 == TYPE_FLYING)
gBattleMons[gBattlerAttacker].type1 = TYPE_MYSTERY;
if (gBattleMons[gBattlerAttacker].type2 == TYPE_FLYING)
gBattleMons[gBattlerAttacker].type2 = TYPE_MYSTERY;
}
// Non-flying type.
else if (!IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_FLYING))
{
gBattleStruct->roostTypes[gBattlerAttacker][0] = gBattleMons[gBattlerAttacker].type1;
gBattleStruct->roostTypes[gBattlerAttacker][1] = gBattleMons[gBattlerAttacker].type2;
}
gBattlescriptCurrInstr++;
2017-09-22 21:33:49 +02:00
}
2017-09-28 15:34:21 +02:00
static void atk43_jumpifabilitypresent(void)
2017-09-22 21:33:49 +02:00
{
2017-09-28 15:34:21 +02:00
if (AbilityBattleEffects(ABILITYEFFECT_CHECK_ON_FIELD, 0, gBattlescriptCurrInstr[1], 0, 0))
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
2017-09-22 21:33:49 +02:00
else
gBattlescriptCurrInstr += 6;
}
static void atk44_endselectionscript(void)
2017-09-22 21:33:49 +02:00
{
2018-02-06 23:09:39 +01:00
*(gBattlerAttacker + gBattleStruct->selectionScriptFinished) = TRUE;
2017-09-22 21:33:49 +02:00
}
2017-09-28 15:34:21 +02:00
static void atk45_playanimation(void)
2017-09-22 21:33:49 +02:00
{
const u16* argumentPtr;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-03-01 00:59:52 +01:00
argumentPtr = T2_READ_PTR(gBattlescriptCurrInstr + 3);
2017-09-22 21:33:49 +02:00
if (gBattlescriptCurrInstr[2] == B_ANIM_STATS_CHANGE
|| gBattlescriptCurrInstr[2] == B_ANIM_SNATCH_MOVE
|| gBattlescriptCurrInstr[2] == B_ANIM_SUBSTITUTE_FADE)
{
2018-02-06 20:48:02 +01:00
BtlController_EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 7;
}
else if (gHitMarker & HITMARKER_NO_ANIMATIONS)
{
BattleScriptPush(gBattlescriptCurrInstr + 7);
gBattlescriptCurrInstr = BattleScript_Pausex20;
}
else if (gBattlescriptCurrInstr[2] == B_ANIM_RAIN_CONTINUES
|| gBattlescriptCurrInstr[2] == B_ANIM_SUN_CONTINUES
|| gBattlescriptCurrInstr[2] == B_ANIM_SANDSTORM_CONTINUES
|| gBattlescriptCurrInstr[2] == B_ANIM_HAIL_CONTINUES)
{
2018-02-06 20:48:02 +01:00
BtlController_EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 7;
}
2018-02-06 02:46:59 +01:00
else if (gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE)
2017-09-22 21:33:49 +02:00
{
gBattlescriptCurrInstr += 7;
}
else
{
2018-02-06 20:48:02 +01:00
BtlController_EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 7;
}
}
2017-09-28 15:34:21 +02:00
static void atk46_playanimation2(void) // animation Id is stored in the first pointer
2017-09-22 21:33:49 +02:00
{
const u16* argumentPtr;
const u8* animationIdPtr;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-03-01 00:59:52 +01:00
animationIdPtr = T2_READ_PTR(gBattlescriptCurrInstr + 2);
argumentPtr = T2_READ_PTR(gBattlescriptCurrInstr + 6);
2017-09-22 21:33:49 +02:00
if (*animationIdPtr == B_ANIM_STATS_CHANGE
|| *animationIdPtr == B_ANIM_SNATCH_MOVE
|| *animationIdPtr == B_ANIM_SUBSTITUTE_FADE)
{
2018-02-06 20:48:02 +01:00
BtlController_EmitBattleAnimation(0, *animationIdPtr, *argumentPtr);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 10;
}
else if (gHitMarker & HITMARKER_NO_ANIMATIONS)
{
gBattlescriptCurrInstr += 10;
}
else if (*animationIdPtr == B_ANIM_RAIN_CONTINUES
|| *animationIdPtr == B_ANIM_SUN_CONTINUES
|| *animationIdPtr == B_ANIM_SANDSTORM_CONTINUES
|| *animationIdPtr == B_ANIM_HAIL_CONTINUES)
{
2018-02-06 20:48:02 +01:00
BtlController_EmitBattleAnimation(0, *animationIdPtr, *argumentPtr);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 10;
}
2018-02-06 02:46:59 +01:00
else if (gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE)
2017-09-22 21:33:49 +02:00
{
gBattlescriptCurrInstr += 10;
}
else
{
2018-02-06 20:48:02 +01:00
BtlController_EmitBattleAnimation(0, *animationIdPtr, *argumentPtr);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 10;
}
}
2017-09-28 15:34:21 +02:00
static void atk47_setgraphicalstatchangevalues(void)
2017-09-22 21:33:49 +02:00
{
u8 value = 0;
2018-07-29 15:51:08 +02:00
switch (GET_STAT_BUFF_VALUE2(gBattleScripting.statChanger))
2017-09-22 21:33:49 +02:00
{
2018-07-29 15:51:08 +02:00
case SET_STAT_BUFF_VALUE(1): // +1
2017-09-22 21:33:49 +02:00
value = 0xF;
break;
2018-07-29 15:51:08 +02:00
case SET_STAT_BUFF_VALUE(2): // +2
case SET_STAT_BUFF_VALUE(3): // +3
2017-09-22 21:33:49 +02:00
value = 0x27;
break;
2018-07-29 15:51:08 +02:00
case SET_STAT_BUFF_VALUE(1) | STAT_BUFF_NEGATIVE: // -1
2017-09-22 21:33:49 +02:00
value = 0x16;
break;
2018-07-29 15:51:08 +02:00
case SET_STAT_BUFF_VALUE(2) | STAT_BUFF_NEGATIVE: // -2
case SET_STAT_BUFF_VALUE(3) | STAT_BUFF_NEGATIVE: // -3
2017-09-22 21:33:49 +02:00
value = 0x2E;
break;
}
2018-07-29 15:51:08 +02:00
gBattleScripting.animArg1 = GET_STAT_BUFF_ID(gBattleScripting.statChanger) + value - 1;
2017-09-22 21:33:49 +02:00
gBattleScripting.animArg2 = 0;
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atk48_playstatchangeanimation(void)
2017-09-22 21:33:49 +02:00
{
2017-09-23 00:06:52 +02:00
u32 currStat = 0;
2018-02-28 19:37:48 +01:00
u16 statAnimId = 0;
s32 changeableStatsCount = 0;
u8 statsToCheck = 0;
2017-09-22 21:33:49 +02:00
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2017-09-23 00:06:52 +02:00
statsToCheck = gBattlescriptCurrInstr[2];
2017-09-22 21:33:49 +02:00
2017-09-23 00:06:52 +02:00
if (gBattlescriptCurrInstr[3] & ATK48_STAT_NEGATIVE) // goes down
2017-09-22 21:33:49 +02:00
{
2018-02-28 19:37:48 +01:00
s16 startingStatAnimId;
if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO)
startingStatAnimId = 0x2D;
else
startingStatAnimId = 0x15;
2017-09-23 00:06:52 +02:00
while (statsToCheck != 0)
2017-09-22 21:33:49 +02:00
{
2017-09-23 00:06:52 +02:00
if (statsToCheck & 1)
2017-09-22 21:33:49 +02:00
{
2018-02-28 19:37:48 +01:00
if (gBattlescriptCurrInstr[3] & ATK48_DONT_CHECK_LOWER)
2017-09-22 21:33:49 +02:00
{
2018-02-06 02:46:59 +01:00
if (gBattleMons[gActiveBattler].statStages[currStat] > 0)
2017-09-23 00:06:52 +02:00
{
2018-02-28 19:37:48 +01:00
statAnimId = startingStatAnimId + currStat;
changeableStatsCount++;
2017-09-23 00:06:52 +02:00
}
2017-09-22 21:33:49 +02:00
}
2018-02-06 02:46:59 +01:00
else if (!gSideTimers[GET_BATTLER_SIDE(gActiveBattler)].mistTimer
&& gBattleMons[gActiveBattler].ability != ABILITY_CLEAR_BODY
&& gBattleMons[gActiveBattler].ability != ABILITY_WHITE_SMOKE
2018-02-08 12:13:29 +01:00
&& !(gBattleMons[gActiveBattler].ability == ABILITY_KEEN_EYE && currStat == STAT_ACC)
&& !(gBattleMons[gActiveBattler].ability == ABILITY_HYPER_CUTTER && currStat == STAT_ATK))
2017-09-22 21:33:49 +02:00
{
2018-02-06 02:46:59 +01:00
if (gBattleMons[gActiveBattler].statStages[currStat] > 0)
2017-09-23 00:06:52 +02:00
{
2018-02-28 19:37:48 +01:00
statAnimId = startingStatAnimId + currStat;
changeableStatsCount++;
2017-09-23 00:06:52 +02:00
}
2017-09-22 21:33:49 +02:00
}
}
2018-02-28 19:37:48 +01:00
statsToCheck >>= 1, currStat++;
2017-09-22 21:33:49 +02:00
}
2018-02-28 19:37:48 +01:00
if (changeableStatsCount > 1) // more than one stat, so the color is gray
2017-09-22 21:33:49 +02:00
{
2017-09-23 00:06:52 +02:00
if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO)
2017-09-22 21:33:49 +02:00
statAnimId = 0x3A;
else
statAnimId = 0x39;
}
}
else // goes up
{
2018-02-28 19:37:48 +01:00
s16 startingStatAnimId;
if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO)
startingStatAnimId = 0x26;
else
startingStatAnimId = 0xE;
2017-09-23 00:06:52 +02:00
while (statsToCheck != 0)
2017-09-22 21:33:49 +02:00
{
2018-02-06 02:46:59 +01:00
if (statsToCheck & 1 && gBattleMons[gActiveBattler].statStages[currStat] < 0xC)
2017-09-22 21:33:49 +02:00
{
2018-02-28 19:37:48 +01:00
statAnimId = startingStatAnimId + currStat;
changeableStatsCount++;
2017-09-22 21:33:49 +02:00
}
2018-02-28 19:37:48 +01:00
statsToCheck >>= 1, currStat++;
2017-09-22 21:33:49 +02:00
}
2018-02-28 19:37:48 +01:00
if (changeableStatsCount > 1) // more than one stat, so the color is gray
2017-09-22 21:33:49 +02:00
{
2017-09-23 00:06:52 +02:00
if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO)
2017-09-22 21:33:49 +02:00
statAnimId = 0x38;
else
statAnimId = 0x37;
}
}
2018-07-29 15:33:16 +02:00
if (gBattlescriptCurrInstr[3] & ATK48_ONLY_MULTIPLE && changeableStatsCount < 2)
2017-09-22 21:33:49 +02:00
{
gBattlescriptCurrInstr += 4;
}
2018-07-29 15:33:16 +02:00
else if (changeableStatsCount != 0 && !gBattleScripting.statAnimPlayed)
2017-09-22 21:33:49 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitBattleAnimation(0, B_ANIM_STATS_CHANGE, statAnimId);
MarkBattlerForControllerExec(gActiveBattler);
2018-07-29 15:33:16 +02:00
if (gBattlescriptCurrInstr[3] & ATK48_ONLY_MULTIPLE && changeableStatsCount > 1)
gBattleScripting.statAnimPlayed = TRUE;
2017-09-22 21:33:49 +02:00
gBattlescriptCurrInstr += 4;
}
else
{
gBattlescriptCurrInstr += 4;
}
}
2017-09-23 20:13:45 +02:00
2018-09-01 20:00:13 +02:00
enum
{
ATK49_RAGE,
ATK49_DEFROST,
ATK49_SYNCHRONIZE_TARGET,
ATK49_MOVE_END_ABILITIES,
ATK49_STATUS_IMMUNITY_ABILITIES,
ATK49_SYNCHRONIZE_ATTACKER,
ATK49_CHOICE_MOVE,
ATK49_CHANGED_ITEMS,
ATK49_ATTACKER_INVISIBLE,
ATK49_ATTACKER_VISIBLE,
ATK49_TARGET_VISIBLE,
ATK49_ITEM_EFFECTS_ALL,
ATK49_KINGSROCK_SHELLBELL,
ATK49_SUBSTITUTE,
ATK49_UPDATE_LAST_MOVES,
ATK49_MIRROR_MOVE,
ATK49_NEXT_TARGET,
2018-09-02 00:07:19 +02:00
ATK49_CLEAR_BITS,
2018-09-01 20:00:13 +02:00
ATK49_COUNT,
};
2017-09-23 20:13:45 +02:00
2017-09-28 15:34:21 +02:00
static void atk49_moveend(void)
2017-09-23 20:13:45 +02:00
{
s32 i;
2018-09-01 20:00:13 +02:00
bool32 effect = FALSE;
u8 moveType = 0;
u8 holdEffectAtk = 0;
u16 *choicedMoveAtk = NULL;
2017-09-23 20:13:45 +02:00
u8 arg1, arg2;
2017-11-26 14:17:02 +01:00
u16 originallyUsedMove;
2017-09-23 20:13:45 +02:00
2017-11-26 18:07:00 +01:00
if (gChosenMove == 0xFFFF)
2017-11-26 14:17:02 +01:00
originallyUsedMove = 0;
2017-09-23 20:13:45 +02:00
else
2017-11-26 18:07:00 +01:00
originallyUsedMove = gChosenMove;
2017-09-23 20:13:45 +02:00
arg1 = gBattlescriptCurrInstr[1];
arg2 = gBattlescriptCurrInstr[2];
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerAttacker].item == ITEM_ENIGMA_BERRY)
holdEffectAtk = gEnigmaBerries[gBattlerAttacker].holdEffect;
2017-09-23 20:13:45 +02:00
else
2018-02-06 23:09:39 +01:00
holdEffectAtk = ItemId_GetHoldEffect(gBattleMons[gBattlerAttacker].item);
2017-09-23 20:13:45 +02:00
2018-02-06 23:09:39 +01:00
choicedMoveAtk = &gBattleStruct->choicedMove[gBattlerAttacker];
2017-09-23 20:13:45 +02:00
GET_MOVE_TYPE(gCurrentMove, moveType);
do
{
switch (gBattleScripting.atk49_state)
{
2018-09-01 20:00:13 +02:00
case ATK49_RAGE: // rage check
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].status2 & STATUS2_RAGE
&& gBattleMons[gBattlerTarget].hp != 0 && gBattlerAttacker != gBattlerTarget
&& GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)
2018-01-16 22:12:38 +01:00
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && TARGET_TURN_DAMAGED
2018-02-08 12:13:29 +01:00
&& gBattleMoves[gCurrentMove].power && gBattleMons[gBattlerTarget].statStages[STAT_ATK] <= 0xB)
2017-09-23 20:13:45 +02:00
{
2018-02-08 12:13:29 +01:00
gBattleMons[gBattlerTarget].statStages[STAT_ATK]++;
2017-09-23 20:13:45 +02:00
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_RageIsBuilding;
effect = TRUE;
}
gBattleScripting.atk49_state++;
break;
2018-09-01 20:00:13 +02:00
case ATK49_DEFROST: // defrosting check
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].status1 & STATUS1_FREEZE
&& gBattleMons[gBattlerTarget].hp != 0 && gBattlerAttacker != gBattlerTarget
2018-02-07 22:53:40 +01:00
&& gSpecialStatuses[gBattlerTarget].specialDmg
2018-08-11 13:30:34 +02:00
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && (moveType == TYPE_FIRE || gBattleMoves[gCurrentMove].effect == EFFECT_SCALD))
2018-01-16 22:12:38 +01:00
{
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerTarget].status1 &= ~(STATUS1_FREEZE);
gActiveBattler = gBattlerTarget;
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gBattlerTarget].status1);
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec(gActiveBattler);
2017-09-23 20:13:45 +02:00
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_DefrostedViaFireMove;
effect = TRUE;
}
gBattleScripting.atk49_state++;
break;
2018-09-01 20:00:13 +02:00
case ATK49_SYNCHRONIZE_TARGET: // target synchronize
2018-02-06 23:09:39 +01:00
if (AbilityBattleEffects(ABILITYEFFECT_SYNCHRONIZE, gBattlerTarget, 0, 0, 0))
2017-09-23 20:13:45 +02:00
effect = TRUE;
gBattleScripting.atk49_state++;
break;
2018-09-01 20:00:13 +02:00
case ATK49_MOVE_END_ABILITIES: // Such as abilities activating on contact(Poison Spore, Rough Skin, etc.).
if (AbilityBattleEffects(ABILITYEFFECT_MOVE_END, gBattlerTarget, 0, 0, 0))
2017-09-23 20:13:45 +02:00
effect = TRUE;
gBattleScripting.atk49_state++;
break;
2018-09-01 20:00:13 +02:00
case ATK49_STATUS_IMMUNITY_ABILITIES: // status immunities
2017-09-23 20:13:45 +02:00
if (AbilityBattleEffects(ABILITYEFFECT_IMMUNITY, 0, 0, 0, 0))
2018-02-08 12:13:29 +01:00
effect = TRUE; // it loops through all battlers, so we increment after its done with all battlers
2017-09-23 20:13:45 +02:00
else
gBattleScripting.atk49_state++;
break;
2018-09-01 20:00:13 +02:00
case ATK49_SYNCHRONIZE_ATTACKER: // attacker synchronize
2018-02-06 23:09:39 +01:00
if (AbilityBattleEffects(ABILITYEFFECT_ATK_SYNCHRONIZE, gBattlerAttacker, 0, 0, 0))
2017-09-23 20:13:45 +02:00
effect = TRUE;
gBattleScripting.atk49_state++;
break;
2018-09-01 20:00:13 +02:00
case ATK49_CHOICE_MOVE: // update choice band move
2018-07-31 23:09:47 +02:00
if (!(gHitMarker & HITMARKER_OBEYS) || !HOLD_EFFECT_CHOICE(holdEffectAtk)
2017-11-26 18:07:00 +01:00
|| gChosenMove == MOVE_STRUGGLE || (*choicedMoveAtk != 0 && *choicedMoveAtk != 0xFFFF))
2017-09-23 20:13:45 +02:00
goto LOOP;
2018-07-26 20:36:16 +02:00
if ((gBattleMoves[gChosenMove].effect == EFFECT_BATON_PASS
|| gBattleMoves[gChosenMove].effect == EFFECT_HEALING_WISH
|| gBattleMoves[gChosenMove].effect == EFFECT_HIT_ESCAPE)
&& !(gMoveResultFlags & MOVE_RESULT_FAILED))
2017-09-23 20:13:45 +02:00
{
gBattleScripting.atk49_state++;
break;
}
2017-11-26 18:07:00 +01:00
*choicedMoveAtk = gChosenMove;
2017-09-23 20:13:45 +02:00
LOOP:
{
for (i = 0; i < 4; i++)
{
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerAttacker].moves[i] == *choicedMoveAtk)
2017-09-23 20:13:45 +02:00
break;
}
if (i == 4)
*choicedMoveAtk = 0;
gBattleScripting.atk49_state++;
}
break;
2018-09-01 20:00:13 +02:00
case ATK49_CHANGED_ITEMS: // changed held items
2018-02-06 02:46:59 +01:00
for (i = 0; i < gBattlersCount; i++)
2017-09-23 20:13:45 +02:00
{
2017-09-27 23:43:45 +02:00
u16* changedItem = &gBattleStruct->changedItems[i];
2017-09-23 20:13:45 +02:00
if (*changedItem != 0)
{
gBattleMons[i].item = *changedItem;
*changedItem = 0;
}
}
gBattleScripting.atk49_state++;
break;
2018-09-01 20:00:13 +02:00
case ATK49_ITEM_EFFECTS_ALL: // item effects for all battlers
if (ItemBattleEffects(ITEMEFFECT_MOVE_END, 0, FALSE))
2017-09-23 20:13:45 +02:00
effect = TRUE;
else
gBattleScripting.atk49_state++;
break;
2018-09-01 20:00:13 +02:00
case ATK49_KINGSROCK_SHELLBELL: // king's rock and shell bell
if (ItemBattleEffects(ITEMEFFECT_KINGSROCK_SHELLBELL, 0, FALSE))
2017-09-23 20:13:45 +02:00
effect = TRUE;
gBattleScripting.atk49_state++;
break;
2018-09-01 20:00:13 +02:00
case ATK49_ATTACKER_INVISIBLE: // make attacker sprite invisible
2018-02-06 23:09:39 +01:00
if (gStatuses3[gBattlerAttacker] & (STATUS3_SEMI_INVULNERABLE)
2017-09-23 20:13:45 +02:00
&& gHitMarker & HITMARKER_NO_ANIMATIONS)
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2018-02-06 20:48:02 +01:00
BtlController_EmitSpriteInvisibility(0, TRUE);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-23 20:13:45 +02:00
gBattleScripting.atk49_state++;
return;
}
gBattleScripting.atk49_state++;
break;
2018-09-01 20:00:13 +02:00
case ATK49_ATTACKER_VISIBLE: // make attacker sprite visible
2018-01-16 22:12:38 +01:00
if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT
2018-02-06 23:09:39 +01:00
|| !(gStatuses3[gBattlerAttacker] & (STATUS3_SEMI_INVULNERABLE))
|| WasUnableToUseMove(gBattlerAttacker))
2018-02-06 20:48:02 +01:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2018-02-06 20:48:02 +01:00
BtlController_EmitSpriteInvisibility(0, FALSE);
MarkBattlerForControllerExec(gActiveBattler);
2018-02-06 23:09:39 +01:00
gStatuses3[gBattlerAttacker] &= ~(STATUS3_SEMI_INVULNERABLE);
2018-07-16 20:47:30 +02:00
gSpecialStatuses[gBattlerAttacker].restoredBattlerSprite = 1;
2017-09-23 20:13:45 +02:00
gBattleScripting.atk49_state++;
return;
}
gBattleScripting.atk49_state++;
break;
2018-09-01 20:00:13 +02:00
case ATK49_TARGET_VISIBLE: // make target sprite visible
2018-07-16 20:47:30 +02:00
if (!gSpecialStatuses[gBattlerTarget].restoredBattlerSprite && gBattlerTarget < gBattlersCount
2018-02-06 23:09:39 +01:00
&& !(gStatuses3[gBattlerTarget] & STATUS3_SEMI_INVULNERABLE))
2017-09-23 20:13:45 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget;
2018-02-06 20:48:02 +01:00
BtlController_EmitSpriteInvisibility(0, FALSE);
MarkBattlerForControllerExec(gActiveBattler);
2018-02-06 23:09:39 +01:00
gStatuses3[gBattlerTarget] &= ~(STATUS3_SEMI_INVULNERABLE);
2017-09-23 20:13:45 +02:00
gBattleScripting.atk49_state++;
return;
}
gBattleScripting.atk49_state++;
break;
2018-09-01 20:00:13 +02:00
case ATK49_SUBSTITUTE: // update substitute
2018-02-06 02:46:59 +01:00
for (i = 0; i < gBattlersCount; i++)
2017-09-23 20:13:45 +02:00
{
if (gDisableStructs[i].substituteHP == 0)
gBattleMons[i].status2 &= ~(STATUS2_SUBSTITUTE);
}
gBattleScripting.atk49_state++;
break;
2018-09-01 20:00:13 +02:00
case ATK49_UPDATE_LAST_MOVES:
gDisableStructs[gBattlerAttacker].usedMoves |= gBitTable[gCurrMovePos];
2018-06-30 14:12:17 +02:00
if (gHitMarker & HITMARKER_SWAP_ATTACKER_TARGET)
2017-09-23 20:13:45 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
gBattlerAttacker = gBattlerTarget;
gBattlerTarget = gActiveBattler;
2018-06-30 14:12:17 +02:00
gHitMarker &= ~(HITMARKER_SWAP_ATTACKER_TARGET);
2017-09-23 20:13:45 +02:00
}
if (gHitMarker & HITMARKER_ATTACKSTRING_PRINTED)
{
2018-02-06 23:09:39 +01:00
gLastPrintedMoves[gBattlerAttacker] = gChosenMove;
2018-09-22 18:37:03 +02:00
gLastUsedMove = gCurrentMove;
2017-09-23 20:13:45 +02:00
}
2018-02-06 23:09:39 +01:00
if (!(gAbsentBattlerFlags & gBitTable[gBattlerAttacker])
&& !(gBattleStruct->field_91 & gBitTable[gBattlerAttacker])
2018-07-26 20:36:16 +02:00
&& gBattleMoves[originallyUsedMove].effect != EFFECT_BATON_PASS
&& gBattleMoves[originallyUsedMove].effect != EFFECT_HEALING_WISH)
2017-09-23 20:13:45 +02:00
{
if (gHitMarker & HITMARKER_OBEYS)
{
2018-02-06 23:09:39 +01:00
gLastMoves[gBattlerAttacker] = gChosenMove;
gLastResultingMoves[gBattlerAttacker] = gCurrentMove;
2017-09-23 20:13:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gLastMoves[gBattlerAttacker] = 0xFFFF;
gLastResultingMoves[gBattlerAttacker] = 0xFFFF;
2017-09-23 20:13:45 +02:00
}
2018-02-06 23:09:39 +01:00
if (!(gHitMarker & HITMARKER_FAINTED(gBattlerTarget)))
gLastHitBy[gBattlerTarget] = gBattlerAttacker;
2017-09-23 20:13:45 +02:00
2018-01-16 22:12:38 +01:00
if (gHitMarker & HITMARKER_OBEYS && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
2017-09-23 20:13:45 +02:00
{
2017-11-26 18:07:00 +01:00
if (gChosenMove == 0xFFFF)
2017-09-23 20:13:45 +02:00
{
2018-02-06 23:09:39 +01:00
gLastLandedMoves[gBattlerTarget] = gChosenMove;
2017-09-23 20:13:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gLastLandedMoves[gBattlerTarget] = gCurrentMove;
GET_MOVE_TYPE(gCurrentMove, gLastHitByType[gBattlerTarget]);
2017-09-23 20:13:45 +02:00
}
}
else
{
2018-02-06 23:09:39 +01:00
gLastLandedMoves[gBattlerTarget] = 0xFFFF;
2017-09-23 20:13:45 +02:00
}
}
gBattleScripting.atk49_state++;
break;
2018-09-01 20:00:13 +02:00
case ATK49_MIRROR_MOVE: // mirror move
2018-02-06 23:09:39 +01:00
if (!(gAbsentBattlerFlags & gBitTable[gBattlerAttacker]) && !(gBattleStruct->field_91 & gBitTable[gBattlerAttacker])
2017-11-26 14:17:02 +01:00
&& gBattleMoves[originallyUsedMove].flags & FLAG_MIRROR_MOVE_AFFECTED && gHitMarker & HITMARKER_OBEYS
2018-02-06 23:09:39 +01:00
&& gBattlerAttacker != gBattlerTarget && !(gHitMarker & HITMARKER_FAINTED(gBattlerTarget))
2018-01-16 22:12:38 +01:00
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
2017-09-23 20:13:45 +02:00
{
u8 target, attacker;
2018-02-06 23:09:39 +01:00
*(gBattleStruct->mirrorMoves + gBattlerTarget * 2 + 0) = gChosenMove;
*(gBattleStruct->mirrorMoves + 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;
2017-11-26 18:07:00 +01:00
*(attacker * 2 + target * 8 + (u8*)(gBattleStruct->mirrorMoveArrays) + 0) = gChosenMove;
2017-09-23 20:13:45 +02:00
2018-02-06 23:09:39 +01:00
target = gBattlerTarget;
attacker = gBattlerAttacker;
2017-11-26 18:07:00 +01:00
*(attacker * 2 + target * 8 + (u8*)(gBattleStruct->mirrorMoveArrays) + 1) = gChosenMove >> 8;
2017-09-23 20:13:45 +02:00
}
gBattleScripting.atk49_state++;
break;
2018-09-01 20:00:13 +02:00
case ATK49_NEXT_TARGET: // For moves hitting two opposing Pokemon.
if (!(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
&& gBattleTypeFlags & BATTLE_TYPE_DOUBLE
&& !gProtectStructs[gBattlerAttacker].chargingTurn
&& (gBattleMoves[gCurrentMove].target == MOVE_TARGET_BOTH || gBattleMoves[gCurrentMove].target == MOVE_TARGET_FOES_AND_ALLY)
2017-09-23 20:13:45 +02:00
&& !(gHitMarker & HITMARKER_NO_ATTACKSTRING))
{
u8 battlerId;
if (gBattleMoves[gCurrentMove].target == MOVE_TARGET_FOES_AND_ALLY)
2017-09-23 20:13:45 +02:00
{
for (battlerId = gBattlerTarget + 1; battlerId < gBattlersCount; battlerId++)
{
if (battlerId == gBattlerAttacker)
continue;
if (IsBattlerAlive(battlerId))
break;
}
}
else
{
battlerId = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerTarget)));
2017-09-23 20:13:45 +02:00
gHitMarker |= HITMARKER_NO_ATTACKSTRING;
}
if (battlerId < gBattlersCount && gBattleMons[battlerId].hp != 0)
{
gBattlerTarget = battlerId;
2017-09-23 20:13:45 +02:00
gBattleScripting.atk49_state = 0;
MoveValuesCleanUp();
gBattleCommunication[MOVE_EFFECT_BYTE] = gBattleScripting.savedMoveEffect;
2017-09-23 20:13:45 +02:00
BattleScriptPush(gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]);
2018-09-01 20:00:13 +02:00
gBattlescriptCurrInstr = BattleScript_FlushMessageBox;
2017-09-23 20:13:45 +02:00
return;
}
else
{
gHitMarker |= HITMARKER_NO_ATTACKSTRING;
}
}
gBattleScripting.atk49_state++;
break;
2018-09-02 00:07:19 +02:00
case ATK49_CLEAR_BITS: // Clear bits active just while using a move.
2018-07-28 10:41:20 +02:00
gProtectStructs[gBattlerAttacker].usesBouncedMove = 0;
2018-07-28 18:41:57 +02:00
gBattleStruct->ateBoost[gBattlerAttacker] = 0;
2018-08-05 16:43:07 +02:00
gStatuses3[gBattlerAttacker] &= ~(STATUS3_ME_FIRST);
2018-07-28 10:41:20 +02:00
gBattleScripting.atk49_state++;
break;
2018-09-01 20:00:13 +02:00
case ATK49_COUNT:
2017-09-23 20:13:45 +02:00
break;
}
if (arg1 == 1 && effect == FALSE)
2018-09-01 20:00:13 +02:00
gBattleScripting.atk49_state = ATK49_COUNT;
2017-09-23 20:13:45 +02:00
if (arg1 == 2 && arg2 == gBattleScripting.atk49_state)
2018-09-01 20:00:13 +02:00
gBattleScripting.atk49_state = ATK49_COUNT;
2017-09-23 20:13:45 +02:00
2018-09-01 20:00:13 +02:00
} while (gBattleScripting.atk49_state != ATK49_COUNT && effect == FALSE);
2017-09-23 20:13:45 +02:00
2018-09-01 20:00:13 +02:00
if (gBattleScripting.atk49_state == ATK49_COUNT && effect == FALSE)
2017-09-23 20:13:45 +02:00
gBattlescriptCurrInstr += 3;
}
static void atk4A_sethealblock(void)
2017-09-24 00:29:52 +02:00
{
if (gStatuses3[gBattlerTarget] & STATUS3_HEAL_BLOCK)
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
gStatuses3[gBattlerTarget] |= STATUS3_HEAL_BLOCK;
gDisableStructs[gBattlerTarget].healBlockTimer = 5;
gBattlescriptCurrInstr += 5;
}
2017-09-24 00:29:52 +02:00
}
static void atk4B_returnatktoball(void)
2017-09-24 00:29:52 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2018-02-06 02:46:59 +01:00
if (!(gHitMarker & HITMARKER_FAINTED(gActiveBattler)))
2017-09-24 00:29:52 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitReturnMonToBall(0, 0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-24 00:29:52 +02:00
}
gBattlescriptCurrInstr++;
}
static void atk4C_getswitchedmondata(void)
2017-09-24 00:29:52 +02:00
{
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags)
2017-09-24 00:29:52 +02:00
return;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2017-09-24 00:29:52 +02:00
2018-02-06 20:48:02 +01:00
gBattlerPartyIndexes[gActiveBattler] = *(gBattleStruct->monToSwitchIntoId + gActiveBattler);
2017-09-24 00:29:52 +02:00
2018-02-06 20:48:02 +01:00
BtlController_EmitGetMonData(0, REQUEST_ALL_BATTLE, gBitTable[gBattlerPartyIndexes[gActiveBattler]]);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-24 00:29:52 +02:00
gBattlescriptCurrInstr += 2;
}
static void atk4D_switchindataupdate(void)
2017-09-24 00:29:52 +02:00
{
struct BattlePokemon oldData;
s32 i;
u8 *monData;
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags)
2017-09-24 00:29:52 +02:00
return;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-02-06 02:46:59 +01:00
oldData = gBattleMons[gActiveBattler];
monData = (u8*)(&gBattleMons[gActiveBattler]);
2017-09-24 00:29:52 +02:00
for (i = 0; i < sizeof(struct BattlePokemon); i++)
{
2018-02-06 02:46:59 +01:00
monData[i] = gBattleBufferB[gActiveBattler][4 + i];
2017-09-24 00:29:52 +02:00
}
2018-02-06 02:46:59 +01:00
gBattleMons[gActiveBattler].type1 = gBaseStats[gBattleMons[gActiveBattler].species].type1;
gBattleMons[gActiveBattler].type2 = gBaseStats[gBattleMons[gActiveBattler].species].type2;
gBattleMons[gActiveBattler].ability = GetAbilityBySpecies(gBattleMons[gActiveBattler].species, gBattleMons[gActiveBattler].altAbility);
2017-09-24 00:29:52 +02:00
// check knocked off item
2018-02-06 02:46:59 +01:00
i = GetBattlerSide(gActiveBattler);
2018-02-06 20:48:02 +01:00
if (gWishFutureKnock.knockedOffPokes[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)
{
for (i = 0; i < BATTLE_STATS_NO; i++)
2017-09-24 00:29:52 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons[gActiveBattler].statStages[i] = oldData.statStages[i];
2017-09-24 00:29:52 +02:00
}
2018-02-06 02:46:59 +01:00
gBattleMons[gActiveBattler].status2 = oldData.status2;
2017-09-24 00:29:52 +02:00
}
2017-10-02 23:32:39 +02:00
SwitchInClearSetData();
2017-09-24 00:29:52 +02:00
2018-02-06 02:46:59 +01:00
if (gBattleTypeFlags & BATTLE_TYPE_PALACE && gBattleMons[gActiveBattler].maxHP / 2 >= gBattleMons[gActiveBattler].hp
&& gBattleMons[gActiveBattler].hp != 0 && !(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP))
2017-09-24 00:29:52 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleStruct->field_92 |= gBitTable[gActiveBattler];
2017-09-24 00:29:52 +02:00
}
2018-02-06 02:46:59 +01:00
gBattleScripting.battler = gActiveBattler;
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;
}
static void atk4E_switchinanim(void)
2017-09-24 00:29:52 +02:00
{
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags)
2017-09-24 00:29:52 +02:00
return;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2017-09-24 00:29:52 +02:00
2018-02-06 02:46:59 +01:00
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT
2017-09-24 00:29:52 +02:00
&& !(gBattleTypeFlags & (BATTLE_TYPE_LINK
| BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_x2000000
2018-09-20 22:00:00 +02:00
| BATTLE_TYPE_TRAINER_HILL
2017-09-24 00:29:52 +02:00
| BATTLE_TYPE_FRONTIER)))
2018-02-06 02:46:59 +01:00
HandleSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gActiveBattler].species), FLAG_SET_SEEN, gBattleMons[gActiveBattler].personality);
2017-09-24 00:29:52 +02:00
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags &= ~(gBitTable[gActiveBattler]);
2017-09-24 00:29:52 +02:00
2018-02-06 20:48:02 +01:00
BtlController_EmitSwitchInAnim(0, gBattlerPartyIndexes[gActiveBattler], gBattlescriptCurrInstr[2]);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-24 00:29:52 +02:00
gBattlescriptCurrInstr += 3;
if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
sub_81A56B4();
}
static void atk4F_jumpifcantswitch(void)
2017-09-24 00:29:52 +02:00
{
2018-02-28 19:37:48 +01:00
s32 i;
s32 lastMonId;
struct Pokemon *party;
2017-09-24 00:29:52 +02:00
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1] & ~(ATK4F_DONT_CHECK_STATUSES));
2017-09-24 00:29:52 +02:00
if (!(gBattlescriptCurrInstr[1] & ATK4F_DONT_CHECK_STATUSES)
2018-02-06 02:46:59 +01:00
&& ((gBattleMons[gActiveBattler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION))
|| (gStatuses3[gActiveBattler] & STATUS3_ROOTED)))
2017-09-24 00:29:52 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
2017-09-24 00:29:52 +02:00
}
else if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
{
#ifndef NONMATCHING
asm("":::"r5");
#endif // NONMATCHING
2018-02-06 02:46:59 +01:00
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
2017-09-24 00:29:52 +02:00
party = gEnemyParty;
else
party = gPlayerParty;
2018-02-28 19:37:48 +01:00
i = 0;
if (gActiveBattler & 2)
i = 3;
2017-09-24 00:29:52 +02:00
2018-02-28 19:37:48 +01:00
for (lastMonId = i + 3; i < lastMonId; i++)
2017-09-24 00:29:52 +02:00
{
2018-02-28 19:37:48 +01:00
if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE
&& !GetMonData(&party[i], MON_DATA_IS_EGG)
&& GetMonData(&party[i], MON_DATA_HP) != 0
&& gBattlerPartyIndexes[gActiveBattler] != i)
2017-09-24 00:29:52 +02:00
break;
}
2018-02-28 19:37:48 +01:00
if (i == lastMonId)
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
2017-09-24 00:29:52 +02:00
else
gBattlescriptCurrInstr += 6;
}
else if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
{
if (gBattleTypeFlags & BATTLE_TYPE_x800000)
{
2018-02-06 02:46:59 +01:00
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
2017-09-24 00:29:52 +02:00
{
party = gPlayerParty;
2018-02-28 19:37:48 +01:00
i = 0;
2018-07-01 11:15:42 +02:00
if (GetLinkTrainerFlankId(GetBattlerMultiplayerId(gActiveBattler)) == TRUE)
2018-02-28 19:37:48 +01:00
i = 3;
2017-09-24 00:29:52 +02:00
}
else
{
party = gEnemyParty;
2018-02-06 02:46:59 +01:00
if (gActiveBattler == 1)
2018-02-28 19:37:48 +01:00
i = 0;
2017-09-24 00:29:52 +02:00
else
2018-02-28 19:37:48 +01:00
i = 3;
2017-09-24 00:29:52 +02:00
}
}
else
{
2018-02-06 02:46:59 +01:00
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
2017-09-24 00:29:52 +02:00
party = gEnemyParty;
else
party = gPlayerParty;
2018-02-28 19:37:48 +01:00
i = 0;
2018-07-01 11:15:42 +02:00
if (GetLinkTrainerFlankId(GetBattlerMultiplayerId(gActiveBattler)) == TRUE)
2018-02-28 19:37:48 +01:00
i = 3;
2017-09-24 00:29:52 +02:00
}
2018-02-28 19:37:48 +01:00
for (lastMonId = i + 3; i < lastMonId; i++)
2017-09-24 00:29:52 +02:00
{
2018-02-28 19:37:48 +01:00
if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE
&& !GetMonData(&party[i], MON_DATA_IS_EGG)
&& GetMonData(&party[i], MON_DATA_HP) != 0
&& gBattlerPartyIndexes[gActiveBattler] != i)
2017-09-24 00:29:52 +02:00
break;
}
2018-02-28 19:37:48 +01:00
if (i == lastMonId)
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
2017-09-24 00:29:52 +02:00
else
gBattlescriptCurrInstr += 6;
}
2018-02-06 02:46:59 +01:00
else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS && GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
2017-09-24 00:29:52 +02:00
{
party = gEnemyParty;
2018-02-28 19:37:48 +01:00
i = 0;
if (gActiveBattler == B_POSITION_OPPONENT_RIGHT)
i = 3;
2017-09-24 00:29:52 +02:00
2018-02-28 19:37:48 +01:00
for (lastMonId = i + 3; i < lastMonId; i++)
2017-09-24 00:29:52 +02:00
{
2018-02-28 19:37:48 +01:00
if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE
&& !GetMonData(&party[i], MON_DATA_IS_EGG)
&& GetMonData(&party[i], MON_DATA_HP) != 0
&& gBattlerPartyIndexes[gActiveBattler] != i)
2017-09-24 00:29:52 +02:00
break;
}
2018-02-28 19:37:48 +01:00
if (i == lastMonId)
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
2017-09-24 00:29:52 +02:00
else
gBattlescriptCurrInstr += 6;
}
else
{
2018-02-28 19:37:48 +01:00
u8 battlerIn1, battlerIn2;
2018-02-06 02:46:59 +01:00
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
2017-09-24 00:29:52 +02:00
{
2018-02-28 19:37:48 +01:00
battlerIn1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
2017-09-24 00:29:52 +02:00
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
2018-02-28 19:37:48 +01:00
battlerIn2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
2017-09-24 00:29:52 +02:00
else
2018-02-28 19:37:48 +01:00
battlerIn2 = battlerIn1;
2017-09-24 00:29:52 +02:00
party = gEnemyParty;
}
else
{
2018-02-28 19:37:48 +01:00
battlerIn1 = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
2017-09-24 00:29:52 +02:00
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
2018-02-28 19:37:48 +01:00
battlerIn2 = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
2017-09-24 00:29:52 +02:00
else
2018-02-28 19:37:48 +01:00
battlerIn2 = battlerIn1;
2017-09-24 00:29:52 +02:00
party = gPlayerParty;
}
2018-02-28 19:37:48 +01:00
for (i = 0; i < PARTY_SIZE; i++)
2017-09-24 00:29:52 +02:00
{
2018-02-28 19:37:48 +01:00
if (GetMonData(&party[i], MON_DATA_HP) != 0
&& GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE
&& !GetMonData(&party[i], MON_DATA_IS_EGG)
&& i != gBattlerPartyIndexes[battlerIn1] && i != gBattlerPartyIndexes[battlerIn2])
2017-09-24 00:29:52 +02:00
break;
}
2018-02-28 19:37:48 +01:00
if (i == 6)
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
2017-09-24 00:29:52 +02:00
else
gBattlescriptCurrInstr += 6;
}
}
2017-09-28 15:34:21 +02:00
static void sub_804CF10(u8 arg0)
2017-09-24 00:29:52 +02:00
{
2018-02-06 20:48:02 +01:00
*(gBattleStruct->field_58 + gActiveBattler) = gBattlerPartyIndexes[gActiveBattler];
2018-02-06 02:46:59 +01:00
*(gBattleStruct->monToSwitchIntoId + gActiveBattler) = 6;
gBattleStruct->field_93 &= ~(gBitTable[gActiveBattler]);
2017-09-24 00:29:52 +02:00
2018-07-07 19:57:09 +02:00
BtlController_EmitChoosePokemon(0, PARTY_MUST_CHOOSE_MON, arg0, 0, gBattleStruct->field_60[gActiveBattler]);
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec(gActiveBattler);
2017-09-24 00:29:52 +02:00
}
2017-09-25 00:09:13 +02:00
2017-09-28 15:34:21 +02:00
static void atk50_openpartyscreen(void)
2017-09-25 00:09:13 +02:00
{
u32 flags;
u8 hitmarkerFaintBits;
2018-02-08 12:13:29 +01:00
u8 battlerId;
2017-09-25 00:09:13 +02:00
const u8 *jumpPtr;
2018-02-08 12:13:29 +01:00
battlerId = 0;
2017-09-25 00:09:13 +02:00
flags = 0;
2018-03-01 00:59:52 +01:00
jumpPtr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
2017-09-25 00:09:13 +02:00
if (gBattlescriptCurrInstr[1] == 5)
{
if ((gBattleTypeFlags & (BATTLE_TYPE_DOUBLE | BATTLE_TYPE_MULTI)) != BATTLE_TYPE_DOUBLE)
{
2018-02-06 02:46:59 +01:00
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
if (gHitMarker & HITMARKER_FAINTED(gActiveBattler))
2017-09-25 00:09:13 +02:00
{
2018-07-01 11:15:42 +02:00
if (HasNoMonsToSwitch(gActiveBattler, 6, 6))
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags |= gBitTable[gActiveBattler];
gHitMarker &= ~(HITMARKER_FAINTED(gActiveBattler));
2018-02-06 20:48:02 +01:00
BtlController_EmitLinkStandbyMsg(0, 2, 0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
}
2018-02-06 02:46:59 +01:00
else if (!gSpecialStatuses[gActiveBattler].flag40)
2017-09-25 00:09:13 +02:00
{
sub_804CF10(6);
2018-02-06 02:46:59 +01:00
gSpecialStatuses[gActiveBattler].flag40 = 1;
2017-09-25 00:09:13 +02:00
}
}
else
{
2018-02-06 20:48:02 +01:00
BtlController_EmitLinkStandbyMsg(0, 2, 0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
}
}
}
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
u8 flag40_0, flag40_1, flag40_2, flag40_3;
hitmarkerFaintBits = gHitMarker >> 0x1C;
if (gBitTable[0] & hitmarkerFaintBits)
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 0;
2018-07-01 11:15:42 +02:00
if (HasNoMonsToSwitch(0, 6, 6))
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags |= gBitTable[gActiveBattler];
gHitMarker &= ~(HITMARKER_FAINTED(gActiveBattler));
2018-02-06 20:48:02 +01:00
BtlController_EmitCmd42(0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
}
2018-02-06 02:46:59 +01:00
else if (!gSpecialStatuses[gActiveBattler].flag40)
2017-09-25 00:09:13 +02:00
{
2017-11-12 17:06:31 +01:00
sub_804CF10(gBattleStruct->monToSwitchIntoId[2]);
2018-02-06 02:46:59 +01:00
gSpecialStatuses[gActiveBattler].flag40 = 1;
2017-09-25 00:09:13 +02:00
}
else
{
2018-02-06 20:48:02 +01:00
BtlController_EmitLinkStandbyMsg(0, 2, 0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
flags |= 1;
}
}
if (gBitTable[2] & hitmarkerFaintBits && !(gBitTable[0] & hitmarkerFaintBits))
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 2;
2018-07-01 11:15:42 +02:00
if (HasNoMonsToSwitch(2, 6, 6))
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags |= gBitTable[gActiveBattler];
gHitMarker &= ~(HITMARKER_FAINTED(gActiveBattler));
2018-02-06 20:48:02 +01:00
BtlController_EmitCmd42(0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
}
2018-02-06 02:46:59 +01:00
else if (!gSpecialStatuses[gActiveBattler].flag40)
2017-09-25 00:09:13 +02:00
{
2017-11-12 17:06:31 +01:00
sub_804CF10(gBattleStruct->monToSwitchIntoId[0]);
2018-02-06 02:46:59 +01:00
gSpecialStatuses[gActiveBattler].flag40 = 1;
2017-09-25 00:09:13 +02:00
}
else if (!(flags & 1))
{
2018-02-06 20:48:02 +01:00
BtlController_EmitLinkStandbyMsg(0, 2, 0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
}
}
if (gBitTable[1] & hitmarkerFaintBits)
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 1;
2018-07-01 11:15:42 +02:00
if (HasNoMonsToSwitch(1, 6, 6))
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags |= gBitTable[gActiveBattler];
gHitMarker &= ~(HITMARKER_FAINTED(gActiveBattler));
2018-02-06 20:48:02 +01:00
BtlController_EmitCmd42(0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
}
2018-02-06 02:46:59 +01:00
else if (!gSpecialStatuses[gActiveBattler].flag40)
2017-09-25 00:09:13 +02:00
{
2017-11-12 17:06:31 +01:00
sub_804CF10(gBattleStruct->monToSwitchIntoId[3]);
2018-02-06 02:46:59 +01:00
gSpecialStatuses[gActiveBattler].flag40 = 1;
2017-09-25 00:09:13 +02:00
}
else
{
2018-02-06 20:48:02 +01:00
BtlController_EmitLinkStandbyMsg(0, 2, 0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
flags |= 2;
}
}
if (gBitTable[3] & hitmarkerFaintBits && !(gBitTable[1] & hitmarkerFaintBits))
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 3;
2018-07-01 11:15:42 +02:00
if (HasNoMonsToSwitch(3, 6, 6))
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags |= gBitTable[gActiveBattler];
gHitMarker &= ~(HITMARKER_FAINTED(gActiveBattler));
2018-02-06 20:48:02 +01:00
BtlController_EmitCmd42(0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
}
2018-02-06 02:46:59 +01:00
else if (!gSpecialStatuses[gActiveBattler].flag40)
2017-09-25 00:09:13 +02:00
{
2017-11-12 17:06:31 +01:00
sub_804CF10(gBattleStruct->monToSwitchIntoId[1]);
2018-02-06 02:46:59 +01:00
gSpecialStatuses[gActiveBattler].flag40 = 1;
2017-09-25 00:09:13 +02:00
}
else if (!(flags & 2))
{
2018-02-06 20:48:02 +01:00
BtlController_EmitLinkStandbyMsg(0, 2, 0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
}
}
flag40_0 = gSpecialStatuses[0].flag40;
if (!flag40_0)
{
flag40_2 = gSpecialStatuses[2].flag40;
if (!flag40_2 && hitmarkerFaintBits != 0)
{
2018-02-06 02:46:59 +01:00
if (gAbsentBattlerFlags & gBitTable[0])
gActiveBattler = 2;
2017-09-25 00:09:13 +02:00
else
2018-02-06 02:46:59 +01:00
gActiveBattler = 0;
2017-09-25 00:09:13 +02:00
2018-02-06 20:48:02 +01:00
BtlController_EmitLinkStandbyMsg(0, 2, 0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
}
}
flag40_1 = gSpecialStatuses[1].flag40;
if (!flag40_1)
{
flag40_3 = gSpecialStatuses[3].flag40;
if (!flag40_3 && hitmarkerFaintBits != 0)
{
2018-02-06 02:46:59 +01:00
if (gAbsentBattlerFlags & gBitTable[1])
gActiveBattler = 3;
2017-09-25 00:09:13 +02:00
else
2018-02-06 02:46:59 +01:00
gActiveBattler = 1;
2017-09-25 00:09:13 +02:00
2018-02-06 20:48:02 +01:00
BtlController_EmitLinkStandbyMsg(0, 2, 0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
}
}
}
gBattlescriptCurrInstr += 6;
}
else if (gBattlescriptCurrInstr[1] == 6)
{
if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI))
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
hitmarkerFaintBits = gHitMarker >> 0x1C;
if (gBitTable[2] & hitmarkerFaintBits && gBitTable[0] & hitmarkerFaintBits)
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 2;
2018-07-01 11:15:42 +02:00
if (HasNoMonsToSwitch(2, gBattleBufferB[0][1], 6))
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags |= gBitTable[gActiveBattler];
gHitMarker &= ~(HITMARKER_FAINTED(gActiveBattler));
2018-02-06 20:48:02 +01:00
BtlController_EmitCmd42(0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
}
2018-02-06 02:46:59 +01:00
else if (!gSpecialStatuses[gActiveBattler].flag40)
2017-09-25 00:09:13 +02:00
{
2017-11-12 17:06:31 +01:00
sub_804CF10(gBattleStruct->monToSwitchIntoId[0]);
2018-02-06 02:46:59 +01:00
gSpecialStatuses[gActiveBattler].flag40 = 1;
2017-09-25 00:09:13 +02:00
}
}
if (gBitTable[3] & hitmarkerFaintBits && hitmarkerFaintBits & gBitTable[1])
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 3;
2018-07-01 11:15:42 +02:00
if (HasNoMonsToSwitch(3, gBattleBufferB[1][1], 6))
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags |= gBitTable[gActiveBattler];
gHitMarker &= ~(HITMARKER_FAINTED(gActiveBattler));
2018-02-06 20:48:02 +01:00
BtlController_EmitCmd42(0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
}
2018-02-06 02:46:59 +01:00
else if (!gSpecialStatuses[gActiveBattler].flag40)
2017-09-25 00:09:13 +02:00
{
2017-11-12 17:06:31 +01:00
sub_804CF10(gBattleStruct->monToSwitchIntoId[1]);
2018-02-06 02:46:59 +01:00
gSpecialStatuses[gActiveBattler].flag40 = 1;
2017-09-25 00:09:13 +02:00
}
}
gBattlescriptCurrInstr += 6;
}
else
{
gBattlescriptCurrInstr += 6;
}
}
else
{
gBattlescriptCurrInstr += 6;
}
hitmarkerFaintBits = gHitMarker >> 0x1C;
2018-02-08 11:17:41 +01:00
gBattlerFainted = 0;
2017-09-25 00:09:13 +02:00
while (1)
{
2018-02-08 11:17:41 +01:00
if (gBitTable[gBattlerFainted] & hitmarkerFaintBits)
2017-09-25 00:09:13 +02:00
break;
2018-02-08 11:17:41 +01:00
if (gBattlerFainted >= gBattlersCount)
2017-09-25 00:09:13 +02:00
break;
2018-02-08 11:17:41 +01:00
gBattlerFainted++;
2017-09-25 00:09:13 +02:00
}
2018-02-08 11:17:41 +01:00
if (gBattlerFainted == gBattlersCount)
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr = jumpPtr;
}
else
{
if (gBattlescriptCurrInstr[1] & 0x80)
2018-07-07 19:57:09 +02:00
hitmarkerFaintBits = PARTY_CHOOSE_MON; // Used here as the caseId for the EmitChoose function.
2017-09-25 00:09:13 +02:00
else
2018-07-07 19:57:09 +02:00
hitmarkerFaintBits = PARTY_MUST_CHOOSE_MON;
2017-09-25 00:09:13 +02:00
2018-02-08 12:13:29 +01:00
battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1] & ~(0x80));
if (gSpecialStatuses[battlerId].flag40)
2017-09-25 00:09:13 +02:00
{
gBattlescriptCurrInstr += 6;
}
2018-07-01 11:15:42 +02:00
else if (HasNoMonsToSwitch(battlerId, 6, 6))
2017-09-25 00:09:13 +02:00
{
2018-02-08 12:13:29 +01:00
gActiveBattler = battlerId;
2018-02-06 02:46:59 +01:00
gAbsentBattlerFlags |= gBitTable[gActiveBattler];
gHitMarker &= ~(HITMARKER_FAINTED(gActiveBattler));
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr = jumpPtr;
}
else
{
2018-02-08 12:13:29 +01:00
gActiveBattler = battlerId;
2018-02-06 20:48:02 +01:00
*(gBattleStruct->field_58 + gActiveBattler) = gBattlerPartyIndexes[gActiveBattler];
2018-02-06 02:46:59 +01:00
*(gBattleStruct->monToSwitchIntoId + gActiveBattler) = 6;
gBattleStruct->field_93 &= ~(gBitTable[gActiveBattler]);
2017-09-25 00:09:13 +02:00
2018-02-06 20:48:02 +01:00
BtlController_EmitChoosePokemon(0, hitmarkerFaintBits, *(gBattleStruct->monToSwitchIntoId + (gActiveBattler ^ 2)), 0, gBattleStruct->field_60[gActiveBattler]);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr += 6;
2018-02-06 02:46:59 +01:00
if (GetBattlerPosition(gActiveBattler) == 0 && gBattleResults.playerSwitchesCounter < 0xFF)
2017-09-25 00:09:13 +02:00
gBattleResults.playerSwitchesCounter++;
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
{
2018-02-06 02:46:59 +01:00
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
2017-09-25 00:09:13 +02:00
{
2018-02-08 12:13:29 +01:00
if (gActiveBattler != battlerId)
2017-09-25 00:09:13 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitLinkStandbyMsg(0, 2, 0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
}
}
}
else
{
2018-02-08 12:13:29 +01:00
gActiveBattler = GetBattlerAtPosition(GetBattlerPosition(battlerId) ^ BIT_SIDE);
2018-02-06 02:46:59 +01:00
if (gAbsentBattlerFlags & gBitTable[gActiveBattler])
gActiveBattler ^= BIT_FLANK;
2017-09-25 00:09:13 +02:00
2018-02-06 20:48:02 +01:00
BtlController_EmitLinkStandbyMsg(0, 2, 0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
}
}
}
}
static void atk51_switchhandleorder(void)
2017-09-25 00:09:13 +02:00
{
s32 i;
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags)
2017-09-25 00:09:13 +02:00
return;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2017-09-25 00:09:13 +02:00
2017-09-28 15:34:21 +02:00
switch (gBattlescriptCurrInstr[2])
2017-09-25 00:09:13 +02:00
{
case 0:
2018-02-06 02:46:59 +01:00
for (i = 0; i < gBattlersCount; i++)
2017-09-25 00:09:13 +02:00
{
if (gBattleBufferB[i][0] == 0x22)
{
2017-11-12 17:06:31 +01:00
*(gBattleStruct->monToSwitchIntoId + i) = gBattleBufferB[i][1];
2017-09-25 00:09:13 +02:00
if (!(gBattleStruct->field_93 & gBitTable[i]))
{
2018-02-06 20:48:02 +01:00
RecordedBattle_SetBattlerAction(i, gBattleBufferB[i][1]);
2017-09-25 00:09:13 +02:00
gBattleStruct->field_93 |= gBitTable[i];
}
}
}
break;
case 1:
if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI))
2018-02-06 02:46:59 +01:00
sub_803BDA0(gActiveBattler);
2017-09-25 00:09:13 +02:00
break;
case 2:
2018-02-06 02:46:59 +01:00
if (!(gBattleStruct->field_93 & gBitTable[gActiveBattler]))
2017-09-25 00:09:13 +02:00
{
2018-02-06 20:48:02 +01:00
RecordedBattle_SetBattlerAction(gActiveBattler, gBattleBufferB[gActiveBattler][1]);
2018-02-06 02:46:59 +01:00
gBattleStruct->field_93 |= gBitTable[gActiveBattler];
2017-09-25 00:09:13 +02:00
}
// fall through
case 3:
2018-02-06 02:46:59 +01:00
gBattleCommunication[0] = gBattleBufferB[gActiveBattler][1];
*(gBattleStruct->monToSwitchIntoId + gActiveBattler) = gBattleBufferB[gActiveBattler][1];
2017-09-25 00:09:13 +02:00
2017-10-04 19:25:14 +02:00
if (gBattleTypeFlags & BATTLE_TYPE_LINK && gBattleTypeFlags & BATTLE_TYPE_MULTI)
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
*(gActiveBattler * 3 + (u8*)(gBattleStruct->field_60) + 0) &= 0xF;
*(gActiveBattler * 3 + (u8*)(gBattleStruct->field_60) + 0) |= (gBattleBufferB[gActiveBattler][2] & 0xF0);
*(gActiveBattler * 3 + (u8*)(gBattleStruct->field_60) + 1) = gBattleBufferB[gActiveBattler][3];
2017-09-25 00:09:13 +02:00
2018-02-06 02:46:59 +01:00
*((gActiveBattler ^ BIT_FLANK) * 3 + (u8*)(gBattleStruct->field_60) + 0) &= (0xF0);
*((gActiveBattler ^ BIT_FLANK) * 3 + (u8*)(gBattleStruct->field_60) + 0) |= (gBattleBufferB[gActiveBattler][2] & 0xF0) >> 4;
*((gActiveBattler ^ BIT_FLANK) * 3 + (u8*)(gBattleStruct->field_60) + 2) = gBattleBufferB[gActiveBattler][3];
2017-09-25 00:09:13 +02:00
}
else if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
{
2018-02-06 02:46:59 +01:00
sub_80571DC(gActiveBattler, *(gBattleStruct->monToSwitchIntoId + gActiveBattler));
2017-09-25 00:09:13 +02:00
}
else
{
2018-02-06 02:46:59 +01:00
sub_803BDA0(gActiveBattler);
2017-09-25 00:09:13 +02:00
}
2018-02-06 23:09:39 +01:00
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].species)
2018-02-06 02:46:59 +01:00
PREPARE_MON_NICK_BUFFER(gBattleTextBuff2, gActiveBattler, gBattleBufferB[gActiveBattler][1])
2017-09-25 00:09:13 +02:00
break;
}
gBattlescriptCurrInstr += 3;
}
2018-07-24 21:47:00 +02:00
static void SetDmgHazardsBattlescript(u8 battlerId, u8 multistringId)
{
gBattleMons[battlerId].status2 &= ~(STATUS2_DESTINY_BOND);
gHitMarker &= ~(HITMARKER_DESTINYBOND);
gBattleScripting.battler = battlerId;
gBattleCommunication[MULTISTRING_CHOOSER] = multistringId;
BattleScriptPushCursor();
if (gBattlescriptCurrInstr[1] == BS_TARGET)
gBattlescriptCurrInstr = BattleScript_DmgHazardsOnTarget;
else if (gBattlescriptCurrInstr[1] == BS_ATTACKER)
gBattlescriptCurrInstr = BattleScript_DmgHazardsOnAttacker;
else
gBattlescriptCurrInstr = BattleScript_DmgHazardsOnFaintedBattler;
}
static void atk52_switchineffects(void)
2017-09-25 00:09:13 +02:00
{
s32 i;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-02-06 02:46:59 +01:00
sub_803FA70(gActiveBattler);
2017-09-25 00:09:13 +02:00
2018-02-06 02:46:59 +01:00
gHitMarker &= ~(HITMARKER_FAINTED(gActiveBattler));
gSpecialStatuses[gActiveBattler].flag40 = 0;
2017-09-25 00:09:13 +02:00
2018-02-06 02:46:59 +01:00
if (!(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES_DAMAGED)
&& (gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES)
2018-07-24 21:47:00 +02:00
&& IsBattlerGrounded(gActiveBattler))
2017-09-25 00:09:13 +02:00
{
2018-07-24 21:47:00 +02:00
u8 spikesDmg = (5 - gSideTimers[GetBattlerSide(gActiveBattler)].spikesAmount) * 2;
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / (spikesDmg);
2017-09-25 00:09:13 +02:00
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
2018-07-24 21:47:00 +02:00
gSideStatuses[GetBattlerSide(gActiveBattler)] |= SIDE_STATUS_SPIKES_DAMAGED;
SetDmgHazardsBattlescript(gActiveBattler, 0);
}
else if (!(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_STEALTH_ROCK_DAMAGED)
&& (gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_STEALTH_ROCK))
{
gSideStatuses[GetBattlerSide(gActiveBattler)] |= SIDE_STATUS_STEALTH_ROCK_DAMAGED;
gBattleMoveDamage = GetStealthHazardDamage(gBattleMoves[MOVE_STEALTH_ROCK].type, gActiveBattler);
2017-09-25 00:09:13 +02:00
2018-07-24 21:47:00 +02:00
if (gBattleMoveDamage != 0)
SetDmgHazardsBattlescript(gActiveBattler, 1);
}
else if (!(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_TOXIC_SPIKES_DAMAGED)
&& (gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_TOXIC_SPIKES)
&& IsBattlerGrounded(gActiveBattler))
{
gSideStatuses[GetBattlerSide(gActiveBattler)] |= SIDE_STATUS_TOXIC_SPIKES_DAMAGED;
if (IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_POISON)) // Absorb the toxic spikes.
{
gSideStatuses[GetBattlerSide(gActiveBattler)] &= ~(SIDE_STATUS_TOXIC_SPIKES);
gSideTimers[GetBattlerSide(gActiveBattler)].toxicSpikesAmount = 0;
gBattleScripting.battler = gActiveBattler;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_ToxicSpikesAbsorbed;
}
2017-09-25 00:09:13 +02:00
else
2018-07-24 21:47:00 +02:00
{
if (!(gBattleMons[gActiveBattler].status1 & STATUS1_ANY)
&& !IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_STEEL)
&& GetBattlerAbility(gActiveBattler) != ABILITY_IMMUNITY
&& !(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SAFEGUARD))
{
if (gSideTimers[GetBattlerSide(gActiveBattler)].toxicSpikesAmount >= 2)
gBattleMons[gActiveBattler].status1 |= STATUS1_TOXIC_POISON;
else
gBattleMons[gActiveBattler].status1 |= STATUS1_POISON;
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1);
MarkBattlerForControllerExec(gActiveBattler);
gBattleScripting.battler = gActiveBattler;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_ToxicSpikesPoisoned;
}
}
2017-09-25 00:09:13 +02:00
}
2018-07-24 22:09:55 +02:00
else if (!(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_STICKY_WEB_DAMAGED)
&& (gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_STICKY_WEB)
&& IsBattlerGrounded(gActiveBattler))
{
gSideStatuses[GetBattlerSide(gActiveBattler)] |= SIDE_STATUS_STICKY_WEB_DAMAGED;
gBattleScripting.battler = gActiveBattler;
SET_STATCHANGER(STAT_SPEED, 1, TRUE);
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_StickyWebOnSwitchIn;
}
2017-09-25 00:09:13 +02:00
else
{
2018-02-06 02:46:59 +01:00
if (gBattleMons[gActiveBattler].ability == ABILITY_TRUANT && !gDisableStructs[gActiveBattler].truantUnknownBit)
gDisableStructs[gActiveBattler].truantCounter = 1;
2017-09-25 00:09:13 +02:00
2018-02-06 02:46:59 +01:00
gDisableStructs[gActiveBattler].truantUnknownBit = 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)
&& !ItemBattleEffects(ITEMEFFECT_ON_SWITCH_IN, gActiveBattler, FALSE))
2017-09-25 00:09:13 +02:00
{
2018-07-24 21:47:00 +02:00
gSideStatuses[GetBattlerSide(gActiveBattler)] &= ~(SIDE_STATUS_SPIKES_DAMAGED | SIDE_STATUS_TOXIC_SPIKES_DAMAGED | SIDE_STATUS_STEALTH_ROCK_DAMAGED | SIDE_STATUS_STICKY_WEB_DAMAGED);
2017-09-25 00:09:13 +02:00
2018-02-06 02:46:59 +01:00
for (i = 0; i < gBattlersCount; i++)
2017-09-25 00:09:13 +02:00
{
2018-06-28 21:06:32 +02:00
if (gBattlerByTurnOrder[i] == gActiveBattler)
2018-02-06 23:09:39 +01:00
gActionsByTurnOrder[i] = B_ACTION_CANCEL_PARTNER;
2017-09-25 00:09:13 +02:00
}
2018-02-06 02:46:59 +01:00
for (i = 0; i < gBattlersCount; i++)
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
u16* hpOnSwitchout = &gBattleStruct->hpOnSwitchout[GetBattlerSide(i)];
2017-09-25 00:09:13 +02:00
*hpOnSwitchout = gBattleMons[i].hp;
}
2017-09-28 15:34:21 +02:00
if (gBattlescriptCurrInstr[1] == 5)
2017-09-25 00:09:13 +02:00
{
u32 hitmarkerFaintBits = gHitMarker >> 0x1C;
2018-02-08 11:17:41 +01:00
gBattlerFainted++;
2017-09-25 00:09:13 +02:00
while (1)
{
2018-02-08 11:17:41 +01:00
if (hitmarkerFaintBits & gBitTable[gBattlerFainted] && !(gAbsentBattlerFlags & gBitTable[gBattlerFainted]))
2017-09-25 00:09:13 +02:00
break;
2018-02-08 11:17:41 +01:00
if (gBattlerFainted >= gBattlersCount)
2017-09-25 00:09:13 +02:00
break;
2018-02-08 11:17:41 +01:00
gBattlerFainted++;
2017-09-25 00:09:13 +02:00
}
}
gBattlescriptCurrInstr += 2;
}
}
}
static void atk53_trainerslidein(void)
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gActiveBattler = GetBattlerAtPosition(gBattlescriptCurrInstr[1]);
2018-02-06 20:48:02 +01:00
BtlController_EmitTrainerSlide(0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr += 2;
}
static void atk54_playse(void)
2017-09-25 00:09:13 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2018-03-01 00:59:52 +01:00
BtlController_EmitPlaySE(0, T2_READ_16(gBattlescriptCurrInstr + 1));
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr += 3;
}
static void atk55_fanfare(void)
2017-09-25 00:09:13 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2018-03-01 00:59:52 +01:00
BtlController_EmitPlayFanfareOrBGM(0, T2_READ_16(gBattlescriptCurrInstr + 1), FALSE);
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr += 3;
}
static void atk56_playfaintcry(void)
2017-09-25 00:09:13 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-02-06 20:48:02 +01:00
BtlController_EmitFaintingCry(0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr += 2;
}
2017-09-28 15:34:21 +02:00
static void atk57(void)
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gActiveBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
2018-02-06 20:48:02 +01:00
BtlController_EmitCmd55(0, gBattleOutcome);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr += 1;
}
static void atk58_returntoball(void)
2017-09-25 00:09:13 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-02-06 20:48:02 +01:00
BtlController_EmitReturnMonToBall(0, 1);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr += 2;
}
static void atk59_handlelearnnewmove(void)
2017-09-25 00:09:13 +02:00
{
2018-03-01 00:59:52 +01:00
const u8 *jumpPtr1 = T1_READ_PTR(gBattlescriptCurrInstr + 1);
const u8 *jumpPtr2 = T1_READ_PTR(gBattlescriptCurrInstr + 5);
2017-09-25 00:09:13 +02:00
2018-02-07 22:53:40 +01:00
u16 ret = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterMonId], gBattlescriptCurrInstr[9]);
2017-09-25 00:09:13 +02:00
while (ret == 0xFFFE)
2018-02-07 22:53:40 +01:00
ret = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterMonId], 0);
2017-09-25 00:09:13 +02:00
if (ret == 0)
{
gBattlescriptCurrInstr = jumpPtr2;
}
else if (ret == 0xFFFF)
{
gBattlescriptCurrInstr += 10;
}
else
{
2018-02-06 02:46:59 +01:00
gActiveBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
2017-09-25 00:09:13 +02:00
2018-02-07 22:53:40 +01:00
if (gBattlerPartyIndexes[gActiveBattler] == gBattleStruct->expGetterMonId
2018-02-06 02:46:59 +01:00
&& !(gBattleMons[gActiveBattler].status2 & STATUS2_TRANSFORMED))
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
GiveMoveToBattleMon(&gBattleMons[gActiveBattler], ret);
2017-09-25 00:09:13 +02:00
}
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
2018-02-06 02:46:59 +01:00
gActiveBattler = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
2018-02-07 22:53:40 +01:00
if (gBattlerPartyIndexes[gActiveBattler] == gBattleStruct->expGetterMonId
2018-02-06 02:46:59 +01:00
&& !(gBattleMons[gActiveBattler].status2 & STATUS2_TRANSFORMED))
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
GiveMoveToBattleMon(&gBattleMons[gActiveBattler], ret);
2017-09-25 00:09:13 +02:00
}
}
gBattlescriptCurrInstr = jumpPtr1;
}
}
2017-09-28 15:34:21 +02:00
static void atk5A_yesnoboxlearnmove(void)
2017-09-25 00:09:13 +02:00
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 0;
2017-09-25 00:09:13 +02:00
switch (gBattleScripting.learnMoveState)
{
case 0:
HandleBattleWindow(0x18, 8, 0x1D, 0xD, 0);
2018-06-17 16:48:58 +02:00
BattlePutTextOnWindow(gText_BattleYesNoChoice, 0xC);
2017-09-25 00:09:13 +02:00
gBattleScripting.learnMoveState++;
gBattleCommunication[CURSOR_POSITION] = 0;
BattleCreateYesNoCursorAt(0);
2017-09-25 00:09:13 +02:00
break;
case 1:
if (gMain.newKeys & DPAD_UP && gBattleCommunication[CURSOR_POSITION] != 0)
{
PlaySE(SE_SELECT);
BattleDestroyYesNoCursorAt(gBattleCommunication[CURSOR_POSITION]);
2017-09-25 00:09:13 +02:00
gBattleCommunication[CURSOR_POSITION] = 0;
BattleCreateYesNoCursorAt(0);
2017-09-25 00:09:13 +02:00
}
if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[CURSOR_POSITION] == 0)
{
PlaySE(SE_SELECT);
BattleDestroyYesNoCursorAt(gBattleCommunication[CURSOR_POSITION]);
2017-09-25 00:09:13 +02:00
gBattleCommunication[CURSOR_POSITION] = 1;
BattleCreateYesNoCursorAt(1);
2017-09-25 00:09:13 +02:00
}
if (gMain.newKeys & A_BUTTON)
{
PlaySE(SE_SELECT);
if (gBattleCommunication[1] == 0)
{
HandleBattleWindow(0x18, 0x8, 0x1D, 0xD, WINDOW_CLEAR);
2018-07-15 13:23:38 +02:00
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, 0);
2017-09-25 00:09:13 +02:00
gBattleScripting.learnMoveState++;
}
else
{
gBattleScripting.learnMoveState = 5;
}
}
else if (gMain.newKeys & B_BUTTON)
{
PlaySE(SE_SELECT);
gBattleScripting.learnMoveState = 5;
}
break;
case 2:
if (!gPaletteFade.active)
{
FreeAllWindowBuffers();
2018-08-12 21:54:07 +02:00
ShowSelectMovePokemonSummaryScreen(gPlayerParty, gBattleStruct->expGetterMonId, gPlayerPartyCount - 1, ReshowBattleScreenAfterMenu, gMoveToLearn);
2017-09-25 00:09:13 +02:00
gBattleScripting.learnMoveState++;
}
break;
case 3:
if (!gPaletteFade.active && gMain.callback2 == BattleMainCB2)
{
gBattleScripting.learnMoveState++;
}
break;
case 4:
if (!gPaletteFade.active && gMain.callback2 == BattleMainCB2)
{
u8 movePosition = sub_81C1B94();
if (movePosition == 4)
{
gBattleScripting.learnMoveState = 5;
}
else
{
2018-02-07 22:53:40 +01:00
u16 moveId = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_MOVE1 + movePosition);
2017-09-25 00:09:13 +02:00
if (IsHMMove2(moveId))
{
2018-02-06 02:46:59 +01:00
PrepareStringBattle(STRINGID_HMMOVESCANTBEFORGOTTEN, gActiveBattler);
2017-09-25 00:09:13 +02:00
gBattleScripting.learnMoveState = 6;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-25 00:09:13 +02:00
PREPARE_MOVE_BUFFER(gBattleTextBuff2, moveId)
2018-02-07 22:53:40 +01:00
RemoveMonPPBonus(&gPlayerParty[gBattleStruct->expGetterMonId], movePosition);
SetMonMoveSlot(&gPlayerParty[gBattleStruct->expGetterMonId], gMoveToLearn, movePosition);
2017-09-25 00:09:13 +02:00
2018-02-07 22:53:40 +01:00
if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterMonId
2017-09-25 00:09:13 +02:00
&& !(gBattleMons[0].status2 & STATUS2_TRANSFORMED)
&& !(gDisableStructs[0].unk18_b & gBitTable[movePosition]))
{
RemoveBattleMonPPBonus(&gBattleMons[0], movePosition);
SetBattleMonMoveSlot(&gBattleMons[0], gMoveToLearn, movePosition);
}
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
2018-02-07 22:53:40 +01:00
&& gBattlerPartyIndexes[2] == gBattleStruct->expGetterMonId
2017-09-25 00:09:13 +02:00
&& !(gBattleMons[2].status2 & STATUS2_TRANSFORMED)
&& !(gDisableStructs[2].unk18_b & gBitTable[movePosition]))
{
RemoveBattleMonPPBonus(&gBattleMons[2], movePosition);
SetBattleMonMoveSlot(&gBattleMons[2], gMoveToLearn, movePosition);
}
}
}
}
break;
case 5:
HandleBattleWindow(0x18, 8, 0x1D, 0xD, WINDOW_CLEAR);
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr += 5;
break;
case 6:
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags == 0)
2017-09-25 00:09:13 +02:00
{
gBattleScripting.learnMoveState = 2;
}
break;
}
}
2017-09-28 15:34:21 +02:00
static void atk5B_yesnoboxstoplearningmove(void)
2017-09-25 00:09:13 +02:00
{
switch (gBattleScripting.learnMoveState)
{
case 0:
HandleBattleWindow(0x18, 8, 0x1D, 0xD, 0);
2018-06-17 16:48:58 +02:00
BattlePutTextOnWindow(gText_BattleYesNoChoice, 0xC);
2017-09-25 00:09:13 +02:00
gBattleScripting.learnMoveState++;
gBattleCommunication[CURSOR_POSITION] = 0;
BattleCreateYesNoCursorAt(0);
2017-09-25 00:09:13 +02:00
break;
case 1:
if (gMain.newKeys & DPAD_UP && gBattleCommunication[CURSOR_POSITION] != 0)
{
PlaySE(SE_SELECT);
BattleDestroyYesNoCursorAt(gBattleCommunication[CURSOR_POSITION]);
2017-09-25 00:09:13 +02:00
gBattleCommunication[CURSOR_POSITION] = 0;
BattleCreateYesNoCursorAt(0);
2017-09-25 00:09:13 +02:00
}
if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[CURSOR_POSITION] == 0)
{
PlaySE(SE_SELECT);
BattleDestroyYesNoCursorAt(gBattleCommunication[CURSOR_POSITION]);
2017-09-25 00:09:13 +02:00
gBattleCommunication[CURSOR_POSITION] = 1;
BattleCreateYesNoCursorAt(1);
2017-09-25 00:09:13 +02:00
}
if (gMain.newKeys & A_BUTTON)
{
PlaySE(SE_SELECT);
if (gBattleCommunication[1] != 0)
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-25 00:09:13 +02:00
else
gBattlescriptCurrInstr += 5;
HandleBattleWindow(0x18, 0x8, 0x1D, 0xD, WINDOW_CLEAR);
2017-09-25 00:09:13 +02:00
}
else if (gMain.newKeys & B_BUTTON)
{
PlaySE(SE_SELECT);
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
HandleBattleWindow(0x18, 0x8, 0x1D, 0xD, WINDOW_CLEAR);
2017-09-25 00:09:13 +02:00
}
break;
}
}
2017-09-28 15:34:21 +02:00
static void atk5C_hitanimation(void)
2017-09-25 00:09:13 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2017-09-25 00:09:13 +02:00
2018-01-16 22:12:38 +01:00
if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
2017-09-25 00:09:13 +02:00
{
gBattlescriptCurrInstr += 2;
}
2018-08-02 20:24:18 +02:00
else if (!(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE) || !(DoesSubstituteBlockMove(gBattlerAttacker, gActiveBattler, gCurrentMove)) || gDisableStructs[gActiveBattler].substituteHP == 0)
2017-09-25 00:09:13 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitHitAnimation(0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr += 2;
}
else
{
gBattlescriptCurrInstr += 2;
}
}
static u32 GetTrainerMoneyToGive(u16 trainerId)
{
u32 i = 0;
u32 lastMonLevel = 0;
u32 moneyReward = 0;
if (trainerId == TRAINER_SECRET_BASE)
2017-09-25 00:09:13 +02:00
{
2018-02-07 13:49:33 +01:00
moneyReward = 20 * gBattleResources->secretBase->party.levels[0] * gBattleStruct->moneyMultiplier;
2017-09-25 00:09:13 +02:00
}
else
{
switch (gTrainers[trainerId].partyFlags)
{
case 0:
{
const struct TrainerMonNoItemDefaultMoves *party = gTrainers[trainerId].party.NoItemDefaultMoves;
lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl;
}
break;
2017-12-17 21:19:08 +01:00
case F_TRAINER_PARTY_CUSTOM_MOVESET:
2017-09-25 00:09:13 +02:00
{
const struct TrainerMonNoItemCustomMoves *party = gTrainers[trainerId].party.NoItemCustomMoves;
lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl;
}
break;
2017-12-17 21:19:08 +01:00
case F_TRAINER_PARTY_HELD_ITEM:
2017-09-25 00:09:13 +02:00
{
const struct TrainerMonItemDefaultMoves *party = gTrainers[trainerId].party.ItemDefaultMoves;
lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl;
}
break;
2017-12-17 21:19:08 +01:00
case F_TRAINER_PARTY_CUSTOM_MOVESET | F_TRAINER_PARTY_HELD_ITEM:
2017-09-25 00:09:13 +02:00
{
const struct TrainerMonItemCustomMoves *party = gTrainers[trainerId].party.ItemCustomMoves;
lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl;
}
break;
}
for (; gTrainerMoneyTable[i].classId != 0xFF; i++)
{
if (gTrainerMoneyTable[i].classId == gTrainers[trainerId].trainerClass)
break;
}
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * gTrainerMoneyTable[i].value;
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * 2 * gTrainerMoneyTable[i].value;
else
moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * gTrainerMoneyTable[i].value;
}
return moneyReward;
}
2017-09-28 15:34:21 +02:00
static void atk5D_getmoneyreward(void)
2017-09-25 00:09:13 +02:00
{
u32 moneyReward = GetTrainerMoneyToGive(gTrainerBattleOpponent_A);
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
moneyReward += GetTrainerMoneyToGive(gTrainerBattleOpponent_B);
AddMoney(&gSaveBlock1Ptr->money, moneyReward);
PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff1, 5, moneyReward)
gBattlescriptCurrInstr++;
}
static void atk5E(void)
2017-09-25 00:09:13 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2017-09-25 00:09:13 +02:00
switch (gBattleCommunication[0])
{
case 0:
2018-02-06 20:48:02 +01:00
BtlController_EmitGetMonData(0, REQUEST_ALL_BATTLE, 0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
gBattleCommunication[0]++;
break;
case 1:
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags == 0)
2017-09-25 00:09:13 +02:00
{
s32 i;
2018-06-30 14:12:17 +02:00
struct BattlePokemon *bufferPoke = (struct BattlePokemon*) &gBattleBufferB[gActiveBattler][4];
2017-09-25 00:09:13 +02:00
for (i = 0; i < 4; i++)
{
2018-02-06 02:46:59 +01:00
gBattleMons[gActiveBattler].moves[i] = bufferPoke->moves[i];
gBattleMons[gActiveBattler].pp[i] = bufferPoke->pp[i];
2017-09-25 00:09:13 +02:00
}
gBattlescriptCurrInstr += 2;
}
break;
}
}
2018-06-30 14:12:17 +02:00
static void atk5F_swapattackerwithtarget(void)
2017-09-25 00:09:13 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
gBattlerAttacker = gBattlerTarget;
gBattlerTarget = gActiveBattler;
2017-09-25 00:09:13 +02:00
2018-06-30 14:12:17 +02:00
if (gHitMarker & HITMARKER_SWAP_ATTACKER_TARGET)
gHitMarker &= ~(HITMARKER_SWAP_ATTACKER_TARGET);
2017-09-25 00:09:13 +02:00
else
2018-06-30 14:12:17 +02:00
gHitMarker |= HITMARKER_SWAP_ATTACKER_TARGET;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr++;
}
static void atk60_incrementgamestat(void)
2017-09-25 00:09:13 +02:00
{
2018-02-06 23:09:39 +01:00
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
2017-09-28 15:34:21 +02:00
IncrementGameStat(gBattlescriptCurrInstr[1]);
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr += 2;
}
static void atk61_drawpartystatussummary(void)
2017-09-25 00:09:13 +02:00
{
s32 i;
2018-06-30 14:12:17 +02:00
struct Pokemon *party;
struct HpAndStatus hpStatuses[PARTY_SIZE];
2017-09-25 00:09:13 +02:00
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags)
2017-09-25 00:09:13 +02:00
return;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2017-09-25 00:09:13 +02:00
2018-02-06 02:46:59 +01:00
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
2017-09-25 00:09:13 +02:00
party = gPlayerParty;
else
party = gEnemyParty;
2018-06-30 14:12:17 +02:00
for (i = 0; i < PARTY_SIZE; i++)
2017-09-25 00:09:13 +02:00
{
if (GetMonData(&party[i], MON_DATA_SPECIES2) == SPECIES_NONE
|| GetMonData(&party[i], MON_DATA_SPECIES2) == SPECIES_EGG)
{
hpStatuses[i].hp = 0xFFFF;
hpStatuses[i].status = 0;
}
else
{
hpStatuses[i].hp = GetMonData(&party[i], MON_DATA_HP);
hpStatuses[i].status = GetMonData(&party[i], MON_DATA_STATUS);
}
}
2018-02-06 20:48:02 +01:00
BtlController_EmitDrawPartyStatusSummary(0, hpStatuses, 1);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr += 2;
}
2018-06-28 21:06:32 +02:00
static void atk62_hidepartystatussummary(void)
2017-09-25 00:09:13 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-06-28 21:06:32 +02:00
BtlController_EmitHidePartyStatusSummary(0);
2018-02-06 20:48:02 +01:00
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr += 2;
}
2018-09-22 19:08:41 +02:00
static void atk63_jumptocalledmove(void)
2017-09-25 00:09:13 +02:00
{
2017-12-02 00:03:46 +01:00
if (gBattlescriptCurrInstr[1])
2018-09-22 18:41:00 +02:00
gCurrentMove = gCalledMove;
2017-09-25 00:09:13 +02:00
else
2018-09-22 18:41:00 +02:00
gChosenMove = gCurrentMove = gCalledMove;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect];
}
2017-09-28 15:34:21 +02:00
static void atk64_statusanimation(void)
2017-09-25 00:09:13 +02:00
{
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags == 0)
2017-09-25 00:09:13 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-02-06 02:46:59 +01:00
if (!(gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE)
&& gDisableStructs[gActiveBattler].substituteHP == 0
2017-09-25 00:09:13 +02:00
&& !(gHitMarker & HITMARKER_NO_ANIMATIONS))
{
2018-02-06 20:48:02 +01:00
BtlController_EmitStatusAnimation(0, FALSE, gBattleMons[gActiveBattler].status1);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
}
gBattlescriptCurrInstr += 2;
}
}
2017-09-28 15:34:21 +02:00
static void atk65_status2animation(void)
2017-09-25 00:09:13 +02:00
{
u32 wantedToAnimate;
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags == 0)
2017-09-25 00:09:13 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-03-01 00:59:52 +01:00
wantedToAnimate = T1_READ_32(gBattlescriptCurrInstr + 2);
2018-02-06 02:46:59 +01:00
if (!(gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE)
&& gDisableStructs[gActiveBattler].substituteHP == 0
2017-09-25 00:09:13 +02:00
&& !(gHitMarker & HITMARKER_NO_ANIMATIONS))
{
2018-02-06 20:48:02 +01:00
BtlController_EmitStatusAnimation(0, TRUE, gBattleMons[gActiveBattler].status2 & wantedToAnimate);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
}
gBattlescriptCurrInstr += 6;
}
}
2017-09-28 15:34:21 +02:00
static void atk66_chosenstatusanimation(void)
2017-09-25 00:09:13 +02:00
{
u32 wantedStatus;
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags == 0)
2017-09-25 00:09:13 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-03-01 00:59:52 +01:00
wantedStatus = T1_READ_32(gBattlescriptCurrInstr + 3);
2018-02-06 02:46:59 +01:00
if (!(gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE)
&& gDisableStructs[gActiveBattler].substituteHP == 0
2017-09-25 00:09:13 +02:00
&& !(gHitMarker & HITMARKER_NO_ANIMATIONS))
{
2018-02-06 20:48:02 +01:00
BtlController_EmitStatusAnimation(0, gBattlescriptCurrInstr[2], wantedStatus);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-25 00:09:13 +02:00
}
gBattlescriptCurrInstr += 7;
}
}
2017-09-28 15:34:21 +02:00
static void atk67_yesnobox(void)
2017-09-25 00:09:13 +02:00
{
switch (gBattleCommunication[0])
{
case 0:
HandleBattleWindow(0x18, 8, 0x1D, 0xD, 0);
2018-06-17 16:48:58 +02:00
BattlePutTextOnWindow(gText_BattleYesNoChoice, 0xC);
2017-09-25 00:09:13 +02:00
gBattleCommunication[0]++;
gBattleCommunication[CURSOR_POSITION] = 0;
BattleCreateYesNoCursorAt(0);
2017-09-25 00:09:13 +02:00
break;
case 1:
if (gMain.newKeys & DPAD_UP && gBattleCommunication[CURSOR_POSITION] != 0)
{
PlaySE(SE_SELECT);
BattleDestroyYesNoCursorAt(gBattleCommunication[CURSOR_POSITION]);
2017-09-25 00:09:13 +02:00
gBattleCommunication[CURSOR_POSITION] = 0;
BattleCreateYesNoCursorAt(0);
2017-09-25 00:09:13 +02:00
}
if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[CURSOR_POSITION] == 0)
{
PlaySE(SE_SELECT);
BattleDestroyYesNoCursorAt(gBattleCommunication[CURSOR_POSITION]);
2017-09-25 00:09:13 +02:00
gBattleCommunication[CURSOR_POSITION] = 1;
BattleCreateYesNoCursorAt(1);
2017-09-25 00:09:13 +02:00
}
if (gMain.newKeys & B_BUTTON)
{
gBattleCommunication[CURSOR_POSITION] = 1;
PlaySE(SE_SELECT);
HandleBattleWindow(0x18, 8, 0x1D, 0xD, WINDOW_CLEAR);
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr++;
}
else if (gMain.newKeys & A_BUTTON)
{
PlaySE(SE_SELECT);
HandleBattleWindow(0x18, 8, 0x1D, 0xD, WINDOW_CLEAR);
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr++;
}
break;
}
}
static void atk68_cancelallactions(void)
2017-09-25 00:09:13 +02:00
{
s32 i;
2018-02-06 02:46:59 +01:00
for (i = 0; i < gBattlersCount; i++)
2018-02-06 23:09:39 +01:00
gActionsByTurnOrder[i] = B_ACTION_CANCEL_PARTNER;
2017-09-25 00:09:13 +02:00
gBattlescriptCurrInstr++;
}
static void atk69_setgravity(void)
2017-09-25 00:09:13 +02:00
{
if (gFieldStatuses & STATUS_FIELD_GRAVITY)
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
u32 i;
gFieldStatuses |= STATUS_FIELD_GRAVITY;
gFieldTimers.gravityTimer = 5;
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
gStatuses3[i] &= ~(STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS | STATUS3_ON_AIR);
gBattlescriptCurrInstr += 5;
}
2017-09-25 00:09:13 +02:00
}
2017-09-26 22:39:59 +02:00
2017-09-28 15:34:21 +02:00
static void atk6A_removeitem(void)
2017-09-26 22:39:59 +02:00
{
2018-07-14 22:56:03 +02:00
u16 *usedHeldItem;
2017-09-26 22:39:59 +02:00
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2017-09-26 22:39:59 +02:00
2018-02-06 02:46:59 +01:00
usedHeldItem = &gBattleStruct->usedHeldItems[gActiveBattler];
*usedHeldItem = gBattleMons[gActiveBattler].item;
gBattleMons[gActiveBattler].item = 0;
2017-09-26 22:39:59 +02:00
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gActiveBattler].item);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr += 2;
}
2017-09-28 15:34:21 +02:00
static void atk6B_atknameinbuff1(void)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBattlerAttacker, gBattlerPartyIndexes[gBattlerAttacker])
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr++;
}
static void atk6C_drawlvlupbox(void)
2017-09-26 22:39:59 +02:00
{
if (gBattleScripting.atk6C_state == 0)
{
if (IsMonGettingExpSentOut())
gBattleScripting.atk6C_state = 3;
else
gBattleScripting.atk6C_state = 1;
}
switch (gBattleScripting.atk6C_state)
{
case 1:
gBattle_BG2_Y = 0x60;
SetBgAttribute(2, BG_CTRL_ATTR_MOSAIC, 0);
ShowBg(2);
sub_804F17C();
gBattleScripting.atk6C_state = 2;
break;
case 2:
if (!sub_804F1CC())
gBattleScripting.atk6C_state = 3;
break;
case 3:
gBattle_BG1_X = 0;
gBattle_BG1_Y = 0x100;
SetBgAttribute(0, BG_CTRL_ATTR_MOSAIC, 1);
SetBgAttribute(1, BG_CTRL_ATTR_MOSAIC, 0);
ShowBg(0);
ShowBg(1);
HandleBattleWindow(0x12, 7, 0x1D, 0x13, WINDOW_x80);
2017-09-26 22:39:59 +02:00
gBattleScripting.atk6C_state = 4;
break;
case 4:
sub_804F100();
PutWindowTilemap(13);
CopyWindowToVram(13, 3);
gBattleScripting.atk6C_state++;
break;
case 5:
case 7:
if (!IsDma3ManagerBusyWithBgCopy())
{
gBattle_BG1_Y = 0;
gBattleScripting.atk6C_state++;
}
break;
case 6:
if (gMain.newKeys != 0)
{
PlaySE(SE_SELECT);
sub_804F144();
CopyWindowToVram(13, 2);
gBattleScripting.atk6C_state++;
}
break;
case 8:
if (gMain.newKeys != 0)
{
PlaySE(SE_SELECT);
HandleBattleWindow(0x12, 7, 0x1D, 0x13, WINDOW_x80 | WINDOW_CLEAR);
2017-09-26 22:39:59 +02:00
gBattleScripting.atk6C_state++;
}
break;
case 9:
if (!sub_804F344())
{
ClearWindowTilemap(14);
CopyWindowToVram(14, 1);
ClearWindowTilemap(13);
CopyWindowToVram(13, 1);
SetBgAttribute(2, BG_CTRL_ATTR_MOSAIC, 2);
ShowBg(2);
gBattleScripting.atk6C_state = 10;
}
break;
case 10:
if (!IsDma3ManagerBusyWithBgCopy())
{
SetBgAttribute(0, BG_CTRL_ATTR_MOSAIC, 0);
SetBgAttribute(1, BG_CTRL_ATTR_MOSAIC, 1);
ShowBg(0);
ShowBg(1);
gBattlescriptCurrInstr++;
}
break;
}
}
2017-09-28 15:34:21 +02:00
static void sub_804F100(void)
2017-09-26 22:39:59 +02:00
{
struct StatsArray currentStats;
2018-02-07 22:53:40 +01:00
sub_81D388C(&gPlayerParty[gBattleStruct->expGetterMonId], &currentStats);
2017-09-26 22:39:59 +02:00
sub_81D3640(0xD, gBattleResources->statsBeforeLvlUp, &currentStats, 0xE, 0xD, 0xF);
}
2017-09-28 15:34:21 +02:00
static void sub_804F144(void)
2017-09-26 22:39:59 +02:00
{
struct StatsArray currentStats;
2018-02-07 22:53:40 +01:00
sub_81D388C(&gPlayerParty[gBattleStruct->expGetterMonId], &currentStats);
2017-09-26 22:39:59 +02:00
sub_81D3784(0xD, &currentStats, 0xE, 0xD, 0xF);
}
2017-09-28 15:34:21 +02:00
static void sub_804F17C(void)
2017-09-26 22:39:59 +02:00
{
gBattle_BG2_Y = 0;
gBattle_BG2_X = 0x1A0;
2017-09-28 16:51:24 +02:00
LoadPalette(sUnknown_0831C2C8, 0x60, 0x20);
CopyToWindowPixelBuffer(14, sUnknown_0831C2E8, 0, 0);
2017-09-26 22:39:59 +02:00
PutWindowTilemap(14);
CopyWindowToVram(14, 3);
PutMonIconOnLvlUpBox();
}
2017-09-28 15:34:21 +02:00
static bool8 sub_804F1CC(void)
2017-09-26 22:39:59 +02:00
{
if (IsDma3ManagerBusyWithBgCopy())
return TRUE;
if (gBattle_BG2_X == 0x200)
return FALSE;
if (gBattle_BG2_X == 0x1A0)
PutLevelAndGenderOnLvlUpBox();
gBattle_BG2_X += 8;
if (gBattle_BG2_X >= 0x200)
gBattle_BG2_X = 0x200;
return (gBattle_BG2_X != 0x200);
}
2017-09-28 15:34:21 +02:00
static void PutLevelAndGenderOnLvlUpBox(void)
2017-09-26 22:39:59 +02:00
{
u16 monLevel;
u8 monGender;
struct TextSubPrinter subPrinter;
u8 *txtPtr;
u32 var;
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
subPrinter.current_text_offset = gStringVar4;
subPrinter.windowId = 14;
subPrinter.fontId = 0;
subPrinter.x = 32;
subPrinter.y = 0;
subPrinter.currentX = 32;
subPrinter.currentY = 0;
subPrinter.letterSpacing = 0;
subPrinter.lineSpacing = 0;
subPrinter.fontColor_l = TEXT_COLOR_TRANSPARENT;
2018-01-25 22:25:35 +01:00
subPrinter.fgColor = TEXT_COLOR_WHITE;
2017-09-26 22:39:59 +02:00
subPrinter.bgColor = TEXT_COLOR_TRANSPARENT;
subPrinter.shadowColor = TEXT_COLOR_DARK_GREY;
AddTextPrinter(&subPrinter, 0xFF, NULL);
txtPtr = gStringVar4;
gStringVar4[0] = CHAR_SPECIAL_F9;
txtPtr++;
txtPtr[0] = 5;
txtPtr++;
var = (u32)(txtPtr);
txtPtr = ConvertIntToDecimalStringN(txtPtr, monLevel, STR_CONV_MODE_LEFT_ALIGN, 3);
var = (u32)(txtPtr) - var;
txtPtr = StringFill(txtPtr, 0x77, 4 - var);
if (monGender != MON_GENDERLESS)
{
if (monGender == MON_MALE)
{
txtPtr = WriteColorChangeControlCode(txtPtr, 0, 0xC);
txtPtr = WriteColorChangeControlCode(txtPtr, 1, 0xD);
*(txtPtr++) = CHAR_MALE;
}
else
{
txtPtr = WriteColorChangeControlCode(txtPtr, 0, 0xE);
txtPtr = WriteColorChangeControlCode(txtPtr, 1, 0xF);
*(txtPtr++) = CHAR_FEMALE;
}
*(txtPtr++) = EOS;
}
subPrinter.y = 10;
subPrinter.currentY = 10;
AddTextPrinter(&subPrinter, 0xFF, NULL);
CopyWindowToVram(14, 2);
}
2017-09-28 15:34:21 +02:00
static bool8 sub_804F344(void)
2017-09-26 22:39:59 +02:00
{
if (gBattle_BG2_X == 0x1A0)
return FALSE;
if (gBattle_BG2_X - 16 < 0x1A0)
gBattle_BG2_X = 0x1A0;
else
gBattle_BG2_X -= 16;
return (gBattle_BG2_X != 0x1A0);
}
2017-12-02 21:44:50 +01:00
#define sDestroy data[0]
#define sSavedLvlUpBoxXPosition data[1]
2017-09-26 22:39:59 +02:00
2017-09-28 15:34:21 +02:00
static void PutMonIconOnLvlUpBox(void)
2017-09-26 22:39:59 +02:00
{
u8 spriteId;
const u16* iconPal;
struct SpriteSheet iconSheet;
struct SpritePalette iconPalSheet;
2018-02-07 22:53:40 +01:00
u16 species = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPECIES);
u32 personality = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_PERSONALITY);
2017-09-26 22:39:59 +02:00
const u8* iconPtr = GetMonIconPtr(species, personality, 1);
iconSheet.data = iconPtr;
iconSheet.size = 0x200;
iconSheet.tag = MON_ICON_LVLUP_BOX_TAG;
iconPal = GetValidMonIconPalettePtr(species);
iconPalSheet.data = iconPal;
iconPalSheet.tag = MON_ICON_LVLUP_BOX_TAG;
LoadSpriteSheet(&iconSheet);
LoadSpritePalette(&iconPalSheet);
2017-09-28 16:51:24 +02:00
spriteId = CreateSprite(&sSpriteTemplate_MonIconOnLvlUpBox, 256, 10, 0);
2017-09-26 22:39:59 +02:00
gSprites[spriteId].sDestroy = FALSE;
gSprites[spriteId].sSavedLvlUpBoxXPosition = gBattle_BG2_X;
}
2017-09-28 16:32:23 +02:00
static void SpriteCB_MonIconOnLvlUpBox(struct Sprite* sprite)
2017-09-26 22:39:59 +02:00
{
sprite->pos2.x = sprite->sSavedLvlUpBoxXPosition - gBattle_BG2_X;
if (sprite->pos2.x != 0)
{
sprite->sDestroy = TRUE;
}
else if (sprite->sDestroy)
{
DestroySprite(sprite);
FreeSpriteTilesByTag(MON_ICON_LVLUP_BOX_TAG);
FreeSpritePaletteByTag(MON_ICON_LVLUP_BOX_TAG);
}
}
#undef sDestroy
#undef sSavedLvlUpBoxXPosition
2017-09-28 15:34:21 +02:00
static bool32 IsMonGettingExpSentOut(void)
2017-09-26 22:39:59 +02:00
{
2018-02-07 22:53:40 +01:00
if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterMonId)
2017-09-26 22:39:59 +02:00
return TRUE;
2018-02-07 22:53:40 +01:00
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattlerPartyIndexes[2] == gBattleStruct->expGetterMonId)
2017-09-26 22:39:59 +02:00
return TRUE;
return FALSE;
}
static void atk6D_resetsentmonsvalue(void)
2017-09-26 22:39:59 +02:00
{
ResetSentPokesToOpponentValue();
gBattlescriptCurrInstr++;
}
static void atk6E_setatktoplayer0(void)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gBattlerAttacker = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr++;
}
static void atk6F_makevisible(void)
2017-09-26 22:39:59 +02:00
{
2018-07-26 20:36:16 +02:00
if (gBattleControllerExecFlags)
return;
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-02-06 20:48:02 +01:00
BtlController_EmitSpriteInvisibility(0, FALSE);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr += 2;
}
2018-07-22 18:40:18 +02:00
static void atk70_recordability(void)
2017-09-26 22:39:59 +02:00
{
2018-07-22 18:40:18 +02:00
u8 battler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
RecordAbilityBattle(battler, gBattleMons[battler].ability);
gBattlescriptCurrInstr += 2;
2017-09-26 22:39:59 +02:00
}
void BufferMoveToLearnIntoBattleTextBuff2(void)
{
PREPARE_MOVE_BUFFER(gBattleTextBuff2, gMoveToLearn);
}
static void atk71_buffermovetolearn(void)
2017-09-26 22:39:59 +02:00
{
BufferMoveToLearnIntoBattleTextBuff2();
gBattlescriptCurrInstr++;
}
static void atk72_jumpifplayerran(void)
2017-09-26 22:39:59 +02:00
{
2018-02-08 11:17:41 +01:00
if (TryRunFromBattle(gBattlerFainted))
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-26 22:39:59 +02:00
else
gBattlescriptCurrInstr += 5;
}
static void atk73_hpthresholds(void)
2017-09-26 22:39:59 +02:00
{
u8 opposingBank;
s32 result;
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-02-06 02:46:59 +01:00
opposingBank = gActiveBattler ^ BIT_SIDE;
2017-09-26 22:39:59 +02:00
result = gBattleMons[opposingBank].hp * 100 / gBattleMons[opposingBank].maxHP;
if (result == 0)
result = 1;
if (result > 69 || !gBattleMons[opposingBank].hp)
gBattleStruct->hpScale = 0;
else if (result > 39)
gBattleStruct->hpScale = 1;
else if (result > 9)
gBattleStruct->hpScale = 2;
else
gBattleStruct->hpScale = 3;
}
gBattlescriptCurrInstr += 2;
}
static void atk74_hpthresholds2(void)
2017-09-26 22:39:59 +02:00
{
u8 opposingBank;
s32 result;
u8 hpSwitchout;
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-02-06 02:46:59 +01:00
opposingBank = gActiveBattler ^ BIT_SIDE;
hpSwitchout = *(gBattleStruct->hpOnSwitchout + GetBattlerSide(opposingBank));
2017-09-26 22:39:59 +02:00
result = (hpSwitchout - gBattleMons[opposingBank].hp) * 100 / hpSwitchout;
if (gBattleMons[opposingBank].hp >= hpSwitchout)
gBattleStruct->hpScale = 0;
else if (result <= 29)
gBattleStruct->hpScale = 1;
else if (result <= 69)
gBattleStruct->hpScale = 2;
else
gBattleStruct->hpScale = 3;
}
gBattlescriptCurrInstr += 2;
}
static void atk75_useitemonopponent(void)
2017-09-26 22:39:59 +02:00
{
2018-02-07 22:53:40 +01:00
gBattlerInMenuId = gBattlerAttacker;
2018-02-09 18:46:00 +01:00
PokemonUseItemEffects(&gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker]], gLastUsedItem, gBattlerPartyIndexes[gBattlerAttacker], 0, 1);
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr += 1;
}
2018-07-26 23:40:55 +02:00
static bool32 HasAttackerFaintedTarget(void)
{
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& gBattleMoves[gCurrentMove].power != 0
&& (gLastHitBy[gBattlerTarget] == 0xFF || gLastHitBy[gBattlerTarget] == gBattlerAttacker)
&& gBattleStruct->moveTarget[gBattlerAttacker] == gBattlerTarget
&& gBattlerTarget != gBattlerAttacker
&& gCurrentTurnActionNumber == GetBattlerTurnOrderNum(gBattlerAttacker)
&& gChosenMove == gChosenMoveByBattler[gBattlerAttacker])
return TRUE;
else
return FALSE;
}
2018-08-05 12:43:57 +02:00
static void HandleTerrainMove(u32 moveEffect)
{
u32 statusFlag = 0;
u8 *timer = NULL;
switch (moveEffect)
{
case EFFECT_MISTY_TERRAIN:
statusFlag = STATUS_FIELD_MISTY_TERRAIN, timer = &gFieldTimers.mistyTerrainTimer;
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
break;
case EFFECT_GRASSY_TERRAIN:
statusFlag = STATUS_FIELD_GRASSY_TERRAIN, timer = &gFieldTimers.grassyTerrainTimer;
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
break;
case EFFECT_ELECTRIC_TERRAIN:
statusFlag = STATUS_FIELD_ELECTRIC_TERRAIN, timer = &gFieldTimers.electricTerrainTimer;
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
break;
case EFFECT_PSYCHIC_TERRAIN:
statusFlag = STATUS_FIELD_PSYCHIC_TERRAIN, timer = &gFieldTimers.psychicTerrainTimer;
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
break;
}
if (gFieldStatuses & statusFlag || statusFlag == 0)
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
}
else
{
gFieldStatuses &= ~(STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_GRASSY_TERRAIN | EFFECT_ELECTRIC_TERRAIN | EFFECT_PSYCHIC_TERRAIN);
gFieldStatuses |= statusFlag;
*timer = 5;
gBattlescriptCurrInstr += 7;
}
}
bool32 CanUseLastResort(u8 battlerId)
{
u32 i;
u32 knownMovesCount = 0, usedMovesCount = 0;
for (i = 0; i < 4; i++)
{
if (gBattleMons[battlerId].moves[i] != MOVE_NONE)
knownMovesCount++;
if (gDisableStructs[battlerId].usedMoves & gBitTable[i])
usedMovesCount++;
}
if (knownMovesCount >= 2 && usedMovesCount >= knownMovesCount - 1)
return TRUE;
else
return FALSE;
}
2018-09-23 19:03:53 +02:00
#define DEFOG_CLEAR(status, structField, battlescript, move)\
{ \
if (*sideStatuses & status) \
{ \
if (clear) \
{ \
if (move) \
PREPARE_MOVE_BUFFER(gBattleTextBuff1, move);\
*sideStatuses &= ~(status); \
sideTimer->structField = 0; \
BattleScriptPushCursor(); \
gBattlescriptCurrInstr = battlescript; \
} \
return TRUE; \
} \
}
static bool32 ClearDefogHazards(u8 battlerAtk, bool32 clear)
{
s32 i;
for (i = 0; i < 2; i++)
{
struct SideTimer *sideTimer = &gSideTimers[i];
u32 *sideStatuses = &gSideStatuses[i];
gBattlerAttacker = i;
if (GetBattlerSide(battlerAtk) != i)
{
DEFOG_CLEAR(SIDE_STATUS_REFLECT, reflectTimer, BattleScript_SideStatusWoreOffReturn, MOVE_REFLECT);
DEFOG_CLEAR(SIDE_STATUS_LIGHTSCREEN, lightscreenTimer, BattleScript_SideStatusWoreOffReturn, MOVE_LIGHT_SCREEN);
DEFOG_CLEAR(SIDE_STATUS_MIST, mistTimer, BattleScript_SideStatusWoreOffReturn, MOVE_MIST);
DEFOG_CLEAR(SIDE_STATUS_AURORA_VEIL, auroraVeilTimer, BattleScript_SideStatusWoreOffReturn, MOVE_AURORA_VEIL);
DEFOG_CLEAR(SIDE_STATUS_SAFEGUARD, safeguardTimer, BattleScript_SideStatusWoreOffReturn, MOVE_SAFEGUARD);
}
DEFOG_CLEAR(SIDE_STATUS_SPIKES, spikesAmount, BattleScript_SpikesFree, 0);
DEFOG_CLEAR(SIDE_STATUS_STEALTH_ROCK, stealthRockAmount, BattleScript_StealthRockFree, 0);
DEFOG_CLEAR(SIDE_STATUS_TOXIC_SPIKES, toxicSpikesAmount, BattleScript_ToxicSpikesFree, 0);
DEFOG_CLEAR(SIDE_STATUS_STICKY_WEB, stickyWebAmount, BattleScript_StickyWebFree, 0);
}
return FALSE;
}
2017-09-28 15:34:21 +02:00
static void atk76_various(void)
2017-09-26 22:39:59 +02:00
{
2018-09-16 18:55:32 +02:00
struct Pokemon *mon;
2017-09-26 22:39:59 +02:00
u8 side;
s32 i, j;
2018-07-26 20:36:16 +02:00
u8 data[10];
if (gBattleControllerExecFlags)
return;
2017-09-26 22:39:59 +02:00
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2017-09-26 22:39:59 +02:00
switch (gBattlescriptCurrInstr[2])
{
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;
case VARIOUS_IS_RUNNING_IMPOSSIBLE:
2017-09-26 22:39:59 +02:00
gBattleCommunication[0] = IsRunningFromBattleImpossible();
break;
case VARIOUS_GET_MOVE_TARGET:
2018-02-06 23:09:39 +01:00
gBattlerTarget = GetMoveTarget(gCurrentMove, 0);
2017-09-26 22:39:59 +02:00
break;
case 4:
2018-02-06 02:46:59 +01:00
if (gHitMarker & HITMARKER_FAINTED(gActiveBattler))
2017-09-26 22:39:59 +02:00
gBattleCommunication[0] = 1;
else
gBattleCommunication[0] = 0;
break;
case VARIOUS_RESET_INTIMIDATE_TRACE_BITS:
2018-07-16 20:47:30 +02:00
gSpecialStatuses[gActiveBattler].intimidatedMon = 0;
2018-02-06 02:46:59 +01:00
gSpecialStatuses[gActiveBattler].traced = 0;
2018-07-22 22:21:47 +02:00
gSpecialStatuses[gActiveBattler].switchInAbilityDone = 0;
2017-09-26 22:39:59 +02:00
break;
case VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP:
2018-02-07 22:53:40 +01:00
if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterMonId || gBattlerPartyIndexes[2] == gBattleStruct->expGetterMonId)
2017-09-26 22:39:59 +02:00
{
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
for (i = 0; i < 4; i++)
{
2018-02-06 02:46:59 +01:00
if (gBattleMons[gActiveBattler].moves[i] == *choicedMove)
2017-09-26 22:39:59 +02:00
break;
}
if (i == 4)
*choicedMove = 0;
}
break;
case 7:
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_DOUBLE))
&& gBattleTypeFlags & BATTLE_TYPE_TRAINER
&& gBattleMons[0].hp != 0
&& gBattleMons[1].hp != 0)
{
gHitMarker &= ~(HITMARKER_x400000);
}
break;
case 8:
gBattleCommunication[0] = 0;
2018-02-06 02:46:59 +01:00
gBattleScripting.battler = gActiveBattler = gBattleCommunication[1];
if (!(gBattleStruct->field_92 & gBitTable[gActiveBattler])
&& gBattleMons[gActiveBattler].maxHP / 2 >= gBattleMons[gActiveBattler].hp
&& gBattleMons[gActiveBattler].hp != 0
&& !(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP))
2017-09-26 22:39:59 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleStruct->field_92 |= gBitTable[gActiveBattler];
2017-09-26 22:39:59 +02:00
gBattleCommunication[0] = 1;
2018-02-06 02:46:59 +01:00
gBattleCommunication[MULTISTRING_CHOOSER] = sUnknown_0831C4F8[GetNatureFromPersonality(gBattleMons[gActiveBattler].personality)];
2017-09-26 22:39:59 +02:00
}
break;
case 9:
i = sub_81A5258(gBattleCommunication);
if (i == 0)
return;
gBattleCommunication[1] = i;
break;
case 10:
gBattleMons[1].hp = 0;
gHitMarker |= HITMARKER_FAINTED(1);
2018-02-06 20:48:02 +01:00
gBattleStruct->field_2A1 |= gBitTable[gBattlerPartyIndexes[1]];
2017-09-26 22:39:59 +02:00
gDisableStructs[1].truantUnknownBit = 1;
break;
case 11:
gBattleMons[0].hp = 0;
gHitMarker |= HITMARKER_FAINTED(0);
gHitMarker |= HITMARKER_x400000;
2018-02-06 20:48:02 +01:00
gBattleStruct->field_2A0 |= gBitTable[gBattlerPartyIndexes[0]];
2017-09-26 22:39:59 +02:00
gDisableStructs[0].truantUnknownBit = 1;
break;
case 12:
gBattleMons[0].hp = 0;
gBattleMons[1].hp = 0;
gHitMarker |= HITMARKER_FAINTED(0);
gHitMarker |= HITMARKER_FAINTED(1);
gHitMarker |= HITMARKER_x400000;
2018-02-06 20:48:02 +01:00
gBattleStruct->field_2A0 |= gBitTable[gBattlerPartyIndexes[0]];
gBattleStruct->field_2A1 |= gBitTable[gBattlerPartyIndexes[1]];
2017-09-26 22:39:59 +02:00
gDisableStructs[0].truantUnknownBit = 1;
gDisableStructs[1].truantUnknownBit = 1;
break;
case VARIOUS_EMIT_YESNOBOX:
2018-02-06 20:48:02 +01:00
BtlController_EmitUnknownYesNoBox(0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-26 22:39:59 +02:00
break;
case 14:
sub_81A5BF8();
break;
case 15:
sub_81A5D44();
break;
case 16:
BattleStringExpandPlaceholdersToDisplayedString(gRefereeStringsTable[gBattlescriptCurrInstr[1]]);
2018-06-17 16:48:58 +02:00
BattlePutTextOnWindow(gDisplayedStringBattle, 0x16);
2017-09-26 22:39:59 +02:00
break;
case 17:
if (IsTextPrinterActive(0x16))
return;
break;
case VARIOUS_WAIT_CRY:
if (!IsCryFinished())
return;
break;
case VARIOUS_RETURN_OPPONENT_MON1:
2018-02-06 02:46:59 +01:00
gActiveBattler = 1;
if (gBattleMons[gActiveBattler].hp != 0)
2017-09-26 22:39:59 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitReturnMonToBall(0, 0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-26 22:39:59 +02:00
}
break;
case VARIOUS_RETURN_OPPONENT_MON2:
2018-02-06 02:46:59 +01:00
if (gBattlersCount > 3)
2017-09-26 22:39:59 +02:00
{
2018-02-06 02:46:59 +01:00
gActiveBattler = 3;
if (gBattleMons[gActiveBattler].hp != 0)
2017-09-26 22:39:59 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitReturnMonToBall(0, 0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-26 22:39:59 +02:00
}
}
break;
2018-09-01 12:38:38 +02:00
case VARIOUS_VOLUME_DOWN:
m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x55);
2017-09-26 22:39:59 +02:00
break;
2018-09-01 12:38:38 +02:00
case VARIOUS_VOLUME_UP:
m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100);
2017-09-26 22:39:59 +02:00
break;
case 23:
2018-02-06 02:46:59 +01:00
gBattleStruct->field_2A2 |= gBitTable[gActiveBattler];
2017-09-26 22:39:59 +02:00
break;
case 24:
2018-02-06 02:46:59 +01:00
if (sub_805725C(gActiveBattler))
2017-09-26 22:39:59 +02:00
return;
break;
case VARIOUS_SET_TELEPORT_OUTCOME:
2018-02-06 02:46:59 +01:00
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
2018-01-16 22:12:38 +01:00
gBattleOutcome = B_OUTCOME_PLAYER_TELEPORTED;
2017-09-26 22:39:59 +02:00
else
2018-02-08 00:35:13 +01:00
gBattleOutcome = B_OUTCOME_MON_TELEPORTED;
2017-09-26 22:39:59 +02:00
break;
case VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC:
2018-02-06 20:48:02 +01:00
BtlController_EmitPlayFanfareOrBGM(0, MUS_KACHI1, TRUE);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-26 22:39:59 +02:00
break;
2018-07-22 18:40:18 +02:00
case VARIOUS_STAT_TEXT_BUFFER:
PREPARE_STAT_BUFFER(gBattleTextBuff1, gBattleCommunication[0]);
break;
case VARIOUS_SWITCHIN_ABILITIES:
gBattlescriptCurrInstr += 3;
AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, gActiveBattler, 0, 0, 0);
return;
2018-07-24 22:09:55 +02:00
case VARIOUS_SAVE_TARGET:
gBattleStruct->savedBattlerTarget = gBattlerTarget;
break;
case VARIOUS_RESTORE_TARGET:
gBattlerTarget = gBattleStruct->savedBattlerTarget;
break;
2018-07-26 20:36:16 +02:00
case VARIOUS_INSTANT_HP_DROP:
BtlController_EmitHealthBarUpdate(0, INSTANT_HP_BAR_DROP);
MarkBattlerForControllerExec(gActiveBattler);
break;
case VARIOUS_CLEAR_STATUS:
gBattleMons[gActiveBattler].status1 = 0;
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1);
MarkBattlerForControllerExec(gActiveBattler);
break;
case VARIOUS_RESTORE_PP:
for (i = 0; i < 4; i++)
{
gBattleMons[gActiveBattler].pp[i] = CalculatePPWithBonus(gBattleMons[gActiveBattler].moves[i], gBattleMons[gActiveBattler].ppBonuses, i);
data[i] = gBattleMons[gActiveBattler].pp[i];
}
data[i] = gBattleMons[gActiveBattler].ppBonuses;
BtlController_EmitSetMonData(0, REQUEST_PP_DATA_BATTLE, 0, 5, data);
2018-07-27 22:24:07 +02:00
MarkBattlerForControllerExec(gActiveBattler);
2018-07-26 20:36:16 +02:00
break;
2018-07-26 22:52:13 +02:00
case VARIOUS_TRY_ACTIVATE_MOXIE:
if (GetBattlerAbility(gActiveBattler) == ABILITY_MOXIE
2018-07-26 23:40:55 +02:00
&& HasAttackerFaintedTarget()
2018-07-26 22:52:13 +02:00
&& !IsBattleLostForPlayer()
&& !IsBattleWonForPlayer()
&& gBattleMons[gBattlerAttacker].statStages[STAT_ATK] != 12)
2018-07-26 22:52:13 +02:00
{
gBattleMons[gBattlerAttacker].statStages[STAT_ATK]++;
SET_STATCHANGER(STAT_ATK, 1, FALSE);
PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK);
BattleScriptPush(gBattlescriptCurrInstr + 3);
gBattlescriptCurrInstr = BattleScript_AttackerAbilityStatRaise;
return;
}
break;
2018-07-26 23:40:55 +02:00
case VARIOUS_TRY_ACTIVATE_FELL_STINGER:
if (gBattleMoves[gCurrentMove].effect == EFFECT_FELL_STINGER
&& HasAttackerFaintedTarget()
&& !IsBattleLostForPlayer()
&& !IsBattleWonForPlayer()
&& gBattleMons[gBattlerAttacker].statStages[STAT_ATK] != 12)
2018-07-26 23:40:55 +02:00
{
if (gBattleMons[gBattlerAttacker].statStages[STAT_ATK] >= 11)
2018-07-26 23:40:55 +02:00
SET_STATCHANGER(STAT_ATK, 1, FALSE);
else if (gBattleMons[gBattlerAttacker].statStages[STAT_ATK] <= 9 && B_FELL_STINGER_STAT_RAISE == GEN_7)
SET_STATCHANGER(STAT_ATK, 3, FALSE);
2018-07-26 23:40:55 +02:00
else
SET_STATCHANGER(STAT_ATK, 2, FALSE);
PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK);
BattleScriptPush(gBattlescriptCurrInstr + 3);
gBattlescriptCurrInstr = BattleScript_FellStingerRaisesStat;
return;
}
break;
2018-07-29 12:21:28 +02:00
case VARIOUS_PLAY_MOVE_ANIMATION:
BtlController_EmitMoveAnimation(0, T1_READ_16(gBattlescriptCurrInstr + 3), gBattleScripting.animTurn, 0, 0, gBattleMons[gActiveBattler].friendship, &gDisableStructs[gActiveBattler], gMultiHitCounter);
MarkBattlerForControllerExec(gActiveBattler);
gBattlescriptCurrInstr += 5;
return;
case VARIOUS_SET_LUCKY_CHANT:
if (!(gSideStatuses[GET_BATTLER_SIDE(gActiveBattler)] & SIDE_STATUS_LUCKY_CHANT))
{
gSideStatuses[GET_BATTLER_SIDE(gActiveBattler)] |= SIDE_STATUS_LUCKY_CHANT;
gSideTimers[GET_BATTLER_SIDE(gActiveBattler)].luckyChantBattlerId = gActiveBattler;
gSideTimers[GET_BATTLER_SIDE(gActiveBattler)].luckyChantTimer = 5;
gBattlescriptCurrInstr += 7;
}
else
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
}
return;
case VARIOUS_SUCKER_PUNCH_CHECK:
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else if (gBattleMoves[gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]]].power == 0)
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else
gBattlescriptCurrInstr += 7;
return;
case VARIOUS_SET_SIMPLE_BEAM:
switch (gBattleMons[gActiveBattler].ability)
{
case ABILITY_SIMPLE:
case ABILITY_TRUANT:
case ABILITY_STANCE_CHANGE:
case ABILITY_MULTITYPE:
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
break;
default:
gBattleMons[gActiveBattler].ability = ABILITY_SIMPLE;
gBattlescriptCurrInstr += 7;
break;
}
return;
case VARIOUS_TRY_ENTRAINMENT:
switch (gBattleMons[gBattlerTarget].ability)
{
case ABILITY_TRUANT:
case ABILITY_MULTITYPE:
case ABILITY_STANCE_CHANGE:
case ABILITY_SCHOOLING:
case ABILITY_COMATOSE:
case ABILITY_SHIELDS_DOWN:
case ABILITY_DISGUISE:
case ABILITY_RKS_SYSTEM:
case ABILITY_BATTLE_BOND:
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
return;
}
switch (gBattleMons[gBattlerAttacker].ability)
{
case ABILITY_TRACE:
case ABILITY_FORECAST:
case ABILITY_FLOWER_GIFT:
case ABILITY_ZEN_MODE:
case ABILITY_ILLUSION:
case ABILITY_IMPOSTER:
case ABILITY_POWER_OF_ALCHEMY:
case ABILITY_RECEIVER:
case ABILITY_DISGUISE:
case ABILITY_POWER_CONSTRUCT:
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
return;
}
if (gBattleMons[gBattlerTarget].ability == gBattleMons[gBattlerAttacker].ability)
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
}
else
{
gBattleMons[gBattlerTarget].ability = gBattleMons[gBattlerAttacker].ability;
gBattlescriptCurrInstr += 7;
}
return;
case VARIOUS_SET_LAST_USED_ABILITY:
gLastUsedAbility = gBattleMons[gActiveBattler].ability;
break;
case VARIOUS_TRY_HEAL_PULSE:
if (BATTLER_MAX_HP(gActiveBattler))
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
}
else
{
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_MEGA_LAUNCHER && gBattleMoves[gCurrentMove].flags & FLAG_MEGA_LAUNCHER_BOOST)
gBattleMoveDamage = -(gBattleMons[gActiveBattler].maxHP * 75 / 100);
else
gBattleMoveDamage = -(gBattleMons[gActiveBattler].maxHP / 2);
if (gBattleMoveDamage == 0)
gBattleMoveDamage = -1;
gBattlescriptCurrInstr += 7;
}
return;
case VARIOUS_TRY_QUASH:
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
}
else
{
for (i = 0; i < gBattlersCount; i++)
data[i] = gBattlerByTurnOrder[i];
for (i = 0; i < gBattlersCount; i++)
{
if (data[i] == gBattlerTarget)
{
for (j = i + 1; j < gBattlersCount; j++)
data[i++] = data[j];
}
else
{
gBattlerByTurnOrder[i] = data[i];
}
}
gBattlerByTurnOrder[gBattlersCount - 1] = gBattlerTarget;
gBattlescriptCurrInstr += 7;
}
return;
2018-08-04 23:34:29 +02:00
case VARIOUS_INVERT_STAT_STAGES:
for (i = 0; i < BATTLE_STATS_NO; i++)
{
if (gBattleMons[gActiveBattler].statStages[i] < 6) // Negative becomes positive.
gBattleMons[gActiveBattler].statStages[i] = 6 + (6 - gBattleMons[gActiveBattler].statStages[i]);
else if (gBattleMons[gActiveBattler].statStages[i] > 6) // Positive becomes negative.
gBattleMons[gActiveBattler].statStages[i] = 6 - (gBattleMons[gActiveBattler].statStages[i] - 6);
}
break;
2018-08-05 12:43:57 +02:00
case VARIOUS_SET_TERRAIN:
HandleTerrainMove(gBattleMoves[gCurrentMove].effect);
return;
2018-08-05 16:43:07 +02:00
case VARIOUS_TRY_ME_FIRST:
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else if (gBattleMoves[gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]]].power == 0)
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else
{
u16 move = gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]];
switch (move)
{
case MOVE_STRUGGLE:
case MOVE_CHATTER:
case MOVE_FOCUS_PUNCH:
case MOVE_THIEF:
case MOVE_COVET:
case MOVE_COUNTER:
case MOVE_MIRROR_COAT:
case MOVE_METAL_BURST:
case MOVE_ME_FIRST:
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
break;
default:
2018-09-22 19:27:56 +02:00
gCalledMove = move;
2018-08-05 16:43:07 +02:00
gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED);
2018-09-22 19:27:56 +02:00
gBattlerTarget = GetMoveTarget(gCalledMove, 0);
2018-08-05 16:43:07 +02:00
gStatuses3[gBattlerAttacker] |= STATUS3_ME_FIRST;
gBattlescriptCurrInstr += 7;
break;
}
}
return;
2018-08-11 12:16:00 +02:00
case VARIOUS_JUMP_IF_BATTLE_END:
if (IsBattleLostForPlayer() || IsBattleWonForPlayer())
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else
gBattlescriptCurrInstr += 7;
return;
2018-08-11 13:30:34 +02:00
case VARIOUS_TRY_ELECTRIFY:
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
}
else
{
gStatuses3[gBattlerTarget] |= STATUS3_ELECTRIFIED;
gBattlescriptCurrInstr += 7;
}
return;
case VARIOUS_TRY_REFLECT_TYPE:
if (gBattleMons[gBattlerTarget].species == SPECIES_ARCEUS || gBattleMons[gBattlerTarget].species == SPECIES_SILVALLY)
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
}
else if (gBattleMons[gBattlerTarget].type1 == TYPE_MYSTERY && gBattleMons[gBattlerTarget].type2 != TYPE_MYSTERY)
{
gBattleMons[gBattlerAttacker].type1 = gBattleMons[gBattlerTarget].type2;
gBattleMons[gBattlerAttacker].type2 = gBattleMons[gBattlerTarget].type2;
gBattlescriptCurrInstr += 7;
}
else if (gBattleMons[gBattlerTarget].type1 != TYPE_MYSTERY && gBattleMons[gBattlerTarget].type2 == TYPE_MYSTERY)
{
gBattleMons[gBattlerAttacker].type1 = gBattleMons[gBattlerTarget].type1;
gBattleMons[gBattlerAttacker].type2 = gBattleMons[gBattlerTarget].type1;
gBattlescriptCurrInstr += 7;
}
else if (gBattleMons[gBattlerTarget].type1 == TYPE_MYSTERY && gBattleMons[gBattlerTarget].type2 == TYPE_MYSTERY)
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
}
else
{
gBattleMons[gBattlerAttacker].type1 = gBattleMons[gBattlerTarget].type1;
gBattleMons[gBattlerAttacker].type2 = gBattleMons[gBattlerTarget].type2;
gBattlescriptCurrInstr += 7;
}
return;
case VARIOUS_TRY_SOAK:
if (gBattleMons[gBattlerTarget].type1 == TYPE_WATER && gBattleMons[gBattlerTarget].type2 == TYPE_WATER)
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
}
else
{
SET_BATTLER_TYPE(gBattlerTarget, TYPE_WATER);
gBattlescriptCurrInstr += 7;
}
return;
2018-09-16 18:55:32 +02:00
case VARIOUS_HANDLE_MEGA_EVO:
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
mon = &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]];
else
mon = &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]];
gBattleStruct->mega.evolvedSpecies[gActiveBattler] = gBattleMons[gActiveBattler].species;
if (GetBattlerPosition(gActiveBattler) == B_POSITION_PLAYER_LEFT
|| (GetBattlerPosition(gActiveBattler) == B_POSITION_PLAYER_RIGHT && !(gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER))))
{
gBattleStruct->mega.playerEvolvedSpecies = gBattleStruct->mega.evolvedSpecies[gActiveBattler];
}
gBattleMons[gActiveBattler].species = GetMegaEvolutionSpecies(gBattleStruct->mega.evolvedSpecies[gActiveBattler], gBattleMons[gActiveBattler].item);
2018-09-16 18:55:32 +02:00
SetMonData(mon, MON_DATA_SPECIES, &gBattleMons[gActiveBattler].species);
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gActiveBattler].species);
CalculateMonStats(mon);
2018-09-16 21:08:49 +02:00
gBattleMons[gActiveBattler].level = GetMonData(mon, MON_DATA_LEVEL);
2018-09-16 18:55:32 +02:00
gBattleMons[gActiveBattler].hp = GetMonData(mon, MON_DATA_HP);
gBattleMons[gActiveBattler].maxHP = GetMonData(mon, MON_DATA_MAX_HP);
gBattleMons[gActiveBattler].attack = GetMonData(mon, MON_DATA_ATK);
gBattleMons[gActiveBattler].defense = GetMonData(mon, MON_DATA_DEF);
gBattleMons[gActiveBattler].speed = GetMonData(mon, MON_DATA_SPEED);
gBattleMons[gActiveBattler].spAttack = GetMonData(mon, MON_DATA_SPATK);
gBattleMons[gActiveBattler].spDefense = GetMonData(mon, MON_DATA_SPDEF);
2018-09-16 21:08:49 +02:00
gBattleMons[gActiveBattler].ability = GetMonAbility(mon);
gBattleMons[gActiveBattler].type1 = gBaseStats[gBattleMons[gActiveBattler].species].type1;
gBattleMons[gActiveBattler].type2 = gBaseStats[gBattleMons[gActiveBattler].species].type2;
2018-09-16 18:55:32 +02:00
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], mon, HEALTHBOX_ALL);
gBattleStruct->mega.alreadyEvolved[GetBattlerPosition(gActiveBattler)] = TRUE;
gBattleStruct->mega.evolvedPartyIds[GetBattlerSide(gActiveBattler)] |= gBitTable[gBattlerPartyIndexes[gActiveBattler]];
BtlController_EmitSetMonData(0, REQUEST_ALL_BATTLE, gBitTable[gBattlerPartyIndexes[gActiveBattler]], sizeof(struct BattlePokemon), &gBattleMons[gActiveBattler]);
MarkBattlerForControllerExec(gActiveBattler);
2018-09-16 18:55:32 +02:00
break;
case VARIOUS_TRY_LAST_RESORT:
if (CanUseLastResort(gActiveBattler))
gBattlescriptCurrInstr += 7;
else
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
return;
case VARIOUS_ARGUMENT_STATUS_EFFECT:
switch (gBattleMoves[gCurrentMove].argument)
{
case STATUS1_BURN:
gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_BURN;
break;
case STATUS1_FREEZE:
gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_FREEZE;
break;
case STATUS1_PARALYSIS:
gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_PARALYSIS;
break;
case STATUS1_POISON:
gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_POISON;
break;
case STATUS1_TOXIC_POISON:
gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_TOXIC;
break;
default:
gBattleCommunication[MOVE_EFFECT_BYTE] = 0;
break;
}
if (gBattleCommunication[MOVE_EFFECT_BYTE] != 0)
{
BattleScriptPush(gBattlescriptCurrInstr + 3);
gBattlescriptCurrInstr = BattleScript_EffectWithChance;
return;
}
break;
2018-09-22 16:15:00 +02:00
case VARIOUS_TRY_HIT_SWITCH_TARGET:
if (IsBattlerAlive(gBattlerAttacker)
&& IsBattlerAlive(gBattlerTarget)
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& TARGET_TURN_DAMAGED)
{
gBattlescriptCurrInstr = BattleScript_ForceRandomSwitch;
}
else
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
}
return;
2018-09-22 17:27:51 +02:00
case VARIOUS_TRY_AUTONOMIZE:
if (GetBattlerWeight(gActiveBattler) > 1)
{
gDisableStructs[gActiveBattler].autonomizeCount++;
gBattlescriptCurrInstr += 7;
}
else
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
}
return;
2018-09-22 18:37:03 +02:00
case VARIOUS_TRY_COPYCAT:
for (i = 0; sMovesForbiddenToCopy[i] != COPYCAT_FORBIDDEN_END; i++)
{
if (sMovesForbiddenToCopy[i] == gLastUsedMove)
break;
}
if (gLastUsedMove == 0 || gLastUsedMove == 0xFFFF || sMovesForbiddenToCopy[i] != COPYCAT_FORBIDDEN_END)
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
}
else
{
2018-09-22 19:27:56 +02:00
gCalledMove = gLastUsedMove;
2018-09-22 18:37:03 +02:00
gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED);
2018-09-22 19:27:56 +02:00
gBattlerTarget = GetMoveTarget(gCalledMove, 0);
2018-09-22 18:37:03 +02:00
gBattlescriptCurrInstr += 7;
}
return;
case VARIOUS_ABILITY_POPUP:
2018-09-29 12:47:35 +02:00
CreateAbilityPopUp(gActiveBattler, gBattleMons[gActiveBattler].ability, (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) != 0);
break;
2018-09-23 19:03:53 +02:00
case VARIOUS_DEFOG:
if (T1_READ_8(gBattlescriptCurrInstr + 3)) // Clear
{
if (ClearDefogHazards(gEffectBattler, TRUE))
return;
else
gBattlescriptCurrInstr += 8;
}
else
{
if (ClearDefogHazards(gActiveBattler, FALSE))
gBattlescriptCurrInstr += 8;
else
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 4);
}
return;
2018-09-29 14:10:53 +02:00
case VARIOUS_JUMP_IF_TARGET_ALLY:
if (GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget))
gBattlescriptCurrInstr += 7;
else
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
return;
2018-09-29 15:43:56 +02:00
case VARIOUS_TRY_SYNCHRONOISE:
if (!DoBattlersShareType(gBattlerAttacker, gBattlerTarget))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else
gBattlescriptCurrInstr += 7;
return;
2018-09-29 18:40:14 +02:00
case VARIOUS_PSYCHO_SHIFT:
i = TRUE;
if (gBattleMons[gBattlerAttacker].status1 & STATUS1_PARALYSIS)
{
if (GetBattlerAbility(gBattlerTarget) == ABILITY_LIMBER)
{
gBattlerAbility = gBattlerTarget;
BattleScriptPush(T1_READ_PTR(gBattlescriptCurrInstr + 3));
gBattlescriptCurrInstr = BattleScript_PRLZPrevention;
i = FALSE;
}
else if (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_ELECTRIC))
{
BattleScriptPush(T1_READ_PTR(gBattlescriptCurrInstr + 3));
gBattlescriptCurrInstr = BattleScript_PRLZPrevention;
i = FALSE;
}
else
{
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
}
}
else if (gBattleMons[gBattlerAttacker].status1 & STATUS1_PSN_ANY)
{
if (GetBattlerAbility(gBattlerTarget) == ABILITY_IMMUNITY)
{
gBattlerAbility = gBattlerTarget;
BattleScriptPush(T1_READ_PTR(gBattlescriptCurrInstr + 3));
gBattlescriptCurrInstr = BattleScript_PSNPrevention;
i = FALSE;
}
else if (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_POISON) || IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_STEEL))
{
BattleScriptPush(T1_READ_PTR(gBattlescriptCurrInstr + 3));
gBattlescriptCurrInstr = BattleScript_PSNPrevention;
i = FALSE;
}
else
{
if (gBattleMons[gBattlerAttacker].status1 & STATUS1_POISON)
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
else
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
}
}
else if (gBattleMons[gBattlerAttacker].status1 & STATUS1_BURN)
{
if (GetBattlerAbility(gBattlerTarget) == ABILITY_WATER_VEIL)
{
gBattlerAbility = gBattlerTarget;
BattleScriptPush(T1_READ_PTR(gBattlescriptCurrInstr + 3));
gBattlescriptCurrInstr = BattleScript_BRNPrevention;
i = FALSE;
}
else if (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_FIRE))
{
BattleScriptPush(T1_READ_PTR(gBattlescriptCurrInstr + 3));
gBattlescriptCurrInstr = BattleScript_BRNPrevention;
i = FALSE;
}
else
{
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
}
}
else if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP)
{
if (GetBattlerAbility(gBattlerTarget) == ABILITY_INSOMNIA || GetBattlerAbility(gBattlerTarget) == ABILITY_VITAL_SPIRIT)
{
gBattlerAbility = gBattlerTarget;
// BattleScriptPush(T1_READ_PTR(gBattlescriptCurrInstr + 3));
// gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
i = FALSE;
}
else
{
gBattleCommunication[MULTISTRING_CHOOSER] = 4;
}
}
if (i == TRUE)
{
gBattleMons[gBattlerTarget].status1 = gBattleMons[gBattlerAttacker].status1;
gActiveBattler = gBattlerTarget;
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1);
MarkBattlerForControllerExec(gActiveBattler);
gBattlescriptCurrInstr += 7;
}
return;
case VARIOUS_CURE_STATUS:
gBattleMons[gActiveBattler].status1 = 0;
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1);
MarkBattlerForControllerExec(gActiveBattler);
break;
case VARIOUS_POWER_TRICK:
gStatuses3[gActiveBattler] ^= STATUS3_POWER_TRICK;
SWAP(gBattleMons[gActiveBattler].attack, gBattleMons[gActiveBattler].defense, i);
break;
2018-09-29 19:37:39 +02:00
case VARIOUS_AFTER_YOU:
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)
|| GetBattlerTurnOrderNum(gBattlerAttacker) == GetBattlerTurnOrderNum(gBattlerTarget) + 1)
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
}
else
{
for (i = 0; i < gBattlersCount; i++)
data[i] = gBattlerByTurnOrder[i];
if (GetBattlerTurnOrderNum(gBattlerAttacker) == 0 && GetBattlerTurnOrderNum(gBattlerTarget) == 2)
{
gBattlerByTurnOrder[1] = gBattlerTarget;
gBattlerByTurnOrder[2] = data[1];
gBattlerByTurnOrder[3] = data[3];
}
else if (GetBattlerTurnOrderNum(gBattlerAttacker) == 0 && GetBattlerTurnOrderNum(gBattlerTarget) == 3)
{
gBattlerByTurnOrder[1] = gBattlerTarget;
gBattlerByTurnOrder[2] = data[1];
gBattlerByTurnOrder[3] = data[2];
}
else
{
gBattlerByTurnOrder[2] = gBattlerTarget;
gBattlerByTurnOrder[3] = data[2];
}
gBattlescriptCurrInstr += 7;
}
return;
2018-09-30 12:27:51 +02:00
case VARIOUS_BESTOW:
if (gBattleMons[gBattlerAttacker].item == ITEM_NONE
|| gBattleMons[gBattlerTarget].item != ITEM_NONE
|| !CanBattlerGetOrLoseItem(gBattlerAttacker, gBattleMons[gBattlerAttacker].item)
|| !CanBattlerGetOrLoseItem(gBattlerTarget, gBattleMons[gBattlerAttacker].item))
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
}
else
{
gLastUsedItem = gBattleMons[gBattlerAttacker].item;
gActiveBattler = gBattlerAttacker;
gBattleMons[gActiveBattler].item = ITEM_NONE;
BtlController_EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gActiveBattler].item);
MarkBattlerForControllerExec(gActiveBattler);
gActiveBattler = gBattlerTarget;
gBattleMons[gActiveBattler].item = gLastUsedItem;
BtlController_EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gActiveBattler].item);
MarkBattlerForControllerExec(gActiveBattler);
gBattlescriptCurrInstr += 7;
}
return;
2018-09-30 14:04:46 +02:00
case VARIOUS_ARGUMENT_TO_MOVE_EFFECT:
gBattleCommunication[MOVE_EFFECT_BYTE] = gBattleMoves[gCurrentMove].argument;
break;
case VARIOUS_JUMP_IF_NOT_GROUNDED:
if (!IsBattlerGrounded(gActiveBattler))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else
gBattlescriptCurrInstr += 7;
return;
2017-09-26 22:39:59 +02:00
}
gBattlescriptCurrInstr += 3;
}
static void atk77_setprotectlike(void) // protect and endure
2017-09-26 22:39:59 +02:00
{
bool8 notLastTurn = TRUE;
2018-02-06 23:09:39 +01:00
u16 lastMove = gLastResultingMoves[gBattlerAttacker];
2017-09-26 22:39:59 +02:00
if (lastMove != MOVE_PROTECT && lastMove != MOVE_DETECT && lastMove != MOVE_ENDURE)
2018-02-06 23:09:39 +01:00
gDisableStructs[gBattlerAttacker].protectUses = 0;
2017-09-26 22:39:59 +02:00
2018-02-06 02:46:59 +01:00
if (gCurrentTurnActionNumber == (gBattlersCount - 1))
2017-09-26 22:39:59 +02:00
notLastTurn = FALSE;
2018-02-06 23:09:39 +01:00
if (sProtectSuccessRates[gDisableStructs[gBattlerAttacker].protectUses] >= Random() && notLastTurn)
2017-09-26 22:39:59 +02:00
{
if (gBattleMoves[gCurrentMove].effect == EFFECT_PROTECT)
{
2018-02-06 23:09:39 +01:00
gProtectStructs[gBattlerAttacker].protected = 1;
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
}
if (gBattleMoves[gCurrentMove].effect == EFFECT_ENDURE)
{
2018-02-06 23:09:39 +01:00
gProtectStructs[gBattlerAttacker].endured = 1;
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
}
2018-02-06 23:09:39 +01:00
gDisableStructs[gBattlerAttacker].protectUses++;
2017-09-26 22:39:59 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gDisableStructs[gBattlerAttacker].protectUses = 0;
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
2017-09-26 22:39:59 +02:00
}
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atk78_faintifabilitynotdamp(void)
2017-09-26 22:39:59 +02:00
{
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags)
2017-09-26 22:39:59 +02:00
return;
2018-02-06 23:09:39 +01:00
for (gBattlerTarget = 0; gBattlerTarget < gBattlersCount; gBattlerTarget++)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].ability == ABILITY_DAMP)
2017-09-26 22:39:59 +02:00
break;
}
2018-02-06 23:09:39 +01:00
if (gBattlerTarget == gBattlersCount)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gBattleMons[gActiveBattler].hp;
2018-02-06 20:48:02 +01:00
BtlController_EmitHealthBarUpdate(0, INSTANT_HP_BAR_DROP);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr++;
2018-02-06 23:09:39 +01:00
for (gBattlerTarget = 0; gBattlerTarget < gBattlersCount; gBattlerTarget++)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if (gBattlerTarget == gBattlerAttacker)
2017-09-26 22:39:59 +02:00
continue;
2018-02-06 23:09:39 +01:00
if (!(gAbsentBattlerFlags & gBitTable[gBattlerTarget]))
2017-09-26 22:39:59 +02:00
break;
}
}
else
{
gLastUsedAbility = ABILITY_DAMP;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability);
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = BattleScript_DampStopsExplosion;
}
}
2017-09-28 15:34:21 +02:00
static void atk79_setatkhptozero(void)
2017-09-26 22:39:59 +02:00
{
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags)
2017-09-26 22:39:59 +02:00
return;
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2018-02-06 02:46:59 +01:00
gBattleMons[gActiveBattler].hp = 0;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData(0, REQUEST_HP_BATTLE, 0, 2, &gBattleMons[gActiveBattler].hp);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr++;
}
static void atk7A_jumpifnexttargetvalid(void)
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
const u8 *jumpPtr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-26 22:39:59 +02:00
2018-09-30 14:04:46 +02:00
for (gBattlerTarget++; gBattlerTarget < gBattlersCount; gBattlerTarget++)
2017-09-26 22:39:59 +02:00
{
2018-09-30 14:04:46 +02:00
if (gBattlerTarget == gBattlerAttacker && !(gBattleMoves[gCurrentMove].target & MOVE_TARGET_USER))
continue;
if (!(gAbsentBattlerFlags & gBitTable[gBattlerTarget]))
break;
2017-09-26 22:39:59 +02:00
}
2018-09-30 14:04:46 +02:00
if (gBattlerTarget >= gBattlersCount)
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr += 5;
2018-09-30 14:04:46 +02:00
else
gBattlescriptCurrInstr = jumpPtr;
2017-09-26 22:39:59 +02:00
}
static void atk7B_tryhealhalfhealth(void)
2017-09-26 22:39:59 +02:00
{
2018-09-30 14:04:46 +02:00
const u8 *failPtr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-26 22:39:59 +02:00
2018-02-08 11:17:41 +01:00
if (gBattlescriptCurrInstr[5] == BS_ATTACKER)
2018-02-06 23:09:39 +01:00
gBattlerTarget = gBattlerAttacker;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP / 2;
2017-09-26 22:39:59 +02:00
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
gBattleMoveDamage *= -1;
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].hp == gBattleMons[gBattlerTarget].maxHP)
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = failPtr;
else
gBattlescriptCurrInstr += 6;
}
2017-09-28 15:34:21 +02:00
static void atk7C_trymirrormove(void)
2017-09-26 22:39:59 +02:00
{
s32 validMovesCount;
s32 i;
u16 move;
u16 movesArray[4];
for (i = 0; i < 3; i++)
movesArray[i] = 0;
2018-02-06 02:46:59 +01:00
for (validMovesCount = 0, i = 0; i < gBattlersCount; i++)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if (i != gBattlerAttacker)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
move = *(i * 2 + gBattlerAttacker * 8 + (u8*)(gBattleStruct->mirrorMoveArrays) + 0)
| (*(i * 2 + gBattlerAttacker * 8 + (u8*)(gBattleStruct->mirrorMoveArrays) + 1) << 8);
2017-09-26 22:39:59 +02:00
if (move != 0 && move != 0xFFFF)
{
movesArray[validMovesCount] = move;
validMovesCount++;
}
}
}
2018-02-06 23:09:39 +01:00
move = *(gBattleStruct->mirrorMoves + gBattlerAttacker * 2 + 0)
| (*(gBattleStruct->mirrorMoves + gBattlerAttacker * 2 + 1) << 8);
2017-09-26 22:39:59 +02:00
if (move != 0 && move != 0xFFFF)
{
gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED);
gCurrentMove = move;
2018-02-06 23:09:39 +01:00
gBattlerTarget = GetMoveTarget(gCurrentMove, 0);
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect];
}
else if (validMovesCount)
{
gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED);
i = Random() % validMovesCount;
gCurrentMove = movesArray[i];
2018-02-06 23:09:39 +01:00
gBattlerTarget = GetMoveTarget(gCurrentMove, 0);
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect];
}
else
{
2018-02-06 23:09:39 +01:00
gSpecialStatuses[gBattlerAttacker].flag20 = 1;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr++;
}
}
static void atk7D_setrain(void)
2017-09-26 22:39:59 +02:00
{
if (!TryChangeBattleWeather(gBattlerAttacker, ENUM_WEATHER_RAIN, FALSE))
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
}
else
{
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
}
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atk7E_setreflect(void)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if (gSideStatuses[GET_BATTLER_SIDE(gBattlerAttacker)] & SIDE_STATUS_REFLECT)
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
}
else
{
2018-02-06 23:09:39 +01:00
gSideStatuses[GET_BATTLER_SIDE(gBattlerAttacker)] |= SIDE_STATUS_REFLECT;
gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].reflectTimer = 5;
2018-02-07 22:53:40 +01:00
gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].reflectBattlerId = gBattlerAttacker;
2017-09-26 22:39:59 +02:00
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && CountAliveMonsInBattle(BATTLE_ALIVE_ATK_SIDE) == 2)
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
else
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
}
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atk7F_setseeded(void)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT || gStatuses3[gBattlerTarget] & STATUS3_LEECHSEED)
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
}
2018-03-01 00:59:52 +01:00
else if (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_GRASS))
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
}
else
{
2018-02-06 23:09:39 +01:00
gStatuses3[gBattlerTarget] |= gBattlerAttacker;
gStatuses3[gBattlerTarget] |= STATUS3_LEECHSEED;
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
}
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atk80_manipulatedamage(void)
2017-09-26 22:39:59 +02:00
{
2017-09-28 15:34:21 +02:00
switch (gBattlescriptCurrInstr[1])
2017-09-26 22:39:59 +02:00
{
case ATK80_DMG_CHANGE_SIGN:
gBattleMoveDamage *= -1;
break;
case ATK80_DMG_HALF_BY_TWO_NOT_MORE_THAN_HALF_MAX_HP:
gBattleMoveDamage /= 2;
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
2018-02-06 23:09:39 +01:00
if ((gBattleMons[gBattlerTarget].maxHP / 2) < gBattleMoveDamage)
gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP / 2;
2017-09-26 22:39:59 +02:00
break;
case ATK80_DMG_DOUBLED:
gBattleMoveDamage *= 2;
break;
2018-07-22 21:05:12 +02:00
case ATK80_1_8_TARGET_HP:
gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP / 8;
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
break;
2018-07-26 20:36:16 +02:00
case ATK80_FULL_ATTACKER_HP:
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP;
break;
2018-09-22 16:15:00 +02:00
case ATK80_CURR_ATTACKER_HP:
gBattleMoveDamage = gBattleMons[gBattlerAttacker].hp;
break;
2017-09-26 22:39:59 +02:00
}
gBattlescriptCurrInstr += 2;
}
static void atk81_trysetrest(void)
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
const u8 *failJump = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget = gBattlerAttacker;
gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP * (-1);
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].hp == gBattleMons[gBattlerTarget].maxHP)
2017-09-26 22:39:59 +02:00
{
gBattlescriptCurrInstr = failJump;
}
else
{
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].status1 & ((u8)(~STATUS1_SLEEP)))
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
else
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerTarget].status1 = 3;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr += 5;
}
}
2017-09-28 15:34:21 +02:00
static void atk82_jumpifnotfirstturn(void)
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
const u8* failJump = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if (gDisableStructs[gBattlerAttacker].isFirstTurn)
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr += 5;
else
gBattlescriptCurrInstr = failJump;
}
static void atk83_setmiracleeye(void)
2017-09-26 22:39:59 +02:00
{
if (!(gStatuses3[gBattlerTarget] & STATUS3_MIRACLE_EYED))
{
gStatuses3[gBattlerTarget] |= STATUS3_MIRACLE_EYED;
gBattlescriptCurrInstr += 5;
}
else
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
2017-09-26 22:39:59 +02:00
}
2018-02-08 12:13:29 +01:00
bool8 UproarWakeUpCheck(u8 battlerId)
2017-09-26 22:39:59 +02:00
{
s32 i;
2018-02-06 02:46:59 +01:00
for (i = 0; i < gBattlersCount; i++)
2017-09-26 22:39:59 +02:00
{
2018-02-08 12:13:29 +01:00
if (!(gBattleMons[i].status2 & STATUS2_UPROAR) || gBattleMons[battlerId].ability == ABILITY_SOUNDPROOF)
2017-09-26 22:39:59 +02:00
continue;
2018-02-06 02:46:59 +01:00
gBattleScripting.battler = i;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if (gBattlerTarget == 0xFF)
gBattlerTarget = i;
else if (gBattlerTarget == i)
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
else
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
break;
}
2018-02-06 02:46:59 +01:00
if (i == gBattlersCount)
2017-09-26 22:39:59 +02:00
return FALSE;
else
return TRUE;
}
static void atk84_jumpifcantmakeasleep(void)
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
const u8 *jumpPtr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if (UproarWakeUpCheck(gBattlerTarget))
2017-09-26 22:39:59 +02:00
{
gBattlescriptCurrInstr = jumpPtr;
}
2018-02-06 23:09:39 +01:00
else if (gBattleMons[gBattlerTarget].ability == ABILITY_INSOMNIA
|| gBattleMons[gBattlerTarget].ability == ABILITY_VITAL_SPIRIT)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gLastUsedAbility = gBattleMons[gBattlerTarget].ability;
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
gBattlescriptCurrInstr = jumpPtr;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle(gBattlerTarget, gLastUsedAbility);
2017-09-26 22:39:59 +02:00
}
else
{
gBattlescriptCurrInstr += 5;
}
}
2017-09-28 15:34:21 +02:00
static void atk85_stockpile(void)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if (gDisableStructs[gBattlerAttacker].stockpileCounter == 3)
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
}
else
{
2018-02-06 23:09:39 +01:00
gDisableStructs[gBattlerAttacker].stockpileCounter++;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff1, 1, gDisableStructs[gBattlerAttacker].stockpileCounter)
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
}
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atk86_stockpiletobasedamage(void)
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
const u8* jumpPtr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2018-02-06 23:09:39 +01:00
if (gDisableStructs[gBattlerAttacker].stockpileCounter == 0)
2017-09-26 22:39:59 +02:00
{
gBattlescriptCurrInstr = jumpPtr;
}
else
{
if (gBattleCommunication[6] != 1)
{
2018-02-06 23:09:39 +01:00
gBattleScripting.animTurn = gDisableStructs[gBattlerAttacker].stockpileCounter;
2017-09-26 22:39:59 +02:00
}
2018-02-06 23:09:39 +01:00
gDisableStructs[gBattlerAttacker].stockpileCounter = 0;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr += 5;
}
}
2017-09-28 15:34:21 +02:00
static void atk87_stockpiletohpheal(void)
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
const u8* jumpPtr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if (gDisableStructs[gBattlerAttacker].stockpileCounter == 0)
2017-09-26 22:39:59 +02:00
{
gBattlescriptCurrInstr = jumpPtr;
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
}
2018-02-06 23:09:39 +01:00
else if (gBattleMons[gBattlerAttacker].maxHP == gBattleMons[gBattlerAttacker].hp)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gDisableStructs[gBattlerAttacker].stockpileCounter = 0;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = jumpPtr;
2018-02-06 23:09:39 +01:00
gBattlerTarget = gBattlerAttacker;
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
}
else
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / (1 << (3 - gDisableStructs[gBattlerAttacker].stockpileCounter));
2017-09-26 22:39:59 +02:00
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
gBattleMoveDamage *= -1;
2018-02-06 23:09:39 +01:00
gBattleScripting.animTurn = gDisableStructs[gBattlerAttacker].stockpileCounter;
gDisableStructs[gBattlerAttacker].stockpileCounter = 0;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr += 5;
2018-02-06 23:09:39 +01:00
gBattlerTarget = gBattlerAttacker;
2017-09-26 22:39:59 +02:00
}
}
static void atk88_setdrainedhp(void)
2017-09-26 22:39:59 +02:00
{
if (gBattleMoves[gCurrentMove].argument != 0)
gBattleMoveDamage = -(gHpDealt * gBattleMoves[gCurrentMove].argument / 100);
else
gBattleMoveDamage = -(gHpDealt / 2);
2017-09-26 22:39:59 +02:00
if (gBattleMoveDamage == 0)
gBattleMoveDamage = -1;
gBattlescriptCurrInstr++;
}
2017-11-26 11:55:17 +01:00
static u8 ChangeStatBuffs(s8 statValue, u8 statId, u8 flags, const u8 *BS_ptr)
2017-09-26 22:39:59 +02:00
{
2017-11-26 11:55:17 +01:00
bool8 certain = FALSE;
2017-09-26 22:39:59 +02:00
bool8 notProtectAffected = FALSE;
u32 index;
if (flags & MOVE_EFFECT_AFFECTS_USER)
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2017-09-26 22:39:59 +02:00
else
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget;
2017-09-26 22:39:59 +02:00
flags &= ~(MOVE_EFFECT_AFFECTS_USER);
if (flags & MOVE_EFFECT_CERTAIN)
certain++;
flags &= ~(MOVE_EFFECT_CERTAIN);
if (flags & STAT_CHANGE_NOT_PROTECT_AFFECTED)
notProtectAffected++;
flags &= ~(STAT_CHANGE_NOT_PROTECT_AFFECTED);
PREPARE_STAT_BUFFER(gBattleTextBuff1, statId)
2018-08-11 23:00:16 +02:00
if (statValue <= -1) // Stat decrease.
2017-09-26 22:39:59 +02:00
{
2018-02-06 02:46:59 +01:00
if (gSideTimers[GET_BATTLER_SIDE(gActiveBattler)].mistTimer
2017-09-26 22:39:59 +02:00
&& !certain && gCurrentMove != MOVE_CURSE)
{
if (flags == STAT_CHANGE_BS_PTR)
{
2018-02-06 02:46:59 +01:00
if (gSpecialStatuses[gActiveBattler].statLowered)
2017-09-26 22:39:59 +02:00
{
gBattlescriptCurrInstr = BS_ptr;
}
else
{
BattleScriptPush(BS_ptr);
2018-02-06 02:46:59 +01:00
gBattleScripting.battler = gActiveBattler;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = BattleScript_MistProtected;
2018-02-06 02:46:59 +01:00
gSpecialStatuses[gActiveBattler].statLowered = 1;
2017-09-26 22:39:59 +02:00
}
}
return STAT_CHANGE_DIDNT_WORK;
}
else if (gCurrentMove != MOVE_CURSE
&& notProtectAffected != TRUE && JumpIfMoveAffectedByProtect(0))
{
gBattlescriptCurrInstr = BattleScript_ButItFailed;
return STAT_CHANGE_DIDNT_WORK;
}
2018-02-06 02:46:59 +01:00
else if ((gBattleMons[gActiveBattler].ability == ABILITY_CLEAR_BODY
|| gBattleMons[gActiveBattler].ability == ABILITY_WHITE_SMOKE)
2017-09-26 22:39:59 +02:00
&& !certain && gCurrentMove != MOVE_CURSE)
{
if (flags == STAT_CHANGE_BS_PTR)
{
2018-02-06 02:46:59 +01:00
if (gSpecialStatuses[gActiveBattler].statLowered)
2017-09-26 22:39:59 +02:00
{
gBattlescriptCurrInstr = BS_ptr;
}
else
{
BattleScriptPush(BS_ptr);
2018-02-06 02:46:59 +01:00
gBattleScripting.battler = gActiveBattler;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = BattleScript_AbilityNoStatLoss;
2018-02-06 02:46:59 +01:00
gLastUsedAbility = gBattleMons[gActiveBattler].ability;
RecordAbilityBattle(gActiveBattler, gLastUsedAbility);
gSpecialStatuses[gActiveBattler].statLowered = 1;
2017-09-26 22:39:59 +02:00
}
}
return STAT_CHANGE_DIDNT_WORK;
}
2018-02-06 02:46:59 +01:00
else if (gBattleMons[gActiveBattler].ability == ABILITY_KEEN_EYE
2018-02-08 12:13:29 +01:00
&& !certain && statId == STAT_ACC)
2017-09-26 22:39:59 +02:00
{
if (flags == STAT_CHANGE_BS_PTR)
{
BattleScriptPush(BS_ptr);
2018-02-06 02:46:59 +01:00
gBattleScripting.battler = gActiveBattler;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss;
2018-02-06 02:46:59 +01:00
gLastUsedAbility = gBattleMons[gActiveBattler].ability;
RecordAbilityBattle(gActiveBattler, gLastUsedAbility);
2017-09-26 22:39:59 +02:00
}
return STAT_CHANGE_DIDNT_WORK;
}
2018-02-06 02:46:59 +01:00
else if (gBattleMons[gActiveBattler].ability == ABILITY_HYPER_CUTTER
2018-02-08 12:13:29 +01:00
&& !certain && statId == STAT_ATK)
2017-09-26 22:39:59 +02:00
{
if (flags == STAT_CHANGE_BS_PTR)
{
BattleScriptPush(BS_ptr);
2018-02-06 02:46:59 +01:00
gBattleScripting.battler = gActiveBattler;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss;
2018-02-06 02:46:59 +01:00
gLastUsedAbility = gBattleMons[gActiveBattler].ability;
RecordAbilityBattle(gActiveBattler, gLastUsedAbility);
2017-09-26 22:39:59 +02:00
}
return STAT_CHANGE_DIDNT_WORK;
}
2018-02-06 02:46:59 +01:00
else if (gBattleMons[gActiveBattler].ability == ABILITY_SHIELD_DUST && flags == 0)
2017-09-26 22:39:59 +02:00
{
return STAT_CHANGE_DIDNT_WORK;
}
else // try to decrease
{
statValue = -GET_STAT_BUFF_VALUE(statValue);
gBattleTextBuff2[0] = B_BUFF_PLACEHOLDER_BEGIN;
index = 1;
if (statValue == -2)
{
gBattleTextBuff2[1] = B_BUFF_STRING;
2017-11-26 11:55:17 +01:00
gBattleTextBuff2[2] = STRINGID_STATHARSHLY;
gBattleTextBuff2[3] = STRINGID_STATHARSHLY >> 8;
2017-09-26 22:39:59 +02:00
index = 4;
}
else if (statValue == -3)
{
gBattleTextBuff2[1] = B_BUFF_STRING;
gBattleTextBuff2[2] = STRINGID_SEVERELY & 0xFF;
gBattleTextBuff2[3] = STRINGID_SEVERELY >> 8;
index = 4;
}
2017-09-26 22:39:59 +02:00
gBattleTextBuff2[index] = B_BUFF_STRING;
index++;
2017-11-26 11:55:17 +01:00
gBattleTextBuff2[index] = STRINGID_STATFELL;
2017-09-26 22:39:59 +02:00
index++;
2017-11-26 11:55:17 +01:00
gBattleTextBuff2[index] = STRINGID_STATFELL >> 8;
2017-09-26 22:39:59 +02:00
index++;
gBattleTextBuff2[index] = B_BUFF_EOS;
2018-02-06 02:46:59 +01:00
if (gBattleMons[gActiveBattler].statStages[statId] == 0)
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
else
2018-02-06 23:09:39 +01:00
gBattleCommunication[MULTISTRING_CHOOSER] = (gBattlerTarget == gActiveBattler);
2017-09-26 22:39:59 +02:00
}
}
else // stat increase
{
statValue = GET_STAT_BUFF_VALUE(statValue);
gBattleTextBuff2[0] = B_BUFF_PLACEHOLDER_BEGIN;
index = 1;
if (statValue == 2)
{
gBattleTextBuff2[1] = B_BUFF_STRING;
2017-11-26 11:55:17 +01:00
gBattleTextBuff2[2] = STRINGID_STATSHARPLY;
gBattleTextBuff2[3] = STRINGID_STATSHARPLY >> 8;
2017-09-26 22:39:59 +02:00
index = 4;
}
else if (statValue == 3)
{
gBattleTextBuff2[1] = B_BUFF_STRING;
gBattleTextBuff2[2] = STRINGID_DRASTICALLY & 0xFF;
gBattleTextBuff2[3] = STRINGID_DRASTICALLY >> 8;
index = 4;
2017-09-26 22:39:59 +02:00
}
gBattleTextBuff2[index] = B_BUFF_STRING;
index++;
2017-11-26 11:55:17 +01:00
gBattleTextBuff2[index] = STRINGID_STATROSE;
2017-09-26 22:39:59 +02:00
index++;
2017-11-26 11:55:17 +01:00
gBattleTextBuff2[index] = STRINGID_STATROSE >> 8;
2017-09-26 22:39:59 +02:00
index++;
gBattleTextBuff2[index] = B_BUFF_EOS;
2018-02-06 02:46:59 +01:00
if (gBattleMons[gActiveBattler].statStages[statId] == 0xC)
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
else
2018-02-06 23:09:39 +01:00
gBattleCommunication[MULTISTRING_CHOOSER] = (gBattlerTarget == gActiveBattler);
2017-09-26 22:39:59 +02:00
}
2018-02-06 02:46:59 +01:00
gBattleMons[gActiveBattler].statStages[statId] += statValue;
if (gBattleMons[gActiveBattler].statStages[statId] < 0)
gBattleMons[gActiveBattler].statStages[statId] = 0;
if (gBattleMons[gActiveBattler].statStages[statId] > 0xC)
gBattleMons[gActiveBattler].statStages[statId] = 0xC;
2017-09-26 22:39:59 +02:00
if (gBattleCommunication[MULTISTRING_CHOOSER] == 2 && flags & STAT_CHANGE_BS_PTR)
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
2017-09-26 22:39:59 +02:00
if (gBattleCommunication[MULTISTRING_CHOOSER] == 2 && !(flags & STAT_CHANGE_BS_PTR))
return STAT_CHANGE_DIDNT_WORK;
return STAT_CHANGE_WORKED;
}
2017-09-28 15:34:21 +02:00
static void atk89_statbuffchange(void)
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
const u8* jumpPtr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
2017-09-28 15:34:21 +02:00
if (ChangeStatBuffs(gBattleScripting.statChanger & 0xF0, GET_STAT_BUFF_ID(gBattleScripting.statChanger), gBattlescriptCurrInstr[1], jumpPtr) == STAT_CHANGE_WORKED)
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr += 6;
}
2017-09-28 15:34:21 +02:00
static void atk8A_normalisebuffs(void) // haze
2017-09-26 22:39:59 +02:00
{
s32 i, j;
2018-02-06 02:46:59 +01:00
for (i = 0; i < gBattlersCount; i++)
2017-09-26 22:39:59 +02:00
{
for (j = 0; j < BATTLE_STATS_NO; j++)
gBattleMons[i].statStages[j] = 6;
}
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atk8B_setbide(void)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerAttacker].status2 |= STATUS2_MULTIPLETURNS;
gLockedMoves[gBattlerAttacker] = gCurrentMove;
gTakenDmg[gBattlerAttacker] = 0;
gBattleMons[gBattlerAttacker].status2 |= (STATUS2_BIDE - 0x100); // 2 turns
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atk8C_confuseifrepeatingattackends(void)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if (!(gBattleMons[gBattlerAttacker].status2 & STATUS2_LOCK_CONFUSE))
2017-09-26 22:39:59 +02:00
gBattleCommunication[MOVE_EFFECT_BYTE] = (MOVE_EFFECT_THRASH | MOVE_EFFECT_AFFECTS_USER);
gBattlescriptCurrInstr++;
}
static void atk8D_setmultihitcounter(void)
2017-09-26 22:39:59 +02:00
{
2017-09-28 15:34:21 +02:00
if (gBattlescriptCurrInstr[1])
2017-09-26 22:39:59 +02:00
{
2017-09-28 15:34:21 +02:00
gMultiHitCounter = gBattlescriptCurrInstr[1];
2017-09-26 22:39:59 +02:00
}
else
{
gMultiHitCounter = Random() & 3;
if (gMultiHitCounter > 1)
gMultiHitCounter = (Random() & 3) + 2;
else
gMultiHitCounter += 2;
2018-07-22 18:40:18 +02:00
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SKILL_LINK)
gMultiHitCounter = 5;
2017-09-26 22:39:59 +02:00
}
gBattlescriptCurrInstr += 2;
}
static void atk8E_initmultihitstring(void)
2017-09-26 22:39:59 +02:00
{
PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0)
gBattlescriptCurrInstr++;
}
2017-12-02 00:03:46 +01:00
static bool8 TryDoForceSwitchOut(void)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
*(gBattleStruct->field_58 + gBattlerTarget) = gBattlerPartyIndexes[gBattlerTarget];
2017-09-26 22:39:59 +02:00
}
else
{
u16 random = Random() & 0xFF;
2018-02-06 23:09:39 +01:00
if ((u32)((random * (gBattleMons[gBattlerAttacker].level + gBattleMons[gBattlerTarget].level) >> 8) + 1) <= (gBattleMons[gBattlerTarget].level / 4))
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-26 22:39:59 +02:00
return FALSE;
}
2018-02-06 23:09:39 +01:00
*(gBattleStruct->field_58 + gBattlerTarget) = gBattlerPartyIndexes[gBattlerTarget];
2017-09-26 22:39:59 +02:00
}
2017-12-02 00:03:46 +01:00
gBattlescriptCurrInstr = BattleScript_SuccessForceOut;
2017-09-26 22:39:59 +02:00
return TRUE;
}
2017-09-28 15:34:21 +02:00
static void atk8F_forcerandomswitch(void)
2017-09-26 22:39:59 +02:00
{
s32 i;
2018-02-08 12:13:29 +01:00
s32 battler1PartyId = 0;
s32 battler2PartyId = 0;
2018-09-22 16:15:00 +02:00
s32 lastMonId = 0; // + 1
2017-09-26 22:39:59 +02:00
s32 firstMonId = 0;
s32 monsCount = 0;
2018-09-22 16:15:00 +02:00
struct Pokemon *party = NULL;
2017-09-26 22:39:59 +02:00
s32 validMons = 0;
s32 minNeeded = 0;
if ((gBattleTypeFlags & BATTLE_TYPE_TRAINER))
{
2018-02-06 23:09:39 +01:00
if (GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER)
2017-09-26 22:39:59 +02:00
party = gPlayerParty;
else
party = gEnemyParty;
if ((gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER && gBattleTypeFlags & BATTLE_TYPE_LINK)
|| (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER && gBattleTypeFlags & BATTLE_TYPE_x2000000)
|| (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER))
{
2018-02-06 23:09:39 +01:00
if ((gBattlerTarget & BIT_FLANK) != 0)
2017-09-26 22:39:59 +02:00
{
firstMonId = 3;
lastMonId = 6;
}
else
{
firstMonId = 0;
lastMonId = 3;
}
monsCount = 3;
minNeeded = 1;
2018-02-08 12:13:29 +01:00
battler2PartyId = gBattlerPartyIndexes[gBattlerTarget];
battler1PartyId = gBattlerPartyIndexes[gBattlerTarget ^ BIT_FLANK];
2017-09-26 22:39:59 +02:00
}
else if ((gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_LINK)
|| (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_x2000000))
{
2018-07-01 11:15:42 +02:00
if (GetLinkTrainerFlankId(GetBattlerMultiplayerId(gBattlerTarget)) == 1)
2017-09-26 22:39:59 +02:00
{
firstMonId = 3;
lastMonId = 6;
}
else
{
firstMonId = 0;
lastMonId = 3;
}
monsCount = 3;
minNeeded = 1;
2018-02-08 12:13:29 +01:00
battler2PartyId = gBattlerPartyIndexes[gBattlerTarget];
battler1PartyId = gBattlerPartyIndexes[gBattlerTarget ^ BIT_FLANK];
2017-09-26 22:39:59 +02:00
}
else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
{
2018-02-06 23:09:39 +01:00
if (GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER)
2017-09-26 22:39:59 +02:00
{
firstMonId = 0;
lastMonId = 6;
monsCount = 6;
minNeeded = 2; // since there are two opponents, it has to be a double battle
}
else
{
2018-02-06 23:09:39 +01:00
if ((gBattlerTarget & BIT_FLANK) != 0)
2017-09-26 22:39:59 +02:00
{
firstMonId = 3;
lastMonId = 6;
}
else
{
firstMonId = 0;
lastMonId = 3;
}
monsCount = 3;
minNeeded = 1;
}
2018-02-08 12:13:29 +01:00
battler2PartyId = gBattlerPartyIndexes[gBattlerTarget];
battler1PartyId = gBattlerPartyIndexes[gBattlerTarget ^ BIT_FLANK];
2017-09-26 22:39:59 +02:00
}
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
firstMonId = 0;
lastMonId = 6;
monsCount = 6;
minNeeded = 2;
2018-02-08 12:13:29 +01:00
battler2PartyId = gBattlerPartyIndexes[gBattlerTarget];
battler1PartyId = gBattlerPartyIndexes[gBattlerTarget ^ BIT_FLANK];
2017-09-26 22:39:59 +02:00
}
else
{
firstMonId = 0;
lastMonId = 6;
monsCount = 6;
minNeeded = 1;
2018-02-08 12:13:29 +01:00
battler2PartyId = gBattlerPartyIndexes[gBattlerTarget]; // there is only one pokemon out in single battles
battler1PartyId = gBattlerPartyIndexes[gBattlerTarget];
2017-09-26 22:39:59 +02:00
}
for (i = firstMonId; i < lastMonId; i++)
{
if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE
&& !GetMonData(&party[i], MON_DATA_IS_EGG)
&& GetMonData(&party[i], MON_DATA_HP) != 0)
{
validMons++;
}
}
if (validMons <= minNeeded)
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-26 22:39:59 +02:00
}
else
{
2017-12-02 00:03:46 +01:00
if (TryDoForceSwitchOut())
2017-09-26 22:39:59 +02:00
{
do
{
i = Random() % monsCount;
i += firstMonId;
}
2018-02-08 12:13:29 +01:00
while (i == battler2PartyId
|| i == battler1PartyId
2017-09-26 22:39:59 +02:00
|| GetMonData(&party[i], MON_DATA_SPECIES) == SPECIES_NONE
|| GetMonData(&party[i], MON_DATA_IS_EGG) == TRUE
|| GetMonData(&party[i], MON_DATA_HP) == 0);
}
2018-02-06 23:09:39 +01:00
*(gBattleStruct->monToSwitchIntoId + gBattlerTarget) = i;
2017-09-26 22:39:59 +02:00
if (!sub_81B1250())
2018-02-06 23:09:39 +01:00
sub_803BDA0(gBattlerTarget);
2017-09-26 22:39:59 +02:00
if ((gBattleTypeFlags & BATTLE_TYPE_LINK && gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
|| (gBattleTypeFlags & BATTLE_TYPE_LINK && gBattleTypeFlags & BATTLE_TYPE_MULTI)
|| (gBattleTypeFlags & BATTLE_TYPE_x2000000 && gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
|| (gBattleTypeFlags & BATTLE_TYPE_x2000000 && gBattleTypeFlags & BATTLE_TYPE_MULTI))
{
2018-02-06 23:09:39 +01:00
sub_81B8E80(gBattlerTarget, i, 0);
sub_81B8E80(gBattlerTarget ^ BIT_FLANK, i, 1);
2017-09-26 22:39:59 +02:00
}
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
2018-02-06 23:09:39 +01:00
sub_80571DC(gBattlerTarget, i);
2017-09-26 22:39:59 +02:00
}
}
else
{
2017-12-02 00:03:46 +01:00
TryDoForceSwitchOut();
2017-09-26 22:39:59 +02:00
}
}
static void atk90_tryconversiontypechange(void) // randomly changes user's type to one of its moves' type
2017-09-26 22:39:59 +02:00
{
u8 validMoves = 0;
u8 moveChecked;
u8 moveType;
while (validMoves < 4)
{
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerAttacker].moves[validMoves] == 0)
2017-09-26 22:39:59 +02:00
break;
validMoves++;
}
for (moveChecked = 0; moveChecked < validMoves; moveChecked++)
{
2018-02-06 23:09:39 +01:00
moveType = gBattleMoves[gBattleMons[gBattlerAttacker].moves[moveChecked]].type;
2017-09-26 22:39:59 +02:00
if (moveType == TYPE_MYSTERY)
{
2018-03-01 00:59:52 +01:00
if (IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GHOST))
2017-09-26 22:39:59 +02:00
moveType = TYPE_GHOST;
else
moveType = TYPE_NORMAL;
}
2018-02-06 23:09:39 +01:00
if (moveType != gBattleMons[gBattlerAttacker].type1
&& moveType != gBattleMons[gBattlerAttacker].type2)
2017-09-26 22:39:59 +02:00
{
break;
}
}
if (moveChecked == validMoves)
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-26 22:39:59 +02:00
}
else
{
do
{
while ((moveChecked = Random() & 3) >= validMoves);
2018-02-06 23:09:39 +01:00
moveType = gBattleMoves[gBattleMons[gBattlerAttacker].moves[moveChecked]].type;
2017-09-26 22:39:59 +02:00
if (moveType == TYPE_MYSTERY)
{
2018-03-01 00:59:52 +01:00
if (IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GHOST))
2017-09-26 22:39:59 +02:00
moveType = TYPE_GHOST;
else
moveType = TYPE_NORMAL;
}
}
2018-02-06 23:09:39 +01:00
while (moveType == gBattleMons[gBattlerAttacker].type1 || moveType == gBattleMons[gBattlerAttacker].type2);
2017-09-26 22:39:59 +02:00
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE(gBattlerAttacker, moveType);
PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType);
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr += 5;
}
}
2017-09-28 15:34:21 +02:00
static void atk91_givepaydaymoney(void)
2017-09-26 22:39:59 +02:00
{
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)) && gPaydayMoney != 0)
{
u32 bonusMoney = gPaydayMoney * gBattleStruct->moneyMultiplier;
AddMoney(&gSaveBlock1Ptr->money, bonusMoney);
PREPARE_HWORD_NUMBER_BUFFER(gBattleTextBuff1, 5, bonusMoney)
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_PrintPayDayMoneyString;
}
else
{
gBattlescriptCurrInstr++;
}
}
2017-09-28 15:34:21 +02:00
static void atk92_setlightscreen(void)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if (gSideStatuses[GET_BATTLER_SIDE(gBattlerAttacker)] & SIDE_STATUS_LIGHTSCREEN)
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
}
else
{
2018-02-06 23:09:39 +01:00
gSideStatuses[GET_BATTLER_SIDE(gBattlerAttacker)] |= SIDE_STATUS_LIGHTSCREEN;
gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].lightscreenTimer = 5;
2018-02-07 22:53:40 +01:00
gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].lightscreenBattlerId = gBattlerAttacker;
2017-09-26 22:39:59 +02:00
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && CountAliveMonsInBattle(BATTLE_ALIVE_ATK_SIDE) == 2)
gBattleCommunication[MULTISTRING_CHOOSER] = 4;
else
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
}
gBattlescriptCurrInstr++;
}
static void atk93_tryKO(void)
2017-09-26 22:39:59 +02:00
{
u8 holdEffect, param;
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].item == ITEM_ENIGMA_BERRY)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
holdEffect = gEnigmaBerries[gBattlerTarget].holdEffect;
param = gEnigmaBerries[gBattlerTarget].holdEffectParam;
2017-09-26 22:39:59 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
holdEffect = ItemId_GetHoldEffect(gBattleMons[gBattlerTarget].item);
param = ItemId_GetHoldEffectParam(gBattleMons[gBattlerTarget].item);
2017-09-26 22:39:59 +02:00
}
2018-02-08 12:13:29 +01:00
gPotentialItemEffectBattler = gBattlerTarget;
2017-09-26 22:39:59 +02:00
if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < param)
{
2018-02-06 23:09:39 +01:00
RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_FOCUS_BAND);
gSpecialStatuses[gBattlerTarget].focusBanded = 1;
2017-09-26 22:39:59 +02:00
}
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].ability == ABILITY_STURDY)
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
2017-09-26 22:39:59 +02:00
gLastUsedAbility = ABILITY_STURDY;
gBattlescriptCurrInstr = BattleScript_SturdyPreventsOHKO;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle(gBattlerTarget, ABILITY_STURDY);
2017-09-26 22:39:59 +02:00
}
else
{
u16 chance;
2018-02-06 23:09:39 +01:00
if (!(gStatuses3[gBattlerTarget] & STATUS3_ALWAYS_HITS))
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
chance = gBattleMoves[gCurrentMove].accuracy + (gBattleMons[gBattlerAttacker].level - gBattleMons[gBattlerTarget].level);
if (Random() % 100 + 1 < chance && gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level)
2017-09-26 22:39:59 +02:00
chance = TRUE;
else
chance = FALSE;
}
2018-02-06 23:09:39 +01:00
else if (gDisableStructs[gBattlerTarget].battlerWithSureHit == gBattlerAttacker
&& gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level)
2017-09-26 22:39:59 +02:00
{
chance = TRUE;
}
else
{
2018-02-06 23:09:39 +01:00
chance = gBattleMoves[gCurrentMove].accuracy + (gBattleMons[gBattlerAttacker].level - gBattleMons[gBattlerTarget].level);
if (Random() % 100 + 1 < chance && gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level)
2017-09-26 22:39:59 +02:00
chance = TRUE;
else
chance = FALSE;
}
if (chance)
{
2018-02-06 23:09:39 +01:00
if (gProtectStructs[gBattlerTarget].endured)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - 1;
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_FOE_ENDURED;
2017-09-26 22:39:59 +02:00
}
2018-02-06 23:09:39 +01:00
else if (gSpecialStatuses[gBattlerTarget].focusBanded)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - 1;
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_FOE_HUNG_ON;
2018-02-06 23:09:39 +01:00
gLastUsedItem = gBattleMons[gBattlerTarget].item;
2017-09-26 22:39:59 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons[gBattlerTarget].hp;
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_ONE_HIT_KO;
2017-09-26 22:39:59 +02:00
}
gBattlescriptCurrInstr += 5;
}
else
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level)
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
else
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-26 22:39:59 +02:00
}
}
}
2017-09-28 15:34:21 +02:00
static void atk94_damagetohalftargethp(void) // super fang
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons[gBattlerTarget].hp / 2;
2017-09-26 22:39:59 +02:00
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atk95_setsandstorm(void)
2017-09-26 22:39:59 +02:00
{
if (!TryChangeBattleWeather(gBattlerAttacker, ENUM_WEATHER_SANDSTORM, FALSE))
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
}
else
{
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
}
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atk96_weatherdamage(void)
2017-09-26 22:39:59 +02:00
{
if (WEATHER_HAS_EFFECT)
{
u32 ability = GetBattlerAbility(gBattlerAttacker);
2017-09-26 22:39:59 +02:00
if (gBattleWeather & WEATHER_SANDSTORM_ANY)
{
if (!IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_ROCK)
&& !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GROUND)
&& !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_STEEL)
&& ability != ABILITY_SAND_VEIL
&& ability != ABILITY_SAND_FORCE
&& ability != ABILITY_SAND_RUSH
2018-07-26 21:56:23 +02:00
&& ability != ABILITY_OVERCOAT
2018-02-06 23:09:39 +01:00
&& !(gStatuses3[gBattlerAttacker] & STATUS3_UNDERGROUND)
&& !(gStatuses3[gBattlerAttacker] & STATUS3_UNDERWATER))
{
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 16;
2017-09-26 22:39:59 +02:00
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
}
else
{
gBattleMoveDamage = 0;
}
}
if (gBattleWeather & WEATHER_HAIL_ANY)
2017-09-26 22:39:59 +02:00
{
if (ability == ABILITY_ICE_BODY
&& !(gStatuses3[gBattlerAttacker] & STATUS3_UNDERGROUND)
2018-07-31 23:09:47 +02:00
&& !(gStatuses3[gBattlerAttacker] & STATUS3_UNDERWATER)
&& !BATTLER_MAX_HP(gBattlerAttacker)
&& !gStatuses3[gBattlerAttacker] & STATUS3_HEAL_BLOCK)
{
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 16;
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
gBattleMoveDamage *= -1;
}
else if (!IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_ICE)
&& ability != ABILITY_SNOW_CLOAK
2018-07-26 21:56:23 +02:00
&& ability != ABILITY_OVERCOAT
2018-07-31 23:09:47 +02:00
&& ability != ABILITY_ICE_BODY
2018-02-06 23:09:39 +01:00
&& !(gStatuses3[gBattlerAttacker] & STATUS3_UNDERGROUND)
&& !(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++;
}
static void atk97_tryinfatuating(void)
2017-09-26 22:39:59 +02:00
{
struct Pokemon *monAttacker, *monTarget;
u16 speciesAttacker, speciesTarget;
u32 personalityAttacker, personalityTarget;
2018-02-06 23:09:39 +01:00
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
monAttacker = &gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]];
2017-09-26 22:39:59 +02:00
else
2018-02-06 23:09:39 +01:00
monAttacker = &gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker]];
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if (GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER)
monTarget = &gPlayerParty[gBattlerPartyIndexes[gBattlerTarget]];
2017-09-26 22:39:59 +02:00
else
2018-02-06 23:09:39 +01:00
monTarget = &gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]];
2017-09-26 22:39:59 +02:00
speciesAttacker = GetMonData(monAttacker, MON_DATA_SPECIES);
personalityAttacker = GetMonData(monAttacker, MON_DATA_PERSONALITY);
speciesTarget = GetMonData(monTarget, MON_DATA_SPECIES);
personalityTarget = GetMonData(monTarget, MON_DATA_PERSONALITY);
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].ability == ABILITY_OBLIVIOUS)
2017-09-26 22:39:59 +02:00
{
gBattlescriptCurrInstr = BattleScript_ObliviousPreventsAttraction;
gLastUsedAbility = ABILITY_OBLIVIOUS;
2018-02-06 23:09:39 +01:00
RecordAbilityBattle(gBattlerTarget, ABILITY_OBLIVIOUS);
2017-09-26 22:39:59 +02:00
}
else
{
if (GetGenderFromSpeciesAndPersonality(speciesAttacker, personalityAttacker) == GetGenderFromSpeciesAndPersonality(speciesTarget, personalityTarget)
2018-02-06 23:09:39 +01:00
|| gBattleMons[gBattlerTarget].status2 & STATUS2_INFATUATION
2017-09-26 22:39:59 +02:00
|| GetGenderFromSpeciesAndPersonality(speciesAttacker, personalityAttacker) == MON_GENDERLESS
|| GetGenderFromSpeciesAndPersonality(speciesTarget, personalityTarget) == MON_GENDERLESS)
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
2017-09-26 22:39:59 +02:00
else
{
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerTarget].status2 |= STATUS2_INFATUATED_WITH(gBattlerAttacker);
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr += 5;
}
}
}
static void atk98_updatestatusicon(void)
2017-09-26 22:39:59 +02:00
{
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags)
2017-09-26 22:39:59 +02:00
return;
2017-09-28 15:34:21 +02:00
if (gBattlescriptCurrInstr[1] != BS_ATTACKER_WITH_PARTNER)
2017-09-26 22:39:59 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2018-02-06 20:48:02 +01:00
BtlController_EmitStatusIconUpdate(0, gBattleMons[gActiveBattler].status1, gBattleMons[gActiveBattler].status2);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr += 2;
}
else
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2018-02-06 02:46:59 +01:00
if (!(gAbsentBattlerFlags & gBitTable[gActiveBattler]))
2017-09-26 22:39:59 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitStatusIconUpdate(0, gBattleMons[gActiveBattler].status1, gBattleMons[gActiveBattler].status2);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-26 22:39:59 +02:00
}
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
{
2018-02-06 23:09:39 +01:00
gActiveBattler = GetBattlerAtPosition(GetBattlerPosition(gBattlerAttacker) ^ BIT_FLANK);
2018-02-06 02:46:59 +01:00
if (!(gAbsentBattlerFlags & gBitTable[gActiveBattler]))
2017-09-26 22:39:59 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitStatusIconUpdate(0, gBattleMons[gActiveBattler].status1, gBattleMons[gActiveBattler].status2);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-26 22:39:59 +02:00
}
}
gBattlescriptCurrInstr += 2;
}
}
2017-09-28 15:34:21 +02:00
static void atk99_setmist(void)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if (gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].mistTimer)
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_FAILED;
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
}
else
{
2018-02-06 23:09:39 +01:00
gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].mistTimer = 5;
2018-02-07 22:53:40 +01:00
gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].mistBattlerId = gBattlerAttacker;
2018-02-06 23:09:39 +01:00
gSideStatuses[GET_BATTLER_SIDE(gBattlerAttacker)] |= SIDE_STATUS_MIST;
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
}
gBattlescriptCurrInstr++;
}
static void atk9A_setfocusenergy(void)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_FOCUS_ENERGY)
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_FAILED;
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
}
else
{
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerAttacker].status2 |= STATUS2_FOCUS_ENERGY;
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
}
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atk9B_transformdataexecution(void)
2017-09-26 22:39:59 +02:00
{
2017-11-26 18:07:00 +01:00
gChosenMove = 0xFFFF;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr++;
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].status2 & STATUS2_TRANSFORMED
|| gStatuses3[gBattlerTarget] & STATUS3_SEMI_INVULNERABLE)
2017-09-26 22:39:59 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_FAILED;
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
}
else
{
s32 i;
u8 *battleMonAttacker, *battleMonTarget;
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerAttacker].status2 |= STATUS2_TRANSFORMED;
gDisableStructs[gBattlerAttacker].disabledMove = 0;
gDisableStructs[gBattlerAttacker].disableTimer1 = 0;
gDisableStructs[gBattlerAttacker].transformedMonPersonality = gBattleMons[gBattlerTarget].personality;
gDisableStructs[gBattlerAttacker].unk18_b = 0;
gDisableStructs[gBattlerAttacker].usedMoves = 0;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerTarget].species)
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
battleMonAttacker = (u8*)(&gBattleMons[gBattlerAttacker]);
battleMonTarget = (u8*)(&gBattleMons[gBattlerTarget]);
2017-09-26 22:39:59 +02:00
for (i = 0; i < offsetof(struct BattlePokemon, pp); i++)
battleMonAttacker[i] = battleMonTarget[i];
for (i = 0; i < 4; i++)
{
2018-02-06 23:09:39 +01:00
if (gBattleMoves[gBattleMons[gBattlerAttacker].moves[i]].pp < 5)
gBattleMons[gBattlerAttacker].pp[i] = gBattleMoves[gBattleMons[gBattlerAttacker].moves[i]].pp;
2017-09-26 22:39:59 +02:00
else
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerAttacker].pp[i] = 5;
2017-09-26 22:39:59 +02:00
}
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2018-02-06 20:48:02 +01:00
BtlController_EmitResetActionMoveSelection(0, RESET_MOVE_SELECTION);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
}
}
static void atk9C_setsubstitute(void)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
u32 hp = gBattleMons[gBattlerAttacker].maxHP / 4;
if (gBattleMons[gBattlerAttacker].maxHP / 4 == 0)
2017-09-26 22:39:59 +02:00
hp = 1;
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerAttacker].hp <= hp)
2017-09-26 22:39:59 +02:00
{
gBattleMoveDamage = 0;
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
}
else
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 4; // one bit value will only work for pokemon which max hp can go to 1020(which is more than possible in games)
2017-09-26 22:39:59 +02:00
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerAttacker].status2 |= STATUS2_SUBSTITUTE;
gBattleMons[gBattlerAttacker].status2 &= ~(STATUS2_WRAPPED);
gDisableStructs[gBattlerAttacker].substituteHP = gBattleMoveDamage;
2017-09-26 22:39:59 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE;
}
gBattlescriptCurrInstr++;
}
static bool8 IsMoveUncopyableByMimic(u16 move)
{
s32 i;
2017-09-28 16:51:24 +02:00
for (i = 0; sMovesForbiddenToCopy[i] != MIMIC_FORBIDDEN_END
&& sMovesForbiddenToCopy[i] != move; i++);
2017-09-26 22:39:59 +02:00
2017-09-28 16:51:24 +02:00
return (sMovesForbiddenToCopy[i] != MIMIC_FORBIDDEN_END);
2017-09-26 22:39:59 +02:00
}
2017-09-28 15:34:21 +02:00
static void atk9D_mimicattackcopy(void)
2017-09-26 22:39:59 +02:00
{
2017-11-26 18:07:00 +01:00
gChosenMove = 0xFFFF;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if (IsMoveUncopyableByMimic(gLastMoves[gBattlerTarget])
|| gBattleMons[gBattlerAttacker].status2 & STATUS2_TRANSFORMED
|| gLastMoves[gBattlerTarget] == 0
|| gLastMoves[gBattlerTarget] == 0xFFFF)
2017-09-26 22:39:59 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-26 22:39:59 +02:00
}
else
{
s32 i;
for (i = 0; i < 4; i++)
{
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerAttacker].moves[i] == gLastMoves[gBattlerTarget])
2017-09-26 22:39:59 +02:00
break;
}
if (i == 4)
{
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
2018-02-06 23:09:39 +01:00
gDisableStructs[gBattlerAttacker].unk18_b |= gBitTable[gCurrMovePos];
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr += 5;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-26 22:39:59 +02:00
}
}
}
2017-09-28 15:34:21 +02:00
static void atk9E_metronome(void)
2017-09-26 22:39:59 +02:00
{
while (1)
{
2017-11-11 22:58:23 +01:00
s32 i;
2017-09-26 22:39:59 +02:00
2018-08-01 23:14:02 +02:00
gCurrentMove = (Random() % MOVES_COUNT) + 1;
2017-09-26 22:39:59 +02:00
2017-11-11 22:58:23 +01:00
i = -1;
while (1)
2017-09-26 22:39:59 +02:00
{
2017-11-11 22:58:23 +01:00
i++;
if (sMovesForbiddenToCopy[i] == gCurrentMove)
2017-09-26 22:39:59 +02:00
break;
2017-11-11 22:58:23 +01:00
if (sMovesForbiddenToCopy[i] == METRONOME_FORBIDDEN_END)
2017-09-26 22:39:59 +02:00
break;
}
2017-11-11 22:58:23 +01:00
if (sMovesForbiddenToCopy[i] == METRONOME_FORBIDDEN_END)
{
gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED);
gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect];
2018-02-06 23:09:39 +01:00
gBattlerTarget = GetMoveTarget(gCurrentMove, 0);
2017-11-11 22:58:23 +01:00
return;
}
2017-09-26 22:39:59 +02:00
}
}
2017-09-28 15:34:21 +02:00
static void atk9F_dmgtolevel(void)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons[gBattlerAttacker].level;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atkA0_psywavedamageeffect(void)
2017-09-26 22:39:59 +02:00
{
s32 randDamage;
while ((randDamage = (Random() & 0xF)) > 10);
randDamage *= 10;
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons[gBattlerAttacker].level * (randDamage + 50) / 100;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atkA1_counterdamagecalculator(void)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
u8 sideAttacker = GetBattlerSide(gBattlerAttacker);
2018-02-07 22:53:40 +01:00
u8 sideTarget = GetBattlerSide(gProtectStructs[gBattlerAttacker].physicalBattlerId);
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if (gProtectStructs[gBattlerAttacker].physicalDmg
2017-09-26 22:39:59 +02:00
&& sideAttacker != sideTarget
2018-02-07 22:53:40 +01:00
&& gBattleMons[gProtectStructs[gBattlerAttacker].physicalBattlerId].hp)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gProtectStructs[gBattlerAttacker].physicalDmg * 2;
2017-09-26 22:39:59 +02:00
if (gSideTimers[sideTarget].followmeTimer && gBattleMons[gSideTimers[sideTarget].followmeTarget].hp)
2018-02-06 23:09:39 +01:00
gBattlerTarget = gSideTimers[sideTarget].followmeTarget;
2017-09-26 22:39:59 +02:00
else
2018-02-07 22:53:40 +01:00
gBattlerTarget = gProtectStructs[gBattlerAttacker].physicalBattlerId;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr += 5;
}
else
{
2018-02-06 23:09:39 +01:00
gSpecialStatuses[gBattlerAttacker].flag20 = 1;
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-26 22:39:59 +02:00
}
}
2017-09-28 15:34:21 +02:00
static void atkA2_mirrorcoatdamagecalculator(void) // a copy of atkA1 with the physical -> special field changes
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
u8 sideAttacker = GetBattlerSide(gBattlerAttacker);
2018-02-07 22:53:40 +01:00
u8 sideTarget = GetBattlerSide(gProtectStructs[gBattlerAttacker].specialBattlerId);
2017-09-26 22:39:59 +02:00
2018-02-07 22:53:40 +01:00
if (gProtectStructs[gBattlerAttacker].specialDmg && sideAttacker != sideTarget && gBattleMons[gProtectStructs[gBattlerAttacker].specialBattlerId].hp)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gProtectStructs[gBattlerAttacker].specialDmg * 2;
2017-09-26 22:39:59 +02:00
if (gSideTimers[sideTarget].followmeTimer && gBattleMons[gSideTimers[sideTarget].followmeTarget].hp)
2018-02-06 23:09:39 +01:00
gBattlerTarget = gSideTimers[sideTarget].followmeTarget;
2017-09-26 22:39:59 +02:00
else
2018-02-07 22:53:40 +01:00
gBattlerTarget = gProtectStructs[gBattlerAttacker].specialBattlerId;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr += 5;
}
else
{
2018-02-06 23:09:39 +01:00
gSpecialStatuses[gBattlerAttacker].flag20 = 1;
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-26 22:39:59 +02:00
}
}
2017-09-28 15:34:21 +02:00
static void atkA3_disablelastusedattack(void)
2017-09-26 22:39:59 +02:00
{
s32 i;
for (i = 0; i < 4; i++)
{
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
&& i != 4 && 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];
gDisableStructs[gBattlerTarget].disableTimer1 = (Random() & 3) + 2;
gDisableStructs[gBattlerTarget].disableTimer2 = gDisableStructs[gBattlerTarget].disableTimer1; // 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
}
}
static void atkA4_trysetencore(void)
2017-09-26 22:39:59 +02:00
{
s32 i;
for (i = 0; i < 4; i++)
{
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;
gDisableStructs[gBattlerTarget].encoreTimer1 = (Random() & 3) + 3;
gDisableStructs[gBattlerTarget].encoreTimer2 = gDisableStructs[gBattlerTarget].encoreTimer1;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr += 5;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-26 22:39:59 +02:00
}
}
2017-09-28 15:34:21 +02:00
static void atkA5_painsplitdmgcalc(void)
2017-09-26 22:39:59 +02:00
{
2018-08-02 20:24:18 +02:00
if (!(DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)))
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
s32 hpDiff = (gBattleMons[gBattlerAttacker].hp + gBattleMons[gBattlerTarget].hp) / 2;
s32 painSplitHp = gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - hpDiff;
2017-09-26 22:39:59 +02:00
u8* storeLoc = (void*)(&gBattleScripting.painSplitHp);
storeLoc[0] = (painSplitHp);
storeLoc[1] = (painSplitHp & 0x0000FF00) >> 8;
storeLoc[2] = (painSplitHp & 0x00FF0000) >> 16;
storeLoc[3] = (painSplitHp & 0xFF000000) >> 24;
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons[gBattlerAttacker].hp - hpDiff;
2018-02-07 22:53:40 +01:00
gSpecialStatuses[gBattlerTarget].dmg = 0xFFFF;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr += 5;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-26 22:39:59 +02:00
}
}
2017-09-28 15:34:21 +02:00
static void atkA6_settypetorandomresistance(void) // conversion 2
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
if (gLastLandedMoves[gBattlerAttacker] == 0
|| 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
{
s32 i, j, rands;
for (rands = 0; rands < 1000; rands++)
2017-09-26 22:39:59 +02:00
{
while (((i = (Random() & 0x7F)) > sizeof(gTypeEffectiveness) / 3));
2017-09-26 22:39:59 +02: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]
&& 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-09-26 22:39:59 +02:00
for (j = 0, rands = 0; rands < sizeof(gTypeEffectiveness); j += 3, rands += 3)
2017-09-26 22:39:59 +02:00
{
switch (TYPE_EFFECT_ATK_TYPE(j))
2017-09-26 22:39:59 +02: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));
PREPARE_TYPE_BUFFER(gBattleTextBuff1, TYPE_EFFECT_DEF_TYPE(rands))
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr += 5;
return;
}
break;
2017-09-26 22:39:59 +02:00
}
}
2017-09-26 22:39:59 +02:00
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-26 22:39:59 +02:00
}
}
2017-09-28 15:34:21 +02:00
static void atkA7_setalwayshitflag(void)
2017-09-26 22:39:59 +02:00
{
2018-02-06 23:09:39 +01:00
gStatuses3[gBattlerTarget] &= ~(STATUS3_ALWAYS_HITS);
gStatuses3[gBattlerTarget] |= 0x10;
gDisableStructs[gBattlerTarget].battlerWithSureHit = gBattlerAttacker;
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atkA8_copymovepermanently(void) // sketch
2017-09-26 22:39:59 +02:00
{
2017-11-26 18:07:00 +01:00
gChosenMove = 0xFFFF;
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
if (!(gBattleMons[gBattlerAttacker].status2 & STATUS2_TRANSFORMED)
&& gLastPrintedMoves[gBattlerTarget] != MOVE_STRUGGLE
&& gLastPrintedMoves[gBattlerTarget] != 0
&& gLastPrintedMoves[gBattlerTarget] != 0xFFFF
&& gLastPrintedMoves[gBattlerTarget] != MOVE_SKETCH)
2017-09-26 22:39:59 +02:00
{
s32 i;
for (i = 0; i < 4; i++)
{
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;
}
if (i != 4)
{
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
for (i = 0; i < 4; i++)
{
2018-02-06 23:09:39 +01:00
movePpData.moves[i] = gBattleMons[gBattlerAttacker].moves[i];
movePpData.pp[i] = gBattleMons[gBattlerAttacker].pp[i];
2017-09-26 22:39:59 +02:00
}
2018-02-06 23:09:39 +01:00
movePpData.ppBonuses = gBattleMons[gBattlerAttacker].ppBonuses;
2017-09-26 22:39:59 +02:00
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData(0, REQUEST_MOVES_PP_BATTLE, 0, sizeof(struct MovePpInfo), &movePpData);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-26 22:39:59 +02:00
2018-02-06 23:09:39 +01:00
PREPARE_MOVE_BUFFER(gBattleTextBuff1, gLastPrintedMoves[gBattlerTarget])
2017-09-26 22:39:59 +02:00
gBattlescriptCurrInstr += 5;
}
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-26 22:39:59 +02:00
}
}
2017-09-28 15:34:21 +02:00
static bool8 IsTwoTurnsMove(u16 move)
2017-09-27 23:43:45 +02:00
{
if (gBattleMoves[move].effect == EFFECT_SKULL_BASH
2018-09-30 14:04:46 +02:00
|| gBattleMoves[move].effect == EFFECT_TWO_TURNS_ATTACK
2017-09-27 23:43:45 +02:00
|| gBattleMoves[move].effect == EFFECT_SOLARBEAM
|| gBattleMoves[move].effect == EFFECT_SEMI_INVULNERABLE
2017-09-27 23:43:45 +02:00
|| gBattleMoves[move].effect == EFFECT_BIDE)
return TRUE;
else
return FALSE;
}
static bool8 IsInvalidForSleepTalkOrAssist(u16 move)
{
if (move == 0 || move == MOVE_SLEEP_TALK || move == MOVE_ASSIST
|| move == MOVE_MIRROR_MOVE || move == MOVE_METRONOME)
return TRUE;
else
return FALSE;
}
2018-02-08 12:13:29 +01:00
static u8 AttacksThisTurn(u8 battlerId, u16 move) // Note: returns 1 if it's a charging turn, otherwise 2
2017-09-27 23:43:45 +02:00
{
// first argument is unused
if (gBattleMoves[move].effect == EFFECT_SOLARBEAM
&& (gBattleWeather & WEATHER_SUN_ANY))
return 2;
if (gBattleMoves[move].effect == EFFECT_SKULL_BASH
2018-09-30 14:04:46 +02:00
|| gBattleMoves[move].effect == EFFECT_TWO_TURNS_ATTACK
2017-09-27 23:43:45 +02:00
|| gBattleMoves[move].effect == EFFECT_SOLARBEAM
|| gBattleMoves[move].effect == EFFECT_SEMI_INVULNERABLE
2017-09-27 23:43:45 +02:00
|| gBattleMoves[move].effect == EFFECT_BIDE)
{
if ((gHitMarker & HITMARKER_x8000000))
return 1;
}
return 2;
}
2017-11-26 01:19:57 +01:00
static void atkA9_trychoosesleeptalkmove(void)
2017-09-27 23:43:45 +02:00
{
s32 i;
u8 unusableMovesBits = 0;
for (i = 0; i < 4; i++)
{
2018-02-06 23:09:39 +01:00
if (IsInvalidForSleepTalkOrAssist(gBattleMons[gBattlerAttacker].moves[i])
|| gBattleMons[gBattlerAttacker].moves[i] == MOVE_FOCUS_PUNCH
|| gBattleMons[gBattlerAttacker].moves[i] == MOVE_UPROAR
|| IsTwoTurnsMove(gBattleMons[gBattlerAttacker].moves[i]))
2017-09-27 23:43:45 +02:00
{
unusableMovesBits |= gBitTable[i];
}
}
2018-02-06 23:09:39 +01:00
unusableMovesBits = CheckMoveLimitations(gBattlerAttacker, unusableMovesBits, ~(MOVE_LIMITATION_PP));
2017-09-27 23:43:45 +02:00
if (unusableMovesBits == 0xF) // all 4 moves cannot be chosen
{
gBattlescriptCurrInstr += 5;
}
else // at least one move can be chosen
{
u32 movePosition;
do
{
movePosition = Random() & 3;
} while ((gBitTable[movePosition] & unusableMovesBits));
2018-09-22 18:41:00 +02:00
gCalledMove = gBattleMons[gBattlerAttacker].moves[movePosition];
2017-09-27 23:43:45 +02:00
gCurrMovePos = movePosition;
gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED);
2018-09-22 18:41:00 +02:00
gBattlerTarget = GetMoveTarget(gCalledMove, 0);
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
}
static void atkAA_setdestinybond(void)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerAttacker].status2 |= STATUS2_DESTINY_BOND;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr++;
}
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;
}
}
static void atkAB_trysetdestinybondtohappen(void)
2017-09-27 23:43:45 +02:00
{
TrySetDestinyBondToHappen();
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr++;
}
static void atkAC_settailwind(void)
2017-09-27 23:43:45 +02:00
{
u8 side = GetBattlerSide(gBattlerAttacker);
if (!(gSideStatuses[side] & SIDE_STATUS_TAILWIND))
{
gSideStatuses[side] |= SIDE_STATUS_TAILWIND;
gSideTimers[side].tailwindBattlerId = gBattlerAttacker;
gSideTimers[side].tailwindTimer = 3;
gBattlescriptCurrInstr += 5;
}
else
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
2017-09-27 23:43:45 +02:00
}
static void atkAD_tryspiteppreduce(void)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if (gLastMoves[gBattlerTarget] != 0
&& gLastMoves[gBattlerTarget] != 0xFFFF)
2017-09-27 23:43:45 +02:00
{
s32 i;
for (i = 0; i < 4; i++)
{
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-02-06 23:09:39 +01:00
if (i != 4 && gBattleMons[gBattlerTarget].pp[i] > 1)
2017-09-27 23:43:45 +02:00
{
s32 ppToDeduct = (Random() & 3) + 2;
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].pp[i] < ppToDeduct)
ppToDeduct = gBattleMons[gBattlerTarget].pp[i];
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
PREPARE_MOVE_BUFFER(gBattleTextBuff1, gLastMoves[gBattlerTarget])
2017-09-27 23:43:45 +02:00
ConvertIntToDecimalStringN(gBattleTextBuff2, ppToDeduct, 0, 1);
PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 1, ppToDeduct)
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerTarget].pp[i] -= ppToDeduct;
gActiveBattler = gBattlerTarget;
2017-09-27 23:43:45 +02:00
2018-02-06 02:46:59 +01:00
if (!(gDisableStructs[gActiveBattler].unk18_b & gBitTable[i])
&& !(gBattleMons[gActiveBattler].status2 & STATUS2_TRANSFORMED))
2017-09-27 23:43:45 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + i, 0, 1, &gBattleMons[gActiveBattler].pp[i]);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-27 23:43:45 +02:00
}
gBattlescriptCurrInstr += 5;
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].pp[i] == 0)
CancelMultiTurnMoves(gBattlerTarget);
2017-09-27 23:43:45 +02:00
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
}
static void atkAE_healpartystatus(void)
2017-09-27 23:43:45 +02:00
{
u32 zero = 0;
u8 toHeal = 0;
if (gCurrentMove == MOVE_HEAL_BELL)
{
2018-06-30 14:12:17 +02:00
struct Pokemon *party;
2017-09-27 23:43:45 +02:00
s32 i;
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
2018-02-06 23:09:39 +01:00
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
2017-09-27 23:43:45 +02:00
party = gPlayerParty;
else
party = gEnemyParty;
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerAttacker].ability != ABILITY_SOUNDPROOF)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerAttacker].status1 = 0;
gBattleMons[gBattlerAttacker].status2 &= ~(STATUS2_NIGHTMARE);
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
RecordAbilityBattle(gBattlerAttacker, gBattleMons[gBattlerAttacker].ability);
2017-09-27 23:43:45 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] |= 1;
}
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattleScripting.battler = GetBattlerAtPosition(GetBattlerPosition(gBattlerAttacker) ^ BIT_FLANK);
2017-09-27 23:43:45 +02:00
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
2018-02-06 02:46:59 +01:00
&& !(gAbsentBattlerFlags & gBitTable[gActiveBattler]))
2017-09-27 23:43:45 +02:00
{
2018-02-06 02:46:59 +01:00
if (gBattleMons[gActiveBattler].ability != ABILITY_SOUNDPROOF)
2017-09-27 23:43:45 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons[gActiveBattler].status1 = 0;
gBattleMons[gActiveBattler].status2 &= ~(STATUS2_NIGHTMARE);
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 02:46:59 +01:00
RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability);
2017-09-27 23:43:45 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] |= 2;
}
}
2018-06-30 14:12:17 +02:00
for (i = 0; i < PARTY_SIZE; i++)
2017-09-27 23:43:45 +02:00
{
u16 species = GetMonData(&party[i], MON_DATA_SPECIES2);
u8 abilityBit = GetMonData(&party[i], MON_DATA_ALT_ABILITY);
if (species != 0 && species != SPECIES_EGG)
{
u8 ability;
2018-02-06 23:09:39 +01:00
if (gBattlerPartyIndexes[gBattlerAttacker] == i)
ability = gBattleMons[gBattlerAttacker].ability;
2017-09-27 23:43:45 +02:00
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
2018-02-06 20:48:02 +01:00
&& gBattlerPartyIndexes[gActiveBattler] == i
2018-02-06 02:46:59 +01:00
&& !(gAbsentBattlerFlags & gBitTable[gActiveBattler]))
ability = gBattleMons[gActiveBattler].ability;
2017-09-27 23:43:45 +02:00
else
ability = GetAbilityBySpecies(species, abilityBit);
if (ability != ABILITY_SOUNDPROOF)
toHeal |= (1 << i);
}
}
}
else // Aromatherapy
{
gBattleCommunication[MULTISTRING_CHOOSER] = 4;
toHeal = 0x3F;
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerAttacker].status1 = 0;
gBattleMons[gBattlerAttacker].status2 &= ~(STATUS2_NIGHTMARE);
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
gActiveBattler = GetBattlerAtPosition(GetBattlerPosition(gBattlerAttacker) ^ BIT_FLANK);
2017-09-27 23:43:45 +02:00
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
2018-02-06 02:46:59 +01:00
&& !(gAbsentBattlerFlags & gBitTable[gActiveBattler]))
2017-09-27 23:43:45 +02:00
{
2018-02-06 02:46:59 +01:00
gBattleMons[gActiveBattler].status1 = 0;
gBattleMons[gActiveBattler].status2 &= ~(STATUS2_NIGHTMARE);
2017-09-27 23:43:45 +02:00
}
}
if (toHeal)
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, toHeal, 4, &zero);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-27 23:43:45 +02:00
}
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atkAF_cursetarget(void)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].status2 & STATUS2_CURSED)
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerTarget].status2 |= STATUS2_CURSED;
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 2;
2017-09-27 23:43:45 +02:00
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
gBattlescriptCurrInstr += 5;
}
}
static void atkB0_trysetspikes(void)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
u8 targetSide = GetBattlerSide(gBattlerAttacker) ^ BIT_SIDE;
2017-09-27 23:43:45 +02:00
if (gSideTimers[targetSide].spikesAmount == 3)
{
2018-02-06 23:09:39 +01:00
gSpecialStatuses[gBattlerAttacker].flag20 = 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;
}
}
static void atkB1_setforesight(void)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerTarget].status2 |= STATUS2_FORESIGHT;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr++;
}
static void atkB2_trysetperishsong(void)
2017-09-27 23:43:45 +02:00
{
s32 i;
s32 notAffectedCount = 0;
2018-02-06 02:46:59 +01:00
for (i = 0; i < gBattlersCount; i++)
2017-09-27 23:43:45 +02:00
{
if (gStatuses3[i] & STATUS3_PERISH_SONG
|| gBattleMons[i].ability == ABILITY_SOUNDPROOF)
{
notAffectedCount++;
}
else
{
gStatuses3[i] |= STATUS3_PERISH_SONG;
2017-11-12 17:11:06 +01:00
gDisableStructs[i].perishSongTimer1 = 3;
gDisableStructs[i].perishSongTimer2 = 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;
}
static void atkB3_handlerollout(void)
2017-09-27 23:43:45 +02:00
{
2018-01-16 22:12:38 +01:00
if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
CancelMultiTurnMoves(gBattlerAttacker);
gBattlescriptCurrInstr = BattleScript_MoveMissedPause;
2017-09-27 23:43:45 +02:00
}
else
{
if (!(gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)) // First hit.
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gDisableStructs[gBattlerAttacker].rolloutCounter1 = 5;
gDisableStructs[gBattlerAttacker].rolloutCounter2 = 5;
gBattleMons[gBattlerAttacker].status2 |= STATUS2_MULTIPLETURNS;
gLockedMoves[gBattlerAttacker] = gCurrentMove;
2017-09-27 23:43:45 +02:00
}
if (--gDisableStructs[gBattlerAttacker].rolloutCounter1 == 0) // Last hit.
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerAttacker].status2 &= ~(STATUS2_MULTIPLETURNS);
2017-09-27 23:43:45 +02:00
}
gBattlescriptCurrInstr++;
}
}
2017-09-28 15:34:21 +02:00
static void atkB4_jumpifconfusedandstatmaxed(void)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].status2 & STATUS2_CONFUSION
&& gBattleMons[gBattlerTarget].statStages[gBattlescriptCurrInstr[1]] == 0xC)
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
2017-09-27 23:43:45 +02:00
else
gBattlescriptCurrInstr += 6;
}
static void atkB5_handlefurycutter(void)
2017-09-27 23:43:45 +02:00
{
2018-01-16 22:12:38 +01:00
if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gDisableStructs[gBattlerAttacker].furyCutterCounter = 0;
gBattlescriptCurrInstr = BattleScript_MoveMissedPause;
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
if (gDisableStructs[gBattlerAttacker].furyCutterCounter != 5)
gDisableStructs[gBattlerAttacker].furyCutterCounter++;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr++;
}
}
static void atkB6_setembargo(void)
2017-09-27 23:43:45 +02:00
{
if (gStatuses3[gBattlerTarget] & STATUS3_EMBARGO)
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
gStatuses3[gBattlerTarget] |= STATUS3_EMBARGO;
gDisableStructs[gBattlerTarget].embargoTimer = 5;
gBattlescriptCurrInstr += 5;
}
2017-09-27 23:43:45 +02:00
}
2017-09-28 15:34:21 +02:00
static void atkB7_presentdamagecalculation(void)
2017-09-27 23:43:45 +02:00
{
u32 rand = Random() & 0xFF;
2017-09-27 23:43:45 +02:00
if (rand < 102)
{
gBattleStruct->presentBasePower = 40;
}
2017-09-27 23:43:45 +02:00
else if (rand < 178)
{
gBattleStruct->presentBasePower = 80;
}
2017-09-27 23:43:45 +02:00
else if (rand < 204)
{
gBattleStruct->presentBasePower = 120;
}
2017-09-27 23:43:45 +02:00
else
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP / 4;
2017-09-27 23:43:45 +02:00
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
gBattleMoveDamage *= -1;
}
2017-09-27 23:43:45 +02:00
if (rand < 204)
{
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;
}
2017-09-27 23:43:45 +02:00
else
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags &= ~(MOVE_RESULT_DOESNT_AFFECT_FOE);
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr = BattleScript_PresentHealTarget;
}
}
static void atkB8_setsafeguard(void)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if (gSideStatuses[GET_BATTLER_SIDE(gBattlerAttacker)] & SIDE_STATUS_SAFEGUARD)
2017-09-27 23:43:45 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
2017-09-27 23:43:45 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
}
else
{
2018-02-06 23:09:39 +01:00
gSideStatuses[GET_BATTLER_SIDE(gBattlerAttacker)] |= SIDE_STATUS_SAFEGUARD;
gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].safeguardTimer = 5;
2018-02-07 22:53:40 +01:00
gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].safeguardBattlerId = gBattlerAttacker;
2017-09-27 23:43:45 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 5;
}
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atkB9_magnitudedamagecalculation(void)
2017-09-27 23:43:45 +02:00
{
u32 magnitude = Random() % 100;
2017-09-27 23:43:45 +02:00
if (magnitude < 5)
{
gBattleStruct->magnitudeBasePower = 10;
2017-09-27 23:43:45 +02:00
magnitude = 4;
}
else if (magnitude < 15)
{
gBattleStruct->magnitudeBasePower = 30;
2017-09-27 23:43:45 +02:00
magnitude = 5;
}
else if (magnitude < 35)
{
gBattleStruct->magnitudeBasePower = 50;
2017-09-27 23:43:45 +02:00
magnitude = 6;
}
else if (magnitude < 65)
{
gBattleStruct->magnitudeBasePower = 70;
2017-09-27 23:43:45 +02:00
magnitude = 7;
}
else if (magnitude < 85)
{
gBattleStruct->magnitudeBasePower = 90;
2017-09-27 23:43:45 +02:00
magnitude = 8;
}
else if (magnitude < 95)
{
gBattleStruct->magnitudeBasePower = 110;
2017-09-27 23:43:45 +02:00
magnitude = 9;
}
else
{
gBattleStruct->magnitudeBasePower = 150;
2017-09-27 23:43:45 +02:00
magnitude = 10;
}
PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff1, 2, magnitude);
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
for (gBattlerTarget = 0; gBattlerTarget < gBattlersCount; gBattlerTarget++)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if (gBattlerTarget == gBattlerAttacker)
2017-09-27 23:43:45 +02:00
continue;
if (!(gAbsentBattlerFlags & gBitTable[gBattlerTarget])) // A valid target was found.
2017-09-27 23:43:45 +02:00
break;
}
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atkBA_jumpifnopursuitswitchdmg(void)
2017-09-27 23:43:45 +02:00
{
if (gMultiHitCounter == 1)
{
2018-02-06 23:09:39 +01:00
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
2017-09-27 23:43:45 +02:00
else
2018-02-06 23:09:39 +01:00
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
2017-09-27 23:43:45 +02:00
else
2018-02-06 23:09:39 +01:00
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
2017-09-27 23:43:45 +02:00
}
2018-02-06 23:09:39 +01:00
if (gChosenActionByBattler[gBattlerTarget] == B_ACTION_USE_MOVE
&& gBattlerAttacker == *(gBattleStruct->moveTarget + gBattlerTarget)
&& !(gBattleMons[gBattlerTarget].status1 & (STATUS1_SLEEP | STATUS1_FREEZE))
&& gBattleMons[gBattlerAttacker].hp
&& !gDisableStructs[gBattlerTarget].truantCounter
&& gChosenMoveByBattler[gBattlerTarget] == MOVE_PURSUIT)
2017-09-27 23:43:45 +02:00
{
s32 i;
2018-02-06 02:46:59 +01:00
for (i = 0; i < gBattlersCount; i++)
2017-09-27 23:43:45 +02:00
{
2018-06-28 21:06:32 +02:00
if (gBattlerByTurnOrder[i] == gBattlerTarget)
2017-10-04 19:25:14 +02:00
gActionsByTurnOrder[i] = 11;
2017-09-27 23:43:45 +02:00
}
gCurrentMove = MOVE_PURSUIT;
2018-02-08 11:17:41 +01:00
gCurrMovePos = gChosenMovePos = *(gBattleStruct->chosenMovePositions + gBattlerTarget);
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr += 5;
gBattleScripting.animTurn = 1;
gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED);
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
}
2017-09-28 15:34:21 +02:00
static void atkBB_setsunny(void)
2017-09-27 23:43:45 +02:00
{
if (!TryChangeBattleWeather(gBattlerAttacker, ENUM_WEATHER_SUN, FALSE))
2017-09-27 23:43:45 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
2017-09-27 23:43:45 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
}
else
{
gBattleCommunication[MULTISTRING_CHOOSER] = 4;
}
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atkBC_maxattackhalvehp(void) // belly drum
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
u32 halfHp = gBattleMons[gBattlerAttacker].maxHP / 2;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
if (!(gBattleMons[gBattlerAttacker].maxHP / 2))
2017-09-27 23:43:45 +02:00
halfHp = 1;
2018-02-08 12:13:29 +01:00
if (gBattleMons[gBattlerAttacker].statStages[STAT_ATK] < 12
2018-02-06 23:09:39 +01:00
&& gBattleMons[gBattlerAttacker].hp > halfHp)
2017-09-27 23:43:45 +02:00
{
2018-02-08 12:13:29 +01:00
gBattleMons[gBattlerAttacker].statStages[STAT_ATK] = 12;
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 2;
2017-09-27 23:43:45 +02:00
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
gBattlescriptCurrInstr += 5;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
}
2017-09-28 15:34:21 +02:00
static void atkBD_copyfoestats(void) // psych up
2017-09-27 23:43:45 +02:00
{
s32 i;
for (i = 0; i < BATTLE_STATS_NO; i++)
{
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerAttacker].statStages[i] = gBattleMons[gBattlerTarget].statStages[i];
2017-09-27 23:43:45 +02:00
}
gBattlescriptCurrInstr += 5; // Has an unused jump ptr(possibly for a failed attempt) parameter.
}
2017-09-28 15:34:21 +02:00
static void atkBE_rapidspinfree(void)
2017-09-27 23:43:45 +02:00
{
u8 atkSide = GetBattlerSide(gBattlerAttacker);
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_WRAPPED)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleScripting.battler = gBattlerTarget;
gBattleMons[gBattlerAttacker].status2 &= ~(STATUS2_WRAPPED);
gBattlerTarget = *(gBattleStruct->wrappedBy + gBattlerAttacker);
2017-09-27 23:43:45 +02:00
gBattleTextBuff1[0] = B_BUFF_PLACEHOLDER_BEGIN;
gBattleTextBuff1[1] = B_BUFF_MOVE;
2018-02-06 23:09:39 +01:00
gBattleTextBuff1[2] = *(gBattleStruct->wrappedMove + gBattlerAttacker * 2 + 0);
gBattleTextBuff1[3] = *(gBattleStruct->wrappedMove + gBattlerAttacker * 2 + 1);
2017-09-27 23:43:45 +02:00
gBattleTextBuff1[4] = B_BUFF_EOS;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_WrapFree;
}
2018-02-06 23:09:39 +01:00
else if (gStatuses3[gBattlerAttacker] & STATUS3_LEECHSEED)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gStatuses3[gBattlerAttacker] &= ~(STATUS3_LEECHSEED);
2018-07-01 11:15:42 +02:00
gStatuses3[gBattlerAttacker] &= ~(STATUS3_LEECHSEED_BATTLER);
2017-09-27 23:43:45 +02:00
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_LeechSeedFree;
}
else if (gSideStatuses[atkSide] & SIDE_STATUS_SPIKES)
2017-09-27 23:43:45 +02:00
{
gSideStatuses[atkSide] &= ~(SIDE_STATUS_SPIKES);
gSideTimers[atkSide].spikesAmount = 0;
2017-09-27 23:43:45 +02:00
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_SpikesFree;
}
else if (gSideStatuses[atkSide] & SIDE_STATUS_TOXIC_SPIKES)
{
gSideStatuses[atkSide] &= ~(SIDE_STATUS_TOXIC_SPIKES);
gSideTimers[atkSide].toxicSpikesAmount = 0;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_ToxicSpikesFree;
}
else if (gSideStatuses[atkSide] & SIDE_STATUS_STICKY_WEB)
{
gSideStatuses[atkSide] &= ~(SIDE_STATUS_STICKY_WEB);
gSideTimers[atkSide].stickyWebAmount = 0;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_StickyWebFree;
}
else if (gSideStatuses[atkSide] & SIDE_STATUS_STEALTH_ROCK)
{
gSideStatuses[atkSide] &= ~(SIDE_STATUS_STEALTH_ROCK);
gSideTimers[atkSide].stealthRockAmount = 0;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_StealthRockFree;
}
2017-09-27 23:43:45 +02:00
else
{
gBattlescriptCurrInstr++;
}
}
static void atkBF_setdefensecurlbit(void)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerAttacker].status2 |= STATUS2_DEFENSE_CURL;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atkC0_recoverbasedonsunlight(void)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattlerTarget = gBattlerAttacker;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerAttacker].hp != gBattleMons[gBattlerAttacker].maxHP)
2017-09-27 23:43:45 +02:00
{
if (gBattleWeather == 0 || !WEATHER_HAS_EFFECT)
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 2;
2017-09-27 23:43:45 +02:00
else if (gBattleWeather & WEATHER_SUN_ANY)
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = 20 * gBattleMons[gBattlerAttacker].maxHP / 30;
2017-09-27 23:43:45 +02:00
else // not sunny weather
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 4;
2017-09-27 23:43:45 +02:00
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
gBattleMoveDamage *= -1;
gBattlescriptCurrInstr += 5;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
}
static void atkC1_setstickyweb(void)
2017-09-27 23:43:45 +02:00
{
u8 targetSide = GetBattlerSide(gBattlerTarget);
if (gSideStatuses[targetSide] & SIDE_STATUS_STICKY_WEB)
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
gSideStatuses[targetSide] |= SIDE_STATUS_STICKY_WEB;
gSideTimers[targetSide].stickyWebAmount = 1;
gBattlescriptCurrInstr += 5;
}
2017-09-27 23:43:45 +02:00
}
static void atkC2_selectfirstvalidtarget(void)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
for (gBattlerTarget = 0; gBattlerTarget < gBattlersCount; gBattlerTarget++)
2017-09-27 23:43:45 +02:00
{
2018-09-30 14:04:46 +02:00
if (gBattlerTarget == gBattlerAttacker && !(gBattleMoves[gCurrentMove].target & MOVE_TARGET_USER))
2017-09-27 23:43:45 +02:00
continue;
2018-02-06 23:09:39 +01:00
if (!(gAbsentBattlerFlags & gBitTable[gBattlerTarget]))
2017-09-27 23:43:45 +02:00
break;
}
gBattlescriptCurrInstr++;
}
static void atkC3_trysetfutureattack(void)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if (gWishFutureKnock.futureSightCounter[gBattlerTarget] != 0)
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gSideStatuses[GET_BATTLER_SIDE(gBattlerTarget)] |= SIDE_STATUS_FUTUREATTACK;
gWishFutureKnock.futureSightMove[gBattlerTarget] = gCurrentMove;
gWishFutureKnock.futureSightAttacker[gBattlerTarget] = gBattlerAttacker;
gWishFutureKnock.futureSightCounter[gBattlerTarget] = 3;
2017-09-27 23:43:45 +02:00
if (gCurrentMove == MOVE_DOOM_DESIRE)
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
else
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
gBattlescriptCurrInstr += 5;
}
}
static void atkC4_trydobeatup(void)
2017-09-27 23:43:45 +02:00
{
struct Pokemon *party;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
2017-09-27 23:43:45 +02:00
party = gPlayerParty;
else
party = gEnemyParty;
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].hp == 0)
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
else
{
u8 beforeLoop = gBattleCommunication[0];
for (;gBattleCommunication[0] < 6; gBattleCommunication[0]++)
{
if (GetMonData(&party[gBattleCommunication[0]], MON_DATA_HP)
&& GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES2)
&& GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES2) != SPECIES_EGG
&& !GetMonData(&party[gBattleCommunication[0]], MON_DATA_STATUS))
break;
}
if (gBattleCommunication[0] < 6)
{
2018-02-06 23:09:39 +01:00
PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattlerAttacker, gBattleCommunication[0])
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr += 9;
gBattleMoveDamage = gBaseStats[GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES)].baseAttack;
gBattleMoveDamage *= gBattleMoves[gCurrentMove].power;
gBattleMoveDamage *= (GetMonData(&party[gBattleCommunication[0]], MON_DATA_LEVEL) * 2 / 5 + 2);
2018-02-06 23:09:39 +01:00
gBattleMoveDamage /= gBaseStats[gBattleMons[gBattlerTarget].species].baseDefense;
2017-09-27 23:43:45 +02:00
gBattleMoveDamage = (gBattleMoveDamage / 50) + 2;
2018-02-06 23:09:39 +01:00
if (gProtectStructs[gBattlerAttacker].helpingHand)
2017-09-27 23:43:45 +02:00
gBattleMoveDamage = gBattleMoveDamage * 15 / 10;
gBattleCommunication[0]++;
}
else if (beforeLoop != 0)
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
else
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 5);
2017-09-27 23:43:45 +02:00
}
}
2017-09-28 15:34:21 +02:00
static void atkC5_setsemiinvulnerablebit(void)
2017-09-27 23:43:45 +02:00
{
switch (gCurrentMove)
{
case MOVE_FLY:
case MOVE_BOUNCE:
2018-02-06 23:09:39 +01:00
gStatuses3[gBattlerAttacker] |= STATUS3_ON_AIR;
2017-09-27 23:43:45 +02:00
break;
case MOVE_DIG:
2018-02-06 23:09:39 +01:00
gStatuses3[gBattlerAttacker] |= STATUS3_UNDERGROUND;
2017-09-27 23:43:45 +02:00
break;
case MOVE_DIVE:
2018-02-06 23:09:39 +01:00
gStatuses3[gBattlerAttacker] |= STATUS3_UNDERWATER;
2017-09-27 23:43:45 +02:00
break;
}
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atkC6_clearsemiinvulnerablebit(void)
2017-09-27 23:43:45 +02:00
{
switch (gCurrentMove)
{
case MOVE_FLY:
case MOVE_BOUNCE:
2018-02-06 23:09:39 +01:00
gStatuses3[gBattlerAttacker] &= ~STATUS3_ON_AIR;
2017-09-27 23:43:45 +02:00
break;
case MOVE_DIG:
2018-02-06 23:09:39 +01:00
gStatuses3[gBattlerAttacker] &= ~STATUS3_UNDERGROUND;
2017-09-27 23:43:45 +02:00
break;
case MOVE_DIVE:
2018-02-06 23:09:39 +01:00
gStatuses3[gBattlerAttacker] &= ~STATUS3_UNDERWATER;
2017-09-27 23:43:45 +02:00
break;
}
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atkC7_setminimize(void)
2017-09-27 23:43:45 +02:00
{
if (gHitMarker & HITMARKER_OBEYS)
2018-02-06 23:09:39 +01:00
gStatuses3[gBattlerAttacker] |= STATUS3_MINIMIZED;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atkC8_sethail(void)
2017-09-27 23:43:45 +02:00
{
if (!TryChangeBattleWeather(gBattlerAttacker, ENUM_WEATHER_HAIL, FALSE))
2017-09-27 23:43:45 +02:00
{
2018-01-16 22:12:38 +01:00
gMoveResultFlags |= MOVE_RESULT_MISSED;
2017-09-27 23:43:45 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
}
else
{
gBattleCommunication[MULTISTRING_CHOOSER] = 5;
}
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atkC9_jumpifattackandspecialattackcannotfall(void) // memento
2017-09-27 23:43:45 +02:00
{
2018-02-08 12:13:29 +01:00
if (gBattleMons[gBattlerTarget].statStages[STAT_ATK] == 0
&& gBattleMons[gBattlerTarget].statStages[STAT_SPATK] == 0
2017-09-27 23:43:45 +02:00
&& gBattleCommunication[6] != 1)
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2018-02-06 02:46:59 +01:00
gBattleMoveDamage = gBattleMons[gActiveBattler].hp;
2018-02-06 20:48:02 +01:00
BtlController_EmitHealthBarUpdate(0, INSTANT_HP_BAR_DROP);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr += 5;
}
}
2017-09-28 15:34:21 +02:00
static void atkCA_setforcedtarget(void) // follow me
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gSideTimers[GetBattlerSide(gBattlerAttacker)].followmeTimer = 1;
gSideTimers[GetBattlerSide(gBattlerAttacker)].followmeTarget = gBattlerAttacker;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atkCB_setcharge(void)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gStatuses3[gBattlerAttacker] |= STATUS3_CHARGED_UP;
gDisableStructs[gBattlerAttacker].chargeTimer1 = 2;
gDisableStructs[gBattlerAttacker].chargeTimer2 = 2;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atkCC_callterrainattack(void) // nature power
2017-09-27 23:43:45 +02:00
{
gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED);
gCurrentMove = sNaturePowerMoves[gBattleTerrain];
2018-02-06 23:09:39 +01:00
gBattlerTarget = GetMoveTarget(gCurrentMove, 0);
2017-09-27 23:43:45 +02:00
BattleScriptPush(gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]);
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atkCD_cureifburnedparalysedorpoisoned(void) // refresh
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerAttacker].status1 & (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON))
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerAttacker].status1 = 0;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr += 5;
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-27 23:43:45 +02:00
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
}
2017-09-28 15:34:21 +02:00
static void atkCE_settorment(void)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].status2 & STATUS2_TORMENT)
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerTarget].status2 |= STATUS2_TORMENT;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr += 5;
}
}
2017-09-28 15:34:21 +02:00
static void atkCF_jumpifnodamage(void)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if (gProtectStructs[gBattlerAttacker].physicalDmg || gProtectStructs[gBattlerAttacker].specialDmg)
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr += 5;
else
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
2017-09-28 15:34:21 +02:00
static void atkD0_settaunt(void)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if (gDisableStructs[gBattlerTarget].tauntTimer1 == 0)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gDisableStructs[gBattlerTarget].tauntTimer1 = 2;
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
}
}
static void atkD1_trysethelpinghand(void)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerAttacker) ^ BIT_FLANK);
2017-09-27 23:43:45 +02:00
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
2018-02-06 23:09:39 +01:00
&& !(gAbsentBattlerFlags & gBitTable[gBattlerTarget])
&& !gProtectStructs[gBattlerAttacker].helpingHand
&& !gProtectStructs[gBattlerTarget].helpingHand)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gProtectStructs[gBattlerTarget].helpingHand = 1;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr += 5;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
}
static void atkD2_tryswapitems(void) // trick
2017-09-27 23:43:45 +02:00
{
// opponent can't swap items with player in regular battles
2018-09-20 22:00:00 +02:00
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_HILL
2018-02-06 23:09:39 +01:00
|| (GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT
2017-09-27 23:43:45 +02:00
&& !(gBattleTypeFlags & (BATTLE_TYPE_LINK
| BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_FRONTIER
| BATTLE_TYPE_SECRET_BASE
| BATTLE_TYPE_x2000000))))
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
u8 sideAttacker = GetBattlerSide(gBattlerAttacker);
u8 sideTarget = GetBattlerSide(gBattlerTarget);
2017-09-27 23:43:45 +02:00
// you can't swap items if they were knocked off in regular battles
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK
| BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_FRONTIER
| BATTLE_TYPE_SECRET_BASE
| BATTLE_TYPE_x2000000))
2018-02-06 23:09:39 +01:00
&& (gWishFutureKnock.knockedOffPokes[sideAttacker] & gBitTable[gBattlerPartyIndexes[gBattlerAttacker]]
|| gWishFutureKnock.knockedOffPokes[sideTarget] & gBitTable[gBattlerPartyIndexes[gBattlerTarget]]))
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
// can't swap if two pokemon don't have an item
// or if either of them is an enigma berry or a mail
2018-02-06 23:09:39 +01:00
else if ((gBattleMons[gBattlerAttacker].item == 0 && gBattleMons[gBattlerTarget].item == 0)
2018-09-30 12:27:51 +02:00
|| !CanBattlerGetOrLoseItem(gBattlerAttacker, gBattleMons[gBattlerAttacker].item)
|| !CanBattlerGetOrLoseItem(gBattlerAttacker, gBattleMons[gBattlerTarget].item)
|| !CanBattlerGetOrLoseItem(gBattlerTarget, gBattleMons[gBattlerTarget].item)
|| !CanBattlerGetOrLoseItem(gBattlerTarget, gBattleMons[gBattlerAttacker].item))
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
// check if ability prevents swapping
2018-02-06 23:09:39 +01:00
else if (gBattleMons[gBattlerTarget].ability == ABILITY_STICKY_HOLD)
2017-09-27 23:43:45 +02:00
{
gBattlescriptCurrInstr = BattleScript_StickyHoldActivates;
2018-02-06 23:09:39 +01:00
gLastUsedAbility = gBattleMons[gBattlerTarget].ability;
RecordAbilityBattle(gBattlerTarget, gLastUsedAbility);
2017-09-27 23:43:45 +02:00
}
// took a while, but all checks passed and items can be safely swapped
else
{
u16 oldItemAtk, *newItemAtk;
2018-02-06 23:09:39 +01:00
newItemAtk = &gBattleStruct->changedItems[gBattlerAttacker];
oldItemAtk = gBattleMons[gBattlerAttacker].item;
*newItemAtk = gBattleMons[gBattlerTarget].item;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerAttacker].item = 0;
gBattleMons[gBattlerTarget].item = oldItemAtk;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, newItemAtk);
2018-02-06 23:09:39 +01:00
MarkBattlerForControllerExec(gBattlerAttacker);
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerTarget;
BtlController_EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gBattlerTarget].item);
MarkBattlerForControllerExec(gBattlerTarget);
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
*(u8*)((u8*)(&gBattleStruct->choicedMove[gBattlerTarget]) + 0) = 0;
*(u8*)((u8*)(&gBattleStruct->choicedMove[gBattlerTarget]) + 1) = 0;
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
*(u8*)((u8*)(&gBattleStruct->choicedMove[gBattlerAttacker]) + 0) = 0;
*(u8*)((u8*)(&gBattleStruct->choicedMove[gBattlerAttacker]) + 1) = 0;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr += 5;
PREPARE_ITEM_BUFFER(gBattleTextBuff1, *newItemAtk)
PREPARE_ITEM_BUFFER(gBattleTextBuff2, oldItemAtk)
if (oldItemAtk != 0 && *newItemAtk != 0)
gBattleCommunication[MULTISTRING_CHOOSER] = 2; // attacker's item -> <- target's item
else if (oldItemAtk == 0 && *newItemAtk != 0)
gBattleCommunication[MULTISTRING_CHOOSER] = 0; // nothing -> <- target's item
else
gBattleCommunication[MULTISTRING_CHOOSER] = 1; // attacker's item -> <- nothing
}
}
}
static void atkD3_trycopyability(void) // role play
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].ability != 0
&& gBattleMons[gBattlerTarget].ability != ABILITY_WONDER_GUARD)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerAttacker].ability = gBattleMons[gBattlerTarget].ability;
gLastUsedAbility = gBattleMons[gBattlerTarget].ability;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr += 5;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
}
static void atkD4_trywish(void)
2017-09-27 23:43:45 +02:00
{
2017-09-28 15:34:21 +02:00
switch (gBattlescriptCurrInstr[1])
2017-09-27 23:43:45 +02:00
{
case 0: // use wish
2018-02-06 23:09:39 +01:00
if (gWishFutureKnock.wishCounter[gBattlerAttacker] == 0)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gWishFutureKnock.wishCounter[gBattlerAttacker] = 2;
2018-02-07 22:53:40 +01:00
gWishFutureKnock.wishMonId[gBattlerAttacker] = gBattlerPartyIndexes[gBattlerAttacker];
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr += 6;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
2017-09-27 23:43:45 +02:00
}
break;
case 1: // heal effect
2018-02-07 22:53:40 +01:00
PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattlerTarget, gWishFutureKnock.wishMonId[gBattlerTarget])
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP / 2;
2017-09-27 23:43:45 +02:00
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
gBattleMoveDamage *= -1;
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].hp == gBattleMons[gBattlerTarget].maxHP)
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
2017-09-27 23:43:45 +02:00
else
gBattlescriptCurrInstr += 6;
break;
}
}
2018-07-21 21:58:07 +02:00
static void atkD5_settoxicspikes(void)
2017-09-27 23:43:45 +02:00
{
2018-07-21 21:58:07 +02:00
u8 targetSide = GetBattlerSide(gBattlerTarget);
if (gSideTimers[targetSide].toxicSpikesAmount >= 2)
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
else
{
2018-07-21 21:58:07 +02:00
gSideTimers[targetSide].toxicSpikesAmount++;
gSideStatuses[targetSide] |= SIDE_STATUS_TOXIC_SPIKES;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr += 5;
}
}
2018-07-21 21:58:07 +02:00
static void atkD6_setgastroacid(void)
2017-09-27 23:43:45 +02:00
{
2018-07-21 21:58:07 +02:00
switch (gBattleMons[gBattlerTarget].ability)
{
2018-07-21 21:58:07 +02:00
case ABILITY_MULTITYPE:
case ABILITY_STANCE_CHANGE:
case ABILITY_SCHOOLING:
case ABILITY_COMATOSE:
case ABILITY_SHIELDS_DOWN:
case ABILITY_DISGUISE:
case ABILITY_RKS_SYSTEM:
case ABILITY_BATTLE_BOND:
case ABILITY_POWER_CONSTRUCT:
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2018-07-21 21:58:07 +02:00
break;
default:
gStatuses3[gBattlerTarget] |= STATUS3_GASTRO_ACID;
gBattlescriptCurrInstr += 5;
2018-07-21 21:58:07 +02:00
break;
}
2017-09-27 23:43:45 +02:00
}
2017-09-28 15:34:21 +02:00
static void atkD7_setyawn(void)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if (gStatuses3[gBattlerTarget] & STATUS3_YAWN
|| gBattleMons[gBattlerTarget].status1 & STATUS1_ANY)
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gStatuses3[gBattlerTarget] |= 0x1000;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr += 5;
}
}
2017-09-28 15:34:21 +02:00
static void atkD8_setdamagetohealthdifference(void)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].hp <= gBattleMons[gBattlerAttacker].hp)
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - gBattleMons[gBattlerAttacker].hp;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr += 5;
}
}
2018-07-21 21:58:07 +02:00
static void HandleRoomMove(u32 statusFlag, u8 *timer, u8 stringId)
2017-09-27 23:43:45 +02:00
{
2018-07-21 21:58:07 +02:00
if (gFieldStatuses & statusFlag)
{
gFieldStatuses &= ~(statusFlag);
*timer = 0;
gBattleCommunication[MULTISTRING_CHOOSER] = stringId + 1;
}
else
{
gFieldStatuses |= statusFlag;
*timer = 5;
gBattleCommunication[MULTISTRING_CHOOSER] = stringId;
}
}
static void atkD9_setroom(void)
{
2018-08-05 12:43:57 +02:00
switch (gBattleMoves[gCurrentMove].effect)
2018-07-21 21:58:07 +02:00
{
2018-08-05 12:43:57 +02:00
case EFFECT_TRICK_ROOM:
2018-07-21 21:58:07 +02:00
HandleRoomMove(STATUS_FIELD_TRICK_ROOM, &gFieldTimers.trickRoomTimer, 0);
break;
2018-08-05 12:43:57 +02:00
case EFFECT_WONDER_ROOM:
2018-07-21 21:58:07 +02:00
HandleRoomMove(STATUS_FIELD_WONDER_ROOM, &gFieldTimers.wonderRoomTimer, 2);
break;
2018-08-05 12:43:57 +02:00
case EFFECT_MAGIC_ROOM:
2018-07-21 21:58:07 +02:00
HandleRoomMove(STATUS_FIELD_MAGIC_ROOM, &gFieldTimers.magicRoomTimer, 4);
break;
default:
gBattleCommunication[MULTISTRING_CHOOSER] = 6;
break;
}
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr++;
}
static void atkDA_tryswapabilities(void) // skill swap
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if ((gBattleMons[gBattlerAttacker].ability == 0
&& gBattleMons[gBattlerTarget].ability == 0)
|| gBattleMons[gBattlerAttacker].ability == ABILITY_WONDER_GUARD
|| gBattleMons[gBattlerTarget].ability == ABILITY_WONDER_GUARD
2018-01-16 22:12:38 +01:00
|| gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
else
{
2018-02-06 23:09:39 +01:00
u8 abilityAtk = gBattleMons[gBattlerAttacker].ability;
gBattleMons[gBattlerAttacker].ability = gBattleMons[gBattlerTarget].ability;
gBattleMons[gBattlerTarget].ability = abilityAtk;
2017-09-27 23:43:45 +02:00
2018-07-21 21:58:07 +02:00
gBattlescriptCurrInstr += 5;
2017-09-27 23:43:45 +02:00
}
}
static void atkDB_tryimprision(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);
PressurePPLoseOnUsingImprision(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;
for (attackerMoveId = 0; attackerMoveId < 4; attackerMoveId++)
{
s32 i;
for (i = 0; i < 4; i++)
{
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;
}
if (i != 4)
break;
}
if (attackerMoveId != 4)
{
2018-02-06 23:09:39 +01:00
gStatuses3[gBattlerAttacker] |= STATUS3_IMPRISONED_OTHERS;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr += 5;
break;
}
}
}
2018-07-21 21:58:07 +02:00
if (battlerId == gBattlersCount) // In Generation 3 games, Imprison fails if the user doesn't share any moves with any of the foes.
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
}
2018-07-21 21:58:07 +02:00
static void atkDC_setstealthrock(void)
2017-09-27 23:43:45 +02:00
{
2018-07-21 21:58:07 +02:00
u8 targetSide = GetBattlerSide(gBattlerTarget);
if (gSideStatuses[targetSide] & SIDE_STATUS_STEALTH_ROCK)
2017-09-27 23:43:45 +02:00
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
else
{
2018-07-21 21:58:07 +02:00
gSideStatuses[targetSide] |= SIDE_STATUS_STEALTH_ROCK;
2018-07-24 21:47:00 +02:00
gSideTimers[targetSide].stealthRockAmount = 1;
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr += 5;
}
}
2018-07-21 21:58:07 +02:00
static void atkDD_setuserstatus3(void)
2017-09-27 23:43:45 +02:00
{
2018-07-21 21:58:07 +02:00
u32 flags = T1_READ_32(gBattlescriptCurrInstr + 1);
if (gStatuses3[gBattlerAttacker] & flags)
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 5);
}
else
{
gStatuses3[gBattlerAttacker] |= flags;
gBattlescriptCurrInstr += 9;
}
2017-09-27 23:43:45 +02:00
}
2017-09-28 15:34:21 +02:00
static void atkDE_asistattackselect(void)
2017-09-27 23:43:45 +02:00
{
s32 chooseableMovesNo = 0;
struct Pokemon* party;
s32 monId, moveId;
u16* movesArray = gBattleStruct->assistPossibleMoves;
2018-02-06 23:09:39 +01:00
if (GET_BATTLER_SIDE(gBattlerAttacker) != B_SIDE_PLAYER)
2017-09-27 23:43:45 +02:00
party = gEnemyParty;
else
party = gPlayerParty;
2018-07-21 21:58:07 +02:00
for (monId = 0; monId < PARTY_SIZE; monId++)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if (monId == gBattlerPartyIndexes[gBattlerAttacker])
2017-09-27 23:43:45 +02:00
continue;
if (GetMonData(&party[monId], MON_DATA_SPECIES2) == SPECIES_NONE)
continue;
if (GetMonData(&party[monId], MON_DATA_SPECIES2) == SPECIES_EGG)
continue;
for (moveId = 0; moveId < 4; moveId++)
{
s32 i = 0;
u16 move = GetMonData(&party[monId], MON_DATA_MOVE1 + moveId);
if (IsInvalidForSleepTalkOrAssist(move))
continue;
2017-09-28 16:51:24 +02:00
for (; sMovesForbiddenToCopy[i] != ASSIST_FORBIDDEN_END && move != sMovesForbiddenToCopy[i]; i++);
2017-09-27 23:43:45 +02:00
2017-09-28 16:51:24 +02:00
if (sMovesForbiddenToCopy[i] != ASSIST_FORBIDDEN_END)
2017-09-27 23:43:45 +02:00
continue;
if (move == MOVE_NONE)
continue;
movesArray[chooseableMovesNo] = move;
chooseableMovesNo++;
}
}
if (chooseableMovesNo)
{
gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED);
2018-09-22 18:41:00 +02:00
gCalledMove = movesArray[((Random() & 0xFF) * chooseableMovesNo) >> 8];
gBattlerTarget = GetMoveTarget(gCalledMove, 0);
2017-09-27 23:43:45 +02:00
gBattlescriptCurrInstr += 5;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
}
}
static void atkDF_trysetmagiccoat(void)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gBattlerTarget = gBattlerAttacker;
gSpecialStatuses[gBattlerAttacker].flag20 = 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;
}
}
static void atkE0_trysetsnatch(void) // snatch
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
gSpecialStatuses[gBattlerAttacker].flag20 = 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;
}
}
static void atkE1_trygetintimidatetarget(void)
2017-09-27 23:43:45 +02:00
{
u8 side;
2018-07-01 11:15:42 +02:00
gBattleScripting.battler = gBattleStruct->intimidateBattler;
2018-02-06 02:46:59 +01:00
side = GetBattlerSide(gBattleScripting.battler);
2017-09-27 23:43:45 +02:00
2018-02-06 02:46:59 +01:00
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gBattleMons[gBattleScripting.battler].ability)
2017-09-27 23:43:45 +02:00
2018-02-06 23:09:39 +01:00
for (;gBattlerTarget < gBattlersCount; gBattlerTarget++)
2017-09-27 23:43:45 +02:00
{
2018-02-06 23:09:39 +01:00
if (GetBattlerSide(gBattlerTarget) == side)
2017-09-27 23:43:45 +02:00
continue;
2018-02-06 23:09:39 +01:00
if (!(gAbsentBattlerFlags & gBitTable[gBattlerTarget]))
2017-09-27 23:43:45 +02:00
break;
}
2018-02-06 23:09:39 +01:00
if (gBattlerTarget >= gBattlersCount)
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-27 23:43:45 +02:00
else
gBattlescriptCurrInstr += 5;
}
static void atkE2_switchoutabilities(void)
2017-09-27 23:43:45 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2017-09-27 23:43:45 +02:00
2018-07-26 21:56:23 +02:00
switch (GetBattlerAbility(gActiveBattler))
2017-09-27 23:43:45 +02:00
{
case ABILITY_NATURAL_CURE:
2018-02-06 02:46:59 +01:00
gBattleMons[gActiveBattler].status1 = 0;
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, gBitTable[*(gBattleStruct->field_58 + gActiveBattler)], 4, &gBattleMons[gActiveBattler].status1);
MarkBattlerForControllerExec(gActiveBattler);
2018-07-26 21:56:23 +02:00
break;
case ABILITY_REGENERATOR:
gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 3;
gBattleMoveDamage += gBattleMons[gActiveBattler].hp;
if (gBattleMoveDamage > gBattleMons[gActiveBattler].maxHP)
gBattleMons[gActiveBattler].maxHP = gBattleMons[gActiveBattler].maxHP;
BtlController_EmitSetMonData(0, REQUEST_HP_BATTLE, gBitTable[*(gBattleStruct->field_58 + gActiveBattler)], 2, &gBattleMoveDamage);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-27 23:43:45 +02:00
break;
}
gBattlescriptCurrInstr += 2;
}
2017-09-28 15:34:21 +02:00
static void atkE3_jumpifhasnohp(void)
2017-09-27 23:43:45 +02:00
{
2018-02-08 11:17:41 +01:00
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
2017-09-27 23:43:45 +02:00
2018-02-06 02:46:59 +01:00
if (gBattleMons[gActiveBattler].hp == 0)
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
2017-09-27 23:43:45 +02:00
else
gBattlescriptCurrInstr += 6;
}
2017-09-28 15:34:21 +02:00
static void atkE4_getsecretpowereffect(void)
2017-09-27 23:43:45 +02:00
{
switch (gBattleTerrain)
{
case BATTLE_TERRAIN_GRASS:
gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_POISON;
break;
case BATTLE_TERRAIN_LONG_GRASS:
gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_SLEEP;
break;
case BATTLE_TERRAIN_SAND:
gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_ACC_MINUS_1;
break;
case BATTLE_TERRAIN_UNDERWATER:
gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_DEF_MINUS_1;
break;
case BATTLE_TERRAIN_WATER:
gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_ATK_MINUS_1;
break;
case BATTLE_TERRAIN_POND:
gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_SPD_MINUS_1;
break;
2017-12-16 01:08:55 +01:00
case BATTLE_TERRAIN_MOUNTAIN:
2017-09-27 23:43:45 +02:00
gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_CONFUSION;
break;
case BATTLE_TERRAIN_CAVE:
gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_FLINCH;
break;
default:
gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_PARALYSIS;
break;
}
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atkE5_pickup(void)
2017-09-27 23:43:45 +02:00
{
if (!InBattlePike())
{
s32 i;
u16 species, heldItem;
u8 ability;
if (InBattlePyramid())
{
for (i = 0; i < 6; i++)
{
species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2);
heldItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM);
if (GetMonData(&gPlayerParty[i], MON_DATA_ALT_ABILITY))
ability = gBaseStats[species].ability2;
else
ability = gBaseStats[species].ability1;
if (ability == ABILITY_PICKUP
&& species != 0
&& species != SPECIES_EGG
&& heldItem == ITEM_NONE
&& (Random() % 10) == 0)
{
heldItem = GetBattlePyramidPickupItemId();
SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &heldItem);
}
}
}
else
{
for (i = 0; i < 6; i++)
{
species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2);
heldItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM);
if (GetMonData(&gPlayerParty[i], MON_DATA_ALT_ABILITY))
ability = gBaseStats[species].ability2;
else
ability = gBaseStats[species].ability1;
if (ability == ABILITY_PICKUP
&& species != 0
&& species != SPECIES_EGG
&& heldItem == ITEM_NONE
&& (Random() % 10) == 0)
{
s32 j;
s32 rand = Random() % 100;
u8 lvlDivBy10 = (GetMonData(&gPlayerParty[i], MON_DATA_LEVEL) - 1) / 10;
if (lvlDivBy10 > 9)
lvlDivBy10 = 9;
for (j = 0; j < 9; j++)
{
2017-09-28 16:51:24 +02:00
if (sPickupProbabilities[j] > rand)
2017-09-27 23:43:45 +02:00
{
2017-09-28 16:51:24 +02:00
SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &sPickupItems[lvlDivBy10 + j]);
2017-09-27 23:43:45 +02:00
break;
}
else if (rand == 99 || rand == 98)
{
2017-09-28 16:51:24 +02:00
SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &sRarePickupItems[lvlDivBy10 + (99 - rand)]);
2017-09-27 23:43:45 +02:00
break;
}
}
}
}
}
}
gBattlescriptCurrInstr++;
}
2017-09-28 15:34:21 +02:00
static void atkE6_docastformchangeanimation(void)
2017-09-28 15:34:21 +02:00
{
2018-02-06 02:46:59 +01:00
gActiveBattler = gBattleScripting.battler;
2017-09-28 15:34:21 +02:00
2018-02-06 02:46:59 +01:00
if (gBattleMons[gActiveBattler].status2 & STATUS2_SUBSTITUTE)
2017-09-28 15:34:21 +02:00
*(&gBattleStruct->formToChangeInto) |= 0x80;
2018-02-06 20:48:02 +01:00
BtlController_EmitBattleAnimation(0, B_ANIM_CASTFORM_CHANGE, gBattleStruct->formToChangeInto);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr++;
}
static void atkE7_trycastformdatachange(void)
2017-09-28 15:34:21 +02:00
{
u8 form;
gBattlescriptCurrInstr++;
2018-02-06 02:46:59 +01:00
form = CastformDataTypeChange(gBattleScripting.battler);
2017-09-28 15:34:21 +02:00
if (form)
{
BattleScriptPushCursorAndCallback(BattleScript_CastformChange);
*(&gBattleStruct->formToChangeInto) = form - 1;
}
}
static void atkE8_settypebasedhalvers(void) // water and mud sport
{
bool8 worked = FALSE;
if (gBattleMoves[gCurrentMove].effect == EFFECT_MUD_SPORT)
{
2018-07-14 13:17:10 +02:00
if (!(gFieldStatuses & STATUS_FIELD_MUDSPORT))
2017-09-28 15:34:21 +02:00
{
2018-07-14 13:17:10 +02:00
gFieldStatuses |= STATUS_FIELD_MUDSPORT;
gFieldTimers.mudSportTimer = 5;
2017-09-28 15:34:21 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
worked = TRUE;
}
}
else // water sport
{
2018-07-14 13:17:10 +02:00
if (!(gFieldStatuses & STATUS_FIELD_WATERSPORT))
2017-09-28 15:34:21 +02:00
{
2018-07-14 13:17:10 +02:00
gFieldStatuses |= STATUS_FIELD_WATERSPORT;
gFieldTimers.waterSportTimer = 5;
2017-09-28 15:34:21 +02:00
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
worked = TRUE;
}
}
if (worked)
gBattlescriptCurrInstr += 5;
else
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-28 15:34:21 +02:00
}
2018-08-02 20:24:18 +02:00
bool32 DoesSubstituteBlockMove(u8 battlerAtk, u8 battlerDef, u32 move)
2017-09-28 15:34:21 +02:00
{
2018-08-02 20:24:18 +02:00
if (!(gBattleMons[battlerDef].status2 & STATUS2_SUBSTITUTE))
return FALSE;
else if (gBattleMoves[move].flags & FLAG_SOUND && B_SOUND_SUBSTITUTE >= GEN_6)
return FALSE;
else if (GetBattlerAbility(battlerAtk) == ABILITY_INFILTRATOR)
return FALSE;
else
return TRUE;
}
static void atkE9_jumpifsubstituteblocks(void)
{
if (DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
else
gBattlescriptCurrInstr += 5;
2017-09-28 15:34:21 +02:00
}
static void atkEA_tryrecycleitem(void)
2017-09-28 15:34:21 +02:00
{
u16 *usedHeldItem;
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
2018-02-06 02:46:59 +01:00
usedHeldItem = &gBattleStruct->usedHeldItems[gActiveBattler];
if (*usedHeldItem != 0 && gBattleMons[gActiveBattler].item == 0)
2017-09-28 15:34:21 +02:00
{
gLastUsedItem = *usedHeldItem;
*usedHeldItem = 0;
2018-02-06 02:46:59 +01:00
gBattleMons[gActiveBattler].item = gLastUsedItem;
2017-09-28 15:34:21 +02:00
2018-02-06 20:48:02 +01:00
BtlController_EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gActiveBattler].item);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr += 5;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-28 15:34:21 +02:00
}
}
static void atkEB_settypetoterrain(void)
{
2018-03-01 00:59:52 +01:00
if (!IS_BATTLER_OF_TYPE(gBattlerAttacker, sTerrainToType[gBattleTerrain]))
2017-09-28 15:34:21 +02:00
{
2018-03-01 00:59:52 +01:00
SET_BATTLER_TYPE(gBattlerAttacker, sTerrainToType[gBattleTerrain]);
PREPARE_TYPE_BUFFER(gBattleTextBuff1, sTerrainToType[gBattleTerrain]);
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr += 5;
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-28 15:34:21 +02:00
}
}
static void atkEC_pursuitrelated(void)
2017-09-28 15:34:21 +02:00
{
2018-02-06 23:09:39 +01:00
gActiveBattler = GetBattlerAtPosition(GetBattlerPosition(gBattlerAttacker) ^ BIT_FLANK);
2017-09-28 15:34:21 +02:00
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
2018-02-06 02:46:59 +01:00
&& !(gAbsentBattlerFlags & gBitTable[gActiveBattler])
2018-02-06 23:09:39 +01:00
&& gChosenActionByBattler[gActiveBattler] == 0
&& gChosenMoveByBattler[gActiveBattler] == MOVE_PURSUIT)
2017-09-28 15:34:21 +02:00
{
2018-02-06 02:46:59 +01:00
gActionsByTurnOrder[gActiveBattler] = 11;
2017-09-28 15:34:21 +02:00
gCurrentMove = MOVE_PURSUIT;
gBattlescriptCurrInstr += 5;
gBattleScripting.animTurn = 1;
2018-02-06 23:09:39 +01:00
gBattleScripting.field_20 = gBattlerAttacker;
gBattlerAttacker = gActiveBattler;
2017-09-28 15:34:21 +02:00
}
else
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-28 15:34:21 +02:00
}
}
2018-06-30 14:12:17 +02:00
static void atkEF_snatchsetbattlers(void)
2017-09-28 15:34:21 +02:00
{
2018-02-08 11:17:41 +01:00
gEffectBattler = gBattlerAttacker;
2017-09-28 15:34:21 +02:00
2018-02-06 23:09:39 +01:00
if (gBattlerAttacker == gBattlerTarget)
gBattlerAttacker = gBattlerTarget = gBattleScripting.battler;
2017-09-28 15:34:21 +02:00
else
2018-02-06 23:09:39 +01:00
gBattlerTarget = gBattleScripting.battler;
2017-09-28 15:34:21 +02:00
2018-02-08 11:17:41 +01:00
gBattleScripting.battler = gEffectBattler;
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr++;
}
static void atkEE_removelightscreenreflect(void) // brick break
{
2018-02-06 23:09:39 +01:00
u8 opposingSide = GetBattlerSide(gBattlerAttacker) ^ BIT_SIDE;
2017-09-28 15:34:21 +02:00
if (gSideTimers[opposingSide].reflectTimer || gSideTimers[opposingSide].lightscreenTimer)
{
2018-01-16 22:12:38 +01:00
gSideStatuses[opposingSide] &= ~(SIDE_STATUS_REFLECT);
gSideStatuses[opposingSide] &= ~(SIDE_STATUS_LIGHTSCREEN);
2017-09-28 15:34:21 +02:00
gSideTimers[opposingSide].reflectTimer = 0;
gSideTimers[opposingSide].lightscreenTimer = 0;
gBattleScripting.animTurn = 1;
gBattleScripting.animTargetsHit = 1;
}
else
{
gBattleScripting.animTurn = 0;
gBattleScripting.animTargetsHit = 0;
}
gBattlescriptCurrInstr++;
}
2017-11-26 01:19:57 +01:00
static void atkEF_handleballthrow(void)
2017-09-28 15:34:21 +02:00
{
u8 ballMultiplier = 0;
2018-02-06 20:48:02 +01:00
if (gBattleControllerExecFlags)
2017-09-28 15:34:21 +02:00
return;
2018-02-06 23:09:39 +01:00
gActiveBattler = gBattlerAttacker;
gBattlerTarget = gBattlerAttacker ^ BIT_SIDE;
2017-09-28 15:34:21 +02:00
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
{
2018-02-06 20:48:02 +01:00
BtlController_EmitBallThrowAnim(0, BALL_TRAINER_BLOCK);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr = BattleScript_TrainerBallBlock;
}
else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL)
{
2018-02-06 20:48:02 +01:00
BtlController_EmitBallThrowAnim(0, BALL_3_SHAKES_SUCCESS);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr = BattleScript_WallyBallThrow;
}
else
{
u32 odds;
u8 catchRate;
if (gLastUsedItem == ITEM_SAFARI_BALL)
2018-07-01 11:15:42 +02:00
catchRate = gBattleStruct->safariCatchFactor * 1275 / 100;
2017-09-28 15:34:21 +02:00
else
2018-02-06 23:09:39 +01:00
catchRate = gBaseStats[gBattleMons[gBattlerTarget].species].catchRate;
2017-09-28 15:34:21 +02:00
if (gLastUsedItem > ITEM_SAFARI_BALL)
{
switch (gLastUsedItem)
{
case ITEM_NET_BALL:
2018-03-01 00:59:52 +01:00
if (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_WATER) || IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_BUG))
2017-09-28 15:34:21 +02:00
ballMultiplier = 30;
else
ballMultiplier = 10;
break;
case ITEM_DIVE_BALL:
2018-06-30 14:12:17 +02:00
if (Overworld_GetMapTypeOfSaveblockLocation() == MAP_TYPE_UNDERWATER)
2017-09-28 15:34:21 +02:00
ballMultiplier = 35;
else
ballMultiplier = 10;
break;
case ITEM_NEST_BALL:
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].level < 40)
2017-09-28 15:34:21 +02:00
{
2018-02-06 23:09:39 +01:00
ballMultiplier = 40 - gBattleMons[gBattlerTarget].level;
2017-09-28 15:34:21 +02:00
if (ballMultiplier <= 9)
ballMultiplier = 10;
}
else
{
ballMultiplier = 10;
}
break;
case ITEM_REPEAT_BALL:
2018-02-06 23:09:39 +01:00
if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gBattlerTarget].species), FLAG_GET_CAUGHT))
2017-09-28 15:34:21 +02:00
ballMultiplier = 30;
else
ballMultiplier = 10;
break;
case ITEM_TIMER_BALL:
ballMultiplier = gBattleResults.battleTurnCounter + 10;
if (ballMultiplier > 40)
ballMultiplier = 40;
break;
case ITEM_LUXURY_BALL:
case ITEM_PREMIER_BALL:
ballMultiplier = 10;
break;
}
}
else
ballMultiplier = sBallCatchBonuses[gLastUsedItem - 2];
odds = (catchRate * ballMultiplier / 10)
2018-02-06 23:09:39 +01:00
* (gBattleMons[gBattlerTarget].maxHP * 3 - gBattleMons[gBattlerTarget].hp * 2)
/ (3 * gBattleMons[gBattlerTarget].maxHP);
2017-09-28 15:34:21 +02:00
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].status1 & (STATUS1_SLEEP | STATUS1_FREEZE))
2017-09-28 15:34:21 +02:00
odds *= 2;
2018-02-06 23:09:39 +01:00
if (gBattleMons[gBattlerTarget].status1 & (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON))
2017-09-28 15:34:21 +02:00
odds = (odds * 15) / 10;
if (gLastUsedItem != ITEM_SAFARI_BALL)
{
if (gLastUsedItem == ITEM_MASTER_BALL)
{
Decompile TV (#80) * ClearTVShowData * special_0x44 * DoTVShow (nonmatching because align) * DoTVShowBravoTrainerPokemonProfile * Update field names * DoTVShowBravoTrainerBattleTower * Renaming of struct fields * sub_80EBFF4 and UpdateTVScreensOnMap * SetTVMetatilesOnMap * Power buttons for the TV screens on the map * special_0x45 * sub_80EC18C * special_0x4a * ResetGabbyAndTy * GabbyAndTyBeforeInterview * GabbyAndTyAfterInterview * Through IsTVShowInSearchOfTrainersAiring * GabbyAndTyGetLastQuote * GabbyAndTyGetLastBattleTrivia * GabbyAndTySetScriptVarsToFieldObjectLocalIds * InterviewAfter; use TVShow as a precursor for making the individual show structs anonymous * Make TV structs anonymous within the union * Move the TV union to its own subheader * Move TV show enums to the global.tv.h subheader * Funcion renaming * Apply static attributes where able * PutPokemonTodayCaughtOnAir * sub_80EC8A4 * PutPokemonTodayFailedOnTheAir * sub_80EC9E8, sub_80ECA10 * sub_80ECA38 * sub_80ECB00 * Put3CheersForPokeblocksOnTheAir * PutFanClubSpecialOnTheAir * ContestLiveUpdates_BeforeInterview * Other before-interview Contest Live Updates functions * ContestLiveUpdates_BeforeInterview_5 * InterviewAfter_BravoTrainerPokemonProfile * BravoTrainerPokemonProfile_BeforeInterview1 * BravoTrainerPokemonProfile_BeforeInterview2 * Disassemble TV data * Decompile TV data * InterviewAfter_BravoTrainerBattleTowerProfile * SaveRecordedItemPurchasesForTVShow * PutNameRaterShowOnTheAir * StartMassOutbreak * PutLilycoveContestLadyShowOnTheAir * InterviewAfter_FanClubLetter * Rip TV strings * InterviewAfter_RecentHappenings * InterviewAfter_PkmnFanClubOpinions * sub_80ED718 * EndMassOutbreak * sub_80ED888 * sub_80ED8B4 * UpdateMassOutbreakTimeLeft * sub_80ED950 * PutFishingAdviceShowOnTheAir * through sub_80EDA80 * ewram and common syms are now fetched from the object files * BSS symbols are taken from the tv.o file * through sub_80EDC60 * sub_80EDCE8 * sub_80EDD78 * through sub_80EDE84 * nomatching sub_80EDE98 * sub_80EDFB4 * sub_80EE104 * sub_80EE104 * sub_80EE184 * sub_80EE2CC * sub_80EE35C * sub_80EE44C * sub_80EE4DC * sub_80EE5A4 * sub_80EE69C * sub_80EE72C * sub_80EE7C0 * sub_80EE818 * sub_80EE8C8 * sub_80EEA70 * sub_80EEB98 * sub_80EEBF4 * through sub_80EED60 * Functions relating to Pokemon News * sub_80EEF6C * GetPriceReduction * IsPriceDiscounted * sub_80EF120 * through sub_80EF370 * sub_80EF40C * HasMixableShowAlreadyBeenSpawnedWithPlayerID * TV_SortPurchasesByQuantity * FindActiveBroadcastByShowType_SetScriptResult * InterviewBefore * through sub_80EF88C * through sub_80EF93C * through sub_80EFA24 * through TV_BernoulliTrial * sub_80EFB58 * sub_80EFBA4 * sub_80EFBDC * through sub_80EFD98 * ChangePokemonNickname * ChangeBoxPokemonNickname * sub_80EFF9C * through player_id_to_dword * CheckForBigMovieOrEmergencyNewsOnTV * GetMomOrDadStringForTVMessage * sub_80F01E8 * sub_80F0358 * sub_80F049C * TV record mixing functions * sub_80F06D0 * sub_80F0708 nonmatching * through sub_80F0B24 * sub_80F0B64 * through sub_80F0C04 * sub_80F0C7C * sub_80F0D60 * sub_80F0E58 * sub_80F0E84 * through sub_80F0F24 * sub_80F0F64 * sub_80F1208 * sub_80F1254 * sub_80F1290 * sub_80F12A4 * sub_80F14F8 * DoTVShowTodaysSmartShopper * DoTVShowTheNameRaterShow * DoTVShowPokemonTodaySuccessfulCapture * DoTVShowPokemonTodayFailedCapture * DoTVShowPokemonFanClubLetter * DoTVShowRecentHappenings * DoTVShowPokemonFanClubOpinions * DoTVShowPokemonNewsMassOutbreak * DoTVShowPokemonContestLiveUpdates * DoTVShowPokemonBattleUpdate * DoTVShow3CheersForPokeblocks * DoTVShowInSearchOfTrainers * Label GabbyAndTyData fields; remove ddump comments from data/text/tv.inc * DoTVShowPokemonAngler * DoTVShowTheWorldOfMasters; update RAM symbols and field names * Decorate static functions * DoTVShowTodaysRivalTrainer; region map enums * TVDewfordTrendWatcherNetworkTextGroup * DoTVShowHoennTreasureInvestigators * DoTVShowFindThatGamer * DoTVShowBreakingNewsTV * DoTVShowSecretBaseVisit * DoTVShowPokemonLotterWinnerFlashReport * DoTVShowThePokemonBattleSeminar * DoTVShowTrainerFanClubSpecial, DoTVShowTrainerFanClub * DoTVShowSpotTheCuties * DoTVShowPokemonNewsBattleFrontier * DoTVShowWhatsNo1InHoennToday * Helpers for DoTVShowSecretBaseSecrets * DoTVShowSecretBaseSecrets * DoTVShowSafariFanClub * Finish decompilation of tv.s * Some renaming * Rename text group pointers * revoke statis; pokenews enums * Labels are number one * Label all TV struct fields * Make data/text/tv.inc more readable * Split data/text/tv.inc * Rename pokenews text pointers * Frontier Symbol constants; indicate static rodata objects with 's' prefix * Fix leading spaces/tabs F*** CLion sometimes * Fix inconsequential warning
2017-10-13 17:09:36 +02:00
gBattleResults.usedMasterBall = TRUE;
2017-09-28 15:34:21 +02:00
}
else
{
if (gBattleResults.catchAttempts[gLastUsedItem - ITEM_ULTRA_BALL] < 0xFF)
gBattleResults.catchAttempts[gLastUsedItem - ITEM_ULTRA_BALL]++;
}
}
if (odds > 254) // mon caught
{
2018-02-06 20:48:02 +01:00
BtlController_EmitBallThrowAnim(0, BALL_3_SHAKES_SUCCESS);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr = BattleScript_SuccessBallThrow;
2018-02-06 23:09:39 +01:00
SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_POKEBALL, &gLastUsedItem);
2017-09-28 15:34:21 +02:00
if (CalculatePlayerPartyCount() == 6)
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
else
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
}
else // mon may be caught, calculate shakes
{
u8 shakes;
odds = Sqrt(Sqrt(16711680 / odds));
odds = 1048560 / odds;
for (shakes = 0; shakes < 4 && Random() < odds; shakes++);
if (gLastUsedItem == ITEM_MASTER_BALL)
shakes = BALL_3_SHAKES_SUCCESS; // why calculate the shakes before that check?
2018-02-06 20:48:02 +01:00
BtlController_EmitBallThrowAnim(0, shakes);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-28 15:34:21 +02:00
if (shakes == BALL_3_SHAKES_SUCCESS) // mon caught, copy of the code above
{
gBattlescriptCurrInstr = BattleScript_SuccessBallThrow;
2018-02-06 23:09:39 +01:00
SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_POKEBALL, &gLastUsedItem);
2017-09-28 15:34:21 +02:00
if (CalculatePlayerPartyCount() == 6)
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
else
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
}
else // not caught
{
gBattleCommunication[MULTISTRING_CHOOSER] = shakes;
gBattlescriptCurrInstr = BattleScript_ShakeBallThrow;
}
}
}
}
static void atkF0_givecaughtmon(void)
2017-09-28 15:34:21 +02:00
{
2018-02-06 23:09:39 +01:00
if (GiveMonToPlayer(&gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker ^ BIT_SIDE]]) != MON_GIVEN_TO_PARTY)
2017-09-28 15:34:21 +02:00
{
if (!sub_813B21C())
{
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
StringCopy(gStringVar1, GetBoxNamePtr(VarGet(VAR_STORAGE_UNKNOWN)));
2018-02-06 23:09:39 +01:00
GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gStringVar2);
2017-09-28 15:34:21 +02:00
}
else
{
StringCopy(gStringVar1, GetBoxNamePtr(VarGet(VAR_STORAGE_UNKNOWN)));
2018-02-06 23:09:39 +01:00
GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gStringVar2);
2017-09-28 15:34:21 +02:00
StringCopy(gStringVar3, GetBoxNamePtr(get_unknown_box_id()));
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
}
2017-11-08 22:20:10 +01:00
if (FlagGet(FLAG_SYS_PC_LANETTE))
2017-09-28 15:34:21 +02:00
gBattleCommunication[MULTISTRING_CHOOSER]++;
}
2018-02-06 23:09:39 +01:00
gBattleResults.caughtMonSpecies = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker ^ BIT_SIDE]], MON_DATA_SPECIES, NULL);
GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gBattleResults.caughtMonNick);
gBattleResults.caughtMonBall = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker ^ BIT_SIDE]], MON_DATA_POKEBALL, NULL);
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr++;
}
static void atkF1_trysetcaughtmondexflags(void)
2017-09-28 15:34:21 +02:00
{
u16 species = GetMonData(&gEnemyParty[0], MON_DATA_SPECIES, NULL);
u32 personality = GetMonData(&gEnemyParty[0], MON_DATA_PERSONALITY, NULL);
if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_CAUGHT))
{
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-28 15:34:21 +02:00
}
else
{
HandleSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_SET_CAUGHT, personality);
gBattlescriptCurrInstr += 5;
}
}
static void atkF2_displaydexinfo(void)
2017-09-28 15:34:21 +02:00
{
u16 species = GetMonData(&gEnemyParty[0], MON_DATA_SPECIES, NULL);
switch (gBattleCommunication[0])
{
case 0:
2018-07-15 13:23:38 +02:00
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, 0);
2017-09-28 15:34:21 +02:00
gBattleCommunication[0]++;
break;
case 1:
if (!gPaletteFade.active)
{
FreeAllWindowBuffers();
gBattleCommunication[TASK_ID] = CreateDexDisplayMonDataTask(SpeciesToNationalPokedexNum(species),
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerTarget].otId,
gBattleMons[gBattlerTarget].personality);
2017-09-28 15:34:21 +02:00
gBattleCommunication[0]++;
}
break;
case 2:
if (!gPaletteFade.active
&& gMain.callback2 == BattleMainCB2
&& !gTasks[gBattleCommunication[TASK_ID]].isActive)
{
SetVBlankCallback(VBlankCB_Battle);
gBattleCommunication[0]++;
}
break;
case 3:
2017-10-01 18:54:01 +02:00
sub_80356D0();
2017-10-01 01:12:42 +02:00
LoadBattleTextboxAndBackground();
2017-09-28 15:34:21 +02:00
gBattle_BG3_X = 0x100;
gBattleCommunication[0]++;
break;
case 4:
if (!IsDma3ManagerBusyWithBgCopy())
{
BeginNormalPaletteFade(0xFFFF, 0, 0x10, 0, 0);
ShowBg(0);
ShowBg(3);
gBattleCommunication[0]++;
}
break;
case 5:
if (!gPaletteFade.active)
gBattlescriptCurrInstr++;
break;
}
}
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;
}
if (flags & WINDOW_CLEAR)
2017-09-28 15:34:21 +02:00
var = 0;
if (flags & WINDOW_x80)
2017-09-28 15:34:21 +02:00
CopyToBgTilemapBufferRect_ChangePalette(1, &var, destX, destY, 1, 1, 0x11);
else
CopyToBgTilemapBufferRect_ChangePalette(0, &var, destX, destY, 1, 1, 0x11);
}
}
}
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);
}
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);
}
static void atkF3_trygivecaughtmonnick(void)
2017-09-28 15:34:21 +02:00
{
switch (gBattleCommunication[MULTIUSE_STATE])
{
case 0:
HandleBattleWindow(0x18, 8, 0x1D, 0xD, 0);
2018-06-17 16:48:58 +02:00
BattlePutTextOnWindow(gText_BattleYesNoChoice, 0xC);
2017-09-28 15:34:21 +02:00
gBattleCommunication[MULTIUSE_STATE]++;
gBattleCommunication[CURSOR_POSITION] = 0;
BattleCreateYesNoCursorAt(0);
2017-09-28 15:34:21 +02:00
break;
case 1:
if (gMain.newKeys & DPAD_UP && gBattleCommunication[CURSOR_POSITION] != 0)
{
PlaySE(SE_SELECT);
BattleDestroyYesNoCursorAt(gBattleCommunication[CURSOR_POSITION]);
2017-09-28 15:34:21 +02:00
gBattleCommunication[CURSOR_POSITION] = 0;
BattleCreateYesNoCursorAt(0);
2017-09-28 15:34:21 +02:00
}
if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[CURSOR_POSITION] == 0)
{
PlaySE(SE_SELECT);
BattleDestroyYesNoCursorAt(gBattleCommunication[CURSOR_POSITION]);
2017-09-28 15:34:21 +02:00
gBattleCommunication[CURSOR_POSITION] = 1;
BattleCreateYesNoCursorAt(1);
2017-09-28 15:34:21 +02:00
}
if (gMain.newKeys & A_BUTTON)
{
PlaySE(SE_SELECT);
if (gBattleCommunication[CURSOR_POSITION] == 0)
{
gBattleCommunication[MULTIUSE_STATE]++;
BeginFastPaletteFade(3);
}
else
{
gBattleCommunication[MULTIUSE_STATE] = 4;
}
}
else if (gMain.newKeys & B_BUTTON)
{
PlaySE(SE_SELECT);
gBattleCommunication[MULTIUSE_STATE] = 4;
}
break;
case 2:
if (!gPaletteFade.active)
{
2018-02-06 23:09:39 +01:00
GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gBattleStruct->caughtMonNick);
2017-09-28 15:34:21 +02:00
FreeAllWindowBuffers();
DoNamingScreen(NAMING_SCREEN_CAUGHT_MON, gBattleStruct->caughtMonNick,
2018-02-06 23:09:39 +01:00
GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker ^ BIT_SIDE]], MON_DATA_SPECIES),
GetMonGender(&gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker ^ BIT_SIDE]]),
GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker ^ BIT_SIDE]], MON_DATA_PERSONALITY, NULL),
2017-09-28 15:34:21 +02:00
BattleMainCB2);
gBattleCommunication[MULTIUSE_STATE]++;
}
break;
case 3:
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active )
{
2018-02-06 23:09:39 +01:00
SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gBattleStruct->caughtMonNick);
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-28 15:34:21 +02:00
}
break;
case 4:
if (CalculatePlayerPartyCount() == 6)
gBattlescriptCurrInstr += 5;
else
2018-03-01 00:59:52 +01:00
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
2017-09-28 15:34:21 +02:00
break;
}
}
static void atkF4_subattackerhpbydmg(void)
{
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerAttacker].hp -= gBattleMoveDamage;
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr++;
}
static void atkF5_removeattackerstatus1(void)
{
2018-02-06 23:09:39 +01:00
gBattleMons[gBattlerAttacker].status1 = 0;
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr++;
}
static void atkF6_finishaction(void)
2017-09-28 15:34:21 +02:00
{
2018-02-06 23:09:39 +01:00
gCurrentActionFuncId = B_ACTION_FINISHED;
2017-09-28 15:34:21 +02:00
}
static void atkF7_finishturn(void)
2017-09-28 15:34:21 +02:00
{
2018-02-06 23:09:39 +01:00
gCurrentActionFuncId = B_ACTION_FINISHED;
2018-02-06 02:46:59 +01:00
gCurrentTurnActionNumber = gBattlersCount;
2017-09-28 15:34:21 +02:00
}
static void atkF8_trainerslideout(void)
2017-09-28 15:34:21 +02:00
{
2018-02-06 02:46:59 +01:00
gActiveBattler = GetBattlerAtPosition(gBattlescriptCurrInstr[1]);
2018-02-06 20:48:02 +01:00
BtlController_EmitTrainerSlideBack(0);
MarkBattlerForControllerExec(gActiveBattler);
2017-09-28 15:34:21 +02:00
gBattlescriptCurrInstr += 2;
}
2018-07-21 21:58:07 +02:00
static void atkF9_settelekinesis(void)
{
if (gStatuses3[gBattlerTarget] & (STATUS3_TELEKINESIS | STATUS3_ROOTED | STATUS3_SMACKED_DOWN)
|| gFieldStatuses & STATUS_FIELD_GRAVITY
|| (gBattleMons[gBattlerTarget].species == SPECIES_DIGLETT || gBattleMons[gBattlerTarget].species == SPECIES_DUGTRIO))
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
gStatuses3[gBattlerTarget] |= STATUS3_TELEKINESIS;
gDisableStructs[gBattlerTarget].telekinesisTimer = 3;
gBattlescriptCurrInstr += 5;
}
}
static void atkFA_swapstatstages(void)
{
u8 statId = T1_READ_8(gBattlescriptCurrInstr + 1);
s8 atkStatStage = gBattleMons[gBattlerAttacker].statStages[statId];
s8 defStatStage = gBattleMons[gBattlerTarget].statStages[statId];
gBattleMons[gBattlerAttacker].statStages[statId] = defStatStage;
gBattleMons[gBattlerTarget].statStages[statId] = atkStatStage;
gBattlescriptCurrInstr += 2;
}
static void atkFB_averagestats(void)
{
u8 statId = T1_READ_8(gBattlescriptCurrInstr + 1);
u16 atkStat = *(u16*)((&gBattleMons[gBattlerAttacker].attack) + (statId - 1));
u16 defStat = *(u16*)((&gBattleMons[gBattlerTarget].attack) + (statId - 1));
u16 average = (atkStat + defStat) / 2;
*(u16*)((&gBattleMons[gBattlerAttacker].attack) + (statId - 1)) = average;
*(u16*)((&gBattleMons[gBattlerTarget].attack) + (statId - 1)) = average;
gBattlescriptCurrInstr += 2;
}
2018-07-22 15:08:32 +02:00
static void atkFC_jumpifoppositegenders(void)
{
u32 atkGender = GetGenderFromSpeciesAndPersonality(gBattleMons[gBattlerAttacker].species, gBattleMons[gBattlerAttacker].personality);
u32 defGender = GetGenderFromSpeciesAndPersonality(gBattleMons[gBattlerTarget].species, gBattleMons[gBattlerTarget].personality);
if ((atkGender == MON_MALE && defGender == MON_FEMALE) || (atkGender == MON_FEMALE && defGender == MON_MALE))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
else
gBattlescriptCurrInstr += 5;
}
2018-07-22 21:05:12 +02:00
static void atkFD_trygetbaddreamstarget(void)
{
u8 badDreamsMonSide = GetBattlerSide(gBattlerAttacker);
for (;gBattlerTarget < gBattlersCount; gBattlerTarget++)
{
if (GetBattlerSide(gBattlerTarget) == badDreamsMonSide)
continue;
if (gBattleMons[gBattlerTarget].status1 & STATUS1_SLEEP && IsBattlerAlive(gBattlerTarget))
break;
}
if (gBattlerTarget >= gBattlersCount)
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
else
gBattlescriptCurrInstr += 5;
}
2018-07-23 22:18:56 +02:00
static void atkFE_tryworryseed(void)
{
switch (gBattleMons[gBattlerTarget].ability)
{
case ABILITY_INSOMNIA:
case ABILITY_MULTITYPE:
case ABILITY_TRUANT:
case ABILITY_STANCE_CHANGE:
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
break;
default:
gBattleMons[gBattlerTarget].ability = ABILITY_INSOMNIA;
gBattlescriptCurrInstr += 5;
break;
}
}
static void atkFF_metalburstdamagecalculator(void)
{
u8 sideAttacker = GetBattlerSide(gBattlerAttacker);
u8 sideTarget = 0;
if (gProtectStructs[gBattlerAttacker].physicalDmg
&& sideAttacker != (sideTarget = GetBattlerSide(gProtectStructs[gBattlerAttacker].physicalBattlerId))
&& gBattleMons[gProtectStructs[gBattlerAttacker].physicalBattlerId].hp)
{
gBattleMoveDamage = gProtectStructs[gBattlerAttacker].physicalDmg * 150 / 100;
if (gSideTimers[sideTarget].followmeTimer && gBattleMons[gSideTimers[sideTarget].followmeTarget].hp)
gBattlerTarget = gSideTimers[sideTarget].followmeTarget;
else
gBattlerTarget = gProtectStructs[gBattlerAttacker].physicalBattlerId;
gBattlescriptCurrInstr += 5;
}
else if (gProtectStructs[gBattlerAttacker].specialDmg
&& sideAttacker != (sideTarget = GetBattlerSide(gProtectStructs[gBattlerAttacker].specialBattlerId))
&& gBattleMons[gProtectStructs[gBattlerAttacker].specialBattlerId].hp)
{
gBattleMoveDamage = gProtectStructs[gBattlerAttacker].specialDmg * 150 / 100;
if (gSideTimers[sideTarget].followmeTimer && gBattleMons[gSideTimers[sideTarget].followmeTarget].hp)
gBattlerTarget = gSideTimers[sideTarget].followmeTarget;
else
gBattlerTarget = gProtectStructs[gBattlerAttacker].specialBattlerId;
gBattlescriptCurrInstr += 5;
}
else
{
gSpecialStatuses[gBattlerAttacker].flag20 = 1;
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}