From 5019615be125e49de6fcc4cca8d7f5b0502debc2 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Mon, 4 Oct 2021 21:28:15 -0300 Subject: [PATCH 01/42] Refactored Secret Power move effect into a function --- include/battle_script_commands.h | 1 + src/battle_script_commands.c | 27 +++++++++++++++++---------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/include/battle_script_commands.h b/include/battle_script_commands.h index dec1596f2..a765aafdd 100644 --- a/include/battle_script_commands.h +++ b/include/battle_script_commands.h @@ -36,6 +36,7 @@ u32 IsAbilityStatusProtected(u32 battler); bool32 TryResetBattlerStatChanges(u8 battler); bool32 CanCamouflage(u8 battlerId); u16 GetNaturePowerMove(void); +u16 GetSecretPowerMoveEffect(void); void StealTargetItem(u8 battlerStealer, u8 battlerItem); extern void (* const gBattleScriptingCommandsTable[])(void); diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 8d6dd5bdb..6662cb269 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -12068,37 +12068,44 @@ static void Cmd_jumpifhasnohp(void) static void Cmd_getsecretpowereffect(void) { + gBattleScripting.moveEffect = GetSecretPowerMoveEffect(); + gBattlescriptCurrInstr++; +} + +u16 GetSecretPowerMoveEffect(void) +{ + u16 moveEffect; switch (gBattleTerrain) { case BATTLE_TERRAIN_GRASS: - gBattleScripting.moveEffect = MOVE_EFFECT_SLEEP; + moveEffect = MOVE_EFFECT_SLEEP; break; case BATTLE_TERRAIN_LONG_GRASS: - gBattleScripting.moveEffect = MOVE_EFFECT_SLEEP; + moveEffect = MOVE_EFFECT_SLEEP; break; case BATTLE_TERRAIN_SAND: - gBattleScripting.moveEffect = MOVE_EFFECT_ACC_MINUS_1; + moveEffect = MOVE_EFFECT_ACC_MINUS_1; break; case BATTLE_TERRAIN_UNDERWATER: - gBattleScripting.moveEffect = MOVE_EFFECT_ATK_MINUS_1; + moveEffect = MOVE_EFFECT_ATK_MINUS_1; break; case BATTLE_TERRAIN_WATER: - gBattleScripting.moveEffect = MOVE_EFFECT_ATK_MINUS_1; + moveEffect = MOVE_EFFECT_ATK_MINUS_1; break; case BATTLE_TERRAIN_POND: - gBattleScripting.moveEffect = MOVE_EFFECT_ATK_MINUS_1; + moveEffect = MOVE_EFFECT_ATK_MINUS_1; break; case BATTLE_TERRAIN_MOUNTAIN: - gBattleScripting.moveEffect = MOVE_EFFECT_ACC_MINUS_1; + moveEffect = MOVE_EFFECT_ACC_MINUS_1; break; case BATTLE_TERRAIN_CAVE: - gBattleScripting.moveEffect = MOVE_EFFECT_FLINCH; + moveEffect = MOVE_EFFECT_FLINCH; break; default: - gBattleScripting.moveEffect = MOVE_EFFECT_PARALYSIS; + moveEffect = MOVE_EFFECT_PARALYSIS; break; } - gBattlescriptCurrInstr++; + return moveEffect; } static void Cmd_pickup(void) From 563ce8f416080d18c0807d76bde4a3dfab0f0c99 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Mon, 4 Oct 2021 21:32:08 -0300 Subject: [PATCH 02/42] Field terrain move effect --- src/battle_script_commands.c | 83 +++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 29 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 6662cb269..80bb69ecc 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -8709,7 +8709,7 @@ static void Cmd_various(void) else gBattlescriptCurrInstr += 7; // can heal return; - case VARIOUS_REMOVE_TERRAIN: + case VARIOUS_REMOVE_TERRAIN: switch (gFieldStatuses & STATUS_FIELD_TERRAIN_ANY) { case STATUS_FIELD_MISTY_TERRAIN: @@ -12075,35 +12075,60 @@ static void Cmd_getsecretpowereffect(void) u16 GetSecretPowerMoveEffect(void) { u16 moveEffect; - switch (gBattleTerrain) + u32 fieldTerrain = gFieldStatuses & STATUS_FIELD_TERRAIN_ANY; + if (fieldTerrain) { - case BATTLE_TERRAIN_GRASS: - moveEffect = MOVE_EFFECT_SLEEP; - break; - case BATTLE_TERRAIN_LONG_GRASS: - moveEffect = MOVE_EFFECT_SLEEP; - break; - case BATTLE_TERRAIN_SAND: - moveEffect = MOVE_EFFECT_ACC_MINUS_1; - break; - case BATTLE_TERRAIN_UNDERWATER: - moveEffect = MOVE_EFFECT_ATK_MINUS_1; - break; - case BATTLE_TERRAIN_WATER: - moveEffect = MOVE_EFFECT_ATK_MINUS_1; - break; - case BATTLE_TERRAIN_POND: - moveEffect = MOVE_EFFECT_ATK_MINUS_1; - break; - case BATTLE_TERRAIN_MOUNTAIN: - moveEffect = MOVE_EFFECT_ACC_MINUS_1; - break; - case BATTLE_TERRAIN_CAVE: - moveEffect = MOVE_EFFECT_FLINCH; - break; - default: - moveEffect = MOVE_EFFECT_PARALYSIS; - break; + switch (fieldTerrain) + { + case STATUS_FIELD_MISTY_TERRAIN: + moveEffect = MOVE_EFFECT_SP_ATK_MINUS_1; + break; + case STATUS_FIELD_GRASSY_TERRAIN: + moveEffect = MOVE_EFFECT_SLEEP; + break; + case STATUS_FIELD_ELECTRIC_TERRAIN: + moveEffect = MOVE_EFFECT_PARALYSIS; + break; + case STATUS_FIELD_PSYCHIC_TERRAIN: + moveEffect = MOVE_EFFECT_SPD_MINUS_1; + break; + default: + moveEffect = MOVE_EFFECT_PARALYSIS; + break; + } + } + else + { + switch (gBattleTerrain) + { + case BATTLE_TERRAIN_GRASS: + moveEffect = MOVE_EFFECT_SLEEP; + break; + case BATTLE_TERRAIN_LONG_GRASS: + moveEffect = MOVE_EFFECT_SLEEP; + break; + case BATTLE_TERRAIN_SAND: + moveEffect = MOVE_EFFECT_ACC_MINUS_1; + break; + case BATTLE_TERRAIN_UNDERWATER: + moveEffect = MOVE_EFFECT_ATK_MINUS_1; + break; + case BATTLE_TERRAIN_WATER: + moveEffect = MOVE_EFFECT_ATK_MINUS_1; + break; + case BATTLE_TERRAIN_POND: + moveEffect = MOVE_EFFECT_ATK_MINUS_1; + break; + case BATTLE_TERRAIN_MOUNTAIN: + moveEffect = MOVE_EFFECT_ACC_MINUS_1; + break; + case BATTLE_TERRAIN_CAVE: + moveEffect = MOVE_EFFECT_FLINCH; + break; + default: + moveEffect = MOVE_EFFECT_PARALYSIS; + break; + } } return moveEffect; } From e2bf660c97a21d1b2ed8ebc33e9f4d464c104680 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Mon, 4 Oct 2021 21:51:51 -0300 Subject: [PATCH 03/42] Secret Power field terrain animations --- data/battle_anim_scripts.s | 23 ++++++++++++++--------- src/battle_anim_utility_funcs.c | 6 ++++++ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index d7de92096..c7b4020f3 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -23251,16 +23251,21 @@ Move_SKY_UPPERCUT: end Move_SECRET_POWER: + createvisualtask AnimTask_GetFieldTerrain, 5 + jumpargeq 0, STATUS_FIELD_MISTY_TERRAIN, Move_FAIRY_WIND + jumpargeq 0, STATUS_FIELD_GRASSY_TERRAIN, Move_NEEDLE_ARM + jumpargeq 0, STATUS_FIELD_ELECTRIC_TERRAIN, Move_THUNDER_SHOCK + jumpargeq 0, STATUS_FIELD_PSYCHIC_TERRAIN, Move_CONFUSION createvisualtask AnimTask_GetBattleTerrain, 5 - jumpargeq 0, BATTLE_TERRAIN_GRASS, Move_NEEDLE_ARM - jumpargeq 0, BATTLE_TERRAIN_LONG_GRASS, Move_MAGICAL_LEAF - jumpargeq 0, BATTLE_TERRAIN_SAND, Move_MUD_SHOT - jumpargeq 0, BATTLE_TERRAIN_UNDERWATER, Move_WATERFALL - jumpargeq 0, BATTLE_TERRAIN_WATER, Move_SURF - jumpargeq 0, BATTLE_TERRAIN_POND, Move_BUBBLE_BEAM - jumpargeq 0, BATTLE_TERRAIN_MOUNTAIN, Move_ROCK_THROW - jumpargeq 0, BATTLE_TERRAIN_CAVE, Move_BITE - jumpargeq 0, BATTLE_TERRAIN_BUILDING, Move_STRENGTH + jumpargeq 0, BATTLE_TERRAIN_GRASS, Move_NEEDLE_ARM + jumpargeq 0, BATTLE_TERRAIN_LONG_GRASS, Move_MAGICAL_LEAF + jumpargeq 0, BATTLE_TERRAIN_SAND, Move_MUD_SHOT + jumpargeq 0, BATTLE_TERRAIN_UNDERWATER, Move_WATERFALL + jumpargeq 0, BATTLE_TERRAIN_WATER, Move_SURF + jumpargeq 0, BATTLE_TERRAIN_POND, Move_BUBBLE_BEAM + jumpargeq 0, BATTLE_TERRAIN_MOUNTAIN, Move_ROCK_THROW + jumpargeq 0, BATTLE_TERRAIN_CAVE, Move_BITE + jumpargeq 0, BATTLE_TERRAIN_BUILDING, Move_STRENGTH goto Move_SLAM Move_TWISTER: diff --git a/src/battle_anim_utility_funcs.c b/src/battle_anim_utility_funcs.c index 6cefba92a..0f35657db 100644 --- a/src/battle_anim_utility_funcs.c +++ b/src/battle_anim_utility_funcs.c @@ -904,6 +904,12 @@ void AnimTask_GetBattleTerrain(u8 taskId) DestroyAnimVisualTask(taskId); } +void AnimTask_GetFieldTerrain(u8 taskId) +{ + gBattleAnimArgs[0] = gFieldStatuses & STATUS_FIELD_TERRAIN_ANY; + DestroyAnimVisualTask(taskId); +} + void AnimTask_AllocBackupPalBuffer(u8 taskId) { gMonSpritesGfxPtr->buffer = AllocZeroed(0x2000); From aa7484bba0441ebd3e0974037610ef987953692b Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Mon, 4 Oct 2021 22:07:28 -0300 Subject: [PATCH 04/42] Camouflage with field terrains. --- src/battle_script_commands.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 80bb69ecc..1da3248d8 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -11484,13 +11484,13 @@ static void Cmd_callterrainattack(void) // nature power u16 GetNaturePowerMove(void) { if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN) - return MOVE_MOONBLAST; + return MOVE_MOONBLAST; else if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) - return MOVE_THUNDERBOLT; + return MOVE_THUNDERBOLT; else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN) - return MOVE_ENERGY_BALL; + return MOVE_ENERGY_BALL; else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN) - return MOVE_PSYCHIC; + return MOVE_PSYCHIC; return sNaturePowerMoves[gBattleTerrain]; } @@ -12358,10 +12358,30 @@ bool32 CanCamouflage(u8 battlerId) static void Cmd_settypetoterrain(void) { - if (!IS_BATTLER_OF_TYPE(gBattlerAttacker, sTerrainToType[gBattleTerrain])) + u8 terrainType; + switch(gFieldStatuses & STATUS_FIELD_TERRAIN_ANY) { - SET_BATTLER_TYPE(gBattlerAttacker, sTerrainToType[gBattleTerrain]); - PREPARE_TYPE_BUFFER(gBattleTextBuff1, sTerrainToType[gBattleTerrain]); + case STATUS_FIELD_ELECTRIC_TERRAIN: + terrainType = TYPE_ELECTRIC; + break; + case STATUS_FIELD_GRASSY_TERRAIN: + terrainType = TYPE_GRASS; + break; + case STATUS_FIELD_MISTY_TERRAIN: + terrainType = TYPE_FAIRY; + break; + case STATUS_FIELD_PSYCHIC_TERRAIN: + terrainType = TYPE_PSYCHIC; + break; + default: + terrainType = sTerrainToType[gBattleTerrain]; + break; + } + + if (!IS_BATTLER_OF_TYPE(gBattlerAttacker, terrainType)) + { + SET_BATTLER_TYPE(gBattlerAttacker, terrainType); + PREPARE_TYPE_BUFFER(gBattleTextBuff1, terrainType); gBattlescriptCurrInstr += 5; } From 43d42c95cfa0c7318a0748ee6a04af2ec30aa4db Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Mon, 4 Oct 2021 22:45:37 -0300 Subject: [PATCH 05/42] Terrain Pulse effect implemented --- data/battle_anim_scripts.s | 2 +- data/battle_scripts_1.s | 1 + include/constants/battle_move_effects.h | 3 ++- src/battle_main.c | 17 +++++++++++++++++ src/battle_util.c | 5 +++++ src/data/battle_moves.h | 2 +- 6 files changed, 27 insertions(+), 3 deletions(-) diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index c7b4020f3..0b630072a 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -13979,7 +13979,7 @@ Move_RISING_VOLTAGE:: end @to do: Move_TERRAIN_PULSE:: - end @to do: + goto Move_DRAGON_PULSE @Temporary, needs to setup different animations based on terrain Move_SKITTER_SMACK:: end @to do: diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 5a9aec525..f018ff504 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -379,6 +379,7 @@ gBattleScriptsForMoveEffects:: .4byte BattleScript_EffectDecorate @ EFFECT_DECORATE .4byte BattleScript_EffectHit @ EFFECT_SNIPE_SHOT .4byte BattleScript_EffectTripleHit @ EFFECT_TRIPLE_HIT + .4byte BattleScript_EffectHit @ EFFECT_TERRAIN_PULSE BattleScript_EffectDecorate: attackcanceler diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index 440e6e76b..966d35971 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -363,7 +363,8 @@ #define EFFECT_DECORATE 357 #define EFFECT_SNIPE_SHOT 358 #define EFFECT_TRIPLE_HIT 359 +#define EFFECT_TERRAIN_PULSE 360 -#define NUM_BATTLE_MOVE_EFFECTS 360 +#define NUM_BATTLE_MOVE_EFFECTS 361 #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/src/battle_main.c b/src/battle_main.c index 25db65f78..c7a5962ac 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -5095,6 +5095,23 @@ void SetTypeBeforeUsingMove(u16 move, u8 battlerAtk) if (ItemId_GetPocket(gBattleMons[battlerAtk].item) == POCKET_BERRIES) gBattleStruct->dynamicMoveType = gNaturalGiftTable[ITEM_TO_BERRY(gBattleMons[battlerAtk].item)].type; } + else if (gBattleMoves[move].effect == EFFECT_TERRAIN_PULSE) + { + if ((gFieldStatuses & STATUS_FIELD_TERRAIN_ANY) + && IsBattlerGrounded(battlerAtk)) + { + if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) + gBattleStruct->dynamicMoveType = TYPE_ELECTRIC | 0x80; + else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN) + gBattleStruct->dynamicMoveType = TYPE_GRASS | 0x80; + else if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN) + gBattleStruct->dynamicMoveType = TYPE_FAIRY | 0x80; + else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN) + gBattleStruct->dynamicMoveType = TYPE_PSYCHIC | 0x80; + else + gBattleStruct->dynamicMoveType = TYPE_NORMAL | 0x80; + } + } attackerAbility = GetBattlerAbility(battlerAtk); GET_MOVE_TYPE(move, moveType); diff --git a/src/battle_util.c b/src/battle_util.c index 462b58bd4..5ae5d80cb 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -7572,6 +7572,11 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef) basePower *= 2; #endif break; + case EFFECT_TERRAIN_PULSE: + if ((gFieldStatuses & STATUS_FIELD_TERRAIN_ANY) + && IsBattlerGrounded(gBattlerAttacker)) + basePower *= 2; + break; } // move-specific base power changes diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index a7a2752e0..542594e80 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -11332,7 +11332,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_TERRAIN_PULSE] = { - .effect = EFFECT_PLACEHOLDER, //TODO + .effect = EFFECT_TERRAIN_PULSE, .power = 50, .type = TYPE_NORMAL, .accuracy = 100, From ce4375a10cade942f39cd93e7ee880aa50175ad1 Mon Sep 17 00:00:00 2001 From: ultima-soul Date: Wed, 6 Oct 2021 10:22:17 -0700 Subject: [PATCH 06/42] 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 07/42] 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 08/42] 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 09/42] 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 10/42] 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 11/42] 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 12/42] 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 24cb5f66548656ff3d4af5f7f2014a15475e2ed2 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Thu, 4 Nov 2021 15:45:03 -0400 Subject: [PATCH 13/42] dont trigger x_up_hit effect if battle is over --- src/battle_script_commands.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 6f0fec8a7..861f2b8c4 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -2992,7 +2992,8 @@ void SetMoveEffect(bool32 primary, u32 certain) case MOVE_EFFECT_SP_DEF_PLUS_1: case MOVE_EFFECT_ACC_PLUS_1: case MOVE_EFFECT_EVS_PLUS_1: - if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(1), + if (NoAliveMonsForEitherParty() + || ChangeStatBuffs(SET_STAT_BUFF_VALUE(1), gBattleScripting.moveEffect - MOVE_EFFECT_ATK_PLUS_1 + 1, affectsUser, 0)) { @@ -3153,8 +3154,15 @@ void SetMoveEffect(bool32 primary, u32 certain) gBattlescriptCurrInstr++; break; case MOVE_EFFECT_ALL_STATS_UP: - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_AllStatsUp; + if (NoAliveMonsForEitherParty()) + { + gBattlescriptCurrInstr++; + } + else + { + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_AllStatsUp; + } break; case MOVE_EFFECT_RAPIDSPIN: BattleScriptPush(gBattlescriptCurrInstr + 1); From 03f290d937b3acb98162498302f4f6ad58d281ba Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Sat, 6 Nov 2021 08:53:00 -0400 Subject: [PATCH 14/42] add check for plus_2 effects --- src/battle_script_commands.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 861f2b8c4..5a85ee6b8 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3040,7 +3040,8 @@ void SetMoveEffect(bool32 primary, u32 certain) case MOVE_EFFECT_SP_DEF_PLUS_2: case MOVE_EFFECT_ACC_PLUS_2: case MOVE_EFFECT_EVS_PLUS_2: - if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(2), + if (NoAliveMonsForEitherParty() + || ChangeStatBuffs(SET_STAT_BUFF_VALUE(2), gBattleScripting.moveEffect - MOVE_EFFECT_ATK_PLUS_2 + 1, affectsUser, 0)) { From 62b6accbcc803cd701333f41777b3c35fcee0ae6 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Sat, 6 Nov 2021 11:07:40 -0300 Subject: [PATCH 15/42] Using IsBattlerTerrainAffected --- src/battle_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/battle_main.c b/src/battle_main.c index e8e27b316..63c4982f1 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -5194,8 +5194,7 @@ void SetTypeBeforeUsingMove(u16 move, u8 battlerAtk) } else if (gBattleMoves[move].effect == EFFECT_TERRAIN_PULSE) { - if ((gFieldStatuses & STATUS_FIELD_TERRAIN_ANY) - && IsBattlerGrounded(battlerAtk)) + if (IsBattlerTerrainAffected(battlerAtk, STATUS_FIELD_TERRAIN_ANY)) { if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) gBattleStruct->dynamicMoveType = TYPE_ELECTRIC | 0x80; From 328976bf8174963eccff09e7eb3742ddbd39abd2 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Sat, 6 Nov 2021 17:05:13 -0300 Subject: [PATCH 16/42] Secret Power effect config --- include/constants/battle.h | 33 ++++++++++++++------ include/constants/battle_config.h | 1 + src/battle_script_commands.c | 51 ++++++++++++++++++++++++++++--- 3 files changed, 71 insertions(+), 14 deletions(-) diff --git a/include/constants/battle.h b/include/constants/battle.h index 438b5660c..3ba45e0d8 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -364,16 +364,29 @@ #define MOVE_EFFECT_CERTAIN 0x8000 // Battle terrain defines for gBattleTerrain. -#define BATTLE_TERRAIN_GRASS 0 -#define BATTLE_TERRAIN_LONG_GRASS 1 -#define BATTLE_TERRAIN_SAND 2 -#define BATTLE_TERRAIN_UNDERWATER 3 -#define BATTLE_TERRAIN_WATER 4 -#define BATTLE_TERRAIN_POND 5 -#define BATTLE_TERRAIN_MOUNTAIN 6 -#define BATTLE_TERRAIN_CAVE 7 -#define BATTLE_TERRAIN_BUILDING 8 -#define BATTLE_TERRAIN_PLAIN 9 +#define BATTLE_TERRAIN_GRASS 0 +#define BATTLE_TERRAIN_LONG_GRASS 1 +#define BATTLE_TERRAIN_SAND 2 +#define BATTLE_TERRAIN_UNDERWATER 3 +#define BATTLE_TERRAIN_WATER 4 +#define BATTLE_TERRAIN_POND 5 +#define BATTLE_TERRAIN_MOUNTAIN 6 +#define BATTLE_TERRAIN_CAVE 7 +#define BATTLE_TERRAIN_BUILDING 8 +#define BATTLE_TERRAIN_PLAIN 9 +// New battle terrains are used for Secret Power but not fully implemented. +#define BATTLE_TERRAIN_SOARING 10 +#define BATTLE_TERRAIN_SKY_PILLAR 11 +#define BATTLE_TERRAIN_BURIAL_GROUND 12 +#define BATTLE_TERRAIN_PUDDLE 13 +#define BATTLE_TERRAIN_MARSH 14 +#define BATTLE_TERRAIN_SWAMP 15 +#define BATTLE_TERRAIN_SNOW 16 +#define BATTLE_TERRAIN_ICE 17 +#define BATTLE_TERRAIN_VOLCANO 18 +#define BATTLE_TERRAIN_DISTORTION_WORLD 19 +#define BATTLE_TERRAIN_SPACE 20 +#define BATTLE_TERRAIN_ULTRA_SPACE 21 #define B_WAIT_TIME_LONG 64 #define B_WAIT_TIME_MED 48 diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 95ff4f4a0..13f2be0d8 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -153,6 +153,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_SECRET_POWER_EFFECT GEN_7 // Secret Power's effects change depending on the generation. See GetSecretPowerMoveEffect. // 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 5267cfbd1..fcba67bca 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -12483,7 +12483,11 @@ u16 GetSecretPowerMoveEffect(void) switch (gBattleTerrain) { case BATTLE_TERRAIN_GRASS: - moveEffect = MOVE_EFFECT_SLEEP; + #if B_SECRET_POWER_EFFECT >= GEN_4 + moveEffect = MOVE_EFFECT_SLEEP; + #else + moveEffect = MOVE_EFFECT_POISON; + #endif break; case BATTLE_TERRAIN_LONG_GRASS: moveEffect = MOVE_EFFECT_SLEEP; @@ -12492,20 +12496,59 @@ u16 GetSecretPowerMoveEffect(void) moveEffect = MOVE_EFFECT_ACC_MINUS_1; break; case BATTLE_TERRAIN_UNDERWATER: - moveEffect = MOVE_EFFECT_ATK_MINUS_1; + #if B_SECRET_POWER_EFFECT >= GEN_6 + moveEffect = MOVE_EFFECT_ATK_MINUS_1; + #else + moveEffect = MOVE_EFFECT_DEF_MINUS_1; + #endif break; case BATTLE_TERRAIN_WATER: moveEffect = MOVE_EFFECT_ATK_MINUS_1; break; case BATTLE_TERRAIN_POND: - moveEffect = MOVE_EFFECT_ATK_MINUS_1; + #if B_SECRET_POWER_EFFECT >= GEN_4 + moveEffect = MOVE_EFFECT_ATK_MINUS_1; + #else + moveEffect = MOVE_EFFECT_SPD_MINUS_1; + #endif break; case BATTLE_TERRAIN_MOUNTAIN: - moveEffect = MOVE_EFFECT_ACC_MINUS_1; + #if B_SECRET_POWER_EFFECT >= GEN_5 + moveEffect = MOVE_EFFECT_ACC_MINUS_1; + #elif B_SECRET_POWER_EFFECT == GEN_4 + moveEffect = MOVE_EFFECT_FLINCH; + #else + moveEffect = MOVE_EFFECT_CONFUSION; + #endif break; case BATTLE_TERRAIN_CAVE: + case BATTLE_TERRAIN_BURIAL_GROUND: + case BATTLE_TERRAIN_SPACE: moveEffect = MOVE_EFFECT_FLINCH; break; + case BATTLE_TERRAIN_SOARING: + case BATTLE_TERRAIN_SKY_PILLAR: + case BATTLE_TERRAIN_MARSH: + case BATTLE_TERRAIN_SWAMP: + moveEffect = MOVE_EFFECT_SPD_MINUS_1; + break; + case BATTLE_TERRAIN_PUDDLE: + #if B_SECRET_POWER_EFFECT >= GEN_5 + moveEffect = MOVE_EFFECT_SPD_MINUS_1; + #else + moveEffect = MOVE_EFFECT_ACC_MINUS_1; + #endif + break; + case BATTLE_TERRAIN_SNOW: + case BATTLE_TERRAIN_ICE: + moveEffect = MOVE_EFFECT_FREEZE; + break; + case BATTLE_TERRAIN_VOLCANO: + moveEffect = MOVE_EFFECT_BURN; + break; + case BATTLE_TERRAIN_ULTRA_SPACE: + moveEffect = MOVE_EFFECT_DEF_MINUS_1; + break; default: moveEffect = MOVE_EFFECT_PARALYSIS; break; From e9804a50233a26c8480ab50bc9e47c24ab2eb4db Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Sat, 6 Nov 2021 17:32:34 -0300 Subject: [PATCH 17/42] Secret Power animation config --- data/battle_anim_scripts.s | 29 +++++++++++++++++++++++++++++ include/constants/battle_config.h | 1 + 2 files changed, 30 insertions(+) diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 6077a3ae4..3e7f02692 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -5,6 +5,7 @@ #include "constants/moves.h" #include "constants/pokemon.h" #include "constants/items.h" +#include "constants/battle_config.h" .include "asm/macros.inc" .include "asm/macros/battle_anim_script.inc" .include "constants/constants.inc" @@ -23367,8 +23368,36 @@ Move_SECRET_POWER: jumpargeq 0, BATTLE_TERRAIN_POND, Move_BUBBLE_BEAM jumpargeq 0, BATTLE_TERRAIN_MOUNTAIN, Move_ROCK_THROW jumpargeq 0, BATTLE_TERRAIN_CAVE, Move_BITE + jumpargeq 0, BATTLE_TERRAIN_BUILDING, Move_STRENGTH + jumpargeq 0, BATTLE_TERRAIN_SOARING, Move_GUST + jumpargeq 0, BATTLE_TERRAIN_SKY_PILLAR, Move_GUST + jumpargeq 0, BATTLE_TERRAIN_BURIAL_GROUND, Move_SHADOW_SNEAK + jumpargeq 0, BATTLE_TERRAIN_PUDDLE, Move_MUD_SHOT + jumpargeq 0, BATTLE_TERRAIN_MARSH, Move_MUD_SHOT + jumpargeq 0, BATTLE_TERRAIN_SWAMP, Move_MUD_SHOT +.if B_SECRET_POWER_ANIMATION >= GEN_7 + jumpargeq 0, BATTLE_TERRAIN_SNOW, Move_ICE_SHARD +.else + jumpargeq 0, BATTLE_TERRAIN_SNOW, Move_AVALANCHE +.endif + jumpargeq 0, BATTLE_TERRAIN_ICE, Move_ICE_SHARD + jumpargeq 0, BATTLE_TERRAIN_VOLCANO, Move_INCINERATE + jumpargeq 0, BATTLE_TERRAIN_DISTORTION_WORLD, Move_POUND + jumpargeq 0, BATTLE_TERRAIN_SPACE, Move_SWIFT + jumpargeq 0, BATTLE_TERRAIN_ULTRA_SPACE, Move_PSYWAVE +.if B_SECRET_POWER_ANIMATION >= GEN_7 + jumpargeq 0, BATTLE_TERRAIN_BUILDING, Move_SPIT_UP + goto Move_SPIT_UP +.elseif B_SECRET_POWER_ANIMATION == GEN_6 + jumpargeq 0, BATTLE_TERRAIN_BUILDING, Move_BODY_SLAM + goto Move_BODY_SLAM +.elseif B_SECRET_POWER_ANIMATION == GEN_5 || B_SECRET_POWER_ANIMATION == GEN_4 + jumpargeq 0, BATTLE_TERRAIN_BUILDING, Move_BODY_SLAM + goto Move_MUD_SLAP +.else jumpargeq 0, BATTLE_TERRAIN_BUILDING, Move_STRENGTH goto Move_SLAM +.endif Move_TWISTER: loadspritegfx ANIM_TAG_LEAF diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 13f2be0d8..61723ced4 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -154,6 +154,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_SECRET_POWER_EFFECT GEN_7 // Secret Power's effects change depending on the generation. See GetSecretPowerMoveEffect. +#define B_SECRET_POWER_ANIMATION GEN_7 // Secret Power's animations change depending on the generation. // 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 b220da1d2ad9fd9696256a39ec626029d42187fb Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Sat, 6 Nov 2021 18:50:01 -0300 Subject: [PATCH 18/42] Updated NaturePowerMoves table for new terrains + added failsafe in case the terrain isn't defined in the table --- include/constants/battle.h | 2 + include/constants/battle_config.h | 1 + src/battle_script_commands.c | 68 +++++++++++++++++++++++++++++-- 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/include/constants/battle.h b/include/constants/battle.h index 3ba45e0d8..2fb4d3401 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -388,6 +388,8 @@ #define BATTLE_TERRAIN_SPACE 20 #define BATTLE_TERRAIN_ULTRA_SPACE 21 +#define BATTLE_TERRAIN_COUNT 22 + #define B_WAIT_TIME_LONG 64 #define B_WAIT_TIME_MED 48 #define B_WAIT_TIME_SHORT 32 diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 61723ced4..9d94966dd 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -155,6 +155,7 @@ #define B_SKILL_SWAP GEN_7 // In Gen4+, Skill Swap triggers switch-in abilities after use. #define B_SECRET_POWER_EFFECT GEN_7 // Secret Power's effects change depending on the generation. See GetSecretPowerMoveEffect. #define B_SECRET_POWER_ANIMATION GEN_7 // Secret Power's animations change depending on the generation. +#define B_NATURE_POWER_MOVES GEN_8 // Nature Power calls different moves depending on the generation. // 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 fcba67bca..57f02e2f5 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1097,18 +1097,76 @@ static const u16 sMoveEffectsForbiddenToInstruct[] = FORBIDDEN_INSTRUCT_END }; -static const u16 sNaturePowerMoves[] = +static const u16 sNaturePowerMoves[BATTLE_TERRAIN_COUNT] = { +#if B_NATURE_POWER_MOVES >= GEN_7 [BATTLE_TERRAIN_GRASS] = MOVE_ENERGY_BALL, [BATTLE_TERRAIN_LONG_GRASS] = MOVE_ENERGY_BALL, [BATTLE_TERRAIN_SAND] = MOVE_EARTH_POWER, - [BATTLE_TERRAIN_UNDERWATER] = MOVE_HYDRO_PUMP, [BATTLE_TERRAIN_WATER] = MOVE_HYDRO_PUMP, [BATTLE_TERRAIN_POND] = MOVE_HYDRO_PUMP, [BATTLE_TERRAIN_MOUNTAIN] = MOVE_EARTH_POWER, - [BATTLE_TERRAIN_CAVE] = MOVE_POWER_GEM, + [BATTLE_TERRAIN_CAVE] = MOVE_EARTH_POWER, [BATTLE_TERRAIN_BUILDING] = MOVE_TRI_ATTACK, - [BATTLE_TERRAIN_PLAIN] = MOVE_TRI_ATTACK + [BATTLE_TERRAIN_PLAIN] = MOVE_TRI_ATTACK, + [BATTLE_TERRAIN_SNOW] = MOVE_ICE_BEAM, +#elif B_NATURE_POWER_MOVES == GEN_6 + [BATTLE_TERRAIN_GRASS] = MOVE_ENERGY_BALL, + [BATTLE_TERRAIN_LONG_GRASS] = MOVE_ENERGY_BALL, + [BATTLE_TERRAIN_SAND] = MOVE_EARTH_POWER, + [BATTLE_TERRAIN_WATER] = MOVE_HYDRO_PUMP, + [BATTLE_TERRAIN_POND] = MOVE_HYDRO_PUMP, + [BATTLE_TERRAIN_MOUNTAIN] = MOVE_EARTH_POWER, + [BATTLE_TERRAIN_CAVE] = MOVE_EARTH_POWER, + [BATTLE_TERRAIN_BUILDING] = MOVE_TRI_ATTACK, + [BATTLE_TERRAIN_PLAIN] = MOVE_TRI_ATTACK, + [BATTLE_TERRAIN_SNOW] = MOVE_FROST_BREATH, +#elif B_NATURE_POWER_MOVES == GEN_5 + [BATTLE_TERRAIN_GRASS] = MOVE_SEED_BOMB, + [BATTLE_TERRAIN_LONG_GRASS] = MOVE_SEED_BOMB, + [BATTLE_TERRAIN_SAND] = MOVE_EARTHQUAKE, + [BATTLE_TERRAIN_WATER] = MOVE_HYDRO_PUMP, + [BATTLE_TERRAIN_POND] = MOVE_HYDRO_PUMP, + [BATTLE_TERRAIN_MOUNTAIN] = MOVE_EARTHQUAKE, + [BATTLE_TERRAIN_CAVE] = MOVE_EARTHQUAKE, + [BATTLE_TERRAIN_BUILDING] = MOVE_TRI_ATTACK, + [BATTLE_TERRAIN_PLAIN] = MOVE_EARTHQUAKE, + [BATTLE_TERRAIN_SNOW] = MOVE_BLIZZARD, +#elif B_NATURE_POWER_MOVES == GEN_4 + [BATTLE_TERRAIN_GRASS] = MOVE_SEED_BOMB, + [BATTLE_TERRAIN_LONG_GRASS] = MOVE_SEED_BOMB, + [BATTLE_TERRAIN_SAND] = MOVE_EARTHQUAKE, + [BATTLE_TERRAIN_WATER] = MOVE_HYDRO_PUMP, + [BATTLE_TERRAIN_POND] = MOVE_HYDRO_PUMP, + [BATTLE_TERRAIN_MOUNTAIN] = MOVE_ROCK_SLIDE, + [BATTLE_TERRAIN_CAVE] = MOVE_ROCK_SLIDE, + [BATTLE_TERRAIN_BUILDING] = MOVE_TRI_ATTACK, + [BATTLE_TERRAIN_PLAIN] = MOVE_EARTHQUAKE, + [BATTLE_TERRAIN_SNOW] = MOVE_BLIZZARD, +#else // Gen 1-3 + [BATTLE_TERRAIN_GRASS] = MOVE_STUN_SPORE, + [BATTLE_TERRAIN_LONG_GRASS] = MOVE_RAZOR_LEAF, + [BATTLE_TERRAIN_SAND] = MOVE_EARTHQUAKE, + [BATTLE_TERRAIN_WATER] = MOVE_SURF, + [BATTLE_TERRAIN_POND] = MOVE_BUBBLE_BEAM, + [BATTLE_TERRAIN_MOUNTAIN] = MOVE_ROCK_SLIDE, + [BATTLE_TERRAIN_CAVE] = MOVE_SHADOW_BALL, + [BATTLE_TERRAIN_BUILDING] = MOVE_SWIFT, + [BATTLE_TERRAIN_PLAIN] = MOVE_SWIFT, + [BATTLE_TERRAIN_SNOW] = MOVE_BLIZZARD, +#endif + [BATTLE_TERRAIN_UNDERWATER] = MOVE_HYDRO_PUMP, + [BATTLE_TERRAIN_SOARING] = MOVE_AIR_SLASH, + [BATTLE_TERRAIN_SKY_PILLAR] = MOVE_AIR_SLASH, + [BATTLE_TERRAIN_BURIAL_GROUND] = MOVE_SHADOW_BALL, + [BATTLE_TERRAIN_PUDDLE] = MOVE_MUD_BOMB, + [BATTLE_TERRAIN_MARSH] = MOVE_MUD_BOMB, + [BATTLE_TERRAIN_SWAMP] = MOVE_MUD_BOMB, + [BATTLE_TERRAIN_ICE] = MOVE_ICE_BEAM, + [BATTLE_TERRAIN_VOLCANO] = MOVE_LAVA_PLUME, + [BATTLE_TERRAIN_DISTORTION_WORLD] = MOVE_TRI_ATTACK, + [BATTLE_TERRAIN_SPACE] = MOVE_DRACO_METEOR, + [BATTLE_TERRAIN_ULTRA_SPACE] = MOVE_PSYSHOCK, }; static const u16 sPickupItems[] = @@ -11866,6 +11924,8 @@ u16 GetNaturePowerMove(void) return MOVE_ENERGY_BALL; else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN) return MOVE_PSYCHIC; + else if (sNaturePowerMoves == MOVE_NONE) + return MOVE_TRI_ATTACK; return sNaturePowerMoves[gBattleTerrain]; } From 1c4a0c205acc405d3dff3590e1ed88e70ed4a206 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Sat, 6 Nov 2021 19:09:35 -0300 Subject: [PATCH 19/42] Camouflage types config + extra terrains --- include/constants/battle_config.h | 1 + src/battle_script_commands.c | 42 +++++++++++++++++++++++-------- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 9d94966dd..be81610cc 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -156,6 +156,7 @@ #define B_SECRET_POWER_EFFECT GEN_7 // Secret Power's effects change depending on the generation. See GetSecretPowerMoveEffect. #define B_SECRET_POWER_ANIMATION GEN_7 // Secret Power's animations change depending on the generation. #define B_NATURE_POWER_MOVES GEN_8 // Nature Power calls different moves depending on the generation. +#define B_CAMOUFLAGE_TYPES GEN_7 // Camouflage changes the user to different types depending on the generation // 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 57f02e2f5..85ddede46 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1211,18 +1211,38 @@ static const u8 sPickupProbabilities[] = 30, 40, 50, 60, 70, 80, 90, 94, 98 }; -static const u8 sTerrainToType[] = +static const u8 sTerrainToType[BATTLE_TERRAIN_COUNT] = { - [BATTLE_TERRAIN_GRASS] = TYPE_GRASS, - [BATTLE_TERRAIN_LONG_GRASS] = TYPE_GRASS, - [BATTLE_TERRAIN_SAND] = TYPE_GROUND, - [BATTLE_TERRAIN_UNDERWATER] = TYPE_WATER, - [BATTLE_TERRAIN_WATER] = TYPE_WATER, - [BATTLE_TERRAIN_POND] = TYPE_WATER, - [BATTLE_TERRAIN_MOUNTAIN] = TYPE_GROUND, - [BATTLE_TERRAIN_CAVE] = TYPE_ROCK, - [BATTLE_TERRAIN_BUILDING] = TYPE_NORMAL, - [BATTLE_TERRAIN_PLAIN] = TYPE_NORMAL, + [BATTLE_TERRAIN_GRASS] = TYPE_GRASS, + [BATTLE_TERRAIN_LONG_GRASS] = TYPE_GRASS, + [BATTLE_TERRAIN_SAND] = TYPE_GROUND, + [BATTLE_TERRAIN_UNDERWATER] = TYPE_WATER, + [BATTLE_TERRAIN_WATER] = TYPE_WATER, + [BATTLE_TERRAIN_POND] = TYPE_WATER, + [BATTLE_TERRAIN_CAVE] = TYPE_ROCK, + [BATTLE_TERRAIN_BUILDING] = TYPE_NORMAL, + [BATTLE_TERRAIN_SOARING] = TYPE_FLYING, + [BATTLE_TERRAIN_SKY_PILLAR] = TYPE_FLYING, + [BATTLE_TERRAIN_BURIAL_GROUND] = TYPE_GHOST, + [BATTLE_TERRAIN_PUDDLE] = TYPE_GROUND, + [BATTLE_TERRAIN_MARSH] = TYPE_GROUND, + [BATTLE_TERRAIN_SWAMP] = TYPE_GROUND, + [BATTLE_TERRAIN_SNOW] = TYPE_ICE, + [BATTLE_TERRAIN_ICE] = TYPE_ICE, + [BATTLE_TERRAIN_VOLCANO] = TYPE_FIRE, + [BATTLE_TERRAIN_DISTORTION_WORLD] = TYPE_NORMAL, + [BATTLE_TERRAIN_SPACE] = TYPE_DRAGON, + [BATTLE_TERRAIN_ULTRA_SPACE] = TYPE_PSYCHIC, +#if B_CAMOUFLAGE_TYPES >= GEN_5 + [BATTLE_TERRAIN_MOUNTAIN] = TYPE_GROUND, + [BATTLE_TERRAIN_PLAIN] = TYPE_GROUND, +#elif B_CAMOUFLAGE_TYPES == GEN_4 + [BATTLE_TERRAIN_MOUNTAIN] = TYPE_ROCK, + [BATTLE_TERRAIN_PLAIN] = TYPE_GROUND, +#else + [BATTLE_TERRAIN_MOUNTAIN] = TYPE_ROCK, + [BATTLE_TERRAIN_PLAIN] = TYPE_NORMAL, +#endif }; // - ITEM_ULTRA_BALL skips Master Ball and ITEM_NONE From 8773e552ace6994a85dd728dee32f29dde984d14 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Sat, 6 Nov 2021 19:24:06 -0300 Subject: [PATCH 20/42] Organized config and added failsafe to AnimTask_SetCamouflageBlend --- include/constants/battle_config.h | 30 +++++++++++++++--------------- src/battle_anim_utility_funcs.c | 1 + 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index be81610cc..5338b304e 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -95,7 +95,6 @@ #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. #define B_PARALYSIS_SPEED GEN_7 // In Gen7+, Speed is decreased by 50% instead of 75%. -#define B_TERRAIN_TYPE_BOOST GEN_8 // In Gen8, damage is boosted by 30% instead of 50%. #define B_CONFUSION_SELF_DMG_CHANCE GEN_7 // In Gen7+, confusion has a 33.3% of self-damage, instead of 50%. #define B_MULTI_HIT_CHANCE GEN_7 // In Gen5+, multi-hit moves have different %. See Cmd_setmultihitcounter for values. @@ -153,10 +152,6 @@ #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_SECRET_POWER_EFFECT GEN_7 // Secret Power's effects change depending on the generation. See GetSecretPowerMoveEffect. -#define B_SECRET_POWER_ANIMATION GEN_7 // Secret Power's animations change depending on the generation. -#define B_NATURE_POWER_MOVES GEN_8 // Nature Power calls different moves depending on the generation. -#define B_CAMOUFLAGE_TYPES GEN_7 // Camouflage changes the user to different types depending on the generation // 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. @@ -187,26 +182,31 @@ // Eg: Replace with VAR_UNUSED_0x40F7 so you can use VAR_TERRAIN for that feature. #define VAR_TERRAIN 0 // If this var has a value, assigning a STATUS_FIELD_xx_TERRAIN to it before battle causes the battle to start with that terrain active +// Terrain settings +#define B_TERRAIN_BG_CHANGE TRUE // If set to TRUE, terrain moves permanently change the default battle background until the effect fades. +#define B_THUNDERSTORM_TERRAIN TRUE // If TRUE, overworld Thunderstorm generates Rain and Electric Terrain as in Gen 8. +#define B_TERRAIN_TYPE_BOOST GEN_8 // In Gen8, damage is boosted by 30% instead of 50%. +#define B_SECRET_POWER_EFFECT GEN_7 // Secret Power's effects change depending on terrain and generation. See GetSecretPowerMoveEffect. +#define B_SECRET_POWER_ANIMATION GEN_7 // Secret Power's animations change depending on terrain and generation. +#define B_NATURE_POWER_MOVES GEN_8 // Nature Power calls different moves depending on terrain and generation. See sNaturePowerMoves. +#define B_CAMOUFLAGE_TYPES GEN_7 // Camouflage changes the user to different types depending on terrain and generation. See sTerrainToType. + // Interface settings #define B_ABILITY_POP_UP TRUE // In Gen5+, the Pokémon abilities are displayed in a pop-up, when they activate in battle. #define B_FAST_INTRO TRUE // If set to TRUE, battle intro texts print at the same time as animation of a Pokémon, as opposing to waiting for the animation to end. #define B_SHOW_TARGETS TRUE // If set to TRUE, all available targets, for moves hitting 2 or 3 Pokémon, will be shown before selecting a move. #define B_SHOW_SPLIT_ICON TRUE // If set to TRUE, it will show an icon in the summary showing the move's category split. #define B_HIDE_HEALTHBOX_IN_ANIMS TRUE // If set to TRUE, hides healthboxes during move animations. -#define B_TERRAIN_BG_CHANGE TRUE // If set to TRUE, terrain moves permanently change the default battle background until the effect fades. -// Critical Capture -#define B_CRITICAL_CAPTURE TRUE // If set to TRUE, Critical Capture will be enabled. -#define B_CATCHING_CHARM_BOOST 20 // % boost in Critical Capture odds if player has the Catching Charm. - -// Last Used Ball -#define B_LAST_USED_BALL TRUE // If TRUE, the "last used ball" feature from Gen 7 will be implemented -#define B_LAST_USED_BALL_BUTTON R_BUTTON // If last used ball is implemented, this button (or button combo) will trigger throwing the last used ball. +// Catching settings +#define B_SEMI_INVULNERABLE_CATCH GEN_7 // In Gen4+, you cannot throw a ball against a Pokemon that is in a semi-invulnerable state (dig/fly/etc) +#define B_CATCHING_CHARM_BOOST 20 // % boost in Critical Capture odds if player has the Catching Charm. +#define B_CRITICAL_CAPTURE TRUE // If set to TRUE, Critical Capture will be enabled. +#define B_LAST_USED_BALL TRUE // If TRUE, the "last used ball" feature from Gen 7 will be implemented +#define B_LAST_USED_BALL_BUTTON R_BUTTON // If last used ball is implemented, this button (or button combo) will trigger throwing the last used ball. // Other #define B_DOUBLE_WILD_CHANCE 0 // % chance of encountering two Pokémon in a Wild Encounter. -#define B_THUNDERSTORM_TERRAIN TRUE // If TRUE, overworld Thunderstorm generates Rain and Electric Terrain as in Gen 8. -#define B_SEMI_INVULNERABLE_CATCH GEN_7 // In Gen4+, you cannot throw a ball against a Pokemon that is in a semi-invulnerable state (dig/fly/etc) // Animation Settings #define B_NEW_SWORD_PARTICLE FALSE // If set to TRUE, it updates Swords Dance's particle. diff --git a/src/battle_anim_utility_funcs.c b/src/battle_anim_utility_funcs.c index 0f35657db..c85a918da 100644 --- a/src/battle_anim_utility_funcs.c +++ b/src/battle_anim_utility_funcs.c @@ -136,6 +136,7 @@ void AnimTask_SetCamouflageBlend(u8 taskId) gBattleAnimArgs[4] = RGB(31, 31, 31); break; case BATTLE_TERRAIN_PLAIN: + default: gBattleAnimArgs[4] = RGB(31, 31, 31); break; } From 4e6a459b1439c9e81dbcc1068b09dfba3781571b Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Sat, 6 Nov 2021 19:46:52 -0300 Subject: [PATCH 21/42] Optimized terrain timers --- include/battle.h | 5 +---- src/battle_script_commands.c | 13 +++++-------- src/battle_util.c | 16 ++++++++-------- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/include/battle.h b/include/battle.h index 7602c5d09..3c4b4d220 100644 --- a/include/battle.h +++ b/include/battle.h @@ -222,10 +222,7 @@ struct FieldTimer u8 wonderRoomTimer; u8 magicRoomTimer; u8 trickRoomTimer; - u8 grassyTerrainTimer; - u8 mistyTerrainTimer; - u8 electricTerrainTimer; - u8 psychicTerrainTimer; + u8 terrainTimer; u8 gravityTimer; u8 fairyLockTimer; }; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 85ddede46..4eec84088 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -7328,19 +7328,19 @@ static void HandleTerrainMove(u32 moveEffect) switch (moveEffect) { case EFFECT_MISTY_TERRAIN: - statusFlag = STATUS_FIELD_MISTY_TERRAIN, timer = &gFieldTimers.mistyTerrainTimer; + statusFlag = STATUS_FIELD_MISTY_TERRAIN, timer = &gFieldTimers.terrainTimer; gBattleCommunication[MULTISTRING_CHOOSER] = 0; break; case EFFECT_GRASSY_TERRAIN: - statusFlag = STATUS_FIELD_GRASSY_TERRAIN, timer = &gFieldTimers.grassyTerrainTimer; + statusFlag = STATUS_FIELD_GRASSY_TERRAIN, timer = &gFieldTimers.terrainTimer; gBattleCommunication[MULTISTRING_CHOOSER] = 1; break; case EFFECT_ELECTRIC_TERRAIN: - statusFlag = STATUS_FIELD_ELECTRIC_TERRAIN, timer = &gFieldTimers.electricTerrainTimer; + statusFlag = STATUS_FIELD_ELECTRIC_TERRAIN, timer = &gFieldTimers.terrainTimer; gBattleCommunication[MULTISTRING_CHOOSER] = 2; break; case EFFECT_PSYCHIC_TERRAIN: - statusFlag = STATUS_FIELD_PSYCHIC_TERRAIN, timer = &gFieldTimers.psychicTerrainTimer; + statusFlag = STATUS_FIELD_PSYCHIC_TERRAIN, timer = &gFieldTimers.terrainTimer; gBattleCommunication[MULTISTRING_CHOOSER] = 3; break; } @@ -8937,22 +8937,19 @@ static void Cmd_various(void) gBattlescriptCurrInstr += 7; // can heal return; case VARIOUS_REMOVE_TERRAIN: + gFieldTimers.terrainTimer = 0; switch (gFieldStatuses & STATUS_FIELD_TERRAIN_ANY) { case STATUS_FIELD_MISTY_TERRAIN: - gFieldTimers.mistyTerrainTimer = 0; gBattleCommunication[MULTISTRING_CHOOSER] = 0; break; case STATUS_FIELD_GRASSY_TERRAIN: - gFieldTimers.grassyTerrainTimer = 0; gBattleCommunication[MULTISTRING_CHOOSER] = 1; break; case STATUS_FIELD_ELECTRIC_TERRAIN: - gFieldTimers.electricTerrainTimer = 0; gBattleCommunication[MULTISTRING_CHOOSER] = 2; break; case STATUS_FIELD_PSYCHIC_TERRAIN: - gFieldTimers.psychicTerrainTimer = 0; gBattleCommunication[MULTISTRING_CHOOSER] = 3; break; default: diff --git a/src/battle_util.c b/src/battle_util.c index 15d13b85a..66247c7f6 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2326,7 +2326,7 @@ u8 DoFieldEndTurnEffects(void) break; case ENDTURN_ELECTRIC_TERRAIN: if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN - && (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.electricTerrainTimer == 0)) + && (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.terrainTimer == 0)) { gFieldStatuses &= ~(STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_TERRAIN_PERMANENT); TryToRevertMimicry(); @@ -2337,7 +2337,7 @@ u8 DoFieldEndTurnEffects(void) break; case ENDTURN_MISTY_TERRAIN: if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN - && (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.mistyTerrainTimer == 0)) + && (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.terrainTimer == 0)) { gFieldStatuses &= ~(STATUS_FIELD_MISTY_TERRAIN); TryToRevertMimicry(); @@ -2350,7 +2350,7 @@ u8 DoFieldEndTurnEffects(void) if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN) { if (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) - && (gFieldTimers.grassyTerrainTimer == 0 || --gFieldTimers.grassyTerrainTimer == 0)) + && (gFieldTimers.terrainTimer == 0 || --gFieldTimers.terrainTimer == 0)) { gFieldStatuses &= ~(STATUS_FIELD_GRASSY_TERRAIN); TryToRevertMimicry(); @@ -2362,7 +2362,7 @@ u8 DoFieldEndTurnEffects(void) break; case ENDTURN_PSYCHIC_TERRAIN: if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN - && (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.psychicTerrainTimer == 0)) + && (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.terrainTimer == 0)) { gFieldStatuses &= ~(STATUS_FIELD_PSYCHIC_TERRAIN); TryToRevertMimicry(); @@ -4338,28 +4338,28 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move } break; case ABILITY_ELECTRIC_SURGE: - if (TryChangeBattleTerrain(battler, STATUS_FIELD_ELECTRIC_TERRAIN, &gFieldTimers.electricTerrainTimer)) + if (TryChangeBattleTerrain(battler, STATUS_FIELD_ELECTRIC_TERRAIN, &gFieldTimers.terrainTimer)) { BattleScriptPushCursorAndCallback(BattleScript_ElectricSurgeActivates); effect++; } break; case ABILITY_GRASSY_SURGE: - if (TryChangeBattleTerrain(battler, STATUS_FIELD_GRASSY_TERRAIN, &gFieldTimers.grassyTerrainTimer)) + if (TryChangeBattleTerrain(battler, STATUS_FIELD_GRASSY_TERRAIN, &gFieldTimers.terrainTimer)) { BattleScriptPushCursorAndCallback(BattleScript_GrassySurgeActivates); effect++; } break; case ABILITY_MISTY_SURGE: - if (TryChangeBattleTerrain(battler, STATUS_FIELD_MISTY_TERRAIN, &gFieldTimers.mistyTerrainTimer)) + if (TryChangeBattleTerrain(battler, STATUS_FIELD_MISTY_TERRAIN, &gFieldTimers.terrainTimer)) { BattleScriptPushCursorAndCallback(BattleScript_MistySurgeActivates); effect++; } break; case ABILITY_PSYCHIC_SURGE: - if (TryChangeBattleTerrain(battler, STATUS_FIELD_PSYCHIC_TERRAIN, &gFieldTimers.psychicTerrainTimer)) + if (TryChangeBattleTerrain(battler, STATUS_FIELD_PSYCHIC_TERRAIN, &gFieldTimers.terrainTimer)) { BattleScriptPushCursorAndCallback(BattleScript_PsychicSurgeActivates); effect++; From c2a17510a962b9f26fbce84399b9df23aefbd31d Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Sun, 7 Nov 2021 11:25:08 -0300 Subject: [PATCH 22/42] Terrain Pulse animations --- data/battle_anim_scripts.s | 82 +++++++++++++++++++++++++++++++++++++- src/battle_anim_new.c | 22 ++++++++++ src/battle_main.c | 2 +- 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 3e7f02692..b10c937ae 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -14082,7 +14082,87 @@ Move_RISING_VOLTAGE:: end @to do: Move_TERRAIN_PULSE:: - goto Move_DRAGON_PULSE @Temporary, needs to setup different animations based on terrain + loadspritegfx ANIM_TAG_DRAGON_PULSE + monbg ANIM_TARGET + setalpha 12, 8 + createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, 1, 1, 0, 7, RGB_BLACK + launchtask AnimTask_TerrainPulse 0x5 0x0 + jumpargeq 0x0, TYPE_ELECTRIC, TerrainPulseElectric + jumpargeq 0x0, TYPE_GRASS, TerrainPulseGrass + jumpargeq 0x0, TYPE_FAIRY, TerrainPulseFairy + jumpargeq 0x0, TYPE_PSYCHIC, TerrainPulsePsychic +TerrainPulseNormal: + createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_DRAGON_PULSE, 0, 12, 12, RGB_WHITE + waitforvisualfinish + playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER + createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_PSYBEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 3, 4, 0, 15 + call DragonPulseParticle + call DragonPulseParticle + createvisualtask AnimTask_SwayMon, 5, 0, 2, 51200, 24, ANIM_TARGET + createvisualtask AnimTask_BlendColorCycle, 2, 4, 2, 2, 0, 12, RGB_WHITE + goto TerrainPulseEnd + +TerrainPulseElectric: + createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_DRAGON_PULSE, 0, 12, 12, RGB(27, 27, 0) + waitforvisualfinish + playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER + createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_PSYBEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 3, 4, 0, 15 + call DragonPulseParticle + call DragonPulseParticle + createvisualtask AnimTask_SwayMon, 5, 0, 4, 51200, 24, ANIM_TARGET + createvisualtask AnimTask_BlendColorCycle, 2, 4, 2, 2, 0, 12, RGB(27, 27, 0) + goto TerrainPulseEnd + +TerrainPulseGrass: + createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_DRAGON_PULSE, 0, 12, 12, RGB(11, 26, 11) + waitforvisualfinish + playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER + createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_PSYBEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 3, 4, 0, 15 + call DragonPulseParticle + call DragonPulseParticle + createvisualtask AnimTask_SwayMon, 5, 0, 4, 51200, 24, ANIM_TARGET + createvisualtask AnimTask_BlendColorCycle, 2, 4, 2, 2, 0, 12, RGB(11, 26, 11) + goto TerrainPulseEnd + +TerrainPulseFairy: + createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_DRAGON_PULSE, 0, 12, 12, RGB(31, 24, 31) + waitforvisualfinish + playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER + createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_PSYBEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 3, 4, 0, 15 + call DragonPulseParticle + call DragonPulseParticle + createvisualtask AnimTask_SwayMon, 5, 0, 4, 51200, 24, ANIM_TARGET + createvisualtask AnimTask_BlendColorCycle, 2, 4, 2, 2, 0, 12, RGB(31, 24, 31) + goto TerrainPulseEnd + +TerrainPulsePsychic: + createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_DRAGON_PULSE, 0, 12, 12, RGB(27, 0, 13) + waitforvisualfinish + playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER + createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_PSYBEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 3, 4, 0, 15 + call DragonPulseParticle + call DragonPulseParticle + createvisualtask AnimTask_SwayMon, 5, 0, 4, 51200, 24, ANIM_TARGET + createvisualtask AnimTask_BlendColorCycle, 2, 4, 2, 2, 0, 12, RGB(27, 0, 13) + goto TerrainPulseEnd + +TerrainPulseEnd: + call DragonPulseParticle + call DragonPulseParticle + call DragonPulseParticle + call DragonPulseParticle + call DragonPulseParticle + call DragonPulseParticle + call DragonPulseParticle + call DragonPulseParticle + call DragonPulseParticle + waitforvisualfinish + delay 1 + createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, 1, 1, 7, 0, RGB_BLACK + waitforvisualfinish + blendoff + clearmonbg ANIM_TARGET + end Move_SKITTER_SMACK:: end @to do: diff --git a/src/battle_anim_new.c b/src/battle_anim_new.c index 3bc45939f..63fed0b3d 100644 --- a/src/battle_anim_new.c +++ b/src/battle_anim_new.c @@ -5073,3 +5073,25 @@ void AnimTask_ShellSideArm(u8 taskId) gBattleAnimArgs[0] = FALSE; DestroyAnimVisualTask(taskId); } + +void AnimTask_TerrainPulse(u8 taskId) +{ + if (IsBattlerTerrainAffected(gBattleAnimAttacker, STATUS_FIELD_TERRAIN_ANY)) + { + if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) + gBattleAnimArgs[0] = TYPE_ELECTRIC; + else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN) + gBattleAnimArgs[0] = TYPE_GRASS; + else if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN) + gBattleAnimArgs[0] = TYPE_FAIRY; + else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN) + gBattleAnimArgs[0] = TYPE_PSYCHIC; + else //failsafe + gBattleAnimArgs[0] = 0; + } + else + { + gBattleAnimArgs[0] = 0; + } + DestroyAnimVisualTask(taskId); +} diff --git a/src/battle_main.c b/src/battle_main.c index 63c4982f1..84491987e 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -5204,7 +5204,7 @@ void SetTypeBeforeUsingMove(u16 move, u8 battlerAtk) gBattleStruct->dynamicMoveType = TYPE_FAIRY | 0x80; else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN) gBattleStruct->dynamicMoveType = TYPE_PSYCHIC | 0x80; - else + else //failsafe gBattleStruct->dynamicMoveType = TYPE_NORMAL | 0x80; } } From b358f774dd1f53bf10c87c345e211f80dc48822b Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Sun, 7 Nov 2021 14:40:18 -0300 Subject: [PATCH 23/42] Fixed the offensive boost of the Soul Dew --- 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 dbc46a3ec..9c5b77cd6 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8091,7 +8091,7 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe #if B_SOUL_DEW_BOOST >= GEN_7 if ((gBattleMons[battlerAtk].species == SPECIES_LATIAS || gBattleMons[battlerAtk].species == SPECIES_LATIOS) && (moveType == TYPE_PSYCHIC || moveType == TYPE_DRAGON)) #else - if ((gBattleMons[battlerAtk].species == SPECIES_LATIAS || gBattleMons[battlerAtk].species == SPECIES_LATIOS) && !(gBattleTypeFlags & BATTLE_TYPE_FRONTIER)) + if ((gBattleMons[battlerAtk].species == SPECIES_LATIAS || gBattleMons[battlerAtk].species == SPECIES_LATIOS) && !(gBattleTypeFlags & BATTLE_TYPE_FRONTIER) && IS_MOVE_SPECIAL(move)) #endif MulModifier(&modifier, holdEffectModifier); break; From 3a113e33b26ceaaa8d7f0492796796c677fdab44 Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Mon, 8 Nov 2021 19:28:09 +1300 Subject: [PATCH 24/42] Uncomment AI Full Metal Body checks This ability is Clear Body with a different name, so it should be working and doesn't need to be commented out. --- src/battle_ai_util.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 1e229fbe8..781fb50e6 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -1685,7 +1685,7 @@ bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility) && defAbility != ABILITY_CONTRARY && defAbility != ABILITY_CLEAR_BODY && defAbility != ABILITY_WHITE_SMOKE - //&& defAbility != ABILITY_FULL_METAL_BODY + && defAbility != ABILITY_FULL_METAL_BODY && defAbility != ABILITY_HYPER_CUTTER) return TRUE; return FALSE; @@ -1701,7 +1701,7 @@ bool32 ShouldLowerDefense(u8 battlerAtk, u8 battlerDef, u16 defAbility) && defAbility != ABILITY_CONTRARY && defAbility != ABILITY_CLEAR_BODY && defAbility != ABILITY_WHITE_SMOKE - //&& defAbility != ABILITY_FULL_METAL_BODY + && defAbility != ABILITY_FULL_METAL_BODY && defAbility != ABILITY_BIG_PECKS) return TRUE; return FALSE; @@ -1715,7 +1715,7 @@ bool32 ShouldLowerSpeed(u8 battlerAtk, u8 battlerDef, u16 defAbility) if (IsAiFaster(AI_CHECK_SLOWER) && defAbility != ABILITY_CONTRARY && defAbility != ABILITY_CLEAR_BODY - //&& defAbility != ABILITY_FULL_METAL_BODY + && defAbility != ABILITY_FULL_METAL_BODY && defAbility != ABILITY_WHITE_SMOKE) return TRUE; return FALSE; @@ -1730,7 +1730,7 @@ bool32 ShouldLowerSpAtk(u8 battlerAtk, u8 battlerDef, u16 defAbility) && HasMoveWithSplit(battlerDef, SPLIT_SPECIAL) && defAbility != ABILITY_CONTRARY && defAbility != ABILITY_CLEAR_BODY - //&& defAbility != ABILITY_FULL_METAL_BODY + && defAbility != ABILITY_FULL_METAL_BODY && defAbility != ABILITY_WHITE_SMOKE) return TRUE; return FALSE; @@ -1745,7 +1745,7 @@ bool32 ShouldLowerSpDef(u8 battlerAtk, u8 battlerDef, u16 defAbility) && HasMoveWithSplit(battlerAtk, SPLIT_SPECIAL) && defAbility != ABILITY_CONTRARY && defAbility != ABILITY_CLEAR_BODY - //&& defAbility != ABILITY_FULL_METAL_BODY + && defAbility != ABILITY_FULL_METAL_BODY && defAbility != ABILITY_WHITE_SMOKE) return TRUE; return FALSE; @@ -1759,7 +1759,7 @@ bool32 ShouldLowerAccuracy(u8 battlerAtk, u8 battlerDef, u16 defAbility) if (defAbility != ABILITY_CONTRARY && defAbility != ABILITY_CLEAR_BODY && defAbility != ABILITY_WHITE_SMOKE - //&& defAbility != ABILITY_FULL_METAL_BODY + && defAbility != ABILITY_FULL_METAL_BODY && defAbility != ABILITY_KEEN_EYE) return TRUE; return FALSE; @@ -1773,7 +1773,7 @@ bool32 ShouldLowerEvasion(u8 battlerAtk, u8 battlerDef, u16 defAbility) if (gBattleMons[battlerDef].statStages[STAT_EVASION] > DEFAULT_STAT_STAGE && defAbility != ABILITY_CONTRARY && defAbility != ABILITY_CLEAR_BODY - //&& defAbility != ABILITY_FULL_METAL_BODY + && defAbility != ABILITY_FULL_METAL_BODY && defAbility != ABILITY_WHITE_SMOKE) return TRUE; return FALSE; From d3a845d51170c6b103c15f908300727cb4f6da3c Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Mon, 8 Nov 2021 20:37:28 +1300 Subject: [PATCH 25/42] Fix CanAIFaintTarget Rename CanAIFaintTarget to CanIndexMoveFaintTarget and create a new function, CanAIFaintTarget, that checks if any known move can KO the target. --- include/battle_ai_util.h | 3 ++- src/battle_ai_main.c | 18 +++++++------- src/battle_ai_util.c | 54 +++++++++++++++++++++++++++++----------- 3 files changed, 51 insertions(+), 24 deletions(-) diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h index b6df2168e..1b2591899 100644 --- a/include/battle_ai_util.h +++ b/include/battle_ai_util.h @@ -35,7 +35,8 @@ u16 AI_GetHoldEffect(u32 battlerId); u32 AI_GetMoveAccuracy(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u8 atkHoldEffect, u8 defHoldEffect, u16 move); bool32 DoesBattlerIgnoreAbilityChecks(u16 atkAbility, u16 move); bool32 AI_WeatherHasEffect(void); -bool32 CanAttackerFaintTarget(u8 battlerAtk, u8 battlerDef, u8 index, u8 numHits); +bool32 CanAIFaintTarget(u8 battlerAtk, u8 battlerDef, u8 numHits); +bool32 CanIndexMoveFaintTarget(u8 battlerAtk, u8 battlerDef, u8 index, u8 numHits); bool32 AI_IsTerrainAffected(u8 battlerId, u32 flags); bool32 AI_IsBattlerGrounded(u8 battlerId); bool32 HasDamagingMove(u8 battlerId); diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 77196cf9a..7fbb43260 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -1473,7 +1473,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) else if (move == MOVE_FAKE_OUT) // filter out first impression { if ((AI_DATA->atkHoldEffect == HOLD_EFFECT_CHOICE_BAND || AI_DATA->atkAbility == ABILITY_GORILLA_TACTICS) - && (CountUsablePartyMons(battlerDef) > 0 || !CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))) + && (CountUsablePartyMons(battlerDef) > 0 || !CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))) { if (CountUsablePartyMons(battlerAtk) == 0) score -= 10; // Don't lock the attacker into Fake Out if they can't switch out afterwards. @@ -1714,7 +1714,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) if (AI_DATA->defAbility == ABILITY_WONDER_GUARD && effectiveness < AI_EFFECTIVENESS_x2) score -= 10; else if (AI_DATA->atkAbility != ABILITY_TRUANT - && !CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + && !CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) score -= 2; break; case EFFECT_SPITE: @@ -2465,7 +2465,7 @@ static s16 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) if (gBattleMoves[move].power == 0) return score; // can't make anything faint with no power - if (CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0) && gBattleMoves[move].effect != EFFECT_EXPLOSION) + if (CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0) && gBattleMoves[move].effect != EFFECT_EXPLOSION) { // this move can faint the target if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0 || GetMovePriority(battlerAtk, move) > 0) @@ -2707,7 +2707,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) && !IS_MOVE_STATUS(move) && HasMoveWithSplit(battlerAtkPartner, SPLIT_PHYSICAL) && BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_ATK) - && !CanAttackerFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 1)) + && !CanIndexMoveFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 1)) { RETURN_SCORE_PLUS(1); } @@ -2716,7 +2716,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) if (!IS_MOVE_STATUS(move) && (moveType == TYPE_DARK || moveType == TYPE_GHOST || moveType == TYPE_BUG) && BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_SPEED) - && !CanAttackerFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 1)) + && !CanIndexMoveFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 1)) { RETURN_SCORE_PLUS(1); } @@ -2782,7 +2782,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) && !IS_MOVE_STATUS(move) && HasMoveWithSplit(battlerAtkPartner, SPLIT_PHYSICAL) && BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_ATK) - && !CanAttackerFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 0)) + && !CanIndexMoveFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 0)) { RETURN_SCORE_PLUS(1); } @@ -2971,7 +2971,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) case ABILITY_BEAST_BOOST: if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // attacker should go first { - if (CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + if (CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) score += 8; // prioritize killing target for stat boost } break; @@ -3772,7 +3772,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) case EFFECT_FELL_STINGER: if (gBattleMons[battlerAtk].statStages[STAT_ATK] < MAX_STAT_STAGE && AI_DATA->atkAbility != ABILITY_CONTRARY - && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + && CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) { if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // Attacker goes first score += 9; @@ -4923,7 +4923,7 @@ static s16 AI_HPAware(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) } // consider target HP - if (CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + if (CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) { score += 2; } diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 781fb50e6..84637b683 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -1048,6 +1048,32 @@ bool32 CanTargetFaintAi(u8 battlerDef, u8 battlerAtk) return FALSE; } +// Check if AI mon has the means to faint the target with any of its moves. +// If numHits > 1, check if the target will be KO'ed by that number of hits (ignoring healing effects) +bool32 CanAIFaintTarget(u8 battlerAtk, u8 battlerDef, u8 numHits) +{ + s32 i, dmg; + u32 unusable = CheckMoveLimitations(battlerAtk, 0, 0xFF & ~MOVE_LIMITATION_PP); + u16 *moves = gBattleMons[battlerAtk].moves; + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] != MOVE_NONE && moves[i] != 0xFFFF && !(unusable & gBitTable[i])) + { + continue; + } + // Use the pre-calculated value in simulatedDmg instead of re-calculating it + dmg = AI_THINKING_STRUCT->simulatedDmg[battlerAtk][battlerDef][i]; + + if (numHits) + dmg *= numHits; + if (gBattleMons[battlerDef].hp <= dmg) + return TRUE; + } + + return FALSE; +} + bool32 CanMoveFaintBattler(u16 move, u8 battlerDef, u8 battlerAtk, u8 nHits) { s32 i, dmg; @@ -1677,7 +1703,7 @@ u32 CountNegativeStatStages(u8 battlerId) bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility) { - if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + if (IsAiFaster(AI_CHECK_FASTER) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (gBattleMons[battlerDef].statStages[STAT_ATK] > 4 @@ -1693,7 +1719,7 @@ bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility) bool32 ShouldLowerDefense(u8 battlerAtk, u8 battlerDef, u16 defAbility) { - if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + if (IsAiFaster(AI_CHECK_FASTER) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (gBattleMons[battlerDef].statStages[STAT_DEF] > 4 @@ -1709,7 +1735,7 @@ bool32 ShouldLowerDefense(u8 battlerAtk, u8 battlerDef, u16 defAbility) bool32 ShouldLowerSpeed(u8 battlerAtk, u8 battlerDef, u16 defAbility) { - if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + if (IsAiFaster(AI_CHECK_FASTER) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (IsAiFaster(AI_CHECK_SLOWER) @@ -1723,7 +1749,7 @@ bool32 ShouldLowerSpeed(u8 battlerAtk, u8 battlerDef, u16 defAbility) bool32 ShouldLowerSpAtk(u8 battlerAtk, u8 battlerDef, u16 defAbility) { - if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + if (IsAiFaster(AI_CHECK_FASTER) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (gBattleMons[battlerDef].statStages[STAT_SPATK] > 4 @@ -1738,7 +1764,7 @@ bool32 ShouldLowerSpAtk(u8 battlerAtk, u8 battlerDef, u16 defAbility) bool32 ShouldLowerSpDef(u8 battlerAtk, u8 battlerDef, u16 defAbility) { - if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + if (IsAiFaster(AI_CHECK_FASTER) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (gBattleMons[battlerDef].statStages[STAT_SPDEF] > 4 @@ -1753,7 +1779,7 @@ bool32 ShouldLowerSpDef(u8 battlerAtk, u8 battlerDef, u16 defAbility) bool32 ShouldLowerAccuracy(u8 battlerAtk, u8 battlerDef, u16 defAbility) { - if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + if (IsAiFaster(AI_CHECK_FASTER) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (defAbility != ABILITY_CONTRARY @@ -1767,7 +1793,7 @@ bool32 ShouldLowerAccuracy(u8 battlerAtk, u8 battlerDef, u16 defAbility) bool32 ShouldLowerEvasion(u8 battlerAtk, u8 battlerDef, u16 defAbility) { - if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + if (IsAiFaster(AI_CHECK_FASTER) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (gBattleMons[battlerDef].statStages[STAT_EVASION] > DEFAULT_STAT_STAGE @@ -1779,7 +1805,7 @@ bool32 ShouldLowerEvasion(u8 battlerAtk, u8 battlerDef, u16 defAbility) return FALSE; } -bool32 CanAttackerFaintTarget(u8 battlerAtk, u8 battlerDef, u8 index, u8 numHits) +bool32 CanIndexMoveFaintTarget(u8 battlerAtk, u8 battlerDef, u8 index, u8 numHits) { s32 dmg = AI_THINKING_STRUCT->simulatedDmg[battlerAtk][battlerDef][index]; @@ -2433,9 +2459,9 @@ bool32 ShouldPivot(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u8 mo if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // Attacker goes first { - if (!CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex, 0)) // Can't KO foe otherwise + if (!CanAIFaintTarget(battlerAtk, battlerDef, 0)) // Can't KO foe otherwise { - if (CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex, 2)) + if (CanAIFaintTarget(battlerAtk, battlerDef, 2)) { // attacker can kill target in two hits (theoretically) if (CanTargetFaintAi(battlerDef, battlerAtk)) @@ -2500,7 +2526,7 @@ bool32 ShouldPivot(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u8 mo } else if (CanTargetFaintAiWithMod(battlerDef, battlerAtk, 0, 2)) // Foe can 2HKO AI { - if (CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex, 0)) + if (CanAIFaintTarget(battlerAtk, battlerDef, 0)) { if (!BattlerWillFaintFromSecondaryDamage(battlerAtk, AI_DATA->atkAbility)) return CAN_TRY_PIVOT; // Use this move to KO if you must @@ -2512,7 +2538,7 @@ bool32 ShouldPivot(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u8 mo } else // Foe can 3HKO+ AI { - if (CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex, 0)) + if (CanAIFaintTarget(battlerAtk, battlerDef, 0)) { if (!BattlerWillFaintFromSecondaryDamage(battlerAtk, AI_DATA->atkAbility) // This is the only move that can KO && !hasStatBoost) //You're not wasting a valuable stat boost @@ -2520,7 +2546,7 @@ bool32 ShouldPivot(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u8 mo return CAN_TRY_PIVOT; } } - else if (CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex, 2)) + else if (CanAIFaintTarget(battlerAtk, battlerDef, 2)) { // can knock out foe in 2 hits if (IS_MOVE_STATUS(move) && (shouldSwitch //Damaging move @@ -2904,7 +2930,7 @@ bool32 ShouldUseRecoilMove(u8 battlerAtk, u8 battlerDef, u32 recoilDmg, u8 moveI if (recoilDmg >= gBattleMons[battlerAtk].hp //Recoil kills attacker && CountUsablePartyMons(battlerDef) != 0) //Foe has more than 1 target left { - if (recoilDmg >= gBattleMons[battlerDef].hp && !CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex, 0)) + if (recoilDmg >= gBattleMons[battlerDef].hp && !CanAIFaintTarget(battlerAtk, battlerDef, 0)) return TRUE; //If it's the only KO move then just use it else return FALSE; //Not as good to use move if you'll faint and not win From 03cab2058a7b6d77b670251fc0702e5b3c4cef2f Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Mon, 8 Nov 2021 23:57:16 +1300 Subject: [PATCH 26/42] Fix goof, make AI check PP in move limitations Was skipping valid moves instead of invalid ones in CanAIFaintTarget. Also, remove all instances of ~MOVE_LIMITATION_PP from the AI as it seemed detrimental. --- src/battle_ai_util.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 84637b683..71dc78d0a 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -660,9 +660,9 @@ bool32 MovesWithSplitUnusable(u32 attacker, u32 target, u32 split) for (i = 0; i < MAX_MON_MOVES; i++) { if (moves[i] != MOVE_NONE - && moves[i] != 0xFFFF - && GetBattleMoveSplit(moves[i]) == split - && !(unusable & gBitTable[i])) + && moves[i] != 0xFFFF + && GetBattleMoveSplit(moves[i]) == split + && !(unusable & gBitTable[i])) { SetTypeBeforeUsingMove(moves[i], attacker); GET_MOVE_TYPE(moves[i], moveType); @@ -1033,7 +1033,7 @@ bool32 IsAiFaster(u8 battler) bool32 CanTargetFaintAi(u8 battlerDef, u8 battlerAtk) { s32 i, dmg; - u32 unusable = CheckMoveLimitations(battlerDef, 0, 0xFF & ~MOVE_LIMITATION_PP); + u32 unusable = CheckMoveLimitations(battlerDef, 0, 0xFF); u16 *moves = gBattleResources->battleHistory->usedMoves[battlerDef]; for (i = 0; i < MAX_MON_MOVES; i++) @@ -1053,22 +1053,22 @@ bool32 CanTargetFaintAi(u8 battlerDef, u8 battlerAtk) bool32 CanAIFaintTarget(u8 battlerAtk, u8 battlerDef, u8 numHits) { s32 i, dmg; - u32 unusable = CheckMoveLimitations(battlerAtk, 0, 0xFF & ~MOVE_LIMITATION_PP); + u32 moveLimitations = CheckMoveLimitations(battlerAtk, 0, 0xFF); u16 *moves = gBattleMons[battlerAtk].moves; for (i = 0; i < MAX_MON_MOVES; i++) { - if (moves[i] != MOVE_NONE && moves[i] != 0xFFFF && !(unusable & gBitTable[i])) + if (moves[i] != MOVE_NONE && moves[i] != 0xFFFF && !(moveLimitations & gBitTable[i])) { - continue; - } - // Use the pre-calculated value in simulatedDmg instead of re-calculating it - dmg = AI_THINKING_STRUCT->simulatedDmg[battlerAtk][battlerDef][i]; + // Use the pre-calculated value in simulatedDmg instead of re-calculating it + dmg = AI_THINKING_STRUCT->simulatedDmg[battlerAtk][battlerDef][i]; - if (numHits) - dmg *= numHits; - if (gBattleMons[battlerDef].hp <= dmg) - return TRUE; + if (numHits) + dmg *= numHits; + + if (gBattleMons[battlerDef].hp <= dmg) + return TRUE; + } } return FALSE; @@ -1077,7 +1077,7 @@ bool32 CanAIFaintTarget(u8 battlerAtk, u8 battlerDef, u8 numHits) bool32 CanMoveFaintBattler(u16 move, u8 battlerDef, u8 battlerAtk, u8 nHits) { s32 i, dmg; - u32 unusable = CheckMoveLimitations(battlerDef, 0, 0xFF & ~MOVE_LIMITATION_PP); + u32 unusable = CheckMoveLimitations(battlerDef, 0, 0xFF); if (move != MOVE_NONE && move != 0xFFFF && !(unusable & gBitTable[i]) && AI_CalcDamage(move, battlerDef, battlerAtk) >= gBattleMons[battlerAtk].hp) return TRUE; @@ -1089,7 +1089,7 @@ bool32 CanMoveFaintBattler(u16 move, u8 battlerDef, u8 battlerAtk, u8 nHits) bool32 CanTargetFaintAiWithMod(u8 battlerDef, u8 battlerAtk, s32 hpMod, s32 dmgMod) { u32 i; - u32 unusable = CheckMoveLimitations(battlerDef, 0, 0xFF & ~MOVE_LIMITATION_PP); + u32 unusable = CheckMoveLimitations(battlerDef, 0, 0xFF); u16 *moves = gBattleResources->battleHistory->usedMoves[battlerDef]; for (i = 0; i < MAX_MON_MOVES; 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 27/42] 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 28/42] 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 29/42] 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 30/42] 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 31/42] 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 From adc1413d984b49b1c80e5574a9d650c07f38c35e Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Thu, 11 Nov 2021 17:48:15 -0500 Subject: [PATCH 32/42] 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 aaf02a37f..ba9c1b984 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 4b3fc11aa..8b23cdec3 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 6214d8b62511df9c5a0c519589d2b7a84f1ae66b Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 12 Nov 2021 07:47:24 -0500 Subject: [PATCH 33/42] 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 ba9c1b984..d28e9da5c 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 8b23cdec3..18847b8cc 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 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 34/42] 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 d28e9da5c..eb7600cc2 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 35/42] 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 34fa1d370..7ceb1d64b 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 24a758153..37c46055d 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 36/42] 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 37c46055d..65b149817 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 37/42] 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 65b149817..51aa36515 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 38/42] 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 51aa36515..d36a37072 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 39/42] 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 d36a37072..0dbe68acf 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 40/42] 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 0dbe68acf..578f6d180 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 41/42] 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 578f6d180..7134818e0 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 42/42] 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 eb7600cc2..8e72b2c99 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 7134818e0..3f9ba388f 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; }