From 28bc7dc14d46744afafe35a666f2cd3397c0c3ff Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 29 Oct 2021 22:32:19 -0400 Subject: [PATCH 01/69] start ability --- data/battle_scripts_1.s | 17 ++++++++ include/battle.h | 14 ++++--- include/battle_scripts.h | 2 + include/battle_util.h | 32 +++++++------- include/constants/battle_string_ids.h | 5 ++- src/battle_main.c | 6 ++- src/battle_message.c | 6 ++- src/battle_script_commands.c | 60 +++++++++++++++++---------- src/battle_util.c | 60 +++++++++++++++++++++++++-- 9 files changed, 154 insertions(+), 48 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 009c3a882f..e104db758e 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -8091,6 +8091,12 @@ BattleScript_SwitchInAbilityMsg:: waitmessage B_WAIT_TIME_LONG end3 +BattleScript_SwitchInAbilityMsgRet:: + call BattleScript_AbilityPopUp + printfromtable gSwitchInAbilityStringIds + waitmessage B_WAIT_TIME_LONG + return + BattleScript_ActivateAsOne:: call BattleScript_AbilityPopUp printfromtable gSwitchInAbilityStringIds @@ -8909,3 +8915,14 @@ BattleScript_DarkTypePreventsPrankster:: waitmessage B_WAIT_TIME_LONG orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT goto BattleScript_MoveEnd + +BattleScript_NeutralizingGasExits:: + pause B_WAIT_TIME_SHORT + printstring STRINGID_NEUTRALIZINGGASOVER + waitmessage B_WAIT_TIME_LONG + setbyte gBattlerTarget, 0 +BattleScript_NeutralizingGasExitsLoop: + switchinabilities BS_TARGET + addbyte gBattlerTarget, 1 + jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_NeutralizingGasExitsLoop + return diff --git a/include/battle.h b/include/battle.h index 5077053e35..68a40c9789 100644 --- a/include/battle.h +++ b/include/battle.h @@ -62,12 +62,13 @@ struct ResourceFlags u32 flags[4]; }; -#define RESOURCE_FLAG_FLASH_FIRE 0x1 -#define RESOURCE_FLAG_ROOST 0x2 -#define RESOURCE_FLAG_UNBURDEN 0x4 -#define RESOURCE_FLAG_INTIMIDATED 0x8 -#define RESOURCE_FLAG_TRACED 0x10 -#define RESOURCE_FLAG_EMERGENCY_EXIT 0x20 +#define RESOURCE_FLAG_FLASH_FIRE 0x1 +#define RESOURCE_FLAG_ROOST 0x2 +#define RESOURCE_FLAG_UNBURDEN 0x4 +#define RESOURCE_FLAG_INTIMIDATED 0x8 +#define RESOURCE_FLAG_TRACED 0x10 +#define RESOURCE_FLAG_EMERGENCY_EXIT 0x20 +#define RESOURCE_FLAG_NEUTRALIZING_GAS 0x40 struct DisableStruct { @@ -181,6 +182,7 @@ struct SpecialStatus u8 damagedMons:4; // Mons that have been damaged directly by using a move, includes substitute. u8 dancerUsedMove:1; u8 dancerOriginalTarget:3; + u8 announceNeutralizingGas:1; s32 dmg; s32 physicalDmg; s32 specialDmg; diff --git a/include/battle_scripts.h b/include/battle_scripts.h index ec95a45497..1c48800113 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -261,6 +261,7 @@ extern const u8 BattleScript_AttackerAbilityStatRaiseEnd3[]; extern const u8 BattleScript_PoisonHealActivates[]; extern const u8 BattleScript_BadDreamsActivates[]; extern const u8 BattleScript_SwitchInAbilityMsg[]; +extern const u8 BattleScript_SwitchInAbilityMsgRet[]; extern const u8 BattleScript_ToxicSpikesPoisoned[]; extern const u8 BattleScript_ToxicSpikesAbsorbed[]; extern const u8 BattleScript_StickyWebOnSwitchIn[]; @@ -402,5 +403,6 @@ extern const u8 BattleScript_BlockedByPrimalWeatherEnd3[]; extern const u8 BattleScript_BlockedByPrimalWeatherRet[]; extern const u8 BattleScript_PrimalReversion[]; extern const u8 BattleScript_HyperspaceFuryRemoveProtect[]; +extern const u8 BattleScript_NeutralizingGasExits[]; #endif // GUARD_BATTLE_SCRIPTS_H diff --git a/include/battle_util.h b/include/battle_util.h index ee7337ef2d..32c7a53dc4 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -8,21 +8,23 @@ #define MOVE_LIMITATION_TAUNT (1 << 4) #define MOVE_LIMITATION_IMPRISON (1 << 5) -#define ABILITYEFFECT_ON_SWITCHIN 0x0 -#define ABILITYEFFECT_ENDTURN 0x1 -#define ABILITYEFFECT_MOVES_BLOCK 0x2 -#define ABILITYEFFECT_ABSORBING 0x3 -#define ABILITYEFFECT_MOVE_END_ATTACKER 0x4 -#define ABILITYEFFECT_MOVE_END 0x5 -#define ABILITYEFFECT_IMMUNITY 0x6 -#define ABILITYEFFECT_FORECAST 0x7 -#define ABILITYEFFECT_SYNCHRONIZE 0x8 -#define ABILITYEFFECT_ATK_SYNCHRONIZE 0x9 -#define ABILITYEFFECT_INTIMIDATE1 0xA -#define ABILITYEFFECT_INTIMIDATE2 0xB -#define ABILITYEFFECT_TRACE1 0xC -#define ABILITYEFFECT_TRACE2 0xD -#define ABILITYEFFECT_MOVE_END_OTHER 0xE +#define ABILITYEFFECT_ON_SWITCHIN 0 +#define ABILITYEFFECT_ENDTURN 1 +#define ABILITYEFFECT_MOVES_BLOCK 2 +#define ABILITYEFFECT_ABSORBING 3 +#define ABILITYEFFECT_MOVE_END_ATTACKER 4 +#define ABILITYEFFECT_MOVE_END 5 +#define ABILITYEFFECT_IMMUNITY 6 +#define ABILITYEFFECT_FORECAST 7 +#define ABILITYEFFECT_SYNCHRONIZE 8 +#define ABILITYEFFECT_ATK_SYNCHRONIZE 9 +#define ABILITYEFFECT_INTIMIDATE1 10 +#define ABILITYEFFECT_INTIMIDATE2 11 +#define ABILITYEFFECT_TRACE1 12 +#define ABILITYEFFECT_TRACE2 13 +#define ABILITYEFFECT_MOVE_END_OTHER 14 +#define ABILITYEFFECT_NEUTRALIZINGGAS 15 +// Special cases #define ABILITYEFFECT_SWITCH_IN_TERRAIN 0xFE #define ABILITYEFFECT_SWITCH_IN_WEATHER 0xFF diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 1d461e2a00..7167296198 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -597,8 +597,10 @@ #define STRINGID_BUTPOKEMONCANTUSETHEMOVE 594 #define STRINGID_BUTHOOPACANTUSEIT 595 #define STRINGID_BROKETHROUGHPROTECTION 596 +#define STRINGID_NEUTRALIZINGGASENTERS 597 +#define STRINGID_NEUTRALIZINGGASOVER 598 -#define BATTLESTRINGS_COUNT 597 +#define BATTLESTRINGS_COUNT 599 // The below IDs are all indexes into battle message tables, // used to determine which of a set of messages to print. @@ -833,6 +835,7 @@ #define B_MSG_SWITCHIN_SCREENCLEANER 12 #define B_MSG_SWITCHIN_ASONE 13 #define B_MSG_SWITCHIN_CURIOUS_MEDICINE 14 +#define B_MSG_SWITCHIN_NEUTRALIZING_GAS 15 // gMentalHerbCureStringIds #define B_MSG_MENTALHERBCURE_INFATUATION 0 diff --git a/src/battle_main.c b/src/battle_main.c index 271e977314..19e0d49403 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3533,7 +3533,11 @@ static void TryDoEventsBeforeFirstTurn(void) return; } } - + + // Check neutralizing gas + if (AbilityBattleEffects(ABILITYEFFECT_NEUTRALIZINGGAS, 0, 0, 0, 0) != 0) + return; + // Check all switch in abilities happening from the fastest mon to slowest. while (gBattleStruct->switchInAbilitiesCounter < gBattlersCount) { diff --git a/src/battle_message.c b/src/battle_message.c index f26726a69a..48e7ab1a43 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -723,9 +723,12 @@ static const u8 sText_PkmnRevertedToPrimal[] = _("{B_ATK_NAME_WITH_PREFIX}'s Pri static const u8 sText_ButPokemonCantUseTheMove[] = _("But {B_ATK_NAME_WITH_PREFIX} can't\nuse the move!"); static const u8 sText_ButHoopaCantUseIt[] = _("But Hoopa can't use it\nthe way it is now!"); static const u8 sText_BrokeThroughProtection[] = _("It broke through the\n{B_DEF_NAME_WITH_PREFIX}'s protection!"); - +static const u8 sText_NeutralizingGasEnters[] = _("Neutralizing Gas filled the area!"); +static const u8 sText_NeutralizingGasOver[] = _("The effects of Neutralizing\nGas wore off!"); const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = { + [STRINGID_NEUTRALIZINGGASOVER - 12] = sText_NeutralizingGasOver, + [STRINGID_NEUTRALIZINGGASENTERS - 12] = sText_NeutralizingGasEnters, [STRINGID_BROKETHROUGHPROTECTION - 12] = sText_BrokeThroughProtection, [STRINGID_BUTPOKEMONCANTUSETHEMOVE - 12] = sText_ButPokemonCantUseTheMove, [STRINGID_BUTHOOPACANTUSEIT - 12] = sText_ButHoopaCantUseIt, @@ -1371,6 +1374,7 @@ const u16 gSwitchInAbilityStringIds[] = [B_MSG_SWITCHIN_SCREENCLEANER] = STRINGID_SCREENCLEANERENTERS, [B_MSG_SWITCHIN_ASONE] = STRINGID_ASONEENTERS, [B_MSG_SWITCHIN_CURIOUS_MEDICINE] = STRINGID_CURIOUSMEDICINEENTERS, + [B_MSG_SWITCHIN_NEUTRALIZING_GAS] = STRINGID_NEUTRALIZINGGASENTERS, }; const u16 gMissStringIds[] = diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index e41f0982a7..e2c6aff027 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -5416,7 +5416,7 @@ static void Cmd_sethealblock(void) static void Cmd_returnatktoball(void) { - gActiveBattler = gBattlerAttacker; + gActiveBattler = gBattlerAttacker; if (!(gHitMarker & HITMARKER_FAINTED(gActiveBattler))) { BtlController_EmitReturnMonToBall(0, 0); @@ -6077,8 +6077,17 @@ static void Cmd_switchineffects(void) gHitMarker &= ~(HITMARKER_FAINTED(gActiveBattler)); gSpecialStatuses[gActiveBattler].flag40 = 0; - - if (!(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES_DAMAGED) + + // Neutralizing Gas announces itself before hazards + if (gBattleMons[gActiveBattler].ability == ABILITY_NEUTRALIZING_GAS && gSpecialStatuses[gActiveBattler].announceNeutralizingGas == 0) + { + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SWITCHIN_NEUTRALIZING_GAS; + gSpecialStatuses[gActiveBattler].announceNeutralizingGas = TRUE; + gBattlerAbility = gActiveBattler; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_SwitchInAbilityMsgRet; + } + else if (!(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES_DAMAGED) && (gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES) && GetBattlerAbility(gActiveBattler) != ABILITY_MAGIC_GUARD && IsBattlerAffectedByHazards(gActiveBattler, FALSE) @@ -6240,7 +6249,7 @@ static void Cmd_endlinkbattle(void) } static void Cmd_returntoball(void) -{ +{ gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); BtlController_EmitReturnMonToBall(0, 1); MarkBattlerForControllerExec(gActiveBattler); @@ -12281,25 +12290,34 @@ static void Cmd_trygetintimidatetarget(void) static void Cmd_switchoutabilities(void) { gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); - - switch (GetBattlerAbility(gActiveBattler)) + + if (gBattleMons[gActiveBattler].ability == ABILITY_NEUTRALIZING_GAS) { - case ABILITY_NATURAL_CURE: - gBattleMons[gActiveBattler].status1 = 0; - BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, gBitTable[*(gBattleStruct->field_58 + gActiveBattler)], 4, &gBattleMons[gActiveBattler].status1); - MarkBattlerForControllerExec(gActiveBattler); - break; - case ABILITY_REGENERATOR: - gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 3; - gBattleMoveDamage += gBattleMons[gActiveBattler].hp; - if (gBattleMoveDamage > gBattleMons[gActiveBattler].maxHP) - gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP; - BtlController_EmitSetMonData(0, REQUEST_HP_BATTLE, gBitTable[*(gBattleStruct->field_58 + gActiveBattler)], 2, &gBattleMoveDamage); - MarkBattlerForControllerExec(gActiveBattler); - break; + gBattleMons[gActiveBattler].ability = 0; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits; + } + else + { + switch (GetBattlerAbility(gActiveBattler)) + { + case ABILITY_NATURAL_CURE: + gBattleMons[gActiveBattler].status1 = 0; + BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, gBitTable[*(gBattleStruct->field_58 + gActiveBattler)], 4, &gBattleMons[gActiveBattler].status1); + MarkBattlerForControllerExec(gActiveBattler); + break; + case ABILITY_REGENERATOR: + gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 3; + gBattleMoveDamage += gBattleMons[gActiveBattler].hp; + if (gBattleMoveDamage > gBattleMons[gActiveBattler].maxHP) + gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP; + BtlController_EmitSetMonData(0, REQUEST_HP_BATTLE, gBitTable[*(gBattleStruct->field_58 + gActiveBattler)], 2, &gBattleMoveDamage); + MarkBattlerForControllerExec(gActiveBattler); + break; + } + + gBattlescriptCurrInstr += 2; } - - gBattlescriptCurrInstr += 2; } static void Cmd_jumpifhasnohp(void) diff --git a/src/battle_util.c b/src/battle_util.c index 275139f4f4..0125d362c1 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -5436,6 +5436,20 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move } } break; + case ABILITYEFFECT_NEUTRALIZINGGAS: + // for the start of battle only. The switch-in message plays in Cmd_switchineffects because it comes before the hazards + for (i = 0; i < gBattlersCount; i++) + { + if (gBattleMons[i].ability == ABILITY_NEUTRALIZING_GAS && !(gBattleResources->flags->flags[i] & RESOURCE_FLAG_NEUTRALIZING_GAS)) + { + gBattleResources->flags->flags[i] |= RESOURCE_FLAG_NEUTRALIZING_GAS; + gBattlerAbility = i; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SWITCHIN_NEUTRALIZING_GAS; + BattleScriptPushCursorAndCallback(BattleScript_SwitchInAbilityMsg); + effect++; + } + } + break; } if (effect && gLastUsedAbility != 0xFF) @@ -5446,11 +5460,51 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move return effect; } +static bool32 IsNeutralizingGasBannedAbility(u32 ability) +{ + switch (ability) + { + case ABILITY_MULTITYPE: + case ABILITY_ZEN_MODE: + case ABILITY_STANCE_CHANGE: + case ABILITY_POWER_CONSTRUCT: + case ABILITY_SCHOOLING: + case ABILITY_RKS_SYSTEM: + case ABILITY_SHIELDS_DOWN: + case ABILITY_COMATOSE: + case ABILITY_DISGUISE: + case ABILITY_GULP_MISSILE: + case ABILITY_ICE_FACE: + case ABILITY_AS_ONE_ICE_RIDER: + case ABILITY_AS_ONE_SHADOW_RIDER: + return TRUE; + default: + return FALSE; + } +} + +static bool32 IsNeutralizingGasOnField(void) +{ + u32 i; + + for (i = 0; i < gBattlersCount; i++) + { + if (IsBattlerAlive(i) && gBattleMons[i].ability == ABILITY_NEUTRALIZING_GAS) + return TRUE; + } + + return FALSE; +} + u32 GetBattlerAbility(u8 battlerId) { if (gStatuses3[battlerId] & STATUS3_GASTRO_ACID) return ABILITY_NONE; - else if ((((gBattleMons[gBattlerAttacker].ability == ABILITY_MOLD_BREAKER + + if (IsNeutralizingGasOnField() && !IsNeutralizingGasBannedAbility(gBattleMons[battlerId].ability)) + return ABILITY_NONE; + + if ((((gBattleMons[gBattlerAttacker].ability == ABILITY_MOLD_BREAKER || gBattleMons[gBattlerAttacker].ability == ABILITY_TERAVOLT || gBattleMons[gBattlerAttacker].ability == ABILITY_TURBOBLAZE) && !(gStatuses3[gBattlerAttacker] & STATUS3_GASTRO_ACID)) @@ -5460,8 +5514,8 @@ u32 GetBattlerAbility(u8 battlerId) && gActionsByTurnOrder[gBattlerByTurnOrder[gBattlerAttacker]] == B_ACTION_USE_MOVE && gCurrentTurnActionNumber < gBattlersCount) return ABILITY_NONE; - else - return gBattleMons[battlerId].ability; + + return gBattleMons[battlerId].ability; } u32 IsAbilityOnSide(u32 battlerId, u32 ability) From 4b0325dbe49cf5434cffde97e825ffc8337d7797 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Sat, 30 Oct 2021 09:13:08 -0400 Subject: [PATCH 02/69] neutralizing gas switchout --- data/battle_scripts_1.s | 9 ++++++++- src/battle_script_commands.c | 5 +++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index e104db758e..9fdd54e712 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -8916,13 +8916,20 @@ BattleScript_DarkTypePreventsPrankster:: orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT goto BattleScript_MoveEnd +sByteFour: +.byte MAX_BATTLERS_COUNT + BattleScript_NeutralizingGasExits:: + savetarget pause B_WAIT_TIME_SHORT printstring STRINGID_NEUTRALIZINGGASOVER waitmessage B_WAIT_TIME_LONG setbyte gBattlerTarget, 0 BattleScript_NeutralizingGasExitsLoop: + jumpifbyteequal gEffectBattler, gBattlerTarget, BattleScript_NeutralizingGasExitsIncrement @ skip over battler switching out switchinabilities BS_TARGET +BattleScript_NeutralizingGasExitsIncrement: addbyte gBattlerTarget, 1 - jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_NeutralizingGasExitsLoop + jumpifbytenotequal gBattlerTarget, sByteFour, BattleScript_NeutralizingGasExitsLoop @ SOMEHOW, comparing to gBattlersCount is problematic. + restoretarget return diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index e2c6aff027..35b04fcd2e 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -12293,8 +12293,9 @@ static void Cmd_switchoutabilities(void) if (gBattleMons[gActiveBattler].ability == ABILITY_NEUTRALIZING_GAS) { - gBattleMons[gActiveBattler].ability = 0; - BattleScriptPushCursor(); + gBattleMons[gActiveBattler].ability = ABILITY_NONE; + gEffectBattler = gActiveBattler; + BattleScriptPush(gBattlescriptCurrInstr); gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits; } else From dc9e418155452ae38e1f6b9fe8a87be31e0d3339 Mon Sep 17 00:00:00 2001 From: ghoulslash <41651341+ghoulslash@users.noreply.github.com> Date: Sat, 30 Oct 2021 11:53:58 -0400 Subject: [PATCH 03/69] Update src/battle_script_commands.c Co-authored-by: LOuroboros --- 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 35b04fcd2e..062f77876b 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -5416,7 +5416,7 @@ static void Cmd_sethealblock(void) static void Cmd_returnatktoball(void) { - gActiveBattler = gBattlerAttacker; + gActiveBattler = gBattlerAttacker; if (!(gHitMarker & HITMARKER_FAINTED(gActiveBattler))) { BtlController_EmitReturnMonToBall(0, 0); From 915054e84e535d8a24d8fb456bfafd6246c0f244 Mon Sep 17 00:00:00 2001 From: ghoulslash <41651341+ghoulslash@users.noreply.github.com> Date: Sat, 30 Oct 2021 11:54:04 -0400 Subject: [PATCH 04/69] Update src/battle_script_commands.c Co-authored-by: LOuroboros --- 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 062f77876b..7148ab8650 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -6249,7 +6249,7 @@ static void Cmd_endlinkbattle(void) } static void Cmd_returntoball(void) -{ +{ gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); BtlController_EmitReturnMonToBall(0, 1); MarkBattlerForControllerExec(gActiveBattler); From bcf272353ca8f9be51a9279fb48c91629defac8c Mon Sep 17 00:00:00 2001 From: ghoulslash <41651341+ghoulslash@users.noreply.github.com> Date: Sat, 30 Oct 2021 11:54:09 -0400 Subject: [PATCH 05/69] Update src/battle_script_commands.c Co-authored-by: LOuroboros --- 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 7148ab8650..3f53bd3015 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -12290,7 +12290,6 @@ static void Cmd_trygetintimidatetarget(void) static void Cmd_switchoutabilities(void) { gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); - if (gBattleMons[gActiveBattler].ability == ABILITY_NEUTRALIZING_GAS) { gBattleMons[gActiveBattler].ability = ABILITY_NONE; From ae0260fa625d852b0a2fc9870e43f2ed39ee6b10 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Sat, 30 Oct 2021 12:06:02 -0400 Subject: [PATCH 06/69] fix run away check in TryRunFromBattle --- 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 0125d362c1..9497f7d180 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -627,7 +627,7 @@ bool8 TryRunFromBattle(u8 battler) effect++; } #endif - else if (gBattleMons[battler].ability == ABILITY_RUN_AWAY) + else if (GetBattlerAbility(battler) == ABILITY_RUN_AWAY) { if (InBattlePyramid()) { From a2b8f3f1693ddb2be5eaa9af9eaa9ff10fa05ee7 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Sun, 31 Oct 2021 17:19:30 -0400 Subject: [PATCH 07/69] replace gBattleMons[x].ability w GetBattlerAbility --- src/battle_ai_switch_items.c | 6 +++--- src/battle_ai_util.c | 18 +++++++++++------ src/battle_script_commands.c | 9 +++++---- src/battle_util.c | 38 ++++++++++++++++++------------------ src/battle_util2.c | 2 +- 5 files changed, 40 insertions(+), 33 deletions(-) diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index e8e3999357..400876cc9b 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -82,7 +82,7 @@ static bool8 ShouldSwitchIfWonderGuard(void) opposingPosition = BATTLE_OPPOSITE(GetBattlerPosition(gActiveBattler)); - if (gBattleMons[GetBattlerAtPosition(opposingPosition)].ability != ABILITY_WONDER_GUARD) + if (GetBattlerAbility(GetBattlerAtPosition(opposingPosition)) != ABILITY_WONDER_GUARD) return FALSE; // Check if Pokemon has a super effective move. @@ -176,7 +176,7 @@ static bool8 FindMonThatAbsorbsOpponentsMove(void) else return FALSE; - if (gBattleMons[gActiveBattler].ability == absorbingTypeAbility) + if (AI_GetAbility(gActiveBattler) == absorbingTypeAbility) return FALSE; GetAIPartyIndexes(gActiveBattler, &firstId, &lastId); @@ -228,7 +228,7 @@ static bool8 ShouldSwitchIfNaturalCure(void) { if (!(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP)) return FALSE; - if (gBattleMons[gActiveBattler].ability != ABILITY_NATURAL_CURE) + if (AI_GetAbility(gActiveBattler) != ABILITY_NATURAL_CURE) return FALSE; if (gBattleMons[gActiveBattler].hp < gBattleMons[gActiveBattler].maxHP / 2) return FALSE; diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index fef6e6c6ff..2223e38d37 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -1068,19 +1068,24 @@ bool32 CanTargetFaintAiWithMod(u8 battlerDef, u8 battlerAtk, s32 hpMod, s32 dmgM // does NOT include ability suppression checks s32 AI_GetAbility(u32 battlerId) { + u32 knownAbility = GetBattlerAbility(battlerId); + // The AI knows its own ability. if (IsBattlerAIControlled(battlerId)) - return gBattleMons[battlerId].ability; + return knownAbility; + + // Check neutralizing gas, gastro acid + if (knownAbility == ABILITY_NONE) + return knownAbility; if (BATTLE_HISTORY->abilities[battlerId] != ABILITY_NONE) return BATTLE_HISTORY->abilities[battlerId]; - // Abilities that prevent fleeing. - if (gBattleMons[battlerId].ability == ABILITY_SHADOW_TAG - || gBattleMons[battlerId].ability == ABILITY_MAGNET_PULL - || gBattleMons[battlerId].ability == ABILITY_ARENA_TRAP) - return gBattleMons[battlerId].ability; + // Abilities that prevent fleeing - treat as always known + if (knownAbility == ABILITY_SHADOW_TAG || knownAbility == ABILITY_MAGNET_PULL || knownAbility == ABILITY_ARENA_TRAP) + return knownAbility; + // Else, guess the ability if (gBaseStats[gBattleMons[battlerId].species].abilities[0] != ABILITY_NONE) { if (gBaseStats[gBattleMons[battlerId].species].abilities[1] != ABILITY_NONE) @@ -1093,6 +1098,7 @@ s32 AI_GetAbility(u32 battlerId) return gBaseStats[gBattleMons[battlerId].species].abilities[0]; // It's definitely ability 1. } } + return ABILITY_NONE; // Unknown. } diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 3f53bd3015..79d9672aff 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -6161,7 +6161,7 @@ static void Cmd_switchineffects(void) { // There is a hack here to ensure the truant counter will be 0 when the battler's next turn starts. // The truant counter is not updated in the case where a mon switches in after a lost judgement in the battle arena. - if (gBattleMons[gActiveBattler].ability == ABILITY_TRUANT + if (GetBattlerAbility(gActiveBattler) == ABILITY_TRUANT && gCurrentActionFuncId != B_ACTION_USE_MOVE && !gDisableStructs[gActiveBattler].truantSwitchInHack) gDisableStructs[gActiveBattler].truantCounter = 1; @@ -7353,7 +7353,7 @@ u32 IsLeafGuardProtected(u32 battler) bool32 IsShieldsDownProtected(u32 battler) { - return (gBattleMons[battler].ability == ABILITY_SHIELDS_DOWN + return (GetBattlerAbility(battler) == ABILITY_SHIELDS_DOWN && GetFormIdFromFormSpeciesId(gBattleMons[battler].species) < GetFormIdFromFormSpeciesId(SPECIES_MINIOR_CORE_RED)); // Minior is not in core form } @@ -7821,6 +7821,7 @@ static void Cmd_various(void) break; case VARIOUS_SWITCHIN_ABILITIES: gBattlescriptCurrInstr += 3; + AbilityBattleEffects(ABILITYEFFECT_NEUTRALIZINGGAS, gActiveBattler, 0, 0, 0); AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, gActiveBattler, 0, 0, 0); AbilityBattleEffects(ABILITYEFFECT_INTIMIDATE2, gActiveBattler, 0, 0, 0); AbilityBattleEffects(ABILITYEFFECT_TRACE2, gActiveBattler, 0, 0, 0); @@ -11060,11 +11061,11 @@ static void Cmd_healpartystatus(void) u16 ability; if (gBattlerPartyIndexes[gBattlerAttacker] == i) - ability = gBattleMons[gBattlerAttacker].ability; + ability = GetBattlerAbility(gBattlerAttacker); else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattlerPartyIndexes[gActiveBattler] == i && !(gAbsentBattlerFlags & gBitTable[gActiveBattler])) - ability = gBattleMons[gActiveBattler].ability; + ability = GetBattlerAbility(gBattlerAttacker); else ability = GetAbilityBySpecies(species, abilityNum); diff --git a/src/battle_util.c b/src/battle_util.c index 9497f7d180..212f4216e3 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -317,8 +317,8 @@ void HandleAction_UseMove(void) else if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gSideTimers[side].followmeTimer == 0 && (gBattleMoves[gCurrentMove].power != 0 || gBattleMoves[gCurrentMove].target != MOVE_TARGET_USER) - && ((gBattleMons[*(gBattleStruct->moveTarget + gBattlerAttacker)].ability != ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC) - || (gBattleMons[*(gBattleStruct->moveTarget + gBattlerAttacker)].ability != ABILITY_STORM_DRAIN && moveType == TYPE_WATER))) + && ((GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC) + || (GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_STORM_DRAIN && moveType == TYPE_WATER))) { side = GetBattlerSide(gBattlerAttacker); for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) @@ -387,9 +387,9 @@ void HandleAction_UseMove(void) { gActiveBattler = gBattlerByTurnOrder[var]; RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability); - if (gBattleMons[gActiveBattler].ability == ABILITY_LIGHTNING_ROD) + if (GetBattlerAbility(gActiveBattler) == ABILITY_LIGHTNING_ROD) gSpecialStatuses[gActiveBattler].lightningRodRedirected = 1; - else if (gBattleMons[gActiveBattler].ability == ABILITY_STORM_DRAIN) + else if (GetBattlerAbility(gActiveBattler) == ABILITY_STORM_DRAIN) gSpecialStatuses[gActiveBattler].stormDrainRedirected = 1; gBattlerTarget = gActiveBattler; } @@ -2641,7 +2641,7 @@ u8 DoBattlerEndTurnEffects(void) for (gBattlerAttacker = 0; gBattlerAttacker < gBattlersCount; gBattlerAttacker++) { if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) - && gBattleMons[gBattlerAttacker].ability != ABILITY_SOUNDPROOF) + && GetBattlerAbility(gBattlerAttacker) != ABILITY_SOUNDPROOF) { gBattleMons[gBattlerAttacker].status1 &= ~(STATUS1_SLEEP); gBattleMons[gBattlerAttacker].status2 &= ~(STATUS2_NIGHTMARE); @@ -3225,7 +3225,7 @@ u8 AtkCanceller_UnableToUseMove(void) gBattleStruct->atkCancellerTracker++; break; case CANCELLER_TRUANT: // truant - if (gBattleMons[gBattlerAttacker].ability == ABILITY_TRUANT && gDisableStructs[gBattlerAttacker].truantCounter) + if (GetBattlerAbility(gBattlerAttacker) == ABILITY_TRUANT && gDisableStructs[gBattlerAttacker].truantCounter) { CancelMultiTurnMoves(gBattlerAttacker); gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; @@ -3665,7 +3665,7 @@ u8 TryWeatherFormChange(u8 battler) if (gBattleMons[battler].species == SPECIES_CASTFORM) { - if (gBattleMons[battler].ability != ABILITY_FORECAST || gBattleMons[battler].hp == 0) + if (GetBattlerAbility(battler) != ABILITY_FORECAST || gBattleMons[battler].hp == 0) { ret = 0; } @@ -3701,7 +3701,7 @@ u8 TryWeatherFormChange(u8 battler) } else if (gBattleMons[battler].species == SPECIES_CHERRIM) { - if (gBattleMons[battler].ability != ABILITY_FLOWER_GIFT || gBattleMons[battler].hp == 0) + if (GetBattlerAbility(battler) != ABILITY_FLOWER_GIFT || gBattleMons[battler].hp == 0) ret = 0; else if (gBattleMonForms[battler] == 0 && weatherEffect && gBattleWeather & WEATHER_SUN_ANY) ret = 2; @@ -3791,7 +3791,7 @@ static bool32 ShouldChangeFormHpBased(u32 battler) for (i = 0; i < ARRAY_COUNT(forms); i++) { - if (gBattleMons[battler].ability == forms[i][0]) + if (GetBattlerAbility(battler) == forms[i][0]) { if (gBattleMons[battler].species == forms[i][2] && gBattleMons[battler].hp > gBattleMons[battler].maxHP / forms[i][3]) @@ -5220,7 +5220,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move case ABILITYEFFECT_IMMUNITY: // 5 for (battler = 0; battler < gBattlersCount; battler++) { - switch (gBattleMons[battler].ability) + switch (GetBattlerAbility(battler)) { case ABILITY_IMMUNITY: if (gBattleMons[battler].status1 & (STATUS1_POISON | STATUS1_TOXIC_POISON | STATUS1_TOXIC_COUNTER)) @@ -5310,7 +5310,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move case ABILITYEFFECT_FORECAST: // 6 for (battler = 0; battler < gBattlersCount; battler++) { - if (gBattleMons[battler].ability == ABILITY_FORECAST || gBattleMons[battler].ability == ABILITY_FLOWER_GIFT) + if (GetBattlerAbility(battler) == ABILITY_FORECAST || GetBattlerAbility(battler) == ABILITY_FLOWER_GIFT) { effect = TryWeatherFormChange(battler); if (effect) @@ -5369,7 +5369,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move case ABILITYEFFECT_INTIMIDATE2: for (i = 0; i < gBattlersCount; i++) { - if (gBattleMons[i].ability == ABILITY_INTIMIDATE && gBattleResources->flags->flags[i] & RESOURCE_FLAG_INTIMIDATED) + if (GetBattlerAbility(i) == ABILITY_INTIMIDATE && gBattleResources->flags->flags[i] & RESOURCE_FLAG_INTIMIDATED) { gLastUsedAbility = ABILITY_INTIMIDATE; gBattleResources->flags->flags[i] &= ~(RESOURCE_FLAG_INTIMIDATED); @@ -5437,7 +5437,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move } break; case ABILITYEFFECT_NEUTRALIZINGGAS: - // for the start of battle only. The switch-in message plays in Cmd_switchineffects because it comes before the hazards + // Prints message only. separate from ABILITYEFFECT_ON_SWITCHIN bc activates before entry hazards for (i = 0; i < gBattlersCount; i++) { if (gBattleMons[i].ability == ABILITY_NEUTRALIZING_GAS && !(gBattleResources->flags->flags[i] & RESOURCE_FLAG_NEUTRALIZING_GAS)) @@ -5460,7 +5460,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move return effect; } -static bool32 IsNeutralizingGasBannedAbility(u32 ability) +bool32 IsNeutralizingGasBannedAbility(u32 ability) { switch (ability) { @@ -5483,7 +5483,7 @@ static bool32 IsNeutralizingGasBannedAbility(u32 ability) } } -static bool32 IsNeutralizingGasOnField(void) +bool32 IsNeutralizingGasOnField(void) { u32 i; @@ -5567,7 +5567,7 @@ u32 IsAbilityPreventingEscape(u32 battlerId) return 0; #endif #if B_SHADOW_TAG_ESCAPE >= GEN_4 - if ((id = IsAbilityOnOpposingSide(battlerId, ABILITY_SHADOW_TAG)) && gBattleMons[battlerId].ability != ABILITY_SHADOW_TAG) + if ((id = IsAbilityOnOpposingSide(battlerId, ABILITY_SHADOW_TAG)) && GetBattlerAbility(battlerId) != ABILITY_SHADOW_TAG) #else if (id = IsAbilityOnOpposingSide(battlerId, ABILITY_SHADOW_TAG)) #endif @@ -7113,7 +7113,7 @@ u32 GetMoveTarget(u16 move, u8 setTarget) targetBattler = SetRandomTarget(gBattlerAttacker); if (gBattleMoves[move].type == TYPE_ELECTRIC && IsAbilityOnOpposingSide(gBattlerAttacker, ABILITY_LIGHTNING_ROD) - && gBattleMons[targetBattler].ability != ABILITY_LIGHTNING_ROD) + && GetBattlerAbility(targetBattler) != ABILITY_LIGHTNING_ROD) { targetBattler ^= BIT_FLANK; RecordAbilityBattle(targetBattler, gBattleMons[targetBattler].ability); @@ -7121,7 +7121,7 @@ u32 GetMoveTarget(u16 move, u8 setTarget) } else if (gBattleMoves[move].type == TYPE_WATER && IsAbilityOnOpposingSide(gBattlerAttacker, ABILITY_STORM_DRAIN) - && gBattleMons[targetBattler].ability != ABILITY_STORM_DRAIN) + && GetBattlerAbility(targetBattler) != ABILITY_STORM_DRAIN) { targetBattler ^= BIT_FLANK; RecordAbilityBattle(targetBattler, gBattleMons[targetBattler].ability); @@ -7299,7 +7299,7 @@ u32 GetBattlerHoldEffect(u8 battlerId, bool32 checkNegating) return HOLD_EFFECT_NONE; if (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM) return HOLD_EFFECT_NONE; - if (gBattleMons[battlerId].ability == ABILITY_KLUTZ && !(gStatuses3[battlerId] & STATUS3_GASTRO_ACID)) + if (GetBattlerAbility(battlerId) == ABILITY_KLUTZ && !(gStatuses3[battlerId] & STATUS3_GASTRO_ACID)) return HOLD_EFFECT_NONE; } diff --git a/src/battle_util2.c b/src/battle_util2.c index d15700706a..0af19de274 100644 --- a/src/battle_util2.c +++ b/src/battle_util2.c @@ -142,7 +142,7 @@ u32 sub_805725C(u8 battlerId) { u32 toSub; - if (gBattleMons[battlerId].ability == ABILITY_EARLY_BIRD) + if (GetBattlerAbility(battlerId) == ABILITY_EARLY_BIRD) toSub = 2; else toSub = 1; From a1e64fce4f52f40a68d06f18e313e76450677009 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 1 Nov 2021 13:50:57 -0400 Subject: [PATCH 08/69] handle simple beam, gastro acid --- asm/macros/battle_script.inc | 4 ++++ data/battle_scripts_1.s | 2 ++ include/battle.h | 3 ++- include/constants/battle_script_commands.h | 1 + src/battle_script_commands.c | 15 +++++++++++++++ src/battle_util.c | 2 +- 6 files changed, 25 insertions(+), 2 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 04f6e04dc7..80c78a932b 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1863,6 +1863,10 @@ .2byte \species .4byte \ptr .endm + + .macro tryendneutralizinggas battler:req + various \battler, VARIOUS_TRY_END_NEUTRALIZING_GAS + .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 9fdd54e712..2b07f49d94 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -1993,6 +1993,7 @@ BattleScript_EffectSimpleBeam: printstring STRINGID_PKMNACQUIREDSIMPLE waitmessage B_WAIT_TIME_LONG trytoclearprimalweather + tryendneutralizinggas BS_TARGET printstring STRINGID_EMPTYSTRING3 waitmessage 1 goto BattleScript_MoveEnd @@ -2215,6 +2216,7 @@ BattleScript_EffectGastroAcid: printstring STRINGID_PKMNSABILITYSUPPRESSED waitmessage B_WAIT_TIME_LONG trytoclearprimalweather + tryendneutralizinggas BS_TARGET printstring STRINGID_EMPTYSTRING3 waitmessage 1 goto BattleScript_MoveEnd diff --git a/include/battle.h b/include/battle.h index 68a40c9789..d505220839 100644 --- a/include/battle.h +++ b/include/battle.h @@ -182,7 +182,8 @@ struct SpecialStatus u8 damagedMons:4; // Mons that have been damaged directly by using a move, includes substitute. u8 dancerUsedMove:1; u8 dancerOriginalTarget:3; - u8 announceNeutralizingGas:1; + u8 announceNeutralizingGas:1; // See Cmd_switchineffects + u8 neutralizingGasRemoved:1; // See VARIOUS_TRY_END_NEUTRALIZING_GAS s32 dmg; s32 physicalDmg; s32 specialDmg; diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index f006952766..d05559bf42 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -194,6 +194,7 @@ #define VARIOUS_HANDLE_PRIMAL_REVERSION 121 #define VARIOUS_APPLY_PLASMA_FISTS 122 #define VARIOUS_JUMP_IF_SPECIES 123 +#define VARIOUS_TRY_END_NEUTRALIZING_GAS 124 // Cmd_manipulatedamage #define DMG_CHANGE_SIGN 0 diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 79d9672aff..802c151b4f 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -8002,6 +8002,9 @@ static void Cmd_various(void) } else { + if (gBattleMons[gBattlerTarget].ability == ABILITY_NEUTRALIZING_GAS) + gSpecialStatuses[gBattlerTarget].neutralizingGasRemoved = TRUE; + gBattleMons[gBattlerTarget].ability = ABILITY_SIMPLE; gBattlescriptCurrInstr += 7; } @@ -8899,6 +8902,15 @@ static void Cmd_various(void) } break; } + case VARIOUS_TRY_END_NEUTRALIZING_GAS: + if (gSpecialStatuses[gActiveBattler].neutralizingGasRemoved) + { + gSpecialStatuses[gActiveBattler].neutralizingGasRemoved = FALSE; + BattleScriptPush(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits; + return; + } + break; case VARIOUS_GET_ROTOTILLER_TARGETS: // Gets the battlers to be affected by rototiller. If there are none, print 'But it failed!' { @@ -12011,6 +12023,9 @@ static void Cmd_setgastroacid(void) } else { + if (gBattleMons[gBattlerTarget].ability == ABILITY_NEUTRALIZING_GAS) + gSpecialStatuses[gBattlerTarget].neutralizingGasRemoved = TRUE; + gStatuses3[gBattlerTarget] |= STATUS3_GASTRO_ACID; gBattlescriptCurrInstr += 5; } diff --git a/src/battle_util.c b/src/battle_util.c index 212f4216e3..3ec6fc3d97 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -5489,7 +5489,7 @@ bool32 IsNeutralizingGasOnField(void) for (i = 0; i < gBattlersCount; i++) { - if (IsBattlerAlive(i) && gBattleMons[i].ability == ABILITY_NEUTRALIZING_GAS) + if (IsBattlerAlive(i) && gBattleMons[i].ability == ABILITY_NEUTRALIZING_GAS && !(gStatuses3[i] & STATUS3_GASTRO_ACID)) return TRUE; } From 48bea554a3ce764bc8546e326f5eb92afbbde88a Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 1 Nov 2021 14:21:28 -0400 Subject: [PATCH 09/69] fix tryendneutralizinggas placement --- data/battle_scripts_1.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index aca99afbc8..3549a1f7f0 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -1993,9 +1993,9 @@ BattleScript_EffectSimpleBeam: printstring STRINGID_PKMNACQUIREDSIMPLE waitmessage B_WAIT_TIME_LONG trytoclearprimalweather - tryendneutralizinggas BS_TARGET printstring STRINGID_EMPTYSTRING3 waitmessage 1 + tryendneutralizinggas BS_TARGET goto BattleScript_MoveEnd BattleScript_EffectSuckerPunch: @@ -2216,9 +2216,9 @@ BattleScript_EffectGastroAcid: printstring STRINGID_PKMNSABILITYSUPPRESSED waitmessage B_WAIT_TIME_LONG trytoclearprimalweather - tryendneutralizinggas BS_TARGET printstring STRINGID_EMPTYSTRING3 waitmessage 1 + tryendneutralizinggas BS_TARGET goto BattleScript_MoveEnd BattleScript_EffectToxicSpikes: From e4242d04abf2a1c3e906283302a4fe3aee1ac2a8 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 1 Nov 2021 14:28:41 -0400 Subject: [PATCH 10/69] remove battler skipping in neutralizing gas exit bs --- data/battle_scripts_1.s | 2 -- src/battle_script_commands.c | 1 - 2 files changed, 3 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 3549a1f7f0..59941ec23e 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -8962,9 +8962,7 @@ BattleScript_NeutralizingGasExits:: waitmessage B_WAIT_TIME_LONG setbyte gBattlerTarget, 0 BattleScript_NeutralizingGasExitsLoop: - jumpifbyteequal gEffectBattler, gBattlerTarget, BattleScript_NeutralizingGasExitsIncrement @ skip over battler switching out switchinabilities BS_TARGET -BattleScript_NeutralizingGasExitsIncrement: addbyte gBattlerTarget, 1 jumpifbytenotequal gBattlerTarget, sByteFour, BattleScript_NeutralizingGasExitsLoop @ SOMEHOW, comparing to gBattlersCount is problematic. restoretarget diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 5c61b9278c..b4345bff5a 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -12312,7 +12312,6 @@ static void Cmd_switchoutabilities(void) if (gBattleMons[gActiveBattler].ability == ABILITY_NEUTRALIZING_GAS) { gBattleMons[gActiveBattler].ability = ABILITY_NONE; - gEffectBattler = gActiveBattler; BattleScriptPush(gBattlescriptCurrInstr); gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits; } From 802ba88621a65f0be7d1f1849ae42e2dab990a70 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 1 Nov 2021 15:10:51 -0400 Subject: [PATCH 11/69] fix ABILITYEFFECT_NEUTRALIZINGGAS --- src/battle_util.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/battle_util.c b/src/battle_util.c index 071f999f33..b39df4992d 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -5498,6 +5498,9 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move BattleScriptPushCursorAndCallback(BattleScript_SwitchInAbilityMsg); effect++; } + + if (effect) + break; } break; } From 71ca9fdb58345542c7de05ce7b25a65b824b8d90 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 1 Nov 2021 15:18:41 -0400 Subject: [PATCH 12/69] fix Cmd_healpartystatus GetBattlerAbility check --- 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 b4345bff5a..db9794836d 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -11080,7 +11080,7 @@ static void Cmd_healpartystatus(void) else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattlerPartyIndexes[gActiveBattler] == i && !(gAbsentBattlerFlags & gBitTable[gActiveBattler])) - ability = GetBattlerAbility(gBattlerAttacker); + ability = GetBattlerAbility(gActiveBattler); else ability = GetAbilityBySpecies(species, abilityNum); From 2d5ed4a1e2aad32f2b7e24ac57c8b6fbc7e80c7d Mon Sep 17 00:00:00 2001 From: Blackforest92 Date: Tue, 2 Nov 2021 12:53:11 +0700 Subject: [PATCH 13/69] Allow Giga Impact fadein background & upgrade its graphic --- data/battle_anim_scripts.s | 24 +++++++++++++----- .../battle_anims/backgrounds/giga_impact.pal | 19 -------------- .../backgrounds/new/giga_impact.pal | 19 ++++++++++++++ .../backgrounds/new/giga_impact.png | Bin 0 -> 2395 bytes .../backgrounds/new/giga_impact_contest.bin | 3 +++ .../backgrounds/new/giga_impact_opponent.bin | Bin 896 -> 896 bytes .../backgrounds/new/giga_impact_opponent.pal | 19 -------------- .../backgrounds/new/giga_impact_opponent.png | Bin 3056 -> 0 bytes .../backgrounds/new/giga_impact_player.bin | Bin 896 -> 896 bytes .../backgrounds/new/giga_impact_player.pal | 19 -------------- .../backgrounds/new/giga_impact_player.png | Bin 3098 -> 0 bytes .../backgrounds/new/spacial_rend_opponent.bin | 3 --- .../backgrounds/new/spacial_rend_player.bin | Bin 896 -> 0 bytes include/graphics.h | 8 +++--- src/battle_anim.c | 10 ++++---- src/graphics.c | 17 +++++-------- 16 files changed, 55 insertions(+), 86 deletions(-) delete mode 100644 graphics/battle_anims/backgrounds/giga_impact.pal create mode 100644 graphics/battle_anims/backgrounds/new/giga_impact.pal create mode 100644 graphics/battle_anims/backgrounds/new/giga_impact.png create mode 100644 graphics/battle_anims/backgrounds/new/giga_impact_contest.bin delete mode 100644 graphics/battle_anims/backgrounds/new/giga_impact_opponent.pal delete mode 100644 graphics/battle_anims/backgrounds/new/giga_impact_opponent.png delete mode 100644 graphics/battle_anims/backgrounds/new/giga_impact_player.pal delete mode 100644 graphics/battle_anims/backgrounds/new/giga_impact_player.png delete mode 100644 graphics/battle_anims/backgrounds/new/spacial_rend_opponent.bin delete mode 100644 graphics/battle_anims/backgrounds/new/spacial_rend_player.bin diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 03d72f3ea4..6b417944ef 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -2502,15 +2502,24 @@ Move_GIGA_IMPACT: waitforvisualfinish delay 11 createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 26, 0, 0, 5 - delay 6 - @monbg ANIM_DEF_PARTNER - @setalpha 12, 8 - @createvisualtask AnimTask_WindUpLunge, 5, 7, 0, -18, 8, 23, 10, 40, 10 - @delay 35 - createsprite gComplexPaletteBlendSpriteTemplate, 2, 7, 31, 3, 1, 0, 10, 0, 0 + createvisualtask AnimTask_IsContest, 2 + jumprettrue SetGigaImpactContestsBG + createvisualtask AnimTask_IsTargetPlayerSide, 2 + jumpretfalse SetGigaImpactOpponentBG + goto SetGigaImpactPlayerBG +SetGigaImpactOpponentBG: + fadetobg BG_GIGA_IMPACT_OPPONENT + goto GigaImpactContinuity +SetGigaImpactPlayerBG: + fadetobg BG_GIGA_IMPACT_PLAYER + goto GigaImpactContinuity +SetGigaImpactContestsBG: + fadetobg BG_GIGA_IMPACT_CONTEST + goto GigaImpactContinuity +GigaImpactContinuity: + waitbgfadeout createsprite gBasicHitSplatSpriteTemplate, 4, 4, -10, 0, 1, 0 playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET - call SetImpactBackground delay 1 createsprite gSlideMonToOffsetSpriteTemplate 2, 5, 1, -16, 0, 0, 4 waitforvisualfinish @@ -2525,6 +2534,7 @@ Move_GIGA_IMPACT: blendoff restorebg waitbgfadein + waitforvisualfinish end Move_NASTY_PLOT: diff --git a/graphics/battle_anims/backgrounds/giga_impact.pal b/graphics/battle_anims/backgrounds/giga_impact.pal deleted file mode 100644 index 944174076e..0000000000 --- a/graphics/battle_anims/backgrounds/giga_impact.pal +++ /dev/null @@ -1,19 +0,0 @@ -JASC-PAL -0100 -16 -0 0 0 -255 214 0 -255 197 0 -255 173 0 -255 165 0 -148 90 222 -255 107 0 -255 132 0 -255 148 0 -255 156 41 -0 0 0 -0 90 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 diff --git a/graphics/battle_anims/backgrounds/new/giga_impact.pal b/graphics/battle_anims/backgrounds/new/giga_impact.pal new file mode 100644 index 0000000000..06f02604a6 --- /dev/null +++ b/graphics/battle_anims/backgrounds/new/giga_impact.pal @@ -0,0 +1,19 @@ +JASC-PAL +0100 +16 +0 0 0 +240 136 184 +232 104 168 +136 8 40 +248 24 104 +216 32 96 +224 72 136 +160 0 48 +216 0 64 +200 40 88 +192 0 56 +176 32 128 +176 24 72 +152 16 56 +200 48 80 +216 56 160 diff --git a/graphics/battle_anims/backgrounds/new/giga_impact.png b/graphics/battle_anims/backgrounds/new/giga_impact.png new file mode 100644 index 0000000000000000000000000000000000000000..0d5d705fe32a0bc2f3922e8dcecad12a06272eed GIT binary patch literal 2395 zcmV-h38eOkP){(J`cel1EpWJz|Bo3r3$Y2E4xh#?MSCF%~md}P7B3hV5 zfB=fI*v=LhfR0k+3h}gs8-i+F3KDR@U3EYzu`-eXK{`Rb-+AYI=G|Q?DU&Hq3j8n3IklTVi!ML)&eRFMEb*J zy#w07Dp4Q)(2#+lUrKoo-pCJsXbO?gW96;LX{$6%$Kwy(%c@6=%glfRq@(*JU{?Ul zPd&h&(81EZtUcSK=mSRRfYe7be-wQH)2Cxn-y;lE0QTIg*mem66@dFBU_}^+T5e|u zAoU^wN6>oHe&1_~VBfjgx=aARAOXAfJd}XY`Brs?D|ZqKfQ{U(&TvK<0D#?HT$y2y zNDu+YL zX~!Io6;S|gRs=vBFs39`z)AqDi7-+bvhh&8#zX;~L;%|6Rb96=r&mM);|jp1+JGJe zQNZ;Vt^o$HrlJ}IYhCCGy}6u?s{q=7dsAFbe&ZQ%0X>-^v9|WCxiqcBH;QLkqd}Luc^B@_v{rlR$GKK z4?1JPN!#`yI7>RdMMEw?Mi7PvW`;3gfEVQ43mqQ8=pbyjO|Y}68GEF2H+J|x2awEx z5kZ`c%`u1*J*3Wp5_1gb!?qDYGD=5|0ikyRyuHf+2TSdXoqF_AdEJ~+?wY77Ftdeq zZZy&cURtMh0CZgd(}zX`_LhI$no-q&FRK8teb{#P1=idQom<;EY=_~K?!*RQhVA?6 z{m8npV&|C0ZUv_XC&RvFAa+k_0LUB%7=gYOJ5B=jmjTdq02o22D_{nmsCSN@12XFp zk3d1$k>ks#vH>8=Yzr8Ho}SMt&y51m&Zg2q7t_QFG_vx@q5%u;VA7pTCUO?2FLde+ z0O0a;3Ix_khGAd?SCoUwW1|A>WM#SNzJ_{6zz9?-aczPKxKfs7_SI`J7Ca25-%)^P z^#w4%)oEEy@BWO*Sr{0>XA;n_Pmlw^LHW(=pf6bkEQ0o8A^@F=Q>O>`?Zrh_PD|*R zMX;j=c4W-KI>4jg62nXZz$!SD4*E?6Fu)-wA96sMb$79XMJ6j~(hI;}IRHXr8D1@A zhNDIU0Qi7qC>>2_QJd}XNQHaBuc`LnWPt9?S72qfcUPnL)5gg)ZL=!^Z zAEl|IPg-pp#o*^0fDtkPskhgbL<7DF0-Vt0LteomqiT3+pS$ES?=lA*BH$>*QH7b9 zdHQGe{uE2VRh$NajG!&%gS%I7{n*nx0F013;5Ec=ntFX}Dm@2m2U{`%4l0F%Snj;I zy`>+y0cgObV;;c{*H8KS8mj}C^I$~D;byved<--BjiSH^4uu0;>EBiR3lG36fW2-V z7R51419TuF#BpT(;~^I2R7?iI-?VP$$9WLEJuFxRq5{l-=`XYGMiij*eM1g_JkS3a z1h;aGKvn=2y0}A5GT5#4A&8;;U+`AcE7!33BNLNr|0avCl zB`4d2Ke@E1qipdL))d6CUlT~LdYFJpy#8b4-W|U9^n030w4|iL+RU;dukN;WGIZ4 z5#|4!ROwR+kaK|4-|=rM(b%3x0Du5Drn%y+uYpEtzX4!cSKu<;AfF-8^Fq4k8-q~CDc`qIB&reU+>oqkG^hBsS^qQ^0 zfl&cD291D1hd`g)HNZLY=riP=yfRCSMgi0}qjLiwulDNo48UK^q5VYzYD=AC-kQLe1_NO zr|WYAaOQr^dS0blGE0oM|3CrY-5Djf*R{lJ8t~CMsaH>6*l&iuUIXk$HF{r?SaH6r z2H1tFwij6d_QRu!?!2!$$$$$$$$$ J!K!L!M!N!O!B!,,,,,,,,,((((((((((((((((J)K)L)M)N)O)B),,,,,,,,,((((((((((((((((:);)<)=)>)?)2),,,,,,,,,((((((((((((((((*)+),)-).)/)"),,,,,,,,,(((((((((((((((())))))),,,,,,,,,(((((((((((((((( +) ) ) )))),,,,,,,,,(((((((((((((((((((((((,,,,,,,,,((((((((((((((((D)E)F)G)H)I)@) \ No newline at end of file diff --git a/graphics/battle_anims/backgrounds/new/giga_impact_opponent.bin b/graphics/battle_anims/backgrounds/new/giga_impact_opponent.bin index a55ff2f56d9a53ef07152d362167283f90593bd6..0cfa1f1ec6dca34cd21cca537bd29b56db5bc585 100644 GIT binary patch literal 896 zcmV~$=}!m%7zg0ZN5tl%&^!CR+dFC zupZKb`VzIM!3#XcGdx8#s!)jvl%ou#C_yobr9?`lOvZL&%rAeBlMOvjzPV0F+r>@kqdPcus2!r^H z0er$o^rH{G=s`ES(1{MTqg^_rQ@W&EdZbtSq+c#*s9x3(y`;fsu@#R!HmEF&^1V=^uiGAUCsEn#|3@9G`Btr2=lcd(6L_=zoS;s-Xcjy0@e z1$YJRJk&3Hh+pzxzv$mN&u^ULSI%;V)12ZYCpgYAj&g*<9JUb~ zwJ{sF37fPjo3_(_-p{!^{j8tyFC5|^KXZVe_>ukWV=sHy%`SGbgY9g$4(qfo>$V>2 zwLa^&V;E^Y-9uLS;so7w+3spCTq49Yqd5z z;79$42l!z>vLEZQHhO+qP}nwrwZ9JzKM>UqAKgP4~RM=k~2O zaKafE469sm!yOMi@xmJ)eDT8{8vz8WZ;LI@>h6cLNq#33&6h))7NO9*Ne5|NlB zBqbTi2_pq5NkwYXkd}0$CxdmPK}Ir>nJi=_8`%jb2RX?_Zt{?qeB`G95foHih{6=1 zD8(pF3C)+J6s0LcS^Zaz@>HNAm8eV=s#1;W)SxD{6kA($1a+uOJ?hhdhMH(ZW17&E zW;CY-Ev-zgXiXd1(vJ3Y&}1ZSR!2I~nJ$(#`t7>XjqdcIC%x#cUaAj$>1S~!-Jbyr zWDtWL@Ix5NForWi)ksD$nlW~?=`ogZjCa6CCo!17L?$uWAwPwwDqW;{8q=A$VHwL=!Ae$X-D=jbmUXOW0~_^Z6Pww>R<^O79qeQmyX_qI zu$O)8*Xn;0oBIPCWRIIB+1{f9SQ&U1l_T;eiUxXLxI zbAy}Q;x>1<%RR;4*Zcz>@<{K(!yfa5r#$01FL=o-Uh{^xO8JiWeBdLW_{(P)003|V0{{R3Yu{!u0000mP)t-sDKRl> zi@o-PwEqDA{}5vCVx;ClgWdo+-WXcVDN4;CQoR5%tPnw*04bCZF@p#o(kMrR000Yn zNklEVED$n7w z(GY5=)C(b2kwL&U2EGYHH4BKuWBnBaZxqD{;7O7+?jlKuZ{TB}fE(cz2L5g~5QxU; zQ!NpQC!jD41w4EpL{piu9WG=9T)hMc#H|VuBoKNwmN>;T1_j)n&l)+(;}p zS>muL{z1S6w)s^JxYqE2|7(M1cW1D>2wWWuiVp&TA=|v}1HtBGp`!4xO=CKgT#e5% z5G4xndjsqP5G2ABs(_sYLx_9&;lH-c`1W{)Vt&I7HBfz;gL$R$zF3hO7%~w5?$;`@ z-JUfGMC72>bFe3xAT!{2MBq*QGoqe*z?mvBJXbkAcn+ixQf7gD2U+~9unzi7q%Tyc`BBp zC@>Z`Ao&Ynfpwx5dDc7PUyorFMaxNCP`T``AW&QUY*Z8{9&mzqhkm*iHYk7KuVMV# zlL!hQHc26RJe-R$)bW=t`f*&v=LEfI`WuYT@sFF3`~b`{br8-)GAB;M0C^@}1Fz4( z@_e&4u|AQK1CT+M=inev7)#B&-teo7)zNFP%5H(7L#1!nbKHC{^W>%*T6K5Wt;#o&OoY^Y`HQSN&+1Z z$NSCc#5Dp&G}aJ^v{*}g;|uH*wV3v0I%l7I!0QN%Wg3B80On+ILksK->cEOj=bHZ_ z5I)Bgq{W^q9_va*B8tq*(ljLlvW$HHgoSq$zNns)2m}~Lhw4(;{~2w~Wz>D-fcODC zncv4)XWz=gz$lKu;&}=y z=Ap!%8;^H2Fl-p0>SDHl#DIx} z(Gkm2c+}59wRt>c34f<<6)I(F>%AgvBJjS%Xq57%OP%X zrR_q)Xxoh`x$NvyPLK}i#pa{P>wc6f4}}>Gll0Spqw0J~Z-tT4Edr4EdNU2X-b;aH z#lYN4I!xLuvp|QuTp`BX&;v$kMPlv&Ei$P9&)>D7S#dqZ*q7*A97U#gR-3NDf7h}i z1ERI;=70+#ZmMMijfWEXLJ*iKAHh3NJqX zg-e{jD+t1dXtsM#lw^w|FVP2;l7RW5B{I&e8=a27aS8OqlS!!!Gai1Crg%*GZ9cBI zxmno)24gRPx!G5iIMUs`b~DZ}E4=VlwW`2x0~Z=>vtQdPMS@Ibn=6ZCRbe?<9Q<0J zO-8lhPb`tfWL)Yho#Du-%3a}F5*=EBvzb6bLSP%M_JnHe)fq35mmsDdIf0YihTdNW zHC*XA_HC=_Rfa_lejQPR>Jt9aZdVEDcL+w{+ZLWU=3c2;)Ul5%9PXh$eSH6tXuH4o zxm-VuW8QPxb=PX^qRppgu!Wj2f@()Z20!Oo^9S;ZR|(Tam!q#|0;}H^!?&h-t#jNs zBGjS2BhCcgtN)~UZtLOtL@;9M*!G~GT}XG1X(gHnY=>+9V3JM;V=LlvlQ^K`{fWdB zMGg45W$U#)R5sC##|T`04Y7P)!BL1*fS)(p%?X~$cpASBBdt&!XyWH84zq0N1L1vE z;2*uh#R|E@2*!5@GcatVPy(8LS92T`B>wGi+z(%NjxcRwzs_2 zfd%Rfo{UXnlS~78UiSQN9A>&3th-Ag3yfWP*q)|v2-^xQtFUFgQmcF%%2L+>k9;|jSS*-@#be$mrNl>^}YYjbzxGzwCDZOqc&@?4>1`pfd{DC_0 zQ%R}=v7UpPL<9RI(61?L%la6>+?VKbdcN7dhwToX8Vk2I*%KrOHk5!3_5=x3yuYT6 za3UyT@~p3k#h7>yqI5Dy0&m#VR4ovjrc2>`9H&uWWNpwInPm_4#n9{`U*eIROJID@ zR$-32S1j=QoOY_7oSiABntGhUmePKMC((DXIbh+>EO45gkJj&^o^ zoX0z){$o^(Mf@2oe;yH}3O5nb48x38UUQmn;20~oC-(g+_=XmeD zmZ;=i0V>odM)$+agcaW842LIT$LASb&vqSWZ8n&{L48m<0$O-rMVUYOS8NuS@F+rqT4GWnag1V3(rYj;a5$su`i0x|xj^aF`}s3J zF*)iB6Qp`U@_=u6E`~!h7tIOa1g|s-Uzqt z6`<~z>83PkKAf@pETejAnDi8!d zo#63iv}LC7fbU8AGy&Uqu~YCRZo4g-&6O&!Zmza@$X?VpOnlAIw--&Yp7n7S)S>c%wjfkn9Drovw+8VoF{mar+AuYc$Po-lfU?zfB2Ul_>mP}?qy!; zC0^`BUg(7^Vlhit$}*O-g6DXi7kH7Ec$rstm4<4h#%iLbYNq-+SsT3G>%7)$yxOb0 z(kofTYSyrpb*yItukku>@Fs8ZHt+B*7wZyTs>^h_uF%;!M?1XT+q~6VyxE()(Hq&s zX11`EZER-;@9{n#@F5@ZF`w`$&DBDYTB?;=D@L(8;Qij`z24*9-sPR%$u4%YhrR4$ zKL_}X&-sEc`HHXkhHq)7_UfRH>ZHy}R*LFe>l#|Y(r7*{=_GC;JsHSICb2VxQ;1T)NBJs~_f!7LN`MMf_P+niAQh}aRHzEmeC*sYmdXDE+`ibE diff --git a/graphics/battle_anims/backgrounds/new/giga_impact_player.pal b/graphics/battle_anims/backgrounds/new/giga_impact_player.pal deleted file mode 100644 index ea01813a95..0000000000 --- a/graphics/battle_anims/backgrounds/new/giga_impact_player.pal +++ /dev/null @@ -1,19 +0,0 @@ -JASC-PAL -0100 -16 -0 0 0 -255 255 255 -255 0 255 -255 16 98 -246 131 180 -238 98 164 -230 65 131 -222 0 57 -222 24 90 -205 32 82 -205 41 74 -189 0 49 -172 16 65 -156 0 41 -148 16 49 -131 8 32 diff --git a/graphics/battle_anims/backgrounds/new/giga_impact_player.png b/graphics/battle_anims/backgrounds/new/giga_impact_player.png deleted file mode 100644 index b258035e343ddd983c12bf8098ed54eac3aa8430..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3098 zcmV+#4CV8QP)003|V0{{R3Yu{!u0000mP)t-s00030 z|Ns90|NjtT_Jg$UVx;ClgWdo+-WXcVAX3dKO1%IvtPnw*04bCZF@p#otxB+1lXwNDI`*o_@xHQY5I^Obtd>3E)y3 zU7KK2ja-Pqj!;jWS}zBzF_7G221JM4AwVnCh@Pa5Cq2!Bhb$RrQf0ui#04%SHj%B7 z3uEoj01r9jb23s)M<8lQ8$g}Y4iN4g30VV6$)V?X*M-cTdlDTNIISSiqS5d2+%3HOOR&nz7U8#RYr~rcg0M%KJI&VTGQDLPCg8W z6hsXqwHyW{yLMq@T8p`!%bIsw|4QH|Z6GM~%88jg zhYpua(o2JV%s{858E$O2qH74`&Ad^RnmfmGZvqfce zR}OG46RPIWoFUNG?|Y87>x+KB?+4p8E&Nqg0Hr7xn73R=55Oi6qweYISc@mE%{|}u ze+w5Mzz=y|)kR$)AkVGDft^05x`cc6y9NmK{T?WrgF=85;JkCtlg~(DWn5T@#Ul%B zG-hZDs`KH-#U_ZGd_iE3?8-Bs%(5&Cf~}cSv-1xTht4Dyeu}`Q z?U-9pUVh@*d<3zrz)T=20^-+)H-M+`S?Izrqv+U{zMVGF1O9t~z%7+S#(*p}gAWb- z-FlX*nF3+d1(EG(BpauR0sj2v@q~Wbw>E!((Lf#z20ruG@BmVYT)2k{m&Rbz&b@u9 ztJtZ#lcm&FK+Oa?2=?IfJBF&fT9DP5o{Z47Xp?RCFy|@m*bUyxRTKD>fe;vs%a)S4 zn2scE?3&!%da@&DGh_Ba@CS^GD9o`AA1SSHIpm-i9>!zow5E0ScXT8;%qTp8+aWFn z2yqFODE!wM0qw5xCz6dssmcGq^j6L|3Gma`CTB2vK(ZG2^VgI%2B+sAmZ9iVzNE@2 zDsA91-(P2iP%!WWD=dF%0v|}EaL^@Hkw3+#w1M9VFgxK?%AHllYZ?sC3Bw=+iC9PT z9Bn>o15b<}z=eAh?Yc0)x;2C^o!WAM6C&agHd7RK5E)YT`0q>3hnz;m3Q$7ywdrG0 zD$Cm$mV{jODeMe<$Z$Af%QIXkyvunHYV)?~Ij_Btj35zJVU)h#VBns11Z5M}%@)uJ zkZHAesYKsVe(NZ0Q9AnK%24NJUU--BaLSlwP4`V(IxKyTQUge#VTF|dCoYd)1Bpc4 zm1y8ocH9=Rd*VXf&5x7ioMQF9{+|A`y zqP4lFl4NT-1@s3=qND^VPMr1;V41m2FPvG3pNCiu)vJtvX3!QFb3 zw=_J^{P+oYVZff`n&YwMU;6&XF-=RZ8+k=JT;$NI&R2Qb2Ty+BbB`!{o>3Bc@wm&t z4k{c-VY?S_f1X!M>s!sM+oO7Y#4ZJ;-gw*vZ+_|bI$d-jS)64*nhY*d)12aXvD)pz z&>hu5m?Yk~)9J+BYyMhioWL`8T+ z+Sa^~T>r&kdcNDS*P(IMzX?LsU{g&K&M(M?419TR!|@Jv_)pri=`{B6)4$c}j>mCF z;2(q9XTj|_Ry^Yey0Cy^E^ZZc%6hg;lQ`~n(avifxIrN>zOvrwbi10@x#FW+zX&m% z=$;egZIExzLGR)Ww*jUJoyKDrbZ0kCo_cDk;?H{>XI#Of_~4cS(oPrqLIs@xwv7H0 z(<&zlu97<;U3^kF_8Y)83{w!}+(eU4`moX6c}9q+ zb+#o*EYRdzmapQX=vz8|Zi!o@P)pPa=PJBydB$doGkcZ>(I~vC0~m|IKY7=o9_qtP zUZA`%I5wEZ!V-_vv>D2-m^=tPOgD|6u|!9n!_&Kb8a?HvGo=Fqp^A8}14v>TVJ#R$ z_GP*hs)v@?X(d}1+lIg4jh^cO*!buCo-Yi;mOfYj^E~YvVjGxn6%9R=|C1T4>f6;4 z`sR=YR>JF6O8vh+;5XSr^;6ixm21|etj)bjK!I~8E~*TTi=tkFo{ z?}t>eQQ&Iw(T=BTD7@1s40D@@QJNAEYHYYi0-fsOn4FpW0T_N`U5ewS!^2nTlS#CD z{>PbWl^Fzz!Yng3d*9FrtM4#s3{r?OQDU+ob{!uoV>9>IFViN5h2gjl`64exq!u?! zr9HAcprLAs!ojq!{_?iAeSwsiZr4c{a#jO)87_MD!`rvU2}Yqv1mD?w!EiKy+Qj>h zU%h(kP~4%{^yze}9T=N@xkTZmh~_Z8kXG2W;pK(s*8+uztGakG{=a~_kx5LQ#y!bY o;`~1VYu%y7CauRNFl~kZ1&Sx+N{gjQzyJUM07*qoM6N<$g3DFoaR2}S diff --git a/graphics/battle_anims/backgrounds/new/spacial_rend_opponent.bin b/graphics/battle_anims/backgrounds/new/spacial_rend_opponent.bin deleted file mode 100644 index 0cfa1f1ec6..0000000000 --- a/graphics/battle_anims/backgrounds/new/spacial_rend_opponent.bin +++ /dev/null @@ -1,3 +0,0 @@ -@%I%H%G%F%E%D%$$$$$$$$$$$$$$$$ $$$$$$$$$$$$$$$$$$$$$$$ %%% % % % -%$$$$$$$$$$$$$$$$ %%%%%%%$$$$$$$$$$$$$$$$ "%/%.%-%,%+%*%$$$$$$$$$$$$$$$$ 2%?%>%=%<%;%:%$$$$$$$$$$$$$$$$ B%O%N%M%L%K%J%$$$$$$$$$$$$$$$$ B-O-N-M-L-K-J-,,,,,,,,,,,,,,,,(((((((((2-?->-=-<-;-:-,,,,,,,,,,,,,,,,((((((((("-/-.---,-+-*-,,,,,,,,,,,,,,,,(((((((((-------,,,,,,,,,,,,,,,,(((((((((--- - - - --,,,,,,,,,,,,,,,,(((((((((,,,,,,,,,,,,,,,,,,,,,,,(((((((((@-I-H-G-F-E-D-,,,,,,,,,,,,,,,,((((((((( \ No newline at end of file diff --git a/graphics/battle_anims/backgrounds/new/spacial_rend_player.bin b/graphics/battle_anims/backgrounds/new/spacial_rend_player.bin deleted file mode 100644 index 3b89218e0e6cbba254e78a9f11abe717002cba8a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 896 zcmWN@WnfSR0EJP(KuNpfyW8FN9z0+@n)P5wV@qR8V@qRzG}zME(%912(%7y?V|Sik zC&BTKvmNUg%NRrqvHvHIcoGN*X-*3wTGEQvG^7!YX+l$)QIGm$INfPZb&8Xnp7n7S)S>c%wjfkn9Drovw+8VoF{mar+AuYc$Po-lfU?zfB2Ul_>mP}?qy!; zC0^`BUg(7^Vlhit$}*O-g6DXi7kH7Ec$rstm4<4h#%iLbYNq-+SsT3G>%7)$yxOb0 z(kofTYSyrpb*yItukku>@Fs8ZHt+B*7wZyTs>^h_uF%;!M?1XT+q~6VyxE()(Hq&s zX11`EZER-;@9{n#@F5@ZF`w`$&DBDYTB?;=D@L(8;Qij`z24*9-sPR%$u4%YhrR4$ zKL_}X&-sEc`HHXkhHq)7_UfRH>ZHy}R*LFe>l# Date: Wed, 3 Nov 2021 00:37:22 +0700 Subject: [PATCH 14/69] Adjust Giga Impact background to fade in before impact --- data/battle_anim_scripts.s | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 6b417944ef..aa914bf892 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -2497,11 +2497,6 @@ Move_GIGA_IMPACT: loadspritegfx ANIM_TAG_IMPACT monbg ANIM_DEF_PARTNER setalpha 12, 8 - playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER - createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 6, 1, ANIM_ATTACKER - waitforvisualfinish - delay 11 - createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 26, 0, 0, 5 createvisualtask AnimTask_IsContest, 2 jumprettrue SetGigaImpactContestsBG createvisualtask AnimTask_IsTargetPlayerSide, 2 @@ -2517,6 +2512,12 @@ SetGigaImpactContestsBG: fadetobg BG_GIGA_IMPACT_CONTEST goto GigaImpactContinuity GigaImpactContinuity: + playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER + createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 6, 1, ANIM_ATTACKER + waitforvisualfinish + delay 11 + createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 26, 0, 0, 5 + delay 6 waitbgfadeout createsprite gBasicHitSplatSpriteTemplate, 4, 4, -10, 0, 1, 0 playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET From 8f320a8d33a3a7222471a5c1bf10108f325430a9 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 8 Nov 2021 11:37:41 -0500 Subject: [PATCH 15/69] some ai updates, recycle + ripen logic --- include/battle_ai_util.h | 2 ++ src/battle_ai_main.c | 13 +++++++++- src/battle_ai_util.c | 56 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h index 1b2591899b..6da519342f 100644 --- a/include/battle_ai_util.h +++ b/include/battle_ai_util.h @@ -52,6 +52,8 @@ bool32 ShouldRecover(u8 battlerAtk, u8 battlerDef, u16 move, u8 healPercent); bool32 ShouldSetScreen(u8 battlerAtk, u8 battlerDef, u16 moveEffect); bool32 ShouldPivot(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u8 moveIndex); bool32 IsRecycleEncouragedItem(u16 item); +bool32 IsHpRestoringBerry(u16 item); +bool32 IsStatBoostingBerry(u16 item); bool32 CanKnockOffItem(u8 battler, u16 item); bool32 IsAbilityOfRating(u16 ability, s8 rating); s8 GetAbilityRating(u16 ability); diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 7fbb432603..b8dbdebac8 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -2969,6 +2969,10 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) { case ABILITY_MOXIE: case ABILITY_BEAST_BOOST: + case ABILITY_CHILLING_NEIGH: + case ABILITY_GRIM_NEIGH: + case ABILITY_AS_ONE_ICE_RIDER: + case ABILITY_AS_ONE_SHADOW_RIDER: if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // attacker should go first { if (CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) @@ -2980,7 +2984,6 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) // move effect checks switch (moveEffect) { - case EFFECT_HIT: break; case EFFECT_SLEEP: @@ -4101,6 +4104,14 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) score++; if (IsRecycleEncouragedItem(GetUsedHeldItem(battlerAtk))) score++; + if (AI_DATA->atkAbility == ABILITY_RIPEN) + { + u16 item = GetUsedHeldItem(battlerAtk); + if (IsStatBoostingBerry(item) && atkHpPercent > 60) + score++; + else if (IsHpRestoringBerry(item) && atkHpPercent < 60) + score++; // TODO check if player can still faint us after we heal + } break; case EFFECT_BRICK_BREAK: if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_REFLECT) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 71dc78d0aa..3ccf065a50 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -3368,6 +3368,44 @@ static const u16 sRecycleEncouragedItems[] = // TODO expand this }; +// Its assumed that the berry is strategically given, so no need to check benefits of the berry +bool32 IsStatBoostingBerry(u16 item) +{ + switch (item) + { + case ITEM_LIECHI_BERRY: + case ITEM_GANLON_BERRY: + case ITEM_SALAC_BERRY: + case ITEM_PETAYA_BERRY: + case ITEM_APICOT_BERRY: + //case ITEM_LANSAT_BERRY: + case ITEM_STARF_BERRY: + #ifdef ITEM_EXPANSION + case ITEM_MICLE_BERRY: + #endif + return TRUE; + default: + return FALSE; + } +} + +bool32 IsHpRestoringBerry(u16 item) +{ + switch (item) + { + case ITEM_ORAN_BERRY: + case ITEM_SITRUS_BERRY: + case ITEM_FIGY_BERRY: + case ITEM_WIKI_BERRY: + case ITEM_MAGO_BERRY: + case ITEM_AGUAV_BERRY: + case ITEM_IAPAPA_BERRY: + return TRUE; + default: + return FALSE; + } +} + bool32 IsRecycleEncouragedItem(u16 item) { u32 i; @@ -3389,6 +3427,9 @@ void IncreaseStatUpScore(u8 battlerAtk, u8 battlerDef, u8 statId, s16 *score) if (GetHealthPercentage(battlerAtk) < 80 && AI_RandLessThan(128)) return; + + if (CanAIFaintTarget(battlerAtk, battlerDef, 0)) + return; // Damaging moves would get a score boost from AI_TryToFaint or PreferStrongestMove so we don't consider them here switch (statId) { @@ -3461,6 +3502,9 @@ void IncreaseStatUpScore(u8 battlerAtk, u8 battlerDef, u8 statId, s16 *score) void IncreasePoisonScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) { + if (CanAIFaintTarget(battlerAtk, battlerDef, 0)) + return; + if (AI_CanPoison(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove) && GetHealthPercentage(battlerDef) > 20) { if (!HasDamagingMove(battlerDef)) @@ -3481,6 +3525,9 @@ void IncreasePoisonScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) void IncreaseBurnScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) { + if (CanAIFaintTarget(battlerAtk, battlerDef, 0)) + return; + if (AI_CanBurn(battlerAtk, battlerDef, AI_DATA->defAbility, AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) { (*score)++; // burning is good @@ -3497,6 +3544,9 @@ void IncreaseBurnScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) void IncreaseParalyzeScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) { + if (CanAIFaintTarget(battlerAtk, battlerDef, 0)) + return; + if (AI_CanParalyze(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove)) { u8 atkSpeed = GetBattlerTotalSpeedStat(battlerAtk); @@ -3515,6 +3565,9 @@ void IncreaseParalyzeScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) void IncreaseSleepScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) { + if (CanAIFaintTarget(battlerAtk, battlerDef, 0)) + return; + if (AI_CanPutToSleep(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove)) *score += 2; else @@ -3530,6 +3583,9 @@ void IncreaseSleepScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) void IncreaseConfusionScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) { + if (CanAIFaintTarget(battlerAtk, battlerDef, 0)) + return; + if (AI_CanConfuse(battlerAtk, battlerDef, AI_DATA->defAbility, AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove) && AI_DATA->defHoldEffect != HOLD_EFFECT_CURE_CONFUSION && AI_DATA->defHoldEffect != HOLD_EFFECT_CURE_STATUS) From e5a0630596a83fe823d5bae01f12aa8dc79d7cfd Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 8 Nov 2021 11:42:32 -0500 Subject: [PATCH 16/69] add ai flag checks alongside CanFaintTarget --- src/battle_ai_util.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 3ccf065a50..60083bb29c 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -1703,7 +1703,7 @@ u32 CountNegativeStatStages(u8 battlerId) bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility) { - if (IsAiFaster(AI_CHECK_FASTER) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if (IsAiFaster(AI_CHECK_FASTER) && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (gBattleMons[battlerDef].statStages[STAT_ATK] > 4 @@ -1719,7 +1719,7 @@ bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility) bool32 ShouldLowerDefense(u8 battlerAtk, u8 battlerDef, u16 defAbility) { - if (IsAiFaster(AI_CHECK_FASTER) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if (IsAiFaster(AI_CHECK_FASTER) && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (gBattleMons[battlerDef].statStages[STAT_DEF] > 4 @@ -1735,7 +1735,7 @@ bool32 ShouldLowerDefense(u8 battlerAtk, u8 battlerDef, u16 defAbility) bool32 ShouldLowerSpeed(u8 battlerAtk, u8 battlerDef, u16 defAbility) { - if (IsAiFaster(AI_CHECK_FASTER) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if (IsAiFaster(AI_CHECK_FASTER) && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (IsAiFaster(AI_CHECK_SLOWER) @@ -1749,7 +1749,7 @@ bool32 ShouldLowerSpeed(u8 battlerAtk, u8 battlerDef, u16 defAbility) bool32 ShouldLowerSpAtk(u8 battlerAtk, u8 battlerDef, u16 defAbility) { - if (IsAiFaster(AI_CHECK_FASTER) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if (IsAiFaster(AI_CHECK_FASTER) && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (gBattleMons[battlerDef].statStages[STAT_SPATK] > 4 @@ -1764,7 +1764,7 @@ bool32 ShouldLowerSpAtk(u8 battlerAtk, u8 battlerDef, u16 defAbility) bool32 ShouldLowerSpDef(u8 battlerAtk, u8 battlerDef, u16 defAbility) { - if (IsAiFaster(AI_CHECK_FASTER) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if (IsAiFaster(AI_CHECK_FASTER) && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (gBattleMons[battlerDef].statStages[STAT_SPDEF] > 4 @@ -1779,7 +1779,7 @@ bool32 ShouldLowerSpDef(u8 battlerAtk, u8 battlerDef, u16 defAbility) bool32 ShouldLowerAccuracy(u8 battlerAtk, u8 battlerDef, u16 defAbility) { - if (IsAiFaster(AI_CHECK_FASTER) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if (IsAiFaster(AI_CHECK_FASTER) && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (defAbility != ABILITY_CONTRARY @@ -1793,7 +1793,7 @@ bool32 ShouldLowerAccuracy(u8 battlerAtk, u8 battlerDef, u16 defAbility) bool32 ShouldLowerEvasion(u8 battlerAtk, u8 battlerDef, u16 defAbility) { - if (IsAiFaster(AI_CHECK_FASTER) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if (IsAiFaster(AI_CHECK_FASTER) && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (gBattleMons[battlerDef].statStages[STAT_EVASION] > DEFAULT_STAT_STAGE @@ -3428,7 +3428,7 @@ void IncreaseStatUpScore(u8 battlerAtk, u8 battlerDef, u8 statId, s16 *score) if (GetHealthPercentage(battlerAtk) < 80 && AI_RandLessThan(128)) return; - if (CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return; // Damaging moves would get a score boost from AI_TryToFaint or PreferStrongestMove so we don't consider them here switch (statId) @@ -3502,7 +3502,7 @@ void IncreaseStatUpScore(u8 battlerAtk, u8 battlerDef, u8 statId, s16 *score) void IncreasePoisonScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) { - if (CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return; if (AI_CanPoison(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove) && GetHealthPercentage(battlerDef) > 20) @@ -3525,7 +3525,7 @@ void IncreasePoisonScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) void IncreaseBurnScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) { - if (CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return; if (AI_CanBurn(battlerAtk, battlerDef, AI_DATA->defAbility, AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) @@ -3544,7 +3544,7 @@ void IncreaseBurnScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) void IncreaseParalyzeScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) { - if (CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return; if (AI_CanParalyze(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove)) @@ -3565,7 +3565,7 @@ void IncreaseParalyzeScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) void IncreaseSleepScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) { - if (CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return; if (AI_CanPutToSleep(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove)) @@ -3583,7 +3583,7 @@ void IncreaseSleepScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) void IncreaseConfusionScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) { - if (CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return; if (AI_CanConfuse(battlerAtk, battlerDef, AI_DATA->defAbility, AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove) From 01cf8e6452d592b5d8010a25fab32dcf0eab9ab7 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 8 Nov 2021 11:55:06 -0500 Subject: [PATCH 17/69] add AI_MoveMakesContact, dissuade multi-hit attacks against rocky helmet --- include/battle_ai_util.h | 1 + src/battle_ai_main.c | 3 +++ src/battle_ai_util.c | 9 +++++++++ 3 files changed, 13 insertions(+) diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h index 6da519342f..cc626fa5e4 100644 --- a/include/battle_ai_util.h +++ b/include/battle_ai_util.h @@ -58,6 +58,7 @@ bool32 CanKnockOffItem(u8 battler, u16 item); bool32 IsAbilityOfRating(u16 ability, s8 rating); s8 GetAbilityRating(u16 ability); bool32 AI_IsAbilityOnSide(u32 battlerId, u32 ability); +bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u16 move); // stat stage checks bool32 AnyStatIsRaised(u8 battlerId); diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index b8dbdebac8..cc0f8b2c7b 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -3246,6 +3246,9 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) case EFFECT_MULTI_HIT: case EFFECT_DOUBLE_HIT: case EFFECT_TRIPLE_KICK: + if (AI_MoveMakesContact(AI_DATA->atkAbility, AI_DATA->atkHoldEffect, move) + && AI_DATA->defHoldEffect == HOLD_EFFECT_ROCKY_HELMET) + score -= 2; break; case EFFECT_CONVERSION: if (!IS_BATTLER_OF_TYPE(battlerAtk, gBattleMoves[gBattleMons[battlerAtk].moves[0]].type)) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 60083bb29c..19dfab8577 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -3598,3 +3598,12 @@ void IncreaseConfusionScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) *score += 2; } } + +bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u16 move) +{ + if (TestMoveFlags(move, FLAG_MAKES_CONTACT) + && ability != ABILITY_LONG_REACH + && holdEffect != HOLD_EFFECT_PROTECTIVE_PADS) + return TRUE; + return FALSE; +} From 4566b5234fde6772184f191471455d3296ddf547 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 8 Nov 2021 11:56:51 -0500 Subject: [PATCH 18/69] magic guard user doesnt care about rocky helmet --- src/battle_ai_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index cc0f8b2c7b..317f79d977 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -3247,6 +3247,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) case EFFECT_DOUBLE_HIT: case EFFECT_TRIPLE_KICK: if (AI_MoveMakesContact(AI_DATA->atkAbility, AI_DATA->atkHoldEffect, move) + && AI_DATA->atkAbility != ABILITY_MAGIC_GUARD && AI_DATA->defHoldEffect == HOLD_EFFECT_ROCKY_HELMET) score -= 2; break; From 6f6e0d6baf6abe2b58b2ebe37d64ac5579b89873 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 8 Nov 2021 21:27:40 -0500 Subject: [PATCH 19/69] add recycle hp berry logic --- src/battle_ai_main.c | 8 ++++++-- src/battle_ai_util.c | 5 ++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 317f79d977..1dcb86805d 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -4111,10 +4111,14 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) if (AI_DATA->atkAbility == ABILITY_RIPEN) { u16 item = GetUsedHeldItem(battlerAtk); + u16 toHeal = (ItemId_GetHoldEffectParam(item) == 10) ? 10 : gBattleMons[battlerAtk].maxHP / ItemId_GetHoldEffectParam(item); + if (IsStatBoostingBerry(item) && atkHpPercent > 60) score++; - else if (IsHpRestoringBerry(item) && atkHpPercent < 60) - score++; // TODO check if player can still faint us after we heal + else if (IsHpRestoringBerry(item) && !CanAIFaintTarget(battlerAtk, battlerDef, 0) + && ((GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0 && CanTargetFaintAiWithMod(battlerDef, battlerAtk, 0, 0)) + || !CanTargetFaintAiWithMod(battlerDef, battlerAtk, toheal, 0))) + score++; // Recycle healing berry if we can't otherwise faint the target and the target wont kill us after we activate the berry } break; case EFFECT_BRICK_BREAK: diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 19dfab8577..dc85901e32 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -3389,11 +3389,14 @@ bool32 IsStatBoostingBerry(u16 item) } } -bool32 IsHpRestoringBerry(u16 item) +bool32 IsHpRestoringBerry(u8 battlerAtk, u16 item) { switch (item) { case ITEM_ORAN_BERRY: + if (gBattleMons[battlerAtk].maxHp <= 50) + return TRUE; // Only worth it in the early game + return FALSE; case ITEM_SITRUS_BERRY: case ITEM_FIGY_BERRY: case ITEM_WIKI_BERRY: From e635930a150918581e2d6266335327592058450b Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 8 Nov 2021 21:33:00 -0500 Subject: [PATCH 20/69] fixes --- include/battle_ai_util.h | 2 +- src/battle_ai_main.c | 4 ++-- src/battle_ai_util.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h index cc626fa5e4..4fe36c48d5 100644 --- a/include/battle_ai_util.h +++ b/include/battle_ai_util.h @@ -52,7 +52,7 @@ bool32 ShouldRecover(u8 battlerAtk, u8 battlerDef, u16 move, u8 healPercent); bool32 ShouldSetScreen(u8 battlerAtk, u8 battlerDef, u16 moveEffect); bool32 ShouldPivot(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u8 moveIndex); bool32 IsRecycleEncouragedItem(u16 item); -bool32 IsHpRestoringBerry(u16 item); +bool32 ShouldRestoreHpBerry(u8 battlerAtk, u16 item); bool32 IsStatBoostingBerry(u16 item); bool32 CanKnockOffItem(u8 battler, u16 item); bool32 IsAbilityOfRating(u16 ability, s8 rating); diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 1dcb86805d..fcd11d1c3c 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -4115,9 +4115,9 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) if (IsStatBoostingBerry(item) && atkHpPercent > 60) score++; - else if (IsHpRestoringBerry(item) && !CanAIFaintTarget(battlerAtk, battlerDef, 0) + else if (ShouldRestoreHpBerry(battlerAtk, item) && !CanAIFaintTarget(battlerAtk, battlerDef, 0) && ((GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0 && CanTargetFaintAiWithMod(battlerDef, battlerAtk, 0, 0)) - || !CanTargetFaintAiWithMod(battlerDef, battlerAtk, toheal, 0))) + || !CanTargetFaintAiWithMod(battlerDef, battlerAtk, toHeal, 0))) score++; // Recycle healing berry if we can't otherwise faint the target and the target wont kill us after we activate the berry } break; diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index dc85901e32..c90c9cdab4 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -3389,12 +3389,12 @@ bool32 IsStatBoostingBerry(u16 item) } } -bool32 IsHpRestoringBerry(u8 battlerAtk, u16 item) +bool32 ShouldRestoreHpBerry(u8 battlerAtk, u16 item) { switch (item) { case ITEM_ORAN_BERRY: - if (gBattleMons[battlerAtk].maxHp <= 50) + if (gBattleMons[battlerAtk].maxHP <= 50) return TRUE; // Only worth it in the early game return FALSE; case ITEM_SITRUS_BERRY: From e47317aa73bab1905f19a567c91348c05be8a9b4 Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Wed, 10 Nov 2021 21:24:48 +1300 Subject: [PATCH 21/69] Fix Big Pecks ChangeStatBuffs was missing a check for Big Pecks. --- src/battle_script_commands.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 93e1b31e26..3874febf36 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -9833,8 +9833,9 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr return STAT_CHANGE_DIDNT_WORK; } else if (!certain - && ((GetBattlerAbility(gActiveBattler) == ABILITY_KEEN_EYE && statId == STAT_ACC) - || (GetBattlerAbility(gActiveBattler) == ABILITY_HYPER_CUTTER && statId == STAT_ATK))) + && ((GetBattlerAbility(gActiveBattler) == ABILITY_KEEN_EYE && statId == STAT_ACC) + || (GetBattlerAbility(gActiveBattler) == ABILITY_HYPER_CUTTER && statId == STAT_ATK) + || (GetBattlerAbility(gActiveBattler) == ABILITY_BIG_PECKS && statId == STAT_DEF))) { if (flags == STAT_BUFF_ALLOW_PTR) { From 59abb0ff4e818a31696364cf1f94bb69d8ea549a Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Wed, 10 Nov 2021 20:45:39 +0100 Subject: [PATCH 22/69] Serene Grace affects King's rock according to https://bulbapedia.bulbagarden.net/wiki/King%27s_Rock --- src/battle_util.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/battle_util.c b/src/battle_util.c index 4f09e3bb7a..385b09a1cf 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -6847,6 +6847,8 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) switch (atkHoldEffect) { case HOLD_EFFECT_FLINCH: + if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SERENE_GRACE) + atkHoldEffectParam *= 2; if (gBattleMoveDamage != 0 // Need to have done damage && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && TARGET_TURN_DAMAGED From adc1413d984b49b1c80e5574a9d650c07f38c35e Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Thu, 11 Nov 2021 17:48:15 -0500 Subject: [PATCH 23/69] add kings rock serene grace boost config --- include/constants/battle_config.h | 1 + src/battle_util.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index aaf02a37f1..ba9c1b984c 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -181,6 +181,7 @@ #define B_LURE_BALL_MODIFIER GEN_7 // In Gen7+, Lure Ball's catch multiplier is x5 instead of x3. #define B_HEAVY_BALL_MODIFIER GEN_7 // In Gen7+, Heavy Ball's ranges change. See Cmd_handleballthrow. #define B_DREAM_BALL_MODIFIER GEN_8 // In Gen8, Dream Ball's catch multiplier is x4 when the target is asleep or has the ability Comatose. +#define B_KINGS_ROCK_BOOST GEN_7 // In Gen5+, King's Rock is boosted by Serene Grace // Flag settings // To use the following features in scripting, replace the 0s with the flag ID you're assigning it to. diff --git a/src/battle_util.c b/src/battle_util.c index 4b3fc11aa9..8b23cdec37 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -6860,8 +6860,10 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) switch (atkHoldEffect) { case HOLD_EFFECT_FLINCH: - if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SERENE_GRACE) - atkHoldEffectParam *= 2; + #if B_KINGS_ROCK_BOOST >= GEN_5 + if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SERENE_GRACE) + atkHoldEffectParam *= 2; + #endif if (gBattleMoveDamage != 0 // Need to have done damage && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && TARGET_TURN_DAMAGED From bdbdd0564fe9e3aaf3d15139e6260d371c939923 Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Fri, 12 Nov 2021 21:05:42 +1300 Subject: [PATCH 24/69] Fix Knock Off, add config Added a config for Knock Off's damage boost. Also fixed the conditions it checks to do bonus damage. --- include/constants/battle_config.h | 1 + src/battle_util.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index aaf02a37f1..62bd7e447f 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -114,6 +114,7 @@ #define B_PAYBACK_SWITCH_BOOST GEN_7 // In Gen5+, if the opponent switches out, Payback's damage will no longer be doubled. #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_ROUGH_SKIN_DMG GEN_7 // In Gen4+, Rough Skin contact damage is 1/8th of max HP instead of 1/16th. This will also affect Iron Barbs. +#define B_KNOCK_OFF_DMG GEN_8 // In Gen6+, Knock Off deals 50% more damage when knocking off an item // Type settings #define B_GHOSTS_ESCAPE GEN_7 // In Gen6+, abilities like Shadow Tag or moves like Mean Look fail on Ghost-type Pokémon. They can also escape any Wild Battle. diff --git a/src/battle_util.c b/src/battle_util.c index 4b3fc11aa9..7f01891bdd 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8191,8 +8191,11 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe MulModifier(&modifier, UQ_4_12(0.5)); break; case EFFECT_KNOCK_OFF: - if (gBattleMons[battlerDef].item != ITEM_NONE && GetBattlerAbility(battlerDef) != ABILITY_STICKY_HOLD) + #if B_KNOCK_OFF_DMG >= GEN_6 + if (gBattleMons[battlerDef].item != ITEM_NONE + && CanBattlerGetOrLoseItem(battlerDef, gBattleMons[battlerDef].item)) MulModifier(&modifier, UQ_4_12(1.5)); + #endif break; } From 6214d8b62511df9c5a0c519589d2b7a84f1ae66b Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 12 Nov 2021 07:47:24 -0500 Subject: [PATCH 25/69] rename config --- include/constants/battle_config.h | 2 +- src/battle_util.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index ba9c1b984c..d28e9da5c2 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -181,7 +181,7 @@ #define B_LURE_BALL_MODIFIER GEN_7 // In Gen7+, Lure Ball's catch multiplier is x5 instead of x3. #define B_HEAVY_BALL_MODIFIER GEN_7 // In Gen7+, Heavy Ball's ranges change. See Cmd_handleballthrow. #define B_DREAM_BALL_MODIFIER GEN_8 // In Gen8, Dream Ball's catch multiplier is x4 when the target is asleep or has the ability Comatose. -#define B_KINGS_ROCK_BOOST GEN_7 // In Gen5+, King's Rock is boosted by Serene Grace +#define B_SERENE_GRACE_BOOST GEN_7 // In Gen5+, Serene Grace boosts King's Rock and Razor fang // Flag settings // To use the following features in scripting, replace the 0s with the flag ID you're assigning it to. diff --git a/src/battle_util.c b/src/battle_util.c index 8b23cdec37..18847b8cce 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -6860,7 +6860,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) switch (atkHoldEffect) { case HOLD_EFFECT_FLINCH: - #if B_KINGS_ROCK_BOOST >= GEN_5 + #if B_SERENE_GRACE_BOOST >= GEN_5 if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SERENE_GRACE) atkHoldEffectParam *= 2; #endif From 276b454b4088d7ffd4f57e22fdc5982056375f11 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 12 Nov 2021 08:13:17 -0500 Subject: [PATCH 26/69] primal weather checks --- src/battle_ai_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index fcd11d1c3c..3e51b0dc4a 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -1392,22 +1392,22 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) } break; case EFFECT_SANDSTORM: - if (gBattleWeather & WEATHER_SANDSTORM_ANY //TODO | WEATHER_PRIMAL_ANY) + if (gBattleWeather & (WEATHER_SANDSTORM_ANY | WEATHER_PRIMAL_ANY) || PartnerMoveEffectIsWeather(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove)) score -= 8; break; case EFFECT_SUNNY_DAY: - if (gBattleWeather & WEATHER_SUN_ANY //TODO | WEATHER_PRIMAL_ANY) + if (gBattleWeather & (WEATHER_SUN_ANY | WEATHER_PRIMAL_ANY) || PartnerMoveEffectIsWeather(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove)) score -= 8; break; case EFFECT_RAIN_DANCE: - if (gBattleWeather & WEATHER_RAIN_ANY //TODO | WEATHER_PRIMAL_ANY) + if (gBattleWeather & (WEATHER_RAIN_ANY | WEATHER_PRIMAL_ANY) || PartnerMoveEffectIsWeather(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove)) score -= 8; break; case EFFECT_HAIL: - if (gBattleWeather & WEATHER_HAIL_ANY //TODO | WEATHER_PRIMAL_ANY) + if (gBattleWeather & (WEATHER_HAIL_ANY | WEATHER_PRIMAL_ANY) || PartnerMoveEffectIsWeather(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove)) score -= 8; break; From c5dabf34b89f2934316a2a66122acf131210bdca Mon Sep 17 00:00:00 2001 From: ultima-soul <33333039+ultima-soul@users.noreply.github.com> Date: Fri, 12 Nov 2021 09:39:18 -0800 Subject: [PATCH 27/69] Improve Serene Grace boost config comment. --- 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 d28e9da5c2..eb7600cc2a 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -181,7 +181,7 @@ #define B_LURE_BALL_MODIFIER GEN_7 // In Gen7+, Lure Ball's catch multiplier is x5 instead of x3. #define B_HEAVY_BALL_MODIFIER GEN_7 // In Gen7+, Heavy Ball's ranges change. See Cmd_handleballthrow. #define B_DREAM_BALL_MODIFIER GEN_8 // In Gen8, Dream Ball's catch multiplier is x4 when the target is asleep or has the ability Comatose. -#define B_SERENE_GRACE_BOOST GEN_7 // In Gen5+, Serene Grace boosts King's Rock and Razor fang +#define B_SERENE_GRACE_BOOST GEN_7 // In Gen5+, Serene Grace boosts the added flinch chance of King's Rock and Razor Fang. // Flag settings // To use the following features in scripting, replace the 0s with the flag ID you're assigning it to. From a26da51e9d55baf3fa5ca9de37136ed8d8712270 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 12 Nov 2021 12:44:45 -0500 Subject: [PATCH 28/69] fix contrary animations for MOVE_EFFECT_statchange --- include/constants/battle_script_commands.h | 1 + src/battle_script_commands.c | 131 ++++++++++++++++++++- 2 files changed, 127 insertions(+), 5 deletions(-) diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 34fa1d3707..7ceb1d64bf 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -225,6 +225,7 @@ // Cmd_statbuffchange #define STAT_BUFF_ALLOW_PTR (1 << 0) // If set, allow use of jumpptr. Set in every use of statbuffchange #define STAT_BUFF_NOT_PROTECT_AFFECTED (1 << 5) +#define STAT_BUFF_UPDATE_MOVE_EFFECT (1 << 6) // stat change flags for Cmd_playstatchangeanimation #define STAT_CHANGE_NEGATIVE (1 << 0) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 24a758153f..37c46055da 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3071,7 +3071,7 @@ void SetMoveEffect(bool32 primary, u32 certain) if (NoAliveMonsForEitherParty() || ChangeStatBuffs(SET_STAT_BUFF_VALUE(1), gBattleScripting.moveEffect - MOVE_EFFECT_ATK_PLUS_1 + 1, - affectsUser, 0)) + affectsUser | STAT_BUFF_UPDATE_MOVE_EFFECT, 0)) { gBattlescriptCurrInstr++; } @@ -3096,7 +3096,7 @@ void SetMoveEffect(bool32 primary, u32 certain) if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(1) | STAT_BUFF_NEGATIVE, gBattleScripting.moveEffect - MOVE_EFFECT_ATK_MINUS_1 + 1, - flags, gBattlescriptCurrInstr + 1)) + flags | STAT_BUFF_UPDATE_MOVE_EFFECT, gBattlescriptCurrInstr + 1)) { if (!mirrorArmorReflected) gBattlescriptCurrInstr++; @@ -3119,7 +3119,7 @@ void SetMoveEffect(bool32 primary, u32 certain) if (NoAliveMonsForEitherParty() || ChangeStatBuffs(SET_STAT_BUFF_VALUE(2), gBattleScripting.moveEffect - MOVE_EFFECT_ATK_PLUS_2 + 1, - affectsUser, 0)) + affectsUser | STAT_BUFF_UPDATE_MOVE_EFFECT, 0)) { gBattlescriptCurrInstr++; } @@ -3143,7 +3143,7 @@ void SetMoveEffect(bool32 primary, u32 certain) flags |= STAT_BUFF_ALLOW_PTR; if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(2) | STAT_BUFF_NEGATIVE, gBattleScripting.moveEffect - MOVE_EFFECT_ATK_MINUS_2 + 1, - flags, gBattlescriptCurrInstr + 1)) + flags | STAT_BUFF_UPDATE_MOVE_EFFECT, gBattlescriptCurrInstr + 1)) { if (!mirrorArmorReflected) gBattlescriptCurrInstr++; @@ -4657,9 +4657,55 @@ static void Cmd_endselectionscript(void) *(gBattlerAttacker + gBattleStruct->selectionScriptFinished) = TRUE; } +static u32 ReverseStatAnimId(u16 *argumentPtr) +{ + u8 value = 0; + switch (GET_STAT_BUFF_VALUE_WITH_SIGN(gBattleScripting.statChanger)) + { + case SET_STAT_BUFF_VALUE(1): // +1 + value = STAT_ANIM_MINUS1; + break; + case SET_STAT_BUFF_VALUE(2): // +2 + value = STAT_ANIM_MINUS2; + break; + case SET_STAT_BUFF_VALUE(3): // +3 + value = STAT_ANIM_MINUS2; + break; + case SET_STAT_BUFF_VALUE(4): // +4 + value = STAT_ANIM_MINUS2; + break; + case SET_STAT_BUFF_VALUE(5): // +5 + value = STAT_ANIM_MINUS2; + break; + case SET_STAT_BUFF_VALUE(6): // +6 + value = STAT_ANIM_MINUS2; + break; + case SET_STAT_BUFF_VALUE(1) | STAT_BUFF_NEGATIVE: // -1 + value = STAT_ANIM_PLUS1; + break; + case SET_STAT_BUFF_VALUE(2) | STAT_BUFF_NEGATIVE: // -2 + value = STAT_ANIM_PLUS2; + break; + case SET_STAT_BUFF_VALUE(3) | STAT_BUFF_NEGATIVE: // -3 + value = STAT_ANIM_PLUS2; + break; + case SET_STAT_BUFF_VALUE(4) | STAT_BUFF_NEGATIVE: // -1 + value = STAT_ANIM_PLUS2; + break; + case SET_STAT_BUFF_VALUE(5) | STAT_BUFF_NEGATIVE: // -2 + value = STAT_ANIM_PLUS2; + break; + case SET_STAT_BUFF_VALUE(6) | STAT_BUFF_NEGATIVE: // -3 + value = STAT_ANIM_PLUS2; + break; + } + + *argumentPtr = GET_STAT_BUFF_ID(gBattleScripting.statChanger) + value - 1; +} + static void Cmd_playanimation(void) { - const u16* argumentPtr; + u16* argumentPtr; u8 animId = gBattlescriptCurrInstr[2]; gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); @@ -4673,6 +4719,9 @@ static void Cmd_playanimation(void) return; } #endif + + //if (animId == B_ANIM_STATS_CHANGE && GetBattlerAbility(gActiveBattler) == ABILITY_CONTRARY) + //ReverseStatAnimId(argumentPtr); if (animId == B_ANIM_STATS_CHANGE || animId == B_ANIM_SNATCH_MOVE @@ -9815,6 +9864,72 @@ static void Cmd_setdrainedhp(void) gBattlescriptCurrInstr++; } +static u16 ReverseStatChangeMoveEffect(u16 moveEffect) +{ + switch (moveEffect) + { + // +1 + case MOVE_EFFECT_ATK_PLUS_1: + return MOVE_EFFECT_ATK_MINUS_1; + case MOVE_EFFECT_DEF_PLUS_1: + return MOVE_EFFECT_DEF_MINUS_1; + case MOVE_EFFECT_SPD_PLUS_1: + return MOVE_EFFECT_SPD_MINUS_1; + case MOVE_EFFECT_SP_ATK_PLUS_1: + return MOVE_EFFECT_SP_ATK_MINUS_1; + case MOVE_EFFECT_SP_DEF_PLUS_1: + return MOVE_EFFECT_SP_DEF_MINUS_1; + case MOVE_EFFECT_ACC_PLUS_1: + return MOVE_EFFECT_ACC_MINUS_1; + case MOVE_EFFECT_EVS_PLUS_1: + return MOVE_EFFECT_EVS_MINUS_1; + // -1 + case MOVE_EFFECT_ATK_MINUS_1: + return MOVE_EFFECT_ATK_PLUS_1; + case MOVE_EFFECT_DEF_MINUS_1: + return MOVE_EFFECT_DEF_PLUS_1; + case MOVE_EFFECT_SPD_MINUS_1: + return MOVE_EFFECT_SPD_PLUS_1; + case MOVE_EFFECT_SP_ATK_MINUS_1: + return MOVE_EFFECT_SP_ATK_PLUS_1; + case MOVE_EFFECT_SP_DEF_MINUS_1: + return MOVE_EFFECT_SP_DEF_PLUS_1; + case MOVE_EFFECT_ACC_MINUS_1: + return MOVE_EFFECT_ACC_PLUS_1; + case MOVE_EFFECT_EVS_MINUS_1: + // +2 + case MOVE_EFFECT_ATK_PLUS_2: + return MOVE_EFFECT_ATK_MINUS_2; + case MOVE_EFFECT_DEF_PLUS_2: + return MOVE_EFFECT_DEF_MINUS_2; + case MOVE_EFFECT_SPD_PLUS_2: + return MOVE_EFFECT_SPD_MINUS_2; + case MOVE_EFFECT_SP_ATK_PLUS_2: + return MOVE_EFFECT_SP_ATK_MINUS_2; + case MOVE_EFFECT_SP_DEF_PLUS_2: + return MOVE_EFFECT_SP_DEF_MINUS_2; + case MOVE_EFFECT_ACC_PLUS_2: + return MOVE_EFFECT_ACC_MINUS_2; + case MOVE_EFFECT_EVS_PLUS_2: + return MOVE_EFFECT_EVS_MINUS_2; + // -2 + case MOVE_EFFECT_ATK_MINUS_2: + return MOVE_EFFECT_ATK_PLUS_2; + case MOVE_EFFECT_DEF_MINUS_2: + return MOVE_EFFECT_DEF_PLUS_2; + case MOVE_EFFECT_SPD_MINUS_2: + return MOVE_EFFECT_SPD_PLUS_2; + case MOVE_EFFECT_SP_ATK_MINUS_2: + return MOVE_EFFECT_SP_ATK_PLUS_2; + case MOVE_EFFECT_SP_DEF_MINUS_2: + return MOVE_EFFECT_SP_DEF_PLUS_2; + case MOVE_EFFECT_ACC_MINUS_2: + return MOVE_EFFECT_ACC_PLUS_2; + case MOVE_EFFECT_EVS_MINUS_2: + return MOVE_EFFECT_EVS_PLUS_2; + } +} + static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr) { bool32 certain = FALSE; @@ -9843,6 +9958,11 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr { statValue ^= STAT_BUFF_NEGATIVE; gBattleScripting.statChanger ^= STAT_BUFF_NEGATIVE; + if (flags & STAT_BUFF_UPDATE_MOVE_EFFECT) + { + flags &= ~(STAT_BUFF_UPDATE_MOVE_EFFECT); + gBattleScripting.moveEffect = ReverseStatChangeMoveEffect(gBattleScripting.moveEffect); + } } else if (GetBattlerAbility(gActiveBattler) == ABILITY_SIMPLE) { @@ -9963,6 +10083,7 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr statValue = -1; else if (gBattleMons[gActiveBattler].statStages[statId] == 2 && statValue < -2) statValue = -2; + gBattleTextBuff2[0] = B_BUFF_PLACEHOLDER_BEGIN; index = 1; if (statValue == -2) From 2ff9c2f8341a7a1da9de88bfc15103a436f12e7c Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 12 Nov 2021 13:00:28 -0500 Subject: [PATCH 29/69] remove test code --- src/battle_script_commands.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 37c46055da..65b149817a 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4720,9 +4720,6 @@ static void Cmd_playanimation(void) } #endif - //if (animId == B_ANIM_STATS_CHANGE && GetBattlerAbility(gActiveBattler) == ABILITY_CONTRARY) - //ReverseStatAnimId(argumentPtr); - if (animId == B_ANIM_STATS_CHANGE || animId == B_ANIM_SNATCH_MOVE || animId == B_ANIM_MEGA_EVOLUTION From 395cffa702a6ed06fd236c407b0f0d96ad2d7588 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 12 Nov 2021 13:04:33 -0500 Subject: [PATCH 30/69] remove ReverseStatAnimId --- src/battle_script_commands.c | 46 ------------------------------------ 1 file changed, 46 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 65b149817a..51aa365158 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4657,52 +4657,6 @@ static void Cmd_endselectionscript(void) *(gBattlerAttacker + gBattleStruct->selectionScriptFinished) = TRUE; } -static u32 ReverseStatAnimId(u16 *argumentPtr) -{ - u8 value = 0; - switch (GET_STAT_BUFF_VALUE_WITH_SIGN(gBattleScripting.statChanger)) - { - case SET_STAT_BUFF_VALUE(1): // +1 - value = STAT_ANIM_MINUS1; - break; - case SET_STAT_BUFF_VALUE(2): // +2 - value = STAT_ANIM_MINUS2; - break; - case SET_STAT_BUFF_VALUE(3): // +3 - value = STAT_ANIM_MINUS2; - break; - case SET_STAT_BUFF_VALUE(4): // +4 - value = STAT_ANIM_MINUS2; - break; - case SET_STAT_BUFF_VALUE(5): // +5 - value = STAT_ANIM_MINUS2; - break; - case SET_STAT_BUFF_VALUE(6): // +6 - value = STAT_ANIM_MINUS2; - break; - case SET_STAT_BUFF_VALUE(1) | STAT_BUFF_NEGATIVE: // -1 - value = STAT_ANIM_PLUS1; - break; - case SET_STAT_BUFF_VALUE(2) | STAT_BUFF_NEGATIVE: // -2 - value = STAT_ANIM_PLUS2; - break; - case SET_STAT_BUFF_VALUE(3) | STAT_BUFF_NEGATIVE: // -3 - value = STAT_ANIM_PLUS2; - break; - case SET_STAT_BUFF_VALUE(4) | STAT_BUFF_NEGATIVE: // -1 - value = STAT_ANIM_PLUS2; - break; - case SET_STAT_BUFF_VALUE(5) | STAT_BUFF_NEGATIVE: // -2 - value = STAT_ANIM_PLUS2; - break; - case SET_STAT_BUFF_VALUE(6) | STAT_BUFF_NEGATIVE: // -3 - value = STAT_ANIM_PLUS2; - break; - } - - *argumentPtr = GET_STAT_BUFF_ID(gBattleScripting.statChanger) + value - 1; -} - static void Cmd_playanimation(void) { u16* argumentPtr; From d5db3293183e49cf317cd5af510c417d8d770f7c Mon Sep 17 00:00:00 2001 From: ghoulslash <41651341+ghoulslash@users.noreply.github.com> Date: Fri, 12 Nov 2021 13:07:41 -0500 Subject: [PATCH 31/69] Update src/battle_script_commands.c Co-authored-by: ultima-soul <33333039+ultima-soul@users.noreply.github.com> --- 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 51aa365158..d36a37072e 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -10034,7 +10034,6 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr statValue = -1; else if (gBattleMons[gActiveBattler].statStages[statId] == 2 && statValue < -2) statValue = -2; - gBattleTextBuff2[0] = B_BUFF_PLACEHOLDER_BEGIN; index = 1; if (statValue == -2) From 0634d3e541ab336b24ea64b1b234b535f5efc598 Mon Sep 17 00:00:00 2001 From: ghoulslash <41651341+ghoulslash@users.noreply.github.com> Date: Fri, 12 Nov 2021 13:07:53 -0500 Subject: [PATCH 32/69] Update src/battle_script_commands.c Co-authored-by: LOuroboros --- 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 d36a37072e..0dbe68acf3 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4673,7 +4673,6 @@ static void Cmd_playanimation(void) return; } #endif - if (animId == B_ANIM_STATS_CHANGE || animId == B_ANIM_SNATCH_MOVE || animId == B_ANIM_MEGA_EVOLUTION From 876813a41843932e3aefc1868e42bfd05038cafd Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 12 Nov 2021 13:08:23 -0500 Subject: [PATCH 33/69] revert old attempts --- 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 0dbe68acf3..578f6d1807 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4659,7 +4659,7 @@ static void Cmd_endselectionscript(void) static void Cmd_playanimation(void) { - u16* argumentPtr; + const u16* argumentPtr; u8 animId = gBattlescriptCurrInstr[2]; gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); From cdb20e89fcbc6123aba19b5a964d013ae06b0c2e Mon Sep 17 00:00:00 2001 From: ghoulslash <41651341+ghoulslash@users.noreply.github.com> Date: Fri, 12 Nov 2021 13:12:05 -0500 Subject: [PATCH 34/69] Update src/battle_script_commands.c Co-authored-by: ultima-soul <33333039+ultima-soul@users.noreply.github.com> --- src/battle_script_commands.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 578f6d1807..7134818e06 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4673,6 +4673,7 @@ static void Cmd_playanimation(void) return; } #endif + if (animId == B_ANIM_STATS_CHANGE || animId == B_ANIM_SNATCH_MOVE || animId == B_ANIM_MEGA_EVOLUTION From 96fd8e696b0d991aa707835659d719c87f0e35e2 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 12 Nov 2021 15:00:21 -0500 Subject: [PATCH 35/69] brick break gen 4 and 5 config. clears aurora veil --- include/constants/battle_config.h | 1 + src/battle_script_commands.c | 32 ++++++++++++++++++++++++------- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index eb7600cc2a..8e72b2c99d 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -152,6 +152,7 @@ #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_GLARE_GHOST GEN_7 // In Gen4+, Glare can hit Ghost-type Pokémon normally. #define B_SKILL_SWAP GEN_7 // In Gen4+, Skill Swap triggers switch-in abilities after use. +#define B_BRICK_BREAK GEN_7 // In Gen4+, you can destroy your own side's screens. In Gen 5+, screens are not removed if the target is immune. // 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_script_commands.c b/src/battle_script_commands.c index 7134818e06..3f9ba388f7 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -13103,14 +13103,32 @@ static void Cmd_snatchsetbattlers(void) static void Cmd_removelightscreenreflect(void) // brick break { - u8 opposingSide = GetBattlerSide(gBattlerAttacker) ^ BIT_SIDE; - - if (gSideTimers[opposingSide].reflectTimer || gSideTimers[opposingSide].lightscreenTimer) + u8 side; + bool32 failed; + + #if B_BRICK_BREAK >= GEN_4 + side = GetBattlerSide(gBattlerAttacker); + #else + side = GetBattlerSide(gBattlerAttacker) ^ BIT_SIDE; + #endif + + #if B_BRICK_BREAK >= GEN_5 + failed = (gMoveResultFlags & MOVE_RESULT_NO_EFFECT); + #else + failed = FALSE; + #endif + + if (!failed + && (gSideTimers[side].reflectTimer + || gSideTimers[side].lightscreenTimer + || gSideTimers[side].auroraVeilTimer)) { - gSideStatuses[opposingSide] &= ~(SIDE_STATUS_REFLECT); - gSideStatuses[opposingSide] &= ~(SIDE_STATUS_LIGHTSCREEN); - gSideTimers[opposingSide].reflectTimer = 0; - gSideTimers[opposingSide].lightscreenTimer = 0; + gSideStatuses[side] &= ~(SIDE_STATUS_REFLECT); + gSideStatuses[side] &= ~(SIDE_STATUS_LIGHTSCREEN); + gSideStatuses[side] &= ~(SIDE_STATUS_AURORA_VEIL); + gSideTimers[side].reflectTimer = 0; + gSideTimers[side].lightscreenTimer = 0; + gSideTimers[side].auroraVeilTimer = 0; gBattleScripting.animTurn = 1; gBattleScripting.animTargetsHit = 1; } From 05699884d5114694103486021fd709dc58c2c899 Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Fri, 12 Nov 2021 21:19:06 +0100 Subject: [PATCH 36/69] Crits and Confusion bypass screens --- src/battle_util.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/battle_util.c b/src/battle_util.c index 18847b8cce..ee03453550 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8609,7 +8609,8 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move if (((gSideStatuses[defSide] & SIDE_STATUS_REFLECT && IS_MOVE_PHYSICAL(move)) || (gSideStatuses[defSide] & SIDE_STATUS_LIGHTSCREEN && IS_MOVE_SPECIAL(move)) || (gSideStatuses[defSide] & SIDE_STATUS_AURORA_VEIL)) - && abilityAtk != ABILITY_INFILTRATOR) + && abilityAtk != ABILITY_INFILTRATOR && !(isCrit) + && !gProtectStructs[gBattlerAttacker].confusionSelfDmg) { if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) MulModifier(&finalModifier, UQ_4_12(0.66)); From 2e3aafe81becb4f32232903ffb0cf821992f6082 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Fri, 12 Nov 2021 18:53:46 -0300 Subject: [PATCH 37/69] Fix Assault Vest's battle message --- src/battle_message.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_message.c b/src/battle_message.c index 30af20a784..28bcca187b 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -629,7 +629,7 @@ static const u8 sText_TerrainBecomesGrassy[] = _("Grass grew to cover\nthe battl static const u8 sText_TerrainBecomesElectric[] = _("An electric current runs across\nthe battlefield!"); static const u8 sText_TerrainBecomesPsychic[] = _("The battlefield got weird!"); static const u8 sText_TargetElectrified[] = _("The {B_DEF_NAME_WITH_PREFIX}'s moves\nhave been electrified!"); -static const u8 sText_AssaultVestDoesntAllow[] = _("The effects of the {B_LAST_ITEM} prevent status\nmoves from being used!\p"); +static const u8 sText_AssaultVestDoesntAllow[] = _("{B_LAST_ITEM}'s effects prevent\nstatus moves from being used!\p"); static const u8 sText_GravityPreventsUsage[] = _("{B_ATK_NAME_WITH_PREFIX} can't use {B_CURRENT_MOVE}\nbecause of gravity!\p"); static const u8 sText_HealBlockPreventsUsage[] = _("{B_ATK_NAME_WITH_PREFIX} was\nprevented from healing!\p"); static const u8 sText_MegaEvoReacting[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_LAST_ITEM} is \nreacting to {B_ATK_TRAINER_NAME}'s Mega Ring!"); From 2489023332e766aab01fd5c75f4d56b1eeb2241d Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Fri, 12 Nov 2021 19:24:50 -0300 Subject: [PATCH 38/69] Fixed assault Vest restricting Me First --- src/battle_util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/battle_util.c b/src/battle_util.c index 18847b8cce..acc402de45 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1762,7 +1762,7 @@ u8 TrySetCantSelectMoveBattleScript(void) limitations++; } } - else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[move].power == 0) + else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[move].power == 0 && move != MOVE_ME_FIRST) { gCurrentMove = move; gLastUsedItem = gBattleMons[gActiveBattler].item; @@ -1834,7 +1834,7 @@ u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u8 check) unusableMoves |= gBitTable[i]; else if (HOLD_EFFECT_CHOICE(holdEffect) && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != gBattleMons[battlerId].moves[i]) unusableMoves |= gBitTable[i]; - else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[gBattleMons[battlerId].moves[i]].power == 0) + else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[gBattleMons[battlerId].moves[i]].power == 0 && gBattleMons[battlerId].moves[i] != MOVE_STUFF_CHEEKS) unusableMoves |= gBitTable[i]; else if (IsGravityPreventingMove(gBattleMons[battlerId].moves[i])) unusableMoves |= gBitTable[i]; From fdff1ae1b6633ab750f5f12948b734a04f568fa2 Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Fri, 12 Nov 2021 23:34:44 +0100 Subject: [PATCH 39/69] Update src/battle_util.c Co-authored-by: Eduardo Quezada D'Ottone --- src/battle_util.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/battle_util.c b/src/battle_util.c index ee03453550..81897096fb 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8609,7 +8609,8 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move if (((gSideStatuses[defSide] & SIDE_STATUS_REFLECT && IS_MOVE_PHYSICAL(move)) || (gSideStatuses[defSide] & SIDE_STATUS_LIGHTSCREEN && IS_MOVE_SPECIAL(move)) || (gSideStatuses[defSide] & SIDE_STATUS_AURORA_VEIL)) - && abilityAtk != ABILITY_INFILTRATOR && !(isCrit) + && abilityAtk != ABILITY_INFILTRATOR + && !(isCrit) && !gProtectStructs[gBattlerAttacker].confusionSelfDmg) { if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) From c4efe06f3831a344f19b4c56f87acff7d0c19f88 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 12 Nov 2021 17:55:05 -0500 Subject: [PATCH 40/69] wish update --- include/constants/battle_config.h | 1 + src/battle_script_commands.c | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 8e72b2c99d..b7071221eb 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -153,6 +153,7 @@ #define B_GLARE_GHOST GEN_7 // In Gen4+, Glare can hit Ghost-type Pokémon normally. #define B_SKILL_SWAP GEN_7 // In Gen4+, Skill Swap triggers switch-in abilities after use. #define B_BRICK_BREAK GEN_7 // In Gen4+, you can destroy your own side's screens. In Gen 5+, screens are not removed if the target is immune. +#define B_WISH GEN_7 // In Gen5+, it heals half of the user's max HP instead of the target // 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_script_commands.c b/src/battle_script_commands.c index 3f9ba388f7..36e438ae1e 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -12347,12 +12347,13 @@ static void Cmd_trywish(void) break; case 1: // heal effect PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattlerTarget, gWishFutureKnock.wishMonId[gBattlerTarget]) - - gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP / 2; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; + #if B_WISH >= GEN_5 + gBattleMoveDamage = max(1, gBattleMons[gWishFutureKnock.wishMonId[gBattlerTarget]].maxHP / 2); + #else + gBattleMoveDamage = max(1, gBattleMons[gBattlerTarget].maxHP / 2); + #endif + gBattleMoveDamage *= -1; - if (gBattleMons[gBattlerTarget].hp == gBattleMons[gBattlerTarget].maxHP) gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); else From 704957efb91101a2331c4ea3801f5b226e010b6f Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Sat, 13 Nov 2021 07:30:12 -0300 Subject: [PATCH 41/69] Fixed Relic Song's SE --- data/battle_anim_scripts.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index b10c937aec..fd118a64ac 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -7279,7 +7279,7 @@ Move_RELIC_SONG: monbg ANIM_DEF_PARTNER launchtask AnimTask_MusicNotesRainbowBlend 0x2 0x0 waitforvisualfinish - panse_1B 0x1DF, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 0x2, 0x0 @ ??? + createvisualtask SoundTask_PlayCryWithEcho, 2, ANIM_ATTACKER, 2 launchtask AnimTask_UproarDistortion 0x2 0x1 0x0 launchtemplate gUproarRingSpriteTemplate 0x3 0x6 0x0 0x0 0x0 0x0 0x1f 0x8 launchtemplate gJaggedMusicNoteSpriteTemplate 0x2 0x4 0x0 0x1d 0xfff4 0x0 From 10c390b9ec4a7a8ea0fd184dc2010617348b81d8 Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Sat, 13 Nov 2021 11:53:49 +0100 Subject: [PATCH 42/69] Effectiveness is calculated for moves bypassing king's shield I'm curious what this is for. Before the change it just prevented moves that bypass protections from dealing super effective/not very effective damage to an aegislash using king's shield. So I just added a check with IsBattlerProtected, but in my opinion this line should be entirely removed. Unless I'm missing something. --- 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 81897096fb..74068ec0b3 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8783,7 +8783,7 @@ static void MulByTypeEffectiveness(u16 *modifier, u16 move, u8 moveType, u8 batt if (moveType == TYPE_FIRE && gDisableStructs[battlerDef].tarShot) mod = UQ_4_12(2.0); - if (gProtectStructs[battlerDef].kingsShielded && gBattleMoves[move].effect != EFFECT_FEINT) + if (gProtectStructs[battlerDef].kingsShielded && gBattleMoves[move].effect != EFFECT_FEINT && IsBattlerProtected(battlerDef, move)) mod = UQ_4_12(1.0); // WEATHER_STRONG_WINDS weakens Super Effective moves against Flying-type Pokémon From 90b6c7d56c50ef8ebca818ee6782be5e11693ea2 Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Sat, 13 Nov 2021 13:24:30 +0100 Subject: [PATCH 43/69] Remove unwanted check According to bulbapedia this check shouldn't exist. It was just preventing effectiveness from being calculated when a move bypassing protection would go through king's shield --- src/battle_util.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/battle_util.c b/src/battle_util.c index 74068ec0b3..5ae26d37bb 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8783,9 +8783,6 @@ static void MulByTypeEffectiveness(u16 *modifier, u16 move, u8 moveType, u8 batt if (moveType == TYPE_FIRE && gDisableStructs[battlerDef].tarShot) mod = UQ_4_12(2.0); - if (gProtectStructs[battlerDef].kingsShielded && gBattleMoves[move].effect != EFFECT_FEINT && IsBattlerProtected(battlerDef, move)) - mod = UQ_4_12(1.0); - // WEATHER_STRONG_WINDS weakens Super Effective moves against Flying-type Pokémon if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_STRONG_WINDS) { From f808710932b83815c1299c1a7297fb699b33f1c1 Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Sat, 13 Nov 2021 13:38:07 +0100 Subject: [PATCH 44/69] Moving IsBattlerProtected --- include/battle_util.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/battle_util.h b/include/battle_util.h index fb74610d0c..d3b930feda 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -102,6 +102,7 @@ u32 IsAbilityOnOpposingSide(u32 battlerId, u32 ability); u32 IsAbilityOnField(u32 ability); u32 IsAbilityOnFieldExcept(u32 battlerId, u32 ability); u32 IsAbilityPreventingEscape(u32 battlerId); +bool32 IsBattlerProtected(u8 battlerId, u16 move); bool32 CanBattlerEscape(u32 battlerId); // no ability check void BattleScriptExecute(const u8* BS_ptr); void BattleScriptPushCursorAndCallback(const u8* BS_ptr); From 89e9b989c943903972cd21cfb95d3c0860a7c474 Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Sat, 13 Nov 2021 13:40:19 +0100 Subject: [PATCH 45/69] Moving isBattlerProtected --- src/battle_script_commands.c | 41 ------------------------------------ 1 file changed, 41 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 7134818e06..5122f4f3bc 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1313,47 +1313,6 @@ static const u8 sBattlePalaceNatureToFlavorTextId[NUM_NATURES] = [NATURE_QUIRKY] = B_MSG_EAGER_FOR_MORE, }; -bool32 IsBattlerProtected(u8 battlerId, u16 move) -{ - // Decorate bypasses protect and detect, but not crafty shield - if (move == MOVE_DECORATE) - { - if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_CRAFTY_SHIELD) - return TRUE; - else if (gProtectStructs[battlerId].protected) - return FALSE; - } - - if (!(gBattleMoves[move].flags & FLAG_PROTECT_AFFECTED)) - return FALSE; - else if (gBattleMoves[move].effect == MOVE_EFFECT_FEINT) - return FALSE; - else if (gProtectStructs[battlerId].protected) - return TRUE; - else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_WIDE_GUARD - && gBattleMoves[move].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)) - return TRUE; - else if (gProtectStructs[battlerId].banefulBunkered) - return TRUE; - else if (gProtectStructs[battlerId].obstructed && !IS_MOVE_STATUS(move)) - return TRUE; - else if (gProtectStructs[battlerId].spikyShielded) - return TRUE; - else if (gProtectStructs[battlerId].kingsShielded && gBattleMoves[move].power != 0) - return TRUE; - else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_QUICK_GUARD - && GetChosenMovePriority(gBattlerAttacker) > 0) - return TRUE; - else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_CRAFTY_SHIELD - && IS_MOVE_STATUS(move)) - return TRUE; - else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_MAT_BLOCK - && !IS_MOVE_STATUS(move)) - return TRUE; - else - return FALSE; -} - static bool32 NoTargetPresent(u32 move) { if (!IsBattlerAlive(gBattlerTarget)) From b3b3cd2c67e4f61664dac27a3b0e684b0b36ce3c Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Sat, 13 Nov 2021 13:48:08 +0100 Subject: [PATCH 46/69] IsBattlerProtected --- src/battle_util.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/battle_util.c b/src/battle_util.c index 5ae26d37bb..1f89a082e5 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -7450,6 +7450,48 @@ bool32 IsMoveMakingContact(u16 move, u8 battlerAtk) } } +bool32 IsBattlerProtected(u8 battlerId, u16 move) +{ + // Decorate bypasses protect and detect, but not crafty shield + if (move == MOVE_DECORATE) + { + if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_CRAFTY_SHIELD) + return TRUE; + else if (gProtectStructs[battlerId].protected) + return FALSE; + } + + if (!(gBattleMoves[move].flags & FLAG_PROTECT_AFFECTED)) + return FALSE; + else if (gBattleMoves[move].effect == MOVE_EFFECT_FEINT) + return FALSE; + else if (gProtectStructs[battlerId].protected) + return TRUE; + else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_WIDE_GUARD + && gBattleMoves[move].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)) + return TRUE; + else if (gProtectStructs[battlerId].banefulBunkered) + return TRUE; + else if (gProtectStructs[battlerId].obstructed && !IS_MOVE_STATUS(move)) + return TRUE; + else if (gProtectStructs[battlerId].spikyShielded) + return TRUE; + else if (gProtectStructs[battlerId].kingsShielded && gBattleMoves[move].power != 0) + return TRUE; + else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_QUICK_GUARD + && GetChosenMovePriority(gBattlerAttacker) > 0) + return TRUE; + else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_CRAFTY_SHIELD + && IS_MOVE_STATUS(move)) + return TRUE; + else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_MAT_BLOCK + && !IS_MOVE_STATUS(move)) + return TRUE; + else + return FALSE; +} + + bool32 IsBattlerGrounded(u8 battlerId) { if (GetBattlerHoldEffect(battlerId, TRUE) == HOLD_EFFECT_IRON_BALL) From a4204e5491e30ec2b1cc8fd113cd4ad2d284cd66 Mon Sep 17 00:00:00 2001 From: ghoulslash <41651341+ghoulslash@users.noreply.github.com> Date: Sat, 13 Nov 2021 08:50:24 -0500 Subject: [PATCH 47/69] Update include/constants/battle_config.h Co-authored-by: Eduardo Quezada D'Ottone --- 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 b7071221eb..0b80c9bc66 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -153,7 +153,7 @@ #define B_GLARE_GHOST GEN_7 // In Gen4+, Glare can hit Ghost-type Pokémon normally. #define B_SKILL_SWAP GEN_7 // In Gen4+, Skill Swap triggers switch-in abilities after use. #define B_BRICK_BREAK GEN_7 // In Gen4+, you can destroy your own side's screens. In Gen 5+, screens are not removed if the target is immune. -#define B_WISH GEN_7 // In Gen5+, it heals half of the user's max HP instead of the target +#define B_WISH_HP_SOURCE GEN_7 // In Gen5+, Wish heals half of the user's max HP instead of the target's. // 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 b68c596ce5c3029179dcfb53930c1351ffd67f97 Mon Sep 17 00:00:00 2001 From: ghoulslash <41651341+ghoulslash@users.noreply.github.com> Date: Sat, 13 Nov 2021 08:50:30 -0500 Subject: [PATCH 48/69] Update src/battle_script_commands.c Co-authored-by: Eduardo Quezada D'Ottone --- 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 36e438ae1e..a5cce7c45d 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -12347,7 +12347,7 @@ static void Cmd_trywish(void) break; case 1: // heal effect PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattlerTarget, gWishFutureKnock.wishMonId[gBattlerTarget]) - #if B_WISH >= GEN_5 + #if B_WISH_HP_SOURCE >= GEN_5 gBattleMoveDamage = max(1, gBattleMons[gWishFutureKnock.wishMonId[gBattlerTarget]].maxHP / 2); #else gBattleMoveDamage = max(1, gBattleMons[gBattlerTarget].maxHP / 2); From ad393385ac22595207e1ca0d52b27257636d59aa Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Sat, 13 Nov 2021 10:58:18 -0300 Subject: [PATCH 49/69] Oops --- 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 acc402de45..bef9c4f652 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1834,7 +1834,7 @@ u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u8 check) unusableMoves |= gBitTable[i]; else if (HOLD_EFFECT_CHOICE(holdEffect) && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != gBattleMons[battlerId].moves[i]) unusableMoves |= gBitTable[i]; - else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[gBattleMons[battlerId].moves[i]].power == 0 && gBattleMons[battlerId].moves[i] != MOVE_STUFF_CHEEKS) + else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[gBattleMons[battlerId].moves[i]].power == 0 && gBattleMons[battlerId].moves[i] != MOVE_ME_FIRST) unusableMoves |= gBitTable[i]; else if (IsGravityPreventingMove(gBattleMons[battlerId].moves[i])) unusableMoves |= gBitTable[i]; From bcbdb353f5145c64c1dd0d2d00436e97af4b0ccb Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Sat, 13 Nov 2021 12:10:20 -0300 Subject: [PATCH 50/69] Adjusted elements to simplify the conflicts between BE and IE --- include/constants/hold_effects.h | 4 ++-- src/battle_ai_main.c | 2 +- src/battle_debug.c | 16 ++++++++++++---- src/battle_script_commands.c | 8 ++++++-- src/battle_util.c | 4 ++-- src/data/items.h | 4 ++-- 6 files changed, 25 insertions(+), 13 deletions(-) diff --git a/include/constants/hold_effects.h b/include/constants/hold_effects.h index d7d74d3e1b..cba2321ce2 100644 --- a/include/constants/hold_effects.h +++ b/include/constants/hold_effects.h @@ -62,12 +62,12 @@ #define HOLD_EFFECT_FIRE_POWER 58 #define HOLD_EFFECT_DRAGON_POWER 59 #define HOLD_EFFECT_NORMAL_POWER 60 -#define HOLD_EFFECT_UP_GRADE 61 +#define HOLD_EFFECT_UPGRADE 61 #define HOLD_EFFECT_SHELL_BELL 62 #define HOLD_EFFECT_LUCKY_PUNCH 63 #define HOLD_EFFECT_METAL_POWDER 64 #define HOLD_EFFECT_THICK_CLUB 65 -#define HOLD_EFFECT_STICK 66 +#define HOLD_EFFECT_LEEK 66 // Gen4 hold effects. #define HOLD_EFFECT_CHOICE_SCARF 67 diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 7fbb432603..e3b8e8d5d3 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -2320,7 +2320,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) || IsInstructBannedMove(instructedMove) || MoveRequiresRecharging(instructedMove) || MoveCallsOtherMove(instructedMove) - #ifdef ITEM_Z_RING + #ifdef ITEM_Z_POWER_RING //|| (IsZMove(instructedMove)) #endif || (gLockedMoves[battlerDef] != 0 && gLockedMoves[battlerDef] != 0xFFFF) diff --git a/src/battle_debug.c b/src/battle_debug.c index c967cfe00e..a10e60412f 100644 --- a/src/battle_debug.c +++ b/src/battle_debug.c @@ -1924,12 +1924,20 @@ static const u8 sText_HoldEffectPsychicPower[] = _("Psychic Power"); static const u8 sText_HoldEffectFirePower[] = _("Fire Power"); static const u8 sText_HoldEffectDragonPower[] = _("Dragon Power"); static const u8 sText_HoldEffectNormalPower[] = _("Normal Power"); -static const u8 sText_HoldEffectUpGrade[] = _("Up Grade"); +#ifdef ITEM_EXPANSION +static const u8 sText_HoldEffectUpgrade[] = _("Upgrade"); +#else +static const u8 sText_HoldEffectUpgrade[] = _("Up Grade"); +#endif static const u8 sText_HoldEffectShellBell[] = _("Shell Bell"); static const u8 sText_HoldEffectLuckyPunch[] = _("Lucky Punch"); static const u8 sText_HoldEffectMetalPowder[] = _("Metal Powder"); static const u8 sText_HoldEffectThickClub[] = _("Thick Club"); -static const u8 sText_HoldEffectStick[] = _("Stick"); +#ifdef ITEM_EXPANSION +static const u8 sText_HoldEffectLeek[] = _("Leek"); +#else +static const u8 sText_HoldEffectLeek[] = _("Stick"); +#endif static const u8 sText_HoldEffectChoiceScarf[] = _("Choice Scarf"); static const u8 sText_HoldEffectChoiceSpecs[] = _("Choice Specs"); static const u8 sText_HoldEffectDampRock[] = _("Damp Rock"); @@ -2064,12 +2072,12 @@ static const u8 *const sHoldEffectNames[] = [HOLD_EFFECT_FIRE_POWER] = sText_HoldEffectFirePower, [HOLD_EFFECT_DRAGON_POWER] = sText_HoldEffectDragonPower, [HOLD_EFFECT_NORMAL_POWER] = sText_HoldEffectNormalPower, - [HOLD_EFFECT_UP_GRADE] = sText_HoldEffectUpGrade, + [HOLD_EFFECT_UPGRADE] = sText_HoldEffectUpgrade, [HOLD_EFFECT_SHELL_BELL] = sText_HoldEffectShellBell, [HOLD_EFFECT_LUCKY_PUNCH] = sText_HoldEffectLuckyPunch, [HOLD_EFFECT_METAL_POWDER] = sText_HoldEffectMetalPowder, [HOLD_EFFECT_THICK_CLUB] = sText_HoldEffectThickClub, - [HOLD_EFFECT_STICK] = sText_HoldEffectStick, + [HOLD_EFFECT_LEEK] = sText_HoldEffectLeek, [HOLD_EFFECT_CHOICE_SCARF] = sText_HoldEffectChoiceScarf, [HOLD_EFFECT_CHOICE_SPECS] = sText_HoldEffectChoiceSpecs, [HOLD_EFFECT_DAMP_ROCK] = sText_HoldEffectDampRock, diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index eb9334c4ea..a3fb8fe454 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1893,7 +1893,7 @@ s32 CalcCritChanceStage(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbi + ((gBattleMoves[gCurrentMove].flags & FLAG_HIGH_CRIT) != 0) + (holdEffectAtk == HOLD_EFFECT_SCOPE_LENS) + 2 * (holdEffectAtk == HOLD_EFFECT_LUCKY_PUNCH && gBattleMons[gBattlerAttacker].species == SPECIES_CHANSEY) - + 2 * (holdEffectAtk == HOLD_EFFECT_STICK && gBattleMons[gBattlerAttacker].species == SPECIES_FARFETCHD) + + 2 * (holdEffectAtk == HOLD_EFFECT_LEEK && gBattleMons[gBattlerAttacker].species == SPECIES_FARFETCHD) + (abilityAtk == ABILITY_SUPER_LUCK); if (critChance >= ARRAY_COUNT(sCriticalHitChance)) @@ -3164,7 +3164,11 @@ void SetMoveEffect(bool32 primary, u32 certain) RecordAbilityBattle(gBattlerTarget, gLastUsedAbility); } else if (gBattleMons[gBattlerAttacker].item != 0 + #ifdef ITEM_EXPANSION + || gBattleMons[gBattlerTarget].item == ITEM_ENIGMA_BERRY_E_READER + #else || gBattleMons[gBattlerTarget].item == ITEM_ENIGMA_BERRY + #endif || gBattleMons[gBattlerTarget].item == 0) { gBattlescriptCurrInstr++; @@ -13138,7 +13142,7 @@ static void Cmd_handleballthrow(void) u8 catchRate; gLastThrownBall = gLastUsedItem; - if (gLastUsedItem == ITEM_SAFARI_BALL) + if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) catchRate = gBattleStruct->safariCatchFactor * 1275 / 100; else catchRate = gBaseStats[gBattleMons[gBattlerTarget].species].catchRate; diff --git a/src/battle_util.c b/src/battle_util.c index 6ce984cf40..7f65ec55f0 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -9048,9 +9048,9 @@ bool32 CanMegaEvolve(u8 battlerId) struct MegaEvolutionData *mega = &(((struct ChooseMoveStruct*)(&gBattleResources->bufferA[gActiveBattler][4]))->mega); #ifdef ITEM_EXPANSION - // Check if Player has a Mega Bracelet + // Check if Player has a Mega Ring if ((GetBattlerPosition(battlerId) == B_POSITION_PLAYER_LEFT || (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) && GetBattlerPosition(battlerId) == B_POSITION_PLAYER_RIGHT)) - && !CheckBagHasItem(ITEM_MEGA_BRACELET, 1)) + && !CheckBagHasItem(ITEM_MEGA_RING, 1)) return FALSE; #endif diff --git a/src/data/items.h b/src/data/items.h index ef5c8825d3..7e62558aa4 100644 --- a/src/data/items.h +++ b/src/data/items.h @@ -2680,7 +2680,7 @@ const struct Item gItems[] = .name = _("UP-GRADE"), .itemId = ITEM_UP_GRADE, .price = 2100, - .holdEffect = HOLD_EFFECT_UP_GRADE, + .holdEffect = HOLD_EFFECT_UPGRADE, .description = sUpGradeDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_BAG_MENU, @@ -2767,7 +2767,7 @@ const struct Item gItems[] = .name = _("STICK"), .itemId = ITEM_STICK, .price = 200, - .holdEffect = HOLD_EFFECT_STICK, + .holdEffect = HOLD_EFFECT_LEEK, .description = sStickDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_BAG_MENU, From cedc2e07bda0199fda7e8da7465e2ac0cbe6a0a3 Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Sun, 14 Nov 2021 13:31:06 +1300 Subject: [PATCH 51/69] Fix Cherrim softlock Fix typo that caused infinite loop. --- 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 6ce984cf40..2c2918a004 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -3792,7 +3792,7 @@ u8 TryWeatherFormChange(u8 battler) ret = 0; else if (gBattleMonForms[battler] == 0 && weatherEffect && holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA && gBattleWeather & WEATHER_SUN_ANY) ret = 2; - else if (gBattleMonForms[battler] != 0 && (!weatherEffect || holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA || !(gBattleWeather & WEATHER_SUN_ANY))) + else if (gBattleMonForms[battler] != 0 && (!weatherEffect || holdEffect == HOLD_EFFECT_UTILITY_UMBRELLA || !(gBattleWeather & WEATHER_SUN_ANY))) ret = 1; } From d4fa346540f4f955dc45648d6fc20269cac5fa2a Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Mon, 15 Nov 2021 21:40:20 +1300 Subject: [PATCH 52/69] Fix Dark Aura and Fairy Aura Damage boost should be 33%, not 25%. --- 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 7d0f6cebf4..d57d25e0ec 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8131,7 +8131,7 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe if (IsAbilityOnField(ABILITY_AURA_BREAK)) MulModifier(&modifier, UQ_4_12(0.75)); else - MulModifier(&modifier, UQ_4_12(1.25)); + MulModifier(&modifier, UQ_4_12(1.33)); } // attacker partner's abilities From 9fdd6fffee4d06d56f610ff3265adcb4571dbc3c Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 15 Nov 2021 10:45:23 -0500 Subject: [PATCH 53/69] AI_GetAbility supports hidden abilities --- src/battle_ai_util.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index c90c9cdab4..499969ec33 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -1133,18 +1133,17 @@ s32 AI_GetAbility(u32 battlerId) || gBattleMons[battlerId].ability == ABILITY_MAGNET_PULL || gBattleMons[battlerId].ability == ABILITY_ARENA_TRAP) return gBattleMons[battlerId].ability; - + + // AI has no knowledge of opponent, so it guesses which ability. if (gBaseStats[gBattleMons[battlerId].species].abilities[0] != ABILITY_NONE) { - if (gBaseStats[gBattleMons[battlerId].species].abilities[1] != ABILITY_NONE) + u16 abilityGuess = ABILITY_NONE; + while (abilityGuess == ABILITY_NONE) { - // AI has no knowledge of opponent, so it guesses which ability. - return gBaseStats[gBattleMons[battlerId].species].abilities[Random() & 1]; - } - else - { - return gBaseStats[gBattleMons[battlerId].species].abilities[0]; // It's definitely ability 1. + abilityGuess = gBaseStats[gBattleMons[battlerId].species].abilities[Random() % NUM_ABILITY_SLOTS]; } + + return abilityGuess; } return ABILITY_NONE; // Unknown. } From ea34d4694d7c9bf50ac7b1cef8b4ccfdebc15c85 Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Mon, 15 Nov 2021 16:48:44 +0100 Subject: [PATCH 54/69] PartyBattlerShouldAvoidHazards fix AI was loading and modifying wrong data in the RAM --- src/battle_ai_util.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 71dc78d0aa..d46a43f6b9 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -2408,9 +2408,19 @@ static bool32 AnyUsefulStatIsRaised(u8 battler) return FALSE; } +struct Pokemon *GetPartyBattlerPartyData(u8 battlerId, u8 switchBattler) +{ + struct Pokemon *mon; + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) + mon = &gPlayerParty[switchBattler]; + else + mon = &gEnemyParty[switchBattler]; + return mon; +} + static bool32 PartyBattlerShouldAvoidHazards(u8 currBattler, u8 switchBattler) { - struct Pokemon *mon = GetBattlerPartyData(switchBattler); + struct Pokemon *mon = GetPartyBattlerPartyData(currBattler, switchBattler); u16 ability = GetMonAbility(mon); // we know our own party data u16 holdEffect = GetBattlerHoldEffect(GetMonData(mon, MON_DATA_HELD_ITEM), TRUE); u32 flags = gSideStatuses[GetBattlerSide(currBattler)] & (SIDE_STATUS_SPIKES | SIDE_STATUS_STEALTH_ROCK | SIDE_STATUS_STICKY_WEB | SIDE_STATUS_TOXIC_SPIKES); From a1bd6bd52fd9021c12d07624882afa483004948d Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Mon, 15 Nov 2021 22:30:20 -0300 Subject: [PATCH 55/69] Updated species that benefit from Leek --- include/constants/battle_config.h | 1 + src/battle_script_commands.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 6f4e283ca5..7f4facf026 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -51,6 +51,7 @@ #define SPECIES_MELOETTA_PIROUETTE 10019 #define SPECIES_MORPEKO 0 #define SPECIES_MORPEKO_HANGRY 10020 + #define SPECIES_SIRFETCHD 10021 #endif // Items with peculiar battle effects. diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 4a5b09df37..fe7d3ca305 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1893,7 +1893,9 @@ s32 CalcCritChanceStage(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbi + ((gBattleMoves[gCurrentMove].flags & FLAG_HIGH_CRIT) != 0) + (holdEffectAtk == HOLD_EFFECT_SCOPE_LENS) + 2 * (holdEffectAtk == HOLD_EFFECT_LUCKY_PUNCH && gBattleMons[gBattlerAttacker].species == SPECIES_CHANSEY) - + 2 * (holdEffectAtk == HOLD_EFFECT_LEEK && gBattleMons[gBattlerAttacker].species == SPECIES_FARFETCHD) + + 2 * (holdEffectAtk == HOLD_EFFECT_LEEK + && (GET_BASE_SPECIES_ID(gBattleMons[gBattlerAttacker].species) == SPECIES_FARFETCHD + || gBattleMons[gBattlerAttacker].species == SPECIES_SIRFETCHD)) + (abilityAtk == ABILITY_SUPER_LUCK); if (critChance >= ARRAY_COUNT(sCriticalHitChance)) From cc833ebb5979730389ac6897636b63cd9d1ef652 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Mon, 15 Nov 2021 23:21:46 -0300 Subject: [PATCH 56/69] Created macro + config for always critting when using high-crit moves --- include/constants/battle_config.h | 1 + src/battle_script_commands.c | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 7f4facf026..5e6c7d7293 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -186,6 +186,7 @@ #define B_HEAVY_BALL_MODIFIER GEN_7 // In Gen7+, Heavy Ball's ranges change. See Cmd_handleballthrow. #define B_DREAM_BALL_MODIFIER GEN_8 // In Gen8, Dream Ball's catch multiplier is x4 when the target is asleep or has the ability Comatose. #define B_SERENE_GRACE_BOOST GEN_7 // In Gen5+, Serene Grace boosts the added flinch chance of King's Rock and Razor Fang. +#define B_LEEK_ALWAYS_CRIT GEN_7 // In Gen6+, if a Farfetch'd or Sirfetch'd holding a Leek use a move with increased Critical Hit ratio, it will always result in a Critical Hit. // Flag settings // To use the following features in scripting, replace the 0s with the flag ID you're assigning it to. diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index fe7d3ca305..99441e1425 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1861,11 +1861,13 @@ static void Cmd_ppreduce(void) static const u8 sCriticalHitChance[] = {16, 8, 4, 3, 2}; // Gens 2,3,4,5 #endif // B_CRIT_CHANCE +#define BENEFITS_FROM_LEEK(battler, holdEffect)((holdEffect == HOLD_EFFECT_LEEK) && (GET_BASE_SPECIES_ID(gBattleMons[battler].species) == SPECIES_FARFETCHD || gBattleMons[battler].species == SPECIES_SIRFETCHD)) s32 CalcCritChanceStage(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbility) { s32 critChance = 0; u32 abilityAtk = GetBattlerAbility(gBattlerAttacker); u32 abilityDef = GetBattlerAbility(gBattlerTarget); + u32 holdEffectAtk = GetBattlerHoldEffect(battlerAtk, TRUE); if (gSideStatuses[battlerDef] & SIDE_STATUS_LUCKY_CHANT || gStatuses3[gBattlerAttacker] & STATUS3_CANT_SCORE_A_CRIT) @@ -1881,21 +1883,21 @@ s32 CalcCritChanceStage(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbi else if (gStatuses3[battlerAtk] & STATUS3_LASER_FOCUS || gBattleMoves[move].effect == EFFECT_ALWAYS_CRIT || (abilityAtk == ABILITY_MERCILESS && gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY) - || move == MOVE_SURGING_STRIKES) + || move == MOVE_SURGING_STRIKES + #if B_LEEK_ALWAYS_CRIT >= GEN_6 + || ((gBattleMoves[gCurrentMove].flags & FLAG_HIGH_CRIT) && BENEFITS_FROM_LEEK(battlerAtk, holdEffectAtk)) + #endif + ) { critChance = -2; } else { - u32 holdEffectAtk = GetBattlerHoldEffect(battlerAtk, TRUE); - critChance = 2 * ((gBattleMons[gBattlerAttacker].status2 & STATUS2_FOCUS_ENERGY) != 0) + ((gBattleMoves[gCurrentMove].flags & FLAG_HIGH_CRIT) != 0) + (holdEffectAtk == HOLD_EFFECT_SCOPE_LENS) + 2 * (holdEffectAtk == HOLD_EFFECT_LUCKY_PUNCH && gBattleMons[gBattlerAttacker].species == SPECIES_CHANSEY) - + 2 * (holdEffectAtk == HOLD_EFFECT_LEEK - && (GET_BASE_SPECIES_ID(gBattleMons[gBattlerAttacker].species) == SPECIES_FARFETCHD - || gBattleMons[gBattlerAttacker].species == SPECIES_SIRFETCHD)) + + 2 * BENEFITS_FROM_LEEK(battlerAtk, holdEffectAtk) + (abilityAtk == ABILITY_SUPER_LUCK); if (critChance >= ARRAY_COUNT(sCriticalHitChance)) @@ -1904,6 +1906,7 @@ s32 CalcCritChanceStage(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbi return critChance; } +#undef BenefitsFromLeek s8 GetInverseCritChance(u8 battlerAtk, u8 battlerDef, u32 move) { From 0af63c04ebfac6730cfb9c972621258d70ad8212 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Mon, 15 Nov 2021 23:29:54 -0300 Subject: [PATCH 57/69] Removed redundant uses of STATUS3_GASTRO_ACID check. --- src/battle_script_commands.c | 10 +++++----- src/battle_util.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 99441e1425..2f290c3aba 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -8971,11 +8971,11 @@ static void Cmd_various(void) for (i = 0; i < gBattlersCount; i++) { - if (((GetBattlerAbility(i) == ABILITY_DESOLATE_LAND && gBattleWeather & WEATHER_SUN_PRIMAL) - || (GetBattlerAbility(i) == ABILITY_PRIMORDIAL_SEA && gBattleWeather & WEATHER_RAIN_PRIMAL) - || (GetBattlerAbility(i) == ABILITY_DELTA_STREAM && gBattleWeather & WEATHER_STRONG_WINDS)) - && IsBattlerAlive(i) - && !(gStatuses3[i] & STATUS3_GASTRO_ACID)) + u32 ability = GetBattlerAbility(i); + if (((ability == ABILITY_DESOLATE_LAND && gBattleWeather & WEATHER_SUN_PRIMAL) + || (ability == ABILITY_PRIMORDIAL_SEA && gBattleWeather & WEATHER_RAIN_PRIMAL) + || (ability == ABILITY_DELTA_STREAM && gBattleWeather & WEATHER_STRONG_WINDS)) + && IsBattlerAlive(i)) shouldNotClear = TRUE; } if (gBattleWeather & WEATHER_SUN_PRIMAL && !shouldNotClear) diff --git a/src/battle_util.c b/src/battle_util.c index 1e29695e25..6eb95d848a 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -7462,7 +7462,7 @@ u32 GetBattlerHoldEffect(u8 battlerId, bool32 checkNegating) return HOLD_EFFECT_NONE; if (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM) return HOLD_EFFECT_NONE; - if (GetBattlerAbility(battlerId) == ABILITY_KLUTZ && !(gStatuses3[battlerId] & STATUS3_GASTRO_ACID)) + if (GetBattlerAbility(battlerId) == ABILITY_KLUTZ) return HOLD_EFFECT_NONE; } From 7dbc94deefc0945597d81f249425876a40d277c3 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Mon, 15 Nov 2021 23:36:52 -0300 Subject: [PATCH 58/69] Fixed undef --- 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 2f290c3aba..7923a67395 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1906,7 +1906,7 @@ s32 CalcCritChanceStage(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbi return critChance; } -#undef BenefitsFromLeek +#undef BENEFITS_FROM_LEEK s8 GetInverseCritChance(u8 battlerAtk, u8 battlerDef, u32 move) { From c4f27174c3f138b591f582399193b80c6d1b8d33 Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Fri, 19 Nov 2021 16:21:33 +1300 Subject: [PATCH 59/69] Implement Unseen Fist Unseen Fist allows contact moves to bypass protect effects, but doesn't lift the effect. --- src/battle_util.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/battle_util.c b/src/battle_util.c index 1e29695e25..0b25f72276 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -7517,8 +7517,13 @@ bool32 IsBattlerProtected(u8 battlerId, u16 move) else if (gProtectStructs[battlerId].protected) return FALSE; } - - if (!(gBattleMoves[move].flags & FLAG_PROTECT_AFFECTED)) + + // Protective Pads doesn't stop Unseen Fist from bypassing Protect effects, so IsMoveMakingContact() isn't used here. + // This means extra logic is needed to handle Shell Side Arm. + if (GetBattlerAbility(gBattlerAttacker == ABILITY_UNSEEN_FIST) + && (gBattleMoves[move].flags & FLAG_MAKES_CONTACT || (gBattleMoves[move].effect == EFFECT_SHELL_SIDE_ARM && gSwapDamageCategory))) + return FALSE; + else if (!(gBattleMoves[move].flags & FLAG_PROTECT_AFFECTED)) return FALSE; else if (gBattleMoves[move].effect == MOVE_EFFECT_FEINT) return FALSE; From 03a9f3f41338eedd9e6555d8aeb4788aba2f5463 Mon Sep 17 00:00:00 2001 From: kleeenexfeu Date: Fri, 19 Nov 2021 22:03:10 +0100 Subject: [PATCH 60/69] Mega Evolution alters turn order --- include/constants/battle_config.h | 5 +++++ src/battle_main.c | 32 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 5e6c7d7293..cc331c3163 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -92,6 +92,11 @@ #define GEN_8 5 #endif + +// Mega Evolution settings +#define B_MEGA_EVO_ALTER_TURN_ORDER GEN_7 // In gen6, mega evolving doesn't change the turn order when mega evolving occurs. This is fixed in gen 7 + + // Calculation settings #define B_CRIT_CHANCE GEN_7 // Chances of a critical hit landing. See CalcCritChanceStage. #define B_CRIT_MULTIPLIER GEN_7 // In Gen6+, critical hits multiply damage by 1.5 instead of 2. diff --git a/src/battle_main.c b/src/battle_main.c index 5277ade1ea..f0a2ee0455 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -104,6 +104,7 @@ static void RunTurnActionsFunctions(void); static void SetActionsAndBattlersTurnOrder(void); static void sub_803CDF8(void); static bool8 AllAtActionConfirmed(void); +static void TryChangeTurnOrder(void); static void CheckFocusPunch_ClearVarsBeforeTurnStarts(void); static void CheckMegaEvolutionBeforeTurn(void); static void CheckQuickClaw_CustapBerryActivation(void); @@ -4688,10 +4689,41 @@ static void CheckMegaEvolutionBeforeTurn(void) } } + #if B_MEGA_EVO_ALTER_TURN_ORDER <= GEN_6 + gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts; + gBattleStruct->focusPunchBattlerId = 0; + #else + gBattleMainFunc = TryChangeTurnOrder; // This will just do nothing if no mon has mega evolved + #endif +} + +// In gen7, priority and speed are recalculated during the turn in which a pokemon mega evolves +static void TryChangeTurnOrder(void) +{ + s32 i, j; + for (i = 0; i < gBattlersCount - 1; i++) + { + for (j = i + 1; j < gBattlersCount; j++) + { + u8 battler1 = gBattlerByTurnOrder[i]; + u8 battler2 = gBattlerByTurnOrder[j]; + if (gActionsByTurnOrder[i] != B_ACTION_USE_ITEM + && gActionsByTurnOrder[j] != B_ACTION_USE_ITEM + && gActionsByTurnOrder[i] != 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); + } + } + } gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts; gBattleStruct->focusPunchBattlerId = 0; } + static void CheckFocusPunch_ClearVarsBeforeTurnStarts(void) { u32 i; From fa4d71817b975e1ae6514ab4582114a728d3ce94 Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Fri, 19 Nov 2021 22:30:30 +0100 Subject: [PATCH 61/69] Spaces instead of tab --- src/battle_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/battle_main.c b/src/battle_main.c index f0a2ee0455..3c000989bc 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -4717,8 +4717,8 @@ static void TryChangeTurnOrder(void) if (GetWhoStrikesFirst(battler1, battler2, FALSE)) SwapTurnOrder(i, j); } - } - } + } + } gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts; gBattleStruct->focusPunchBattlerId = 0; } From fb468b67762fd08f9021152bf7fa70216ab4d771 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 19 Nov 2021 16:32:00 -0500 Subject: [PATCH 62/69] fix unseen fist check --- 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 c37d64adcb..cc619decf8 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -7520,7 +7520,7 @@ bool32 IsBattlerProtected(u8 battlerId, u16 move) // Protective Pads doesn't stop Unseen Fist from bypassing Protect effects, so IsMoveMakingContact() isn't used here. // This means extra logic is needed to handle Shell Side Arm. - if (GetBattlerAbility(gBattlerAttacker == ABILITY_UNSEEN_FIST) + if (GetBattlerAbility(gBattlerAttacker) == ABILITY_UNSEEN_FIST && (gBattleMoves[move].flags & FLAG_MAKES_CONTACT || (gBattleMoves[move].effect == EFFECT_SHELL_SIDE_ARM && gSwapDamageCategory))) return FALSE; else if (!(gBattleMoves[move].flags & FLAG_PROTECT_AFFECTED)) From acddeeb1f92cd9e211710d28f1eef72885ff49fc Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Fri, 19 Nov 2021 23:30:33 +0100 Subject: [PATCH 63/69] follow suggestion Co-authored-by: LOuroboros --- 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 cc331c3163..13a59060ab 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -94,7 +94,7 @@ // Mega Evolution settings -#define B_MEGA_EVO_ALTER_TURN_ORDER GEN_7 // In gen6, mega evolving doesn't change the turn order when mega evolving occurs. This is fixed in gen 7 +#define B_MEGA_EVO_TURN_ORDER GEN_7 // In Gen7, a Pokémon's Speed after Mega Evolution is used to determine turn order, not its Speed before. // Calculation settings From c1743db19aa353aab5448ca3f8d4e40060b0db01 Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Fri, 19 Nov 2021 23:30:45 +0100 Subject: [PATCH 64/69] follow suggestion Co-authored-by: LOuroboros --- src/battle_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_main.c b/src/battle_main.c index 3c000989bc..3737fcc543 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -4689,7 +4689,7 @@ static void CheckMegaEvolutionBeforeTurn(void) } } - #if B_MEGA_EVO_ALTER_TURN_ORDER <= GEN_6 + #if B_MEGA_EVO_TURN_ORDER <= GEN_6 gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts; gBattleStruct->focusPunchBattlerId = 0; #else From 6402a7ab6e0b01e319ba2753563475596310effc Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Fri, 19 Nov 2021 23:42:20 +0100 Subject: [PATCH 65/69] follow suggestion Co-authored-by: LOuroboros --- include/constants/battle_config.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 13a59060ab..4ca3ae4dda 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -92,11 +92,9 @@ #define GEN_8 5 #endif - // Mega Evolution settings #define B_MEGA_EVO_TURN_ORDER GEN_7 // In Gen7, a Pokémon's Speed after Mega Evolution is used to determine turn order, not its Speed before. - // Calculation settings #define B_CRIT_CHANCE GEN_7 // Chances of a critical hit landing. See CalcCritChanceStage. #define B_CRIT_MULTIPLIER GEN_7 // In Gen6+, critical hits multiply damage by 1.5 instead of 2. From da20dae9c35f77616189c6cada31ab7d1e1166b9 Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Sat, 20 Nov 2021 02:09:33 +0100 Subject: [PATCH 66/69] Only recalculate speed for battler choosing a move Other actions have priority --- src/battle_main.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/battle_main.c b/src/battle_main.c index 3737fcc543..6caff36f50 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -4707,12 +4707,8 @@ static void TryChangeTurnOrder(void) { u8 battler1 = gBattlerByTurnOrder[i]; u8 battler2 = gBattlerByTurnOrder[j]; - if (gActionsByTurnOrder[i] != B_ACTION_USE_ITEM - && gActionsByTurnOrder[j] != B_ACTION_USE_ITEM - && gActionsByTurnOrder[i] != B_ACTION_SWITCH - && gActionsByTurnOrder[j] != B_ACTION_SWITCH - && gActionsByTurnOrder[i] != B_ACTION_THROW_BALL - && gActionsByTurnOrder[j] != B_ACTION_THROW_BALL) + if (gActionsByTurnOrder[i] = B_ACTION_USE_MOVE + && gActionsByTurnOrder[j] = B_ACTION_USE_MOVE) { if (GetWhoStrikesFirst(battler1, battler2, FALSE)) SwapTurnOrder(i, j); From 62b31aec55cf20f6b972e5e633a3dec7d92efdfe Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Sat, 20 Nov 2021 02:12:43 +0100 Subject: [PATCH 67/69] syntax --- src/battle_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/battle_main.c b/src/battle_main.c index 6caff36f50..0c7f023bba 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -4707,8 +4707,8 @@ static void TryChangeTurnOrder(void) { u8 battler1 = gBattlerByTurnOrder[i]; u8 battler2 = gBattlerByTurnOrder[j]; - if (gActionsByTurnOrder[i] = B_ACTION_USE_MOVE - && gActionsByTurnOrder[j] = B_ACTION_USE_MOVE) + if (gActionsByTurnOrder[i] == B_ACTION_USE_MOVE + && gActionsByTurnOrder[j] == B_ACTION_USE_MOVE) { if (GetWhoStrikesFirst(battler1, battler2, FALSE)) SwapTurnOrder(i, j); From 37ab20e29ca52fc6379bb54aa70da88e444e7445 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Sat, 20 Nov 2021 16:49:04 -0500 Subject: [PATCH 68/69] fix wish --- include/battle.h | 2 +- src/battle_script_commands.c | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/battle.h b/include/battle.h index b587e482db..5658f603cf 100644 --- a/include/battle.h +++ b/include/battle.h @@ -239,7 +239,7 @@ struct WishFutureKnock u8 futureSightAttacker[MAX_BATTLERS_COUNT]; u16 futureSightMove[MAX_BATTLERS_COUNT]; u8 wishCounter[MAX_BATTLERS_COUNT]; - u8 wishMonId[MAX_BATTLERS_COUNT]; + u8 wishPartyId[MAX_BATTLERS_COUNT]; u8 weatherDuration; u8 knockedOffMons[2]; // Each battler is represented by a bit. The array entry is dependent on the battler's side. }; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 7923a67395..b3e1d07145 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -12327,7 +12327,7 @@ static void Cmd_trywish(void) if (gWishFutureKnock.wishCounter[gBattlerAttacker] == 0) { gWishFutureKnock.wishCounter[gBattlerAttacker] = 2; - gWishFutureKnock.wishMonId[gBattlerAttacker] = gBattlerPartyIndexes[gBattlerAttacker]; + gWishFutureKnock.wishPartyId[gBattlerAttacker] = gBattlerPartyIndexes[gBattlerAttacker]; gBattlescriptCurrInstr += 6; } else @@ -12336,9 +12336,12 @@ static void Cmd_trywish(void) } break; case 1: // heal effect - PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattlerTarget, gWishFutureKnock.wishMonId[gBattlerTarget]) + PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattlerTarget, gWishFutureKnock.wishPartyId[gBattlerTarget]) #if B_WISH_HP_SOURCE >= GEN_5 - gBattleMoveDamage = max(1, gBattleMons[gWishFutureKnock.wishMonId[gBattlerTarget]].maxHP / 2); + if (GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER) + gBattleMoveDamage = max(1, GetMonData(&gPlayerParty[gWishFutureKnock.wishPartyId[gBattlerTarget]], MON_DATA_MAX_HP) / 2); + else + gBattleMoveDamage = max(1, GetMonData(&gEnemyParty[gWishFutureKnock.wishPartyId[gBattlerTarget]], MON_DATA_MAX_HP) / 2); #else gBattleMoveDamage = max(1, gBattleMons[gBattlerTarget].maxHP / 2); #endif From 3fb62f74c6f029123f8e9d4a39d0459fd4c42aff Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Sat, 20 Nov 2021 18:35:56 -0500 Subject: [PATCH 69/69] fix rampage cancelling --- include/constants/battle_config.h | 1 + src/battle_script_commands.c | 8 ++++++++ src/battle_util.c | 1 + 3 files changed, 10 insertions(+) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 5e6c7d7293..0831b93a34 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -156,6 +156,7 @@ #define B_SKILL_SWAP GEN_7 // In Gen4+, Skill Swap triggers switch-in abilities after use. #define B_BRICK_BREAK GEN_7 // In Gen4+, you can destroy your own side's screens. In Gen 5+, screens are not removed if the target is immune. #define B_WISH_HP_SOURCE GEN_7 // In Gen5+, Wish heals half of the user's max HP instead of the target's. +#define B_RAMPAGE_CANCELLING GEN_7 // In Gen5+, a failed Thrash, etc, will cancel except on its last turn. // 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_script_commands.c b/src/battle_script_commands.c index 7923a67395..0f2fdfe84a 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -5466,6 +5466,14 @@ static void Cmd_moveend(void) *(gBattleStruct->moveTarget + gBattlerAttacker) = gSpecialStatuses[gBattlerAttacker].instructedChosenTarget & 0x3; if (gSpecialStatuses[gBattlerAttacker].dancerOriginalTarget) *(gBattleStruct->moveTarget + gBattlerAttacker) = gSpecialStatuses[gBattlerAttacker].dancerOriginalTarget & 0x3; + + #if B_RAMPAGE_CANCELLING >= GEN_5 + if (gBattleMoves[gCurrentMove].effect == EFFECT_RAMPAGE // If we're rampaging + && (gMoveResultFlags & MOVE_RESULT_NO_EFFECT) // And it is unusable + && (gBattleMons[gBattlerAttacker].status2 & STATUS2_LOCK_CONFUSE) != STATUS2_LOCK_CONFUSE_TURN(1)) // And won't end this turn + CancelMultiTurnMoves(gBattlerAttacker); // Cancel it + #endif + gProtectStructs[gBattlerAttacker].usesBouncedMove = FALSE; gProtectStructs[gBattlerAttacker].targetAffected = FALSE; gBattleStruct->ateBoost[gBattlerAttacker] = 0; diff --git a/src/battle_util.c b/src/battle_util.c index cc619decf8..7e2320500c 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2795,6 +2795,7 @@ u8 DoBattlerEndTurnEffects(void) case ENDTURN_FLINCH: // reset flinch gBattleMons[gActiveBattler].status2 &= ~(STATUS2_FLINCHED); gBattleStruct->turnEffectsTracker++; + break; case ENDTURN_DISABLE: // disable if (gDisableStructs[gActiveBattler].disableTimer != 0) {