From 9c94eb6140a0752d5bef391c3679c68af14d5404 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Thu, 16 Sep 2021 10:24:32 -0400 Subject: [PATCH 1/4] but it failed check for rototiller --- asm/macros/battle_script.inc | 10 +++++ data/battle_scripts_1.s | 40 +++++++++++-------- include/battle.h | 1 + include/constants/battle_script_commands.h | 2 + src/battle_script_commands.c | 45 ++++++++++++++++++++++ 5 files changed, 83 insertions(+), 15 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 662bfbf2f5..a2d9407370 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1776,6 +1776,16 @@ .macro pickpocketsteal various 0, VARIOUS_PICKPOCKET .endm + + .macro getrototillertargets ptr:req + various BS_ATTACKER, VARIOUS_GET_ROTOTILLER_TARGETS + .4byte \ptr + .endm + + .macro jumpifnotrototilleraffected battler:req, ptr:req + various \battler, VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED + .4byte \ptr + .endm @ helpful macros .macro setstatchanger stat:req, stages:req, down:req diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 2d6db5a289..177c657ce3 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -814,27 +814,28 @@ BattleScript_FlowerShieldMoveTargetEnd: moveendto MOVEEND_NEXT_TARGET jumpifnexttargetvalid BattleScript_FlowerShieldLoop end + +BattleScript_RototillerRet:: + + return BattleScript_EffectRototiller: attackcanceler attackstring ppreduce - selectfirstvalidtarget -BattleScript_RototillerLoop: - movevaluescleanup - jumpifnotgrounded BS_TARGET, BattleScript_RototillerNoEffect - jumpiftype BS_TARGET, TYPE_GRASS, BattleScript_RototillerLoop2 -BattleScript_RototillerNoEffect: - pause B_WAIT_TIME_SHORT - printstring STRINGID_NOEFFECTONTARGET - waitmessage B_WAIT_TIME_LONG - goto BattleScript_RototillerMoveTargetEnd -BattleScript_RototillerLoop2: - jumpifstat BS_TARGET, CMP_LESS_THAN, STAT_ATK, MAX_STAT_STAGE, BattleScript_RototillerDoMoveAnim - jumpifstat BS_TARGET, CMP_EQUAL, STAT_SPATK, MAX_STAT_STAGE, BattleScript_RototillerCantRaiseMultipleStats -BattleScript_RototillerDoMoveAnim:: + getrototillertargets BattleScript_ButItFailed + @ at least one battler is affected attackanimation waitanimation + savetarget + setbyte gBattlerTarget, 0 +BattleScript_RototillerLoop: + movevaluescleanup + jumpifstat BS_TARGET, CMP_LESS_THAN, STAT_ATK, MAX_STAT_STAGE, BattleScript_RototillerCheckAffected + jumpifstat BS_TARGET, CMP_EQUAL, STAT_SPATK, MAX_STAT_STAGE, BattleScript_RototillerCantRaiseMultipleStats +BattleScript_RototillerCheckAffected: + jumpifnotrototilleraffected BS_TARGET, BattleScript_RototillerNoEffect +BattleScript_RototillerAffected: setbyte sSTAT_ANIM_PLAYED, FALSE playstatchangeanimation BS_TARGET, BIT_ATK | BIT_SPATK, 0 setstatchanger STAT_ATK, 1, FALSE @@ -850,13 +851,22 @@ BattleScript_RototillerTrySpAtk:: waitmessage B_WAIT_TIME_LONG BattleScript_RototillerMoveTargetEnd: moveendto MOVEEND_NEXT_TARGET - jumpifnexttargetvalid BattleScript_RototillerLoop + addbyte gBattlerTarget, 1 + jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_RototillerLoop end + BattleScript_RototillerCantRaiseMultipleStats: + copybyte gBattlerAttacker, gBattlerTarget printstring STRINGID_STATSWONTINCREASE2 waitmessage B_WAIT_TIME_LONG goto BattleScript_RototillerMoveTargetEnd +BattleScript_RototillerNoEffect: + pause B_WAIT_TIME_SHORT + printstring STRINGID_NOEFFECTONTARGET + waitmessage B_WAIT_TIME_LONG + goto BattleScript_RototillerMoveTargetEnd + BattleScript_EffectBestow: attackcanceler accuracycheck BattleScript_PrintMoveMissed, NO_ACC_CALC_CHECK_LOCK_ON diff --git a/include/battle.h b/include/battle.h index 3fbefe55bd..576884d815 100644 --- a/include/battle.h +++ b/include/battle.h @@ -169,6 +169,7 @@ struct SpecialStatus u8 instructedChosenTarget:3; u8 berryReduced:1; u8 gemBoost:1; + u8 rototillerAffected:1; // to be affected by rototiller u8 gemParam; u8 damagedMons:4; // Mons that have been damaged directly by using a move, includes substitute. u8 dancerUsedMove:1; diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 7e7bb6ca9e..6c5e3872ae 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -174,6 +174,8 @@ #define VARIOUS_TOTEM_BOOST 103 #define VARIOUS_TRY_ACTIVATE_GRIM_NEIGH 104 #define VARIOUS_MOVEEND_ITEM_EFFECTS 105 +#define VARIOUS_GET_ROTOTILLER_TARGETS 106 +#define VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED 107 // Cmd_manipulatedamage #define DMG_CHANGE_SIGN 0 diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 05702aec6b..a719db5506 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -7246,6 +7246,21 @@ static u32 GetHighestStatId(u32 battlerId) return highestId; } +static bool32 IsRototillerAffected(u32 battlerId) +{ + if (!IsBattlerAlive(battlerId)) + return FALSE; + if (!IsBattlerGrounded(battlerId)) + return FALSE; // Only grounded battlers affected + if (!IS_BATTLER_OF_TYPE(battlerId, TYPE_GRASS)) + return FALSE; // Only grass types affected + if (gStatuses3[battlerId] & STATUS3_SEMI_INVULNERABLE) + return FALSE; // Rototiller doesn't affected semi-invulnerable battlers + //if (!CompareStat(battlerId, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN) && !CompareStat(battlerId, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN)) + //return FALSE; // Battler unaffected if atk and spatk are maxed + return TRUE; +} + static void Cmd_various(void) { struct Pokemon *mon; @@ -8498,6 +8513,36 @@ static void Cmd_various(void) if (ItemBattleEffects(1, gActiveBattler, FALSE)) return; break; + case VARIOUS_GET_ROTOTILLER_TARGETS: + // Gets the battlers to be affected by rototiller. If there are none, print 'But it failed!' + { + u32 count = 0; + for (i = 0; i < gBattlersCount; i++) + { + if (IsRototillerAffected(i)) + { + gSpecialStatuses[i].rototillerAffected = 1; + count++; + } + } + + if (count == 0) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); // Rototiller fails + else + gBattlescriptCurrInstr += 7; + } + return; + case VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED: + if (gSpecialStatuses[gActiveBattler].rototillerAffected) + { + gSpecialStatuses[gActiveBattler].rototillerAffected = 0; + gBattlescriptCurrInstr += 7; + } + else + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); // Unaffected by rototiller - print STRINGID_NOEFFECTONTARGET + } + return; } gBattlescriptCurrInstr += 3; From aac7ae359518c3610fb02f91b05b244172208944 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Thu, 16 Sep 2021 10:45:33 -0400 Subject: [PATCH 2/4] add MOVE_TARGET_ALL_BATTLERS --- include/constants/battle.h | 2 + src/battle_controller_player.c | 84 ++++++++++++++++++++++++++++------ src/data/battle_moves.h | 4 +- 3 files changed, 74 insertions(+), 16 deletions(-) diff --git a/include/constants/battle.h b/include/constants/battle.h index 73d5c3debe..53e933944a 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -379,4 +379,6 @@ #define MOVE_TARGET_OPPONENTS_FIELD 0x40 #define MOVE_TARGET_ALLY 0x80 +#define MOVE_TARGET_ALL_BATTLERS (MOVE_TARGET_BOTH | MOVE_TARGET_OPPONENTS_FIELD) + #endif // GUARD_CONSTANTS_BATTLE_H diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 841e303270..70a8f51e9d 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -485,6 +485,19 @@ static void HandleInputChooseTarget(void) } } +static void HideAllTargets(void) +{ + s32 i; + for (i = 0; i < MAX_BATTLERS_COUNT; i++) + { + if (IsBattlerAlive(i) && gBattleSpritesDataPtr->healthBoxesData[i].healthboxIsBouncing) + { + gSprites[gBattlerSpriteIds[i]].callback = SpriteCb_HideAsMoveTarget; + EndBounceEffect(i, BOUNCE_HEALTHBOX); + } + } +} + static void HideShownTargets(void) { s32 i; @@ -498,6 +511,34 @@ static void HideShownTargets(void) } } +static void HandleInputShowEntireFieldTargets(void) +{ + if (JOY_HELD(DPAD_ANY) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A) + gPlayerDpadHoldFrames++; + else + gPlayerDpadHoldFrames = 0; + + if (JOY_NEW(A_BUTTON)) + { + PlaySE(SE_SELECT); + HideAllTargets(); + if (gBattleStruct->mega.playerSelect) + BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8)); + else + BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8)); + HideMegaTriggerSprite(); + PlayerBufferExecCompleted(); + } + else if (gMain.newKeys & B_BUTTON || gPlayerDpadHoldFrames > 59) + { + PlaySE(SE_SELECT); + HideAllTargets(); + gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseMove; + DoBounceEffect(gActiveBattler, BOUNCE_HEALTHBOX, 7, 1); + DoBounceEffect(gActiveBattler, BOUNCE_MON, 7, 1); + } +} + static void HandleInputShowTargets(void) { if (JOY_HELD(DPAD_ANY) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A) @@ -589,27 +630,39 @@ static void HandleInputChooseMove(void) } // Show all available targets for multi-target moves - if (B_SHOW_TARGETS && moveTarget & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)) + if (B_SHOW_TARGETS) { - TryShowAsTarget(gMultiUsePlayerCursor); - TryShowAsTarget(BATTLE_PARTNER(gMultiUsePlayerCursor)); - if (moveTarget & MOVE_TARGET_FOES_AND_ALLY) - TryShowAsTarget(BATTLE_PARTNER(gActiveBattler)); - canSelectTarget = 2; + if ((moveTarget & MOVE_TARGET_ALL_BATTLERS) == MOVE_TARGET_ALL_BATTLERS) + { + u32 i = 0; + for (i = 0; i < gBattlersCount; i++) + TryShowAsTarget(i); + + canSelectTarget = 3; + } + else if (moveTarget & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)) + { + TryShowAsTarget(gMultiUsePlayerCursor); + TryShowAsTarget(BATTLE_PARTNER(gMultiUsePlayerCursor)); + if (moveTarget & MOVE_TARGET_FOES_AND_ALLY) + TryShowAsTarget(BATTLE_PARTNER(gActiveBattler)); + canSelectTarget = 2; + } } } - - if (canSelectTarget == 0) + + switch (canSelectTarget) { + case 0: + default: if (gBattleStruct->mega.playerSelect) BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8)); else BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8)); HideMegaTriggerSprite(); PlayerBufferExecCompleted(); - } - else if (canSelectTarget == 1) - { + break; + case 1: gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseTarget; if (moveTarget & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED)) @@ -620,10 +673,13 @@ static void HandleInputChooseMove(void) gMultiUsePlayerCursor = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = SpriteCb_ShowAsMoveTarget; - } - else - { + break; + case 2: gBattlerControllerFuncs[gActiveBattler] = HandleInputShowTargets; + break; + case 3: // Entire field + gBattlerControllerFuncs[gActiveBattler] = HandleInputShowEntireFieldTargets; + break; } } else if (JOY_NEW(B_BUTTON) || gPlayerDpadHoldFrames > 59) diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index 657341b5ef..a63aca114c 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -8838,7 +8838,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 0, .pp = 10, .secondaryEffectChance = 0, - .target = MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .priority = 0, .flags = 0, .split = SPLIT_STATUS, @@ -9083,7 +9083,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 0, .pp = 10, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER | MOVE_TARGET_FOES_AND_ALLY, + .target = MOVE_TARGET_ALL_BATTLERS, .priority = 0, .flags = 0, .split = SPLIT_STATUS, From 11f4f0f08e42a2d6b9c0ba56b9938e755601ea7e Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Wed, 6 Oct 2021 14:41:48 -0400 Subject: [PATCH 3/4] update move data to those that target all battlers --- src/data/battle_moves.h | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index a63aca114c..98b30951e4 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -1789,7 +1789,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 0, .pp = 30, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .priority = 0, .flags = FLAG_PROTECT_AFFECTED, .split = SPLIT_STATUS, @@ -3100,7 +3100,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 0, .pp = 5, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .priority = 0, .flags = FLAG_SOUND, .split = SPLIT_STATUS, @@ -3204,7 +3204,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 0, .pp = 10, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .priority = 0, .flags = 0, .split = SPLIT_STATUS, @@ -3804,7 +3804,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 0, .pp = 5, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .priority = 0, .flags = 0, .split = SPLIT_STATUS, @@ -3818,7 +3818,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 0, .pp = 5, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .priority = 0, .flags = 0, .split = SPLIT_STATUS, @@ -4125,7 +4125,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 0, .pp = 10, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .priority = 0, .flags = FLAG_PROTECT_AFFECTED, .split = SPLIT_STATUS, @@ -4768,7 +4768,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 100, .pp = 15, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .priority = 0, .flags = 0, .split = SPLIT_STATUS, @@ -5504,7 +5504,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 100, .pp = 15, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .priority = 0, .flags = 0, .split = SPLIT_STATUS, @@ -5661,7 +5661,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 0, .pp = 5, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .priority = 0, .flags = 0, .split = SPLIT_STATUS, @@ -6875,7 +6875,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 0, .pp = 5, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .priority = -7, .flags = FLAG_MIRROR_MOVE_AFFECTED, .split = SPLIT_STATUS, @@ -7478,7 +7478,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 0, .pp = 10, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .flags = FLAG_MIRROR_MOVE_AFFECTED, .split = SPLIT_STATUS, }, @@ -7570,7 +7570,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 0, .pp = 10, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .flags = FLAG_MIRROR_MOVE_AFFECTED, .split = SPLIT_STATUS, }, @@ -8932,7 +8932,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 0, .pp = 25, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .priority = 1, .flags = 0, .split = SPLIT_STATUS, @@ -9097,7 +9097,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 0, .pp = 10, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .priority = 0, .flags = 0, .split = SPLIT_STATUS, @@ -9111,7 +9111,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 0, .pp = 10, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .priority = 0, .flags = 0, .split = SPLIT_STATUS, @@ -9195,7 +9195,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 0, .pp = 10, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .priority = 0, .flags = FLAG_MIRROR_MOVE_AFFECTED, .split = SPLIT_STATUS, @@ -9445,7 +9445,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 0, .pp = 10, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .priority = 0, .flags = 0, .split = SPLIT_STATUS, @@ -9965,7 +9965,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 0, .pp = 10, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .priority = 0, .flags = 0, .split = SPLIT_STATUS, @@ -10848,7 +10848,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 0, .pp = 10, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .priority = 0, .flags = 0, .split = SPLIT_STATUS, @@ -10904,7 +10904,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 100, .pp = 10, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_ALL_BATTLERS, .priority = 0, .flags = FLAG_MIRROR_MOVE_AFFECTED, .split = SPLIT_STATUS, From fcada4fcad924a905560a726beb49733c3278382 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Sun, 10 Oct 2021 19:54:17 -0400 Subject: [PATCH 4/4] handle rototiller + prankster --- data/battle_scripts_1.s | 4 ---- include/battle_util.h | 2 +- src/battle_script_commands.c | 19 ++++++++++--------- src/battle_util.c | 25 +++++++++++++++---------- 4 files changed, 26 insertions(+), 24 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 3d9c66bd68..9ed0d1fcc9 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -942,10 +942,6 @@ BattleScript_FlowerShieldMoveTargetEnd: jumpifnexttargetvalid BattleScript_FlowerShieldLoop end -BattleScript_RototillerRet:: - - return - BattleScript_EffectRototiller: attackcanceler attackstring diff --git a/include/battle_util.h b/include/battle_util.h index 612a2e6d9a..43f66db6b7 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -152,7 +152,7 @@ bool32 CompareStat(u8 battlerId, u8 statId, u8 cmpTo, u8 cmpKind); bool32 TryRoomService(u8 battlerId); void BufferStatChange(u8 battlerId, u8 statId, u8 stringId); void DoBurmyFormChange(u32 monId); -bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef); +bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget); // ability checks bool32 IsRolePlayBannedAbilityAtk(u16 ability); diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 339e5bd996..e70b990eb3 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1416,7 +1416,7 @@ static void Cmd_attackcanceler(void) gProtectStructs[gBattlerTarget].bounceMove = 0; gProtectStructs[gBattlerTarget].usesBouncedMove = 1; gBattleCommunication[MULTISTRING_CHOOSER] = 0; - if (BlocksPrankster(gCurrentMove, gBattlerTarget, gBattlerAttacker)) + if (BlocksPrankster(gCurrentMove, gBattlerTarget, gBattlerAttacker, TRUE)) { // Opponent used a prankster'd magic coat -> reflected status move should fail against a dark-type attacker gBattlerTarget = gBattlerAttacker; @@ -7345,8 +7345,8 @@ static bool32 IsRototillerAffected(u32 battlerId) return FALSE; // Only grass types affected if (gStatuses3[battlerId] & STATUS3_SEMI_INVULNERABLE) return FALSE; // Rototiller doesn't affected semi-invulnerable battlers - //if (!CompareStat(battlerId, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN) && !CompareStat(battlerId, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN)) - //return FALSE; // Battler unaffected if atk and spatk are maxed + if (BlocksPrankster(MOVE_ROTOTILLER, gBattlerAttacker, battlerId, FALSE)) + return FALSE; return TRUE; } @@ -8757,21 +8757,22 @@ static void Cmd_various(void) } gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; // remove the terrain break; - case VARIOUS_JUMP_IF_PRANKSTER_BLOCKED: - if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gActiveBattler)) + case VARIOUS_JUMP_IF_PRANKSTER_BLOCKED: + if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gActiveBattler, TRUE)) gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); else gBattlescriptCurrInstr += 7; return; - case VARIOUS_GET_ROTOTILLER_TARGETS: + case VARIOUS_GET_ROTOTILLER_TARGETS: // Gets the battlers to be affected by rototiller. If there are none, print 'But it failed!' { u32 count = 0; for (i = 0; i < gBattlersCount; i++) { + gSpecialStatuses[i].rototillerAffected = FALSE; if (IsRototillerAffected(i)) { - gSpecialStatuses[i].rototillerAffected = 1; + gSpecialStatuses[i].rototillerAffected = TRUE; count++; } } @@ -8785,7 +8786,7 @@ static void Cmd_various(void) case VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED: if (gSpecialStatuses[gActiveBattler].rototillerAffected) { - gSpecialStatuses[gActiveBattler].rototillerAffected = 0; + gSpecialStatuses[gActiveBattler].rototillerAffected = FALSE; gBattlescriptCurrInstr += 7; } else @@ -10954,7 +10955,7 @@ static void Cmd_trysetperishsong(void) { if (gStatuses3[i] & STATUS3_PERISH_SONG || GetBattlerAbility(i) == ABILITY_SOUNDPROOF - || BlocksPrankster(gCurrentMove, gBattlerAttacker, i)) + || BlocksPrankster(gCurrentMove, gBattlerAttacker, i, TRUE)) { notAffectedCount++; } diff --git a/src/battle_util.c b/src/battle_util.c index a709aaf9e9..40a100796e 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -3421,7 +3421,7 @@ u8 AtkCanceller_UnableToUseMove(void) gBattleStruct->atkCancellerTracker++; break; case CANCELLER_PRANKSTER: - if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gBattlerTarget) + if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gBattlerTarget, TRUE) && !(IS_MOVE_STATUS(gCurrentMove) && GetBattlerAbility(gBattlerTarget) == ABILITY_MAGIC_BOUNCE)) { if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE) || !(gBattleMoves[gCurrentMove].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))) @@ -9344,16 +9344,21 @@ void DoBurmyFormChange(u32 monId) } } -bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef) +bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget) { #if B_PRANKSTER_DARK_TYPES >= GEN_7 - if (gProtectStructs[battlerPrankster].pranksterElevated - && GetBattlerSide(battlerPrankster) != GetBattlerSide(battlerDef) - && !(gBattleMoves[gCurrentMove].target & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_DEPENDS)) // Don't block hazards, assist-type moves - && IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK) // Only Dark-types can block Prankster'd - && !(gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE)) - return TRUE; - else - #endif + if (!gProtectStructs[battlerPrankster].pranksterElevated) return FALSE; + if (GetBattlerSide(battlerPrankster) == GetBattlerSide(battlerDef)) + return FALSE; + if (checkTarget && (gBattleMoves[move].target & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_DEPENDS))) + return FALSE; + if (!IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK)) + return FALSE; + if (gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE) + return FALSE; + + return TRUE; + #endif + return FALSE; }