From ce4375a10cade942f39cd93e7ee880aa50175ad1 Mon Sep 17 00:00:00 2001 From: ultima-soul Date: Wed, 6 Oct 2021 10:22:17 -0700 Subject: [PATCH 01/12] Ported new Ball catch rate modifier effects from Item Expansion. --- include/constants/battle_config.h | 10 ++ include/wild_encounter.h | 2 + src/battle_main.c | 3 + src/battle_script_commands.c | 239 ++++++++++++++++++++++++------ src/wild_encounter.c | 4 + 5 files changed, 212 insertions(+), 46 deletions(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 93202bed7..946080137 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -140,6 +140,16 @@ #define B_BERRIES_INSTANT GEN_7 // In Gen4+, most berries activate on battle start/switch-in if applicable. In Gen3, they only activate either at the move end or turn end. #define B_X_ITEMS_BUFF GEN_7 // In Gen7+, the X Items raise a stat by 2 stages instead of 1. #define B_MENTAL_HERB GEN_5 // In Gen5+, the Mental Herb cures Infatuation, Taunt, Encore, Torment, Heal Block, and Disable +#define B_NET_BALL_MODIFIER GEN_7 // In Gen7+, Net Ball's catch multiplier is x5 instead of x3. +#define B_DIVE_BALL_MODIFIER GEN_7 // In Gen4+, Dive Ball's effectiveness increases by when Surfing or Fishing. +#define B_NEST_BALL_MODIFIER GEN_7 // Nest Ball's formula varies depending on the Gen. See Cmd_handleballthrow. +#define B_REPEAT_BALL_MODIFIER GEN_7 // In Gen7+, Repeat Ball's catch multiplier is x3.5 instead of x3. +#define B_TIMER_BALL_MODIFIER GEN_7 // In Gen5+, Timer Ball's effectiveness increases by x0.3 per turn instead of x0.1 +#define B_DUSK_BALL_MODIFIER GEN_7 // In Gen7+, Dusk Ball's catch multiplier is x3 instead of x3.5. +#define B_QUICK_BALL_MODIFIER GEN_7 // In Gen5+, Quick Ball's catch multiplier is x5 instead of x4. +#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. // Flag settings // To use the following features in scripting, replace the 0s with the flag ID you're assigning it to. diff --git a/include/wild_encounter.h b/include/wild_encounter.h index 200243170..5f4fcf536 100644 --- a/include/wild_encounter.h +++ b/include/wild_encounter.h @@ -30,6 +30,8 @@ struct WildPokemonHeader }; extern const struct WildPokemonHeader gWildMonHeaders[]; +extern bool8 gIsFishingEncounter; +extern bool8 gIsSurfingEncounter; void DisableWildEncounters(bool8 disabled); bool8 StandardWildEncounter(u16 currMetaTileBehavior, u16 previousMetaTileBehavior); diff --git a/src/battle_main.c b/src/battle_main.c index 25db65f78..62e31b8e1 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -49,6 +49,7 @@ #include "trig.h" #include "tv.h" #include "util.h" +#include "wild_encounter.h" #include "window.h" #include "constants/abilities.h" #include "constants/battle_config.h" @@ -4925,6 +4926,8 @@ static void FreeResetData_ReturnToOvOrDoEvolutions(void) { if (!gPaletteFade.active) { + gIsFishingEncounter = FALSE; + gIsSurfingEncounter = FALSE; ResetSpriteData(); if (gLeveledUpInBattle && (gBattleOutcome == B_OUTCOME_WON || gBattleOutcome == B_OUTCOME_CAUGHT)) { diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 8d6dd5bdb..6def00fed 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -42,6 +42,8 @@ #include "constants/battle_string_ids.h" #include "battle_setup.h" #include "overworld.h" +#include "wild_encounter.h" +#include "rtc.h" #include "party_menu.h" #include "constants/battle_config.h" #include "battle_arena.h" @@ -56,6 +58,7 @@ #include "constants/party_menu.h" extern struct MusicPlayerInfo gMPlayInfo_BGM; +extern struct Evolution gEvolutionTable[][EVOS_PER_MON]; extern const u8* const gBattleScriptsForMoveEffects[]; @@ -1160,15 +1163,6 @@ static const u8 sTerrainToType[] = [BATTLE_TERRAIN_PLAIN] = TYPE_NORMAL, }; -// - ITEM_ULTRA_BALL skips Master Ball and ITEM_NONE -static const u8 sBallCatchBonuses[] = -{ - [ITEM_ULTRA_BALL - ITEM_ULTRA_BALL] = 20, - [ITEM_GREAT_BALL - ITEM_ULTRA_BALL] = 15, - [ITEM_POKE_BALL - ITEM_ULTRA_BALL] = 10, - [ITEM_SAFARI_BALL - ITEM_ULTRA_BALL] = 15 -}; - // In Battle Palace, moves are chosen based on the pokemons nature rather than by the player // Moves are grouped into "Attack", "Defense", or "Support" (see PALACE_MOVE_GROUP_*) // Each nature has a certain percent chance of selecting a move from a particular group @@ -12406,7 +12400,8 @@ static u8 GetCatchingBattler(void) static void Cmd_handleballthrow(void) { - u8 ballMultiplier = 0; + u8 ballMultiplier = 10; + s8 ballAddition = 0; if (gBattleControllerExecFlags) return; @@ -12428,7 +12423,7 @@ static void Cmd_handleballthrow(void) } else { - u32 odds; + u32 odds, i; u8 catchRate; if (gLastUsedItem == ITEM_SAFARI_BALL) @@ -12436,53 +12431,193 @@ static void Cmd_handleballthrow(void) else catchRate = gBaseStats[gBattleMons[gBattlerTarget].species].catchRate; - if (gLastUsedItem > ITEM_SAFARI_BALL) + #ifdef POKEMON_EXPANSION + if (gBaseStats[gBattleMons[gBattlerTarget].species].flags & F_ULTRA_BEAST) { - switch (gLastUsedItem) - { - case ITEM_NET_BALL: - if (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_WATER) || IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_BUG)) + if (gLastUsedItem == ITEM_BEAST_BALL) + ballMultiplier = 50; + else + ballMultiplier = 1; + } + else + { + #endif + + switch (gLastUsedItem) + { + case ITEM_ULTRA_BALL: + ballMultiplier = 20; + case ITEM_GREAT_BALL: + case ITEM_SAFARI_BALL: + #ifdef ITEM_EXPANSION + case ITEM_SPORT_BALL: + #endif + ballMultiplier = 15; + case ITEM_NET_BALL: + if (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_WATER) || IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_BUG)) + #if B_NET_BALL_MODIFIER >= GEN_7 + ballMultiplier = 50; + #else ballMultiplier = 30; - else - ballMultiplier = 10; - break; - case ITEM_DIVE_BALL: + #endif + break; + case ITEM_DIVE_BALL: + #if B_DIVE_BALL_MODIFIER >= GEN_4 + if (GetCurrentMapType() == MAP_TYPE_UNDERWATER || gIsFishingEncounter || gIsSurfingEncounter) + ballMultiplier = 35; + #else if (GetCurrentMapType() == MAP_TYPE_UNDERWATER) ballMultiplier = 35; - else - ballMultiplier = 10; - break; - case ITEM_NEST_BALL: + #endif + break; + case ITEM_NEST_BALL: + #if B_NEST_BALL_MODIFIER >= GEN_6 + //((41 - Pokémon's level) ÷ 10)× if Pokémon's level is between 1 and 29, 1× otherwise. + if (gBattleMons[gBattlerTarget].level < 30) + ballMultiplier = 41 - gBattleMons[gBattlerTarget].level; + #elif B_NEST_BALL_MODIFIER == GEN_5 + //((41 - Pokémon's level) ÷ 10)×, minimum 1× + if (gBattleMons[gBattlerTarget].level < 31) + ballMultiplier = 41 - gBattleMons[gBattlerTarget].level; + #else + //((40 - Pokémon's level) ÷ 10)×, minimum 1× if (gBattleMons[gBattlerTarget].level < 40) { ballMultiplier = 40 - gBattleMons[gBattlerTarget].level; if (ballMultiplier <= 9) ballMultiplier = 10; } - else - { - ballMultiplier = 10; - } - break; - case ITEM_REPEAT_BALL: - if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gBattlerTarget].species), FLAG_GET_CAUGHT)) + #endif + break; + case ITEM_REPEAT_BALL: + if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gBattlerTarget].species), FLAG_GET_CAUGHT)) + #if B_REPEAT_BALL_MODIFIER >= GEN_7 + ballMultiplier = 35; + #else ballMultiplier = 30; - else - ballMultiplier = 10; - break; - case ITEM_TIMER_BALL: + #endif + break; + case ITEM_TIMER_BALL: + #if B_TIMER_BALL_MODIFIER >= GEN_5 + ballMultiplier = (gBattleResults.battleTurnCounter * 3) + 10; + #else ballMultiplier = gBattleResults.battleTurnCounter + 10; - if (ballMultiplier > 40) + #endif + if (ballMultiplier > 40) + ballMultiplier = 40; + break; + #ifdef ITEM_EXPANSION + case ITEM_DUSK_BALL: + RtcCalcLocalTime(); + if ((gLocalTime.hours >= 20 && gLocalTime.hours <= 3) || gMapHeader.cave || gMapHeader.mapType == MAP_TYPE_UNDERGROUND) + #if B_DUSK_BALL_MODIFIER >= GEN_7 + ballMultiplier = 30; + #else + ballMultiplier = 35; + #endif + break; + case ITEM_QUICK_BALL: + if (gBattleResults.battleTurnCounter == 0) + #if B_QUICK_BALL_MODIFIER >= GEN_5 + ballMultiplier = 50; + #else + ballMultiplier = 40; + #endif + break; + case ITEM_LEVEL_BALL: + if (gBattleMons[gBattlerAttacker].level >= 4 * gBattleMons[gBattlerTarget].level) + ballMultiplier = 80; + else if (gBattleMons[gBattlerAttacker].level > 2 * gBattleMons[gBattlerTarget].level) + ballMultiplier = 40; + else if (gBattleMons[gBattlerAttacker].level > gBattleMons[gBattlerTarget].level) + ballMultiplier = 20; + break; + case ITEM_LURE_BALL: + if (gIsFishingEncounter) + #if B_LURE_BALL_MODIFIER >= GEN_7 + ballMultiplier = 50; + #else + ballMultiplier = 30; + #endif + break; + case ITEM_MOON_BALL: + for (i = 0; i < EVOS_PER_MON; i++) + { + if (gEvolutionTable[gBattleMons[gBattlerTarget].species][i].method == EVO_ITEM + && gEvolutionTable[gBattleMons[gBattlerTarget].species][i].param == ITEM_MOON_STONE) ballMultiplier = 40; - break; - case ITEM_LUXURY_BALL: - case ITEM_PREMIER_BALL: - ballMultiplier = 10; - break; } + break; + case ITEM_LOVE_BALL: + if (gBattleMons[gBattlerTarget].species == gBattleMons[gBattlerAttacker].species) + { + u8 gender1 = GetMonGender(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]]); + u8 gender2 = GetMonGender(&gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]]); + + if (gender1 != gender2 && gender1 != MON_GENDERLESS && gender2 != MON_GENDERLESS) + ballMultiplier = 80; + } + break; + case ITEM_FAST_BALL: + if (gBaseStats[gBattleMons[gBattlerTarget].species].baseSpeed >= 100) + ballMultiplier = 40; + break; + case ITEM_HEAVY_BALL: + i = GetPokedexHeightWeight(SpeciesToNationalPokedexNum(gBattleMons[gBattlerTarget].species), 1); + #if B_HEAVY_BALL_MODIFIER >= GEN_7 + if (i < 1000) + ballAddition = -20; + else if (i < 2000) + ballAddition = 0; + else if (i < 3000) + ballAddition = 20; + else + ballAddition = 30; + #elif B_HEAVY_BALL_MODIFIER >= GEN_4 + if (i < 2048) + ballAddition = -20; + else if (i < 3072) + ballAddition = 20; + else if (i < 4096) + ballAddition = 30; + else + ballAddition = 40; + #else + if (i < 1024) + ballAddition = -20; + else if (i < 2048) + ballAddition = 0; + else if (i < 3072) + ballAddition = 20; + else if (i < 4096) + ballAddition = 30; + else + ballAddition = 40; + #endif + break; + case ITEM_DREAM_BALL: + #if B_DREAM_BALL_MODIFIER >= GEN_8 + if (gBattleMons[gBattlerTarget].status1 & STATUS1_SLEEP || GetBattlerAbility(gBattlerTarget) == ABILITY_COMATOSE) + ballMultiplier = 40; + #else + ballMultiplier = 10; + #endif + break; + case ITEM_BEAST_BALL: + ballMultiplier = 1; + break; + #endif } + + #ifdef POKEMON_EXPANSION + } + #endif + + // catchRate is unsigned, which means that it may potentially overflow if sum is applied directly. + if (catchRate < 21 && ballAddition == -20) + catchRate = 1; else - ballMultiplier = sBallCatchBonuses[gLastUsedItem - ITEM_ULTRA_BALL]; + catchRate = catchRate + ballAddition; odds = (catchRate * ballMultiplier / 10) * (gBattleMons[gBattlerTarget].maxHP * 3 - gBattleMons[gBattlerTarget].hp * 2) @@ -12524,16 +12659,17 @@ static void Cmd_handleballthrow(void) u8 shakes; u8 maxShakes; - gBattleSpritesDataPtr->animationData->isCriticalCapture = 0; //initialize + gBattleSpritesDataPtr->animationData->isCriticalCapture = 0; gBattleSpritesDataPtr->animationData->criticalCaptureSuccess = 0; + if (CriticalCapture(odds)) { - maxShakes = 1; //critical capture doesn't gauarantee capture + maxShakes = BALL_1_SHAKE; // critical capture doesn't guarantee capture gBattleSpritesDataPtr->animationData->isCriticalCapture = 1; } else { - maxShakes = 4; + maxShakes = BALL_3_SHAKES_SUCCESS; } if (gLastUsedItem == ITEM_MASTER_BALL) @@ -12558,10 +12694,21 @@ static void Cmd_handleballthrow(void) UndoFormChange(gBattlerPartyIndexes[gBattlerTarget], GET_BATTLER_SIDE(gBattlerTarget), FALSE); gBattlescriptCurrInstr = BattleScript_SuccessBallThrow; SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_POKEBALL, &gLastUsedItem); + if (CalculatePlayerPartyCount() == PARTY_SIZE) gBattleCommunication[MULTISTRING_CHOOSER] = 0; else gBattleCommunication[MULTISTRING_CHOOSER] = 1; + + #ifdef ITEM_EXPANSION + if (gLastUsedItem == ITEM_HEAL_BALL) + { + MonRestorePP(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]]); + HealStatusConditions(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], gBattlerPartyIndexes[gBattlerTarget], STATUS1_ANY, gBattlerTarget); + gBattleMons[gBattlerTarget].hp = gBattleMons[gBattlerTarget].maxHP; + SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_HP, &gBattleMons[gBattlerTarget].hp); + } + #endif } else // not caught { @@ -12569,7 +12716,7 @@ static void Cmd_handleballthrow(void) gLastUsedBall = gLastUsedItem; if (IsCriticalCapture()) - gBattleCommunication[MULTISTRING_CHOOSER] = shakes + 3; + gBattleCommunication[MULTISTRING_CHOOSER] = BALL_3_SHAKES_FAIL; else gBattleCommunication[MULTISTRING_CHOOSER] = shakes; diff --git a/src/wild_encounter.c b/src/wild_encounter.c index 330a0014b..ef0d57247 100644 --- a/src/wild_encounter.c +++ b/src/wild_encounter.c @@ -41,6 +41,8 @@ static bool8 IsAbilityAllowingEncounter(u8 level); // EWRAM vars EWRAM_DATA static u8 sWildEncountersDisabled = 0; EWRAM_DATA static u32 sFeebasRngValue = 0; +EWRAM_DATA bool8 gIsFishingEncounter = 0; +EWRAM_DATA bool8 gIsSurfingEncounter = 0; #include "data/wild_encounters.h" @@ -652,6 +654,7 @@ bool8 StandardWildEncounter(u16 currMetaTileBehavior, u16 previousMetaTileBehavi { if (TryGenerateWildMon(gWildMonHeaders[headerId].waterMonsInfo, WILD_AREA_WATER, WILD_CHECK_REPEL | WILD_CHECK_KEEN_EYE) == TRUE) { + gIsSurfingEncounter = TRUE; if (TryDoDoubleWildBattle()) { struct Pokemon mon1 = gEnemyParty[0]; @@ -803,6 +806,7 @@ void FishingWildEncounter(u8 rod) } IncrementGameStat(GAME_STAT_FISHING_CAPTURES); SetPokemonAnglerSpecies(species); + gIsFishingEncounter = TRUE; BattleSetup_StartWildBattle(); } From 28e78cb6c4b1b4214b4a6dbb38a7ddfb96304b56 Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Thu, 4 Nov 2021 19:50:54 +1300 Subject: [PATCH 02/12] Gen 8 moves initial commit Full credit to Nunuchu42 and cfmnephrite for this code. --- asm/macros/battle_script.inc | 30 ++++++ data/battle_scripts_1.s | 111 ++++++++++++++++++++- include/battle.h | 3 + include/battle_scripts.h | 2 + include/constants/battle.h | 3 +- include/constants/battle_move_effects.h | 9 +- include/constants/battle_script_commands.h | 5 + include/constants/battle_string_ids.h | 9 +- src/battle_message.c | 14 ++- src/battle_script_commands.c | 94 ++++++++++++++++- src/battle_util.c | 19 ++++ src/data/battle_moves.h | 16 +-- 12 files changed, 298 insertions(+), 17 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 328780f53..aadae8766 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1878,6 +1878,36 @@ .4byte \ptr .endm + .macro trynoretreat battler:req, ptr:req + various \battler, VARIOUS_TRY_NO_RETREAT + .4byte \ptr + .endm + + .macro trytarshot battler:req, ptr:req + various \battler, VARIOUS_TRY_TAR_SHOT + .4byte \ptr + .endm + + .macro trynextdart ptr:req + various BS_ATTACKER, VARIOUS_TRY_NEXT_DART + .4byte \ptr + .endm + + .macro checkpoltergeist battler:req, ptr:req + various \battler, VARIOUS_CHECK_POLTERGEIST + .4byte \ptr + .endm + + .macro setoctolock battler:req, ptr:req + various \battler, VARIOUS_SET_OCTOLOCK + .4byte \ptr + .endm + + .macro cutonethirdhpraisestats ptr:req + various BS_ATTACKER, VARIOUS_CUT_1_3_HP_RAISE_STATS + .4byte \ptr + .endm + @ helpful macros .macro setstatchanger stat:req, stages:req, down:req setbyte sSTATCHANGER \stat | \stages << 3 | \down << 7 diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 6d6c1dae8..bb648c225 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -392,6 +392,115 @@ gBattleScriptsForMoveEffects:: .4byte BattleScript_EffectSparklySwirl @ EFFECT_SPARKLY_SWIRL .4byte BattleScript_EffectPlasmaFists @ EFFECT_PLASMA_FISTS .4byte BattleScript_EffectHyperspaceFury @ EFFECT_HYPERSPACE_FURY + .4byte BattleScript_EffectJawLock @ EFFECT_JAW_LOCK + .4byte BattleScript_EffectNoRetreat @ EFFECT_NO_RETREAT + .4byte BattleScript_EffectTarShot @ EFFECT_TAR_SHOT + .4byte BattleScript_EffectPoltergeist @ EFFECT_POLTERGEIST + .4byte BattleScript_EffectOctolock @ EFFECT_OCTOLOCK + .4byte BattleScript_EffectClangorousSoul @ EFFECT_CLANGOROUS_SOUL + .4byte BattleScript_EffectHit @ EFFECT_BOLT_BEAK + +BattleScript_EffectClangorousSoul: + attackcanceler + attackstring + ppreduce + cutonethirdhpraisestats BattleScript_ButItFailed + orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE + attackanimation + waitanimation + healthbarupdate BS_ATTACKER + datahpupdate BS_ATTACKER + call BattleScript_AllStatsUp + goto BattleScript_MoveEnd + +BattleScript_EffectOctolock: + attackcanceler + jumpifsubstituteblocks BattleScript_ButItFailedAtkStringPpReduce + accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE + attackstring + ppreduce + setoctolock BS_TARGET, BattleScript_ButItFailed + attackanimation + waitanimation + printstring STRINGID_CANTESCAPEBECAUSEOFCURRENTMOVE + waitmessage 0x40 + goto BattleScript_MoveEnd + +BattleScript_OctolockEndTurn:: + playanimation BS_ATTACKER, B_ANIM_TURN_TRAP, 0 + jumpifstat BS_TARGET, CMP_GREATER_THAN, STAT_DEF, MIN_STAT_STAGE, BattleScript_OctolockLowerDef + jumpifstat BS_TARGET, CMP_GREATER_THAN, STAT_SPDEF, MIN_STAT_STAGE, BattleScript_OctolockTryLowerSpDef + goto BattleScript_OctolockEnd2 +BattleScript_OctolockLowerDef: + playstatchangeanimation BS_ATTACKER, BIT_SPATK | BIT_SPDEF, STAT_CHANGE_NEGATIVE + jumpifability BS_TARGET, ABILITY_BIG_PECKS, BattleScript_OctolockTryLowerSpDef + setstatchanger STAT_DEF, 1, TRUE + statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_ALLOW_PTR, BattleScript_OctolockTryLowerSpDef + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 0x2, BattleScript_OctolockTryLowerSpDef + printfromtable gStatUpStringIds + waitmessage 0x40 +BattleScript_OctolockTryLowerSpDef:: + setstatchanger STAT_SPDEF, 1, TRUE + statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_ALLOW_PTR, BattleScript_OctolockEnd2 + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 0x2, BattleScript_OctolockEnd2 + printfromtable gStatUpStringIds + waitmessage 0x40 +BattleScript_OctolockEnd2:: + end2 + +BattleScript_EffectPoltergeist: + attackcanceler + attackstring + ppreduce + checkpoltergeist BS_TARGET, BattleScript_ButItFailed + printstring STRINGID_ABOUTTOUSEPOLTERGEIST + waitmessage 0x40 + goto BattleScript_HitFromCritCalc + +BattleScript_EffectTarShot: + attackcanceler + jumpifsubstituteblocks BattleScript_ButItFailedAtkStringPpReduce + accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE + attackstring + ppreduce + setstatchanger STAT_SPEED, 1, TRUE + attackanimation + waitanimation + statbuffchange STAT_BUFF_ALLOW_PTR, BattleScript_TryTarShot + setgraphicalstatchangevalues + playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 + printfromtable gStatDownStringIds + waitmessage 0x40 +BattleScript_TryTarShot: + trytarshot BS_TARGET, BattleScript_MoveEnd + printstring STRINGID_PKMNBECAMEWEAKERTOFIRE + waitmessage 0x40 + goto BattleScript_MoveEnd + +BattleScript_EffectNoRetreat: + attackcanceler + accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE + attackstring + ppreduce + trynoretreat BS_TARGET, BattleScript_ButItFailed + attackanimation + waitanimation + call BattleScript_AllStatsUp + jumpifstatus2 BS_TARGET, STATUS2_ESCAPE_PREVENTION, BattleScript_MoveEnd + setmoveeffect MOVE_EFFECT_PREVENT_ESCAPE + seteffectprimary + printstring STRINGID_CANTESCAPEDUETOUSEDMOVE + waitmessage 0x40 + goto BattleScript_MoveEnd + +BattleScript_EffectJawLock: + setmoveeffect MOVE_EFFECT_TRAP_BOTH | MOVE_EFFECT_CERTAIN + goto BattleScript_EffectHit + +BattleScript_BothCanNoLongerEscape:: + printstring STRINGID_BOTHCANNOLONGERESCAPE + waitmessage 0x40 + return BattleScript_EffectHyperspaceFury: jumpifspecies BS_ATTACKER, SPECIES_TREECKO, BattleScript_EffectHyperspaceFuryUnbound @@ -1707,7 +1816,7 @@ BattleScript_EffectSoak: attackanimation waitanimation trysoak BattleScript_ButItFailed - printstring STRINGID_TRANSFORMEDINTOWATERTYPE + printstring STRINGID_TARGETCHANGEDTYPE waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd diff --git a/include/battle.h b/include/battle.h index cb99cc44f..a6ef91a93 100644 --- a/include/battle.h +++ b/include/battle.h @@ -112,6 +112,9 @@ struct DisableStruct u8 throatChopTimer; u8 usedMoves:4; u8 wrapTurns; + u8 noRetreat:1; + u8 tarShot:1; + u8 octolock:1; }; struct ProtectStruct diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 12212ff94..09506e87e 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -407,5 +407,7 @@ extern const u8 BattleScript_WanderingSpiritActivates[]; extern const u8 BattleScript_MirrorArmorReflect[]; extern const u8 BattleScript_GooeyActivates[]; extern const u8 BattleScript_PastelVeilActivates[]; +extern const u8 BattleScript_BothCanNoLongerEscape[]; +extern const u8 BattleScript_OctolockEndTurn[]; #endif // GUARD_BATTLE_SCRIPTS_H diff --git a/include/constants/battle.h b/include/constants/battle.h index 918c3e7f0..9b6880a94 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -357,7 +357,8 @@ #define MOVE_EFFECT_INCINERATE 0x44 #define MOVE_EFFECT_BUG_BITE 0x45 #define MOVE_EFFECT_RECOIL_HP_25 0x46 -#define NUM_MOVE_EFFECTS 0x47 +#define MOVE_EFFECT_TRAP_BOTH 0x47 +#define NUM_MOVE_EFFECTS 0x48 #define MOVE_EFFECT_AFFECTS_USER 0x4000 #define MOVE_EFFECT_CERTAIN 0x8000 diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index 62b49a191..d50546d94 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -375,7 +375,14 @@ #define EFFECT_SPARKLY_SWIRL 369 #define EFFECT_PLASMA_FISTS 370 #define EFFECT_HYPERSPACE_FURY 371 +#define EFFECT_JAW_LOCK 372 +#define EFFECT_NO_RETREAT 373 +#define EFFECT_TAR_SHOT 374 +#define EFFECT_POLTERGEIST 375 +#define EFFECT_OCTOLOCK 376 +#define EFFECT_CLANGOROUS_SOUL 377 +#define EFFECT_BOLT_BEAK 378 -#define NUM_BATTLE_MOVE_EFFECTS 372 +#define NUM_BATTLE_MOVE_EFFECTS 379 #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 3b4495208..cc67ef2e3 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -198,6 +198,11 @@ #define VARIOUS_JUMP_IF_WEATHER_AFFECTED 125 #define VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED 126 #define VARIOUS_SET_ATTACKER_STICKY_WEB_USER 127 +#define VARIOUS_TRY_NO_RETREAT 128 +#define VARIOUS_TRY_TAR_SHOT 129 +#define VARIOUS_CHECK_POLTERGEIST 130 +#define VARIOUS_SET_OCTOLOCK 131 +#define VARIOUS_CUT_1_3_HP_RAISE_STATS 132 // Cmd_manipulatedamage #define DMG_CHANGE_SIGN 0 diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 3eb5dc9a4..0a735c4c3 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -420,7 +420,7 @@ #define STRINGID_HURLEDINTOTHEAIR 416 #define STRINGID_HELDITEMSLOSEEFFECTS 417 #define STRINGID_FELLSTRAIGHTDOWN 418 -#define STRINGID_TRANSFORMEDINTOWATERTYPE 419 +#define STRINGID_TARGETCHANGEDTYPE 419 #define STRINGID_PKMNACQUIREDSIMPLE 420 #define STRINGID_EMPTYSTRING5 421 #define STRINGID_KINDOFFER 422 @@ -601,8 +601,13 @@ #define STRINGID_SWAPPEDABILITIES 598 #define STRINGID_PASTELVEILPROTECTED 599 #define STRINGID_PASTELVEILENTERS 600 +#define STRINGID_BOTHCANNOLONGERESCAPE 601 +#define STRINGID_CANTESCAPEDUETOUSEDMOVE 602 +#define STRINGID_PKMNBECAMEWEAKERTOFIRE 603 +#define STRINGID_ABOUTTOUSEPOLTERGEIST 604 +#define STRINGID_CANTESCAPEBECAUSEOFCURRENTMOVE 605 -#define BATTLESTRINGS_COUNT 601 +#define BATTLESTRINGS_COUNT 606 // The below IDs are all indexes into battle message tables, // used to determine which of a set of messages to print. diff --git a/src/battle_message.c b/src/battle_message.c index a1a24b3b1..63890dc41 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -549,7 +549,7 @@ static const u8 sText_BecameNimble[] =_("{B_ATK_NAME_WITH_PREFIX} became nimble! static const u8 sText_HurledIntoTheAir[] =_("{B_DEF_NAME_WITH_PREFIX} was hurled\ninto the air!"); static const u8 sText_HeldItemsLoseEffects[] =_("It created a bizarre area in which\nPokémon's held items lose their effects!"); static const u8 sText_FellStraightDown[] =_("{B_DEF_NAME_WITH_PREFIX} fell\nstraight down!"); -static const u8 sText_TransformedIntoWaterType[] =_("{B_DEF_NAME_WITH_PREFIX} transformed\ninto the water type!"); +static const u8 sText_TargetChangedType[] =_("{B_DEF_NAME_WITH_PREFIX} transformed\ninto the {B_BUFF1} type!"); static const u8 sText_PkmnAcquiredSimple[] =_("{B_DEF_NAME_WITH_PREFIX} acquired\nSimple!"); static const u8 sText_KindOffer[] =_("{B_DEF_NAME_WITH_PREFIX}\ntook the kind offer!"); static const u8 sText_ResetsTargetsStatLevels[] =_("{B_DEF_NAME_WITH_PREFIX}'s stat changes\nwere removed!"); @@ -727,6 +727,11 @@ static const u8 sText_AbilityAllowsOnlyMove[] = _("{B_ATK_ABILITY} allows the\nu static const u8 sText_SwappedAbilities[] = _("{B_DEF_NAME_WITH_PREFIX} swapped Abilities\nwith its target!"); static const u8 sText_PastelVeilProtected[] = _("{B_DEF_NAME_WITH_PREFIX} is protected\nby a pastel veil!"); static const u8 sText_PastelVeilEnters[] = _("{B_DEF_NAME_WITH_PREFIX} was cured\nof its poisoning!"); +static const u8 sText_BothCanNoLongerEscape[] = _("Neither POKéMON can run away!"); +static const u8 sText_CantEscapeDueToUsedMove[] = _("{B_ATK_NAME_WITH_PREFIX} can no longer escape\nbecause it used {B_CURRENT_MOVE}!"); +static const u8 sText_PkmnBecameWeakerToFire[] = _("{B_DEF_NAME_WITH_PREFIX} became\nweaker to fire!"); +static const u8 sText_PkmnAboutToBeAttackedByItsItem[] = _("{B_DEF_NAME_WITH_PREFIX} is about\nto be attacked by its {B_BUFF1}!"); +static const u8 sText_CantEscapeBecauseOfCurrentMove[] = _("{B_DEF_NAME_WITH_PREFIX} can no longer escape\nbecause of {B_CURRENT_MOVE}!"); const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = { @@ -1208,7 +1213,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_HURLEDINTOTHEAIR - 12] = sText_HurledIntoTheAir, [STRINGID_HELDITEMSLOSEEFFECTS - 12] = sText_HeldItemsLoseEffects, [STRINGID_FELLSTRAIGHTDOWN - 12] = sText_FellStraightDown, - [STRINGID_TRANSFORMEDINTOWATERTYPE - 12] = sText_TransformedIntoWaterType, + [STRINGID_TARGETCHANGEDTYPE - 12] = sText_TargetChangedType, [STRINGID_PKMNACQUIREDSIMPLE - 12] = sText_PkmnAcquiredSimple, [STRINGID_EMPTYSTRING5 - 12] = sText_EmptyString4, [STRINGID_KINDOFFER - 12] = sText_KindOffer, @@ -1318,6 +1323,11 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_AURABREAKENTERS - 12] = sText_AuraBreakActivates, [STRINGID_COMATOSEENTERS - 12] = sText_ComatoseActivates, [STRINGID_SCREENCLEANERENTERS - 12] = sText_ScreenCleanerActivates, + [STRINGID_BOTHCANNOLONGERESCAPE - 12] = sText_BothCanNoLongerEscape, + [STRINGID_CANTESCAPEDUETOUSEDMOVE - 12] = sText_CantEscapeDueToUsedMove, + [STRINGID_PKMNBECAMEWEAKERTOFIRE - 12] = sText_PkmnBecameWeakerToFire, + [STRINGID_ABOUTTOUSEPOLTERGEIST - 12] = sText_PkmnAboutToBeAttackedByItsItem, + [STRINGID_CANTESCAPEBECAUSEOFCURRENTMOVE - 12] = sText_CantEscapeBecauseOfCurrentMove, }; const u16 gMentalHerbCureStringIds[] = diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index ee9379d8d..eddde6b44 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3399,6 +3399,21 @@ void SetMoveEffect(bool32 primary, u32 certain) gBattlescriptCurrInstr = BattleScript_MoveEffectBugBite; } break; + case MOVE_EFFECT_TRAP_BOTH: + if (!(gBattleMons[gBattlerTarget].status2 & STATUS2_ESCAPE_PREVENTION) && !(gBattleMons[gBattlerAttacker].status2 & STATUS2_ESCAPE_PREVENTION)) + { + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_BothCanNoLongerEscape; + } + if (!gBattleMons[gBattlerTarget].status2 & STATUS2_ESCAPE_PREVENTION) + gDisableStructs[gBattlerTarget].battlerPreventingEscape = gBattlerAttacker; + + if (!(gBattleMons[gBattlerAttacker].status2 & STATUS2_ESCAPE_PREVENTION)) + gDisableStructs[gBattlerAttacker].battlerPreventingEscape = gBattlerTarget; + + gBattleMons[gBattlerTarget].status2 |= STATUS2_ESCAPE_PREVENTION; + gBattleMons[gBattlerAttacker].status2 |= STATUS2_ESCAPE_PREVENTION; + break; } } } @@ -8154,13 +8169,15 @@ static void Cmd_various(void) } return; case VARIOUS_TRY_SOAK: - if (gBattleMons[gBattlerTarget].type1 == TYPE_WATER && gBattleMons[gBattlerTarget].type2 == TYPE_WATER) + if (gBattleMons[gBattlerTarget].type1 == gBattleMoves[gCurrentMove].type + && gBattleMons[gBattlerTarget].type2 == gBattleMoves[gCurrentMove].type) { gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); } else { - SET_BATTLER_TYPE(gBattlerTarget, TYPE_WATER); + SET_BATTLER_TYPE(gBattlerTarget, gBattleMoves[gCurrentMove].type); + PREPARE_TYPE_BUFFER(gBattleTextBuff1, gBattleMoves[gCurrentMove].type); gBattlescriptCurrInstr += 7; } return; @@ -9017,6 +9034,79 @@ static void Cmd_various(void) if (gBattleStruct->stickyWebUser != 0xFF) gBattlerAttacker = gBattleStruct->stickyWebUser; break; + case VARIOUS_CUT_1_3_HP_RAISE_STATS: + { + bool8 atLeastOneStatBoosted = FALSE; + bool8 hasContrary = (GetBattlerAbility(gBattlerAttacker) == ABILITY_CONTRARY); + u16 hpFraction = min(1, gBattleMons[gBattlerAttacker].maxHP / 3); + + for (i = 1; i < NUM_STATS; i++) + { + if (!(gBattleMons[gBattlerAttacker].statStages[i] == MAX_STAT_STAGE + || (hasContrary && gBattleMons[gBattlerAttacker].statStages[i] == MIN_STAT_STAGE))) + { + atLeastOneStatBoosted = TRUE; + break; + } + } + if (atLeastOneStatBoosted && gBattleMons[gBattlerAttacker].hp > hpFraction) + { + gBattleMoveDamage = hpFraction; + gBattlescriptCurrInstr += 7; + } + else + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + } + } + return; + case VARIOUS_SET_OCTOLOCK: + if (gDisableStructs[gActiveBattler].octolock) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + } + else + { + gDisableStructs[gActiveBattler].octolock = 1; + gBattleMons[gActiveBattler].status2 |= STATUS2_ESCAPE_PREVENTION; + gDisableStructs[gActiveBattler].battlerPreventingEscape = gBattlerAttacker; + gBattlescriptCurrInstr += 7; + } + return; + case VARIOUS_CHECK_POLTERGEIST: + if (gBattleMons[gActiveBattler].item == ITEM_NONE + || gFieldStatuses & STATUS_FIELD_MAGIC_ROOM + || GetBattlerAbility(gActiveBattler) == ABILITY_KLUTZ) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + } + else + { + PREPARE_ITEM_BUFFER(gBattleTextBuff1, gBattleMons[gActiveBattler].item); + gBattlescriptCurrInstr += 7; + } + return; + case VARIOUS_TRY_NO_RETREAT: + if (gDisableStructs[gActiveBattler].noRetreat) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + else + { + if (!(gBattleMons[gActiveBattler].status2 & STATUS2_ESCAPE_PREVENTION)) + gDisableStructs[gActiveBattler].noRetreat = 1; + gBattlescriptCurrInstr += 7; + } + return; + case VARIOUS_TRY_TAR_SHOT: + if (gDisableStructs[gActiveBattler].tarShot) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + } + else + { + gDisableStructs[gActiveBattler].tarShot = 1; + gBattlescriptCurrInstr += 7; + } + return; } gBattlescriptCurrInstr += 3; diff --git a/src/battle_util.c b/src/battle_util.c index f87e0a134..62c7374ff 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2382,6 +2382,7 @@ enum ENDTURN_NIGHTMARES, ENDTURN_CURSE, ENDTURN_WRAP, + ENDTURN_OCTOLOCK, ENDTURN_UPROAR, ENDTURN_THRASH, ENDTURN_FLINCH, @@ -2652,6 +2653,18 @@ u8 DoBattlerEndTurnEffects(void) } gBattleStruct->turnEffectsTracker++; break; + case ENDTURN_OCTOLOCK: + if (gDisableStructs[gActiveBattler].octolock + && !(GetBattlerAbility(gActiveBattler) == ABILITY_CLEAR_BODY + || GetBattlerAbility(gActiveBattler) == ABILITY_FULL_METAL_BODY + || GetBattlerAbility(gActiveBattler) == ABILITY_WHITE_SMOKE)) + { + gBattlerTarget = gActiveBattler; + BattleScriptExecute(BattleScript_OctolockEndTurn); + effect++; + } + gBattleStruct->turnEffectsTracker++; + break; case ENDTURN_UPROAR: // uproar if (gBattleMons[gActiveBattler].status2 & STATUS2_UPROAR) { @@ -7731,6 +7744,10 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef) && (gDisableStructs[battlerDef].isFirstTurn != 2 || B_PAYBACK_SWITCH_BOOST < GEN_5)) basePower *= 2; break; + case EFFECT_BOLT_BEAK: + if (GetBattlerTurnOrderNum(battlerAtk) < GetBattlerTurnOrderNum(battlerDef)) + basePower *= 2; + break; case EFFECT_ROUND: if (gChosenMoveByBattler[BATTLE_PARTNER(battlerAtk)] == MOVE_ROUND && !(gAbsentBattlerFlags & gBitTable[BATTLE_PARTNER(battlerAtk)])) basePower *= 2; @@ -8741,6 +8758,8 @@ u16 CalcTypeEffectivenessMultiplier(u16 move, u8 moveType, u8 battlerAtk, u8 bat modifier = CalcTypeEffectivenessMultiplierInternal(move, moveType, battlerAtk, battlerDef, recordAbilities, modifier); if (gBattleMoves[move].effect == EFFECT_TWO_TYPED_MOVE) modifier = CalcTypeEffectivenessMultiplierInternal(move, gBattleMoves[move].argument, battlerAtk, battlerDef, recordAbilities, modifier); + else if (moveType == TYPE_FIRE && gDisableStructs[battlerDef].tarShot) + modifier = CalcTypeEffectivenessMultiplierInternal(move, moveType, battlerAtk, battlerDef, recordAbilities, UQ_4_12(2.0)); } if (recordAbilities) diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index 97d61202a..06e8ee6ec 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -10771,7 +10771,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_JAW_LOCK] = { - .effect = EFFECT_MEAN_LOOK, + .effect = EFFECT_JAW_LOCK, .power = 80, .type = TYPE_DARK, .accuracy = 100, @@ -10799,7 +10799,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_NO_RETREAT] = { - .effect = EFFECT_PLACEHOLDER, //TODO + .effect = EFFECT_NO_RETREAT, .power = 0, .type = TYPE_FIGHTING, .accuracy = 0, @@ -10827,7 +10827,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_MAGIC_POWDER] = { - .effect = EFFECT_THIRD_TYPE, + .effect = EFFECT_SOAK, .power = 0, .type = TYPE_PSYCHIC, .accuracy = 100, @@ -10870,7 +10870,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_OCTOLOCK] = { - .effect = EFFECT_MEAN_LOOK, + .effect = EFFECT_OCTOLOCK, .power = 0, .type = TYPE_FIGHTING, .accuracy = 100, @@ -10884,7 +10884,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_BOLT_BEAK] = { - .effect = EFFECT_PLACEHOLDER, //TODO + .effect = EFFECT_BOLT_BEAK, .power = 85, .type = TYPE_ELECTRIC, .accuracy = 100, @@ -10898,7 +10898,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_FISHIOUS_REND] = { - .effect = EFFECT_PLACEHOLDER, //TODO. same as bolt beak + .effect = EFFECT_BOLT_BEAK, .power = 85, .type = TYPE_WATER, .accuracy = 100, @@ -10926,7 +10926,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_CLANGOROUS_SOUL] = { - .effect = EFFECT_PLACEHOLDER, //TODO + .effect = EFFECT_CLANGOROUS_SOUL, .power = 0, .type = TYPE_DRAGON, .accuracy = 100, @@ -11402,7 +11402,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_POLTERGEIST] = { - .effect = EFFECT_PLACEHOLDER, //TODO + .effect = EFFECT_POLTERGEIST, .power = 110, .type = TYPE_GHOST, .accuracy = 90, From 3baf2aa331524555c1b491b5594df26916ddd706 Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Thu, 4 Nov 2021 20:19:18 +1300 Subject: [PATCH 03/12] Remove trynextdart, update waitmessage 0x40 Not dealing with Dragon Darts in this PR. Updated waitmessage 0x40 to waitmessage B_WAIT_TIME_LONG. --- asm/macros/battle_script.inc | 5 ----- data/battle_scripts_1.s | 26 +++++++++++++------------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index aadae8766..33c89d55d 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1888,11 +1888,6 @@ .4byte \ptr .endm - .macro trynextdart ptr:req - various BS_ATTACKER, VARIOUS_TRY_NEXT_DART - .4byte \ptr - .endm - .macro checkpoltergeist battler:req, ptr:req various \battler, VARIOUS_CHECK_POLTERGEIST .4byte \ptr diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index bb648c225..a4036bef1 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -423,7 +423,7 @@ BattleScript_EffectOctolock: attackanimation waitanimation printstring STRINGID_CANTESCAPEBECAUSEOFCURRENTMOVE - waitmessage 0x40 + waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd BattleScript_OctolockEndTurn:: @@ -438,13 +438,13 @@ BattleScript_OctolockLowerDef: statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_ALLOW_PTR, BattleScript_OctolockTryLowerSpDef jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 0x2, BattleScript_OctolockTryLowerSpDef printfromtable gStatUpStringIds - waitmessage 0x40 + waitmessage B_WAIT_TIME_LONG BattleScript_OctolockTryLowerSpDef:: setstatchanger STAT_SPDEF, 1, TRUE statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_ALLOW_PTR, BattleScript_OctolockEnd2 jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 0x2, BattleScript_OctolockEnd2 printfromtable gStatUpStringIds - waitmessage 0x40 + waitmessage B_WAIT_TIME_LONG BattleScript_OctolockEnd2:: end2 @@ -454,7 +454,7 @@ BattleScript_EffectPoltergeist: ppreduce checkpoltergeist BS_TARGET, BattleScript_ButItFailed printstring STRINGID_ABOUTTOUSEPOLTERGEIST - waitmessage 0x40 + waitmessage B_WAIT_TIME_LONG goto BattleScript_HitFromCritCalc BattleScript_EffectTarShot: @@ -470,11 +470,11 @@ BattleScript_EffectTarShot: setgraphicalstatchangevalues playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 printfromtable gStatDownStringIds - waitmessage 0x40 + waitmessage B_WAIT_TIME_LONG BattleScript_TryTarShot: trytarshot BS_TARGET, BattleScript_MoveEnd printstring STRINGID_PKMNBECAMEWEAKERTOFIRE - waitmessage 0x40 + waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd BattleScript_EffectNoRetreat: @@ -490,7 +490,7 @@ BattleScript_EffectNoRetreat: setmoveeffect MOVE_EFFECT_PREVENT_ESCAPE seteffectprimary printstring STRINGID_CANTESCAPEDUETOUSEDMOVE - waitmessage 0x40 + waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd BattleScript_EffectJawLock: @@ -499,7 +499,7 @@ BattleScript_EffectJawLock: BattleScript_BothCanNoLongerEscape:: printstring STRINGID_BOTHCANNOLONGERESCAPE - waitmessage 0x40 + waitmessage B_WAIT_TIME_LONG return BattleScript_EffectHyperspaceFury: @@ -6398,7 +6398,7 @@ BattleScript_AttackerItemStatRaise:: playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 waitanimation printstring STRINGID_USINGITEMSTATOFPKMNROSE - waitmessage 0x40 + waitmessage B_WAIT_TIME_LONG removeitem BS_ATTACKER BattleScript_AttackerItemStatRaiseRet: return @@ -9036,7 +9036,7 @@ BattleScript_StickyBarbTransfer:: BattleScript_RedCardActivates:: playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT, NULL printstring STRINGID_REDCARDACTIVATE - waitmessage 0x40 + waitmessage B_WAIT_TIME_LONG swapattackerwithtarget jumpifstatus3 BS_EFFECT_BATTLER, STATUS3_ROOTED, BattleScript_RedCardIngrain jumpifability BS_EFFECT_BATTLER, ABILITY_SUCTION_CUPS, BattleScript_RedCardSuctionCups @@ -9047,13 +9047,13 @@ BattleScript_RedCardEnd: return BattleScript_RedCardIngrain: printstring STRINGID_PKMNANCHOREDITSELF - waitmessage 0x40 + waitmessage B_WAIT_TIME_LONG removeitem BS_SCRIPTING swapattackerwithtarget return BattleScript_RedCardSuctionCups: printstring STRINGID_PKMNANCHORSITSELFWITH - waitmessage 0x40 + waitmessage B_WAIT_TIME_LONG removeitem BS_SCRIPTING swapattackerwithtarget return @@ -9062,7 +9062,7 @@ BattleScript_EjectButtonActivates:: makevisible BS_ATTACKER playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT, NULL printstring STRINGID_EJECTBUTTONACTIVATE - waitmessage 0x40 + waitmessage B_WAIT_TIME_LONG removeitem BS_SCRIPTING makeinvisible BS_SCRIPTING openpartyscreen BS_SCRIPTING, BattleScript_EjectButtonEnd From fb62479d850ce9a4d7b8da994a51663e6bacd1ab Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Thu, 4 Nov 2021 20:28:11 +1300 Subject: [PATCH 04/12] Assign Tar Shot's effect Missed this change. Tar Shot works perfectly now. --- src/data/battle_moves.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index 06e8ee6ec..860a04bd0 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -10813,7 +10813,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_TAR_SHOT] = { - .effect = EFFECT_SPEED_DOWN, + .effect = EFFECT_TAR_SHOT, .power = 0, .type = TYPE_ROCK, .accuracy = 100, From cecd341011e29da4e8ac46584d79f0e6ca619d87 Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Thu, 4 Nov 2021 20:47:45 +1300 Subject: [PATCH 05/12] Fix Tar Shot If Tar Shot can't do anything to the target it should fail. Checking this is clunky, but it works. --- asm/macros/battle_script.inc | 5 +++++ data/battle_scripts_1.s | 1 + include/constants/battle_script_commands.h | 7 ++++--- src/battle_script_commands.c | 9 +++++++++ 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 33c89d55d..a59af74d0 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1888,6 +1888,11 @@ .4byte \ptr .endm + .macro cantarshotwork battler:req, ptr:req + various \battler, VARIOUS_CAN_TAR_SHOT_WORK + .4byte \ptr + .endm + .macro checkpoltergeist battler:req, ptr:req various \battler, VARIOUS_CHECK_POLTERGEIST .4byte \ptr diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index a4036bef1..3e29989b4 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -461,6 +461,7 @@ BattleScript_EffectTarShot: attackcanceler jumpifsubstituteblocks BattleScript_ButItFailedAtkStringPpReduce accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE + cantarshotwork BS_TARGET, BattleScript_ButItFailedAtkStringPpReduce attackstring ppreduce setstatchanger STAT_SPEED, 1, TRUE diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index cc67ef2e3..64809532d 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -200,9 +200,10 @@ #define VARIOUS_SET_ATTACKER_STICKY_WEB_USER 127 #define VARIOUS_TRY_NO_RETREAT 128 #define VARIOUS_TRY_TAR_SHOT 129 -#define VARIOUS_CHECK_POLTERGEIST 130 -#define VARIOUS_SET_OCTOLOCK 131 -#define VARIOUS_CUT_1_3_HP_RAISE_STATS 132 +#define VARIOUS_CAN_TAR_SHOT_WORK 130 +#define VARIOUS_CHECK_POLTERGEIST 131 +#define VARIOUS_SET_OCTOLOCK 132 +#define VARIOUS_CUT_1_3_HP_RAISE_STATS 133 // Cmd_manipulatedamage #define DMG_CHANGE_SIGN 0 diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index eddde6b44..7875e5e65 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -9107,6 +9107,15 @@ static void Cmd_various(void) gBattlescriptCurrInstr += 7; } return; + case VARIOUS_CAN_TAR_SHOT_WORK: + // Tar Shot will fail if it's already been used on the target and its speed can't be lowered further + if (gDisableStructs[gActiveBattler].tarShot + && (gBattleMons[gActiveBattler].statStages[STAT_SPEED] == MIN_STAT_STAGE + || (gBattleMons[gActiveBattler].statStages[STAT_SPEED] == MAX_STAT_STAGE && GetBattlerAbility(gActiveBattler) == ABILITY_CONTRARY))) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + else + gBattlescriptCurrInstr += 7; + return; } gBattlescriptCurrInstr += 3; From ecbe048f96ebd5cae25784dcb29e215628ce1731 Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Thu, 4 Nov 2021 21:26:04 +1300 Subject: [PATCH 06/12] Fix Octolock Fixed two issues: - Octolock doesn't have an end of turn animation in gen 8 - The def drop anim wasn't played if Sp. Def was at -6 and def could still drop --- data/battle_scripts_1.s | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 3e29989b4..16d9f2f0d 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -427,22 +427,24 @@ BattleScript_EffectOctolock: goto BattleScript_MoveEnd BattleScript_OctolockEndTurn:: - playanimation BS_ATTACKER, B_ANIM_TURN_TRAP, 0 jumpifstat BS_TARGET, CMP_GREATER_THAN, STAT_DEF, MIN_STAT_STAGE, BattleScript_OctolockLowerDef jumpifstat BS_TARGET, CMP_GREATER_THAN, STAT_SPDEF, MIN_STAT_STAGE, BattleScript_OctolockTryLowerSpDef goto BattleScript_OctolockEnd2 BattleScript_OctolockLowerDef: - playstatchangeanimation BS_ATTACKER, BIT_SPATK | BIT_SPDEF, STAT_CHANGE_NEGATIVE + playstatchangeanimation BS_ATTACKER, BIT_DEF | BIT_SPDEF, STAT_CHANGE_NEGATIVE jumpifability BS_TARGET, ABILITY_BIG_PECKS, BattleScript_OctolockTryLowerSpDef setstatchanger STAT_DEF, 1, TRUE - statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_ALLOW_PTR, BattleScript_OctolockTryLowerSpDef - jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 0x2, BattleScript_OctolockTryLowerSpDef + statbuffchange STAT_BUFF_ALLOW_PTR, BattleScript_OctolockTryLowerSpDef + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_OctolockTryLowerSpDef printfromtable gStatUpStringIds waitmessage B_WAIT_TIME_LONG -BattleScript_OctolockTryLowerSpDef:: +BattleScript_OctolockTryLowerSpDef: + jumpifstat BS_TARGET, CMP_GREATER_THAN, STAT_DEF, MIN_STAT_STAGE, BattleScript_OctolockSkipSpDefAnim + playstatchangeanimation BS_ATTACKER, BIT_SPDEF, STAT_CHANGE_NEGATIVE +BattleScript_OctolockSkipSpDefAnim: setstatchanger STAT_SPDEF, 1, TRUE - statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_ALLOW_PTR, BattleScript_OctolockEnd2 - jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 0x2, BattleScript_OctolockEnd2 + statbuffchange STAT_BUFF_ALLOW_PTR, BattleScript_OctolockEnd2 + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_OctolockEnd2 printfromtable gStatUpStringIds waitmessage B_WAIT_TIME_LONG BattleScript_OctolockEnd2:: From c9ae140bd1de38540ec722d20361d7f7f096bba1 Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Thu, 4 Nov 2021 21:50:42 +1300 Subject: [PATCH 07/12] Fix Clangourous Soul I broke this while trying to tidy up the code, it worked perfectly before. Also, make sure the "recoil' doesn't break Disguise. --- data/battle_scripts_1.s | 2 +- src/battle_script_commands.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 16d9f2f0d..740357fd1 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -405,7 +405,7 @@ BattleScript_EffectClangorousSoul: attackstring ppreduce cutonethirdhpraisestats BattleScript_ButItFailed - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE + orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_DISGUISE attackanimation waitanimation healthbarupdate BS_ATTACKER diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 7875e5e65..668fc7b7f 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -9038,7 +9038,7 @@ static void Cmd_various(void) { bool8 atLeastOneStatBoosted = FALSE; bool8 hasContrary = (GetBattlerAbility(gBattlerAttacker) == ABILITY_CONTRARY); - u16 hpFraction = min(1, gBattleMons[gBattlerAttacker].maxHP / 3); + u16 hpFraction = max(1, gBattleMons[gBattlerAttacker].maxHP / 3); for (i = 1; i < NUM_STATS; i++) { From d3abd20dfb648601609be6f6039200491b52d44b Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Tue, 9 Nov 2021 18:12:40 +0100 Subject: [PATCH 08/12] Fix heat crash/heavy slam calculation --- 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 7e06b55d1..4f09e3bb7 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -7788,7 +7788,7 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef) if (weight >= ARRAY_COUNT(sHeatCrashPowerTable)) basePower = sHeatCrashPowerTable[ARRAY_COUNT(sHeatCrashPowerTable) - 1]; else - basePower = sHeatCrashPowerTable[i]; + basePower = sHeatCrashPowerTable[weight]; break; case EFFECT_PUNISHMENT: basePower = 60 + (CountBattlerStatIncreases(battlerDef, FALSE) * 20); From e637714e1b51e359399eb6de260e28cd67fb5ab8 Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Wed, 10 Nov 2021 21:11:15 +1300 Subject: [PATCH 09/12] Requested changes Various bug fixes, syntax corrections etc. --- data/battle_scripts_1.s | 6 +++--- src/battle_script_commands.c | 21 ++++++++++----------- src/battle_util.c | 4 ++-- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 14d875543..4925b0c99 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -445,7 +445,7 @@ BattleScript_EffectClangorousSoul: attackstring ppreduce cutonethirdhpraisestats BattleScript_ButItFailed - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_DISGUISE + orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_SKIP_DMG_TRACK | HITMARKER_PASSIVE_DAMAGE | HITMARKER_IGNORE_DISGUISE attackanimation waitanimation healthbarupdate BS_ATTACKER @@ -471,8 +471,8 @@ BattleScript_OctolockEndTurn:: jumpifstat BS_TARGET, CMP_GREATER_THAN, STAT_SPDEF, MIN_STAT_STAGE, BattleScript_OctolockTryLowerSpDef goto BattleScript_OctolockEnd2 BattleScript_OctolockLowerDef: - playstatchangeanimation BS_ATTACKER, BIT_DEF | BIT_SPDEF, STAT_CHANGE_NEGATIVE jumpifability BS_TARGET, ABILITY_BIG_PECKS, BattleScript_OctolockTryLowerSpDef + playstatchangeanimation BS_ATTACKER, BIT_DEF | BIT_SPDEF, STAT_CHANGE_NEGATIVE | MOVE_EFFECT_AFFECTS_USER setstatchanger STAT_DEF, 1, TRUE statbuffchange STAT_BUFF_ALLOW_PTR, BattleScript_OctolockTryLowerSpDef jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_OctolockTryLowerSpDef @@ -480,7 +480,7 @@ BattleScript_OctolockLowerDef: waitmessage B_WAIT_TIME_LONG BattleScript_OctolockTryLowerSpDef: jumpifstat BS_TARGET, CMP_GREATER_THAN, STAT_DEF, MIN_STAT_STAGE, BattleScript_OctolockSkipSpDefAnim - playstatchangeanimation BS_ATTACKER, BIT_SPDEF, STAT_CHANGE_NEGATIVE + playstatchangeanimation BS_ATTACKER, BIT_SPDEF, STAT_CHANGE_NEGATIVE | MOVE_EFFECT_AFFECTS_USER BattleScript_OctolockSkipSpDefAnim: setstatchanger STAT_SPDEF, 1, TRUE statbuffchange STAT_BUFF_ALLOW_PTR, BattleScript_OctolockEnd2 diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 6cd44e10a..835f04a29 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -9201,13 +9201,11 @@ static void Cmd_various(void) case VARIOUS_CUT_1_3_HP_RAISE_STATS: { bool8 atLeastOneStatBoosted = FALSE; - bool8 hasContrary = (GetBattlerAbility(gBattlerAttacker) == ABILITY_CONTRARY); u16 hpFraction = max(1, gBattleMons[gBattlerAttacker].maxHP / 3); for (i = 1; i < NUM_STATS; i++) { - if (!(gBattleMons[gBattlerAttacker].statStages[i] == MAX_STAT_STAGE - || (hasContrary && gBattleMons[gBattlerAttacker].statStages[i] == MIN_STAT_STAGE))) + if (CompareStat(gBattlerAttacker, i, MAX_STAT_STAGE, CMP_LESS_THAN)) { atLeastOneStatBoosted = TRUE; break; @@ -9231,7 +9229,7 @@ static void Cmd_various(void) } else { - gDisableStructs[gActiveBattler].octolock = 1; + gDisableStructs[gActiveBattler].octolock = TRUE; gBattleMons[gActiveBattler].status2 |= STATUS2_ESCAPE_PREVENTION; gDisableStructs[gActiveBattler].battlerPreventingEscape = gBattlerAttacker; gBattlescriptCurrInstr += 7; @@ -9252,11 +9250,13 @@ static void Cmd_various(void) return; case VARIOUS_TRY_NO_RETREAT: if (gDisableStructs[gActiveBattler].noRetreat) + { gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + } else { if (!(gBattleMons[gActiveBattler].status2 & STATUS2_ESCAPE_PREVENTION)) - gDisableStructs[gActiveBattler].noRetreat = 1; + gDisableStructs[gActiveBattler].noRetreat = TRUE; gBattlescriptCurrInstr += 7; } return; @@ -9267,18 +9267,17 @@ static void Cmd_various(void) } else { - gDisableStructs[gActiveBattler].tarShot = 1; + gDisableStructs[gActiveBattler].tarShot = TRUE; gBattlescriptCurrInstr += 7; } return; case VARIOUS_CAN_TAR_SHOT_WORK: // Tar Shot will fail if it's already been used on the target and its speed can't be lowered further - if (gDisableStructs[gActiveBattler].tarShot - && (gBattleMons[gActiveBattler].statStages[STAT_SPEED] == MIN_STAT_STAGE - || (gBattleMons[gActiveBattler].statStages[STAT_SPEED] == MAX_STAT_STAGE && GetBattlerAbility(gActiveBattler) == ABILITY_CONTRARY))) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); - else + if (!gDisableStructs[gActiveBattler].tarShot + && CompareStat(gActiveBattler, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN)) gBattlescriptCurrInstr += 7; + else + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); return; case VARIOUS_TRY_TO_APPLY_MIMICRY: { diff --git a/src/battle_util.c b/src/battle_util.c index 8f376a050..e5851f7b8 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8774,6 +8774,8 @@ static void MulByTypeEffectiveness(u16 *modifier, u16 move, u8 moveType, u8 batt mod = UQ_4_12(2.0); if (moveType == TYPE_GROUND && defType == TYPE_FLYING && IsBattlerGrounded(battlerDef) && mod == UQ_4_12(0.0)) mod = UQ_4_12(1.0); + if (moveType == TYPE_FIRE && gDisableStructs[battlerDef].tarShot) + mod = UQ_4_12(2.0); if (gProtectStructs[battlerDef].kingsShielded && gBattleMoves[move].effect != EFFECT_FEINT) mod = UQ_4_12(1.0); @@ -8867,8 +8869,6 @@ u16 CalcTypeEffectivenessMultiplier(u16 move, u8 moveType, u8 battlerAtk, u8 bat modifier = CalcTypeEffectivenessMultiplierInternal(move, moveType, battlerAtk, battlerDef, recordAbilities, modifier); if (gBattleMoves[move].effect == EFFECT_TWO_TYPED_MOVE) modifier = CalcTypeEffectivenessMultiplierInternal(move, gBattleMoves[move].argument, battlerAtk, battlerDef, recordAbilities, modifier); - else if (moveType == TYPE_FIRE && gDisableStructs[battlerDef].tarShot) - modifier = CalcTypeEffectivenessMultiplierInternal(move, moveType, battlerAtk, battlerDef, recordAbilities, UQ_4_12(2.0)); } if (recordAbilities) From e47317aa73bab1905f19a567c91348c05be8a9b4 Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Wed, 10 Nov 2021 21:24:48 +1300 Subject: [PATCH 10/12] 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 93e1b31e2..3874febf3 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 11/12] 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 4f09e3bb7..385b09a1c 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 e606e54f9d3684fec763bd248b75329818c410c0 Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Thu, 11 Nov 2021 14:32:38 +1300 Subject: [PATCH 12/12] Fix Big Pecks/Octolock animation Also removed MOVE_EFFECT_AFFECTS_USER because that shouldn't be part of playstatchangeanimation. The stat drops still bypass Mirror Armor without this. --- data/battle_scripts_1.s | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 4925b0c99..ee859f0e0 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -467,20 +467,22 @@ BattleScript_EffectOctolock: goto BattleScript_MoveEnd BattleScript_OctolockEndTurn:: + setbyte sSTAT_ANIM_PLAYED, FALSE jumpifstat BS_TARGET, CMP_GREATER_THAN, STAT_DEF, MIN_STAT_STAGE, BattleScript_OctolockLowerDef jumpifstat BS_TARGET, CMP_GREATER_THAN, STAT_SPDEF, MIN_STAT_STAGE, BattleScript_OctolockTryLowerSpDef goto BattleScript_OctolockEnd2 BattleScript_OctolockLowerDef: jumpifability BS_TARGET, ABILITY_BIG_PECKS, BattleScript_OctolockTryLowerSpDef - playstatchangeanimation BS_ATTACKER, BIT_DEF | BIT_SPDEF, STAT_CHANGE_NEGATIVE | MOVE_EFFECT_AFFECTS_USER + playstatchangeanimation BS_ATTACKER, BIT_DEF | BIT_SPDEF, STAT_CHANGE_NEGATIVE + setbyte sSTAT_ANIM_PLAYED, TRUE setstatchanger STAT_DEF, 1, TRUE statbuffchange STAT_BUFF_ALLOW_PTR, BattleScript_OctolockTryLowerSpDef jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_OctolockTryLowerSpDef printfromtable gStatUpStringIds waitmessage B_WAIT_TIME_LONG BattleScript_OctolockTryLowerSpDef: - jumpifstat BS_TARGET, CMP_GREATER_THAN, STAT_DEF, MIN_STAT_STAGE, BattleScript_OctolockSkipSpDefAnim - playstatchangeanimation BS_ATTACKER, BIT_SPDEF, STAT_CHANGE_NEGATIVE | MOVE_EFFECT_AFFECTS_USER + jumpifbyte CMP_EQUAL, sSTAT_ANIM_PLAYED, TRUE, BattleScript_OctolockSkipSpDefAnim + playstatchangeanimation BS_ATTACKER, BIT_SPDEF, STAT_CHANGE_NEGATIVE BattleScript_OctolockSkipSpDefAnim: setstatchanger STAT_SPDEF, 1, TRUE statbuffchange STAT_BUFF_ALLOW_PTR, BattleScript_OctolockEnd2