From a36c35aea10133b7caaac945111fa7174bcd168c Mon Sep 17 00:00:00 2001 From: AgustinGDLV Date: Sun, 26 Feb 2023 23:35:36 -0800 Subject: [PATCH] implemented G-Max Vine Lash, G-Max Wildfire, G-Max Cannonade, G-Max Volcalith --- asm/macros/battle_script.inc | 4 +++ data/battle_scripts_1.s | 32 ++++++++++++++++++ include/battle.h | 2 ++ include/battle_dynamax.h | 3 +- include/battle_scripts.h | 6 ++-- include/constants/battle.h | 4 ++- include/constants/battle_script_commands.h | 1 + include/constants/battle_string_ids.h | 10 +++++- src/battle_dynamax.c | 24 +++++++++++++- src/battle_message.c | 26 +++++++++++++++ src/battle_script_commands.c | 38 +++++++++++++++++++++- src/battle_util.c | 29 +++++++++++++++++ src/data/battle_moves.h | 2 +- 13 files changed, 173 insertions(+), 8 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 656283851e..bbb544de27 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -2233,6 +2233,10 @@ .4byte \failInstr .endm + .macro damagenontypes + various 0, VARIOUS_DAMAGE_NON_TYPES + .endm + @ Tries to increase or decrease a battler's stat's stat stage by a specified amount. If impossible, jumps to \script. .macro modifybattlerstatstage battler:req, stat:req, mode:req, amount:req, script:req, animation:req, customString diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 9efe349025..90ae715fd9 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -10404,6 +10404,38 @@ BattleScript_TargetAbilityStatRaiseRet:: BattleScript_TargetAbilityStatRaiseRet_End: return +BattleScript_DamageNonTypesStarts:: + printfromtable gDamageNonTypesStartStringIds + waitmessage B_WAIT_TIME_LONG + return + +BattleScript_DamageNonTypesContinues:: + @printfromtable gDamageNonTypesStartStringIds + @waitmessage B_WAIT_TIME_LONG + setbyte gBattleCommunication, 0 +BattleScript_DamageNonTypesLoop:: + copyarraywithindex gBattlerAttacker, gBattlerByTurnOrder, gBattleCommunication, 1 + damagenontypes + jumpifword CMP_EQUAL, gBattleMoveDamage, 0, BattleScript_DamageNonTypesLoopIncrement + printfromtable gDamageNonTypesDmgStringIds + waitmessage B_WAIT_TIME_LONG + effectivenesssound + hitanimation BS_ATTACKER + goto BattleScript_DamageNonTypesHpChange +BattleScript_DamageNonTypesHpChange: + orword gHitMarker, HITMARKER_SKIP_DMG_TRACK | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE | HITMARKER_GRUDGE + healthbarupdate BS_ATTACKER + datahpupdate BS_ATTACKER + tryfaintmon BS_ATTACKER + checkteamslost BattleScript_DamageNonTypesLoopIncrement +BattleScript_DamageNonTypesLoopIncrement:: + jumpifbyte CMP_NOT_EQUAL, gBattleOutcome, 0, BattleScript_DamageNonTypesContinuesEnd + addbyte gBattleCommunication, 1 + jumpifbytenotequal gBattleCommunication, gBattlersCount, BattleScript_DamageNonTypesLoop +BattleScript_DamageNonTypesContinuesEnd:: + bicword gHitMarker, HITMARKER_SKIP_DMG_TRACK | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE | HITMARKER_GRUDGE + end2 + BattleScript_PokemonCantUseTheMove:: attackstring ppreduce diff --git a/include/battle.h b/include/battle.h index 483d3cdb50..df467936c6 100644 --- a/include/battle.h +++ b/include/battle.h @@ -224,6 +224,8 @@ struct SideTimer u8 followmeTarget:3; u8 followmePowder:1; // Rage powder, does not affect grass type pokemon. u8 retaliateTimer; + u8 damageNonTypesTimer; + u8 damageNonTypesType; }; struct FieldTimer diff --git a/include/battle_dynamax.h b/include/battle_dynamax.h index b754c356a9..f5b61d082c 100644 --- a/include/battle_dynamax.h +++ b/include/battle_dynamax.h @@ -40,7 +40,7 @@ enum MaxMoveEffect MAX_EFFECT_HEAL_TEAM, MAX_EFFECT_SPITE, MAX_EFFECT_GRAVITY, - MAX_EFFECT_VOLCAITH_FOES, + MAX_EFFECT_VOLCALITH, MAX_EFFECT_SANDBLAST_FOES, MAX_EFFECT_YAWN_FOE, MAX_EFFECT_LOWER_EVASIVENESS_FOES, @@ -56,5 +56,6 @@ bool8 ShouldUseMaxMove(u16 battlerId, u16 baseMove); u16 GetMaxMove(u16 battlerId, u16 baseMove); bool8 IsMaxMove(u16 move); const u8 *GetMaxMoveName(u16 move); +void ChooseDamageNonTypesString(u8 move); #endif diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 1c10989261..308a05e70f 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -454,8 +454,6 @@ extern const u8 BattleScript_HealingWishActivates[]; extern const u8 BattleScript_LunarDanceActivates[]; extern const u8 BattleScript_ShellTrapSetUp[]; extern const u8 BattleScript_StealthRockActivates[]; -extern const u8 BattleScript_SteelsurgeActivates[]; -extern const u8 BattleScript_SteelsurgeFree[]; // zmoves extern const u8 BattleScript_ZMoveActivateDamaging[]; @@ -471,5 +469,9 @@ extern const u8 BattleScript_EffectRaiseSideStats[]; extern const u8 BattleScript_EffectLowerSideStats[]; extern const u8 BattleScript_EffectSetWeather[]; extern const u8 BattleScript_EffectSetTerrain[]; +extern const u8 BattleScript_SteelsurgeActivates[]; +extern const u8 BattleScript_SteelsurgeFree[]; +extern const u8 BattleScript_DamageNonTypesStarts[]; +extern const u8 BattleScript_DamageNonTypesContinues[]; #endif // GUARD_BATTLE_SCRIPTS_H \ No newline at end of file diff --git a/include/constants/battle.h b/include/constants/battle.h index b9909fbfc6..6741ebe47b 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -235,6 +235,7 @@ #define SIDE_STATUS_MAT_BLOCK (1 << 21) #define SIDE_STATUS_STEELSURGE (1 << 22) #define SIDE_STATUS_STEELSURGE_DAMAGED (1 << 23) +#define SIDE_STATUS_DAMAGE_NON_TYPES (1 << 24) #define SIDE_STATUS_HAZARDS_ANY (SIDE_STATUS_SPIKES | SIDE_STATUS_STICKY_WEB | SIDE_STATUS_TOXIC_SPIKES | SIDE_STATUS_STEALTH_ROCK | SIDE_STATUS_STEELSURGE) #define SIDE_STATUS_SCREEN_ANY (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL) @@ -379,8 +380,9 @@ #define MOVE_EFFECT_TERRAIN 76 #define MOVE_EFFECT_STEALTH_ROCK 77 #define MOVE_EFFECT_STEELSURGE 78 +#define MOVE_EFFECT_DAMAGE_NON_TYPES 79 -#define NUM_MOVE_EFFECTS 79 +#define NUM_MOVE_EFFECTS 80 #define MOVE_EFFECT_AFFECTS_USER 0x4000 #define MOVE_EFFECT_CERTAIN 0x8000 diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 258e74b154..0eb219eaad 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -264,6 +264,7 @@ #define VARIOUS_JUMP_IF_TARGET_NOT_ALLY 172 #define VARIOUS_JUMP_IF_TARGET_ABSENT 173 #define VARIOUS_SET_STEELSURGE 174 +#define VARIOUS_DAMAGE_NON_TYPES 175 // Cmd_manipulatedamage #define DMG_CHANGE_SIGN 0 diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 9a0a6e4d1c..17b9d00eab 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -644,8 +644,16 @@ #define STRINGID_SHARPSTEELFLOATS 642 #define STRINGID_SHARPSTEELDMG 643 #define STRINGID_PKMNBLEWAWAYSHARPSTEEL 644 +#define STRINGID_TEAMTRAPPEDWITHVINES 645 +#define STRINGID_PKMNHURTBYVINES 646 +#define STRINGID_TEAMCAUGHTINVORTEX 647 +#define STRINGID_PKMNHURTBYVORTEX 648 +#define STRINGID_TEAMSURROUNDEDBYFIRE 649 +#define STRINGID_PKMNBURNINGUP 650 +#define STRINGID_TEAMSURROUNDEDBYROCKS 651 +#define STRINGID_PKMNHURTBYROCKSTHROWN 652 -#define BATTLESTRINGS_COUNT 645 +#define BATTLESTRINGS_COUNT 653 // This is the string id that gBattleStringsTable starts with. // String ids before this (e.g. STRINGID_INTROMSG) are not in the table, diff --git a/src/battle_dynamax.c b/src/battle_dynamax.c index 06d2611a90..bcca8dabe4 100644 --- a/src/battle_dynamax.c +++ b/src/battle_dynamax.c @@ -71,7 +71,7 @@ static const struct GMaxMove sGMaxMoveTable[] = {SPECIES_URSHIFU_RAPID_STRIKE_STYLE_GMAX, TYPE_WATER, MOVE_G_MAX_RAPID_FLOW}, }; -// Functions: +// Returns whether a move should be converted into a Max Move. bool8 ShouldUseMaxMove(u16 battlerId, u16 baseMove) { // TODO: Raids @@ -82,6 +82,7 @@ bool8 ShouldUseMaxMove(u16 battlerId, u16 baseMove) return FALSE; } +// Returns the appropriate Max Move or G-Max Move for a battler to use. u16 GetMaxMove(u16 battlerId, u16 baseMove) { u16 move = baseMove; @@ -103,11 +104,13 @@ u16 GetMaxMove(u16 battlerId, u16 baseMove) return move; } +// Returns whether a move is a Max Move or not. bool8 IsMaxMove(u16 move) { return move >= FIRST_MAX_MOVE && move <= LAST_MAX_MOVE; } +// Returns the full name of a Max Move for the move usage text. const u8 *GetMaxMoveName(u16 move) { if (IsMaxMove(move)) @@ -115,3 +118,22 @@ const u8 *GetMaxMoveName(u16 move) else return gMaxMoveNames[0]; // Failsafe } + +// Assigns the multistring to use for the "Damage Non- Types" G-Max effect. +void ChooseDamageNonTypesString(u8 type) +{ + switch (type) { + case TYPE_GRASS: + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + break; + case TYPE_WATER: + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + break; + case TYPE_FIRE: + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + break; + case TYPE_ROCK: + gBattleCommunication[MULTISTRING_CHOOSER] = 3; + break; + } +} diff --git a/src/battle_message.c b/src/battle_message.c index 1fb075ef70..8ebc73679f 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -779,9 +779,25 @@ static const u8 sText_ShellTrapDidntWork[] = _("{B_ATK_NAME_WITH_PREFIX}'s shell static const u8 sText_SharpSteelFloats[] = _("Sharp-pointed steel floats\naround {B_DEF_TEAM2} team!"); static const u8 sText_SharpSteelDmg[] = _("Sharp steel bit into {B_DEF_NAME_WITH_PREFIX}!"); static const u8 sText_PkmnBlewAwaySharpSteel[] = _("{B_ATK_NAME_WITH_PREFIX} blew away\nsharp steel!"); +static const u8 sText_TeamTrappedWithVines[] = _("{B_DEF_TEAM1} team got trapped\nwith vines!"); +static const u8 sText_PkmnHurtByVines[] = _("{B_ATK_NAME_WITH_PREFIX} is hurt by\nG-Max Vine Lash's ferocious beating!"); +static const u8 sText_TeamCaughtInVortex[] = _("{B_DEF_TEAM1} team got caught\nin a vortex of water!"); +static const u8 sText_PkmnHurtByVortex[] = _("{B_ATK_NAME_WITH_PREFIX} is hurt by\nG-Max Cannonade's vortex!"); +static const u8 sText_TeamSurroundedByFire[] = _("{B_DEF_TEAM1} team was surrounded\nby flames!"); +static const u8 sText_PkmnBurningUp[] = _("{B_ATK_NAME_WITH_PREFIX} is burning up\nwithin G-Max Wildfire's flames!"); +static const u8 sText_TeamSurroundedByRocks[] = _("{B_DEF_TEAM1} team was surrounded\nby rocks!"); +static const u8 sText_PkmnHurtByRocksThrown[] = _("{B_ATK_NAME_WITH_PREFIX} is hurt by\nrocks thrown out by G-Max Volcalith!"); const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = { + [STRINGID_PKMNHURTBYROCKSTHROWN - BATTLESTRINGS_TABLE_START] = sText_PkmnHurtByRocksThrown, + [STRINGID_TEAMSURROUNDEDBYROCKS - BATTLESTRINGS_TABLE_START] = sText_TeamSurroundedByRocks, + [STRINGID_PKMNBURNINGUP - BATTLESTRINGS_TABLE_START] = sText_PkmnBurningUp, + [STRINGID_TEAMSURROUNDEDBYFIRE - BATTLESTRINGS_TABLE_START] = sText_TeamSurroundedByFire, + [STRINGID_PKMNHURTBYVORTEX - BATTLESTRINGS_TABLE_START] = sText_PkmnHurtByVortex, + [STRINGID_TEAMCAUGHTINVORTEX - BATTLESTRINGS_TABLE_START] = sText_TeamCaughtInVortex, + [STRINGID_PKMNHURTBYVINES - BATTLESTRINGS_TABLE_START] = sText_PkmnHurtByVines, + [STRINGID_TEAMTRAPPEDWITHVINES - BATTLESTRINGS_TABLE_START] = sText_TeamTrappedWithVines, [STRINGID_PKMNBLEWAWAYSHARPSTEEL - BATTLESTRINGS_TABLE_START] = sText_PkmnBlewAwaySharpSteel, [STRINGID_SHARPSTEELDMG - BATTLESTRINGS_TABLE_START] = sText_SharpSteelDmg, [STRINGID_SHARPSTEELFLOATS - BATTLESTRINGS_TABLE_START] = sText_SharpSteelFloats, @@ -1877,6 +1893,16 @@ const u16 gStatusConditionsStringIds[] = STRINGID_PKMNWASPOISONED, STRINGID_PKMNBADLYPOISONED, STRINGID_PKMNWASBURNED, STRINGID_PKMNWASPARALYZED, STRINGID_PKMNFELLASLEEP }; +const u16 gDamageNonTypesStartStringIds[] = +{ + STRINGID_TEAMTRAPPEDWITHVINES, STRINGID_TEAMCAUGHTINVORTEX, STRINGID_TEAMSURROUNDEDBYFIRE, STRINGID_TEAMSURROUNDEDBYROCKS +}; + +const u16 gDamageNonTypesDmgStringIds[] = +{ + STRINGID_PKMNHURTBYVINES, STRINGID_PKMNHURTBYVORTEX, STRINGID_PKMNBURNINGUP, STRINGID_PKMNHURTBYROCKSTHROWN +}; + const u8 gText_PkmnIsEvolving[] = _("What?\n{STR_VAR_1} is evolving!"); const u8 gText_CongratsPkmnEvolved[] = _("Congratulations! Your {STR_VAR_1}\nevolved into {STR_VAR_2}!{WAIT_SE}\p"); const u8 gText_PkmnStoppedEvolving[] = _("Huh? {STR_VAR_1}\nstopped evolving!\p"); diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index c8ac3c6719..eeaefdb1e7 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3845,6 +3845,20 @@ void SetMoveEffect(bool32 primary, u32 certain) gBattlescriptCurrInstr = BattleScript_SteelsurgeActivates; } break; + case MOVE_EFFECT_DAMAGE_NON_TYPES: + { + side = GetBattlerSide(gEffectBattler); + if (!(gSideStatuses[side] & SIDE_STATUS_DAMAGE_NON_TYPES)) + { + gSideStatuses[side] |= SIDE_STATUS_DAMAGE_NON_TYPES; + gSideTimers[side].damageNonTypesTimer = 4; + gSideTimers[side].damageNonTypesType = gBattleMoves[gCurrentMove].type; + BattleScriptPush(gBattlescriptCurrInstr + 1); + ChooseDamageNonTypesString(gBattleMoves[gCurrentMove].type); + gBattlescriptCurrInstr = BattleScript_DamageNonTypesStarts; + } + break; + } } } } @@ -11281,11 +11295,17 @@ static void Cmd_various(void) gBattleScripting.moveEffect = MOVE_EFFECT_WEATHER; break; case MAX_EFFECT_MISTY_TERRAIN: - case MAX_EFFECT_GRASSY_TERRAIN: // TODO: Grassy terrain not working? + case MAX_EFFECT_GRASSY_TERRAIN: case MAX_EFFECT_ELECTRIC_TERRAIN: case MAX_EFFECT_PSYCHIC_TERRAIN: gBattleScripting.moveEffect = MOVE_EFFECT_TERRAIN; break; + case MAX_EFFECT_VINE_LASH: + case MAX_EFFECT_CANNONADE: + case MAX_EFFECT_WILDFIRE: + case MAX_EFFECT_VOLCALITH: + gBattleScripting.moveEffect = MOVE_EFFECT_DAMAGE_NON_TYPES; + break; case MAX_EFFECT_STEALTH_ROCK: gBattleScripting.moveEffect = MOVE_EFFECT_STEALTH_ROCK; break; @@ -11329,6 +11349,22 @@ static void Cmd_various(void) } return; } + case VARIOUS_DAMAGE_NON_TYPES: + { + VARIOUS_ARGS(); + side = GetBattlerSide(gBattlerAttacker); + gBattleMoveDamage = 0; + if (gSideTimers[side].damageNonTypesTimer + && !IS_BATTLER_OF_TYPE(gBattlerAttacker, gSideTimers[side].damageNonTypesType) + && IsBattlerAlive(gBattlerAttacker) + && GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD) + { + gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 6; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + } + break; + } } // End of switch (cmd->id) gBattlescriptCurrInstr = cmd->nextInstr; diff --git a/src/battle_util.c b/src/battle_util.c index 59bd25afde..907891724b 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2117,6 +2117,7 @@ enum ENDTURN_SANDSTORM, ENDTURN_SUN, ENDTURN_HAIL, + ENDTURN_DAMAGE_NON_TYPES, ENDTURN_GRAVITY, ENDTURN_WATER_SPORT, ENDTURN_MUD_SPORT, @@ -2458,6 +2459,34 @@ u8 DoFieldEndTurnEffects(void) } gBattleStruct->turnCountersTracker++; break; + case ENDTURN_DAMAGE_NON_TYPES: + while (gBattleStruct->turnSideTracker < 2) + { + side = gBattleStruct->turnSideTracker; + if (gSideStatuses[side] & SIDE_STATUS_DAMAGE_NON_TYPES) + { + if (--gSideTimers[side].damageNonTypesTimer == 0) + { + gSideStatuses[side] &= ~SIDE_STATUS_DAMAGE_NON_TYPES; + //gBattlescriptCurrInstr = BattleScript_DamageNonTypesEnds; TODO: no end message in-game? + effect++; + } + else + { + ChooseDamageNonTypesString(gSideTimers[side].damageNonTypesType); + BattleScriptExecute(BattleScript_DamageNonTypesContinues); + } + } + gBattleStruct->turnSideTracker++; + if (effect != 0) + break; + } + if (!effect) + { + gBattleStruct->turnCountersTracker++; + gBattleStruct->turnSideTracker = 0; + } + break; case ENDTURN_TRICK_ROOM: if (gFieldStatuses & STATUS_FIELD_TRICK_ROOM && --gFieldTimers.trickRoomTimer == 0) { diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index 966f164b23..88347ae913 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -15613,7 +15613,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = .priority = 0, .flags = 0, .split = SPLIT_PHYSICAL, - .argument = MAX_EFFECT_VOLCAITH_FOES, + .argument = MAX_EFFECT_VOLCALITH, }, [MOVE_G_MAX_TARTNESS] =