From beb126b534a0df8af3ffb9d105b10793401665ac Mon Sep 17 00:00:00 2001 From: MissingNoL Date: Sat, 12 Jun 2021 13:58:54 -0700 Subject: [PATCH 01/58] Implemented Zippy Zap's effect --- data/battle_scripts_1.s | 5 +++++ include/constants/battle_move_effects.h | 3 ++- src/data/battle_moves.h | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 11616e300..39a5ddca7 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -369,6 +369,11 @@ gBattleScriptsForMoveEffects:: @ 82D86A8 .4byte BattleScript_EffectSleepHit .4byte BattleScript_EffectAttackerDefenseDownHit .4byte BattleScript_EffectBodyPress + .4byte BattleScript_EffectEvasionUpHit + +BattleScript_EffectEvasionUpHit: + setmoveeffect MOVE_EFFECT_EVS_PLUS_1 | MOVE_EFFECT_AFFECTS_USER + goto BattleScript_EffectHit BattleScript_EffectAttackerDefenseDownHit: setmoveeffect MOVE_EFFECT_DEF_MINUS_1 | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index 6174ca496..3e831cfd3 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -353,7 +353,8 @@ #define EFFECT_SLEEP_HIT 347 // Relic Song #define EFFECT_ATTACKER_DEFENSE_DOWN_HIT 348 #define EFFECT_BODY_PRESS 349 +#define EFFECT_EVASION_UP_HIT 350 -#define NUM_BATTLE_MOVE_EFFECTS 350 +#define NUM_BATTLE_MOVE_EFFECTS 351 #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index db02083b0..41aad29f6 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -10456,7 +10456,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = { #if B_UPDATED_MOVE_DATA >= GEN_8 .power = 80, - .effect = EFFECT_PLACEHOLDER, // TODO: EFFECT_EVASION_UP_HIT + .effect = EFFECT_EVASION_UP_HIT, // TODO: EFFECT_EVASION_UP_HIT .pp = 10, .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, #else From 610b18bfdbfbf6564978385e37a84989d7e9c928 Mon Sep 17 00:00:00 2001 From: MissingNoL Date: Sat, 12 Jun 2021 14:27:50 -0700 Subject: [PATCH 02/58] Implemented Double Iron Bash's effect --- data/battle_scripts_1.s | 11 +++++++++++ include/constants/battle_move_effects.h | 3 ++- src/data/battle_moves.h | 4 ++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 39a5ddca7..d41231dcd 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -370,6 +370,17 @@ gBattleScriptsForMoveEffects:: @ 82D86A8 .4byte BattleScript_EffectAttackerDefenseDownHit .4byte BattleScript_EffectBodyPress .4byte BattleScript_EffectEvasionUpHit + .4byte BattleScript_EffectDoubleIronBash + +BattleScript_EffectDoubleIronBash: + attackcanceler + accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE + attackstring + ppreduce + setmultihitcounter 2 + initmultihitstring + sethword sMULTIHIT_EFFECT, MOVE_EFFECT_FLINCH + goto BattleScript_MultiHitLoop BattleScript_EffectEvasionUpHit: setmoveeffect MOVE_EFFECT_EVS_PLUS_1 | MOVE_EFFECT_AFFECTS_USER diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index 3e831cfd3..d056edf6a 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -354,7 +354,8 @@ #define EFFECT_ATTACKER_DEFENSE_DOWN_HIT 348 #define EFFECT_BODY_PRESS 349 #define EFFECT_EVASION_UP_HIT 350 +#define EFFECT_DOUBLE_IRON_BASH 351 -#define NUM_BATTLE_MOVE_EFFECTS 351 +#define NUM_BATTLE_MOVE_EFFECTS 352 #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index 41aad29f6..4a917dc9b 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -10456,7 +10456,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = { #if B_UPDATED_MOVE_DATA >= GEN_8 .power = 80, - .effect = EFFECT_EVASION_UP_HIT, // TODO: EFFECT_EVASION_UP_HIT + .effect = EFFECT_EVASION_UP_HIT, .pp = 10, .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, #else @@ -10716,7 +10716,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = #else .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_DMG_MINIMIZE | FLAG_IRON_FIST_BOOST | FLAG_SHEER_FORCE_BOOST, #endif - .effect = EFFECT_PLACEHOLDER, //TODO (EFFECT_FLINCH_HIT + EFFECT_DOUBLE_HIT) + .effect = EFFECT_DOUBLE_IRON_BASH, .power = 60, .type = TYPE_STEEL, .accuracy = 100, From 721dbe917849039df29644729aa879256b24fe16 Mon Sep 17 00:00:00 2001 From: MissingNoL Date: Sat, 12 Jun 2021 18:01:35 -0700 Subject: [PATCH 03/58] Implemented all PLG effects --- data/battle_scripts_1.s | 31 +++++++++++++++++++++++++ include/constants/battle_move_effects.h | 7 +++++- src/data/battle_moves.h | 10 ++++---- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index d41231dcd..1343b0523 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -371,6 +371,37 @@ gBattleScriptsForMoveEffects:: @ 82D86A8 .4byte BattleScript_EffectBodyPress .4byte BattleScript_EffectEvasionUpHit .4byte BattleScript_EffectDoubleIronBash + .4byte BattleScript_EffectGlitzyGlow + .4byte BattleScript_EffectBaddyBad + .4byte BattleScript_EffectSappySeed + .4byte BattleScript_EffectFreezyFrost + .4byte BattleScript_EffectSparklySwirl + +BattleScript_EffectSparklySwirl: + healpartystatus + waitstate + updatestatusicon BS_ATTACKER_WITH_PARTNER + waitstate + goto BattleScript_EffectHit + +BattleScript_EffectFreezyFrost: + normalisebuffs + goto BattleScript_EffectHit + +BattleScript_EffectSappySeed: + jumpifstatus3 BS_TARGET, STATUS3_LEECHSEED, BattleScript_EffectHit + setseeded + goto BattleScript_EffectHit + +BattleScript_EffectBaddyBad: + jumpifsideaffecting BS_ATTACKER, SIDE_STATUS_REFLECT, BattleScript_EffectHit + setreflect + goto BattleScript_EffectHit + +BattleScript_EffectGlitzyGlow: + jumpifsideaffecting BS_ATTACKER, SIDE_STATUS_LIGHTSCREEN, BattleScript_EffectHit + setlightscreen + goto BattleScript_EffectHit BattleScript_EffectDoubleIronBash: attackcanceler diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index d056edf6a..884a83d60 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -355,7 +355,12 @@ #define EFFECT_BODY_PRESS 349 #define EFFECT_EVASION_UP_HIT 350 #define EFFECT_DOUBLE_IRON_BASH 351 +#define EFFECT_GLITZY_GLOW 352 +#define EFFECT_BADDY_BAD 353 +#define EFFECT_SAPPY_SEED 354 +#define EFFECT_FREEZY_FROST 355 +#define EFFECT_SPARKLY_SWIRL 356 -#define NUM_BATTLE_MOVE_EFFECTS 352 +#define NUM_BATTLE_MOVE_EFFECTS 357 #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index 4a917dc9b..df33efb21 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -10599,7 +10599,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 100, .flags = FLAG_PROTECT_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, #endif - .effect = EFFECT_PLACEHOLDER, //TODO (Light Screen + Hit) + .effect = EFFECT_GLITZY_GLOW, .type = TYPE_PSYCHIC, .pp = 15, .secondaryEffectChance = 0, @@ -10619,7 +10619,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .accuracy = 100, .flags = FLAG_PROTECT_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, #endif - .effect = EFFECT_PLACEHOLDER, //TODO (Reflect + Hit) + .effect = EFFECT_BADDY_BAD, .type = TYPE_DARK, .pp = 15, .secondaryEffectChance = 0, @@ -10641,7 +10641,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .pp = 15, .flags = FLAG_PROTECT_AFFECTED | FLAG_MAGIC_COAT_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, #endif - .effect = EFFECT_PLACEHOLDER, //TODO (Leech Seed + Hit) + .effect = EFFECT_SAPPY_SEED, .type = TYPE_GRASS, .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, @@ -10662,7 +10662,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .pp = 15, .flags = FLAG_PROTECT_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, #endif - .effect = EFFECT_PLACEHOLDER, //TODO (Haze + Hit) + .effect = EFFECT_FREEZY_FROST, .type = TYPE_ICE, .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, @@ -10683,7 +10683,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .pp = 15, .flags = FLAG_PROTECT_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, #endif - .effect = EFFECT_PLACEHOLDER, //TODO (Heal Bell + Hit) + .effect = EFFECT_SPARKLY_SWIRL, .type = TYPE_FAIRY, .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, From 32c8de5eca8b2ee46917d5bc6fb4988fb0a2224c Mon Sep 17 00:00:00 2001 From: MissingNoL Date: Sat, 12 Jun 2021 21:23:56 -0700 Subject: [PATCH 04/58] Finished! --- data/battle_scripts_1.s | 114 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 109 insertions(+), 5 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 1343b0523..13b8d720f 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -378,30 +378,134 @@ gBattleScriptsForMoveEffects:: @ 82D86A8 .4byte BattleScript_EffectSparklySwirl BattleScript_EffectSparklySwirl: + attackcanceler + accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE + attackstring + ppreduce + critcalc + damagecalc + adjustdamage + attackanimation + waitanimation + effectivenesssound + hitanimation BS_TARGET + waitstate + healthbarupdate BS_TARGET + datahpupdate BS_TARGET + critmessage + waitmessage B_WAIT_TIME_LONG + resultmessage + waitmessage B_WAIT_TIME_LONG + tryfaintmon BS_TARGET, FALSE, NULL healpartystatus waitstate updatestatusicon BS_ATTACKER_WITH_PARTNER waitstate - goto BattleScript_EffectHit + goto BattleScript_MoveEnd BattleScript_EffectFreezyFrost: + attackcanceler + accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE + attackstring + ppreduce + critcalc + damagecalc + adjustdamage + attackanimation + waitanimation + effectivenesssound + hitanimation BS_TARGET + waitstate + healthbarupdate BS_TARGET + datahpupdate BS_TARGET + critmessage + waitmessage B_WAIT_TIME_LONG + resultmessage + waitmessage B_WAIT_TIME_LONG + tryfaintmon BS_TARGET, FALSE, NULL normalisebuffs - goto BattleScript_EffectHit + printstring STRINGID_STATCHANGESGONE + waitmessage B_WAIT_TIME_LONG + goto BattleScript_MoveEnd BattleScript_EffectSappySeed: jumpifstatus3 BS_TARGET, STATUS3_LEECHSEED, BattleScript_EffectHit + attackcanceler + accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE + attackstring + ppreduce + critcalc + damagecalc + adjustdamage + attackanimation + waitanimation + effectivenesssound + hitanimation BS_TARGET + waitstate + healthbarupdate BS_TARGET + datahpupdate BS_TARGET + critmessage + waitmessage B_WAIT_TIME_LONG + resultmessage + waitmessage B_WAIT_TIME_LONG + tryfaintmon BS_TARGET, FALSE, NULL + jumpifhasnohp BS_TARGET, BattleScript_MoveEnd setseeded - goto BattleScript_EffectHit + printfromtable gLeechSeedStringIds + waitmessage B_WAIT_TIME_LONG + goto BattleScript_MoveEnd BattleScript_EffectBaddyBad: jumpifsideaffecting BS_ATTACKER, SIDE_STATUS_REFLECT, BattleScript_EffectHit + attackcanceler + accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE + attackstring + ppreduce + critcalc + damagecalc + adjustdamage + attackanimation + waitanimation + effectivenesssound + hitanimation BS_TARGET + waitstate + healthbarupdate BS_TARGET + datahpupdate BS_TARGET + critmessage + waitmessage B_WAIT_TIME_LONG + resultmessage + waitmessage B_WAIT_TIME_LONG + tryfaintmon BS_TARGET, FALSE, NULL setreflect - goto BattleScript_EffectHit + printfromtable gReflectLightScreenSafeguardStringIds + waitmessage B_WAIT_TIME_LONG + goto BattleScript_MoveEnd BattleScript_EffectGlitzyGlow: jumpifsideaffecting BS_ATTACKER, SIDE_STATUS_LIGHTSCREEN, BattleScript_EffectHit + attackcanceler + accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE + attackstring + ppreduce + critcalc + damagecalc + adjustdamage + attackanimation + waitanimation + effectivenesssound + hitanimation BS_TARGET + waitstate + healthbarupdate BS_TARGET + datahpupdate BS_TARGET + critmessage + waitmessage B_WAIT_TIME_LONG + resultmessage + waitmessage B_WAIT_TIME_LONG + tryfaintmon BS_TARGET, FALSE, NULL setlightscreen - goto BattleScript_EffectHit + printfromtable gReflectLightScreenSafeguardStringIds + waitmessage B_WAIT_TIME_LONG + goto BattleScript_MoveEnd BattleScript_EffectDoubleIronBash: attackcanceler From c06029bc721119b0efd6e26c24a3f77772dfd77b Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 25 Jun 2021 13:37:59 -0600 Subject: [PATCH 05/58] add last used ball --- graphics/battle_interface/ability_pop_up.pal | 19 ++ graphics/battle_interface/last_used_ball.png | Bin 0 -> 223 bytes include/battle.h | 2 + include/battle_interface.h | 4 + include/battle_util.h | 1 + include/constants/battle_config.h | 4 + include/global.h | 3 +- include/item_use.h | 1 + src/battle_controller_player.c | 16 +- src/battle_interface.c | 181 +++++++++++++++++++ src/battle_main.c | 4 + src/battle_script_commands.c | 3 +- src/battle_util.c | 11 ++ src/item_use.c | 54 ++++-- src/new_game.c | 2 + 15 files changed, 283 insertions(+), 22 deletions(-) create mode 100644 graphics/battle_interface/ability_pop_up.pal create mode 100644 graphics/battle_interface/last_used_ball.png diff --git a/graphics/battle_interface/ability_pop_up.pal b/graphics/battle_interface/ability_pop_up.pal new file mode 100644 index 000000000..19895d0bc --- /dev/null +++ b/graphics/battle_interface/ability_pop_up.pal @@ -0,0 +1,19 @@ +JASC-PAL +0100 +16 +1 177 91 +143 129 149 +103 91 111 +79 65 85 +59 31 81 +103 89 109 +231 239 245 +249 253 255 +0 0 0 +0 0 0 +107 115 115 +74 66 82 +0 0 0 +214 214 206 +132 140 140 +0 0 0 diff --git a/graphics/battle_interface/last_used_ball.png b/graphics/battle_interface/last_used_ball.png new file mode 100644 index 0000000000000000000000000000000000000000..581569cf1bf4ce3f5cee78fcd83a7a34b149d012 GIT binary patch literal 223 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfvg8-ipSH_Le)y2(0UQw2Yj+z{f zK*sa;Uw{7n50nRj?BZfCCy?fA*Uq){^Z*&j&Z>)mRF^unv_P&x8 zS#yg)?8er2d6p7uYPU)$efU;Y`E%9Nr%yw_D=__j$HY1FVdQ&MBb@0Cx9FNdN!< literal 0 HcmV?d00001 diff --git a/include/battle.h b/include/battle.h index f009cbe7f..9a10ae77d 100644 --- a/include/battle.h +++ b/include/battle.h @@ -37,6 +37,7 @@ #define B_ACTION_CANCEL_PARTNER 12 // when choosing an action #define B_ACTION_NOTHING_FAINTED 13 // when choosing an action #define B_ACTION_DEBUG 20 +#define B_ACTION_THROW_BALL 21 // R to throw last used ball #define B_ACTION_NONE 0xFF #define MAX_TRAINER_ITEMS 4 @@ -586,6 +587,7 @@ struct BattleStruct u16 moveEffect2; // For Knock Off u16 changedSpecies[PARTY_SIZE]; // For Zygarde or future forms when multiple mons can change into the same pokemon. u8 quickClawBattlerId; + u8 ballSpriteIds[2]; // item gfx, window gfx }; #define GET_MOVE_TYPE(move, typeArg) \ diff --git a/include/battle_interface.h b/include/battle_interface.h index 0bcadaaac..c852b776a 100644 --- a/include/battle_interface.h +++ b/include/battle_interface.h @@ -93,5 +93,9 @@ u8 GetScaledHPFraction(s16 hp, s16 maxhp, u8 scale); u8 GetHPBarLevel(s16 hp, s16 maxhp); void CreateAbilityPopUp(u8 battlerId, u32 ability, bool32 isDoubleBattle); void DestroyAbilityPopUp(u8 battlerId); +bool32 CanThrowLastUsedBall(void); +void TryHideLastUsedBall(void); +void TryRestoreLastUsedBall(void); +void TryAddLastUsedBallItemSprites(void); #endif // GUARD_BATTLE_INTERFACE_H diff --git a/include/battle_util.h b/include/battle_util.h index 0bf49dadf..717017c06 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -46,6 +46,7 @@ struct TypePower extern const struct TypePower gNaturalGiftTable[]; +void HandleAction_ThrowBall(void); void HandleAction_UseMove(void); void HandleAction_Switch(void); void HandleAction_UseItem(void); diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index fe376da8d..0f878d3af 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -151,6 +151,10 @@ #define B_CRITICAL_CAPTURE TRUE // If set to TRUE, Critical Capture will be enabled. #define B_CATCHING_CHARM_BOOST 20 // % boost in Critical Capture odds if player has the Catching Charm. +// Last Used Ball +#define B_LAST_USED_BALL TRUE // If TRUE, the "last used ball" feature from Gen 7 will be implemented +#define B_LAST_USED_BALL_BUTTON R_BUTTON // If last used ball is implemented, this button (or button combo) will trigger throwing the last used ball. + // Other #define B_DOUBLE_WILD_CHANCE 0 // % chance of encountering two Pokémon in a Wild Encounter. #define B_SLEEP_TURNS GEN_7 // In Gen5+, sleep lasts for 1-3 turns instead of 2-5 turns. diff --git a/include/global.h b/include/global.h index e6b0797e7..a5d720eda 100644 --- a/include/global.h +++ b/include/global.h @@ -490,7 +490,8 @@ struct SaveBlock2 u16 optionsBattleSceneOff:1; // whether battle animations are disabled u16 regionMapZoom:1; // whether the map is zoomed in /*0x18*/ struct Pokedex pokedex; - /*0x90*/ u8 filler_90[0x8]; + /*0x90*/ u16 lastUsedBall; + /*0x92*/ u8 filler_90[0x6]; /*0x98*/ struct Time localTimeOffset; /*0xA0*/ struct Time lastBerryTreeUpdate; /*0xA8*/ u32 gcnLinkFlags; // Read by Pokemon Colosseum/XD diff --git a/include/item_use.h b/include/item_use.h index f577f8d46..42db6ff10 100644 --- a/include/item_use.h +++ b/include/item_use.h @@ -33,5 +33,6 @@ void ItemUseInBattle_EnigmaBerry(u8); void Task_UseDigEscapeRopeOnField(u8 taskId); u8 CanUseDigOrEscapeRopeOnCurMap(void); u8 CheckIfItemIsTMHMOrEvolutionStone(u16 itemId); +u32 CanThrowBall(void); #endif // GUARD_ITEM_USE_H diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 89f73ffc4..89a044275 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -249,7 +249,8 @@ static void HandleInputChooseAction(void) if (JOY_NEW(A_BUTTON)) { PlaySE(SE_SELECT); - + TryHideLastUsedBall(); + switch (gActionSelectionCursor[gActiveBattler]) { case 0: @@ -336,6 +337,15 @@ static void HandleInputChooseAction(void) BtlController_EmitTwoReturnValues(1, B_ACTION_DEBUG, 0); PlayerBufferExecCompleted(); } + #if B_LAST_USED_BALL == TRUE + else if (JOY_NEW(B_LAST_USED_BALL_BUTTON) && CanThrowLastUsedBall()) + { + PlaySE(SE_SELECT); + TryHideLastUsedBall(); + BtlController_EmitTwoReturnValues(1, B_ACTION_THROW_BALL, 0); + PlayerBufferExecCompleted(); + } + #endif } static void UnusedEndBounceEffect(void) @@ -372,6 +382,7 @@ static void HandleInputChooseTarget(void) else BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8)); EndBounceEffect(gMultiUsePlayerCursor, BOUNCE_HEALTHBOX); + TryHideLastUsedBall(); HideMegaTriggerSprite(); PlayerBufferExecCompleted(); } @@ -514,6 +525,7 @@ static void HandleInputShowTargets(void) else BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8)); HideMegaTriggerSprite(); + TryHideLastUsedBall(); PlayerBufferExecCompleted(); } else if (gMain.newKeys & B_BUTTON || gPlayerDpadHoldFrames > 59) @@ -606,6 +618,7 @@ static void HandleInputChooseMove(void) else BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8)); HideMegaTriggerSprite(); + TryHideLastUsedBall(); PlayerBufferExecCompleted(); } else if (canSelectTarget == 1) @@ -2691,6 +2704,7 @@ static void PlayerHandleChooseAction(void) for (i = 0; i < 4; i++) ActionSelectionDestroyCursorAt(i); + TryRestoreLastUsedBall(); ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0); BattleStringExpandPlaceholdersToDisplayedString(gText_WhatWillPkmnDo); BattlePutTextOnWindow(gDisplayedStringBattle, 1); diff --git a/src/battle_interface.c b/src/battle_interface.c index 128f342df..828b57a2f 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -27,6 +27,9 @@ #include "constants/battle_config.h" #include "data.h" #include "pokemon_summary_screen.h" +#include "item_icon.h" +#include "item_use.h" +#include "item.h" enum { // Corresponds to gHealthboxElementsGfxTable (and the tables after it) in graphics.c @@ -196,6 +199,9 @@ static u8 CalcBarFilledPixels(s32 maxValue, s32 oldValue, s32 receivedValue, s32 static void SpriteCb_AbilityPopUp(struct Sprite *sprite); static void Task_FreeAbilityPopUpGfx(u8 taskId); +static void SpriteCB_LastUsedBall(struct Sprite *sprite); +static void SpriteCB_LastUsedBallWin(struct Sprite *sprite); + // const rom data static const struct OamData sUnknown_0832C138 = { @@ -812,6 +818,9 @@ u8 CreateBattlerHealthboxSprites(u8 battlerId) gSprites[megaIndicatorSpriteId].invisible = TRUE; } + gBattleStruct->ballSpriteIds[0] = MAX_SPRITES; + gBattleStruct->ballSpriteIds[1] = MAX_SPRITES; + return healthboxLeftSpriteId; } @@ -3128,3 +3137,175 @@ static void Task_FreeAbilityPopUpGfx(u8 taskId) DestroyTask(taskId); } } + +// last used ball +#define LAST_BALL_WINDOW_TAG 0xD721 + +static const struct OamData sOamData_LastUsedBall = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = SPRITE_SHAPE(32x32), + .x = 0, + .matrixNum = 0, + .size = SPRITE_SIZE(32x32), + .tileNum = 0, + .priority = 1, + .paletteNum = 0, + .affineParam = 0, +}; + +static const struct SpriteTemplate sSpriteTemplate_LastUsedBallWindow = +{ + .tileTag = LAST_BALL_WINDOW_TAG, + .paletteTag = ABILITY_POP_UP_TAG, + .oam = &sOamData_LastUsedBall, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_LastUsedBallWin +}; + +static const u8 sLastUsedBallWindowGfx[] = INCBIN_U8("graphics/battle_interface/last_used_ball.4bpp"); +static const struct SpriteSheet sSpriteSheet_LastUsedBallWindow = +{ + sLastUsedBallWindowGfx, sizeof(sLastUsedBallWindowGfx), LAST_BALL_WINDOW_TAG +}; + +#define LAST_USED_BALL_X_F 15 +#define LAST_USED_BALL_X_0 -15 +#define LAST_USED_BALL_Y 68 + +#define LAST_BALL_WIN_X_F (LAST_USED_BALL_X_F - 1) +#define LAST_BALL_WIN_X_0 (LAST_USED_BALL_X_0 - 0) +#define LAST_USED_WIN_Y (LAST_USED_BALL_Y - 8) + +#define sHide data[0] + +bool32 CanThrowLastUsedBall(void) +{ + return (!(CanThrowBall() != 0 + || (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + || !CheckBagHasItem(gSaveBlock2Ptr->lastUsedBall, 1))); +} + + +void TryAddLastUsedBallItemSprites(void) +{ + if (CanThrowBall() != 0 + || (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + || !CheckBagHasItem(gSaveBlock2Ptr->lastUsedBall, 1)) + return; + + // ball + if (gBattleStruct->ballSpriteIds[0] == MAX_SPRITES) + { + gBattleStruct->ballSpriteIds[0] = AddItemIconSprite(102, 102, gSaveBlock2Ptr->lastUsedBall); + gSprites[gBattleStruct->ballSpriteIds[0]].pos1.x = LAST_USED_BALL_X_0; + gSprites[gBattleStruct->ballSpriteIds[0]].pos1.y = LAST_USED_BALL_Y; + gSprites[gBattleStruct->ballSpriteIds[0]].sHide = FALSE; // restore + gSprites[gBattleStruct->ballSpriteIds[0]].callback = SpriteCB_LastUsedBall; + } + + // window + LoadSpritePalette(&sSpritePalette_AbilityPopUp); + if (GetSpriteTileStartByTag(LAST_BALL_WINDOW_TAG) == 0xFFFF) + LoadSpriteSheet(&sSpriteSheet_LastUsedBallWindow); + + if (gBattleStruct->ballSpriteIds[1] == MAX_SPRITES) + { + gBattleStruct->ballSpriteIds[1] = CreateSprite(&sSpriteTemplate_LastUsedBallWindow, + LAST_BALL_WIN_X_0, + LAST_USED_WIN_Y, 5); + gSprites[gBattleStruct->ballSpriteIds[0]].sHide = FALSE; // restore + } +} + +static void DestroyLastUsedBallWinGfx(struct Sprite *sprite) +{ + FreeSpriteTilesByTag(LAST_BALL_WINDOW_TAG); + FreeSpritePaletteByTag(ABILITY_POP_UP_TAG); + DestroySprite(sprite); + gBattleStruct->ballSpriteIds[1] = MAX_SPRITES; +} + +static void DestroyLastUsedBallGfx(struct Sprite *sprite) +{ + FreeSpriteTilesByTag(102); + FreeSpritePaletteByTag(102); + DestroySprite(sprite); + gBattleStruct->ballSpriteIds[0] = MAX_SPRITES; +} + +static void SpriteCB_LastUsedBallWin(struct Sprite *sprite) +{ + if (sprite->sHide) + { + if (sprite->pos1.x != LAST_BALL_WIN_X_0) + sprite->pos1.x--; + + if (sprite->pos1.x == LAST_BALL_WIN_X_0) + DestroyLastUsedBallWinGfx(sprite); + } + else + { + if (sprite->pos1.x != LAST_BALL_WIN_X_F) + sprite->pos1.x++; + } +} + +static void SpriteCB_LastUsedBall(struct Sprite *sprite) +{ + if (sprite->sHide) + { + if (sprite->pos1.x != LAST_USED_BALL_X_0) + sprite->pos1.x--; + + if (sprite->pos1.x == LAST_USED_BALL_X_0) + DestroyLastUsedBallGfx(sprite); + } + else + { + if (sprite->pos1.x != LAST_USED_BALL_X_F) + sprite->pos1.x++; + } +} + +static void TryHideOrRestoreLastUsedBall(u8 caseId) +{ + if (gBattleStruct->ballSpriteIds[0] == MAX_SPRITES) + return; + + switch (caseId) + { + case 0: // hide + if (gBattleStruct->ballSpriteIds[0] != MAX_SPRITES) + gSprites[gBattleStruct->ballSpriteIds[0]].sHide = TRUE; // hide + if (gBattleStruct->ballSpriteIds[1] != MAX_SPRITES) + gSprites[gBattleStruct->ballSpriteIds[1]].sHide = TRUE; // hide + break; + case 1: // restore + if (gBattleStruct->ballSpriteIds[0] != MAX_SPRITES) + gSprites[gBattleStruct->ballSpriteIds[0]].sHide = FALSE; // restore + if (gBattleStruct->ballSpriteIds[1] != MAX_SPRITES) + gSprites[gBattleStruct->ballSpriteIds[1]].sHide = FALSE; // restore + break; + } +} + +void TryHideLastUsedBall(void) +{ + TryHideOrRestoreLastUsedBall(0); +} + +void TryRestoreLastUsedBall(void) +{ + if (gBattleStruct->ballSpriteIds[0] != MAX_SPRITES) + TryHideOrRestoreLastUsedBall(1); + else + TryAddLastUsedBallItemSprites(); +} + diff --git a/src/battle_main.c b/src/battle_main.c index 9cf56abf7..2d4dfa16f 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -401,6 +401,7 @@ static void (* const sTurnActionsFuncsTable[])(void) = [B_ACTION_TRY_FINISH] = HandleAction_TryFinish, [B_ACTION_FINISHED] = HandleAction_ActionFinished, [B_ACTION_NOTHING_FAINTED] = HandleAction_NothingIsFainted, + [B_ACTION_THROW_BALL] = HandleAction_ThrowBall, }; static void (* const sEndTurnFuncsTable[])(void) = @@ -4053,6 +4054,9 @@ static void HandleTurnActionSelectionState(void) case B_ACTION_SAFARI_BALL: gBattleCommunication[gActiveBattler]++; break; + case B_ACTION_THROW_BALL: + gBattleCommunication[gActiveBattler]++; + break; case B_ACTION_SAFARI_POKEBLOCK: if ((gBattleResources->bufferB[gActiveBattler][1] | (gBattleResources->bufferB[gActiveBattler][2] << 8)) != 0) { diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index c8a393da3..f5f093cc5 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -12017,7 +12017,8 @@ static void Cmd_handleballthrow(void) { u32 odds; u8 catchRate; - + + gSaveBlock2Ptr->lastUsedBall = gLastUsedItem; if (gLastUsedItem == ITEM_SAFARI_BALL) catchRate = gBattleStruct->safariCatchFactor * 1275 / 100; else diff --git a/src/battle_util.c b/src/battle_util.c index 87f9003e0..7a86b659f 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -742,6 +742,17 @@ void HandleAction_SafariZoneBallThrow(void) gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; } +void HandleAction_ThrowBall(void) +{ + gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + gLastUsedItem = gSaveBlock2Ptr->lastUsedBall; + RemoveBagItem(gLastUsedItem, 1); + gBattlescriptCurrInstr = BattleScript_BallThrow; + gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; +} + void HandleAction_ThrowPokeblock(void) { gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; diff --git a/src/item_use.c b/src/item_use.c index 6b1519e9b..ad7a46499 100755 --- a/src/item_use.c +++ b/src/item_use.c @@ -936,42 +936,58 @@ void ItemUseOutOfBattle_EvolutionStone(u8 taskId) SetUpItemUseCallback(taskId); } -void ItemUseInBattle_PokeBall(u8 taskId) +u32 CanThrowBall(void) { if (IsBattlerAlive(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT)) - && IsBattlerAlive(GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT))) // There are two present pokemon. + && IsBattlerAlive(GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT))) { - static const u8 textCantThrowPokeBall[] = _("Cannot throw a ball!\nThere are two pokemon out there!\p"); - - if (!InBattlePyramid()) - DisplayItemMessage(taskId, 1, textCantThrowPokeBall, BagMenu_InitListsMenu); - else - DisplayItemMessageInBattlePyramid(taskId, textCantThrowPokeBall, Task_CloseBattlePyramidBagMessage); + return 1; // There are two present pokemon. } else if (gBattlerInMenuId == GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT) - && IsBattlerAlive(GetBattlerAtPosition(B_POSITION_PLAYER_LEFT))) // Attempting to throw a ball with the second pokemon while both are alive. + && IsBattlerAlive(GetBattlerAtPosition(B_POSITION_PLAYER_LEFT))) { - static const u8 textCantThrowPokeBall[] = _("Cannot throw a ball!\p"); - - if (!InBattlePyramid()) - DisplayItemMessage(taskId, 1, textCantThrowPokeBall, BagMenu_InitListsMenu); - else - DisplayItemMessageInBattlePyramid(taskId, textCantThrowPokeBall, Task_CloseBattlePyramidBagMessage); + return 2; // Attempting to throw a ball with the second pokemon while both are alive. } - else if (IsPlayerPartyAndPokemonStorageFull() == FALSE) // have room for mon? + else if (IsPlayerPartyAndPokemonStorageFull() == TRUE) { + return 3; // No room for mon + } + + return 0; // usable +} + +static const u8 sText_CantThrowPokeBall_TwoMons[] = _("Cannot throw a ball!\nThere are two pokemon out there!\p"); +static const u8 sText_CantThrowPokeBall[] = _("Cannot throw a ball!\p"); +void ItemUseInBattle_PokeBall(u8 taskId) +{ + switch (CanThrowBall()) + { + case 0: // usable + default: RemoveBagItem(gSpecialVar_ItemId, 1); if (!InBattlePyramid()) Task_FadeAndCloseBagMenu(taskId); else CloseBattlePyramidBag(taskId); - } - else - { + break; + case 1: // There are two present pokemon. + if (!InBattlePyramid()) + DisplayItemMessage(taskId, 1, sText_CantThrowPokeBall_TwoMons, BagMenu_InitListsMenu); + else + DisplayItemMessageInBattlePyramid(taskId, sText_CantThrowPokeBall_TwoMons, Task_CloseBattlePyramidBagMessage); + break; + case 2: // Attempting to throw a ball with the second pokemon while both are alive. + if (!InBattlePyramid()) + DisplayItemMessage(taskId, 1, sText_CantThrowPokeBall_TwoMons, BagMenu_InitListsMenu); + else + DisplayItemMessageInBattlePyramid(taskId, sText_CantThrowPokeBall_TwoMons, Task_CloseBattlePyramidBagMessage); + break; + case 3: // No room for mon if (!InBattlePyramid()) DisplayItemMessage(taskId, 1, gText_BoxFull, BagMenu_InitListsMenu); else DisplayItemMessageInBattlePyramid(taskId, gText_BoxFull, Task_CloseBattlePyramidBagMessage); + break; } } diff --git a/src/new_game.c b/src/new_game.c index 2a950efbc..c1dd85e90 100644 --- a/src/new_game.c +++ b/src/new_game.c @@ -45,6 +45,7 @@ #include "berry_powder.h" #include "mevent.h" #include "union_room_chat.h" +#include "constants/items.h" extern const u8 EventScript_ResetAllMapFlags[]; @@ -204,6 +205,7 @@ void NewGameInitData(void) WipeTrainerNameRecords(); ResetTrainerHillResults(); ResetContestLinkResults(); + gSaveBlock2Ptr->lastUsedBall = ITEM_POKE_BALL; } static void ResetMiniGamesRecords(void) From d28ac33b0e8f350d49511257d0d5df10ae2c8352 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Sun, 4 Jul 2021 09:28:59 -0600 Subject: [PATCH 06/58] fix throw last used ball action turn order checks --- src/battle_main.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/battle_main.c b/src/battle_main.c index 2d4dfa16f..6befbfbf5 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -4485,7 +4485,9 @@ static void SetActionsAndBattlersTurnOrder(void) { for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) { - if (gChosenActionByBattler[gActiveBattler] == B_ACTION_USE_ITEM || gChosenActionByBattler[gActiveBattler] == B_ACTION_SWITCH) + if (gChosenActionByBattler[gActiveBattler] == B_ACTION_USE_ITEM + || gChosenActionByBattler[gActiveBattler] == B_ACTION_SWITCH + || gChosenActionByBattler[gActiveBattler] == B_ACTION_THROW_BALL) { gActionsByTurnOrder[turnOrderId] = gChosenActionByBattler[gActiveBattler]; gBattlerByTurnOrder[turnOrderId] = gActiveBattler; @@ -4494,7 +4496,9 @@ static void SetActionsAndBattlersTurnOrder(void) } for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) { - if (gChosenActionByBattler[gActiveBattler] != B_ACTION_USE_ITEM && gChosenActionByBattler[gActiveBattler] != B_ACTION_SWITCH) + if (gChosenActionByBattler[gActiveBattler] != B_ACTION_USE_ITEM + && gChosenActionByBattler[gActiveBattler] != B_ACTION_SWITCH + && gChosenActionByBattler[gActiveBattler] != B_ACTION_THROW_BALL) { gActionsByTurnOrder[turnOrderId] = gChosenActionByBattler[gActiveBattler]; gBattlerByTurnOrder[turnOrderId] = gActiveBattler; @@ -4510,7 +4514,9 @@ static void SetActionsAndBattlersTurnOrder(void) if (gActionsByTurnOrder[i] != B_ACTION_USE_ITEM && gActionsByTurnOrder[j] != B_ACTION_USE_ITEM && gActionsByTurnOrder[i] != B_ACTION_SWITCH - && gActionsByTurnOrder[j] != B_ACTION_SWITCH) + && gActionsByTurnOrder[j] != B_ACTION_SWITCH + && gActionsByTurnOrder[i] != B_ACTION_THROW_BALL + && gActionsByTurnOrder[j] != B_ACTION_THROW_BALL) { if (GetWhoStrikesFirst(battler1, battler2, FALSE)) SwapTurnOrder(i, j); From 542f0accf5a4f0c3dde59e6e76dca98c7ab08db6 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Sun, 4 Jul 2021 10:09:57 -0600 Subject: [PATCH 07/58] fix updating last used ball when run out of item id --- src/battle_interface.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/battle_interface.c b/src/battle_interface.c index 828b57a2f..b233627d8 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -729,6 +729,12 @@ u8 GetMegaIndicatorSpriteId(u32 healthboxSpriteId) return gSprites[spriteId].hOther_IndicatorSpriteId; } +static void InitLastUsedBallAssets(void) +{ + gBattleStruct->ballSpriteIds[0] = MAX_SPRITES; + gBattleStruct->ballSpriteIds[1] = MAX_SPRITES; +} + u8 CreateBattlerHealthboxSprites(u8 battlerId) { s16 data6 = 0; @@ -3195,6 +3201,14 @@ bool32 CanThrowLastUsedBall(void) void TryAddLastUsedBallItemSprites(void) { + if (gSaveBlock2Ptr->lastUsedBall != ITEM_NONE && !CheckBagHasItem(gSaveBlock2Ptr->lastUsedBall, 1)) + { + // we're out of the last used ball, so just set it to the first ball in the bag + // we have to compact the bag first bc it is typically only compacted when you open it + CompactItemsInBagPocket(&gBagPockets[BALLS_POCKET]); + gSaveBlock2Ptr->lastUsedBall = gBagPockets[BALLS_POCKET].itemSlots[0].itemId; + } + if (CanThrowBall() != 0 || (gBattleTypeFlags & BATTLE_TYPE_TRAINER) || !CheckBagHasItem(gSaveBlock2Ptr->lastUsedBall, 1)) From 07e3e73372eb6d625a198e07fd4a2360c5d25031 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Sun, 18 Jul 2021 11:20:51 -0600 Subject: [PATCH 08/58] fix ITEM_NONE to 0 for compilation reasons --- src/battle_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_interface.c b/src/battle_interface.c index b233627d8..1564881e4 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -3201,7 +3201,7 @@ bool32 CanThrowLastUsedBall(void) void TryAddLastUsedBallItemSprites(void) { - if (gSaveBlock2Ptr->lastUsedBall != ITEM_NONE && !CheckBagHasItem(gSaveBlock2Ptr->lastUsedBall, 1)) + if (gSaveBlock2Ptr->lastUsedBall != 0 && !CheckBagHasItem(gSaveBlock2Ptr->lastUsedBall, 1)) { // we're out of the last used ball, so just set it to the first ball in the bag // we have to compact the bag first bc it is typically only compacted when you open it From 4ca6d76160b01738d9fcd326643a89828a045b61 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Sun, 25 Jul 2021 14:55:52 -0600 Subject: [PATCH 09/58] add bug bite --- asm/macros/battle_script.inc | 5 ++++ data/battle_scripts_1.s | 5 ++++ include/battle.h | 1 + include/battle_util.h | 1 + include/constants/battle_script_commands.h | 2 ++ src/battle_script_commands.c | 31 ++++++++++++++++++++-- src/battle_util.c | 5 ++++ 7 files changed, 48 insertions(+), 2 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 9fa3fe0c3..953180d91 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1768,6 +1768,11 @@ .macro tryactivategrimneigh, battler:req various \battler, VARIOUS_TRY_ACTIVATE_GRIM_NEIGH .endm + + .macro consumeberry battler:req, restoreItem=FALSE + various \battler, VARIOUS_CONSUME_BERRY + .byte \restoreItem + .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 522ffb701..d48076e48 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -508,6 +508,11 @@ BattleScript_MoveEffectIncinerate:: BattleScript_MoveEffectBugBite:: printstring STRINGID_BUGBITE waitmessage B_WAIT_TIME_LONG + orword gHitMarker, HITMARKER_NO_ANIMATIONS + setbyte sBERRY_OVERRIDE, TRUE @ override the requirements for eating berries + consumeberry BS_ATTACKER, TRUE @ consume the berry, then restore the item from changedItems + bicword gHitMarker, HITMARKER_NO_ANIMATIONS + setbyte sBERRY_OVERRIDE, FALSE return BattleScript_EffectCoreEnforcer: diff --git a/include/battle.h b/include/battle.h index b51a3d71b..e82253747 100644 --- a/include/battle.h +++ b/include/battle.h @@ -659,6 +659,7 @@ struct BattleScripting u8 illusionNickHack; // To properly display nick in STRINGID_ENEMYABOUTTOSWITCHPKMN. bool8 fixedPopup; // force ability popup to stick until manually called back u16 abilityPopupOverwrite; + u8 overrideBerryRequirements; }; // rom_80A5C6C diff --git a/include/battle_util.h b/include/battle_util.h index e10305e56..bea6af848 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -31,6 +31,7 @@ #define ITEMEFFECT_KINGSROCK_SHELLBELL 0x4 #define ITEMEFFECT_TARGET 0x5 #define ITEMEFFECT_ORBS 0x6 +#define ITEMEFFECT_BATTLER_MOVE_END 0x7 // move end effects for just the battler, not whole field #define WEATHER_HAS_EFFECT ((!IsAbilityOnField(ABILITY_CLOUD_NINE) && !IsAbilityOnField(ABILITY_AIR_LOCK))) diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index faaf8f17e..881bb82e0 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -37,6 +37,7 @@ #define sILLUSION_NICK_HACK gBattleScripting + 0x32 #define sFIXED_ABILITY_POPUP gBattleScripting + 0x33 #define sABILITY_OVERWRITE gBattleScripting + 0x34 +#define sBERRY_OVERRIDE gBattleScripting + 0x36 #define cMULTISTRING_CHOOSER gBattleCommunication + 5 #define cMISS_TYPE gBattleCommunication + 6 @@ -173,6 +174,7 @@ #define VARIOUS_DESTROY_ABILITY_POPUP 102 #define VARIOUS_TOTEM_BOOST 103 #define VARIOUS_TRY_ACTIVATE_GRIM_NEIGH 104 +#define VARIOUS_CONSUME_BERRY 105 // Cmd_manipulatedamage #define DMG_CHANGE_SIGN 0 diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index de7105a27..067d0b62e 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3284,16 +3284,22 @@ void SetMoveEffect(bool32 primary, u32 certain) } break; case MOVE_EFFECT_BUG_BITE: - if ((gBattleMons[gEffectBattler].item >= FIRST_BERRY_INDEX && gBattleMons[gEffectBattler].item <= LAST_BERRY_INDEX) + if (ItemId_GetPocket(gBattleMons[gEffectBattler].item) == POCKET_BERRIES && GetBattlerAbility(gEffectBattler) != ABILITY_STICKY_HOLD) { + // target loses their berry gLastUsedItem = gBattleMons[gEffectBattler].item; gBattleMons[gEffectBattler].item = 0; CheckSetUnburden(gEffectBattler); - gActiveBattler = gEffectBattler; + BtlController_EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gEffectBattler].item); MarkBattlerForControllerExec(gActiveBattler); + + // attacker temporarily gains their item + gBattleStruct->changedItems[gBattlerAttacker] = gBattleMons[gBattlerAttacker].item; + gBattleMons[gBattlerAttacker].item = gLastUsedItem; + BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_MoveEffectBugBite; } @@ -8422,6 +8428,27 @@ static void Cmd_various(void) gBattlescriptCurrInstr += 7; // exit if loop failed (failsafe) } return; + case VARIOUS_CONSUME_BERRY: + if (ItemId_GetHoldEffect(gBattleMons[gActiveBattler].item) == HOLD_EFFECT_NONE) + { + gBattlescriptCurrInstr += 4; + return; + } + + gBattleScripting.battler = gEffectBattler = gBattlerTarget = gActiveBattler; // cover all berry effect battlerId cases. e.g. ChangeStatBuffs uses target ID + // do move end berry effects for just a single battler, instead of looping through all battlers + if (ItemBattleEffects(ITEMEFFECT_BATTLER_MOVE_END, gActiveBattler, FALSE)) + return; + + if (gBattlescriptCurrInstr[3]) + { + gBattleMons[gActiveBattler].item = gBattleStruct->changedItems[gActiveBattler]; + gBattleStruct->changedItems[gActiveBattler] = ITEM_NONE; + gBattleResources->flags->flags[gActiveBattler] &= ~(RESOURCE_FLAG_UNBURDEN); + } + + gBattlescriptCurrInstr += 4; + return; } gBattlescriptCurrInstr += 3; diff --git a/src/battle_util.c b/src/battle_util.c index 7deebd25e..6c9e14187 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -5385,6 +5385,8 @@ bool32 HasEnoughHpToEatBerry(u32 battlerId, u32 hpFraction, u32 itemId) if (gBattleMons[battlerId].hp == 0) return FALSE; + if (gBattleScripting.overrideBerryRequirements) + return TRUE; // Unnerve prevents consumption of opponents' berries. if (isBerry && IsUnnerveAbilityOnOpposingSide(battlerId)) return FALSE; @@ -6095,11 +6097,14 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) } } break; + case ITEMEFFECT_BATTLER_MOVE_END: + goto DO_ITEMEFFECT_MOVE_END; // this hurts a bit to do, but is an easy solution case ITEMEFFECT_MOVE_END: for (battlerId = 0; battlerId < gBattlersCount; battlerId++) { gLastUsedItem = gBattleMons[battlerId].item; battlerHoldEffect = GetBattlerHoldEffect(battlerId, TRUE); + DO_ITEMEFFECT_MOVE_END: switch (battlerHoldEffect) { case HOLD_EFFECT_MICLE_BERRY: From ab529b4e8934afa152ef54ad0189e8a6df7c06d6 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Tue, 27 Jul 2021 10:31:48 -0600 Subject: [PATCH 10/58] add stuff cheeks --- data/battle_scripts_1.s | 28 +++++++++++++++++++++++++ include/battle_scripts.h | 1 + include/constants/battle_move_effects.h | 1 + include/constants/battle_string_ids.h | 3 ++- src/battle_ai_main.c | 12 ++++------- src/battle_message.c | 2 ++ src/battle_util.c | 17 +++++++++++++++ src/data/battle_moves.h | 2 +- 8 files changed, 56 insertions(+), 10 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index d48076e48..37ae9b730 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -368,6 +368,30 @@ gBattleScriptsForMoveEffects:: @ 82D86A8 .4byte BattleScript_EffectSleepHit .4byte BattleScript_EffectAttackerDefenseDownHit .4byte BattleScript_EffectBodyPress + .4byte BattleScript_EffectStuffCheeks + +BattleScript_EffectStuffCheeks:: + attackcanceler + attackstring + ppreduce + jumpifnotberry BS_ATTACKER, BattleScript_ButItFailed + attackanimation + waitanimation +BattleScript_StuffCheeksEatBerry: + setbyte sBERRY_OVERRIDE, TRUE + orword gHitMarker, HITMARKER_NO_ANIMATIONS + consumeberry BS_ATTACKER + bicword gHitMarker, HITMARKER_NO_ANIMATIONS + setbyte sBERRY_OVERRIDE, FALSE + setstatchanger STAT_DEF, 2, FALSE + statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_ALLOW_PTR, BattleScript_StuffCheeksEnd + setgraphicalstatchangevalues + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_StuffCheeksEnd @ cant raise def + playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 + printfromtable gStatUpStringIds + waitmessage B_WAIT_TIME_LONG +BattleScript_StuffCheeksEnd: + goto BattleScript_MoveEnd BattleScript_EffectAttackerDefenseDownHit: setmoveeffect MOVE_EFFECT_DEF_MINUS_1 | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN @@ -5985,6 +6009,10 @@ BattleScript_SelectingNotAllowedMoveGravity:: printselectionstring STRINGID_GRAVITYPREVENTSUSAGE endselectionscript +BattleScript_SelectingNotAllowedStuffCheeks:: + printselectionstring STRINGID_STUFFCHEEKSCANTSELECT + endselectionscript + BattleScript_SelectingNotAllowedBelch:: printselectionstring STRINGID_BELCHCANTSELECT endselectionscript diff --git a/include/battle_scripts.h b/include/battle_scripts.h index f0712fc43..0b81fc675 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -295,6 +295,7 @@ extern const u8 BattleScript_ProteanActivates[]; extern const u8 BattleScript_DazzlingProtected[]; extern const u8 BattleScript_MoveUsedPsychicTerrainPrevents[]; extern const u8 BattleScript_MoveUsedPowder[]; +extern const u8 BattleScript_SelectingNotAllowedStuffCheeks[]; extern const u8 BattleScript_SelectingNotAllowedBelch[]; extern const u8 BattleScript_SelectingNotAllowedBelchInPalace[]; extern const u8 BattleScript_PsychicSurgeActivates[]; diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index cbab68b66..2e54e9ef3 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -352,6 +352,7 @@ #define EFFECT_SLEEP_HIT 346 #define EFFECT_ATTACKER_DEFENSE_DOWN_HIT 347 #define EFFECT_BODY_PRESS 348 +#define EFFECT_STUFF_CHEEKS 349 #define NUM_BATTLE_MOVE_EFFECTS 350 diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index cda885694..e2b97d443 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -570,8 +570,9 @@ #define STRINGID_MICLEBERRYACTIVATES 566 #define STRINGID_PKMNSHOOKOFFTHETAUNT 567 #define STRINGID_PKMNGOTOVERITSINFATUATION 568 +#define STRINGID_STUFFCHEEKSCANTSELECT 569 -#define BATTLESTRINGS_COUNT 569 +#define BATTLESTRINGS_COUNT 570 // The below IDs are all indexes into battle message tables, // used to determine which of a set of messages to print. diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 81d97fcab..da978b427 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -792,21 +792,17 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_ATK) || !HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL)) score -= 10; break; - case EFFECT_DEFENSE_UP_2: - if (move == MOVE_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[battlerAtk].item) != POCKET_BERRIES) - score -= 10; + case EFFECT_STUFF_CHEEKS: + if (ItemId_GetPocket(gBattleMons[battlerAtk].item) != POCKET_BERRIES) + return 0; // cannot even select //fallthrough case EFFECT_DEFENSE_UP: + case EFFECT_DEFENSE_UP_2: case EFFECT_DEFENSE_UP_3: case EFFECT_DEFENSE_CURL: if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_DEF)) score -= 10; break; - case EFFECT_SPEED_UP: - case EFFECT_SPEED_UP_2: - if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPEED)) - score -= 10; - break; case EFFECT_SPECIAL_ATTACK_UP: case EFFECT_SPECIAL_ATTACK_UP_2: case EFFECT_SPECIAL_ATTACK_UP_3: diff --git a/src/battle_message.c b/src/battle_message.c index c4f043e15..439f88e29 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -696,9 +696,11 @@ static const u8 sText_CanActFaster[] = _("{B_ATK_NAME_WITH_PREFIX} can act faste static const u8 sText_MicleBerryActivates[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} boosted the accuracy of its\nnext move using {B_LAST_ITEM}!"); static const u8 sText_PkmnShookOffTheTaunt[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} shook off\nthe taunt!"); static const u8 sText_PkmnGotOverItsInfatuation[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} got over\nits infatuation!"); +static const u8 sText_StuffCheeksCantSelect[] = _("Stuff Cheeks cannot be\nselected without a Berry!\p"); const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = { + [STRINGID_STUFFCHEEKSCANTSELECT - 12] = sText_StuffCheeksCantSelect, [STRINGID_PKMNGOTOVERITSINFATUATION - 12] = sText_PkmnGotOverItsInfatuation, [STRINGID_PKMNSHOOKOFFTHETAUNT - 12] = sText_PkmnShookOffTheTaunt, [STRINGID_MICLEBERRYACTIVATES - 12] = sText_MicleBerryActivates, diff --git a/src/battle_util.c b/src/battle_util.c index 6c9e14187..99217ce6f 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1708,6 +1708,21 @@ u8 TrySetCantSelectMoveBattleScript(void) limitations++; } } + + if (move == MOVE_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[gActiveBattler].item) != POCKET_BERRIES) + { + gCurrentMove = move; + if (gBattleTypeFlags & BATTLE_TYPE_PALACE) + { + gPalaceSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedBelchInPalace; + gProtectStructs[gActiveBattler].palaceUnableToUseMove = 1; + } + else + { + gSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedStuffCheeks; + limitations++; + } + } gPotentialItemEffectBattler = gActiveBattler; if (HOLD_EFFECT_CHOICE(holdEffect) && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != move) @@ -1791,6 +1806,8 @@ u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u8 check) unusableMoves |= gBitTable[i]; else if (gDisableStructs[battlerId].throatChopTimer && gBattleMoves[gBattleMons[battlerId].moves[i]].flags & FLAG_SOUND) unusableMoves |= gBitTable[i]; + else if (gBattleMons[battlerId].moves[i] == MOVE_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[gActiveBattler].item) != POCKET_BERRIES) + unusableMoves |= gBitTable[i]; } return unusableMoves; } diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index 9fc79581f..416c5b850 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -10771,7 +10771,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_STUFF_CHEEKS] = { - .effect = EFFECT_DEFENSE_UP_2, + .effect = EFFECT_STUFF_CHEEKS, .power = 0, .type = TYPE_NORMAL, .accuracy = 0, From d3446123461ee5ccfdf803934189244b351b459f Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Thu, 12 Aug 2021 14:49:17 -0600 Subject: [PATCH 11/58] fix last used ball window in wild doubles --- src/battle_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_interface.c b/src/battle_interface.c index 1564881e4..28d6bc97c 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -3183,7 +3183,7 @@ static const struct SpriteSheet sSpriteSheet_LastUsedBallWindow = #define LAST_USED_BALL_X_F 15 #define LAST_USED_BALL_X_0 -15 -#define LAST_USED_BALL_Y 68 +#define LAST_USED_BALL_Y ((IsDoubleBattle()) ? 78 : 68) #define LAST_BALL_WIN_X_F (LAST_USED_BALL_X_F - 1) #define LAST_BALL_WIN_X_0 (LAST_USED_BALL_X_0 - 0) From e4fb9c4593c8f37700005376b55c6e14c7a3a63d Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Tue, 31 Aug 2021 12:51:03 -0400 Subject: [PATCH 12/58] fix throwing ball in wild doubles --- src/battle_main.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/battle_main.c b/src/battle_main.c index c728ae266..9e08fbbbc 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -4055,6 +4055,7 @@ static void HandleTurnActionSelectionState(void) gBattleCommunication[gActiveBattler]++; break; case B_ACTION_THROW_BALL: + gBattleStruct->throwingPokeBall = TRUE; gBattleCommunication[gActiveBattler]++; break; case B_ACTION_SAFARI_POKEBLOCK: @@ -4170,6 +4171,13 @@ static void HandleTurnActionSelectionState(void) if (gBattleCommunication[ACTIONS_CONFIRMED_COUNT] == gBattlersCount) { sub_818603C(1); + + if (WILD_DOUBLE_BATTLE && gBattleStruct->throwingPokeBall) { + // if we choose to throw a ball with our second mon, skip the action of the first + // (if we have chosen throw ball with first, second's is already skipped) + gChosenActionByBattler[B_POSITION_PLAYER_LEFT] = B_ACTION_NOTHING_FAINTED; + } + gBattleMainFunc = SetActionsAndBattlersTurnOrder; if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) From 88476e0ac27c7fe44450a3f27feebc588ea95090 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Tue, 31 Aug 2021 12:59:20 -0400 Subject: [PATCH 13/58] remove 2nd case in CanThrowBall --- src/item_use.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/item_use.c b/src/item_use.c index ad7a46499..5a5cd6a52 100755 --- a/src/item_use.c +++ b/src/item_use.c @@ -943,11 +943,14 @@ u32 CanThrowBall(void) { return 1; // There are two present pokemon. } - else if (gBattlerInMenuId == GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT) + /*else if (gBattlerInMenuId == GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT) && IsBattlerAlive(GetBattlerAtPosition(B_POSITION_PLAYER_LEFT))) { + /* * this is removed. instead, selecting a ball to throw with the second mon just clears the action of your first mon. + * see the end of HandleTurnActionSelectionState in battle_main.c + */ return 2; // Attempting to throw a ball with the second pokemon while both are alive. - } + }*/ else if (IsPlayerPartyAndPokemonStorageFull() == TRUE) { return 3; // No room for mon From 39a254f80d240243f6e3a0568d0ae98f3ba0d5a5 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Wed, 1 Sep 2021 07:45:41 -0400 Subject: [PATCH 14/58] fix sprite pos changes --- src/battle_interface.c | 24 ++++++++++++------------ src/item_use.c | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/battle_interface.c b/src/battle_interface.c index e17036faa..5f3eecaac 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -3218,8 +3218,8 @@ void TryAddLastUsedBallItemSprites(void) if (gBattleStruct->ballSpriteIds[0] == MAX_SPRITES) { gBattleStruct->ballSpriteIds[0] = AddItemIconSprite(102, 102, gSaveBlock2Ptr->lastUsedBall); - gSprites[gBattleStruct->ballSpriteIds[0]].pos1.x = LAST_USED_BALL_X_0; - gSprites[gBattleStruct->ballSpriteIds[0]].pos1.y = LAST_USED_BALL_Y; + gSprites[gBattleStruct->ballSpriteIds[0]].x = LAST_USED_BALL_X_0; + gSprites[gBattleStruct->ballSpriteIds[0]].y = LAST_USED_BALL_Y; gSprites[gBattleStruct->ballSpriteIds[0]].sHide = FALSE; // restore gSprites[gBattleStruct->ballSpriteIds[0]].callback = SpriteCB_LastUsedBall; } @@ -3258,16 +3258,16 @@ static void SpriteCB_LastUsedBallWin(struct Sprite *sprite) { if (sprite->sHide) { - if (sprite->pos1.x != LAST_BALL_WIN_X_0) - sprite->pos1.x--; + if (sprite->x != LAST_BALL_WIN_X_0) + sprite->x--; - if (sprite->pos1.x == LAST_BALL_WIN_X_0) + if (sprite->x == LAST_BALL_WIN_X_0) DestroyLastUsedBallWinGfx(sprite); } else { - if (sprite->pos1.x != LAST_BALL_WIN_X_F) - sprite->pos1.x++; + if (sprite->x != LAST_BALL_WIN_X_F) + sprite->x++; } } @@ -3275,16 +3275,16 @@ static void SpriteCB_LastUsedBall(struct Sprite *sprite) { if (sprite->sHide) { - if (sprite->pos1.x != LAST_USED_BALL_X_0) - sprite->pos1.x--; + if (sprite->x != LAST_USED_BALL_X_0) + sprite->x--; - if (sprite->pos1.x == LAST_USED_BALL_X_0) + if (sprite->x == LAST_USED_BALL_X_0) DestroyLastUsedBallGfx(sprite); } else { - if (sprite->pos1.x != LAST_USED_BALL_X_F) - sprite->pos1.x++; + if (sprite->x != LAST_USED_BALL_X_F) + sprite->x++; } } diff --git a/src/item_use.c b/src/item_use.c index d0aa82b85..63854a1ac 100755 --- a/src/item_use.c +++ b/src/item_use.c @@ -966,7 +966,7 @@ void ItemUseInBattle_PokeBall(u8 taskId) break; case 1: // There are two present pokemon. if (!InBattlePyramid()) - DisplayItemMessage(taskId, 1, sText_CantThrowPokeBall_TwoMons, BagMenu_InitListsMenu); + DisplayItemMessage(taskId, 1, sText_CantThrowPokeBall_TwoMons, CloseItemMessage); else DisplayItemMessageInBattlePyramid(taskId, sText_CantThrowPokeBall_TwoMons, Task_CloseBattlePyramidBagMessage); break; From 9c94eb6140a0752d5bef391c3679c68af14d5404 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Thu, 16 Sep 2021 10:24:32 -0400 Subject: [PATCH 15/58] 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 662bfbf2f..a2d940737 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 2d6db5a28..177c657ce 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 3fbefe55b..576884d81 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 7e7bb6ca9..6c5e3872a 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 05702aec6..a719db550 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 16/58] 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 73d5c3deb..53e933944 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 841e30327..70a8f51e9 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 657341b5e..a63aca114 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 3f34fec42fb3aa55173e207c384e3b40f1e46591 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Thu, 23 Sep 2021 12:03:01 -0400 Subject: [PATCH 17/58] change last ball graphic based on config. replace saveblock field with ewram field --- .../battle_interface/last_used_ball_l.png | Bin 0 -> 214 bytes ...ast_used_ball.png => last_used_ball_r.png} | Bin include/battle.h | 1 + src/battle_interface.c | 36 ++++++++++++++---- src/battle_main.c | 1 + src/battle_script_commands.c | 2 +- src/battle_util.c | 2 +- 7 files changed, 32 insertions(+), 10 deletions(-) create mode 100644 graphics/battle_interface/last_used_ball_l.png rename graphics/battle_interface/{last_used_ball.png => last_used_ball_r.png} (100%) diff --git a/graphics/battle_interface/last_used_ball_l.png b/graphics/battle_interface/last_used_ball_l.png new file mode 100644 index 0000000000000000000000000000000000000000..90fcef37398ed2b8bef3c2cc0649bc4ad9a8fac1 GIT binary patch literal 214 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfvg8-ipSH_Le)y2(0UQw2Yj+z{f zK*sa;Uw{7n50nRj?BZfCCy?fA*Uq){^Z*&j&Z>)mRHCPgV~EDY^unv_P&x8 zS#yg)?8er2d6p7uYPU)$efU;Y`Lk$&!&Tdk1N(LxH11ySDHySpEAoNZk!hg?jk{ML zNYHg+U~^;L!1<<%`?2$5R*B*OhF;5_9Y;HAOBfhR1(d!8PtREbw2Z;i)z4*}Q$iB} D1m#Ns literal 0 HcmV?d00001 diff --git a/graphics/battle_interface/last_used_ball.png b/graphics/battle_interface/last_used_ball_r.png similarity index 100% rename from graphics/battle_interface/last_used_ball.png rename to graphics/battle_interface/last_used_ball_r.png diff --git a/include/battle.h b/include/battle.h index 54693a33b..0becc4dd4 100644 --- a/include/battle.h +++ b/include/battle.h @@ -890,5 +890,6 @@ extern u8 gNumberOfMovesToChoose; extern u8 gBattleControllerData[MAX_BATTLERS_COUNT]; extern bool8 gHasFetchedBall; extern u8 gLastUsedBall; +extern u16 gLastThrownBall; #endif // GUARD_BATTLE_H diff --git a/src/battle_interface.c b/src/battle_interface.c index 5f3eecaac..4a3d1eaec 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -30,6 +30,7 @@ #include "item_icon.h" #include "item_use.h" #include "item.h" +#include "constants/items.h" enum { // Corresponds to gHealthboxElementsGfxTable (and the tables after it) in graphics.c @@ -3175,7 +3176,11 @@ static const struct SpriteTemplate sSpriteTemplate_LastUsedBallWindow = .callback = SpriteCB_LastUsedBallWin }; -static const u8 sLastUsedBallWindowGfx[] = INCBIN_U8("graphics/battle_interface/last_used_ball.4bpp"); +#if B_LAST_USED_BALL_BUTTON == R_BUTTON + static const u8 sLastUsedBallWindowGfx[] = INCBIN_U8("graphics/battle_interface/last_used_ball_r.4bpp"); +#else + static const u8 sLastUsedBallWindowGfx[] = INCBIN_U8("graphics/battle_interface/last_used_ball_r.4bpp"); +#endif static const struct SpriteSheet sSpriteSheet_LastUsedBallWindow = { sLastUsedBallWindowGfx, sizeof(sLastUsedBallWindowGfx), LAST_BALL_WINDOW_TAG @@ -3193,31 +3198,39 @@ static const struct SpriteSheet sSpriteSheet_LastUsedBallWindow = bool32 CanThrowLastUsedBall(void) { - return (!(CanThrowBall() != 0 - || (gBattleTypeFlags & BATTLE_TYPE_TRAINER) - || !CheckBagHasItem(gSaveBlock2Ptr->lastUsedBall, 1))); + #if B_LAST_USED_BALL == FALSE + return FALSE; + #else + return (!(CanThrowBall() != 0 + || (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + || !CheckBagHasItem(gLastThrownBall, 1))); + #endif } void TryAddLastUsedBallItemSprites(void) { - if (gSaveBlock2Ptr->lastUsedBall != 0 && !CheckBagHasItem(gSaveBlock2Ptr->lastUsedBall, 1)) + #if B_LAST_USED_BALL == TRUE + if (gLastThrownBall == 0) + gLastThrownBall = ITEM_POKE_BALL; + + if (gLastThrownBall != 0 && !CheckBagHasItem(gLastThrownBall, 1)) { // we're out of the last used ball, so just set it to the first ball in the bag // we have to compact the bag first bc it is typically only compacted when you open it CompactItemsInBagPocket(&gBagPockets[BALLS_POCKET]); - gSaveBlock2Ptr->lastUsedBall = gBagPockets[BALLS_POCKET].itemSlots[0].itemId; + gLastThrownBall = gBagPockets[BALLS_POCKET].itemSlots[0].itemId; } if (CanThrowBall() != 0 || (gBattleTypeFlags & BATTLE_TYPE_TRAINER) - || !CheckBagHasItem(gSaveBlock2Ptr->lastUsedBall, 1)) + || !CheckBagHasItem(gLastThrownBall, 1)) return; // ball if (gBattleStruct->ballSpriteIds[0] == MAX_SPRITES) { - gBattleStruct->ballSpriteIds[0] = AddItemIconSprite(102, 102, gSaveBlock2Ptr->lastUsedBall); + gBattleStruct->ballSpriteIds[0] = AddItemIconSprite(102, 102, gLastThrownBall); gSprites[gBattleStruct->ballSpriteIds[0]].x = LAST_USED_BALL_X_0; gSprites[gBattleStruct->ballSpriteIds[0]].y = LAST_USED_BALL_Y; gSprites[gBattleStruct->ballSpriteIds[0]].sHide = FALSE; // restore @@ -3236,6 +3249,7 @@ void TryAddLastUsedBallItemSprites(void) LAST_USED_WIN_Y, 5); gSprites[gBattleStruct->ballSpriteIds[0]].sHide = FALSE; // restore } + #endif } static void DestroyLastUsedBallWinGfx(struct Sprite *sprite) @@ -3290,6 +3304,7 @@ static void SpriteCB_LastUsedBall(struct Sprite *sprite) static void TryHideOrRestoreLastUsedBall(u8 caseId) { + #if B_LAST_USED_BALL == TRUE if (gBattleStruct->ballSpriteIds[0] == MAX_SPRITES) return; @@ -3308,18 +3323,23 @@ static void TryHideOrRestoreLastUsedBall(u8 caseId) gSprites[gBattleStruct->ballSpriteIds[1]].sHide = FALSE; // restore break; } + #endif } void TryHideLastUsedBall(void) { + #if B_LAST_USED_BALL == TRUE TryHideOrRestoreLastUsedBall(0); + #endif } void TryRestoreLastUsedBall(void) { + #if B_LAST_USED_BALL == TRUE if (gBattleStruct->ballSpriteIds[0] != MAX_SPRITES) TryHideOrRestoreLastUsedBall(1); else TryAddLastUsedBallItemSprites(); + #endif } diff --git a/src/battle_main.c b/src/battle_main.c index b1cc8bbc4..b8b013635 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -230,6 +230,7 @@ EWRAM_DATA u16 gPartnerSpriteId = 0; EWRAM_DATA struct TotemBoost gTotemBoosts[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA bool8 gHasFetchedBall = FALSE; EWRAM_DATA u8 gLastUsedBall = 0; +EWRAM_DATA u16 gLastThrownBall = 0; // IWRAM common vars void (*gPreBattleCallback1)(void); diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index cd64a2497..313f47878 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -12021,7 +12021,7 @@ static void Cmd_handleballthrow(void) u32 odds; u8 catchRate; - gSaveBlock2Ptr->lastUsedBall = gLastUsedItem; + gLastThrownBall = gLastUsedItem; if (gLastUsedItem == ITEM_SAFARI_BALL) catchRate = gBattleStruct->safariCatchFactor * 1275 / 100; else diff --git a/src/battle_util.c b/src/battle_util.c index 04070bf7e..f482d40dd 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -759,7 +759,7 @@ void HandleAction_ThrowBall(void) gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; gBattle_BG0_X = 0; gBattle_BG0_Y = 0; - gLastUsedItem = gSaveBlock2Ptr->lastUsedBall; + gLastUsedItem = gLastThrownBall; RemoveBagItem(gLastUsedItem, 1); gBattlescriptCurrInstr = BattleScript_BallThrow; gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; From 768598b1545b361a3a5f3e312a2d66c2d510f1a3 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Thu, 23 Sep 2021 12:22:36 -0400 Subject: [PATCH 18/58] fix bad merge --- include/battle_util.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/battle_util.h b/include/battle_util.h index d01ca3411..15b238b17 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -48,7 +48,6 @@ struct TypePower extern const struct TypePower gNaturalGiftTable[]; void HandleAction_ThrowBall(void); -bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide); bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move); void HandleAction_UseMove(void); void HandleAction_Switch(void); From 3925c07c1a2e7c6b3803e66f49f4af316fe26aec Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Thu, 23 Sep 2021 13:20:32 -0400 Subject: [PATCH 19/58] fix l graphic --- src/battle_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_interface.c b/src/battle_interface.c index 4a3d1eaec..63a05860d 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -3179,7 +3179,7 @@ static const struct SpriteTemplate sSpriteTemplate_LastUsedBallWindow = #if B_LAST_USED_BALL_BUTTON == R_BUTTON static const u8 sLastUsedBallWindowGfx[] = INCBIN_U8("graphics/battle_interface/last_used_ball_r.4bpp"); #else - static const u8 sLastUsedBallWindowGfx[] = INCBIN_U8("graphics/battle_interface/last_used_ball_r.4bpp"); + static const u8 sLastUsedBallWindowGfx[] = INCBIN_U8("graphics/battle_interface/last_used_ball_l.4bpp"); #endif static const struct SpriteSheet sSpriteSheet_LastUsedBallWindow = { From 728756052160a844db62cd746b39666a42215b7e Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Fri, 1 Oct 2021 18:28:51 -0300 Subject: [PATCH 20/58] Fixed confuse berries affecting the wrong battler. --- data/battle_scripts_1.s | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index f1f5995ff..2ce0adf68 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -8041,22 +8041,22 @@ BattleScript_BerryConfuseHealEnd2_Anim: end2 BattleScript_BerryConfuseHealRet:: - jumpifability BS_SCRIPTING, ABILITY_RIPEN, BattleScript_BerryConfuseHealRet_AbilityPopup + jumpifability BS_ATTACKER, ABILITY_RIPEN, BattleScript_BerryConfuseHealRet_AbilityPopup goto BattleScript_BerryConfuseHealRet_Anim BattleScript_BerryConfuseHealRet_AbilityPopup: call BattleScript_AbilityPopUp BattleScript_BerryConfuseHealRet_Anim: - playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT, NULL + playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT, NULL printstring STRINGID_PKMNSITEMRESTOREDHEALTH waitmessage B_WAIT_TIME_LONG orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE - healthbarupdate BS_SCRIPTING - datahpupdate BS_SCRIPTING + healthbarupdate BS_ATTACKER + datahpupdate BS_ATTACKER printstring STRINGID_FORXCOMMAYZ waitmessage B_WAIT_TIME_LONG setmoveeffect MOVE_EFFECT_CONFUSION | MOVE_EFFECT_AFFECTS_USER seteffectprimary - removeitem BS_SCRIPTING + removeitem BS_ATTACKER return BattleScript_BerryStatRaiseEnd2:: From 1ad8448532c33f0962e1bfe8c6838ccc22b23686 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Wed, 6 Oct 2021 13:54:33 -0400 Subject: [PATCH 21/58] remove saveblock field --- include/global.h | 3 +-- src/new_game.c | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/include/global.h b/include/global.h index a0aa45d3d..53a6175a2 100644 --- a/include/global.h +++ b/include/global.h @@ -485,8 +485,7 @@ struct SaveBlock2 u16 optionsBattleSceneOff:1; // whether battle animations are disabled u16 regionMapZoom:1; // whether the map is zoomed in /*0x18*/ struct Pokedex pokedex; - /*0x90*/ u16 lastUsedBall; - /*0x92*/ u8 filler_90[0x6]; + /*0x90*/ u8 filler_90[0x8]; /*0x98*/ struct Time localTimeOffset; /*0xA0*/ struct Time lastBerryTreeUpdate; /*0xA8*/ u32 gcnLinkFlags; // Read by Pokemon Colosseum/XD diff --git a/src/new_game.c b/src/new_game.c index c1dd85e90..e0453c9ad 100644 --- a/src/new_game.c +++ b/src/new_game.c @@ -205,7 +205,6 @@ void NewGameInitData(void) WipeTrainerNameRecords(); ResetTrainerHillResults(); ResetContestLinkResults(); - gSaveBlock2Ptr->lastUsedBall = ITEM_POKE_BALL; } static void ResetMiniGamesRecords(void) From 3d24fd5f3094a20cf1325607148323e397a6f00c Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Wed, 6 Oct 2021 13:56:04 -0400 Subject: [PATCH 22/58] last ball defaults to first bag pocket item --- src/battle_interface.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/battle_interface.c b/src/battle_interface.c index c1f76c6ce..b3bb981c7 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -3206,10 +3206,8 @@ bool32 CanThrowLastUsedBall(void) void TryAddLastUsedBallItemSprites(void) { #if B_LAST_USED_BALL == TRUE - if (gLastThrownBall == 0) - gLastThrownBall = ITEM_POKE_BALL; - - if (gLastThrownBall != 0 && !CheckBagHasItem(gLastThrownBall, 1)) + if ((gLastThrownBall == 0 + || (gLastThrownBall != 0 && !CheckBagHasItem(gLastThrownBall, 1))) { // we're out of the last used ball, so just set it to the first ball in the bag // we have to compact the bag first bc it is typically only compacted when you open it From 33d19d4e348a5bdf0009ebe488e61a78684ca00a Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Wed, 6 Oct 2021 14:19:15 -0400 Subject: [PATCH 23/58] syntax fix --- src/battle_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_interface.c b/src/battle_interface.c index b3bb981c7..0e33455ac 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -3206,7 +3206,7 @@ bool32 CanThrowLastUsedBall(void) void TryAddLastUsedBallItemSprites(void) { #if B_LAST_USED_BALL == TRUE - if ((gLastThrownBall == 0 + if (gLastThrownBall == 0 || (gLastThrownBall != 0 && !CheckBagHasItem(gLastThrownBall, 1))) { // we're out of the last used ball, so just set it to the first ball in the bag From 11f4f0f08e42a2d6b9c0ba56b9938e755601ea7e Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Wed, 6 Oct 2021 14:41:48 -0400 Subject: [PATCH 24/58] 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 a63aca114..98b30951e 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 5f5df066d618a6383dc2858460d5e2076f18d7a5 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Wed, 6 Oct 2021 15:18:42 -0400 Subject: [PATCH 25/58] fix perish song + soundproof --- data/battle_scripts_1.s | 1 + src/battle_util.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 0615e1239..0939b5b18 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -3878,6 +3878,7 @@ BattleScript_PerishSongLoopIncrement:: goto BattleScript_MoveEnd BattleScript_PerishSongBlocked:: + copybyte sBATTLER, gBattlerTarget printstring STRINGID_PKMNSXBLOCKSY2 waitmessage B_WAIT_TIME_LONG goto BattleScript_PerishSongLoopIncrement diff --git a/src/battle_util.c b/src/battle_util.c index a709aaf9e..cd5997f1f 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -4458,7 +4458,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move } break; case ABILITYEFFECT_MOVES_BLOCK: // 2 - if ((gLastUsedAbility == ABILITY_SOUNDPROOF && gBattleMoves[move].flags & FLAG_SOUND) + if ((gLastUsedAbility == ABILITY_SOUNDPROOF && gBattleMoves[move].flags & FLAG_SOUND && gCurrentMove != MOVE_PERISH_SONG) || (gLastUsedAbility == ABILITY_BULLETPROOF && gBattleMoves[move].flags & FLAG_BALLISTIC)) { if (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS) From 1afc43a0e8259ad1b1f025f544cfec1884c68fdb Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Wed, 6 Oct 2021 15:30:44 -0400 Subject: [PATCH 26/58] fix DoesSubstituteBlockMove calls --- src/battle_script_commands.c | 6 +++--- src/battle_util.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 12f7763e3..35c5fee1a 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -5139,7 +5139,7 @@ static void Cmd_moveend(void) // Attacker is the damage-dealer, battler is mon to be switched out if (IsBattlerAlive(battler) && GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_EJECT_BUTTON - && !DoesSubstituteBlockMove(gCurrentMove, gBattlerAttacker, battler) + && !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) && (gSpecialStatuses[battler].physicalDmg != 0 || gSpecialStatuses[battler].specialDmg != 0) && CountUsablePartyMons(battler) > 0) // Has mon to switch into { @@ -5173,7 +5173,7 @@ static void Cmd_moveend(void) // Attacker is the one to be switched out, battler is one with red card if (battler != gBattlerAttacker && IsBattlerAlive(battler) - && !DoesSubstituteBlockMove(gCurrentMove, gBattlerAttacker, battler) + && !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) && GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_RED_CARD && (gSpecialStatuses[battler].physicalDmg != 0 || gSpecialStatuses[battler].specialDmg != 0) && CanBattlerSwitch(gBattlerAttacker)) @@ -5240,7 +5240,7 @@ static void Cmd_moveend(void) if (battler != gBattlerAttacker // Cannot pickpocket yourself && GetBattlerAbility(battler) == ABILITY_PICKPOCKET // Target must have pickpocket ability && BATTLER_DAMAGED(battler) // Target needs to have been damaged - && !DoesSubstituteBlockMove(gCurrentMove, gBattlerAttacker, battler) // Subsitute unaffected + && !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) // Subsitute unaffected && IsBattlerAlive(battler) // Battler must be alive to pickpocket && gBattleMons[battler].item == ITEM_NONE // Pickpocketer can't have an item already && CanStealItem(battler, gBattlerAttacker, gBattleMons[gBattlerAttacker].item)) // Cannot steal plates, mega stones, etc diff --git a/src/battle_util.c b/src/battle_util.c index a709aaf9e..31e5e14fc 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -6810,7 +6810,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) if (TARGET_TURN_DAMAGED && (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) && IsMoveMakingContact(gCurrentMove, gBattlerAttacker) - && !DoesSubstituteBlockMove(gCurrentMove, gBattlerAttacker, battlerId) + && !DoesSubstituteBlockMove(gBattlerAttacker, battlerId, gCurrentMove) && IsBattlerAlive(gBattlerAttacker) && CanStealItem(gBattlerAttacker, gBattlerTarget, gBattleMons[gBattlerTarget].item) && gBattleMons[gBattlerAttacker].item == ITEM_NONE) From db0d9f62358f8dfd44ff4bd5e5042c5f451a9762 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 8 Oct 2021 08:22:49 -0400 Subject: [PATCH 27/58] sound moves targeting user not blocked by own soundproof --- src/battle_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_util.c b/src/battle_util.c index cd5997f1f..81389effd 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -4458,7 +4458,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move } break; case ABILITYEFFECT_MOVES_BLOCK: // 2 - if ((gLastUsedAbility == ABILITY_SOUNDPROOF && gBattleMoves[move].flags & FLAG_SOUND && gCurrentMove != MOVE_PERISH_SONG) + if ((gLastUsedAbility == ABILITY_SOUNDPROOF && gBattleMoves[move].flags & FLAG_SOUND && !(gBattleMoves[move].target & MOVE_TARGET_USER)) || (gLastUsedAbility == ABILITY_BULLETPROOF && gBattleMoves[move].flags & FLAG_BALLISTIC)) { if (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS) From 274e964d9144a9b2c64710d8a4b0150e06899fde Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Sat, 9 Oct 2021 15:05:01 +1300 Subject: [PATCH 28/58] Fix Safety Googles Fix typo and update gLastUsedItem before calling the safety goggles battle script. --- data/battle_scripts_1.s | 2 +- include/constants/battle_string_ids.h | 2 +- include/constants/hold_effects.h | 2 +- src/battle_ai_util.c | 10 +++++----- src/battle_debug.c | 4 ++-- src/battle_message.c | 4 ++-- src/battle_script_commands.c | 4 ++-- src/battle_util.c | 7 ++++--- 8 files changed, 18 insertions(+), 17 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 67f7762ac..38538747b 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -6797,7 +6797,7 @@ BattleScript_PowderMoveNoEffect:: pause B_WAIT_TIME_SHORT jumpiftype BS_TARGET, TYPE_GRASS, BattleScript_PowderMoveNoEffectPrint jumpifability BS_TARGET, ABILITY_OVERCOAT, BattleScript_PowderMoveNoEffectOvercoat - printstring STRINGID_SAFETYGOOGLESPROTECTED + printstring STRINGID_SAFETYGOGGLESPROTECTED goto BattleScript_PowderMoveNoEffectWaitMsg BattleScript_PowderMoveNoEffectOvercoat: call BattleScript_AbilityPopUp diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index b74c9cd14..e8fe7e359 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -523,7 +523,7 @@ #define STRINGID_GRASSYTERRAINHEALS 519 #define STRINGID_ELECTRICTERRAINPREVENTS 520 #define STRINGID_PSYCHICTERRAINPREVENTS 521 -#define STRINGID_SAFETYGOOGLESPROTECTED 522 +#define STRINGID_SAFETYGOGGLESPROTECTED 522 #define STRINGID_FLOWERVEILPROTECTED 523 #define STRINGID_SWEETVEILPROTECTED 524 #define STRINGID_AROMAVEILPROTECTED 525 diff --git a/include/constants/hold_effects.h b/include/constants/hold_effects.h index 3dc4a1389..d7d74d3e1 100644 --- a/include/constants/hold_effects.h +++ b/include/constants/hold_effects.h @@ -130,7 +130,7 @@ // Gen6 hold effects #define HOLD_EFFECT_FAIRY_POWER 139 #define HOLD_EFFECT_MEGA_STONE 140 -#define HOLD_EFFECT_SAFETY_GOOGLES 141 +#define HOLD_EFFECT_SAFETY_GOGGLES 141 #define HOLD_EFFECT_LUMINOUS_MOSS 142 #define HOLD_EFFECT_SNOWBALL 143 #define HOLD_EFFECT_WEAKNESS_POLICY 144 diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 95d979e94..fef6e6c6f 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -643,7 +643,7 @@ bool32 IsAffectedByPowder(u8 battler, u16 ability, u16 holdEffect) { if ((B_POWDER_GRASS >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GRASS)) || ability == ABILITY_OVERCOAT - || holdEffect == HOLD_EFFECT_SAFETY_GOOGLES) + || holdEffect == HOLD_EFFECT_SAFETY_GOGGLES) return FALSE; return TRUE; } @@ -1448,7 +1448,7 @@ bool32 ShouldSetSandstorm(u8 battler, u16 ability, u16 holdEffect) || ability == ABILITY_SAND_FORCE || ability == ABILITY_OVERCOAT || ability == ABILITY_MAGIC_GUARD - || holdEffect == HOLD_EFFECT_SAFETY_GOOGLES + || holdEffect == HOLD_EFFECT_SAFETY_GOGGLES || IS_BATTLER_OF_TYPE(battler, TYPE_ROCK) || IS_BATTLER_OF_TYPE(battler, TYPE_STEEL) || IS_BATTLER_OF_TYPE(battler, TYPE_GROUND) @@ -1473,7 +1473,7 @@ bool32 ShouldSetHail(u8 battler, u16 ability, u16 holdEffect) || ability == ABILITY_SLUSH_RUSH || ability == ABILITY_MAGIC_GUARD || ability == ABILITY_OVERCOAT - || holdEffect == HOLD_EFFECT_SAFETY_GOOGLES + || holdEffect == HOLD_EFFECT_SAFETY_GOGGLES || IS_BATTLER_OF_TYPE(battler, TYPE_ICE) || HasMove(battler, MOVE_BLIZZARD) || HasMoveEffect(battler, EFFECT_AURORA_VEIL) @@ -2273,7 +2273,7 @@ static u32 GetWeatherDamage(u8 battlerId) { if (BattlerAffectedBySandstorm(battlerId, ability) && !(gStatuses3[battlerId] & (STATUS3_UNDERGROUND | STATUS3_UNDERWATER)) - && holdEffect != HOLD_EFFECT_SAFETY_GOOGLES) + && holdEffect != HOLD_EFFECT_SAFETY_GOGGLES) { damage = gBattleMons[battlerId].maxHP / 16; if (damage == 0) @@ -2284,7 +2284,7 @@ static u32 GetWeatherDamage(u8 battlerId) { if (BattlerAffectedByHail(battlerId, ability) && !(gStatuses3[battlerId] & (STATUS3_UNDERGROUND | STATUS3_UNDERWATER)) - && holdEffect != HOLD_EFFECT_SAFETY_GOOGLES) + && holdEffect != HOLD_EFFECT_SAFETY_GOGGLES) { damage = gBattleMons[battlerId].maxHP / 16; if (damage == 0) diff --git a/src/battle_debug.c b/src/battle_debug.c index b9cfcdc03..ce5aa4a97 100644 --- a/src/battle_debug.c +++ b/src/battle_debug.c @@ -1951,7 +1951,7 @@ static const u8 sText_HoldEffectAbsorbBulb[] = _("Absorb Bulb"); static const u8 sText_HoldEffectCellBattery[] = _("Cell Battery"); static const u8 sText_HoldEffectFairyPower[] = _("Fairy Power"); static const u8 sText_HoldEffectMegaStone[] = _("Mega Stone"); -static const u8 sText_HoldEffectSafetyGoogles[] = _("Safety Googles"); +static const u8 sText_HoldEffectSafetyGoggles[] = _("Safety Goggles"); static const u8 sText_HoldEffectLuminousMoss[] = _("Luminous Moss"); static const u8 sText_HoldEffectSnowball[] = _("Snowball"); static const u8 sText_HoldEffectWeaknessPolicy[] = _("Weakness Policy"); @@ -2091,7 +2091,7 @@ static const u8 *const sHoldEffectNames[] = [HOLD_EFFECT_CELL_BATTERY] = sText_HoldEffectCellBattery, [HOLD_EFFECT_FAIRY_POWER] = sText_HoldEffectFairyPower, [HOLD_EFFECT_MEGA_STONE] = sText_HoldEffectMegaStone, - [HOLD_EFFECT_SAFETY_GOOGLES] = sText_HoldEffectSafetyGoogles, + [HOLD_EFFECT_SAFETY_GOGGLES] = sText_HoldEffectSafetyGoggles, [HOLD_EFFECT_LUMINOUS_MOSS] = sText_HoldEffectLuminousMoss, [HOLD_EFFECT_SNOWBALL] = sText_HoldEffectSnowball, [HOLD_EFFECT_WEAKNESS_POLICY] = sText_HoldEffectWeaknessPolicy, diff --git a/src/battle_message.c b/src/battle_message.c index f8df8f4b8..69463ce69 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -653,7 +653,7 @@ static const u8 sText_MistyTerrainPreventsStatus[] = _("{B_DEF_NAME_WITH_PREFIX} static const u8 sText_GrassyTerrainHeals[] = _("{B_ATK_NAME_WITH_PREFIX} is healed\nby the grassy terrain!"); static const u8 sText_ElectricTerrainPreventsSleep[] = _("{B_DEF_NAME_WITH_PREFIX} surrounds itself\nwith electrified terrain!"); static const u8 sText_PsychicTerrainPreventsPriority[] = _("{B_DEF_NAME_WITH_PREFIX} surrounds itself\nwith psychic terrain!"); -static const u8 sText_SafetyGooglesProtected[] = _("{B_DEF_NAME_WITH_PREFIX} is not affected\nthanks to its {B_LAST_ITEM}!"); +static const u8 sText_SafetyGogglesProtected[] = _("{B_DEF_NAME_WITH_PREFIX} is not affected\nthanks to its {B_LAST_ITEM}!"); static const u8 sText_FlowerVeilProtected[] = _("{B_DEF_NAME_WITH_PREFIX} surrounded itself\nwith a veil of petals!"); static const u8 sText_SweetVeilProtected[] = _("{B_DEF_NAME_WITH_PREFIX} surrounded itself\nwith a veil of sweetness!"); static const u8 sText_AromaVeilProtected[] = _("{B_DEF_NAME_WITH_PREFIX} is protected\nby an aromatic veil!"); @@ -780,7 +780,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_AROMAVEILPROTECTED - 12] = sText_AromaVeilProtected, [STRINGID_SWEETVEILPROTECTED - 12] = sText_SweetVeilProtected, [STRINGID_FLOWERVEILPROTECTED - 12] = sText_FlowerVeilProtected, - [STRINGID_SAFETYGOOGLESPROTECTED - 12] = sText_SafetyGooglesProtected, + [STRINGID_SAFETYGOGGLESPROTECTED - 12] = sText_SafetyGogglesProtected, [STRINGID_SPECTRALTHIEFSTEAL - 12] = sText_SpectralThiefSteal, [STRINGID_BELCHCANTSELECT - 12] = sText_BelchCantUse, [STRINGID_TRAINER1LOSETEXT - 12] = sText_Trainer1LoseText, diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 3b627a020..5e5d19750 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -10129,7 +10129,7 @@ static void Cmd_weatherdamage(void) && ability != ABILITY_SAND_RUSH && ability != ABILITY_OVERCOAT && !(gStatuses3[gBattlerAttacker] & (STATUS3_UNDERGROUND | STATUS3_UNDERWATER)) - && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_SAFETY_GOOGLES) + && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_SAFETY_GOGGLES) { gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 16; if (gBattleMoveDamage == 0) @@ -10154,7 +10154,7 @@ static void Cmd_weatherdamage(void) && ability != ABILITY_OVERCOAT && ability != ABILITY_ICE_BODY && !(gStatuses3[gBattlerAttacker] & (STATUS3_UNDERGROUND | STATUS3_UNDERWATER)) - && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_SAFETY_GOOGLES) + && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_SAFETY_GOGGLES) { gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 16; if (gBattleMoveDamage == 0) diff --git a/src/battle_util.c b/src/battle_util.c index 01ee1a691..34855ecd3 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -3386,9 +3386,10 @@ u8 AtkCanceller_UnableToUseMove(void) gBattlerAbility = gBattlerTarget; effect = 1; } - else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_SAFETY_GOOGLES) + else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_SAFETY_GOGGLES) { - RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_SAFETY_GOOGLES); + RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_SAFETY_GOGGLES); + gLastUsedItem = gBattleMons[gBattlerTarget].item; effect = 1; } @@ -4882,7 +4883,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move case ABILITY_EFFECT_SPORE: if (!IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GRASS) && GetBattlerAbility(gBattlerAttacker) != ABILITY_OVERCOAT - && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_SAFETY_GOOGLES) + && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_SAFETY_GOGGLES) { i = Random() % 3; if (i == 0) From 01f563cb5e11c3ba3f38a6084fd9abadd1413f5e Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Sun, 10 Oct 2021 08:46:31 -0300 Subject: [PATCH 29/58] Fix infinite loop --- data/battle_scripts_1.s | 22 +++++++++++----------- src/battle_util.c | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 2ce0adf68..883b90200 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -8022,41 +8022,41 @@ BattleScript_HangedOnMsgRet: return BattleScript_BerryConfuseHealEnd2:: - jumpifability BS_ATTACKER, ABILITY_RIPEN, BattleScript_BerryConfuseHealEnd2_AbilityPopup + jumpifability BS_SCRIPTING, ABILITY_RIPEN, BattleScript_BerryConfuseHealEnd2_AbilityPopup goto BattleScript_BerryConfuseHealEnd2_Anim BattleScript_BerryConfuseHealEnd2_AbilityPopup: call BattleScript_AbilityPopUp BattleScript_BerryConfuseHealEnd2_Anim: - playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT, NULL + playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT, NULL printstring STRINGID_PKMNSITEMRESTOREDHEALTH waitmessage B_WAIT_TIME_LONG orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_SCRIPTING + datahpupdate BS_SCRIPTING printstring STRINGID_FORXCOMMAYZ waitmessage B_WAIT_TIME_LONG setmoveeffect MOVE_EFFECT_CONFUSION | MOVE_EFFECT_AFFECTS_USER seteffectprimary - removeitem BS_ATTACKER + removeitem BS_SCRIPTING end2 BattleScript_BerryConfuseHealRet:: - jumpifability BS_ATTACKER, ABILITY_RIPEN, BattleScript_BerryConfuseHealRet_AbilityPopup + jumpifability BS_SCRIPTING, ABILITY_RIPEN, BattleScript_BerryConfuseHealRet_AbilityPopup goto BattleScript_BerryConfuseHealRet_Anim BattleScript_BerryConfuseHealRet_AbilityPopup: call BattleScript_AbilityPopUp BattleScript_BerryConfuseHealRet_Anim: - playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT, NULL + playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT, NULL printstring STRINGID_PKMNSITEMRESTOREDHEALTH waitmessage B_WAIT_TIME_LONG orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER + healthbarupdate BS_SCRIPTING + datahpupdate BS_SCRIPTING printstring STRINGID_FORXCOMMAYZ waitmessage B_WAIT_TIME_LONG - setmoveeffect MOVE_EFFECT_CONFUSION | MOVE_EFFECT_AFFECTS_USER + setmoveeffect MOVE_EFFECT_CONFUSION | MOVE_EFFECT_CERTAIN seteffectprimary - removeitem BS_ATTACKER + removeitem BS_TARGET return BattleScript_BerryStatRaiseEnd2:: diff --git a/src/battle_util.c b/src/battle_util.c index 20e5d91d1..b3fb71cf6 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -5574,7 +5574,7 @@ static u8 HealConfuseBerry(u32 battlerId, u32 itemId, u8 flavorId, bool32 end2) gBattleMoveDamage *= 2; gBattlerAbility = battlerId; } - + gBattleScripting.battler = battlerId; if (end2) { if (GetFlavorRelationByPersonality(gBattleMons[battlerId].personality, flavorId) < 0) From c3f8b77d8259be1190e49f55ba5532c5c72de041 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Sun, 10 Oct 2021 20:26:38 -0300 Subject: [PATCH 30/58] Setting for pre-Gen6 Hidden Power Damage. --- include/constants/battle_config.h | 1 + src/battle_util.c | 16 ++++++++++++++++ src/data/battle_moves.h | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index bcf4491f9..bce49719e 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -123,6 +123,7 @@ #define B_CRASH_IF_TARGET_IMMUNE GEN_7 // In Gen4+, The user of Jump Kick or High Jump Kick will "keep going and crash" if it attacks a target that is immune to the move. #define B_TAILWIND_TIMER GEN_7 // In Gen5+, Tailwind lasts 4 turns instead of 3. #define B_MEMENTO_FAIL GEN_7 // In Gen4+, Memento fails if there is no target or if the target is protected or behind substitute. But not if Atk/Sp. Atk are at -6. +#define B_HIDDEN_POWER_DMG GEN_7 // In Gen6+, Hidden Power's base power was set to always be 60. Before, it was determined by the mon's IVs. // Ability settings #define B_ABILITY_WEATHER GEN_7 // In Gen6+, ability-induced weather lasts 5 turns. Before, it lasted until the battle ended or until it was changed by a move or a different weather-affecting ability. diff --git a/src/battle_util.c b/src/battle_util.c index 263d7f96d..88a5cc203 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -7658,6 +7658,22 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef) basePower *= 2; #endif break; + case EFFECT_HIDDEN_POWER: + { + #if B_HIDDEN_POWER_DMG < GEN_6 + u8 powerBits; + + powerBits = ((gBattleMons[gBattlerAttacker].hpIV & 2) >> 1) + | ((gBattleMons[gBattlerAttacker].attackIV & 2) << 0) + | ((gBattleMons[gBattlerAttacker].defenseIV & 2) << 1) + | ((gBattleMons[gBattlerAttacker].speedIV & 2) << 2) + | ((gBattleMons[gBattlerAttacker].spAttackIV & 2) << 3) + | ((gBattleMons[gBattlerAttacker].spDefenseIV & 2) << 4); + + basePower = (40 * powerBits) / 63 + 30; + #endif + break; + } } // move-specific base power changes diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index 1aa8c4dfd..8d2188958 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -3753,7 +3753,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_HIDDEN_POWER] = { - #if B_UPDATED_MOVE_DATA >= GEN_6 + #if B_HIDDEN_POWER_DMG >= GEN_6 .power = 60, #else .power = 1, From fcada4fcad924a905560a726beb49733c3278382 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Sun, 10 Oct 2021 19:54:17 -0400 Subject: [PATCH 31/58] 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 3d9c66bd6..9ed0d1fcc 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 612a2e6d9..43f66db6b 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 339e5bd99..e70b990eb 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 a709aaf9e..40a100796 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; } From 6c550cd7490183b25caa294109da057de7824a8f Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Mon, 11 Oct 2021 03:16:59 -0300 Subject: [PATCH 32/58] Implemented Retaliate's effect --- include/battle.h | 1 + src/battle_main.c | 3 +++ src/battle_script_commands.c | 1 + src/battle_util.c | 6 +++++- 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/battle.h b/include/battle.h index 826a0929e..aaecb9ea1 100644 --- a/include/battle.h +++ b/include/battle.h @@ -908,5 +908,6 @@ extern u8 gBattleControllerData[MAX_BATTLERS_COUNT]; extern bool8 gHasFetchedBall; extern u8 gLastUsedBall; extern u16 gLastThrownBall; +extern bool8 gCanRetaliate; #endif // GUARD_BATTLE_H diff --git a/src/battle_main.c b/src/battle_main.c index 055ec9bbe..7d4ae76dd 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -231,6 +231,7 @@ EWRAM_DATA struct TotemBoost gTotemBoosts[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA bool8 gHasFetchedBall = FALSE; EWRAM_DATA u8 gLastUsedBall = 0; EWRAM_DATA u16 gLastThrownBall = 0; +EWRAM_DATA bool8 gCanRetaliate = FALSE; // IWRAM common vars void (*gPreBattleCallback1)(void); @@ -2876,6 +2877,8 @@ static void BattleStartClearSetData(void) gHasFetchedBall = FALSE; gLastUsedBall = 0; + gCanRetaliate = FALSE; + gBattlerAttacker = 0; gBattlerTarget = 0; gBattleWeather = 0; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 2c017b2df..b3ac59863 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3499,6 +3499,7 @@ static void Cmd_tryfaintmon(void) if (gBattleResults.playerFaintCounter < 0xFF) gBattleResults.playerFaintCounter++; AdjustFriendshipOnBattleFaint(gActiveBattler); + gCanRetaliate = TRUE; } else { diff --git a/src/battle_util.c b/src/battle_util.c index 0bca1c0e7..d588d5b08 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -7933,7 +7933,11 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe MulModifier(&modifier, UQ_4_12(2.0)); break; case EFFECT_RETALIATE: - // todo + if (gCanRetaliate) + { + MulModifier(&modifier, UQ_4_12(2.0)); + gCanRetaliate = FALSE; + } break; case EFFECT_SOLARBEAM: if (WEATHER_HAS_EFFECT && gBattleWeather & (WEATHER_HAIL_ANY | WEATHER_SANDSTORM_ANY | WEATHER_RAIN_ANY)) From 791a899eed1a4e34eed30ff80b531a96248f5008 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 11 Oct 2021 21:29:08 -0400 Subject: [PATCH 33/58] fix sand spit + primal weather --- src/battle_util.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/battle_util.c b/src/battle_util.c index 68e787698..7b0c85078 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -5028,20 +5028,21 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && !gProtectStructs[gBattlerAttacker].confusionSelfDmg && TARGET_TURN_DAMAGED - && !(WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SANDSTORM_ANY) - && TryChangeBattleWeather(battler, ENUM_WEATHER_SANDSTORM, TRUE) - && !(WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_PRIMAL_ANY)) + && !(WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SANDSTORM_ANY)) { - gBattleScripting.battler = gActiveBattler = battler; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_SandSpitActivates; - effect++; - } - else if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_PRIMAL_ANY) - { - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_BlockedByPrimalWeatherRet; - effect++; + if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_PRIMAL_ANY) + { + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_BlockedByPrimalWeatherRet; + effect++; + } + else if (TryChangeBattleWeather(battler, ENUM_WEATHER_SANDSTORM, TRUE)) + { + gBattleScripting.battler = gActiveBattler = battler; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_SandSpitActivates; + effect++; + } } break; case ABILITY_PERISH_BODY: From 11626d5043e94f9e82c458eb60ff49f19476e6bd Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Tue, 12 Oct 2021 07:53:28 -0400 Subject: [PATCH 34/58] fix memento fail condition --- src/battle_script_commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 2c017b2df..5d483aa3e 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -11520,7 +11520,7 @@ static void Cmd_jumpifattackandspecialattackcannotfall(void) // memento && gBattleMons[gBattlerTarget].statStages[STAT_SPATK] == MIN_STAT_STAGE && gBattleCommunication[MISS_TYPE] != B_MSG_PROTECTED) #else - if (gBattleCommunication[MISS_TYPE] != B_MSG_PROTECTED + if (gBattleCommunication[MISS_TYPE] == B_MSG_PROTECTED || gStatuses3[gBattlerTarget] & STATUS3_SEMI_INVULNERABLE || IsBattlerProtected(gBattlerTarget, gCurrentMove) || DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)) From b447d582cd6f929acc7aaeba3eb313dfe7df3891 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Wed, 13 Oct 2021 09:04:03 -0400 Subject: [PATCH 35/58] fix terrain timer decrementing and bg changing with anims disabled --- src/battle_script_commands.c | 31 ++++++++++++++++--------------- src/battle_util.c | 6 +++--- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 2c017b2df..6852dee1e 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4527,12 +4527,13 @@ static void Cmd_endselectionscript(void) static void Cmd_playanimation(void) { const u16* argumentPtr; + u8 animId = gBattlescriptCurrInstr[2]; gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); argumentPtr = T2_READ_PTR(gBattlescriptCurrInstr + 3); #if B_TERRAIN_BG_CHANGE == FALSE - if (gBattlescriptCurrInstr[2] == B_ANIM_RESTORE_BG) + if (animId == B_ANIM_RESTORE_BG) { // workaround for .if not working gBattlescriptCurrInstr += 7; @@ -4540,28 +4541,28 @@ static void Cmd_playanimation(void) } #endif - if (gBattlescriptCurrInstr[2] == B_ANIM_STATS_CHANGE - || gBattlescriptCurrInstr[2] == B_ANIM_SNATCH_MOVE - || gBattlescriptCurrInstr[2] == B_ANIM_MEGA_EVOLUTION - || gBattlescriptCurrInstr[2] == B_ANIM_ILLUSION_OFF - || gBattlescriptCurrInstr[2] == B_ANIM_FORM_CHANGE - || gBattlescriptCurrInstr[2] == B_ANIM_SUBSTITUTE_FADE) + if (animId == B_ANIM_STATS_CHANGE + || animId == B_ANIM_SNATCH_MOVE + || animId == B_ANIM_MEGA_EVOLUTION + || animId == B_ANIM_ILLUSION_OFF + || animId == B_ANIM_FORM_CHANGE + || animId == B_ANIM_SUBSTITUTE_FADE) { - BtlController_EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); + BtlController_EmitBattleAnimation(0, animId, *argumentPtr); MarkBattlerForControllerExec(gActiveBattler); gBattlescriptCurrInstr += 7; } - else if (gHitMarker & HITMARKER_NO_ANIMATIONS) + else if (gHitMarker & HITMARKER_NO_ANIMATIONS && animId != B_ANIM_RESTORE_BG) { 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) + else if (animId == B_ANIM_RAIN_CONTINUES + || animId == B_ANIM_SUN_CONTINUES + || animId == B_ANIM_SANDSTORM_CONTINUES + || animId == B_ANIM_HAIL_CONTINUES) { - BtlController_EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); + BtlController_EmitBattleAnimation(0, animId, *argumentPtr); MarkBattlerForControllerExec(gActiveBattler); gBattlescriptCurrInstr += 7; } @@ -4571,7 +4572,7 @@ static void Cmd_playanimation(void) } else { - BtlController_EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); + BtlController_EmitBattleAnimation(0, animId, *argumentPtr); MarkBattlerForControllerExec(gActiveBattler); gBattlescriptCurrInstr += 7; } diff --git a/src/battle_util.c b/src/battle_util.c index 68e787698..68e52f49d 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2234,7 +2234,7 @@ u8 DoFieldEndTurnEffects(void) break; case ENDTURN_ELECTRIC_TERRAIN: if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN - && ((!gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.electricTerrainTimer == 0)) + && (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.electricTerrainTimer == 0)) { gFieldStatuses &= ~(STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_TERRAIN_PERMANENT); BattleScriptExecute(BattleScript_ElectricTerrainEnds); @@ -2244,7 +2244,7 @@ u8 DoFieldEndTurnEffects(void) break; case ENDTURN_MISTY_TERRAIN: if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN - && ((!gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.mistyTerrainTimer == 0)) + && (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.mistyTerrainTimer == 0)) { gFieldStatuses &= ~(STATUS_FIELD_MISTY_TERRAIN); BattleScriptExecute(BattleScript_MistyTerrainEnds); @@ -2266,7 +2266,7 @@ u8 DoFieldEndTurnEffects(void) break; case ENDTURN_PSYCHIC_TERRAIN: if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN - && ((!gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.psychicTerrainTimer == 0)) + && (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.psychicTerrainTimer == 0)) { gFieldStatuses &= ~(STATUS_FIELD_PSYCHIC_TERRAIN); BattleScriptExecute(BattleScript_PsychicTerrainEnds); From 5108d173fc2970dc3fed4514d173eb6e5a693c2b Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Wed, 13 Oct 2021 10:11:02 -0400 Subject: [PATCH 36/58] fix protect struct fields being set during ai calcs --- src/battle_ai_main.c | 6 +++++- src/battle_main.c | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 2ab6e287e..188b30cee 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -209,7 +209,11 @@ u8 BattleAI_ChooseMoveOrAction(void) ret = ChooseMoveOrAction_Singles(); else ret = ChooseMoveOrAction_Doubles(); - + + // Clear protect structures, some flags may be set during AI calcs + // e.g. pranksterElevated from GetMovePriority + memset(&gProtectStructs[gActiveBattler], 0, sizeof(struct ProtectStruct)); + gCurrentMove = savedCurrentMove; return ret; } diff --git a/src/battle_main.c b/src/battle_main.c index 055ec9bbe..a304defee 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3097,6 +3097,7 @@ void FaintClearSetData(void) gProtectStructs[gActiveBattler].usedThroatChopPreventedMove = 0; gProtectStructs[gActiveBattler].statRaised = 0; gProtectStructs[gActiveBattler].statFell = 0; + gProtectStructs[gActiveBattler].pranksterElevated = 0; gDisableStructs[gActiveBattler].isFirstTurn = 2; From 7f2efb66190eb7351d8fae56b5e436d5d419dcb2 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Wed, 13 Oct 2021 18:39:24 -0400 Subject: [PATCH 37/58] format fixes, fix healing berries from printing message at full hp --- data/battle_scripts_1.s | 8 ++++---- src/battle_util.c | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index e842ddc39..cda99c54d 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -380,7 +380,7 @@ gBattleScriptsForMoveEffects:: .4byte BattleScript_EffectHit @ EFFECT_SNIPE_SHOT .4byte BattleScript_EffectTripleHit @ EFFECT_TRIPLE_HIT .4byte BattleScript_EffectRecoilHP25 @ EFFECT_RECOIL_HP_25 - .4byte BattleScript_EffectStuffCheeks @ EFFECT_STUFF_CHEEKS + .4byte BattleScript_EffectStuffCheeks @ EFFECT_STUFF_CHEEKS BattleScript_EffectStuffCheeks:: attackcanceler @@ -398,7 +398,7 @@ BattleScript_StuffCheeksEatBerry: setstatchanger STAT_DEF, 2, FALSE statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_ALLOW_PTR, BattleScript_StuffCheeksEnd setgraphicalstatchangevalues - jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_StuffCheeksEnd @ cant raise def + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_StuffCheeksEnd @ cant raise def playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 printfromtable gStatUpStringIds waitmessage B_WAIT_TIME_LONG @@ -661,8 +661,8 @@ BattleScript_MoveEffectBugBite:: printstring STRINGID_BUGBITE waitmessage B_WAIT_TIME_LONG orword gHitMarker, HITMARKER_NO_ANIMATIONS - setbyte sBERRY_OVERRIDE, TRUE @ override the requirements for eating berries - consumeberry BS_ATTACKER, TRUE @ consume the berry, then restore the item from changedItems + setbyte sBERRY_OVERRIDE, TRUE @ override the requirements for eating berries + consumeberry BS_ATTACKER, TRUE @ consume the berry, then restore the item from changedItems bicword gHitMarker, HITMARKER_NO_ANIMATIONS setbyte sBERRY_OVERRIDE, FALSE return diff --git a/src/battle_util.c b/src/battle_util.c index 6ecc755f6..88350b7c4 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -5862,7 +5862,8 @@ u8 TryHandleSeed(u8 battler, u32 terrainFlag, u8 statId, u16 itemId, bool32 exec static u8 ItemHealHp(u32 battlerId, u32 itemId, bool32 end2, bool32 percentHeal) { - if (HasEnoughHpToEatBerry(battlerId, 2, itemId)) + if (HasEnoughHpToEatBerry(battlerId, 2, itemId) + && !(gBattleScripting.overrideBerryRequirements && gBattleMons[battlerId].hp == gBattleMons[battlerId].maxHP)) { if (percentHeal) gBattleMoveDamage = (gBattleMons[battlerId].maxHP * GetBattlerHoldEffectParam(battlerId) / 100) * -1; From bb8d0e3d6b87d02d93e4bcbad10518e34f936b20 Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Thu, 14 Oct 2021 16:18:11 +1300 Subject: [PATCH 38/58] Fix Battle Bond Battle Bond Greninja transforms only after a KO, and doesn't revert when switched out. --- asm/macros/battle_script.inc | 4 ++++ data/battle_scripts_1.s | 1 + include/constants/battle_script_commands.h | 1 + src/battle_script_commands.c | 13 +++++++++++++ src/battle_util.c | 18 +++--------------- 5 files changed, 22 insertions(+), 15 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 4d8fe0365..7ed108bde 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1825,6 +1825,10 @@ various BS_ATTACKER, VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER .endm + .macro tryactivatebattlebond battler:req + various \battler, VARIOUS_TRY_ACTIVATE_BATTLE_BOND + .endm + @ helpful macros .macro setstatchanger stat:req, stages:req, down:req setbyte sSTATCHANGER \stat | \stages << 3 | \down << 7 diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index e1fb47930..9ec90e3df 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -5288,6 +5288,7 @@ BattleScript_FaintTarget:: tryactivatemoxie BS_ATTACKER @ and chilling neigh, as one ice rider tryactivatebeastboost BS_ATTACKER tryactivategrimneigh BS_ATTACKER @ and as one shadow rider + tryactivatebattlebond BS_ATTACKER trytrainerslidefirstdownmsg BS_TARGET return diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index d61eabbf8..29236c7b0 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -185,6 +185,7 @@ #define VARIOUS_REMOVE_TERRAIN 113 #define VARIOUS_JUMP_IF_PRANKSTER_BLOCKED 114 #define VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER 115 +#define VARIOUS_TRY_ACTIVATE_BATTLE_BOND 116 // Cmd_manipulatedamage #define DMG_CHANGE_SIGN 0 diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 2c017b2df..472487e09 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -8822,6 +8822,19 @@ static void Cmd_various(void) } break; } + case VARIOUS_TRY_ACTIVATE_BATTLE_BOND: + if (gBattleMons[gBattlerAttacker].species == SPECIES_GRENINJA_BATTLE_BOND + && HasAttackerFaintedTarget() + && CalculateEnemyPartyCount() > 1) + { + PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].species); + gBattleStruct->changedSpecies[gBattlerPartyIndexes[gBattlerAttacker]] = gBattleMons[gBattlerAttacker].species; + gBattleMons[gBattlerAttacker].species = SPECIES_GRENINJA_ASH; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_BattleBondActivatesOnMoveEndAttacker; + return; + } + break; } gBattlescriptCurrInstr += 3; diff --git a/src/battle_util.c b/src/battle_util.c index 68e787698..e4b8f9cf3 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -5147,18 +5147,6 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move effect++; } break; - case ABILITY_BATTLE_BOND: - if (gBattleMons[gBattlerAttacker].species == SPECIES_GRENINJA_BATTLE_BOND - && gBattleResults.opponentFaintCounter != 0 - && CalculateEnemyPartyCount() > 1) - { - PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].species); - gBattleStruct->changedSpecies[gBattlerPartyIndexes[gBattlerAttacker]] = gBattleMons[gBattlerAttacker].species; - gBattleMons[gBattlerAttacker].species = SPECIES_GRENINJA_ASH; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_BattleBondActivatesOnMoveEndAttacker; - } - break; } break; case ABILITYEFFECT_MOVE_END_OTHER: // Abilities that activate on *another* battler's moveend: Dancer, Soul-Heart, Receiver, Symbiosis @@ -8846,6 +8834,7 @@ void UndoFormChange(u32 monId, u32 side, bool32 isSwitchingOut) static const u16 species[][2] = // changed form id, default form id { {SPECIES_MIMIKYU_BUSTED, SPECIES_MIMIKYU}, + {SPECIES_GRENINJA_ASH, SPECIES_GRENINJA_BATTLE_BOND}, {SPECIES_AEGISLASH_BLADE, SPECIES_AEGISLASH}, {SPECIES_DARMANITAN_ZEN_MODE, SPECIES_DARMANITAN}, {SPECIES_MINIOR, SPECIES_MINIOR_CORE_RED}, @@ -8858,11 +8847,10 @@ void UndoFormChange(u32 monId, u32 side, bool32 isSwitchingOut) {SPECIES_WISHIWASHI_SCHOOL, SPECIES_WISHIWASHI}, {SPECIES_CRAMORANT_GORGING, SPECIES_CRAMORANT}, {SPECIES_CRAMORANT_GULPING, SPECIES_CRAMORANT}, - {SPECIES_GRENINJA_ASH, SPECIES_GRENINJA_BATTLE_BOND}, }; - if (isSwitchingOut) // Don't revert Mimikyu Busted when switching out - i = 1; + if (isSwitchingOut) // Don't revert Mimikyu Busted or Ash-Greninja when switching out + i = 2; else i = 0; From 85dd7ff63c40778538ece6d465f42a28a232b252 Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Thu, 14 Oct 2021 16:40:18 +1300 Subject: [PATCH 39/58] Fix Storm Drain/Dive bug If Storm Drain is triggered by dive it should clear the attacker's semi-invulnerable status. --- data/battle_scripts_1.s | 1 + 1 file changed, 1 insertion(+) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 616fe21f1..c70bddcd4 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -7525,6 +7525,7 @@ BattleScript_MoveStatDrain:: waitanimation printstring STRINGID_TARGETABILITYSTATRAISE waitmessage B_WAIT_TIME_LONG + clearsemiinvulnerablebit tryfaintmon BS_ATTACKER, FALSE, NULL goto BattleScript_MoveEnd From 85ce72a4d07cbf1f4339d03e2e774938046e98fc Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Thu, 14 Oct 2021 10:47:39 -0400 Subject: [PATCH 40/58] add shell smash anim --- data/battle_anim_scripts.s | 25 +++++++++++++++++++++++++ include/battle_anim.h | 2 ++ src/battle_anim_new.c | 34 ++++++++++++++++++++++++++++++++++ src/battle_anim_rock.c | 9 ++++----- 4 files changed, 65 insertions(+), 5 deletions(-) diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 4063885e0..794cc2c0c 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -5374,6 +5374,31 @@ ScaldHitSplats: return Move_SHELL_SMASH: + loadspritegfx ANIM_TAG_SHELL_RIGHT + loadspritegfx ANIM_TAG_SHELL_LEFT + loadspritegfx ANIM_TAG_IMPACT + loadspritegfx ANIM_TAG_ROCKS + loadspritegfx ANIM_TAG_HANDS_AND_FEET + playsewithpan SE_M_SCRATCH, SOUND_PAN_ATTACKER + createsprite gShellSmashRightShellSpriteTemplate, ANIM_ATTACKER, 2, 0xffd7, 0x0, 0x2, 0x333, 0x0, 0xa + createsprite gShellSmashLeftShellSpriteTemplate, ANIM_ATTACKER, 2, 0x20, 0x0, 0x6, 0xfccd, 0x0, 0xa + delay 10 + createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0x0, 0x1, 0x1 + createsprite gFistFootSpriteTemplate, ANIM_ATTACKER, 3, 0x0, 0x0, 0x8, 0x1, 0x0 + playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET + createvisualtask AnimTask_ShakeMon, 2, 1, 3, 0, 5, 1 + waitforvisualfinish + playsewithpan SE_M_BUBBLE, SOUND_PAN_TARGET + createsprite gShellSmashPurpleRocksSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0x0, 0x14, 0x18, 0xe, 0x2 + createsprite gShellSmashPurpleRocksSpriteTemplate, ANIM_ATTACKER, 2, 0x5, 0x0, 0xffec, 0x18, 0xe, 0x1 + createsprite gShellSmashPurpleRocksSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0x5, 0x14, 0xffe8, 0xe, 0x2 + createsprite gShellSmashPurpleRocksSpriteTemplate, ANIM_ATTACKER, 2, 0xfffb, 0x0, 0xffec, 0xffe8, 0xe, 0x2 + createsprite gShellSmashPurpleRocksSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0xfffb, 0x1e, 0x12, 0x8, 0x2 + createsprite gShellSmashPurpleRocksSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0x0, 0x1e, 0xffee, 0x8, 0x2 + createsprite gShellSmashPurpleRocksSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0x0, 0xffe2, 0x12, 0x8, 0x2 + createsprite gShellSmashPurpleRocksSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0x0, 0xffe2, 0xffee, 0x8, 0x2 + createvisualtask AnimTask_ShakeMon, 2, 1, 0, 3, 7, 1 + waitforvisualfinish end Move_HEAL_PULSE: diff --git a/include/battle_anim.h b/include/battle_anim.h index 9bc51facb..ff388c714 100644 --- a/include/battle_anim.h +++ b/include/battle_anim.h @@ -442,6 +442,7 @@ extern const union AffineAnimCmd *const gAffineAnims_SpinningHandOrFoot[]; extern const union AnimCmd *const gAnims_RevengeBigScratch[]; // battle_anim_rock.c +extern const union AnimCmd *const gAnims_FlyingRock[]; extern const union AffineAnimCmd *const gAffineAnims_Whirlpool[]; extern const union AffineAnimCmd *const gAffineAnims_BasicRock[]; void AnimParticleInVortex(struct Sprite *sprite); @@ -449,6 +450,7 @@ void AnimFallingRock(struct Sprite *sprite); void AnimRaiseSprite(struct Sprite *sprite); void AnimFallingRock_Step(struct Sprite *sprite); void AnimFlyingSandCrescent(struct Sprite *sprite); +void AnimRockFragment(struct Sprite *); // battle_anim_dark.c void AnimClawSlash(struct Sprite *sprite); diff --git a/src/battle_anim_new.c b/src/battle_anim_new.c index 0c452c236..55a617bab 100644 --- a/src/battle_anim_new.c +++ b/src/battle_anim_new.c @@ -93,6 +93,40 @@ const struct SpriteTemplate gPowerTrickSpriteTemplate = //// GEN 5 +//shell smash +const struct SpriteTemplate gShellSmashLeftShellSpriteTemplate = +{ + .tileTag = ANIM_TAG_SHELL_RIGHT, + .paletteTag = ANIM_TAG_SHELL_RIGHT, + .oam = &gOamData_AffineNormal_ObjBlend_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gAffineAnims_Bite, + .callback = AnimBite +}; + +const struct SpriteTemplate gShellSmashRightShellSpriteTemplate = +{ + .tileTag = ANIM_TAG_SHELL_LEFT, + .paletteTag = ANIM_TAG_SHELL_LEFT, + .oam = &gOamData_AffineNormal_ObjBlend_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gAffineAnims_Bite, + .callback = AnimBite +}; + +const struct SpriteTemplate gShellSmashPurpleRocksSpriteTemplate = +{ + .tileTag = ANIM_TAG_ROCKS, + .paletteTag = ANIM_TAG_SHELL_RIGHT, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gAnims_FlyingRock, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimRockFragment +}; + //wide guard const struct SpriteTemplate gWideGuardBlueConversionTemplate = { diff --git a/src/battle_anim_rock.c b/src/battle_anim_rock.c index da2d9b645..afbacc633 100644 --- a/src/battle_anim_rock.c +++ b/src/battle_anim_rock.c @@ -9,7 +9,6 @@ #include "constants/rgb.h" #include "constants/songs.h" -static void AnimRockFragment(struct Sprite *); static void AnimTask_Rollout_Step(u8 taskId); static void AnimRolloutParticle(struct Sprite *); static void AnimRockTomb(struct Sprite *); @@ -43,7 +42,7 @@ static const union AnimCmd sAnim_FlyingRock_2[] = ANIMCMD_END, }; -static const union AnimCmd *const sAnims_FlyingRock[] = +const union AnimCmd *const gAnims_FlyingRock[] = { sAnim_FlyingRock_0, sAnim_FlyingRock_1, @@ -55,7 +54,7 @@ const struct SpriteTemplate gFallingRockSpriteTemplate = .tileTag = ANIM_TAG_ROCKS, .paletteTag = ANIM_TAG_ROCKS, .oam = &gOamData_AffineOff_ObjNormal_32x32, - .anims = sAnims_FlyingRock, + .anims = gAnims_FlyingRock, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimFallingRock, @@ -66,7 +65,7 @@ const struct SpriteTemplate gRockFragmentSpriteTemplate = .tileTag = ANIM_TAG_ROCKS, .paletteTag = ANIM_TAG_ROCKS, .oam = &gOamData_AffineOff_ObjNormal_32x32, - .anims = sAnims_FlyingRock, + .anims = gAnims_FlyingRock, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimRockFragment, @@ -430,7 +429,7 @@ void AnimFallingRock_Step(struct Sprite *sprite) } // Animates the rock particles that are shown on the impact for Rock Blast / Rock Smash -static void AnimRockFragment(struct Sprite *sprite) +void AnimRockFragment(struct Sprite *sprite) { StartSpriteAnim(sprite, gBattleAnimArgs[5]); AnimateSprite(sprite); From 1f97198267a4af39788246db08f583df0fc85682 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Fri, 15 Oct 2021 05:02:14 -0300 Subject: [PATCH 41/58] Oops, I forgot to take the opponent's side into account --- include/battle.h | 3 ++- src/battle_main.c | 6 ++++-- src/battle_script_commands.c | 3 ++- src/battle_util.c | 7 +++++-- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/include/battle.h b/include/battle.h index aaecb9ea1..7958c40f5 100644 --- a/include/battle.h +++ b/include/battle.h @@ -908,6 +908,7 @@ extern u8 gBattleControllerData[MAX_BATTLERS_COUNT]; extern bool8 gHasFetchedBall; extern u8 gLastUsedBall; extern u16 gLastThrownBall; -extern bool8 gCanRetaliate; +extern bool8 gCanPlayerRetaliate; +extern bool8 gCanOpponentRetaliate; #endif // GUARD_BATTLE_H diff --git a/src/battle_main.c b/src/battle_main.c index 7d4ae76dd..ffb33da10 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -231,7 +231,8 @@ EWRAM_DATA struct TotemBoost gTotemBoosts[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA bool8 gHasFetchedBall = FALSE; EWRAM_DATA u8 gLastUsedBall = 0; EWRAM_DATA u16 gLastThrownBall = 0; -EWRAM_DATA bool8 gCanRetaliate = FALSE; +EWRAM_DATA bool8 gCanPlayerRetaliate = FALSE; +EWRAM_DATA bool8 gCanOpponentRetaliate = FALSE; // IWRAM common vars void (*gPreBattleCallback1)(void); @@ -2877,7 +2878,8 @@ static void BattleStartClearSetData(void) gHasFetchedBall = FALSE; gLastUsedBall = 0; - gCanRetaliate = FALSE; + gCanPlayerRetaliate = FALSE; + gCanOpponentRetaliate = FALSE; gBattlerAttacker = 0; gBattlerTarget = 0; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index b3ac59863..132a434cb 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3499,13 +3499,14 @@ static void Cmd_tryfaintmon(void) if (gBattleResults.playerFaintCounter < 0xFF) gBattleResults.playerFaintCounter++; AdjustFriendshipOnBattleFaint(gActiveBattler); - gCanRetaliate = TRUE; + gCanPlayerRetaliate = TRUE; } else { if (gBattleResults.opponentFaintCounter < 0xFF) gBattleResults.opponentFaintCounter++; gBattleResults.lastOpponentSpecies = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES, NULL); + gCanOpponentRetaliate = TRUE; } if ((gHitMarker & HITMARKER_DESTINYBOND) && gBattleMons[gBattlerAttacker].hp != 0) { diff --git a/src/battle_util.c b/src/battle_util.c index d588d5b08..689a846d6 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -7933,10 +7933,13 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe MulModifier(&modifier, UQ_4_12(2.0)); break; case EFFECT_RETALIATE: - if (gCanRetaliate) + if (gCanPlayerRetaliate || gCanOpponentRetaliate) { MulModifier(&modifier, UQ_4_12(2.0)); - gCanRetaliate = FALSE; + if (gCanPlayerRetaliate) + gCanPlayerRetaliate = FALSE; + else if (gCanOpponentRetaliate) + gCanOpponentRetaliate = FALSE; } break; case EFFECT_SOLARBEAM: From 3a25bce185635b9887de6eb91a9803b8e9dbb1aa Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Fri, 15 Oct 2021 06:00:24 -0300 Subject: [PATCH 42/58] Turned Retaliate's effect into a side status --- include/battle.h | 2 -- include/constants/battle.h | 1 + src/battle_main.c | 5 ----- src/battle_script_commands.c | 4 ++-- src/battle_util.c | 8 +++----- 5 files changed, 6 insertions(+), 14 deletions(-) diff --git a/include/battle.h b/include/battle.h index 7958c40f5..826a0929e 100644 --- a/include/battle.h +++ b/include/battle.h @@ -908,7 +908,5 @@ extern u8 gBattleControllerData[MAX_BATTLERS_COUNT]; extern bool8 gHasFetchedBall; extern u8 gLastUsedBall; extern u16 gLastThrownBall; -extern bool8 gCanPlayerRetaliate; -extern bool8 gCanOpponentRetaliate; #endif // GUARD_BATTLE_H diff --git a/include/constants/battle.h b/include/constants/battle.h index a59ea2f1a..39994a049 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -220,6 +220,7 @@ #define SIDE_STATUS_WIDE_GUARD (1 << 19) #define SIDE_STATUS_CRAFTY_SHIELD (1 << 20) #define SIDE_STATUS_MAT_BLOCK (1 << 21) +#define SIDE_STATUS_RETALIATE (1 << 22) #define SIDE_STATUS_HAZARDS_ANY (SIDE_STATUS_SPIKES | SIDE_STATUS_STICKY_WEB | SIDE_STATUS_TOXIC_SPIKES | SIDE_STATUS_STEALTH_ROCK) #define SIDE_STATUS_SCREEN_ANY (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL) diff --git a/src/battle_main.c b/src/battle_main.c index ffb33da10..055ec9bbe 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -231,8 +231,6 @@ EWRAM_DATA struct TotemBoost gTotemBoosts[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA bool8 gHasFetchedBall = FALSE; EWRAM_DATA u8 gLastUsedBall = 0; EWRAM_DATA u16 gLastThrownBall = 0; -EWRAM_DATA bool8 gCanPlayerRetaliate = FALSE; -EWRAM_DATA bool8 gCanOpponentRetaliate = FALSE; // IWRAM common vars void (*gPreBattleCallback1)(void); @@ -2878,9 +2876,6 @@ static void BattleStartClearSetData(void) gHasFetchedBall = FALSE; gLastUsedBall = 0; - gCanPlayerRetaliate = FALSE; - gCanOpponentRetaliate = FALSE; - gBattlerAttacker = 0; gBattlerTarget = 0; gBattleWeather = 0; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 132a434cb..b301047aa 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3499,14 +3499,14 @@ static void Cmd_tryfaintmon(void) if (gBattleResults.playerFaintCounter < 0xFF) gBattleResults.playerFaintCounter++; AdjustFriendshipOnBattleFaint(gActiveBattler); - gCanPlayerRetaliate = TRUE; + gSideStatuses[0] |= SIDE_STATUS_RETALIATE; } else { if (gBattleResults.opponentFaintCounter < 0xFF) gBattleResults.opponentFaintCounter++; gBattleResults.lastOpponentSpecies = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES, NULL); - gCanOpponentRetaliate = TRUE; + gSideStatuses[1] |= SIDE_STATUS_RETALIATE; } if ((gHitMarker & HITMARKER_DESTINYBOND) && gBattleMons[gBattlerAttacker].hp != 0) { diff --git a/src/battle_util.c b/src/battle_util.c index 689a846d6..e3bec3508 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -7681,6 +7681,7 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe u16 basePower = CalcMoveBasePower(move, battlerAtk, battlerDef); u16 holdEffectModifier; u16 modifier = UQ_4_12(1.0); + u32 atkSide = GET_BATTLER_SIDE(battlerAtk); // attacker's abilities switch (GetBattlerAbility(battlerAtk)) @@ -7933,13 +7934,10 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe MulModifier(&modifier, UQ_4_12(2.0)); break; case EFFECT_RETALIATE: - if (gCanPlayerRetaliate || gCanOpponentRetaliate) + if (gSideStatuses[atkSide] & SIDE_STATUS_RETALIATE) { MulModifier(&modifier, UQ_4_12(2.0)); - if (gCanPlayerRetaliate) - gCanPlayerRetaliate = FALSE; - else if (gCanOpponentRetaliate) - gCanOpponentRetaliate = FALSE; + gSideStatuses[atkSide] &= ~SIDE_STATUS_RETALIATE; } break; case EFFECT_SOLARBEAM: From 2bf8022673a7754135097215bc16bebcf6aa0d3b Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Fri, 15 Oct 2021 07:09:27 -0300 Subject: [PATCH 43/58] Changed how SIDE_STATUS_RETALIATE is cleared --- src/battle_main.c | 1 + src/battle_util.c | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/battle_main.c b/src/battle_main.c index 055ec9bbe..f3f86d58f 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3583,6 +3583,7 @@ static void HandleEndTurn_ContinueBattle(void) gBattleMons[i].status2 &= ~(STATUS2_FLINCHED); if ((gBattleMons[i].status1 & STATUS1_SLEEP) && (gBattleMons[i].status2 & STATUS2_MULTIPLETURNS)) CancelMultiTurnMoves(i); + gSideStatuses[GET_BATTLER_SIDE(i)] &= ~SIDE_STATUS_RETALIATE; } gBattleStruct->turnEffectsTracker = 0; gBattleStruct->turnEffectsBattlerId = 0; diff --git a/src/battle_util.c b/src/battle_util.c index e3bec3508..3bf34afd5 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -7935,10 +7935,7 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe break; case EFFECT_RETALIATE: if (gSideStatuses[atkSide] & SIDE_STATUS_RETALIATE) - { MulModifier(&modifier, UQ_4_12(2.0)); - gSideStatuses[atkSide] &= ~SIDE_STATUS_RETALIATE; - } break; case EFFECT_SOLARBEAM: if (WEATHER_HAS_EFFECT && gBattleWeather & (WEATHER_HAIL_ANY | WEATHER_SANDSTORM_ANY | WEATHER_RAIN_ANY)) From 883a2498364d1a8d40989ea5642b2ea24f81f38c Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 15 Oct 2021 09:20:32 -0400 Subject: [PATCH 44/58] config for catching semi-invulnerable mons --- include/constants/battle_config.h | 1 + src/item_use.c | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index bce49719e..eb9d9639e 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -178,6 +178,7 @@ #define B_POWDER_GRASS GEN_7 // In Gen6+, Grass-type Pokémon are immune to powder and spore moves. #define B_STEEL_RESISTANCES GEN_7 // In Gen6+, Steel-type Pokémon are no longer resistant to Dark-type and Ghost-type moves. #define B_THUNDERSTORM_TERRAIN TRUE // If TRUE, overworld Thunderstorm generates Rain and Electric Terrain as in Gen 8. +#define B_SEMI_INVULNERABLE_CATCH GEN_5 // In Gen5+, you cannot throw a ball against a Pokemon that is in a semi-invulnerable state (dig/fly/etc) // Animation Settings #define B_NEW_SWORD_PARTICLE FALSE // If set to TRUE, it updates Swords Dance's particle. diff --git a/src/item_use.c b/src/item_use.c index 63854a1ac..93604efef 100755 --- a/src/item_use.c +++ b/src/item_use.c @@ -947,11 +947,18 @@ u32 CanThrowBall(void) { return 2; // No room for mon } + #if B_SEMI_INVULNERABLE_CATCH >= GEN_5 + else if (gStatuses3[B_POSITION_OPPONENT_LEFT] & STATUS3_SEMI_INVULNERABLE) + { + return 3; // in semi-invulnerable state + } + #endif return 0; // usable } -static const u8 sText_CantThrowPokeBall_TwoMons[] = _("Cannot throw a ball!\nThere are two pokemon out there!\p"); +static const u8 sText_CantThrowPokeBall_TwoMons[] = _("Cannot throw a ball!\nThere are two Pokémon out there!\p"); +static const u8 sText_CantThrowPokeBall_SemiInvulnerable[] = _("Cannot throw a ball!\nThere's no Pokémon in sight!\p"); void ItemUseInBattle_PokeBall(u8 taskId) { switch (CanThrowBall()) @@ -976,6 +983,14 @@ void ItemUseInBattle_PokeBall(u8 taskId) else DisplayItemMessageInBattlePyramid(taskId, gText_BoxFull, Task_CloseBattlePyramidBagMessage); break; + #if B_SEMI_INVULNERABLE_CATCH >= GEN_5 + case 3: // Semi-Invulnerable + if (!InBattlePyramid()) + DisplayItemMessage(taskId, 1, sText_CantThrowPokeBall_SemiInvulnerable, CloseItemMessage); + else + DisplayItemMessageInBattlePyramid(taskId, sText_CantThrowPokeBall_SemiInvulnerable, Task_CloseBattlePyramidBagMessage); + break; + #endif } } From ef19c8c415b0f583bc686f131a58fba169c58fe6 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 15 Oct 2021 09:22:50 -0400 Subject: [PATCH 45/58] fix gen define --- include/constants/battle_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index eb9d9639e..62c8705e5 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -178,7 +178,7 @@ #define B_POWDER_GRASS GEN_7 // In Gen6+, Grass-type Pokémon are immune to powder and spore moves. #define B_STEEL_RESISTANCES GEN_7 // In Gen6+, Steel-type Pokémon are no longer resistant to Dark-type and Ghost-type moves. #define B_THUNDERSTORM_TERRAIN TRUE // If TRUE, overworld Thunderstorm generates Rain and Electric Terrain as in Gen 8. -#define B_SEMI_INVULNERABLE_CATCH GEN_5 // In Gen5+, you cannot throw a ball against a Pokemon that is in a semi-invulnerable state (dig/fly/etc) +#define B_SEMI_INVULNERABLE_CATCH GEN_4 // In Gen5+, you cannot throw a ball against a Pokemon that is in a semi-invulnerable state (dig/fly/etc) // Animation Settings #define B_NEW_SWORD_PARTICLE FALSE // If set to TRUE, it updates Swords Dance's particle. From c077091dbf917a17f469168c86a84c012a88d2ef Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 15 Oct 2021 14:57:26 -0400 Subject: [PATCH 46/58] small fixes, check GetCatchingBattler's semi-invulnerability --- include/constants/battle_config.h | 2 +- src/item_use.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 62c8705e5..fc9bc9f4e 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -178,7 +178,7 @@ #define B_POWDER_GRASS GEN_7 // In Gen6+, Grass-type Pokémon are immune to powder and spore moves. #define B_STEEL_RESISTANCES GEN_7 // In Gen6+, Steel-type Pokémon are no longer resistant to Dark-type and Ghost-type moves. #define B_THUNDERSTORM_TERRAIN TRUE // If TRUE, overworld Thunderstorm generates Rain and Electric Terrain as in Gen 8. -#define B_SEMI_INVULNERABLE_CATCH GEN_4 // In Gen5+, you cannot throw a ball against a Pokemon that is in a semi-invulnerable state (dig/fly/etc) +#define B_SEMI_INVULNERABLE_CATCH GEN_7 // In Gen4+, you cannot throw a ball against a Pokemon that is in a semi-invulnerable state (dig/fly/etc) // Animation Settings #define B_NEW_SWORD_PARTICLE FALSE // If set to TRUE, it updates Swords Dance's particle. diff --git a/src/item_use.c b/src/item_use.c index 93604efef..9a1fd2478 100755 --- a/src/item_use.c +++ b/src/item_use.c @@ -947,8 +947,8 @@ u32 CanThrowBall(void) { return 2; // No room for mon } - #if B_SEMI_INVULNERABLE_CATCH >= GEN_5 - else if (gStatuses3[B_POSITION_OPPONENT_LEFT] & STATUS3_SEMI_INVULNERABLE) + #if B_SEMI_INVULNERABLE_CATCH >= GEN_4 + else if (gStatuses3[GetCatchingBattler()] & STATUS3_SEMI_INVULNERABLE) { return 3; // in semi-invulnerable state } @@ -983,7 +983,7 @@ void ItemUseInBattle_PokeBall(u8 taskId) else DisplayItemMessageInBattlePyramid(taskId, gText_BoxFull, Task_CloseBattlePyramidBagMessage); break; - #if B_SEMI_INVULNERABLE_CATCH >= GEN_5 + #if B_SEMI_INVULNERABLE_CATCH >= GEN_4 case 3: // Semi-Invulnerable if (!InBattlePyramid()) DisplayItemMessage(taskId, 1, sText_CantThrowPokeBall_SemiInvulnerable, CloseItemMessage); From 1f176242aad724148a507c6adc40b72013ee5034 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 15 Oct 2021 16:06:50 -0400 Subject: [PATCH 47/58] add missing func definition --- include/battle_script_commands.h | 1 + src/battle_script_commands.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/battle_script_commands.h b/include/battle_script_commands.h index dec1596f2..b55ac1391 100644 --- a/include/battle_script_commands.h +++ b/include/battle_script_commands.h @@ -37,6 +37,7 @@ bool32 TryResetBattlerStatChanges(u8 battler); bool32 CanCamouflage(u8 battlerId); u16 GetNaturePowerMove(void); void StealTargetItem(u8 battlerStealer, u8 battlerItem); +u8 GetCatchingBattler(void); extern void (* const gBattleScriptingCommandsTable[])(void); extern const u8 gBattlePalaceNatureToMoveGroupLikelihood[NUM_NATURES][4]; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 29614e09b..2c0614ada 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -12565,7 +12565,7 @@ static void Cmd_removelightscreenreflect(void) // brick break gBattlescriptCurrInstr++; } -static u8 GetCatchingBattler(void) +u8 GetCatchingBattler(void) { if (IsBattlerAlive(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT))) return GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); From 3b6ceb1dfafc3a0d7fb57e4f332a92395b0ad970 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Sat, 16 Oct 2021 05:41:50 -0300 Subject: [PATCH 48/58] Turned Retaliate into a side timer --- include/battle.h | 1 + include/constants/battle.h | 1 - src/battle_main.c | 1 - src/battle_script_commands.c | 4 ++-- src/battle_util.c | 9 ++++++++- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/battle.h b/include/battle.h index 826a0929e..49881bacf 100644 --- a/include/battle.h +++ b/include/battle.h @@ -210,6 +210,7 @@ struct SideTimer u8 tailwindBattlerId; u8 luckyChantTimer; u8 luckyChantBattlerId; + u8 retaliateTimer; }; struct FieldTimer diff --git a/include/constants/battle.h b/include/constants/battle.h index 39994a049..a59ea2f1a 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -220,7 +220,6 @@ #define SIDE_STATUS_WIDE_GUARD (1 << 19) #define SIDE_STATUS_CRAFTY_SHIELD (1 << 20) #define SIDE_STATUS_MAT_BLOCK (1 << 21) -#define SIDE_STATUS_RETALIATE (1 << 22) #define SIDE_STATUS_HAZARDS_ANY (SIDE_STATUS_SPIKES | SIDE_STATUS_STICKY_WEB | SIDE_STATUS_TOXIC_SPIKES | SIDE_STATUS_STEALTH_ROCK) #define SIDE_STATUS_SCREEN_ANY (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL) diff --git a/src/battle_main.c b/src/battle_main.c index f3f86d58f..055ec9bbe 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3583,7 +3583,6 @@ static void HandleEndTurn_ContinueBattle(void) gBattleMons[i].status2 &= ~(STATUS2_FLINCHED); if ((gBattleMons[i].status1 & STATUS1_SLEEP) && (gBattleMons[i].status2 & STATUS2_MULTIPLETURNS)) CancelMultiTurnMoves(i); - gSideStatuses[GET_BATTLER_SIDE(i)] &= ~SIDE_STATUS_RETALIATE; } gBattleStruct->turnEffectsTracker = 0; gBattleStruct->turnEffectsBattlerId = 0; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index b301047aa..8813f2029 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3499,14 +3499,14 @@ static void Cmd_tryfaintmon(void) if (gBattleResults.playerFaintCounter < 0xFF) gBattleResults.playerFaintCounter++; AdjustFriendshipOnBattleFaint(gActiveBattler); - gSideStatuses[0] |= SIDE_STATUS_RETALIATE; + gSideTimers[0].retaliateTimer = 2; } else { if (gBattleResults.opponentFaintCounter < 0xFF) gBattleResults.opponentFaintCounter++; gBattleResults.lastOpponentSpecies = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES, NULL); - gSideStatuses[1] |= SIDE_STATUS_RETALIATE; + gSideTimers[1].retaliateTimer = 2; } if ((gHitMarker & HITMARKER_DESTINYBOND) && gBattleMons[gBattlerAttacker].hp != 0) { diff --git a/src/battle_util.c b/src/battle_util.c index 3bf34afd5..6b43709da 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1881,6 +1881,7 @@ enum ENDTURN_PSYCHIC_TERRAIN, ENDTURN_ION_DELUGE, ENDTURN_FAIRY_LOCK, + ENDTURN_RETALIATE, ENDTURN_FIELD_COUNT, }; @@ -2312,6 +2313,12 @@ u8 DoFieldEndTurnEffects(void) } gBattleStruct->turnCountersTracker++; break; + case ENDTURN_RETALIATE: + gActiveBattler = gBattlerByTurnOrder[gBattleStruct->turnSideTracker]; + if (gSideTimers[GET_BATTLER_SIDE(gActiveBattler)].retaliateTimer > 0) + gSideTimers[GET_BATTLER_SIDE(gActiveBattler)].retaliateTimer--; + gBattleStruct->turnCountersTracker++; + break; case ENDTURN_FIELD_COUNT: effect++; break; @@ -7934,7 +7941,7 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe MulModifier(&modifier, UQ_4_12(2.0)); break; case EFFECT_RETALIATE: - if (gSideStatuses[atkSide] & SIDE_STATUS_RETALIATE) + if (gSideTimers[atkSide].retaliateTimer == 1) MulModifier(&modifier, UQ_4_12(2.0)); break; case EFFECT_SOLARBEAM: From c2e25272b0a74402803e62383877faa5a3018489 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Sat, 16 Oct 2021 07:02:26 -0300 Subject: [PATCH 49/58] Added Grav Apple's power boost --- src/battle_util.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/battle_util.c b/src/battle_util.c index e01c89fca..2b72fc3bc 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -7702,6 +7702,10 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef) if (gBattleMons[battlerAtk].species == SPECIES_GRENINJA_ASH) basePower = 20; break; + case MOVE_GRAV_APPLE: + if (gFieldStatuses & STATUS_FIELD_GRAVITY) + basePower = 120; + break; } if (basePower == 0) From 611076c24def2e984c54fdd66824361184af846b Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Sat, 16 Oct 2021 10:15:15 -0400 Subject: [PATCH 50/58] move prankster to ABILITYEFFECT_MOVES_BLOCK --- src/battle_script_commands.c | 1 - src/battle_util.c | 23 ++++++++++------------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index bfd4cc21a..818fd246e 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -6642,7 +6642,6 @@ static void Cmd_jumptocalledmove(void) else gChosenMove = gCurrentMove = gCalledMove; - gBattleStruct->atkCancellerTracker = 0; gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; } diff --git a/src/battle_util.c b/src/battle_util.c index e01c89fca..f3e1eb9aa 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -3130,7 +3130,6 @@ enum CANCELLER_POWDER_MOVE, CANCELLER_POWDER_STATUS, CANCELLER_THROAT_CHOP, - CANCELLER_PRANKSTER, CANCELLER_END, CANCELLER_PSYCHIC_TERRAIN, CANCELLER_END2, @@ -3459,18 +3458,6 @@ u8 AtkCanceller_UnableToUseMove(void) } gBattleStruct->atkCancellerTracker++; break; - case CANCELLER_PRANKSTER: - 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))) - CancelMultiTurnMoves(gBattlerAttacker); // Don't cancel moves that can hit two targets bc one target might not be protected - gBattleScripting.battler = gBattlerAbility = gBattlerTarget; - gBattlescriptCurrInstr = BattleScript_DarkTypePreventsPrankster; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; case CANCELLER_END: break; } @@ -4572,6 +4559,16 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move gBattlescriptCurrInstr = BattleScript_DazzlingProtected; effect = 1; } + else if (BlocksPrankster(move, gBattlerAttacker, gBattlerTarget, TRUE) + && !(IS_MOVE_STATUS(move) && GetBattlerAbility(gBattlerTarget) == ABILITY_MAGIC_BOUNCE)) + { + if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE) || !(gBattleMoves[move].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))) + CancelMultiTurnMoves(gBattlerAttacker); // Don't cancel moves that can hit two targets bc one target might not be protected + gBattleScripting.battler = gBattlerAbility = gBattlerTarget; + gBattlescriptCurrInstr = BattleScript_DarkTypePreventsPrankster; + effect = 1; + } + break; case ABILITYEFFECT_ABSORBING: // 3 if (move != MOVE_NONE) From b7dcbca8718f85b87ba0d53eb0e99c98a4eae6e0 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Sat, 16 Oct 2021 11:25:20 -0400 Subject: [PATCH 51/58] remove atkCancelerTracker reset --- src/battle_script_commands.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 818fd246e..4321881bf 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -5159,7 +5159,6 @@ static void Cmd_moveend(void) MoveValuesCleanUp(); gBattleScripting.moveEffect = gBattleScripting.savedMoveEffect; BattleScriptPush(gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]); - gBattleStruct->atkCancellerTracker = 0; // Run all cancellers on next target gBattlescriptCurrInstr = BattleScript_FlushMessageBox; return; } From 5509ceea0420afdb3628af207f28d7a7db3283d3 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Sat, 16 Oct 2021 16:10:45 -0400 Subject: [PATCH 52/58] expand move target field --- include/battle.h | 2 +- include/battle_util.h | 2 +- include/constants/battle.h | 3 +-- src/battle_controller_player.c | 4 ++-- src/battle_util.c | 2 +- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/include/battle.h b/include/battle.h index 22b60d6e4..26c6b3e40 100644 --- a/include/battle.h +++ b/include/battle.h @@ -491,7 +491,7 @@ struct BattleStruct u8 turnEffectsBattlerId; u8 turnCountersTracker; u16 wrappedMove[MAX_BATTLERS_COUNT]; - u8 moveTarget[MAX_BATTLERS_COUNT]; + u16 moveTarget[MAX_BATTLERS_COUNT]; u8 expGetterMonId; u8 wildVictorySong; u8 dynamicMoveType; diff --git a/include/battle_util.h b/include/battle_util.h index 7d1b99f34..ee7337ef2 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -109,7 +109,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn); void ClearFuryCutterDestinyBondGrudge(u8 battlerId); void HandleAction_RunBattleScript(void); u32 SetRandomTarget(u32 battlerId); -u8 GetMoveTarget(u16 move, u8 setTarget); +u32 GetMoveTarget(u16 move, u8 setTarget); u8 IsMonDisobedient(void); u32 GetBattlerHoldEffect(u8 battlerId, bool32 checkNegating); u32 GetBattlerHoldEffectParam(u8 battlerId); diff --git a/include/constants/battle.h b/include/constants/battle.h index 90294b4b4..c5d5601fa 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -386,7 +386,6 @@ #define MOVE_TARGET_FOES_AND_ALLY 0x20 #define MOVE_TARGET_OPPONENTS_FIELD 0x40 #define MOVE_TARGET_ALLY 0x80 - -#define MOVE_TARGET_ALL_BATTLERS (MOVE_TARGET_BOTH | MOVE_TARGET_OPPONENTS_FIELD) +#define MOVE_TARGET_ALL_BATTLERS 0x100 #endif // GUARD_CONSTANTS_BATTLE_H diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 877e44750..0d4cf51de 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -590,7 +590,7 @@ static void TryShowAsTarget(u32 battlerId) static void HandleInputChooseMove(void) { - u8 moveTarget; + u16 moveTarget; u32 canSelectTarget = 0; struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct*)(&gBattleResources->bufferA[gActiveBattler][4]); @@ -644,7 +644,7 @@ static void HandleInputChooseMove(void) // Show all available targets for multi-target moves if (B_SHOW_TARGETS) { - if ((moveTarget & MOVE_TARGET_ALL_BATTLERS) == MOVE_TARGET_ALL_BATTLERS) + if (moveTarget & MOVE_TARGET_ALL_BATTLERS) { u32 i = 0; for (i = 0; i < gBattlersCount; i++) diff --git a/src/battle_util.c b/src/battle_util.c index e01c89fca..cdacaf179 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -7018,7 +7018,7 @@ u32 SetRandomTarget(u32 battlerId) return target; } -u8 GetMoveTarget(u16 move, u8 setTarget) +u32 GetMoveTarget(u16 move, u8 setTarget) { u8 targetBattler = 0; u32 i, moveTarget, side; From 964e7efba9f900db7ee3f51f3821165e81cd29ff Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Sat, 16 Oct 2021 16:23:17 -0400 Subject: [PATCH 53/58] fix MOVE_TARGET_ALL_BATTLERS and other u8 vars --- include/constants/battle.h | 2 +- include/pokemon.h | 2 +- src/battle_ai_main.c | 4 ++-- src/battle_controller_player.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/constants/battle.h b/include/constants/battle.h index c5d5601fa..577b0ba60 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -386,6 +386,6 @@ #define MOVE_TARGET_FOES_AND_ALLY 0x20 #define MOVE_TARGET_OPPONENTS_FIELD 0x40 #define MOVE_TARGET_ALLY 0x80 -#define MOVE_TARGET_ALL_BATTLERS 0x100 +#define MOVE_TARGET_ALL_BATTLERS (0x100 | MOVE_TARGET_USER) #endif // GUARD_CONSTANTS_BATTLE_H diff --git a/include/pokemon.h b/include/pokemon.h index 1524e16f4..747830412 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -216,7 +216,7 @@ struct BattleMove u8 accuracy; u8 pp; u8 secondaryEffectChance; - u8 target; + u16 target; s8 priority; u32 flags; u8 split; diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index edfd76464..972dc0ed6 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -517,7 +517,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) u8 atkPriority = GetMovePriority(battlerAtk, move); u16 moveEffect = gBattleMoves[move].effect; s32 moveType; - u8 moveTarget = gBattleMoves[move].target; + u16 moveTarget = gBattleMoves[move].target; u16 accuracy = AI_GetMoveAccuracy(battlerAtk, battlerDef, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect, move); u8 effectiveness = AI_GetMoveEffectiveness(move, battlerAtk, battlerDef); bool32 isDoubleBattle = IsValidDoubleBattle(battlerAtk); @@ -2514,7 +2514,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) // move data u8 moveType = gBattleMoves[move].type; u16 effect = gBattleMoves[move].effect; - u8 target = gBattleMoves[move].target; + u16 target = gBattleMoves[move].target; // ally data u8 battlerAtkPartner = AI_DATA->battlerAtkPartner; u16 atkPartnerAbility = AI_DATA->atkPartnerAbility; diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 0d4cf51de..e1cb2f54f 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -644,7 +644,7 @@ static void HandleInputChooseMove(void) // Show all available targets for multi-target moves if (B_SHOW_TARGETS) { - if (moveTarget & MOVE_TARGET_ALL_BATTLERS) + if ((moveTarget & MOVE_TARGET_ALL_BATTLERS) == MOVE_TARGET_ALL_BATTLERS) { u32 i = 0; for (i = 0; i < gBattlersCount; i++) From 59cfbe55c1d7669957714379b060f81c4e7b70db Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Sun, 17 Oct 2021 09:27:35 -0300 Subject: [PATCH 54/58] Gave Grav Apple a move effect of its own --- data/battle_scripts_1.s | 4 ++++ include/constants/battle_move_effects.h | 3 ++- src/battle_util.c | 8 ++++---- src/data/battle_moves.h | 2 +- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index e4fdb3038..7999091e0 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -381,6 +381,10 @@ gBattleScriptsForMoveEffects:: .4byte BattleScript_EffectTripleHit @ EFFECT_TRIPLE_HIT .4byte BattleScript_EffectRecoilHP25 @ EFFECT_RECOIL_HP_25 .4byte BattleScript_EffectStuffCheeks @ EFFECT_STUFF_CHEEKS + .4byte BattleScript_EffectGravApple @ EFFECT_GRAV_APPLE + +BattleScript_EffectGravApple: + goto BattleScript_EffectAttackerDefenseDownHit BattleScript_EffectStuffCheeks:: attackcanceler diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index 9a6efb847..20f6e110d 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -365,7 +365,8 @@ #define EFFECT_TRIPLE_HIT 359 #define EFFECT_RECOIL_HP_25 360 #define EFFECT_STUFF_CHEEKS 361 +#define EFFECT_GRAV_APPLE 362 -#define NUM_BATTLE_MOVE_EFFECTS 362 +#define NUM_BATTLE_MOVE_EFFECTS 363 #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/src/battle_util.c b/src/battle_util.c index 2b72fc3bc..fb485c2e7 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -7693,6 +7693,10 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef) #endif break; } + case EFFECT_GRAV_APPLE: + if (gFieldStatuses & STATUS_FIELD_GRAVITY) + MulModifier(&basePower, UQ_4_12(1.5)); + break; } // move-specific base power changes @@ -7702,10 +7706,6 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef) if (gBattleMons[battlerAtk].species == SPECIES_GRENINJA_ASH) basePower = 20; break; - case MOVE_GRAV_APPLE: - if (gFieldStatuses & STATUS_FIELD_GRAVITY) - basePower = 120; - break; } if (basePower == 0) diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index a6b8d271c..2dcdbf5b2 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -11103,7 +11103,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_GRAV_APPLE] = { - .effect = EFFECT_DEFENSE_DOWN_HIT, + .effect = EFFECT_GRAV_APPLE, .power = 80, .type = TYPE_GRASS, .accuracy = 100, From d6304099ac822a081f259769144cf858c51cba74 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Sun, 17 Oct 2021 09:39:57 -0300 Subject: [PATCH 55/58] Review optimization Co-authored-by: Eduardo Quezada D'Ottone --- data/battle_scripts_1.s | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 7999091e0..88832325a 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -381,10 +381,7 @@ gBattleScriptsForMoveEffects:: .4byte BattleScript_EffectTripleHit @ EFFECT_TRIPLE_HIT .4byte BattleScript_EffectRecoilHP25 @ EFFECT_RECOIL_HP_25 .4byte BattleScript_EffectStuffCheeks @ EFFECT_STUFF_CHEEKS - .4byte BattleScript_EffectGravApple @ EFFECT_GRAV_APPLE - -BattleScript_EffectGravApple: - goto BattleScript_EffectAttackerDefenseDownHit + .4byte BattleScript_EffectDefenseDownHit @ EFFECT_GRAV_APPLE BattleScript_EffectStuffCheeks:: attackcanceler From 5d0350cdbc86310e25ea53946b07819b98366ba2 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Sun, 17 Oct 2021 10:08:30 -0300 Subject: [PATCH 56/58] Set the right .effect to Dynamax Cannon --- src/data/battle_moves.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index 2dcdbf5b2..a34055200 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -10738,7 +10738,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_DYNAMAX_CANNON] = { - .effect = EFFECT_HIT, + .effect = EFFECT_DYNAMAX_DOUBLE_DMG, .power = 100, .type = TYPE_DRAGON, .accuracy = 100, From e7ad7319e3bb3469dba8bce076d85c42912d1dc6 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Sun, 17 Oct 2021 11:54:27 -0300 Subject: [PATCH 57/58] Updated Glare --- data/battle_scripts_1.s | 4 ++++ include/constants/battle_config.h | 1 + 2 files changed, 5 insertions(+) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 88832325a..9806cf939 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -3229,7 +3229,11 @@ BattleScript_EffectParalyze: jumpifleafguard BattleScript_LeafGuardProtects jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects jumpifsubstituteblocks BattleScript_ButItFailed +.if B_GLARE_GHOST >= GEN_4 + jumpifmove MOVE_GLARE, BattleScript_BattleScript_EffectParalyzeNoTypeCalc +.endif typecalc +BattleScript_BattleScript_EffectParalyzeNoTypeCalc: jumpifmovehadnoeffect BattleScript_ButItFailed jumpifstatus BS_TARGET, STATUS1_PARALYSIS, BattleScript_AlreadyParalyzed tryparalyzetype BS_ATTACKER, BS_TARGET, BattleScript_NotAffected diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index fc9bc9f4e..3aa9faea3 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -124,6 +124,7 @@ #define B_TAILWIND_TIMER GEN_7 // In Gen5+, Tailwind lasts 4 turns instead of 3. #define B_MEMENTO_FAIL GEN_7 // In Gen4+, Memento fails if there is no target or if the target is protected or behind substitute. But not if Atk/Sp. Atk are at -6. #define B_HIDDEN_POWER_DMG GEN_7 // In Gen6+, Hidden Power's base power was set to always be 60. Before, it was determined by the mon's IVs. +#define B_GLARE_GHOST GEN_7 // In Gen4+, Glare can hit Ghost-type Pokémon normally. // Ability settings #define B_ABILITY_WEATHER GEN_7 // In Gen6+, ability-induced weather lasts 5 turns. Before, it lasted until the battle ended or until it was changed by a move or a different weather-affecting ability. From 25255475a78c29f563ddbe0a78ea26c13f053a49 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Mon, 18 Oct 2021 10:05:19 -0300 Subject: [PATCH 58/58] AI will now take Grav Apple's new effect in consideration --- src/battle_ai_main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index edfd76464..324ca4934 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -3363,6 +3363,10 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) case EFFECT_PARALYZE: IncreaseParalyzeScore(battlerAtk, battlerDef, move, &score); break; + case EFFECT_GRAV_APPLE: + if (gFieldStatuses & STATUS_FIELD_GRAVITY) + score += 2; + // fall through case EFFECT_ATTACK_DOWN_HIT: case EFFECT_DEFENSE_DOWN_HIT: case EFFECT_SPECIAL_ATTACK_DOWN_HIT: