From 7f50c0b9c35ea8f36da1d9afa73215b6ec10ae72 Mon Sep 17 00:00:00 2001 From: Frank DeBlasio <35279583+fdeblasio@users.noreply.github.com> Date: Tue, 6 Feb 2024 16:24:36 -0500 Subject: [PATCH 1/5] Simplify gTrainerSprites (#4140) * Simplified y_offset equations * Removed trainer pic animation from gTrainerSprites * Used metaprogram to simplify trainer sprites without mugshots * Incorporated comments --------- Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com> --- include/data.h | 1 + src/battle_controller_link_opponent.c | 4 +- src/battle_controller_opponent.c | 4 +- src/battle_controller_player.c | 2 +- src/battle_controller_player_partner.c | 4 +- src/battle_controller_recorded_opponent.c | 4 +- src/battle_controller_recorded_player.c | 2 +- src/battle_controllers.c | 5 +- src/data.c | 4 + src/data/graphics/trainers.h | 195 +++++++++++----------- src/pokemon.c | 4 +- src/trainer_pokemon_sprites.c | 2 +- 12 files changed, 113 insertions(+), 118 deletions(-) diff --git a/include/data.h b/include/data.h index 09a1db7f7e..e80768f68c 100644 --- a/include/data.h +++ b/include/data.h @@ -123,6 +123,7 @@ extern const union AffineAnimCmd *const gAffineAnims_BattleSpriteContest[]; extern const union AnimCmd sAnim_GeneralFrame0[]; extern const union AnimCmd sAnim_GeneralFrame3[]; extern const union AnimCmd *const gAnims_MonPic[]; +extern const union AnimCmd *const sAnims_Trainer[]; extern const struct TrainerSprite gTrainerSprites[]; extern const struct TrainerBacksprite gTrainerBacksprites[]; diff --git a/src/battle_controller_link_opponent.c b/src/battle_controller_link_opponent.c index c9197bc5df..0c71d0a1da 100644 --- a/src/battle_controller_link_opponent.c +++ b/src/battle_controller_link_opponent.c @@ -462,9 +462,7 @@ static void LinkOpponentHandleDrawTrainerPic(u32 battler) } } - BtlController_HandleDrawTrainerPic(battler, trainerPicId, TRUE, - xPos, 40 + 4 * (8 - gTrainerSprites[trainerPicId].y_offset), - -1); + BtlController_HandleDrawTrainerPic(battler, trainerPicId, TRUE, xPos, 40, -1); } static void LinkOpponentHandleTrainerSlide(u32 battler) diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c index 4e272f4d0d..aeb13ec9a5 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -484,9 +484,7 @@ static void OpponentHandleDrawTrainerPic(u32 battler) xPos = 176; } - BtlController_HandleDrawTrainerPic(battler, trainerPicId, TRUE, - xPos, 40 + 4 * (8 - gTrainerSprites[trainerPicId].y_offset), - -1); + BtlController_HandleDrawTrainerPic(battler, trainerPicId, TRUE, xPos, 40, -1); } static void OpponentHandleTrainerSlide(u32 battler) diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index e70784e153..f1bdbdc668 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -1882,7 +1882,7 @@ static void PlayerHandleDrawTrainerPic(u32 battler) if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gPartnerTrainerId < TRAINER_PARTNER(PARTNER_NONE)) { xPos = 90; - yPos = (8 - gTrainerSprites[trainerPicId].y_offset) * 4 + 80; + yPos = 80; } else { diff --git a/src/battle_controller_player_partner.c b/src/battle_controller_player_partner.c index 6ede6587b2..b9dbfdd2c6 100644 --- a/src/battle_controller_player_partner.c +++ b/src/battle_controller_player_partner.c @@ -307,13 +307,13 @@ static void PlayerPartnerHandleDrawTrainerPic(u32 battler) { trainerPicId = gTrainers[gPartnerTrainerId].trainerPic; xPos = 60; - yPos = (8 - gTrainerSprites[trainerPicId].y_offset) * 4 + 80; + yPos = 80; } else { trainerPicId = GetFrontierTrainerFrontSpriteId(gPartnerTrainerId); xPos = 32; - yPos = (8 - gTrainerSprites[trainerPicId].y_offset) * 4 + 80; + yPos = 80; } // Use back pic only if the partner Steven or is custom. diff --git a/src/battle_controller_recorded_opponent.c b/src/battle_controller_recorded_opponent.c index 36caa14c14..abadcc231c 100644 --- a/src/battle_controller_recorded_opponent.c +++ b/src/battle_controller_recorded_opponent.c @@ -420,9 +420,7 @@ static void RecordedOpponentHandleDrawTrainerPic(u32 battler) } } - BtlController_HandleDrawTrainerPic(battler, trainerPicId, TRUE, - xPos, 40 + 4 * (8 - gTrainerSprites[trainerPicId].y_offset), - -1); + BtlController_HandleDrawTrainerPic(battler, trainerPicId, TRUE, xPos, 40, -1); } static void RecordedOpponentHandleTrainerSlideBack(u32 battler) diff --git a/src/battle_controller_recorded_player.c b/src/battle_controller_recorded_player.c index b8322b3eaf..53860990c4 100644 --- a/src/battle_controller_recorded_player.c +++ b/src/battle_controller_recorded_player.c @@ -393,7 +393,7 @@ static void RecordedPlayerHandleDrawTrainerPic(u32 battler) if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) { xPos = 90; - yPos = (8 - gTrainerSprites[trainerPicId].y_offset) * 4 + 80; + yPos = 80; } else { diff --git a/src/battle_controllers.c b/src/battle_controllers.c index 27623c97bc..a7d9610dac 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -2542,10 +2542,7 @@ void BtlController_HandleTrainerSlide(u32 battler, u32 trainerPicId) { DecompressTrainerFrontPic(trainerPicId, battler); SetMultiuseSpriteTemplateToTrainerBack(trainerPicId, GetBattlerPosition(battler)); - gBattlerSpriteIds[battler] = CreateSprite(&gMultiuseSpriteTemplate, - 176, - (8 - gTrainerSprites[trainerPicId].y_offset) * 4 + 40, - 30); + gBattlerSpriteIds[battler] = CreateSprite(&gMultiuseSpriteTemplate, 176, 40, 30); gSprites[gBattlerSpriteIds[battler]].oam.affineParam = trainerPicId; gSprites[gBattlerSpriteIds[battler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerSprites[trainerPicId].palette.tag); gSprites[gBattlerSpriteIds[battler]].x2 = 96; diff --git a/src/data.c b/src/data.c index f559656d35..074b067ac9 100644 --- a/src/data.c +++ b/src/data.c @@ -220,5 +220,9 @@ const union AnimCmd *const gAnims_MonPic[MAX_MON_PIC_FRAMES] = sAnim_MonPic_1, }; +const union AnimCmd *const sAnims_Trainer[] ={ + sAnim_GeneralFrame0, +}; + #include "data/trainer_parties.h" #include "data/trainers.h" diff --git a/src/data/graphics/trainers.h b/src/data/graphics/trainers.h index e20d13ec16..309fd0b80c 100644 --- a/src/data/graphics/trainers.h +++ b/src/data/graphics/trainers.h @@ -292,116 +292,115 @@ const u8 gTrainerBackPic_Steven[] = INCBIN_U8("graphics/trainers/back_pics/steve const u32 gTrainerBackPicPalette_Red[] = INCBIN_U32("graphics/trainers/back_pics/red.gbapal.lz"); const u32 gTrainerBackPicPalette_Leaf[] = INCBIN_U32("graphics/trainers/back_pics/leaf.gbapal.lz"); -static const union AnimCmd *const sAnims_Trainer[] ={ - sAnim_GeneralFrame0, -}; - -#define TRAINER_SPRITE(trainerPic, file, x, y, rotation) \ +// The first two parameters invoke a front pic and palette by +// calling a "TRAINER_PIC" constant (e.g. TRAINER_PIC_HIKER), and +// gTrainerFrontPic/gTrainerPalette pointers, (e.g "gTrainerFrontPic_Hiker" and "gTrainerPalette_Hiker"). +// The last three parameters control the X and Y coordinates and rotation of the mugshot on the screen. +// They default to 0, 0, and 0x200 which are default values used by the majority of the game's trainer sprites. +#define TRAINER_SPRITE(trainerPic, file, ...) \ [TRAINER_PIC_##trainerPic] = \ { \ - .y_offset = 8, \ .frontPic = {gTrainerFrontPic_##file, TRAINER_PIC_SIZE, TRAINER_PIC_##trainerPic},\ .palette = {gTrainerPalette_##file, TRAINER_PIC_##trainerPic}, \ - .animation = sAnims_Trainer, \ - .mugshotCoords = {x, y}, \ - .mugshotRotation = rotation, \ + .mugshotCoords = {DEFAULT(0, __VA_ARGS__), DEFAULT_2(0, __VA_ARGS__)}, \ + .mugshotRotation = DEFAULT_3(0x200, __VA_ARGS__), \ } const struct TrainerSprite gTrainerSprites[] = { - TRAINER_SPRITE(HIKER, Hiker, 0, 0, 0x200), - TRAINER_SPRITE(AQUA_GRUNT_M, AquaGruntM, 0, 0, 0x200), - TRAINER_SPRITE(POKEMON_BREEDER_F, PokemonBreederF, 0, 0, 0x200), - TRAINER_SPRITE(COOLTRAINER_M, CoolTrainerM, 0, 0, 0x200), - TRAINER_SPRITE(BIRD_KEEPER, BirdKeeper, 0, 0, 0x200), - TRAINER_SPRITE(COLLECTOR, Collector, 0, 0, 0x200), - TRAINER_SPRITE(AQUA_GRUNT_F, AquaGruntF, 0, 0, 0x200), - TRAINER_SPRITE(SWIMMER_M, SwimmerM, 0, 0, 0x200), - TRAINER_SPRITE(MAGMA_GRUNT_M, MagmaGruntM, 0, 0, 0x200), - TRAINER_SPRITE(EXPERT_M, ExpertM, 0, 0, 0x200), - TRAINER_SPRITE(AQUA_ADMIN_M, AquaAdminM, 0, 0, 0x200), - TRAINER_SPRITE(BLACK_BELT, BlackBelt, 0, 0, 0x200), - TRAINER_SPRITE(AQUA_ADMIN_F, AquaAdminF, 0, 0, 0x200), - TRAINER_SPRITE(AQUA_LEADER_ARCHIE, AquaLeaderArchie, 0, 0, 0x200), - TRAINER_SPRITE(HEX_MANIAC, HexManiac, 0, 0, 0x200), - TRAINER_SPRITE(AROMA_LADY, AromaLady, 0, 0, 0x200), - TRAINER_SPRITE(RUIN_MANIAC, RuinManiac, 0, 0, 0x200), - TRAINER_SPRITE(INTERVIEWER, Interviewer, 0, 0, 0x200), - TRAINER_SPRITE(TUBER_F, TuberF, 0, 0, 0x200), - TRAINER_SPRITE(TUBER_M, TuberM, 0, 0, 0x200), - TRAINER_SPRITE(COOLTRAINER_F, CoolTrainerF, 0, 0, 0x200), - TRAINER_SPRITE(LADY, Lady, 0, 0, 0x200), - TRAINER_SPRITE(BEAUTY, Beauty, 0, 0, 0x200), - TRAINER_SPRITE(RICH_BOY, RichBoy, 0, 0, 0x200), - TRAINER_SPRITE(EXPERT_F, ExpertF, 0, 0, 0x200), - TRAINER_SPRITE(POKEMANIAC, Pokemaniac, 0, 0, 0x200), - TRAINER_SPRITE(MAGMA_GRUNT_F, MagmaGruntF, 0, 0, 0x200), - TRAINER_SPRITE(GUITARIST, Guitarist, 0, 0, 0x200), - TRAINER_SPRITE(KINDLER, Kindler, 0, 0, 0x200), - TRAINER_SPRITE(CAMPER, Camper, 0, 0, 0x200), - TRAINER_SPRITE(PICNICKER, Picnicker, 0, 0, 0x200), - TRAINER_SPRITE(BUG_MANIAC, BugManiac, 0, 0, 0x200), - TRAINER_SPRITE(POKEMON_BREEDER_M, PokemonBreederM, 0, 0, 0x200), - TRAINER_SPRITE(PSYCHIC_M, PsychicM, 0, 0, 0x200), - TRAINER_SPRITE(PSYCHIC_F, PsychicF, 0, 0, 0x200), - TRAINER_SPRITE(GENTLEMAN, Gentleman, 0, 0, 0x200), - TRAINER_SPRITE(ELITE_FOUR_SIDNEY, EliteFourSidney, 0, 0, 0x200), - TRAINER_SPRITE(ELITE_FOUR_PHOEBE, EliteFourPhoebe, 0, 0, 0x200), + TRAINER_SPRITE(HIKER, Hiker), + TRAINER_SPRITE(AQUA_GRUNT_M, AquaGruntM), + TRAINER_SPRITE(POKEMON_BREEDER_F, PokemonBreederF), + TRAINER_SPRITE(COOLTRAINER_M, CoolTrainerM), + TRAINER_SPRITE(BIRD_KEEPER, BirdKeeper), + TRAINER_SPRITE(COLLECTOR, Collector), + TRAINER_SPRITE(AQUA_GRUNT_F, AquaGruntF), + TRAINER_SPRITE(SWIMMER_M, SwimmerM), + TRAINER_SPRITE(MAGMA_GRUNT_M, MagmaGruntM), + TRAINER_SPRITE(EXPERT_M, ExpertM), + TRAINER_SPRITE(AQUA_ADMIN_M, AquaAdminM), + TRAINER_SPRITE(BLACK_BELT, BlackBelt), + TRAINER_SPRITE(AQUA_ADMIN_F, AquaAdminF), + TRAINER_SPRITE(AQUA_LEADER_ARCHIE, AquaLeaderArchie), + TRAINER_SPRITE(HEX_MANIAC, HexManiac), + TRAINER_SPRITE(AROMA_LADY, AromaLady), + TRAINER_SPRITE(RUIN_MANIAC, RuinManiac), + TRAINER_SPRITE(INTERVIEWER, Interviewer), + TRAINER_SPRITE(TUBER_F, TuberF), + TRAINER_SPRITE(TUBER_M, TuberM), + TRAINER_SPRITE(COOLTRAINER_F, CoolTrainerF), + TRAINER_SPRITE(LADY, Lady), + TRAINER_SPRITE(BEAUTY, Beauty), + TRAINER_SPRITE(RICH_BOY, RichBoy), + TRAINER_SPRITE(EXPERT_F, ExpertF), + TRAINER_SPRITE(POKEMANIAC, Pokemaniac), + TRAINER_SPRITE(MAGMA_GRUNT_F, MagmaGruntF), + TRAINER_SPRITE(GUITARIST, Guitarist), + TRAINER_SPRITE(KINDLER, Kindler), + TRAINER_SPRITE(CAMPER, Camper), + TRAINER_SPRITE(PICNICKER, Picnicker), + TRAINER_SPRITE(BUG_MANIAC, BugManiac), + TRAINER_SPRITE(POKEMON_BREEDER_M, PokemonBreederM), + TRAINER_SPRITE(PSYCHIC_M, PsychicM), + TRAINER_SPRITE(PSYCHIC_F, PsychicF), + TRAINER_SPRITE(GENTLEMAN, Gentleman), + TRAINER_SPRITE(ELITE_FOUR_SIDNEY, EliteFourSidney), + TRAINER_SPRITE(ELITE_FOUR_PHOEBE, EliteFourPhoebe), TRAINER_SPRITE(ELITE_FOUR_GLACIA, EliteFourGlacia, -4, 4, 0x1B0), TRAINER_SPRITE(ELITE_FOUR_DRAKE, EliteFourDrake, 0, 5, 0x1A0), - TRAINER_SPRITE(LEADER_ROXANNE, LeaderRoxanne, 0, 0, 0x200), - TRAINER_SPRITE(LEADER_BRAWLY, LeaderBrawly, 0, 0, 0x200), - TRAINER_SPRITE(LEADER_WATTSON, LeaderWattson, 0, 0, 0x200), - TRAINER_SPRITE(LEADER_FLANNERY, LeaderFlannery, 0, 0, 0x200), - TRAINER_SPRITE(LEADER_NORMAN, LeaderNorman, 0, 0, 0x200), - TRAINER_SPRITE(LEADER_WINONA, LeaderWinona, 0, 0, 0x200), - TRAINER_SPRITE(LEADER_TATE_AND_LIZA, LeaderTateAndLiza, 0, 0, 0x200), - TRAINER_SPRITE(LEADER_JUAN, LeaderJuan, 0, 0, 0x200), - TRAINER_SPRITE(SCHOOL_KID_M, SchoolKidM, 0, 0, 0x200), - TRAINER_SPRITE(SCHOOL_KID_F, SchoolKidF, 0, 0, 0x200), - TRAINER_SPRITE(SR_AND_JR, SrAndJr, 0, 0, 0x200), - TRAINER_SPRITE(POKEFAN_M, PokefanM, 0, 0, 0x200), - TRAINER_SPRITE(POKEFAN_F, PokefanF, 0, 0, 0x200), - TRAINER_SPRITE(YOUNGSTER, Youngster, 0, 0, 0x200), + TRAINER_SPRITE(LEADER_ROXANNE, LeaderRoxanne), + TRAINER_SPRITE(LEADER_BRAWLY, LeaderBrawly), + TRAINER_SPRITE(LEADER_WATTSON, LeaderWattson), + TRAINER_SPRITE(LEADER_FLANNERY, LeaderFlannery), + TRAINER_SPRITE(LEADER_NORMAN, LeaderNorman), + TRAINER_SPRITE(LEADER_WINONA, LeaderWinona), + TRAINER_SPRITE(LEADER_TATE_AND_LIZA, LeaderTateAndLiza), + TRAINER_SPRITE(LEADER_JUAN, LeaderJuan), + TRAINER_SPRITE(SCHOOL_KID_M, SchoolKidM), + TRAINER_SPRITE(SCHOOL_KID_F, SchoolKidF), + TRAINER_SPRITE(SR_AND_JR, SrAndJr), + TRAINER_SPRITE(POKEFAN_M, PokefanM), + TRAINER_SPRITE(POKEFAN_F, PokefanF), + TRAINER_SPRITE(YOUNGSTER, Youngster), TRAINER_SPRITE(CHAMPION_WALLACE, ChampionWallace, -8, 7, 0x188), - TRAINER_SPRITE(FISHERMAN, Fisherman, 0, 0, 0x200), - TRAINER_SPRITE(CYCLING_TRIATHLETE_M, CyclingTriathleteM, 0, 0, 0x200), - TRAINER_SPRITE(CYCLING_TRIATHLETE_F, CyclingTriathleteF, 0, 0, 0x200), - TRAINER_SPRITE(RUNNING_TRIATHLETE_M, RunningTriathleteM, 0, 0, 0x200), - TRAINER_SPRITE(RUNNING_TRIATHLETE_F, RunningTriathleteF, 0, 0, 0x200), - TRAINER_SPRITE(SWIMMING_TRIATHLETE_M, SwimmingTriathleteM, 0, 0, 0x200), - TRAINER_SPRITE(SWIMMING_TRIATHLETE_F, SwimmingTriathleteF, 0, 0, 0x200), - TRAINER_SPRITE(DRAGON_TAMER, DragonTamer, 0, 0, 0x200), - TRAINER_SPRITE(NINJA_BOY, NinjaBoy, 0, 0, 0x200), - TRAINER_SPRITE(BATTLE_GIRL, BattleGirl, 0, 0, 0x200), - TRAINER_SPRITE(PARASOL_LADY, ParasolLady, 0, 0, 0x200), - TRAINER_SPRITE(SWIMMER_F, SwimmerF, 0, 0, 0x200), - TRAINER_SPRITE(TWINS, Twins, 0, 0, 0x200), - TRAINER_SPRITE(SAILOR, Sailor, 0, 0, 0x200), - TRAINER_SPRITE(MAGMA_ADMIN, MagmaAdmin, 0, 0, 0x200), - TRAINER_SPRITE(WALLY, Wally, 0, 0, 0x200), - TRAINER_SPRITE(BRENDAN, Brendan, 0, 0, 0x200), - TRAINER_SPRITE(MAY, May, 0, 0, 0x200), - TRAINER_SPRITE(BUG_CATCHER, BugCatcher, 0, 0, 0x200), - TRAINER_SPRITE(POKEMON_RANGER_M, PokemonRangerM, 0, 0, 0x200), - TRAINER_SPRITE(POKEMON_RANGER_F, PokemonRangerF, 0, 0, 0x200), - TRAINER_SPRITE(MAGMA_LEADER_MAXIE, MagmaLeaderMaxie, 0, 0, 0x200), - TRAINER_SPRITE(LASS, Lass, 0, 0, 0x200), - TRAINER_SPRITE(YOUNG_COUPLE, YoungCouple, 0, 0, 0x200), - TRAINER_SPRITE(OLD_COUPLE, OldCouple, 0, 0, 0x200), - TRAINER_SPRITE(SIS_AND_BRO, SisAndBro, 0, 0, 0x200), + TRAINER_SPRITE(FISHERMAN, Fisherman), + TRAINER_SPRITE(CYCLING_TRIATHLETE_M, CyclingTriathleteM), + TRAINER_SPRITE(CYCLING_TRIATHLETE_F, CyclingTriathleteF), + TRAINER_SPRITE(RUNNING_TRIATHLETE_M, RunningTriathleteM), + TRAINER_SPRITE(RUNNING_TRIATHLETE_F, RunningTriathleteF), + TRAINER_SPRITE(SWIMMING_TRIATHLETE_M, SwimmingTriathleteM), + TRAINER_SPRITE(SWIMMING_TRIATHLETE_F, SwimmingTriathleteF), + TRAINER_SPRITE(DRAGON_TAMER, DragonTamer), + TRAINER_SPRITE(NINJA_BOY, NinjaBoy), + TRAINER_SPRITE(BATTLE_GIRL, BattleGirl), + TRAINER_SPRITE(PARASOL_LADY, ParasolLady), + TRAINER_SPRITE(SWIMMER_F, SwimmerF), + TRAINER_SPRITE(TWINS, Twins), + TRAINER_SPRITE(SAILOR, Sailor), + TRAINER_SPRITE(MAGMA_ADMIN, MagmaAdmin), + TRAINER_SPRITE(WALLY, Wally), + TRAINER_SPRITE(BRENDAN, Brendan), + TRAINER_SPRITE(MAY, May), + TRAINER_SPRITE(BUG_CATCHER, BugCatcher), + TRAINER_SPRITE(POKEMON_RANGER_M, PokemonRangerM), + TRAINER_SPRITE(POKEMON_RANGER_F, PokemonRangerF), + TRAINER_SPRITE(MAGMA_LEADER_MAXIE, MagmaLeaderMaxie), + TRAINER_SPRITE(LASS, Lass), + TRAINER_SPRITE(YOUNG_COUPLE, YoungCouple), + TRAINER_SPRITE(OLD_COUPLE, OldCouple), + TRAINER_SPRITE(SIS_AND_BRO, SisAndBro), TRAINER_SPRITE(STEVEN, Steven, 0, 7, 0x188), - TRAINER_SPRITE(SALON_MAIDEN_ANABEL, SalonMaidenAnabel, 0, 0, 0x200), - TRAINER_SPRITE(DOME_ACE_TUCKER, DomeAceTucker, 0, 0, 0x200), - TRAINER_SPRITE(PALACE_MAVEN_SPENSER, PalaceMavenSpenser, 0, 0, 0x200), - TRAINER_SPRITE(ARENA_TYCOON_GRETA, ArenaTycoonGreta, 0, 0, 0x200), - TRAINER_SPRITE(FACTORY_HEAD_NOLAND, FactoryHeadNoland, 0, 0, 0x200), - TRAINER_SPRITE(PIKE_QUEEN_LUCY, PikeQueenLucy, 0, 0, 0x200), - TRAINER_SPRITE(PYRAMID_KING_BRANDON, PyramidKingBrandon, 0, 0, 0x200), - TRAINER_SPRITE(RED, Red, 0, 0, 0x200), - TRAINER_SPRITE(LEAF, Leaf, 0, 0, 0x200), - TRAINER_SPRITE(RS_BRENDAN, RubySapphireBrendan, 0, 0, 0x200), - TRAINER_SPRITE(RS_MAY, RubySapphireMay, 0, 0, 0x200), + TRAINER_SPRITE(SALON_MAIDEN_ANABEL, SalonMaidenAnabel), + TRAINER_SPRITE(DOME_ACE_TUCKER, DomeAceTucker), + TRAINER_SPRITE(PALACE_MAVEN_SPENSER, PalaceMavenSpenser), + TRAINER_SPRITE(ARENA_TYCOON_GRETA, ArenaTycoonGreta), + TRAINER_SPRITE(FACTORY_HEAD_NOLAND, FactoryHeadNoland), + TRAINER_SPRITE(PIKE_QUEEN_LUCY, PikeQueenLucy), + TRAINER_SPRITE(PYRAMID_KING_BRANDON, PyramidKingBrandon), + TRAINER_SPRITE(RED, Red), + TRAINER_SPRITE(LEAF, Leaf), + TRAINER_SPRITE(RS_BRENDAN, RubySapphireBrendan), + TRAINER_SPRITE(RS_MAY, RubySapphireMay), }; static const union AnimCmd sAnimCmd_Hoenn[] = diff --git a/src/pokemon.c b/src/pokemon.c index 8bb215f901..da5bb15175 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -1927,7 +1927,7 @@ void SetMultiuseSpriteTemplateToTrainerBack(u16 trainerPicId, u8 battlerPosition gMultiuseSpriteTemplate = gMonSpritesGfxPtr->templates[battlerPosition]; else gMultiuseSpriteTemplate = gBattlerSpriteTemplates[battlerPosition]; - gMultiuseSpriteTemplate.anims = gTrainerSprites[trainerPicId].animation; + gMultiuseSpriteTemplate.anims = sAnims_Trainer; } } @@ -1939,7 +1939,7 @@ void SetMultiuseSpriteTemplateToTrainerFront(u16 trainerPicId, u8 battlerPositio gMultiuseSpriteTemplate = gBattlerSpriteTemplates[battlerPosition]; gMultiuseSpriteTemplate.paletteTag = trainerPicId; - gMultiuseSpriteTemplate.anims = gTrainerSprites[trainerPicId].animation; + gMultiuseSpriteTemplate.anims = sAnims_Trainer; } static void EncryptBoxMon(struct BoxPokemon *boxMon) diff --git a/src/trainer_pokemon_sprites.c b/src/trainer_pokemon_sprites.c index cfa013620a..06b21d05cf 100644 --- a/src/trainer_pokemon_sprites.c +++ b/src/trainer_pokemon_sprites.c @@ -116,7 +116,7 @@ static void AssignSpriteAnimsTable(bool8 isTrainer) if (!isTrainer) sCreatingSpriteTemplate.anims = gAnims_MonPic; else - sCreatingSpriteTemplate.anims = gTrainerSprites[0].animation; + sCreatingSpriteTemplate.anims = sAnims_Trainer; } static u16 CreatePicSprite(u16 species, bool8 isShiny, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag, bool8 isTrainer) From 5d2dfe218ea01f28588da574cf0251ab440e59f7 Mon Sep 17 00:00:00 2001 From: ZnogyroP Date: Tue, 6 Feb 2024 19:18:35 -0500 Subject: [PATCH 2/5] Fixes to strings + Hospitality (#4147) * Fixes to strings + Hospitality * Requested changes --------- Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com> --- src/battle_message.c | 12 ++++++------ src/battle_util.c | 1 + test/battle/ability/dry_skin.c | 2 +- test/battle/ability/hospitality.c | 8 ++++---- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/battle_message.c b/src/battle_message.c index 97ea9794a5..a99f3cde9d 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -613,10 +613,10 @@ static const u8 sText_TeravoltEnters[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is r static const u8 sText_TurboblazeEnters[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is radiating\na blazing aura!"); static const u8 sText_SlowStartEnters[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} can't get it going!"); static const u8 sText_SlowStartEnd[] = _("{B_ATK_NAME_WITH_PREFIX} finally got\nits act together!"); -static const u8 sText_SolarPowerHpDrop[] = _("The {B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}\ntakes its toll!"); +static const u8 sText_SolarPowerHpDrop[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}\ntakes its toll!"); static const u8 sText_AftermathDmg[] = _("{B_ATK_NAME_WITH_PREFIX} is hurt!"); static const u8 sText_AnticipationActivates[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} shuddered\nin anticipation!"); -static const u8 sText_ForewarnActivates[] = _("{B_SCR_ACTIVE_ABILITY} alerted {B_SCR_ACTIVE_NAME_WITH_PREFIX}\nto the {B_DEF_NAME_WITH_PREFIX}'s {B_BUFF1}!"); +static const u8 sText_ForewarnActivates[] = _("{B_SCR_ACTIVE_ABILITY} alerted {B_SCR_ACTIVE_NAME_WITH_PREFIX}\nto {B_DEF_NAME_WITH_PREFIX}'s {B_BUFF1}!"); static const u8 sText_IceBodyHpGain[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}\nhealed it a little bit!"); static const u8 sText_SnowWarningHail[] = _("It started to hail!"); static const u8 sText_SnowWarningSnow[] = _("It started to snow!"); @@ -648,14 +648,14 @@ static const u8 sText_ToxicSpikesDisappearedFromTeam[] = _("The poison spikes di static const u8 sText_StealthRockDisappearedFromTeam[] = _("The pointed stones disappeared\nfrom around {B_ATK_TEAM2} team!"); static const u8 sText_StickyWebDisappearedFromTeam[] = _("The sticky web has disappeared from\nthe ground around {B_ATK_TEAM2} team!"); static const u8 sText_StickyWebUsed[] = _("A sticky web spreads out on the\nground around {B_DEF_TEAM2} team!"); -static const u8 sText_QuashSuccess[] = _("The opposing {B_DEF_NAME_WITH_PREFIX}'s\nmove was postponed!"); +static const u8 sText_QuashSuccess[] = _("{B_DEF_NAME_WITH_PREFIX}'s\nmove was postponed!"); static const u8 sText_IonDelugeOn[] = _("A deluge of ions showers\nthe battlefield!"); static const u8 sText_TopsyTurvySwitchedStats[] = _("{B_DEF_NAME_WITH_PREFIX}'s stat changes were\nall reversed!"); static const u8 sText_TerrainBecomesMisty[] = _("Mist swirled about\nthe battlefield!"); static const u8 sText_TerrainBecomesGrassy[] = _("Grass grew to cover\nthe battlefield!"); 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_TargetElectrified[] = _("{B_DEF_NAME_WITH_PREFIX}'s moves\nhave been electrified!"); 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"); @@ -758,7 +758,7 @@ static const u8 sText_StuffCheeksCantSelect[] = _("Stuff Cheeks cannot be\nselec static const u8 sText_PkmnRevertedToPrimal[] = _("{B_ATK_NAME_WITH_PREFIX}'s Primal Reversion!\nIt reverted to its primal form!"); static const u8 sText_ButPokemonCantUseTheMove[] = _("But {B_ATK_NAME_WITH_PREFIX} can't\nuse the move!"); static const u8 sText_ButHoopaCantUseIt[] = _("But Hoopa can't use it\nthe way it is now!"); -static const u8 sText_BrokeThroughProtection[] = _("It broke through the\n{B_DEF_NAME_WITH_PREFIX}'s protection!"); +static const u8 sText_BrokeThroughProtection[] = _("It broke through\n{B_DEF_NAME_WITH_PREFIX}'s protection!"); static const u8 sText_AbilityAllowsOnlyMove[] = _("{B_ATK_ABILITY} allows the\nuse of only {B_CURRENT_MOVE}!\p"); 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!"); @@ -834,7 +834,7 @@ static const u8 sText_HurtByTheSeaOfFire[] = _("{B_ATK_TEAM1} {B_ATK_NAME_WITH_P static const u8 sText_TheSeaOfFireDisappeared[] = _("The sea of fire around {B_ATK_TEAM2}\nteam disappeared!"); static const u8 sText_SwampEnvelopedSide[] = _("A swamp enveloped\n{B_DEF_TEAM2} team!"); static const u8 sText_TheSwampDisappeared[] = _("The swamp around {B_ATK_TEAM2}\nteam disappeared!"); -static const u8 sText_HospitalityRestoration[] = _("The {B_ATK_PARTNER_NAME} drank down all\nthe matcha that Sinistcha made!"); +static const u8 sText_HospitalityRestoration[] = _("{B_ATK_PARTNER_NAME} drank down all the\nmatcha that {B_ATK_NAME_WITH_PREFIX} made!"); static const u8 sText_ElectroShotCharging[] = _("{B_ATK_NAME_WITH_PREFIX} absorbed\nelectricity!"); static const u8 sText_ItemWasUsedUp[] = _("The {B_LAST_ITEM}\nwas used up..."); static const u8 sText_AttackerLostItsType[] = _("{B_ATK_NAME_WITH_PREFIX} lost\nits {B_BUFF1} type!"); diff --git a/src/battle_util.c b/src/battle_util.c index fe40102f6f..39b9060426 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -4653,6 +4653,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 if (!gSpecialStatuses[battler].switchInAbilityDone && IsDoubleBattle() && gBattleMons[partner].hp < gBattleMons[partner].maxHP) { gBattlerTarget = partner; + gBattlerAttacker = battler; gSpecialStatuses[battler].switchInAbilityDone = TRUE; gBattleMoveDamage = (GetNonDynamaxMaxHP(partner) / 4) * -1; BattleScriptPushCursorAndCallback(BattleScript_HospitalityActivates); diff --git a/test/battle/ability/dry_skin.c b/test/battle/ability/dry_skin.c index e91daa1641..368e4b8047 100644 --- a/test/battle/ability/dry_skin.c +++ b/test/battle/ability/dry_skin.c @@ -11,7 +11,7 @@ SINGLE_BATTLE_TEST("Dry Skin causes 1/8th Max HP damage in Sun") } SCENE { ABILITY_POPUP(player, ABILITY_DRY_SKIN); HP_BAR(player, damage: 200 / 8); - MESSAGE("The Parasect's Dry Skin takes its toll!"); + MESSAGE("Parasect's Dry Skin takes its toll!"); } } diff --git a/test/battle/ability/hospitality.c b/test/battle/ability/hospitality.c index 8bb78bffc0..74648b0c9a 100644 --- a/test/battle/ability/hospitality.c +++ b/test/battle/ability/hospitality.c @@ -18,12 +18,12 @@ DOUBLE_BATTLE_TEST("Hospitality user restores 25% of ally's health") } SCENE { if (health == 75) { ABILITY_POPUP(playerLeft, ABILITY_HOSPITALITY); - MESSAGE("The Wobbuffet drank down all the matcha that Sinistcha made!"); + MESSAGE("Wobbuffet drank down all the matcha that Ptchageist made!"); HP_BAR(playerRight, damage: -25); } else { NONE_OF { ABILITY_POPUP(playerLeft, ABILITY_HOSPITALITY); - MESSAGE("The Wobbuffet drank down all the matcha that Sinistcha made!"); + MESSAGE("Wobbuffet drank down all the matcha that Ptchageist made!"); HP_BAR(playerRight, damage: -25); } } @@ -44,7 +44,7 @@ DOUBLE_BATTLE_TEST("Hospitality user restores 25% of ally's health on switch-in" MESSAGE("Wobbuffet, that's enough! Come back!"); MESSAGE("Go! Ptchageist!"); ABILITY_POPUP(playerLeft, ABILITY_HOSPITALITY); - MESSAGE("The Wobbuffet drank down all the matcha that Sinistcha made!"); + MESSAGE("Wobbuffet drank down all the matcha that Ptchageist made!"); HP_BAR(playerRight, damage: -25); } } @@ -65,6 +65,6 @@ DOUBLE_BATTLE_TEST("Hospitality ignores Substitute") MESSAGE("Wobbuffet, that's enough! Come back!"); MESSAGE("Go! Ptchageist!"); ABILITY_POPUP(playerLeft, ABILITY_HOSPITALITY); - MESSAGE("The Wobbuffet drank down all the matcha that Sinistcha made!"); + MESSAGE("Wobbuffet drank down all the matcha that Ptchageist made!"); } } From b18857321a477619ca0aa8709a98d3a80ab1efa2 Mon Sep 17 00:00:00 2001 From: Bassoonian Date: Wed, 7 Feb 2024 10:13:03 +0100 Subject: [PATCH 3/5] Update README.md (#4144) * Update README.md Removes Mulches, Dynamax Candy and Mints from the "Existing item data but missing effects" category in upcoming's README, as said features do in fact have functionality in upcoming. * Add Guillotine to feature branch list * Update README.md Co-authored-by: Eduardo Quezada D'Ottone --------- Co-authored-by: Eduardo Quezada D'Ottone --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 82a9582337..aa85e556a6 100644 --- a/README.md +++ b/README.md @@ -118,9 +118,6 @@ Based off RHH's pokeemerald-expansion v1.7.3 https://github.com/rh-hideout/pokee - Berserk Gene - Most battle items from Gen 4+ - Existing item data but missing effects: - - Mints - - Dynamax Candy - - Mulches - Gimmighoul Coin - Booster Energy - Tera Shards @@ -141,6 +138,7 @@ Based off RHH's pokeemerald-expansion v1.7.3 https://github.com/rh-hideout/pokee - *Dark Mode*. - [Nature Colors](https://github.com/DizzyEggg/pokeemerald/tree/nature_color) in summary screen by @DizzyEggg - [Dynamic Multichoice](https://github.com/SBird1337/pokeemerald/tree/feature/dynmulti) by @SBird1337 + - [Guillotine](https://github.com/aarant/pokeemerald/tree/guillotine) (Decapitalization) by @aarant - ***Other features*** - Pressing B while holding a Pokémon drops them like in modern games (configurable). - Running indoors (configurable). From 02e4154f0c81214ef1b702b1f3e8cacf21d528ab Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Wed, 7 Feb 2024 11:26:23 +0100 Subject: [PATCH 4/5] Electro Shot Animation (#4148) Co-authored-by: Bassoonian --- data/battle_anim_scripts.s | 89 +++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index b9bd3efaf0..f20b30acef 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -17228,6 +17228,94 @@ Move_JET_PUNCH: blendoff end +Move_ELECTRO_SHOT:: + choosetwoturnanim ElectroShotSetUp, ElectroShotUnleash +ElectroShotEnd: + waitforvisualfinish + end +ElectroShotSetUp: + loadspritegfx ANIM_TAG_CIRCLE_OF_LIGHT @charge animation + loadspritegfx ANIM_TAG_ORBS @circles + loadspritegfx ANIM_TAG_BLACK_BALL_2 @blast + loadspritegfx ANIM_TAG_SPARK_2 @blast particles + loadspritegfx ANIM_TAG_GRAY_SMOKE @dispersal + monbg ANIM_ATTACKER + setalpha 14, 8 + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BG, 0x1, 0x0, 0xC, 0x0 + waitforvisualfinish + loopsewithpan SE_M_MEGA_KICK, SOUND_PAN_ATTACKER, 0xE, 0x8 + createsprite gGrowingChargeOrbSpriteTemplate, ANIM_ATTACKER, 2, 0x0 + call TechnoBlastCharging1 + delay 0xF + call TechnoBlastCharging2 + delay 0xF + call TechnoBlastCharging1 + delay 0xF + call TechnoBlastCharging2 + delay 0xF + call TechnoBlastCharging1 + delay 0xF + call TechnoBlastCharging2 + delay 0xF + call TechnoBlastCharging1 + delay 0xF + call TechnoBlastCharging2 + delay 0xF + call TechnoBlastCharging1 + delay 0xF + call TechnoBlastCharging2 + delay 0xF + waitforvisualfinish + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BG, 0x1, 0xC, 0x0, 0x0 + waitforvisualfinish + blendoff + clearmonbg ANIM_ATTACKER + goto ElectroShotEnd +ElectroShotUnleash: + loadspritegfx ANIM_TAG_ELECTRIC_ORBS + loadspritegfx ANIM_TAG_CIRCLE_OF_LIGHT + loadspritegfx ANIM_TAG_ELECTRICITY + loadspritegfx ANIM_TAG_SPARK_2 + setalpha 12, 8 + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BG, 0x1, 0x0, 0xC, 0x0 + waitforvisualfinish + playsewithpan SE_M_CHARGE, SOUND_PAN_ATTACKER + delay 12 + createsprite gGrowingShockWaveOrbSpriteTemplate, ANIM_ATTACKER, 2 + createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 2, 0, 11, RGB(31, 31, 22) + delay 50 + createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_THUNDERBOLT2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 1, 16, 0, 5 + createvisualtask AnimTask_ShakeMon, 2, ANIM_ATTACKER, 0, 4, 50, 1 + call SparkBeam + call SparkBeam + call SparkBeam + call SparkBeam + call SparkBeam + createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 50, 1 + createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 2, 11, 0, RGB(31, 31, 22) + createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 2, 0, 11, RGB(31, 31, 22) + call SparkBeam + call SparkBeam + call SparkBeam + call SparkBeam + call SparkBeam + call SparkBeam + call SparkBeam + call SparkBeam + call SparkBeam + call SparkBeam + call SparkBeam + call SparkBeam + call SparkBeam + call SparkBeam + delay 20 + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BG, 0x1, 0xC, 0x0, 0x0 + waitforvisualfinish + createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 2, 11, 0, RGB(31, 31, 22) + waitforvisualfinish + blendoff + end + Move_TERA_BLAST:: Move_AXE_KICK:: Move_LAST_RESPECTS:: @@ -17271,7 +17359,6 @@ Move_HYDRO_STEAM:: Move_BLOOD_MOON:: Move_MATCHA_GOTCHA:: Move_IVY_CUDGEL:: -Move_ELECTRO_SHOT:: Move_TERA_STARSTORM:: Move_FICKLE_BEAM:: Move_THUNDERCLAP:: From 8d4c3a8acb5abc8c79c4e4a6e180eee59c961856 Mon Sep 17 00:00:00 2001 From: Nephrite Date: Wed, 7 Feb 2024 23:42:05 +0900 Subject: [PATCH 5/5] Two turn moves tweaks (#4150) * Two turn move tweaks Fixed comment bug and added CheckIfCanFireTwoTurnMoveNow function * Renamed `tryfiretwoturnmovenowcheckeffect` macro --- asm/macros/battle_script.inc | 10 +++++++++- data/battle_scripts_1.s | 10 ++++++---- src/battle_script_commands.c | 33 ++++++++++++++++++++++++--------- 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index b3a5c77716..5ae9b691b2 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1061,13 +1061,21 @@ setsemiinvulnerablebit TRUE .endm - .macro jumpifweathercheckchargeeffects battler:req, checkChargeTurnEffects:req, jumpInstr:req + .macro tryfiretwoturnmovenowbyeffect battler:req, checkChargeTurnEffects:req, jumpInstr:req .byte 0xc6 .byte \battler .byte \checkChargeTurnEffects .4byte \jumpInstr .endm + .macro tryfiretwoturnmovewithoutcharging battler:req, jumpInstr:req + tryfiretwoturnmovenowbyeffect \battler, TRUE, \jumpInstr + .endm + + .macro tryfiretwoturnmoveaftercharging battler:req, jumpInstr:req + tryfiretwoturnmovenowbyeffect \battler, FALSE, \jumpInstr + .endm + .macro setminimize .byte 0xc7 .endm diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index d3ac025056..a5d3b7cbcf 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -3718,9 +3718,9 @@ BattleScript_PowerHerbActivation: BattleScript_EffectTwoTurnsAttack:: jumpifstatus2 BS_ATTACKER, STATUS2_MULTIPLETURNS, BattleScript_TwoTurnMovesSecondTurn jumpifword CMP_COMMON_BITS, gHitMarker, HITMARKER_NO_ATTACKSTRING, BattleScript_TwoTurnMovesSecondTurn - jumpifweathercheckchargeeffects BS_ATTACKER, TRUE, BattleScript_EffectHit + tryfiretwoturnmovewithoutcharging BS_ATTACKER, BattleScript_EffectHit @ e.g. Solar Beam call BattleScript_FirstChargingTurn - jumpifweathercheckchargeeffects BS_ATTACKER, FALSE, BattleScript_TwoTurnMovesSecondTurn + tryfiretwoturnmoveaftercharging BS_ATTACKER, BattleScript_TwoTurnMovesSecondTurn @ e.g. Electro Shot jumpifholdeffect BS_ATTACKER, HOLD_EFFECT_POWER_HERB, BattleScript_TwoTurnMovesSecondPowerHerbActivates goto BattleScript_MoveEnd @@ -3766,7 +3766,8 @@ BattleScript_GeomancyEnd:: BattleScript_FirstChargingTurn:: attackcanceler -.if B_UPDATED_MOVE_DATA >= GEN_5 @ before Gen 5, charge moves did not print an attack string on the charge turn +@ before Gen 5, charge moves did not print an attack string on the charge turn +.if B_UPDATED_MOVE_DATA >= GEN_5 flushtextbox attackstring waitmessage B_WAIT_TIME_LONG @@ -3784,7 +3785,8 @@ BattleScript_TwoTurnMovesSecondPowerHerbActivates: call BattleScript_PowerHerbActivation call BattleScript_TwoTurnMovesSecondTurnRet accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE -.if B_UPDATED_MOVE_DATA < GEN_5 @ before Gen 5, charge moves did not print an attack string on the charge turn +@ before Gen 5, charge moves did not print an attack string on the charge turn +.if B_UPDATED_MOVE_DATA < GEN_5 attackstring .endif goto BattleScript_HitFromCritCalc diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index df023953f4..cf282162ac 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -556,7 +556,7 @@ static void Cmd_selectfirstvalidtarget(void); static void Cmd_trysetfutureattack(void); static void Cmd_trydobeatup(void); static void Cmd_setsemiinvulnerablebit(void); -static void Cmd_jumpifweathercheckchargeeffects(void); +static void Cmd_tryfiretwoturnmovenowbyeffect(void); static void Cmd_setminimize(void); static void Cmd_sethail(void); static void Cmd_trymemento(void); @@ -815,7 +815,7 @@ void (* const gBattleScriptingCommandsTable[])(void) = Cmd_trysetfutureattack, //0xC3 Cmd_trydobeatup, //0xC4 Cmd_setsemiinvulnerablebit, //0xC5 - Cmd_jumpifweathercheckchargeeffects, //0xC6 + Cmd_tryfiretwoturnmovenowbyeffect, //0xC6 Cmd_setminimize, //0xC7 Cmd_sethail, //0xC8 Cmd_trymemento, //0xC9 @@ -13668,16 +13668,31 @@ static void Cmd_setsemiinvulnerablebit(void) gBattlescriptCurrInstr = cmd->nextInstr; } -static void Cmd_jumpifweathercheckchargeeffects(void) +static bool32 CheckIfCanFireTwoTurnMoveNow(u8 battler, bool8 checkChargeTurnEffects) +{ + // Semi-invulnerable moves cannot skip their charge turn (except with Power Herb) + if (gBattleMoveEffects[gMovesInfo[gCurrentMove].effect].semiInvulnerableEffect == TRUE) + return FALSE; + + // If this move has charge turn effects, it must charge, activate them, then try to fire + if (checkChargeTurnEffects && MoveHasChargeTurnMoveEffect(gCurrentMove)) + return FALSE; + + // Insert custom conditions here + + // Certain two-turn moves may fire on the first turn in the right weather (Solar Beam, Electro Shot) + // By default, all two-turn moves have the option of adding weather to their argument + if (IsBattlerWeatherAffected(battler, HIHALF(gMovesInfo[gCurrentMove].argument))) + return TRUE; + + return FALSE; +} + +static void Cmd_tryfiretwoturnmovenowbyeffect(void) { CMD_ARGS(u8 battler, bool8 checkChargeTurnEffects, const u8 *jumpInstr); - /* If this is NOT semi-invulnerable move and we don't have charge turn effects - yet to fire, we can fire the move right away so long as the weather matches - the argument and the battler is affected by it (not blocked by Cloud Nine etc) */ - if (gBattleMoveEffects[gMovesInfo[gCurrentMove].effect].semiInvulnerableEffect == FALSE - && !(cmd->checkChargeTurnEffects && MoveHasChargeTurnMoveEffect(gCurrentMove)) - && IsBattlerWeatherAffected(cmd->battler, HIHALF(gMovesInfo[gCurrentMove].argument))) + if (CheckIfCanFireTwoTurnMoveNow(cmd->battler, cmd->checkChargeTurnEffects) == TRUE) { gBattleScripting.animTurn = 1; gBattlescriptCurrInstr = cmd->jumpInstr;