diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 09913a9e6f..39bb3a42ed 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -12326,8 +12326,6 @@ gBattleAnimMove_NaturesMadness:: loadspritegfx ANIM_TAG_SPARKLE_2 @stars PinkStarsTemplate loadspritegfx ANIM_TAG_PINK_PETAL @pink PinkRingTemplate, PinkStarsTemplate loadspritegfx ANIM_TAG_ICE_CHUNK @blue green CrystalsTemplate - loadspritegfx ANIM_TAG_CIRCLE_OF_LIGHT @charge - loadspritegfx ANIM_TAG_TEAL_ALERT @charge particles monbg ANIM_ATTACKER setalpha 14, 8 delay 0x1 @@ -12374,6 +12372,8 @@ gBattleAnimMove_NaturesMadness:: createsprite gNaturesMadnessGrayRingTemplate, ANIM_ATTACKER, 40, 0x0, 0x0, 0x1, 0x0 playsewithpan SE_M_HEAL_BELL, SOUND_PAN_ATTACKER waitforvisualfinish + unloadspritegfx ANIM_TAG_ECLIPSING_ORB + loadspritegfx ANIM_TAG_SPARKLE_2 playsewithpan SE_M_EXPLOSION, SOUND_PAN_ATTACKER createsprite gNaturesMadnessPinkRingTemplate, ANIM_ATTACKER, 3, 0x0, 0x0, 0x1, 0x0, 0x1F, 0x8 createsprite gNaturesMadnessPinkStarsTemplate, ANIM_ATTACKER, 2, 0xa, 0xa, 0x19, 0x1 @@ -16168,7 +16168,6 @@ SandsearStormFireSpin: gBattleAnimMove_LunarBlessing:: loadspritegfx ANIM_TAG_BLUE_STAR loadspritegfx ANIM_TAG_MOON - loadspritegfx ANIM_TAG_SPARKLE_2 loadspritegfx ANIM_TAG_GUARD_RING loadspritegfx ANIM_TAG_SMALL_EMBER @Yellow colour for ring monbg ANIM_ATK_PARTNER @@ -31487,13 +31486,15 @@ gBattleAnimMove_BlackHoleEclipse:: delay 0x8 createsprite gBlackHoleEclipseHoleShrinkSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0x0, ANIM_TARGET, 0x0 waitforvisualfinish + unloadspritegfx ANIM_TAG_THIN_RING + unloadspritegfx ANIM_TAG_ICE_CHUNK loadspritegfx ANIM_TAG_SPARKLE_4 @detect createsprite gTargetTwinkleSpriteTemplate, ANIM_ATTACKER, 13, 0x0, 0x0, ANIM_TARGET @detect star delay 0x2 + unloadspritegfx ANIM_TAG_VERTICAL_HEX @red unloadspritegfx ANIM_TAG_SHADOW_BALL - unloadspritegfx ANIM_TAG_THIN_RING - unloadspritegfx ANIM_TAG_ICE_CHUNK unloadspritegfx ANIM_TAG_BLACK_BALL_2 + unloadspritegfx ANIM_TAG_FOCUS_ENERGY loadspritegfx ANIM_TAG_EXPLOSION_2 call BlackHoleEclipseExplosion createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x1, 0x0, 0x10, 0x7fff @ bg to white pal diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index e8224b25fa..4f17840393 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -6010,7 +6010,6 @@ BattleScript_RoarSuccessSwitch_Ret: swapattackerwithtarget @ continuation of RedCardActivates restoretarget restoreattacker - restoresavedmove setbyte sSWITCH_CASE, B_SWITCH_NORMAL return @@ -9492,7 +9491,6 @@ BattleScript_RedCardActivationNoSwitch:: removeitem BS_SCRIPTING restoretarget restoreattacker - restoresavedmove return BattleScript_RedCardActivates:: @@ -9515,6 +9513,7 @@ BattleScript_RedCardIngrainContinue: waitmessage B_WAIT_TIME_LONG removeitem BS_SCRIPTING restoretarget + restoreattacker return BattleScript_RedCardSuctionCups: printstring STRINGID_PKMNANCHORSITSELFWITH diff --git a/include/battle.h b/include/battle.h index 3e4907050b..823e4813e9 100644 --- a/include/battle.h +++ b/include/battle.h @@ -834,7 +834,6 @@ struct BattleStruct u8 usedMicleBerry; struct MessageStatus slideMessageStatus; u8 trainerSlideSpriteIds[MAX_BATTLERS_COUNT]; - u16 savedMove; // backup current move for mid-turn switching, e.g. Red Card u16 opponentMonCanTera:6; u16 opponentMonCanDynamax:6; u16 padding:4; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index ee367133dd..4837fb970e 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3698,8 +3698,8 @@ void SetMoveEffect(bool32 primary, bool32 certain) flags = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN; else flags = 0; - if (mirrorArmorReflected) - flags |= (STAT_CHANGE_ALLOW_PTR * !affectsUser); + if (mirrorArmorReflected && !affectsUser) + flags |= STAT_CHANGE_ALLOW_PTR; else flags |= STAT_CHANGE_UPDATE_MOVE_EFFECT; @@ -3753,9 +3753,12 @@ void SetMoveEffect(bool32 primary, bool32 certain) flags = 0; if (mirrorArmorReflected && !affectsUser) flags |= STAT_CHANGE_ALLOW_PTR; + else + flags |= STAT_CHANGE_UPDATE_MOVE_EFFECT; + if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(2) | STAT_BUFF_NEGATIVE, gBattleScripting.moveEffect - MOVE_EFFECT_ATK_MINUS_2 + 1, - flags | STAT_CHANGE_UPDATE_MOVE_EFFECT, gBattlescriptCurrInstr + 1) == STAT_CHANGE_DIDNT_WORK) + flags, gBattlescriptCurrInstr + 1) == STAT_CHANGE_DIDNT_WORK) { if (!mirrorArmorReflected) gBattlescriptCurrInstr++; @@ -7196,7 +7199,6 @@ static void Cmd_moveend(void) gLastUsedItem = gBattleMons[battler].item; SaveBattlerTarget(battler); // save battler with red card SaveBattlerAttacker(gBattlerAttacker); - gBattleStruct->savedMove = gCurrentMove; gBattleScripting.battler = battler; gEffectBattler = gBattlerAttacker; if (moveEffect == EFFECT_HIT_ESCAPE) @@ -7411,7 +7413,11 @@ static void Cmd_moveend(void) gBattleScripting.moveendState++; break; case MOVEEND_DANCER: // Special case because it's so annoying - if (IsDanceMove(gCurrentMove) && !gBattleStruct->snatchedMoveIsUsed) + if (gCurrentMove == MOVE_NONE) + originallyUsedMove = gChosenMove; // Fallback to chosen move in case attacker is switched out in the middle of an attack resolution (eg red card) + else + originallyUsedMove = gCurrentMove; + if (IsDanceMove(originallyUsedMove) && !gBattleStruct->snatchedMoveIsUsed) { u32 battler, nextDancer = 0; bool32 hasDancerTriggered = FALSE; @@ -7445,7 +7451,7 @@ static void Cmd_moveend(void) nextDancer = battler | 0x4; } } - if (nextDancer && AbilityBattleEffects(ABILITYEFFECT_MOVE_END_OTHER, nextDancer & 0x3, 0, 0, 0)) + if (nextDancer && AbilityBattleEffects(ABILITYEFFECT_MOVE_END_OTHER, nextDancer & 0x3, 0, 0, originallyUsedMove)) effect = TRUE; } } @@ -17993,6 +17999,7 @@ void BS_TryActivateGulpMissile(void) if (!(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT) && !gProtectStructs[gBattlerAttacker].confusionSelfDmg + && IsBattlerAlive(gBattlerAttacker) && IsBattlerTurnDamaged(gBattlerTarget) && gBattleMons[gBattlerTarget].species != SPECIES_CRAMORANT && GetBattlerAbility(gBattlerTarget) == ABILITY_GULP_MISSILE) @@ -18775,15 +18782,3 @@ void BS_SetSteelsurge(void) gBattlescriptCurrInstr = cmd->nextInstr; } } - -void BS_RestoreSavedMove(void) -{ - NATIVE_ARGS(); - - if (gBattleStruct->savedMove == MOVE_NONE) - DebugPrintfLevel(MGBA_LOG_WARN, "restoresavedmove was called with no move saved!"); - - gCurrentMove = gBattleStruct->savedMove; - gBattleStruct->savedMove = MOVE_NONE; - gBattlescriptCurrInstr = cmd->nextInstr; -} diff --git a/src/battle_util.c b/src/battle_util.c index 1597674c17..0a95f4e59c 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2351,7 +2351,7 @@ u8 DoBattlerEndTurnEffects(void) gBattleScripting.animArg1 = gBattlerTarget; gBattleScripting.animArg2 = gBattlerAttacker; gBattleStruct->moveDamage[gBattlerAttacker] = max(1, GetNonDynamaxMaxHP(battler) / 8); - gBattleStruct->moveDamage[gBattlerTarget] = GetDrainedBigRootHp(gBattlerAttacker, gBattleStruct->moveDamage[gBattlerAttacker]); + gBattleStruct->moveDamage[gBattlerTarget] = GetDrainedBigRootHp(gBattlerTarget, gBattleStruct->moveDamage[gBattlerAttacker]); gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE; if (GetBattlerAbility(battler) == ABILITY_LIQUID_OOZE) { @@ -6091,7 +6091,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 if (!(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT) && !gProtectStructs[gBattlerAttacker].confusionSelfDmg && IsBattlerTurnDamaged(gBattlerTarget) - && IsBattlerAlive(battler) + && IsBattlerAlive(gBattlerAttacker) && gBattleMons[gBattlerTarget].species != SPECIES_CRAMORANT) { if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD) @@ -6271,7 +6271,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 { case ABILITY_DANCER: if (IsBattlerAlive(battler) - && IsDanceMove(gCurrentMove) + && IsDanceMove(move) && !gSpecialStatuses[battler].dancerUsedMove && gBattlerAttacker != battler) { @@ -6279,7 +6279,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 gSpecialStatuses[battler].dancerUsedMove = TRUE; gSpecialStatuses[battler].dancerOriginalTarget = gBattleStruct->moveTarget[battler] | 0x4; gBattlerAttacker = gBattlerAbility = battler; - gCalledMove = gCurrentMove; + gCalledMove = move; // Set the target to the original target of the mon that first used a Dance move gBattlerTarget = gBattleScripting.savedBattler & 0x3; diff --git a/src/daycare.c b/src/daycare.c index 8d2bf13545..bedaf35dd2 100644 --- a/src/daycare.c +++ b/src/daycare.c @@ -336,6 +336,11 @@ static void ApplyDaycareExperience(struct Pokemon *mon) CalculateMonStats(mon); } +static u32 GetExpAtLevelCap(struct Pokemon *mon) +{ + return gExperienceTables[gSpeciesInfo[GetMonData(mon, MON_DATA_SPECIES)].growthRate][GetCurrentLevelCap()]; +} + static u16 TakeSelectedPokemonFromDaycare(struct DaycareMon *daycareMon) { u32 species; @@ -358,6 +363,9 @@ static u16 TakeSelectedPokemonFromDaycare(struct DaycareMon *daycareMon) if (GetMonData(&pokemon, MON_DATA_LEVEL) < GetCurrentLevelCap()) { experience = GetMonData(&pokemon, MON_DATA_EXP) + daycareMon->steps; + u32 maxExp = GetExpAtLevelCap(&pokemon); + if (experience > maxExp) + experience = maxExp; SetMonData(&pokemon, MON_DATA_EXP, &experience); ApplyDaycareExperience(&pokemon); } diff --git a/test/battle/ability/color_change.c b/test/battle/ability/color_change.c index 668cb01b62..cc0a3e2472 100644 --- a/test/battle/ability/color_change.c +++ b/test/battle/ability/color_change.c @@ -47,7 +47,7 @@ SINGLE_BATTLE_TEST("Color Change does not change the type of a dual-type Pokemon ANIMATION(ANIM_TYPE_MOVE, MOVE_PSYCHO_CUT, player); NONE_OF { ABILITY_POPUP(opponent, ABILITY_COLOR_CHANGE); - MESSAGE("The opposing Xatu's Color Change made it the Psychic type!"); + MESSAGE("The opposing Slowbro's Color Change made it the Psychic type!"); } } } diff --git a/test/battle/ability/gulp_missile.c b/test/battle/ability/gulp_missile.c index 72e826b252..76d66c4fb8 100644 --- a/test/battle/ability/gulp_missile.c +++ b/test/battle/ability/gulp_missile.c @@ -190,3 +190,13 @@ SINGLE_BATTLE_TEST("(Gulp Missile) Transformed Cramorant Gulping lowers defense HP_BAR(opponent); } } + +SINGLE_BATTLE_TEST("Gulp Missile triggered by explosion doesn't freeze the game") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_CRAMORANT); + } WHEN { + TURN { MOVE(opponent, MOVE_SURF); MOVE(player, MOVE_EXPLOSION); } + } +} diff --git a/test/battle/ability/mirror_armor.c b/test/battle/ability/mirror_armor.c index 5aa2b55ef3..0918682d76 100644 --- a/test/battle/ability/mirror_armor.c +++ b/test/battle/ability/mirror_armor.c @@ -211,3 +211,18 @@ SINGLE_BATTLE_TEST("Mirror Armor reflects Tangling Hair speed drop") ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); } } + +SINGLE_BATTLE_TEST("Mirror Armor reflects Obstruct defense drop") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_CORVIKNIGHT) { Ability(ABILITY_MIRROR_ARMOR); } + } WHEN { + TURN { MOVE(player, MOVE_OBSTRUCT); MOVE(opponent, MOVE_TACKLE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_OBSTRUCT, player); + NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + ABILITY_POPUP(opponent, ABILITY_MIRROR_ARMOR); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + } +} diff --git a/test/battle/hold_effect/big_root.c b/test/battle/hold_effect/big_root.c index 0b3d9b4af6..41dd09adc0 100644 --- a/test/battle/hold_effect/big_root.c +++ b/test/battle/hold_effect/big_root.c @@ -30,8 +30,6 @@ SINGLE_BATTLE_TEST("Big Root increases healing from absorbing moves", s16 damage SINGLE_BATTLE_TEST("Big Root increases the damage restored from Leech Seed, Ingrain and Aqua Ring", s16 heal, s16 damage) { - KNOWN_FAILING; - u32 item; u32 move; @@ -53,9 +51,9 @@ SINGLE_BATTLE_TEST("Big Root increases the damage restored from Leech Seed, Ingr HP_BAR(player, captureDamage: &results[i].heal); } FINALLY { EXPECT_EQ(results[0].damage, results[1].damage); // Damage is unaffected - EXPECT_MUL_EQ(results[1].heal, Q_4_12(5234 / 4096), results[0].heal); - EXPECT_MUL_EQ(results[3].heal, Q_4_12(5234 / 4096), results[2].heal); - EXPECT_MUL_EQ(results[5].heal, Q_4_12(5234 / 4096), results[4].heal); + EXPECT_MUL_EQ(results[0].heal, Q_4_12(1.3), results[1].heal); + EXPECT_MUL_EQ(results[2].heal, Q_4_12(1.3), results[3].heal); + EXPECT_MUL_EQ(results[4].heal, Q_4_12(1.3), results[5].heal); } }