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/58] 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 dec1596f21..a765aafddd 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 8d6dd5bdb2..6662cb2690 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/58] 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 6662cb2690..80bb69ecc4 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/58] 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 d7de920967..c7b4020f31 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 6cefba92a6..0f35657db4 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/58] 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 80bb69ecc4..1da3248d8b 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/58] 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 c7b4020f31..0b630072a9 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 5a9aec5251..f018ff5047 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 440e6e76b6..966d35971b 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 25db65f784..c7a5962ac9 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 462b58bd48..5ae5d80cbc 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 a7a2752e00..542594e803 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/58] 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 93202bed78..9460801377 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 2002431707..5f4fcf5362 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 25db65f784..62e31b8e1b 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 8d6dd5bdb2..6def00fed6 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 330a0014b9..ef0d572471 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 2d5ed4a1e2aad32f2b7e24ac57c8b6fbc7e80c7d Mon Sep 17 00:00:00 2001 From: Blackforest92 Date: Tue, 2 Nov 2021 12:53:11 +0700 Subject: [PATCH 07/58] Allow Giga Impact fadein background & upgrade its graphic --- data/battle_anim_scripts.s | 24 +++++++++++++----- .../battle_anims/backgrounds/giga_impact.pal | 19 -------------- .../backgrounds/new/giga_impact.pal | 19 ++++++++++++++ .../backgrounds/new/giga_impact.png | Bin 0 -> 2395 bytes .../backgrounds/new/giga_impact_contest.bin | 3 +++ .../backgrounds/new/giga_impact_opponent.bin | Bin 896 -> 896 bytes .../backgrounds/new/giga_impact_opponent.pal | 19 -------------- .../backgrounds/new/giga_impact_opponent.png | Bin 3056 -> 0 bytes .../backgrounds/new/giga_impact_player.bin | Bin 896 -> 896 bytes .../backgrounds/new/giga_impact_player.pal | 19 -------------- .../backgrounds/new/giga_impact_player.png | Bin 3098 -> 0 bytes .../backgrounds/new/spacial_rend_opponent.bin | 3 --- .../backgrounds/new/spacial_rend_player.bin | Bin 896 -> 0 bytes include/graphics.h | 8 +++--- src/battle_anim.c | 10 ++++---- src/graphics.c | 17 +++++-------- 16 files changed, 55 insertions(+), 86 deletions(-) delete mode 100644 graphics/battle_anims/backgrounds/giga_impact.pal create mode 100644 graphics/battle_anims/backgrounds/new/giga_impact.pal create mode 100644 graphics/battle_anims/backgrounds/new/giga_impact.png create mode 100644 graphics/battle_anims/backgrounds/new/giga_impact_contest.bin delete mode 100644 graphics/battle_anims/backgrounds/new/giga_impact_opponent.pal delete mode 100644 graphics/battle_anims/backgrounds/new/giga_impact_opponent.png delete mode 100644 graphics/battle_anims/backgrounds/new/giga_impact_player.pal delete mode 100644 graphics/battle_anims/backgrounds/new/giga_impact_player.png delete mode 100644 graphics/battle_anims/backgrounds/new/spacial_rend_opponent.bin delete mode 100644 graphics/battle_anims/backgrounds/new/spacial_rend_player.bin diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 03d72f3ea4..6b417944ef 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -2502,15 +2502,24 @@ Move_GIGA_IMPACT: waitforvisualfinish delay 11 createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 26, 0, 0, 5 - delay 6 - @monbg ANIM_DEF_PARTNER - @setalpha 12, 8 - @createvisualtask AnimTask_WindUpLunge, 5, 7, 0, -18, 8, 23, 10, 40, 10 - @delay 35 - createsprite gComplexPaletteBlendSpriteTemplate, 2, 7, 31, 3, 1, 0, 10, 0, 0 + createvisualtask AnimTask_IsContest, 2 + jumprettrue SetGigaImpactContestsBG + createvisualtask AnimTask_IsTargetPlayerSide, 2 + jumpretfalse SetGigaImpactOpponentBG + goto SetGigaImpactPlayerBG +SetGigaImpactOpponentBG: + fadetobg BG_GIGA_IMPACT_OPPONENT + goto GigaImpactContinuity +SetGigaImpactPlayerBG: + fadetobg BG_GIGA_IMPACT_PLAYER + goto GigaImpactContinuity +SetGigaImpactContestsBG: + fadetobg BG_GIGA_IMPACT_CONTEST + goto GigaImpactContinuity +GigaImpactContinuity: + waitbgfadeout createsprite gBasicHitSplatSpriteTemplate, 4, 4, -10, 0, 1, 0 playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET - call SetImpactBackground delay 1 createsprite gSlideMonToOffsetSpriteTemplate 2, 5, 1, -16, 0, 0, 4 waitforvisualfinish @@ -2525,6 +2534,7 @@ Move_GIGA_IMPACT: blendoff restorebg waitbgfadein + waitforvisualfinish end Move_NASTY_PLOT: diff --git a/graphics/battle_anims/backgrounds/giga_impact.pal b/graphics/battle_anims/backgrounds/giga_impact.pal deleted file mode 100644 index 944174076e..0000000000 --- a/graphics/battle_anims/backgrounds/giga_impact.pal +++ /dev/null @@ -1,19 +0,0 @@ -JASC-PAL -0100 -16 -0 0 0 -255 214 0 -255 197 0 -255 173 0 -255 165 0 -148 90 222 -255 107 0 -255 132 0 -255 148 0 -255 156 41 -0 0 0 -0 90 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 diff --git a/graphics/battle_anims/backgrounds/new/giga_impact.pal b/graphics/battle_anims/backgrounds/new/giga_impact.pal new file mode 100644 index 0000000000..06f02604a6 --- /dev/null +++ b/graphics/battle_anims/backgrounds/new/giga_impact.pal @@ -0,0 +1,19 @@ +JASC-PAL +0100 +16 +0 0 0 +240 136 184 +232 104 168 +136 8 40 +248 24 104 +216 32 96 +224 72 136 +160 0 48 +216 0 64 +200 40 88 +192 0 56 +176 32 128 +176 24 72 +152 16 56 +200 48 80 +216 56 160 diff --git a/graphics/battle_anims/backgrounds/new/giga_impact.png b/graphics/battle_anims/backgrounds/new/giga_impact.png new file mode 100644 index 0000000000000000000000000000000000000000..0d5d705fe32a0bc2f3922e8dcecad12a06272eed GIT binary patch literal 2395 zcmV-h38eOkP){(J`cel1EpWJz|Bo3r3$Y2E4xh#?MSCF%~md}P7B3hV5 zfB=fI*v=LhfR0k+3h}gs8-i+F3KDR@U3EYzu`-eXK{`Rb-+AYI=G|Q?DU&Hq3j8n3IklTVi!ML)&eRFMEb*J zy#w07Dp4Q)(2#+lUrKoo-pCJsXbO?gW96;LX{$6%$Kwy(%c@6=%glfRq@(*JU{?Ul zPd&h&(81EZtUcSK=mSRRfYe7be-wQH)2Cxn-y;lE0QTIg*mem66@dFBU_}^+T5e|u zAoU^wN6>oHe&1_~VBfjgx=aARAOXAfJd}XY`Brs?D|ZqKfQ{U(&TvK<0D#?HT$y2y zNDu+YL zX~!Io6;S|gRs=vBFs39`z)AqDi7-+bvhh&8#zX;~L;%|6Rb96=r&mM);|jp1+JGJe zQNZ;Vt^o$HrlJ}IYhCCGy}6u?s{q=7dsAFbe&ZQ%0X>-^v9|WCxiqcBH;QLkqd}Luc^B@_v{rlR$GKK z4?1JPN!#`yI7>RdMMEw?Mi7PvW`;3gfEVQ43mqQ8=pbyjO|Y}68GEF2H+J|x2awEx z5kZ`c%`u1*J*3Wp5_1gb!?qDYGD=5|0ikyRyuHf+2TSdXoqF_AdEJ~+?wY77Ftdeq zZZy&cURtMh0CZgd(}zX`_LhI$no-q&FRK8teb{#P1=idQom<;EY=_~K?!*RQhVA?6 z{m8npV&|C0ZUv_XC&RvFAa+k_0LUB%7=gYOJ5B=jmjTdq02o22D_{nmsCSN@12XFp zk3d1$k>ks#vH>8=Yzr8Ho}SMt&y51m&Zg2q7t_QFG_vx@q5%u;VA7pTCUO?2FLde+ z0O0a;3Ix_khGAd?SCoUwW1|A>WM#SNzJ_{6zz9?-aczPKxKfs7_SI`J7Ca25-%)^P z^#w4%)oEEy@BWO*Sr{0>XA;n_Pmlw^LHW(=pf6bkEQ0o8A^@F=Q>O>`?Zrh_PD|*R zMX;j=c4W-KI>4jg62nXZz$!SD4*E?6Fu)-wA96sMb$79XMJ6j~(hI;}IRHXr8D1@A zhNDIU0Qi7qC>>2_QJd}XNQHaBuc`LnWPt9?S72qfcUPnL)5gg)ZL=!^Z zAEl|IPg-pp#o*^0fDtkPskhgbL<7DF0-Vt0LteomqiT3+pS$ES?=lA*BH$>*QH7b9 zdHQGe{uE2VRh$NajG!&%gS%I7{n*nx0F013;5Ec=ntFX}Dm@2m2U{`%4l0F%Snj;I zy`>+y0cgObV;;c{*H8KS8mj}C^I$~D;byved<--BjiSH^4uu0;>EBiR3lG36fW2-V z7R51419TuF#BpT(;~^I2R7?iI-?VP$$9WLEJuFxRq5{l-=`XYGMiij*eM1g_JkS3a z1h;aGKvn=2y0}A5GT5#4A&8;;U+`AcE7!33BNLNr|0avCl zB`4d2Ke@E1qipdL))d6CUlT~LdYFJpy#8b4-W|U9^n030w4|iL+RU;dukN;WGIZ4 z5#|4!ROwR+kaK|4-|=rM(b%3x0Du5Drn%y+uYpEtzX4!cSKu<;AfF-8^Fq4k8-q~CDc`qIB&reU+>oqkG^hBsS^qQ^0 zfl&cD291D1hd`g)HNZLY=riP=yfRCSMgi0}qjLiwulDNo48UK^q5VYzYD=AC-kQLe1_NO zr|WYAaOQr^dS0blGE0oM|3CrY-5Djf*R{lJ8t~CMsaH>6*l&iuUIXk$HF{r?SaH6r z2H1tFwij6d_QRu!?!2!è$ç$æ$å$ä$ã$â$á$à$à á â ã ä å æ ç è é ê ë ì í î ï J!K!L!M!N!O!B!è,ç,æ,å,ä,ã,â,á,à,à(á(â(ã(ä(å(æ(ç(è(é(ê(ë(ì(í(î(ï(J)K)L)M)N)O)B)Ø,×,Ö,Õ,Ô,Ó,Ò,Ñ,Ð,Ð(Ñ(Ò(Ó(Ô(Õ(Ö(×(Ø(Ù(Ú(Û(Ü(Ý(Þ(ß(:);)<)=)>)?)2)È,Ç,Æ,Å,Ä,Ã,Â,Á,À,À(Á(Â(Ã(Ä(Å(Æ(Ç(È(É(Ê(Ë(Ì(Í(Î(Ï(*)+),)-).)/)")¸,·,¶,µ,´,³,²,±,°,°(±(²(³(´(µ(¶(·(¸(¹(º(»(¼(½(¾(¿()))))))¨,§,¦,¥,¤,£,¢,¡, , (¡(¢(£(¤(¥(¦(§(¨(©(ª(«(¬(­(®(¯( +) ) ) ))))˜,—,–,•,”,“,’,‘,�,�(‘(’(“(”(•(–(—(˜(™(š(›(œ(�(ž(Ÿ(ú(û(ü(ý(þ(ÿ(ò(ˆ,‡,†,…,„,ƒ,‚,�,€,€(�(‚(ƒ(„(…(†(‡(ˆ(‰(Š(‹(Œ(�(Ž(�(D)E)F)G)H)I)@) \ No newline at end of file diff --git a/graphics/battle_anims/backgrounds/new/giga_impact_opponent.bin b/graphics/battle_anims/backgrounds/new/giga_impact_opponent.bin index a55ff2f56d9a53ef07152d362167283f90593bd6..0cfa1f1ec6dca34cd21cca537bd29b56db5bc585 100644 GIT binary patch literal 896 zcmV~$=}!m%7zg0ZN5tl%&^!CR+dFC zupZKb`VzIM!3#XcGdx8#s!)jvl%ou#C_yobr9?`lOvZL&%rAeBlMOvjzPV0F+r>@kqdPcus2!r^H z0er$o^rH{G=s`ES(1{MTqg^_rQ@W&EdZbtSq+c#*s9x3(y`;fsu@#R!HmEF&^1V=^uiGAUCsEn#|3@9G`Btr2=lcd(6L_=zoS;s-Xcjy0@e z1$YJRJk&3Hh+pzxzv$mN&u^ULSI%;V)12ZYCpgYAj&g*<9JUb~ zwJ{sF37fPjo3_(_-p{!^{j8tyFC5|^KXZVe_>ukWV=sHy%`SGbgY9g$4(qfo>$V>2 zwLa^&V;E^Y-9uLS;so7w+3spCTq49Yqd5z z;79$42l!z>vLEZQHhO+qP}nwrwZ9JzKM>UqAKgP4~RM=k~2O zaKafE469sm!yOMi@xmJ)eDT8{8vz8WZ;LI@>h6cLNq#33&6h))7NO9*Ne5|NlB zBqbTi2_pq5NkwYXkd}0$CxdmPK}Ir>nJi=_8`%jb2RX?_Zt{?qeB`G95foHih{6=1 zD8(pF3C)+J6s0LcS^Zaz@>HNAm8eV=s#1;W)SxD{6kA($1a+uOJ?hhdhMH(ZW17&E zW;CY-Ev-zgXiXd1(vJ3Y&}1ZSR!2I~nJ$(#`t7>XjqdcIC%x#cUaAj$>1S~!-Jbyr zWDtWL@Ix5NForWi)ksD$nlW~?=`ogZjCa6CCo!17L?$uWAwPwwDqW;{8q=A$VHwL=!Ae$X-D=jbmUXOW0~_^Z6Pww>R<^O79qeQmyX_qI zu$O)8*Xn;0oBIPCWRIIB+1{f9SQ&U1l_T;eiUxXLxI zbAy}Q;x>1<%RR;4*Zcz>@<{K(!yfa5r#$01FL=o-Uh{^xO8JiWeBdLW_{(P)003|V0{{R3Yu{!u0000mP)t-sDKRl> zi@o-PwEqDA{}5vCVx;ClgWdo+-WXcVDN4;CQoR5%tPnw*04bCZF@p#o(kMrR000Yn zNklEVED$n7w z(GY5=)C(b2kwL&U2EGYHH4BKuWBnBaZxqD{;7O7+?jlKuZ{TB}fE(cz2L5g~5QxU; zQ!NpQC!jD41w4EpL{piu9WG=9T)hMc#H|VuBoKNwmN>;T1_j)n&l)+(;}p zS>muL{z1S6w)s^JxYqE2|7(M1cW1D>2wWWuiVp&TA=|v}1HtBGp`!4xO=CKgT#e5% z5G4xndjsqP5G2ABs(_sYLx_9&;lH-c`1W{)Vt&I7HBfz;gL$R$zF3hO7%~w5?$;`@ z-JUfGMC72>bFe3xAT!{2MBq*QGoqe*z?mvBJXbkAcn+ixQf7gD2U+~9unzi7q%Tyc`BBp zC@>Z`Ao&Ynfpwx5dDc7PUyorFMaxNCP`T``AW&QUY*Z8{9&mzqhkm*iHYk7KuVMV# zlL!hQHc26RJe-R$)bW=t`f*&v=LEfI`WuYT@sFF3`~b`{br8-)GAB;M0C^@}1Fz4( z@_e&4u|AQK1CT+M=inev7)#B&-teo7)zNFP%5H(7L#1!nbKHC{^W>%*T6K5Wt;#o&OoY^Y`HQSN&+1Z z$NSCc#5Dp&G}aJ^v{*}g;|uH*wV3v0I%l7I!0QN%Wg3B80On+ILksK->cEOj=bHZ_ z5I)Bgq{W^q9_va*B8tq*(ljLlvW$HHgoSq$zNns)2m}~Lhw4(;{~2w~Wz>D-fcODC zncv4)XWz=gz$lKu;&}=y z=Ap!%8;^H2Fl-p0>SDHl#DIx} z(Gkm2c+}59wRt>c34f<<6)I(F>%AgvBJjS%Xq57%OP%X zrR_q)Xxoh`x$NvyPLK}i#pa{P>wc6f4}}>Gll0Spqw0J~Z-tT4Edr4EdNU2X-b;aH z#lYN4I!xLuvp|QuTp`BX&;v$kMPlv&Ei$P9&)>D7S#dqZ*q7*A97U#gR-3NDf7h}i z1ERI;=70+#ZmMMijfWEXLJ*iKAHh3NJqX zg-e{jD+t1dXtsM#lw^w|FVP2;l7RW5B{I&e8=a27aS8OqlS!!!Gai1Crg%*GZ9cBI zxmno)24gRPx!G5iIMUs`b~DZ}E4=VlwW`2x0~Z=>vtQdPMS@Ibn=6ZCRbe?<9Q<0J zO-8lhPb`tfWL)Yho#Du-%3a}F5*=EBvzb6bLSP%M_JnHe)fq35mmsDdIf0YihTdNW zHC*XA_HC=_Rfa_lejQPR>Jt9aZdVEDcL+w{+ZLWU=3c2;)Ul5%9PXh$eSH6tXuH4o zxm-VuW8QPxb=PX^qRppgu!Wj2f@()Z20!Oo^9S;ZR|(Tam!q#|0;}H^!?&h-t#jNs zBGjS2BhCcgtN)~UZtLOtL@;9M*!G~GT}XG1X(gHnY=>+9V3JM;V=LlvlQ^K`{fWdB zMGg45W$U#)R5sC##|T`04Y7P)!BL1*fS)(p%?X~$cpASBBdt&!XyWH84zq0N1L1vE z;2*uh#R|E@2*!5@GcatVPy(8LS92T`B>wGi+z(%NjxcRwzs_2 zfd%Rfo{UXnlS~78UiSQN9A>&3th-Ag3yfWP*q)|v2-^xQtFUFgQmcF%%2L+>k9;|jSS*-@#be$mrNl>^}YYjbzxGzwCDZOqc&@?4>1`pfd{DC_0 zQ%R}=v7UpPL<9RI(61?L%la6>+?VKbdcN7dhwToX8Vk2I*%KrOHk5!3_5=x3yuYT6 za3UyT@~p3k#h7>yqI5Dy0&m#VR4ovjrc2>`9H&uWWNpwInPm_4#n9{`U*eIROJID@ zR$-32S1j=QoOY_7oSiABntGhUmePKMC((DXIbh+>EO45gkJj&^o^ zoX0z){$o^(Mf@2oe;yH}3O5nb48x38UUQmn;20~oC-(g+_=XmeD zmZ;=i0V>odM)$+agcaW842LIT$LASb&vqSWZ8n&{L48m<0$O-rMVUYOS8NuS@F+rqT4GWnag1V3(rYj;a5$su`i0x|xj^aF`}s3J zF*)iB6Qp`U@_=u6E`~!h7tIOa1g|s-Uzqt z6`<~z>83PkKAf@pETejAnDi8!d zo#63iv}LC7fbU8AGy&Uqu~YCRZo4g-&6O&!Zmza@$X?VpOnlAIw--&Yp7n7S)S>c%wjfkn9Drovw+8VoF{mar+AuYc$Po-lfU?zfB2Ul_>mP}?qy!; zC0^`BUg(7^Vlhit$}*O-g6DXi7kH7Ec$rstm4<4h#%iLbYNq-+SsT3G>%7)$yxOb0 z(kofTYSyrpb*yItukku>@Fs8ZHt+B*7wZyTs>^h_uF%;!M?1XT+q~6VyxE()(Hq&s zX11`EZER-;@9{n#@F5@ZF`w`$&DBDYTB?;=D@L(8;Qij`z24*9-sPR%$u4%YhrR4$ zKL_}X&-sEc`HHXkhHq)7_UfRH>ZHy}R*LFe>l#|Y(r7*{=_GC;JsHSICb2VxQ;1T)NBJs~_f!7LN`MMf_P+niAQh}aRHzEmeC*sYmdXDE+`ibE diff --git a/graphics/battle_anims/backgrounds/new/giga_impact_player.pal b/graphics/battle_anims/backgrounds/new/giga_impact_player.pal deleted file mode 100644 index ea01813a95..0000000000 --- a/graphics/battle_anims/backgrounds/new/giga_impact_player.pal +++ /dev/null @@ -1,19 +0,0 @@ -JASC-PAL -0100 -16 -0 0 0 -255 255 255 -255 0 255 -255 16 98 -246 131 180 -238 98 164 -230 65 131 -222 0 57 -222 24 90 -205 32 82 -205 41 74 -189 0 49 -172 16 65 -156 0 41 -148 16 49 -131 8 32 diff --git a/graphics/battle_anims/backgrounds/new/giga_impact_player.png b/graphics/battle_anims/backgrounds/new/giga_impact_player.png deleted file mode 100644 index b258035e343ddd983c12bf8098ed54eac3aa8430..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3098 zcmV+#4CV8QP)003|V0{{R3Yu{!u0000mP)t-s00030 z|Ns90|NjtT_Jg$UVx;ClgWdo+-WXcVAX3dKO1%IvtPnw*04bCZF@p#otxB+1lXwNDI`*o_@xHQY5I^Obtd>3E)y3 zU7KK2ja-Pqj!;jWS}zBzF_7G221JM4AwVnCh@Pa5Cq2!Bhb$RrQf0ui#04%SHj%B7 z3uEoj01r9jb23s)M<8lQ8$g}Y4iN4g30VV6$)V?X*M-cTdlDTNIISSiqS5d2+%3HOOR&nz7U8#RYr~rcg0M%KJI&VTGQDLPCg8W z6hsXqwHyW{yLMq@T8p`!%bIsw|4QH|Z6GM~%88jg zhYpua(o2JV%s{858E$O2qH74`&Ad^RnmfmGZvqfce zR}OG46RPIWoFUNG?|Y87>x+KB?+4p8E&Nqg0Hr7xn73R=55Oi6qweYISc@mE%{|}u ze+w5Mzz=y|)kR$)AkVGDft^05x`cc6y9NmK{T?WrgF=85;JkCtlg~(DWn5T@#Ul%B zG-hZDs`KH-#U_ZGd_iE3?8-Bs%(5&Cf~}cSv-1xTht4Dyeu}`Q z?U-9pUVh@*d<3zrz)T=20^-+)H-M+`S?Izrqv+U{zMVGF1O9t~z%7+S#(*p}gAWb- z-FlX*nF3+d1(EG(BpauR0sj2v@q~Wbw>E!((Lf#z20ruG@BmVYT)2k{m&Rbz&b@u9 ztJtZ#lcm&FK+Oa?2=?IfJBF&fT9DP5o{Z47Xp?RCFy|@m*bUyxRTKD>fe;vs%a)S4 zn2scE?3&!%da@&DGh_Ba@CS^GD9o`AA1SSHIpm-i9>!zow5E0ScXT8;%qTp8+aWFn z2yqFODE!wM0qw5xCz6dssmcGq^j6L|3Gma`CTB2vK(ZG2^VgI%2B+sAmZ9iVzNE@2 zDsA91-(P2iP%!WWD=dF%0v|}EaL^@Hkw3+#w1M9VFgxK?%AHllYZ?sC3Bw=+iC9PT z9Bn>o15b<}z=eAh?Yc0)x;2C^o!WAM6C&agHd7RK5E)YT`0q>3hnz;m3Q$7ywdrG0 zD$Cm$mV{jODeMe<$Z$Af%QIXkyvunHYV)?~Ij_Btj35zJVU)h#VBns11Z5M}%@)uJ zkZHAesYKsVe(NZ0Q9AnK%24NJUU--BaLSlwP4`V(IxKyTQUge#VTF|dCoYd)1Bpc4 zm1y8ocH9=Rd*VXf&5x7ioMQF9{+|A`y zqP4lFl4NT-1@s3=qND^VPMr1;V41m2FPvG3pNCiu)vJtvX3!QFb3 zw=_J^{P+oYVZff`n&YwMU;6&XF-=RZ8+k=JT;$NI&R2Qb2Ty+BbB`!{o>3Bc@wm&t z4k{c-VY?S_f1X!M>s!sM+oO7Y#4ZJ;-gw*vZ+_|bI$d-jS)64*nhY*d)12aXvD)pz z&>hu5m?Yk~)9J+BYyMhioWL`8T+ z+Sa^~T>r&kdcNDS*P(IMzX?LsU{g&K&M(M?419TR!|@Jv_)pri=`{B6)4$c}j>mCF z;2(q9XTj|_Ry^Yey0Cy^E^ZZc%6hg;lQ`~n(avifxIrN>zOvrwbi10@x#FW+zX&m% z=$;egZIExzLGR)Ww*jUJoyKDrbZ0kCo_cDk;?H{>XI#Of_~4cS(oPrqLIs@xwv7H0 z(<&zlu97<;U3^kF_8Y)83{w!}+(eU4`moX6c}9q+ zb+#o*EYRdzmapQX=vz8|Zi!o@P)pPa=PJBydB$doGkcZ>(I~vC0~m|IKY7=o9_qtP zUZA`%I5wEZ!V-_vv>D2-m^=tPOgD|6u|!9n!_&Kb8a?HvGo=Fqp^A8}14v>TVJ#R$ z_GP*hs)v@?X(d}1+lIg4jh^cO*!buCo-Yi;mOfYj^E~YvVjGxn6%9R=|C1T4>f6;4 z`sR=YR>JF6O8vh+;5XSr^;6ixm21|etj)bjK!I~8E~*TTi=tkFo{ z?}t>eQQ&Iw(T=BTD7@1s40D@@QJNAEYHYYi0-fsOn4FpW0T_N`U5ewS!^2nTlS#CD z{>PbWl^Fzz!Yng3d*9FrtM4#s3{r?OQDU+ob{!uoV>9>IFViN5h2gjl`64exq!u?! zr9HAcprLAs!ojq!{_?iAeSwsiZr4c{a#jO)87_MD!`rvU2}Yqv1mD?w!EiKy+Qj>h zU%h(kP~4%{^yze}9T=N@xkTZmh~_Z8kXG2W;pK(s*8+uztGakG{=a~_kx5LQ#y!bY o;`~1VYu%y7CauRNFl~kZ1&Sx+N{gjQzyJUM07*qoM6N<$g3DFoaR2}S diff --git a/graphics/battle_anims/backgrounds/new/spacial_rend_opponent.bin b/graphics/battle_anims/backgrounds/new/spacial_rend_opponent.bin deleted file mode 100644 index 0cfa1f1ec6..0000000000 --- a/graphics/battle_anims/backgrounds/new/spacial_rend_opponent.bin +++ /dev/null @@ -1,3 +0,0 @@ -@%I%H%G%F%E%D%�$Ž$�$Œ$‹$Š$‰$ˆ$‡$†$…$„$ƒ$‚$�$€$€ � ‚ ƒ „ … † ‡ ˆ ò$ÿ$þ$ý$ü$û$ú$Ÿ$ž$�$œ$›$š$™$˜$—$–$•$”$“$’$‘$�$� ‘ ’ “ ” • – — ˜ %%% % % % -%¯$®$­$¬$«$ª$©$¨$§$¦$¥$¤$£$¢$¡$ $  ¡ ¢ £ ¤ ¥ ¦ § ¨ %%%%%%%¿$¾$½$¼$»$º$¹$¸$·$¶$µ$´$³$²$±$°$° ± ² ³ ´ µ ¶ · ¸ "%/%.%-%,%+%*%Ï$Î$Í$Ì$Ë$Ê$É$È$Ç$Æ$Å$Ä$Ã$Â$Á$À$À Á Â Ã Ä Å Æ Ç È 2%?%>%=%<%;%:%ß$Þ$Ý$Ü$Û$Ú$Ù$Ø$×$Ö$Õ$Ô$Ó$Ò$Ñ$Ð$Ð Ñ Ò Ó Ô Õ Ö × Ø B%O%N%M%L%K%J%ï$î$í$ì$ë$ê$é$è$ç$æ$å$ä$ã$â$á$à$à á â ã ä å æ ç è B-O-N-M-L-K-J-ï,î,í,ì,ë,ê,é,è,ç,æ,å,ä,ã,â,á,à,à(á(â(ã(ä(å(æ(ç(è(2-?->-=-<-;-:-ß,Þ,Ý,Ü,Û,Ú,Ù,Ø,×,Ö,Õ,Ô,Ó,Ò,Ñ,Ð,Ð(Ñ(Ò(Ó(Ô(Õ(Ö(×(Ø("-/-.---,-+-*-Ï,Î,Í,Ì,Ë,Ê,É,È,Ç,Æ,Å,Ä,Ã,Â,Á,À,À(Á(Â(Ã(Ä(Å(Æ(Ç(È(-------¿,¾,½,¼,»,º,¹,¸,·,¶,µ,´,³,²,±,°,°(±(²(³(´(µ(¶(·(¸(--- - - - --¯,®,­,¬,«,ª,©,¨,§,¦,¥,¤,£,¢,¡, , (¡(¢(£(¤(¥(¦(§(¨(ò,ÿ,þ,ý,ü,û,ú,Ÿ,ž,�,œ,›,š,™,˜,—,–,•,”,“,’,‘,�,�(‘(’(“(”(•(–(—(˜(@-I-H-G-F-E-D-�,Ž,�,Œ,‹,Š,‰,ˆ,‡,†,…,„,ƒ,‚,�,€,€(�(‚(ƒ(„(…(†(‡(ˆ( \ No newline at end of file diff --git a/graphics/battle_anims/backgrounds/new/spacial_rend_player.bin b/graphics/battle_anims/backgrounds/new/spacial_rend_player.bin deleted file mode 100644 index 3b89218e0e6cbba254e78a9f11abe717002cba8a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 896 zcmWN@WnfSR0EJP(KuNpfyW8FN9z0+@n)P5wV@qR8V@qRzG}zME(%912(%7y?V|Sik zC&BTKvmNUg%NRrqvHvHIcoGN*X-*3wTGEQvG^7!YX+l$)QIGm$INfPZb&8Xnp7n7S)S>c%wjfkn9Drovw+8VoF{mar+AuYc$Po-lfU?zfB2Ul_>mP}?qy!; zC0^`BUg(7^Vlhit$}*O-g6DXi7kH7Ec$rstm4<4h#%iLbYNq-+SsT3G>%7)$yxOb0 z(kofTYSyrpb*yItukku>@Fs8ZHt+B*7wZyTs>^h_uF%;!M?1XT+q~6VyxE()(Hq&s zX11`EZER-;@9{n#@F5@ZF`w`$&DBDYTB?;=D@L(8;Qij`z24*9-sPR%$u4%YhrR4$ zKL_}X&-sEc`HHXkhHq)7_UfRH>ZHy}R*LFe>l# Date: Wed, 3 Nov 2021 00:37:22 +0700 Subject: [PATCH 08/58] Adjust Giga Impact background to fade in before impact --- data/battle_anim_scripts.s | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 6b417944ef..aa914bf892 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -2497,11 +2497,6 @@ Move_GIGA_IMPACT: loadspritegfx ANIM_TAG_IMPACT monbg ANIM_DEF_PARTNER setalpha 12, 8 - playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER - createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 6, 1, ANIM_ATTACKER - waitforvisualfinish - delay 11 - createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 26, 0, 0, 5 createvisualtask AnimTask_IsContest, 2 jumprettrue SetGigaImpactContestsBG createvisualtask AnimTask_IsTargetPlayerSide, 2 @@ -2517,6 +2512,12 @@ SetGigaImpactContestsBG: fadetobg BG_GIGA_IMPACT_CONTEST goto GigaImpactContinuity GigaImpactContinuity: + playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER + createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 6, 1, ANIM_ATTACKER + waitforvisualfinish + delay 11 + createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 26, 0, 0, 5 + delay 6 waitbgfadeout createsprite gBasicHitSplatSpriteTemplate, 4, 4, -10, 0, 1, 0 playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET From 28e78cb6c4b1b4214b4a6dbb38a7ddfb96304b56 Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Thu, 4 Nov 2021 19:50:54 +1300 Subject: [PATCH 09/58] 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 328780f53a..aadae87664 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 6d6c1dae8b..bb648c2254 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 cb99cc44fa..a6ef91a931 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 12212ff94a..09506e87ec 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 918c3e7f0d..9b6880a941 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 62b49a1910..d50546d945 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 3b4495208f..cc67ef2e3b 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 3eb5dc9a44..0a735c4c3d 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 a1a24b3b13..63890dc419 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 ee9379d8d1..eddde6b446 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 f87e0a1341..62c7374ffb 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 97d61202a4..06e8ee6ecb 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 10/58] 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 aadae87664..33c89d55d9 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 bb648c2254..a4036bef18 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 11/58] 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 06e8ee6ecb..860a04bd03 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 12/58] 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 33c89d55d9..a59af74d0f 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 a4036bef18..3e29989b4a 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 cc67ef2e3b..64809532d3 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 eddde6b446..7875e5e65d 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 13/58] 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 3e29989b4a..16d9f2f0d8 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 14/58] 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 16d9f2f0d8..740357fd19 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 7875e5e65d..668fc7b7fc 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 15/58] 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 6f0fec8a7e..861f2b8c4c 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 16/58] 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 861f2b8c4c..5a85ee6b8c 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 17/58] 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 e8e27b3164..63c4982f17 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 18/58] 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 438b5660ce..3ba45e0d8b 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 95ff4f4a04..13f2be0d81 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 5267cfbd1e..fcba67bcad 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 19/58] 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 6077a3ae4d..3e7f026927 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 13f2be0d81..61723ced4d 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 20/58] 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 3ba45e0d8b..2fb4d34014 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 61723ced4d..9d94966dd6 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 fcba67bcad..57f02e2f5f 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 21/58] 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 9d94966dd6..be81610cc2 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 57f02e2f5f..85ddede469 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 22/58] 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 be81610cc2..5338b304e7 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 0f35657db4..c85a918da8 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 23/58] 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 7602c5d099..3c4b4d220b 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 85ddede469..4eec840881 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 15d13b85a1..66247c7f60 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 24/58] 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 3e7f026927..b10c937aec 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 3bc45939fb..63fed0b3d6 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 63c4982f17..84491987e5 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 25/58] 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 dbc46a3ecb..9c5b77cd67 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 26/58] 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 1e229fbe81..781fb50e67 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 27/58] 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 b6df2168ea..1b2591899b 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 77196cf9ad..7fbb432603 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 781fb50e67..84637b683e 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 28/58] 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 84637b683e..71dc78d0aa 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 29/58] 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 7e06b55d11..4f09e3bb7a 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 30/58] 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 14d8755431..4925b0c997 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 6cd44e10ab..835f04a299 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 8f376a050d..e5851f7b84 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 31/58] Fix Big Pecks ChangeStatBuffs was missing a check for Big Pecks. --- src/battle_script_commands.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 93e1b31e26..3874febf36 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -9833,8 +9833,9 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr return STAT_CHANGE_DIDNT_WORK; } else if (!certain - && ((GetBattlerAbility(gActiveBattler) == ABILITY_KEEN_EYE && statId == STAT_ACC) - || (GetBattlerAbility(gActiveBattler) == ABILITY_HYPER_CUTTER && statId == STAT_ATK))) + && ((GetBattlerAbility(gActiveBattler) == ABILITY_KEEN_EYE && statId == STAT_ACC) + || (GetBattlerAbility(gActiveBattler) == ABILITY_HYPER_CUTTER && statId == STAT_ATK) + || (GetBattlerAbility(gActiveBattler) == ABILITY_BIG_PECKS && statId == STAT_DEF))) { if (flags == STAT_BUFF_ALLOW_PTR) { From 59abb0ff4e818a31696364cf1f94bb69d8ea549a Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Wed, 10 Nov 2021 20:45:39 +0100 Subject: [PATCH 32/58] Serene Grace affects King's rock according to https://bulbapedia.bulbagarden.net/wiki/King%27s_Rock --- src/battle_util.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/battle_util.c b/src/battle_util.c index 4f09e3bb7a..385b09a1cf 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -6847,6 +6847,8 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) switch (atkHoldEffect) { case HOLD_EFFECT_FLINCH: + if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SERENE_GRACE) + atkHoldEffectParam *= 2; if (gBattleMoveDamage != 0 // Need to have done damage && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && TARGET_TURN_DAMAGED From e606e54f9d3684fec763bd248b75329818c410c0 Mon Sep 17 00:00:00 2001 From: BuffelSaft Date: Thu, 11 Nov 2021 14:32:38 +1300 Subject: [PATCH 33/58] 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 4925b0c997..ee859f0e03 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 34/58] add kings rock serene grace boost config --- include/constants/battle_config.h | 1 + src/battle_util.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index aaf02a37f1..ba9c1b984c 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -181,6 +181,7 @@ #define B_LURE_BALL_MODIFIER GEN_7 // In Gen7+, Lure Ball's catch multiplier is x5 instead of x3. #define B_HEAVY_BALL_MODIFIER GEN_7 // In Gen7+, Heavy Ball's ranges change. See Cmd_handleballthrow. #define B_DREAM_BALL_MODIFIER GEN_8 // In Gen8, Dream Ball's catch multiplier is x4 when the target is asleep or has the ability Comatose. +#define B_KINGS_ROCK_BOOST GEN_7 // In Gen5+, King's Rock is boosted by Serene Grace // Flag settings // To use the following features in scripting, replace the 0s with the flag ID you're assigning it to. diff --git a/src/battle_util.c b/src/battle_util.c index 4b3fc11aa9..8b23cdec37 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -6860,8 +6860,10 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) switch (atkHoldEffect) { case HOLD_EFFECT_FLINCH: - if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SERENE_GRACE) - atkHoldEffectParam *= 2; + #if B_KINGS_ROCK_BOOST >= GEN_5 + if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SERENE_GRACE) + atkHoldEffectParam *= 2; + #endif if (gBattleMoveDamage != 0 // Need to have done damage && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && TARGET_TURN_DAMAGED From 6214d8b62511df9c5a0c519589d2b7a84f1ae66b Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 12 Nov 2021 07:47:24 -0500 Subject: [PATCH 35/58] rename config --- include/constants/battle_config.h | 2 +- src/battle_util.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index ba9c1b984c..d28e9da5c2 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -181,7 +181,7 @@ #define B_LURE_BALL_MODIFIER GEN_7 // In Gen7+, Lure Ball's catch multiplier is x5 instead of x3. #define B_HEAVY_BALL_MODIFIER GEN_7 // In Gen7+, Heavy Ball's ranges change. See Cmd_handleballthrow. #define B_DREAM_BALL_MODIFIER GEN_8 // In Gen8, Dream Ball's catch multiplier is x4 when the target is asleep or has the ability Comatose. -#define B_KINGS_ROCK_BOOST GEN_7 // In Gen5+, King's Rock is boosted by Serene Grace +#define B_SERENE_GRACE_BOOST GEN_7 // In Gen5+, Serene Grace boosts King's Rock and Razor fang // Flag settings // To use the following features in scripting, replace the 0s with the flag ID you're assigning it to. diff --git a/src/battle_util.c b/src/battle_util.c index 8b23cdec37..18847b8cce 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -6860,7 +6860,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) switch (atkHoldEffect) { case HOLD_EFFECT_FLINCH: - #if B_KINGS_ROCK_BOOST >= GEN_5 + #if B_SERENE_GRACE_BOOST >= GEN_5 if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SERENE_GRACE) atkHoldEffectParam *= 2; #endif From 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 36/58] Improve Serene Grace boost config comment. --- include/constants/battle_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index d28e9da5c2..eb7600cc2a 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -181,7 +181,7 @@ #define B_LURE_BALL_MODIFIER GEN_7 // In Gen7+, Lure Ball's catch multiplier is x5 instead of x3. #define B_HEAVY_BALL_MODIFIER GEN_7 // In Gen7+, Heavy Ball's ranges change. See Cmd_handleballthrow. #define B_DREAM_BALL_MODIFIER GEN_8 // In Gen8, Dream Ball's catch multiplier is x4 when the target is asleep or has the ability Comatose. -#define B_SERENE_GRACE_BOOST GEN_7 // In Gen5+, Serene Grace boosts King's Rock and Razor fang +#define B_SERENE_GRACE_BOOST GEN_7 // In Gen5+, Serene Grace boosts the added flinch chance of King's Rock and Razor Fang. // Flag settings // To use the following features in scripting, replace the 0s with the flag ID you're assigning it to. From a26da51e9d55baf3fa5ca9de37136ed8d8712270 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 12 Nov 2021 12:44:45 -0500 Subject: [PATCH 37/58] fix contrary animations for MOVE_EFFECT_statchange --- include/constants/battle_script_commands.h | 1 + src/battle_script_commands.c | 131 ++++++++++++++++++++- 2 files changed, 127 insertions(+), 5 deletions(-) diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 34fa1d3707..7ceb1d64bf 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -225,6 +225,7 @@ // Cmd_statbuffchange #define STAT_BUFF_ALLOW_PTR (1 << 0) // If set, allow use of jumpptr. Set in every use of statbuffchange #define STAT_BUFF_NOT_PROTECT_AFFECTED (1 << 5) +#define STAT_BUFF_UPDATE_MOVE_EFFECT (1 << 6) // stat change flags for Cmd_playstatchangeanimation #define STAT_CHANGE_NEGATIVE (1 << 0) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 24a758153f..37c46055da 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3071,7 +3071,7 @@ void SetMoveEffect(bool32 primary, u32 certain) if (NoAliveMonsForEitherParty() || ChangeStatBuffs(SET_STAT_BUFF_VALUE(1), gBattleScripting.moveEffect - MOVE_EFFECT_ATK_PLUS_1 + 1, - affectsUser, 0)) + affectsUser | STAT_BUFF_UPDATE_MOVE_EFFECT, 0)) { gBattlescriptCurrInstr++; } @@ -3096,7 +3096,7 @@ void SetMoveEffect(bool32 primary, u32 certain) if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(1) | STAT_BUFF_NEGATIVE, gBattleScripting.moveEffect - MOVE_EFFECT_ATK_MINUS_1 + 1, - flags, gBattlescriptCurrInstr + 1)) + flags | STAT_BUFF_UPDATE_MOVE_EFFECT, gBattlescriptCurrInstr + 1)) { if (!mirrorArmorReflected) gBattlescriptCurrInstr++; @@ -3119,7 +3119,7 @@ void SetMoveEffect(bool32 primary, u32 certain) if (NoAliveMonsForEitherParty() || ChangeStatBuffs(SET_STAT_BUFF_VALUE(2), gBattleScripting.moveEffect - MOVE_EFFECT_ATK_PLUS_2 + 1, - affectsUser, 0)) + affectsUser | STAT_BUFF_UPDATE_MOVE_EFFECT, 0)) { gBattlescriptCurrInstr++; } @@ -3143,7 +3143,7 @@ void SetMoveEffect(bool32 primary, u32 certain) flags |= STAT_BUFF_ALLOW_PTR; if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(2) | STAT_BUFF_NEGATIVE, gBattleScripting.moveEffect - MOVE_EFFECT_ATK_MINUS_2 + 1, - flags, gBattlescriptCurrInstr + 1)) + flags | STAT_BUFF_UPDATE_MOVE_EFFECT, gBattlescriptCurrInstr + 1)) { if (!mirrorArmorReflected) gBattlescriptCurrInstr++; @@ -4657,9 +4657,55 @@ static void Cmd_endselectionscript(void) *(gBattlerAttacker + gBattleStruct->selectionScriptFinished) = TRUE; } +static u32 ReverseStatAnimId(u16 *argumentPtr) +{ + u8 value = 0; + switch (GET_STAT_BUFF_VALUE_WITH_SIGN(gBattleScripting.statChanger)) + { + case SET_STAT_BUFF_VALUE(1): // +1 + value = STAT_ANIM_MINUS1; + break; + case SET_STAT_BUFF_VALUE(2): // +2 + value = STAT_ANIM_MINUS2; + break; + case SET_STAT_BUFF_VALUE(3): // +3 + value = STAT_ANIM_MINUS2; + break; + case SET_STAT_BUFF_VALUE(4): // +4 + value = STAT_ANIM_MINUS2; + break; + case SET_STAT_BUFF_VALUE(5): // +5 + value = STAT_ANIM_MINUS2; + break; + case SET_STAT_BUFF_VALUE(6): // +6 + value = STAT_ANIM_MINUS2; + break; + case SET_STAT_BUFF_VALUE(1) | STAT_BUFF_NEGATIVE: // -1 + value = STAT_ANIM_PLUS1; + break; + case SET_STAT_BUFF_VALUE(2) | STAT_BUFF_NEGATIVE: // -2 + value = STAT_ANIM_PLUS2; + break; + case SET_STAT_BUFF_VALUE(3) | STAT_BUFF_NEGATIVE: // -3 + value = STAT_ANIM_PLUS2; + break; + case SET_STAT_BUFF_VALUE(4) | STAT_BUFF_NEGATIVE: // -1 + value = STAT_ANIM_PLUS2; + break; + case SET_STAT_BUFF_VALUE(5) | STAT_BUFF_NEGATIVE: // -2 + value = STAT_ANIM_PLUS2; + break; + case SET_STAT_BUFF_VALUE(6) | STAT_BUFF_NEGATIVE: // -3 + value = STAT_ANIM_PLUS2; + break; + } + + *argumentPtr = GET_STAT_BUFF_ID(gBattleScripting.statChanger) + value - 1; +} + static void Cmd_playanimation(void) { - const u16* argumentPtr; + u16* argumentPtr; u8 animId = gBattlescriptCurrInstr[2]; gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); @@ -4673,6 +4719,9 @@ static void Cmd_playanimation(void) return; } #endif + + //if (animId == B_ANIM_STATS_CHANGE && GetBattlerAbility(gActiveBattler) == ABILITY_CONTRARY) + //ReverseStatAnimId(argumentPtr); if (animId == B_ANIM_STATS_CHANGE || animId == B_ANIM_SNATCH_MOVE @@ -9815,6 +9864,72 @@ static void Cmd_setdrainedhp(void) gBattlescriptCurrInstr++; } +static u16 ReverseStatChangeMoveEffect(u16 moveEffect) +{ + switch (moveEffect) + { + // +1 + case MOVE_EFFECT_ATK_PLUS_1: + return MOVE_EFFECT_ATK_MINUS_1; + case MOVE_EFFECT_DEF_PLUS_1: + return MOVE_EFFECT_DEF_MINUS_1; + case MOVE_EFFECT_SPD_PLUS_1: + return MOVE_EFFECT_SPD_MINUS_1; + case MOVE_EFFECT_SP_ATK_PLUS_1: + return MOVE_EFFECT_SP_ATK_MINUS_1; + case MOVE_EFFECT_SP_DEF_PLUS_1: + return MOVE_EFFECT_SP_DEF_MINUS_1; + case MOVE_EFFECT_ACC_PLUS_1: + return MOVE_EFFECT_ACC_MINUS_1; + case MOVE_EFFECT_EVS_PLUS_1: + return MOVE_EFFECT_EVS_MINUS_1; + // -1 + case MOVE_EFFECT_ATK_MINUS_1: + return MOVE_EFFECT_ATK_PLUS_1; + case MOVE_EFFECT_DEF_MINUS_1: + return MOVE_EFFECT_DEF_PLUS_1; + case MOVE_EFFECT_SPD_MINUS_1: + return MOVE_EFFECT_SPD_PLUS_1; + case MOVE_EFFECT_SP_ATK_MINUS_1: + return MOVE_EFFECT_SP_ATK_PLUS_1; + case MOVE_EFFECT_SP_DEF_MINUS_1: + return MOVE_EFFECT_SP_DEF_PLUS_1; + case MOVE_EFFECT_ACC_MINUS_1: + return MOVE_EFFECT_ACC_PLUS_1; + case MOVE_EFFECT_EVS_MINUS_1: + // +2 + case MOVE_EFFECT_ATK_PLUS_2: + return MOVE_EFFECT_ATK_MINUS_2; + case MOVE_EFFECT_DEF_PLUS_2: + return MOVE_EFFECT_DEF_MINUS_2; + case MOVE_EFFECT_SPD_PLUS_2: + return MOVE_EFFECT_SPD_MINUS_2; + case MOVE_EFFECT_SP_ATK_PLUS_2: + return MOVE_EFFECT_SP_ATK_MINUS_2; + case MOVE_EFFECT_SP_DEF_PLUS_2: + return MOVE_EFFECT_SP_DEF_MINUS_2; + case MOVE_EFFECT_ACC_PLUS_2: + return MOVE_EFFECT_ACC_MINUS_2; + case MOVE_EFFECT_EVS_PLUS_2: + return MOVE_EFFECT_EVS_MINUS_2; + // -2 + case MOVE_EFFECT_ATK_MINUS_2: + return MOVE_EFFECT_ATK_PLUS_2; + case MOVE_EFFECT_DEF_MINUS_2: + return MOVE_EFFECT_DEF_PLUS_2; + case MOVE_EFFECT_SPD_MINUS_2: + return MOVE_EFFECT_SPD_PLUS_2; + case MOVE_EFFECT_SP_ATK_MINUS_2: + return MOVE_EFFECT_SP_ATK_PLUS_2; + case MOVE_EFFECT_SP_DEF_MINUS_2: + return MOVE_EFFECT_SP_DEF_PLUS_2; + case MOVE_EFFECT_ACC_MINUS_2: + return MOVE_EFFECT_ACC_PLUS_2; + case MOVE_EFFECT_EVS_MINUS_2: + return MOVE_EFFECT_EVS_PLUS_2; + } +} + static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr) { bool32 certain = FALSE; @@ -9843,6 +9958,11 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr { statValue ^= STAT_BUFF_NEGATIVE; gBattleScripting.statChanger ^= STAT_BUFF_NEGATIVE; + if (flags & STAT_BUFF_UPDATE_MOVE_EFFECT) + { + flags &= ~(STAT_BUFF_UPDATE_MOVE_EFFECT); + gBattleScripting.moveEffect = ReverseStatChangeMoveEffect(gBattleScripting.moveEffect); + } } else if (GetBattlerAbility(gActiveBattler) == ABILITY_SIMPLE) { @@ -9963,6 +10083,7 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr statValue = -1; else if (gBattleMons[gActiveBattler].statStages[statId] == 2 && statValue < -2) statValue = -2; + gBattleTextBuff2[0] = B_BUFF_PLACEHOLDER_BEGIN; index = 1; if (statValue == -2) From 2ff9c2f8341a7a1da9de88bfc15103a436f12e7c Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 12 Nov 2021 13:00:28 -0500 Subject: [PATCH 38/58] remove test code --- src/battle_script_commands.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 37c46055da..65b149817a 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4720,9 +4720,6 @@ static void Cmd_playanimation(void) } #endif - //if (animId == B_ANIM_STATS_CHANGE && GetBattlerAbility(gActiveBattler) == ABILITY_CONTRARY) - //ReverseStatAnimId(argumentPtr); - if (animId == B_ANIM_STATS_CHANGE || animId == B_ANIM_SNATCH_MOVE || animId == B_ANIM_MEGA_EVOLUTION From 395cffa702a6ed06fd236c407b0f0d96ad2d7588 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 12 Nov 2021 13:04:33 -0500 Subject: [PATCH 39/58] remove ReverseStatAnimId --- src/battle_script_commands.c | 46 ------------------------------------ 1 file changed, 46 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 65b149817a..51aa365158 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4657,52 +4657,6 @@ static void Cmd_endselectionscript(void) *(gBattlerAttacker + gBattleStruct->selectionScriptFinished) = TRUE; } -static u32 ReverseStatAnimId(u16 *argumentPtr) -{ - u8 value = 0; - switch (GET_STAT_BUFF_VALUE_WITH_SIGN(gBattleScripting.statChanger)) - { - case SET_STAT_BUFF_VALUE(1): // +1 - value = STAT_ANIM_MINUS1; - break; - case SET_STAT_BUFF_VALUE(2): // +2 - value = STAT_ANIM_MINUS2; - break; - case SET_STAT_BUFF_VALUE(3): // +3 - value = STAT_ANIM_MINUS2; - break; - case SET_STAT_BUFF_VALUE(4): // +4 - value = STAT_ANIM_MINUS2; - break; - case SET_STAT_BUFF_VALUE(5): // +5 - value = STAT_ANIM_MINUS2; - break; - case SET_STAT_BUFF_VALUE(6): // +6 - value = STAT_ANIM_MINUS2; - break; - case SET_STAT_BUFF_VALUE(1) | STAT_BUFF_NEGATIVE: // -1 - value = STAT_ANIM_PLUS1; - break; - case SET_STAT_BUFF_VALUE(2) | STAT_BUFF_NEGATIVE: // -2 - value = STAT_ANIM_PLUS2; - break; - case SET_STAT_BUFF_VALUE(3) | STAT_BUFF_NEGATIVE: // -3 - value = STAT_ANIM_PLUS2; - break; - case SET_STAT_BUFF_VALUE(4) | STAT_BUFF_NEGATIVE: // -1 - value = STAT_ANIM_PLUS2; - break; - case SET_STAT_BUFF_VALUE(5) | STAT_BUFF_NEGATIVE: // -2 - value = STAT_ANIM_PLUS2; - break; - case SET_STAT_BUFF_VALUE(6) | STAT_BUFF_NEGATIVE: // -3 - value = STAT_ANIM_PLUS2; - break; - } - - *argumentPtr = GET_STAT_BUFF_ID(gBattleScripting.statChanger) + value - 1; -} - static void Cmd_playanimation(void) { u16* argumentPtr; From d5db3293183e49cf317cd5af510c417d8d770f7c Mon Sep 17 00:00:00 2001 From: ghoulslash <41651341+ghoulslash@users.noreply.github.com> Date: Fri, 12 Nov 2021 13:07:41 -0500 Subject: [PATCH 40/58] Update src/battle_script_commands.c Co-authored-by: ultima-soul <33333039+ultima-soul@users.noreply.github.com> --- src/battle_script_commands.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 51aa365158..d36a37072e 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -10034,7 +10034,6 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr statValue = -1; else if (gBattleMons[gActiveBattler].statStages[statId] == 2 && statValue < -2) statValue = -2; - gBattleTextBuff2[0] = B_BUFF_PLACEHOLDER_BEGIN; index = 1; if (statValue == -2) From 0634d3e541ab336b24ea64b1b234b535f5efc598 Mon Sep 17 00:00:00 2001 From: ghoulslash <41651341+ghoulslash@users.noreply.github.com> Date: Fri, 12 Nov 2021 13:07:53 -0500 Subject: [PATCH 41/58] Update src/battle_script_commands.c Co-authored-by: LOuroboros --- src/battle_script_commands.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index d36a37072e..0dbe68acf3 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4673,7 +4673,6 @@ static void Cmd_playanimation(void) return; } #endif - if (animId == B_ANIM_STATS_CHANGE || animId == B_ANIM_SNATCH_MOVE || animId == B_ANIM_MEGA_EVOLUTION From 876813a41843932e3aefc1868e42bfd05038cafd Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 12 Nov 2021 13:08:23 -0500 Subject: [PATCH 42/58] revert old attempts --- src/battle_script_commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 0dbe68acf3..578f6d1807 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4659,7 +4659,7 @@ static void Cmd_endselectionscript(void) static void Cmd_playanimation(void) { - u16* argumentPtr; + const u16* argumentPtr; u8 animId = gBattlescriptCurrInstr[2]; gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); From cdb20e89fcbc6123aba19b5a964d013ae06b0c2e Mon Sep 17 00:00:00 2001 From: ghoulslash <41651341+ghoulslash@users.noreply.github.com> Date: Fri, 12 Nov 2021 13:12:05 -0500 Subject: [PATCH 43/58] Update src/battle_script_commands.c Co-authored-by: ultima-soul <33333039+ultima-soul@users.noreply.github.com> --- src/battle_script_commands.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 578f6d1807..7134818e06 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4673,6 +4673,7 @@ static void Cmd_playanimation(void) return; } #endif + if (animId == B_ANIM_STATS_CHANGE || animId == B_ANIM_SNATCH_MOVE || animId == B_ANIM_MEGA_EVOLUTION From 96fd8e696b0d991aa707835659d719c87f0e35e2 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 12 Nov 2021 15:00:21 -0500 Subject: [PATCH 44/58] brick break gen 4 and 5 config. clears aurora veil --- include/constants/battle_config.h | 1 + src/battle_script_commands.c | 32 ++++++++++++++++++++++++------- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index eb7600cc2a..8e72b2c99d 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -152,6 +152,7 @@ #define B_MEMENTO_FAIL GEN_7 // In Gen4+, Memento fails if there is no target or if the target is protected or behind substitute. But not if Atk/Sp. Atk are at -6. #define B_GLARE_GHOST GEN_7 // In Gen4+, Glare can hit Ghost-type Pokémon normally. #define B_SKILL_SWAP GEN_7 // In Gen4+, Skill Swap triggers switch-in abilities after use. +#define B_BRICK_BREAK GEN_7 // In Gen4+, you can destroy your own side's screens. In Gen 5+, screens are not removed if the target is immune. // Ability settings #define B_ABILITY_WEATHER GEN_7 // In Gen6+, ability-induced weather lasts 5 turns. Before, it lasted until the battle ended or until it was changed by a move or a different weather-affecting ability. diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 7134818e06..3f9ba388f7 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -13103,14 +13103,32 @@ static void Cmd_snatchsetbattlers(void) static void Cmd_removelightscreenreflect(void) // brick break { - u8 opposingSide = GetBattlerSide(gBattlerAttacker) ^ BIT_SIDE; - - if (gSideTimers[opposingSide].reflectTimer || gSideTimers[opposingSide].lightscreenTimer) + u8 side; + bool32 failed; + + #if B_BRICK_BREAK >= GEN_4 + side = GetBattlerSide(gBattlerAttacker); + #else + side = GetBattlerSide(gBattlerAttacker) ^ BIT_SIDE; + #endif + + #if B_BRICK_BREAK >= GEN_5 + failed = (gMoveResultFlags & MOVE_RESULT_NO_EFFECT); + #else + failed = FALSE; + #endif + + if (!failed + && (gSideTimers[side].reflectTimer + || gSideTimers[side].lightscreenTimer + || gSideTimers[side].auroraVeilTimer)) { - gSideStatuses[opposingSide] &= ~(SIDE_STATUS_REFLECT); - gSideStatuses[opposingSide] &= ~(SIDE_STATUS_LIGHTSCREEN); - gSideTimers[opposingSide].reflectTimer = 0; - gSideTimers[opposingSide].lightscreenTimer = 0; + gSideStatuses[side] &= ~(SIDE_STATUS_REFLECT); + gSideStatuses[side] &= ~(SIDE_STATUS_LIGHTSCREEN); + gSideStatuses[side] &= ~(SIDE_STATUS_AURORA_VEIL); + gSideTimers[side].reflectTimer = 0; + gSideTimers[side].lightscreenTimer = 0; + gSideTimers[side].auroraVeilTimer = 0; gBattleScripting.animTurn = 1; gBattleScripting.animTargetsHit = 1; } From 05699884d5114694103486021fd709dc58c2c899 Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Fri, 12 Nov 2021 21:19:06 +0100 Subject: [PATCH 45/58] Crits and Confusion bypass screens --- src/battle_util.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/battle_util.c b/src/battle_util.c index 18847b8cce..ee03453550 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8609,7 +8609,8 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move if (((gSideStatuses[defSide] & SIDE_STATUS_REFLECT && IS_MOVE_PHYSICAL(move)) || (gSideStatuses[defSide] & SIDE_STATUS_LIGHTSCREEN && IS_MOVE_SPECIAL(move)) || (gSideStatuses[defSide] & SIDE_STATUS_AURORA_VEIL)) - && abilityAtk != ABILITY_INFILTRATOR) + && abilityAtk != ABILITY_INFILTRATOR && !(isCrit) + && !gProtectStructs[gBattlerAttacker].confusionSelfDmg) { if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) MulModifier(&finalModifier, UQ_4_12(0.66)); From 2e3aafe81becb4f32232903ffb0cf821992f6082 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Fri, 12 Nov 2021 18:53:46 -0300 Subject: [PATCH 46/58] Fix Assault Vest's battle message --- src/battle_message.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_message.c b/src/battle_message.c index 30af20a784..28bcca187b 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -629,7 +629,7 @@ static const u8 sText_TerrainBecomesGrassy[] = _("Grass grew to cover\nthe battl static const u8 sText_TerrainBecomesElectric[] = _("An electric current runs across\nthe battlefield!"); static const u8 sText_TerrainBecomesPsychic[] = _("The battlefield got weird!"); static const u8 sText_TargetElectrified[] = _("The {B_DEF_NAME_WITH_PREFIX}'s moves\nhave been electrified!"); -static const u8 sText_AssaultVestDoesntAllow[] = _("The effects of the {B_LAST_ITEM} prevent status\nmoves from being used!\p"); +static const u8 sText_AssaultVestDoesntAllow[] = _("{B_LAST_ITEM}'s effects prevent\nstatus moves from being used!\p"); static const u8 sText_GravityPreventsUsage[] = _("{B_ATK_NAME_WITH_PREFIX} can't use {B_CURRENT_MOVE}\nbecause of gravity!\p"); static const u8 sText_HealBlockPreventsUsage[] = _("{B_ATK_NAME_WITH_PREFIX} was\nprevented from healing!\p"); static const u8 sText_MegaEvoReacting[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_LAST_ITEM} is \nreacting to {B_ATK_TRAINER_NAME}'s Mega Ring!"); From 2489023332e766aab01fd5c75f4d56b1eeb2241d Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Fri, 12 Nov 2021 19:24:50 -0300 Subject: [PATCH 47/58] Fixed assault Vest restricting Me First --- src/battle_util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/battle_util.c b/src/battle_util.c index 18847b8cce..acc402de45 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1762,7 +1762,7 @@ u8 TrySetCantSelectMoveBattleScript(void) limitations++; } } - else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[move].power == 0) + else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[move].power == 0 && move != MOVE_ME_FIRST) { gCurrentMove = move; gLastUsedItem = gBattleMons[gActiveBattler].item; @@ -1834,7 +1834,7 @@ u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u8 check) unusableMoves |= gBitTable[i]; else if (HOLD_EFFECT_CHOICE(holdEffect) && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != gBattleMons[battlerId].moves[i]) unusableMoves |= gBitTable[i]; - else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[gBattleMons[battlerId].moves[i]].power == 0) + else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[gBattleMons[battlerId].moves[i]].power == 0 && gBattleMons[battlerId].moves[i] != MOVE_STUFF_CHEEKS) unusableMoves |= gBitTable[i]; else if (IsGravityPreventingMove(gBattleMons[battlerId].moves[i])) unusableMoves |= gBitTable[i]; From fdff1ae1b6633ab750f5f12948b734a04f568fa2 Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Fri, 12 Nov 2021 23:34:44 +0100 Subject: [PATCH 48/58] Update src/battle_util.c Co-authored-by: Eduardo Quezada D'Ottone --- src/battle_util.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/battle_util.c b/src/battle_util.c index ee03453550..81897096fb 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8609,7 +8609,8 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move if (((gSideStatuses[defSide] & SIDE_STATUS_REFLECT && IS_MOVE_PHYSICAL(move)) || (gSideStatuses[defSide] & SIDE_STATUS_LIGHTSCREEN && IS_MOVE_SPECIAL(move)) || (gSideStatuses[defSide] & SIDE_STATUS_AURORA_VEIL)) - && abilityAtk != ABILITY_INFILTRATOR && !(isCrit) + && abilityAtk != ABILITY_INFILTRATOR + && !(isCrit) && !gProtectStructs[gBattlerAttacker].confusionSelfDmg) { if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) From c4efe06f3831a344f19b4c56f87acff7d0c19f88 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Fri, 12 Nov 2021 17:55:05 -0500 Subject: [PATCH 49/58] wish update --- include/constants/battle_config.h | 1 + src/battle_script_commands.c | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 8e72b2c99d..b7071221eb 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -153,6 +153,7 @@ #define B_GLARE_GHOST GEN_7 // In Gen4+, Glare can hit Ghost-type Pokémon normally. #define B_SKILL_SWAP GEN_7 // In Gen4+, Skill Swap triggers switch-in abilities after use. #define B_BRICK_BREAK GEN_7 // In Gen4+, you can destroy your own side's screens. In Gen 5+, screens are not removed if the target is immune. +#define B_WISH GEN_7 // In Gen5+, it heals half of the user's max HP instead of the target // Ability settings #define B_ABILITY_WEATHER GEN_7 // In Gen6+, ability-induced weather lasts 5 turns. Before, it lasted until the battle ended or until it was changed by a move or a different weather-affecting ability. diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 3f9ba388f7..36e438ae1e 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -12347,12 +12347,13 @@ static void Cmd_trywish(void) break; case 1: // heal effect PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattlerTarget, gWishFutureKnock.wishMonId[gBattlerTarget]) - - gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP / 2; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; + #if B_WISH >= GEN_5 + gBattleMoveDamage = max(1, gBattleMons[gWishFutureKnock.wishMonId[gBattlerTarget]].maxHP / 2); + #else + gBattleMoveDamage = max(1, gBattleMons[gBattlerTarget].maxHP / 2); + #endif + gBattleMoveDamage *= -1; - if (gBattleMons[gBattlerTarget].hp == gBattleMons[gBattlerTarget].maxHP) gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); else From 704957efb91101a2331c4ea3801f5b226e010b6f Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Sat, 13 Nov 2021 07:30:12 -0300 Subject: [PATCH 50/58] Fixed Relic Song's SE --- data/battle_anim_scripts.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index b10c937aec..fd118a64ac 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -7279,7 +7279,7 @@ Move_RELIC_SONG: monbg ANIM_DEF_PARTNER launchtask AnimTask_MusicNotesRainbowBlend 0x2 0x0 waitforvisualfinish - panse_1B 0x1DF, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 0x2, 0x0 @ ??? + createvisualtask SoundTask_PlayCryWithEcho, 2, ANIM_ATTACKER, 2 launchtask AnimTask_UproarDistortion 0x2 0x1 0x0 launchtemplate gUproarRingSpriteTemplate 0x3 0x6 0x0 0x0 0x0 0x0 0x1f 0x8 launchtemplate gJaggedMusicNoteSpriteTemplate 0x2 0x4 0x0 0x1d 0xfff4 0x0 From 10c390b9ec4a7a8ea0fd184dc2010617348b81d8 Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Sat, 13 Nov 2021 11:53:49 +0100 Subject: [PATCH 51/58] Effectiveness is calculated for moves bypassing king's shield I'm curious what this is for. Before the change it just prevented moves that bypass protections from dealing super effective/not very effective damage to an aegislash using king's shield. So I just added a check with IsBattlerProtected, but in my opinion this line should be entirely removed. Unless I'm missing something. --- src/battle_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_util.c b/src/battle_util.c index 81897096fb..74068ec0b3 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8783,7 +8783,7 @@ static void MulByTypeEffectiveness(u16 *modifier, u16 move, u8 moveType, u8 batt if (moveType == TYPE_FIRE && gDisableStructs[battlerDef].tarShot) mod = UQ_4_12(2.0); - if (gProtectStructs[battlerDef].kingsShielded && gBattleMoves[move].effect != EFFECT_FEINT) + if (gProtectStructs[battlerDef].kingsShielded && gBattleMoves[move].effect != EFFECT_FEINT && IsBattlerProtected(battlerDef, move)) mod = UQ_4_12(1.0); // WEATHER_STRONG_WINDS weakens Super Effective moves against Flying-type Pokémon From 90b6c7d56c50ef8ebca818ee6782be5e11693ea2 Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Sat, 13 Nov 2021 13:24:30 +0100 Subject: [PATCH 52/58] Remove unwanted check According to bulbapedia this check shouldn't exist. It was just preventing effectiveness from being calculated when a move bypassing protection would go through king's shield --- src/battle_util.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/battle_util.c b/src/battle_util.c index 74068ec0b3..5ae26d37bb 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8783,9 +8783,6 @@ static void MulByTypeEffectiveness(u16 *modifier, u16 move, u8 moveType, u8 batt if (moveType == TYPE_FIRE && gDisableStructs[battlerDef].tarShot) mod = UQ_4_12(2.0); - if (gProtectStructs[battlerDef].kingsShielded && gBattleMoves[move].effect != EFFECT_FEINT && IsBattlerProtected(battlerDef, move)) - mod = UQ_4_12(1.0); - // WEATHER_STRONG_WINDS weakens Super Effective moves against Flying-type Pokémon if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_STRONG_WINDS) { From f808710932b83815c1299c1a7297fb699b33f1c1 Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Sat, 13 Nov 2021 13:38:07 +0100 Subject: [PATCH 53/58] Moving IsBattlerProtected --- include/battle_util.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/battle_util.h b/include/battle_util.h index fb74610d0c..d3b930feda 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -102,6 +102,7 @@ u32 IsAbilityOnOpposingSide(u32 battlerId, u32 ability); u32 IsAbilityOnField(u32 ability); u32 IsAbilityOnFieldExcept(u32 battlerId, u32 ability); u32 IsAbilityPreventingEscape(u32 battlerId); +bool32 IsBattlerProtected(u8 battlerId, u16 move); bool32 CanBattlerEscape(u32 battlerId); // no ability check void BattleScriptExecute(const u8* BS_ptr); void BattleScriptPushCursorAndCallback(const u8* BS_ptr); From 89e9b989c943903972cd21cfb95d3c0860a7c474 Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Sat, 13 Nov 2021 13:40:19 +0100 Subject: [PATCH 54/58] Moving isBattlerProtected --- src/battle_script_commands.c | 41 ------------------------------------ 1 file changed, 41 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 7134818e06..5122f4f3bc 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1313,47 +1313,6 @@ static const u8 sBattlePalaceNatureToFlavorTextId[NUM_NATURES] = [NATURE_QUIRKY] = B_MSG_EAGER_FOR_MORE, }; -bool32 IsBattlerProtected(u8 battlerId, u16 move) -{ - // Decorate bypasses protect and detect, but not crafty shield - if (move == MOVE_DECORATE) - { - if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_CRAFTY_SHIELD) - return TRUE; - else if (gProtectStructs[battlerId].protected) - return FALSE; - } - - if (!(gBattleMoves[move].flags & FLAG_PROTECT_AFFECTED)) - return FALSE; - else if (gBattleMoves[move].effect == MOVE_EFFECT_FEINT) - return FALSE; - else if (gProtectStructs[battlerId].protected) - return TRUE; - else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_WIDE_GUARD - && gBattleMoves[move].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)) - return TRUE; - else if (gProtectStructs[battlerId].banefulBunkered) - return TRUE; - else if (gProtectStructs[battlerId].obstructed && !IS_MOVE_STATUS(move)) - return TRUE; - else if (gProtectStructs[battlerId].spikyShielded) - return TRUE; - else if (gProtectStructs[battlerId].kingsShielded && gBattleMoves[move].power != 0) - return TRUE; - else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_QUICK_GUARD - && GetChosenMovePriority(gBattlerAttacker) > 0) - return TRUE; - else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_CRAFTY_SHIELD - && IS_MOVE_STATUS(move)) - return TRUE; - else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_MAT_BLOCK - && !IS_MOVE_STATUS(move)) - return TRUE; - else - return FALSE; -} - static bool32 NoTargetPresent(u32 move) { if (!IsBattlerAlive(gBattlerTarget)) From b3b3cd2c67e4f61664dac27a3b0e684b0b36ce3c Mon Sep 17 00:00:00 2001 From: kleeenexfeu <94004034+kleeenexfeu@users.noreply.github.com> Date: Sat, 13 Nov 2021 13:48:08 +0100 Subject: [PATCH 55/58] IsBattlerProtected --- src/battle_util.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/battle_util.c b/src/battle_util.c index 5ae26d37bb..1f89a082e5 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -7450,6 +7450,48 @@ bool32 IsMoveMakingContact(u16 move, u8 battlerAtk) } } +bool32 IsBattlerProtected(u8 battlerId, u16 move) +{ + // Decorate bypasses protect and detect, but not crafty shield + if (move == MOVE_DECORATE) + { + if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_CRAFTY_SHIELD) + return TRUE; + else if (gProtectStructs[battlerId].protected) + return FALSE; + } + + if (!(gBattleMoves[move].flags & FLAG_PROTECT_AFFECTED)) + return FALSE; + else if (gBattleMoves[move].effect == MOVE_EFFECT_FEINT) + return FALSE; + else if (gProtectStructs[battlerId].protected) + return TRUE; + else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_WIDE_GUARD + && gBattleMoves[move].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)) + return TRUE; + else if (gProtectStructs[battlerId].banefulBunkered) + return TRUE; + else if (gProtectStructs[battlerId].obstructed && !IS_MOVE_STATUS(move)) + return TRUE; + else if (gProtectStructs[battlerId].spikyShielded) + return TRUE; + else if (gProtectStructs[battlerId].kingsShielded && gBattleMoves[move].power != 0) + return TRUE; + else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_QUICK_GUARD + && GetChosenMovePriority(gBattlerAttacker) > 0) + return TRUE; + else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_CRAFTY_SHIELD + && IS_MOVE_STATUS(move)) + return TRUE; + else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_MAT_BLOCK + && !IS_MOVE_STATUS(move)) + return TRUE; + else + return FALSE; +} + + bool32 IsBattlerGrounded(u8 battlerId) { if (GetBattlerHoldEffect(battlerId, TRUE) == HOLD_EFFECT_IRON_BALL) From a4204e5491e30ec2b1cc8fd113cd4ad2d284cd66 Mon Sep 17 00:00:00 2001 From: ghoulslash <41651341+ghoulslash@users.noreply.github.com> Date: Sat, 13 Nov 2021 08:50:24 -0500 Subject: [PATCH 56/58] Update include/constants/battle_config.h Co-authored-by: Eduardo Quezada D'Ottone --- include/constants/battle_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index b7071221eb..0b80c9bc66 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -153,7 +153,7 @@ #define B_GLARE_GHOST GEN_7 // In Gen4+, Glare can hit Ghost-type Pokémon normally. #define B_SKILL_SWAP GEN_7 // In Gen4+, Skill Swap triggers switch-in abilities after use. #define B_BRICK_BREAK GEN_7 // In Gen4+, you can destroy your own side's screens. In Gen 5+, screens are not removed if the target is immune. -#define B_WISH GEN_7 // In Gen5+, it heals half of the user's max HP instead of the target +#define B_WISH_HP_SOURCE GEN_7 // In Gen5+, Wish heals half of the user's max HP instead of the target's. // Ability settings #define B_ABILITY_WEATHER GEN_7 // In Gen6+, ability-induced weather lasts 5 turns. Before, it lasted until the battle ended or until it was changed by a move or a different weather-affecting ability. From b68c596ce5c3029179dcfb53930c1351ffd67f97 Mon Sep 17 00:00:00 2001 From: ghoulslash <41651341+ghoulslash@users.noreply.github.com> Date: Sat, 13 Nov 2021 08:50:30 -0500 Subject: [PATCH 57/58] Update src/battle_script_commands.c Co-authored-by: Eduardo Quezada D'Ottone --- src/battle_script_commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 36e438ae1e..a5cce7c45d 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -12347,7 +12347,7 @@ static void Cmd_trywish(void) break; case 1: // heal effect PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattlerTarget, gWishFutureKnock.wishMonId[gBattlerTarget]) - #if B_WISH >= GEN_5 + #if B_WISH_HP_SOURCE >= GEN_5 gBattleMoveDamage = max(1, gBattleMons[gWishFutureKnock.wishMonId[gBattlerTarget]].maxHP / 2); #else gBattleMoveDamage = max(1, gBattleMons[gBattlerTarget].maxHP / 2); From ad393385ac22595207e1ca0d52b27257636d59aa Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Sat, 13 Nov 2021 10:58:18 -0300 Subject: [PATCH 58/58] Oops --- src/battle_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_util.c b/src/battle_util.c index acc402de45..bef9c4f652 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1834,7 +1834,7 @@ u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u8 check) unusableMoves |= gBitTable[i]; else if (HOLD_EFFECT_CHOICE(holdEffect) && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != gBattleMons[battlerId].moves[i]) unusableMoves |= gBitTable[i]; - else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[gBattleMons[battlerId].moves[i]].power == 0 && gBattleMons[battlerId].moves[i] != MOVE_STUFF_CHEEKS) + else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[gBattleMons[battlerId].moves[i]].power == 0 && gBattleMons[battlerId].moves[i] != MOVE_ME_FIRST) unusableMoves |= gBitTable[i]; else if (IsGravityPreventingMove(gBattleMons[battlerId].moves[i])) unusableMoves |= gBitTable[i];