diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 6e37f6f2f1..3fe0aa950f 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -3059,6 +3059,7 @@ BattleScript_EffectGravity: setgravity BattleScript_ButItFailed attackanimation waitanimation +BattleScript_EffectGravitySuccess:: printstring STRINGID_GRAVITYINTENSIFIED waitmessage B_WAIT_TIME_LONG selectfirstvalidtarget @@ -4208,6 +4209,7 @@ BattleScript_EffectReflect:: BattleScript_PrintReflectLightScreenSafeguardString:: attackanimation waitanimation +BattleScript_EffectAuroraVeilSuccess:: printfromtable gReflectLightScreenSafeguardStringIds waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd @@ -5988,6 +5990,7 @@ BattleScript_EffectYawn:: setyawn BattleScript_ButItFailed attackanimation waitanimation + BattleScript_EffectYawnSuccess:: printstring STRINGID_PKMNWASMADEDROWSY waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd @@ -10451,8 +10454,9 @@ BattleScript_DamageNonTypesContinuesEnd:: bicword gHitMarker, HITMARKER_SKIP_DMG_TRACK | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE | HITMARKER_GRUDGE end2 -BattleScript_EffectSetAuroraVeil:: - printstring STRINGID_PKMNCOVEREDBYVEIL +BattleScript_EffectTryReducePP:: + tryspiteppreduce BattleScript_MoveEnd + printstring STRINGID_PKMNREDUCEDPP waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd diff --git a/include/battle.h b/include/battle.h index df467936c6..9a9da26274 100644 --- a/include/battle.h +++ b/include/battle.h @@ -527,6 +527,7 @@ struct DynamaxData u8 usingMaxMove[MAX_BATTLERS_COUNT]; u8 activeSplit; u8 splits[MAX_BATTLERS_COUNT]; + u8 moveSlot[MAX_BATTLERS_COUNT]; // move slot of Max Move, used for Spite, TODO: Copycat, Encore, Grudge }; struct StolenItem diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 46cc0f4e8a..555f2618c3 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -474,6 +474,9 @@ extern const u8 BattleScript_SteelsurgeFree[]; extern const u8 BattleScript_DamageNonTypesStarts[]; extern const u8 BattleScript_DamageNonTypesContinues[]; extern const u8 BattleScript_DefogTryHazards[]; -extern const u8 BattleScript_EffectSetAuroraVeil[]; +extern const u8 BattleScript_EffectAuroraVeilSuccess[]; +extern const u8 BattleScript_EffectGravitySuccess[]; +extern const u8 BattleScript_EffectYawnSuccess[]; +extern const u8 BattleScript_EffectTryReducePP[]; #endif // GUARD_BATTLE_SCRIPTS_H \ No newline at end of file diff --git a/src/battle_dynamax.c b/src/battle_dynamax.c index 0538ba978b..baf5605c57 100644 --- a/src/battle_dynamax.c +++ b/src/battle_dynamax.c @@ -1,10 +1,15 @@ #include "global.h" #include "battle.h" #include "battle_anim.h" +#include "battle_controllers.h" #include "battle_scripts.h" #include "battle_script_commands.h" #include "data.h" #include "pokemon.h" +#include "random.h" +#include "string_util.h" +#include "util.h" +#include "constants/abilities.h" #include "constants/battle_move_effects.h" #include "constants/battle_string_ids.h" #include "constants/hold_effects.h" @@ -23,9 +28,9 @@ static const u16 sMaxMoveTable[] = [TYPE_GHOST] = MOVE_MAX_PHANTASM, [TYPE_STEEL] = MOVE_MAX_STEELSPIKE, [TYPE_FIRE] = MOVE_MAX_FLARE, - [TYPE_WATER] = MOVE_G_MAX_HYDROSNIPE, + [TYPE_WATER] = MOVE_MAX_GEYSER, [TYPE_GRASS] = MOVE_MAX_OVERGROWTH, - [TYPE_ELECTRIC] = MOVE_MAX_LIGHTNING, + [TYPE_ELECTRIC] = MOVE_G_MAX_DEPLETION, [TYPE_PSYCHIC] = MOVE_MAX_MINDSTORM, [TYPE_ICE] = MOVE_MAX_HAILSTORM, [TYPE_DRAGON] = MOVE_MAX_WYRMWIND, @@ -371,8 +376,76 @@ u16 SetMaxMoveEffect(u16 move) else gSideTimers[GetBattlerSide(gBattlerAttacker)].auroraVeilTimer = 5; gSideTimers[GetBattlerSide(gBattlerAttacker)].auroraVeilBattlerId = gBattlerAttacker; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_SAFEGUARD; BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_EffectSetAuroraVeil; + gBattlescriptCurrInstr = BattleScript_EffectAuroraVeilSuccess; + effect++; + } + break; + case MAX_EFFECT_GRAVITY: + if (!(gFieldStatuses & STATUS_FIELD_GRAVITY)) + { + gFieldStatuses |= STATUS_FIELD_GRAVITY; + gFieldTimers.gravityTimer = 5; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_EffectGravitySuccess; + effect++; + } + break; + case MAX_EFFECT_SANDBLAST_FOES: + case MAX_EFFECT_FIRE_SPIN_FOES: + { + // Affects both opponents, but doesn't print strings so we can handle it here. + u8 battler; + for (battler = 0; battler < MAX_BATTLERS_COUNT; ++battler) + { + if (GetBattlerSide(battler) != GetBattlerSide(gBattlerTarget)) + continue; + if (!(gBattleMons[battler].status2 & STATUS2_WRAPPED)) + { + gBattleMons[battler].status2 |= STATUS2_WRAPPED; + if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_GRIP_CLAW) + #if B_BINDING_TURNS >= GEN_5 + gDisableStructs[battler].wrapTurns = 7; + else + gDisableStructs[battler].wrapTurns = (Random() % 2) + 4; + #else + gDisableStructs[battler].wrapTurns = 5; + else + gDisableStructs[battler].wrapTurns = (Random() % 4) + 2; + #endif + gBattleStruct->wrappedBy[battler] = gBattlerAttacker; + if (maxEffect == MAX_EFFECT_SANDBLAST_FOES) + gBattleStruct->wrappedMove[battler] = MOVE_SAND_TOMB; + else + gBattleStruct->wrappedMove[battler] = MOVE_FIRE_SPIN; + } + } + break; + } + case MAX_EFFECT_YAWN_FOE: + if (!(gStatuses3[gBattlerTarget] & STATUS3_YAWN) + && !(gBattleMons[gBattlerTarget].status1 & STATUS1_ANY) + && gBattleMons[gBattlerTarget].ability != ABILITY_VITAL_SPIRIT + && gBattleMons[gBattlerTarget].ability != ABILITY_INSOMNIA + && gBattleMons[gBattlerTarget].ability != ABILITY_COMATOSE + && gBattleMons[gBattlerTarget].ability != ABILITY_PURIFYING_SALT + && !IsFlowerVeilProtected(gBattlerTarget) + && !(gBattleMons[gBattlerTarget].status2 & STATUS2_SUBSTITUTE) + && !UproarWakeUpCheck(gActiveBattler)) + { + gStatuses3[gBattlerTarget] |= STATUS3_YAWN_TURN(2); + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_EffectYawnSuccess; + effect++; + } + break; + case MAX_EFFECT_SPITE: + if (gLastMoves[gBattlerTarget] != MOVE_NONE + && gLastMoves[gBattlerTarget] != MOVE_UNAVAILABLE) + { + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_EffectTryReducePP; effect++; } break; diff --git a/src/battle_main.c b/src/battle_main.c index caa00e045c..d6b5b2459c 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -4270,7 +4270,10 @@ static void HandleTurnActionSelectionState(void) if (gBattleResources->bufferB[gActiveBattler][2] & RET_MEGA_EVOLUTION) gBattleStruct->mega.toEvolve |= gBitTable[gActiveBattler]; if (ShouldUseMaxMove(gActiveBattler, gChosenMoveByBattler[gActiveBattler])) // max move check + { + gBattleStruct->dynamax.moveSlot[gActiveBattler] = gBattleStruct->chosenMovePositions[gActiveBattler]; gBattleStruct->dynamax.usingMaxMove[gActiveBattler] = TRUE; + } gBattleCommunication[gActiveBattler]++; } break; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 04a2ca06fd..e5d7a94b26 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -13416,11 +13416,13 @@ static void Cmd_tryspiteppreduce(void) { s32 i; - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gLastMoves[gBattlerTarget] == gBattleMons[gBattlerTarget].moves[i]) - break; - } + // Get move slot to reduce PP. + if (IsMaxMove(gLastMoves[gBattlerTarget])) + i = gBattleStruct->dynamax.moveSlot[gBattlerTarget]; + else + for (i = 0; i < MAX_MON_MOVES; i++) + if (gLastMoves[gBattlerTarget] == gBattleMons[gBattlerTarget].moves[i]) + break; #if B_CAN_SPITE_FAIL <= GEN_3 if (i != MAX_MON_MOVES && gBattleMons[gBattlerTarget].pp[i] > 1) @@ -13433,6 +13435,9 @@ static void Cmd_tryspiteppreduce(void) #else s32 ppToDeduct = 4; #endif + // G-Max Depletion only deducts 2 PP. + if (IsMaxMove(gCurrentMove) && gBattleMoves[gCurrentMove].argument == MAX_EFFECT_SPITE) + ppToDeduct = 2; if (gBattleMons[gBattlerTarget].pp[i] < ppToDeduct) ppToDeduct = gBattleMons[gBattlerTarget].pp[i];