diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 3804e64240..fc73a510f1 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1614,6 +1614,11 @@ .4byte \ptr .endm + .macro undodynamax battler:req + callnative BS_UndoDynamax + .byte \battler + .endm + .macro trytrainerslidezmovemsg callnative BS_TryTrainerSlideZMoveMsg .endm @@ -2382,7 +2387,7 @@ callnative BS_SwapStats .byte \stat .endm - + .macro restoresavedmove callnative BS_RestoreSavedMove .endm diff --git a/asm/macros/movement.inc b/asm/macros/movement.inc index 7fb51ce225..e36f81fa55 100644 --- a/asm/macros/movement.inc +++ b/asm/macros/movement.inc @@ -164,6 +164,10 @@ create_movement_action fly_down, MOVEMENT_ACTION_FLY_DOWN create_movement_action emote_double_exclamation_mark, MOVEMENT_ACTION_EMOTE_DOUBLE_EXCL_MARK create_movement_action emote_x, MOVEMENT_ACTION_EMOTE_X + create_movement_action walk_slow_stairs_down, MOVEMENT_ACTION_WALK_SLOW_STAIRS_DOWN + create_movement_action walk_slow_stairs_up, MOVEMENT_ACTION_WALK_SLOW_STAIRS_UP + create_movement_action walk_slow_stairs_left, MOVEMENT_ACTION_WALK_SLOW_STAIRS_LEFT + create_movement_action walk_slow_stairs_right, MOVEMENT_ACTION_WALK_SLOW_STAIRS_RIGHT create_movement_action exit_pokeball, MOVEMENT_ACTION_EXIT_POKEBALL create_movement_action enter_pokeball, MOVEMENT_ACTION_ENTER_POKEBALL diff --git a/charmap.txt b/charmap.txt index cd0972f84a..a35709d652 100644 --- a/charmap.txt +++ b/charmap.txt @@ -424,6 +424,8 @@ B_TRAINER1_NAME_WITH_CLASS = FD 42 B_TRAINER2_NAME_WITH_CLASS = FD 43 B_PARTNER_NAME_WITH_CLASS = FD 44 B_ATK_TRAINER_NAME_WITH_CLASS = FD 45 +B_SCR_TEAM1 = FD 46 +B_SCR_TEAM2 = FD 47 @ indicates the end of a town/city name (before " TOWN" or " CITY") NAME_END = FC 00 diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index aeb3f610d7..f529253934 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -3433,51 +3433,15 @@ BattleScript_EffectSuperFang:: damagetohalftargethp goto BattleScript_HitFromAtkAnimation -BattleScript_EffectRecoilIfMiss:: - attackcanceler - accuracycheck BattleScript_MoveMissedDoDamage, ACC_CURR_MOVE -.if B_CRASH_IF_TARGET_IMMUNE >= GEN_4 - typecalc - jumpifmoveresultflags MOVE_RESULT_DOESNT_AFFECT_FOE, BattleScript_MoveMissedDoDamage -.endif - goto BattleScript_HitFromAtkString -BattleScript_MoveMissedDoDamage:: - jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_PrintMoveMissed - attackstring - ppreduce - pause B_WAIT_TIME_LONG - resultmessage - waitmessage B_WAIT_TIME_LONG -.if B_CRASH_IF_TARGET_IMMUNE < GEN_4 - jumpifmoveresultflags MOVE_RESULT_DOESNT_AFFECT_FOE, BattleScript_MoveEnd -.endif - moveendcase MOVEEND_PROTECT_LIKE_EFFECT @ Spiky Shield's damage happens before recoil. - jumpifhasnohp BS_ATTACKER, BattleScript_MoveEnd +BattleScript_RecoilIfMiss:: printstring STRINGID_PKMNCRASHED waitmessage B_WAIT_TIME_LONG - damagecalc - typecalc - adjustdamage -.if B_CRASH_IF_TARGET_IMMUNE == GEN_4 - manipulatedamage DMG_RECOIL_FROM_IMMUNE -.else - manipulatedamage DMG_RECOIL_FROM_MISS -.endif -.if B_CRASH_IF_TARGET_IMMUNE >= GEN_4 - clearmoveresultflags MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE -.else - clearmoveresultflags MOVE_RESULT_MISSED -.endif - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_DISGUISE + jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_RecoilEnd + orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE | HITMARKER_IGNORE_DISGUISE healthbarupdate BS_ATTACKER datahpupdate BS_ATTACKER tryfaintmon BS_ATTACKER -.if B_CRASH_IF_TARGET_IMMUNE >= GEN_4 - setmoveresultflags MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE -.else - setmoveresultflags MOVE_RESULT_MISSED -.endif - goto BattleScript_MoveEnd + return BattleScript_EffectMist:: attackcanceler @@ -5768,7 +5732,7 @@ BattleScript_ActionSwitch:: BattleScript_DoSwitchOut:: switchoutabilities BS_ATTACKER - updatedynamax + undodynamax BS_ATTACKER waitstate returnatktoball waitstate @@ -7727,13 +7691,15 @@ BattleScript_ShedSkinActivates:: end3 BattleScript_ActivateWeatherAbilities: + saveattacker savetarget - setbyte gBattlerTarget, 0 + setbyte gBattlerAttacker, 0 BattleScript_ActivateWeatherAbilities_Loop: - copybyte sBATTLER, gBattlerTarget + copyarraywithindex gBattlerTarget, gBattlerByTurnOrder, gBattlerAttacker, 1 activateweatherchangeabilities BS_TARGET - addbyte gBattlerTarget, 1 - jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_ActivateWeatherAbilities_Loop + addbyte gBattlerAttacker, 1 + jumpifbytenotequal gBattlerAttacker, gBattlersCount, BattleScript_ActivateWeatherAbilities_Loop + restoreattacker restoretarget return @@ -8027,7 +7993,7 @@ BattleScript_AttackWeakenedByStrongWinds:: waitmessage B_WAIT_TIME_LONG return -BattleScript_MimicryActivates_End3:: +BattleScript_MimicryActivates:: pause B_WAIT_TIME_SHORT call BattleScript_AbilityPopUp printstring STRINGID_BATTLERTYPECHANGEDTO @@ -8053,16 +8019,18 @@ BattleScript_SnowWarningActivatesSnow:: end3 BattleScript_ActivateTerrainEffects: + saveattacker savetarget - setbyte gBattlerTarget, 0 + setbyte gBattlerAttacker, 0 BattleScript_ActivateTerrainSeed: - copybyte sBATTLER, gBattlerTarget + copyarraywithindex gBattlerTarget, gBattlerByTurnOrder, gBattlerAttacker, 1 doterrainseed BS_TARGET, BattleScript_ActivateTerrainAbility removeitem BS_TARGET BattleScript_ActivateTerrainAbility: activateterrainchangeabilities BS_TARGET - addbyte gBattlerTarget, 0x1 - jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_ActivateTerrainSeed + addbyte gBattlerAttacker, 1 + jumpifbytenotequal gBattlerAttacker, gBattlersCount, BattleScript_ActivateTerrainSeed + restoreattacker restoretarget return @@ -9563,6 +9531,7 @@ BattleScript_EjectButtonActivates:: printstring STRINGID_EJECTBUTTONACTIVATE waitmessage B_WAIT_TIME_LONG removeitem BS_SCRIPTING + undodynamax BS_SCRIPTING makeinvisible BS_SCRIPTING openpartyscreen BS_SCRIPTING, BattleScript_EjectButtonEnd copybyte sSAVED_BATTLER, sBATTLER @@ -9662,11 +9631,14 @@ BattleScript_NeutralizingGasExits:: pause B_WAIT_TIME_SHORT printstring STRINGID_NEUTRALIZINGGASOVER waitmessage B_WAIT_TIME_LONG - setbyte gBattlerTarget, 0 + setbyte gBattlerAttacker, 0 BattleScript_NeutralizingGasExitsLoop: + copyarraywithindex gBattlerTarget, gBattlerByTurnOrder, gBattlerAttacker, 1 + saveattacker switchinabilities BS_TARGET - addbyte gBattlerTarget, 1 - jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_NeutralizingGasExitsLoop + restoreattacker + addbyte gBattlerAttacker, 1 + jumpifbytenotequal gBattlerAttacker, gBattlersCount, BattleScript_NeutralizingGasExitsLoop restoreattacker restoretarget return @@ -10039,6 +10011,13 @@ BattleScript_DynamaxEnds:: waitanimation end2 +BattleScript_DynamaxEnds_Ret:: + flushtextbox + updatedynamax + playanimation BS_SCRIPTING, B_ANIM_FORM_CHANGE + waitanimation + return + BattleScript_MoveBlockedByDynamax:: accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE attackstring diff --git a/include/battle.h b/include/battle.h index 0086cff959..13acd4b009 100644 --- a/include/battle.h +++ b/include/battle.h @@ -827,7 +827,7 @@ struct BattleStruct u8 printedStrongWindsWeakenedAttack:1; u8 numSpreadTargets:2; u8 bypassMoldBreakerChecks:1; // for ABILITYEFFECT_IMMUNITY - u8 padding3:1; + u8 noTargetPresent:1; u8 usedEjectItem; u8 usedMicleBerry; struct MessageStatus slideMessageStatus; diff --git a/include/battle_message.h b/include/battle_message.h index adc399dd3c..18f80bb3fd 100644 --- a/include/battle_message.h +++ b/include/battle_message.h @@ -83,6 +83,8 @@ #define B_TXT_TRAINER2_NAME_WITH_CLASS 0x43 #define B_TXT_PARTNER_NAME_WITH_CLASS 0x44 #define B_TXT_ATK_TRAINER_NAME_WITH_CLASS 0x45 +#define B_TXT_SCR_TEAM1 0x46 +#define B_TXT_SCR_TEAM2 0x47 #define B_BUFF_STRING 0 #define B_BUFF_NUMBER 1 diff --git a/include/battle_scripts.h b/include/battle_scripts.h index ffa18d0343..4343d7eeea 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -443,8 +443,6 @@ extern const u8 BattleScript_WanderingSpiritActivates[]; extern const u8 BattleScript_MirrorArmorReflect[]; extern const u8 BattleScript_GooeyActivates[]; extern const u8 BattleScript_PastelVeilActivates[]; -extern const u8 BattleScript_MimicryActivatesEnd3[]; -extern const u8 BattleScript_ApplyMimicry[]; extern const u8 BattleScript_AttackerFormChangeEnd3NoPopup[]; extern const u8 BattleScript_AttackerFormChangeWithStringEnd3NoPopup[]; extern const u8 BattleScript_AttackerFormChangeMoveEffect[]; @@ -480,7 +478,7 @@ extern const u8 BattleScript_CommanderActivates[]; extern const u8 BattleScript_HospitalityActivates[]; extern const u8 BattleScript_ToxicDebrisActivates[]; extern const u8 BattleScript_EarthEaterActivates[]; -extern const u8 BattleScript_MimicryActivates_End3[]; +extern const u8 BattleScript_MimicryActivates[]; extern const u8 BattleScript_IceFaceNullsDamage[]; extern const u8 BattleScript_BattlerFormChangeWithStringEnd3[]; extern const u8 BattleScript_DampPreventsAftermath[]; @@ -560,6 +558,7 @@ extern const u8 BattleScript_RemoveGenericType[]; // dynamax and max raids extern const u8 BattleScript_DynamaxBegins[]; extern const u8 BattleScript_DynamaxEnds[]; +extern const u8 BattleScript_DynamaxEnds_Ret[]; extern const u8 BattleScript_MoveBlockedByDynamax[]; // Battle move scripts @@ -597,7 +596,7 @@ extern const u8 BattleScript_EffectOHKO[]; extern const u8 BattleScript_EffectSuperFang[]; extern const u8 BattleScript_EffectFixedDamageArg[]; extern const u8 BattleScript_EffectHealBlock[]; -extern const u8 BattleScript_EffectRecoilIfMiss[]; +extern const u8 BattleScript_RecoilIfMiss[]; extern const u8 BattleScript_EffectMist[]; extern const u8 BattleScript_EffectFocusEnergy[]; extern const u8 BattleScript_EffectConfuse[]; diff --git a/include/battle_util.h b/include/battle_util.h index 37588d246d..25c38b0ee2 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -133,7 +133,6 @@ enum CANCELLER_STANCE_CHANGE_2, CANCELLER_WEATHER_PRIMAL, CANCELLER_DYNAMAX_BLOCKED, - CANCELLER_POWDER_MOVE, CANCELLER_POWDER_STATUS, CANCELLER_PROTEAN, CANCELLER_PSYCHIC_TERRAIN, @@ -308,7 +307,6 @@ bool32 CanTargetBattler(u32 battlerAtk, u32 battlerDef, u16 move); void CopyMonLevelAndBaseStatsToBattleMon(u32 battler, struct Pokemon *mon); void CopyMonAbilityAndTypesToBattleMon(u32 battler, struct Pokemon *mon); void RecalcBattlerStats(u32 battler, struct Pokemon *mon, bool32 isDynamaxing); -bool32 IsAlly(u32 battlerAtk, u32 battlerDef); bool32 IsGen6ExpShareEnabled(void); bool32 MoveHasAdditionalEffect(u32 move, u32 moveEffect); bool32 MoveHasAdditionalEffectWithChance(u32 move, u32 moveEffect, u32 chance); @@ -354,5 +352,6 @@ bool32 IsPursuitTargetSet(void); void ClearPursuitValuesIfSet(u32 battler); void ClearPursuitValues(void); bool32 HasWeatherEffect(void); +bool32 IsMovePowderBlocked(u32 battlerAtk, u32 battlerDef, u32 move); #endif // GUARD_BATTLE_UTIL_H diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 782e0546c7..939dbd2aea 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -219,13 +219,11 @@ enum CmdVarious // Cmd_manipulatedamage #define DMG_CHANGE_SIGN 1 -#define DMG_RECOIL_FROM_MISS 2 -#define DMG_DOUBLED 3 -#define DMG_1_8_TARGET_HP 4 -#define DMG_FULL_ATTACKER_HP 5 -#define DMG_CURR_ATTACKER_HP 6 -#define DMG_BIG_ROOT 7 -#define DMG_RECOIL_FROM_IMMUNE 8 // Used to calculate recoil for the Gen 4 version of Jump Kick +#define DMG_DOUBLED 2 +#define DMG_1_8_TARGET_HP 3 +#define DMG_FULL_ATTACKER_HP 4 +#define DMG_CURR_ATTACKER_HP 5 +#define DMG_BIG_ROOT 6 // Cmd_jumpifcantswitch #define SWITCH_IGNORE_ESCAPE_PREVENTION (1 << 7) diff --git a/include/constants/event_object_movement.h b/include/constants/event_object_movement.h index 650a6a2357..bc2081a54b 100755 --- a/include/constants/event_object_movement.h +++ b/include/constants/event_object_movement.h @@ -251,6 +251,10 @@ #define MOVEMENT_ACTION_RUN_UP_SLOW 0xA3 #define MOVEMENT_ACTION_RUN_LEFT_SLOW 0xA4 #define MOVEMENT_ACTION_RUN_RIGHT_SLOW 0xA5 +#define MOVEMENT_ACTION_WALK_SLOW_STAIRS_DOWN 0xA6 +#define MOVEMENT_ACTION_WALK_SLOW_STAIRS_UP 0xA7 +#define MOVEMENT_ACTION_WALK_SLOW_STAIRS_LEFT 0xA8 +#define MOVEMENT_ACTION_WALK_SLOW_STAIRS_RIGHT 0xA9 #define MOVEMENT_ACTION_STEP_END 0xFE #define MOVEMENT_ACTION_NONE 0xFF diff --git a/include/event_object_movement.h b/include/event_object_movement.h index 0170baf910..679ad80ea4 100644 --- a/include/event_object_movement.h +++ b/include/event_object_movement.h @@ -222,6 +222,7 @@ void ObjectEventMoveDestCoords(struct ObjectEvent *objEvent, u32 direction, s16 u8 AddCameraObject(u8 linkedSpriteId); void UpdateObjectEventsForCameraUpdate(s16 x, s16 y); u8 GetWalkSlowMovementAction(u32); +u8 GetWalkSlowStairsMovementAction(u32); u8 GetJumpMovementAction(u32); u8 ElevationToPriority(u8 elevation); void ObjectEventUpdateElevation(struct ObjectEvent *objEvent, struct Sprite *); diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 23419ab7e0..4be8605412 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -260,7 +260,8 @@ static bool32 ShouldSwitchIfHasBadOdds(u32 battler) } // Check if mon gets one shot - if(maxDamageTaken > gBattleMons[battler].hp) + if(maxDamageTaken > gBattleMons[battler].hp + && !(gItemsInfo[gBattleMons[battler].item].holdEffect == HOLD_EFFECT_FOCUS_SASH || (!IsMoldBreakerTypeAbility(opposingBattler, gBattleMons[opposingBattler].ability) && B_STURDY >= GEN_5 && aiAbility == ABILITY_STURDY))) { getsOneShot = TRUE; } @@ -1695,7 +1696,7 @@ static u32 GetSwitchinHitsToKO(s32 damageTaken, u32 battler) currentHP = currentHP - damageTaken; // One shot prevention effects - if (damageTaken >= maxHP && currentHP == maxHP && (heldItemEffect == HOLD_EFFECT_FOCUS_SASH || (!opponentCanBreakMold && B_STURDY >= GEN_5 && ability == ABILITY_STURDY))) + if (damageTaken >= maxHP && startingHP == maxHP && (heldItemEffect == HOLD_EFFECT_FOCUS_SASH || (!opponentCanBreakMold && B_STURDY >= GEN_5 && ability == ABILITY_STURDY)) && hitsToKO < 1) currentHP = 1; // If mon is still alive, apply weather impact first, as it might KO the mon before it can heal with its item (order is weather -> item -> status) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 22da0d931b..716df8a870 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -2731,12 +2731,13 @@ static u32 GetPoisonDamage(u32 battlerId) } else if (gBattleMons[battlerId].status1 & STATUS1_TOXIC_POISON) { + u32 status1Temp = gBattleMons[battlerId].status1; damage = gBattleMons[battlerId].maxHP / 16; if (damage == 0) damage = 1; - if ((gBattleMons[battlerId].status1 & STATUS1_TOXIC_COUNTER) != STATUS1_TOXIC_TURN(15)) // not 16 turns - gBattleMons[battlerId].status1 += STATUS1_TOXIC_TURN(1); - damage *= (gBattleMons[battlerId].status1 & STATUS1_TOXIC_COUNTER) >> 8; + if ((status1Temp & STATUS1_TOXIC_COUNTER) != STATUS1_TOXIC_TURN(15)) // not 16 turns + status1Temp += STATUS1_TOXIC_TURN(1); + damage *= (status1Temp & STATUS1_TOXIC_COUNTER) >> 8; } return damage; } diff --git a/src/battle_dynamax.c b/src/battle_dynamax.c index 3e8d0e9db7..fecadd887d 100644 --- a/src/battle_dynamax.c +++ b/src/battle_dynamax.c @@ -491,3 +491,20 @@ void BS_JumpIfDynamaxed(void) else gBattlescriptCurrInstr = cmd->nextInstr; } + +void BS_UndoDynamax(void) +{ + NATIVE_ARGS(u8 battler); + u32 battler = GetBattlerForBattleScript(cmd->battler); + + if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX) + { + BattleScriptPushCursor(); + UndoDynamax(battler); + gBattleScripting.battler = battler; + gBattlescriptCurrInstr = BattleScript_DynamaxEnds_Ret; + return; + } + + gBattlescriptCurrInstr = cmd->nextInstr; +} diff --git a/src/battle_gimmick.c b/src/battle_gimmick.c index 728ff361a9..dfbbe0e7dc 100644 --- a/src/battle_gimmick.c +++ b/src/battle_gimmick.c @@ -204,6 +204,7 @@ static void SpriteCb_GimmickTrigger(struct Sprite *sprite) { s32 xSlide, xPriority, xOptimal; s32 yDiff; + s32 xHealthbox = gSprites[gHealthboxSpriteIds[sprite->tBattler]].x; if (IsDoubleBattle()) { @@ -222,25 +223,29 @@ static void SpriteCb_GimmickTrigger(struct Sprite *sprite) if (sprite->tHide) { - if (sprite->x != gSprites[gHealthboxSpriteIds[sprite->tBattler]].x - xSlide) + if (sprite->x < xHealthbox - xSlide) sprite->x++; - if (sprite->x >= gSprites[gHealthboxSpriteIds[sprite->tBattler]].x - xPriority) + if (sprite->x >= xHealthbox - xPriority) sprite->oam.priority = 2; else sprite->oam.priority = 1; sprite->y = gSprites[gHealthboxSpriteIds[sprite->tBattler]].y - yDiff; sprite->y2 = gSprites[gHealthboxSpriteIds[sprite->tBattler]].y2 - yDiff; - if (sprite->x == gSprites[gHealthboxSpriteIds[sprite->tBattler]].x - xSlide) + if (sprite->x == xHealthbox - xSlide) DestroyGimmickTriggerSprite(); } else { - if (sprite->x != gSprites[gHealthboxSpriteIds[sprite->tBattler]].x - xOptimal) + // Edge case: in doubles, if selecting move and next mon's action too fast, the second battler's gimmick icon uses the x from the first battler's gimmick icon + if (sprite->y != gSprites[gHealthboxSpriteIds[sprite->tBattler]].y - yDiff) + sprite->x = xHealthbox - xSlide; + + if (sprite->x > xHealthbox - xOptimal) sprite->x--; - if (sprite->x >= gSprites[gHealthboxSpriteIds[sprite->tBattler]].x - xPriority) + if (sprite->x >= xHealthbox - xPriority) sprite->oam.priority = 2; else sprite->oam.priority = 1; diff --git a/src/battle_main.c b/src/battle_main.c index d64c11db4b..3beafe1663 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3396,9 +3396,6 @@ const u8* FaintClearSetData(u32 battler) } } - // Clear Dynamax data - UndoDynamax(battler); - return result; } @@ -3518,16 +3515,9 @@ static void DoBattleIntro(void) } if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) - { gBattleStruct->introState++; - } else // Skip party summary since it is a wild battle. - { - if (B_FAST_INTRO_PKMN_TEXT == TRUE) - gBattleStruct->introState = BATTLE_INTRO_STATE_INTRO_TEXT; // Don't wait for sprite, print message at the same time. - else - gBattleStruct->introState++; // Wait for sprite to load. - } + gBattleStruct->introState = BATTLE_INTRO_STATE_INTRO_TEXT; break; case BATTLE_INTRO_STATE_DRAW_PARTY_SUMMARY: if (!gBattleControllerExecFlags) diff --git a/src/battle_message.c b/src/battle_message.c index e91cf957df..8b0f424d86 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -636,7 +636,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_PROTEANTYPECHANGE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY} transformed it into the {B_BUFF1} type!"), [STRINGID_SYMBIOSISITEMPASS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} passed its {B_LAST_ITEM} to {B_EFF_NAME_WITH_PREFIX2} through {B_LAST_ABILITY}!"), [STRINGID_STEALTHROCKDMG] = COMPOUND_STRING("Pointed stones dug into {B_SCR_NAME_WITH_PREFIX2}!"), - [STRINGID_TOXICSPIKESABSORBED] = COMPOUND_STRING("The poison spikes disappeared from the ground around {B_ATK_TEAM2} team!"), + [STRINGID_TOXICSPIKESABSORBED] = COMPOUND_STRING("The poison spikes disappeared from the ground around {B_SCR_TEAM2} team!"), [STRINGID_TOXICSPIKESPOISONED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} was poisoned!"), [STRINGID_STICKYWEBSWITCHIN] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} was caught in a sticky web!"), [STRINGID_HEALINGWISHCAMETRUE] = COMPOUND_STRING("The healing wish came true for {B_ATK_NAME_WITH_PREFIX2}!"), @@ -3116,6 +3116,18 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize) else toCpy = sText_Opposing2; break; + case B_TXT_SCR_TEAM1: + if (GetBattlerSide(gBattleScripting.battler) == B_SIDE_PLAYER) + toCpy = sText_Your1; + else + toCpy = sText_Opposing1; + break; + case B_TXT_SCR_TEAM2: + if (GetBattlerSide(gBattleScripting.battler) == B_SIDE_PLAYER) + toCpy = sText_Your2; + else + toCpy = sText_Opposing2; + break; case B_TXT_ATK_NAME_WITH_PREFIX2: HANDLE_NICKNAME_STRING_LOWERCASE(gBattlerAttacker) break; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index a1623c8b4b..fbc41b00c8 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1198,6 +1198,8 @@ static void Cmd_attackcanceler(void) return; if (gMovesInfo[gCurrentMove].effect == EFFECT_PARALYZE && AbilityBattleEffects(ABILITYEFFECT_ABSORBING, gBattlerTarget, 0, 0, gCurrentMove)) return; + if (IsMovePowderBlocked(gBattlerAttacker, gBattlerTarget, gCurrentMove)) + return; if (!gBattleMons[gBattlerAttacker].pp[gCurrMovePos] && gCurrentMove != MOVE_STRUGGLE && !(gHitMarker & (HITMARKER_ALLOW_NO_PP | HITMARKER_NO_ATTACKSTRING | HITMARKER_NO_PPDEDUCT)) @@ -1215,6 +1217,8 @@ static void Cmd_attackcanceler(void) && (!gBattleMoveEffects[effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))) || (IsMoveNotAllowedInSkyBattles(gCurrentMove))) { + gBattleStruct->noTargetPresent = TRUE; + if (effect == EFFECT_FLING) // Edge case for removing a mon's item when there is no target available after using Fling. gBattlescriptCurrInstr = BattleScript_FlingFailConsumeItem; else @@ -1235,6 +1239,7 @@ static void Cmd_attackcanceler(void) ClearDamageCalcResults(); SetAtkCancellerForCalledMove(); + gEffectBattler = gBattlerTarget; if (BlocksPrankster(gCurrentMove, gBattlerTarget, gBattlerAttacker, TRUE)) { // Opponent used a prankster'd magic coat -> reflected status move should fail against a dark-type attacker @@ -1965,9 +1970,9 @@ static void Cmd_critcalc(void) u32 abilityDef = GetBattlerAbility(battlerDef); if (GetGenConfig(GEN_CONFIG_CRIT_CHANCE) == GEN_1) - gBattleStruct->critChance[battlerDef] = CalcCritChanceStageGen1(gBattlerAttacker, gBattlerTarget, gCurrentMove, TRUE, abilityAtk, abilityDef, holdEffectAtk); + gBattleStruct->critChance[battlerDef] = CalcCritChanceStageGen1(gBattlerAttacker, battlerDef, gCurrentMove, TRUE, abilityAtk, abilityDef, holdEffectAtk); else - gBattleStruct->critChance[battlerDef] = CalcCritChanceStage(gBattlerAttacker, gBattlerTarget, gCurrentMove, TRUE, abilityAtk, abilityDef, holdEffectAtk); + gBattleStruct->critChance[battlerDef] = CalcCritChanceStage(gBattlerAttacker, battlerDef, gCurrentMove, TRUE, abilityAtk, abilityDef, holdEffectAtk); if (gBattleTypeFlags & (BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_FIRST_BATTLE)) gSpecialStatuses[battlerDef].criticalHit = FALSE; @@ -4782,13 +4787,23 @@ static void Cmd_dofaintanimation(void) { CMD_ARGS(u8 battler); - if (gBattleControllerExecFlags == 0) + if (gBattleControllerExecFlags != 0) + return; + + u32 battler = GetBattlerForBattleScript(cmd->battler); + + if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX) { - u32 battler = GetBattlerForBattleScript(cmd->battler); - BtlController_EmitFaintAnimation(battler, BUFFER_A); - MarkBattlerForControllerExec(battler); - gBattlescriptCurrInstr = cmd->nextInstr; + BattleScriptPushCursor(); + UndoDynamax(battler); + gBattleScripting.battler = battler; + gBattlescriptCurrInstr = BattleScript_DynamaxEnds_Ret; + return; } + + BtlController_EmitFaintAnimation(battler, BUFFER_A); + MarkBattlerForControllerExec(battler); + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_cleareffectsonfaint(void) @@ -6360,6 +6375,25 @@ static void Cmd_moveend(void) gBattleScripting.moveendState++; break; } + else if (gMovesInfo[gCurrentMove].effect == EFFECT_RECOIL_IF_MISS + && (!IsBattlerTurnDamaged(gBattlerTarget) || gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT) + && !gBattleStruct->noTargetPresent + && IsBattlerAlive(gBattlerAttacker)) + { + if (B_RECOIL_IF_MISS_DMG >= GEN_5 || (B_CRASH_IF_TARGET_IMMUNE == GEN_4 && gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_DOESNT_AFFECT_FOE)) + gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 2; + else if (B_RECOIL_IF_MISS_DMG == GEN_4 && (GetNonDynamaxMaxHP(gBattlerTarget) / 2) < gBattleStruct->moveDamage[gBattlerTarget]) + gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerTarget) / 2; + else // Fallback if B_RECOIL_IF_MISS_DMG is set to gen3 or lower. + gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerTarget) / 2; + + if (gBattleStruct->moveDamage[gBattlerAttacker] == 0) + gBattleStruct->moveDamage[gBattlerAttacker] = 1; + + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_RecoilIfMiss; + effect = TRUE; + } else if (moveEffect == EFFECT_RECOIL && !(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT) && IsBattlerAlive(gBattlerAttacker) @@ -7256,6 +7290,7 @@ static void Cmd_moveend(void) gBattleStruct->fickleBeamBoosted = FALSE; gBattleStruct->redCardActivates = FALSE; gBattleStruct->battlerState[gBattlerAttacker].usedMicleBerry = FALSE; + gBattleStruct->noTargetPresent = FALSE; if (gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE) gBattleStruct->pledgeMove = FALSE; if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE) @@ -11928,23 +11963,6 @@ static void Cmd_manipulatedamage(void) case DMG_CHANGE_SIGN: gBattleStruct->moveDamage[gBattlerAttacker] *= -1; break; - case DMG_RECOIL_FROM_MISS: - if (B_RECOIL_IF_MISS_DMG >= GEN_5) - { - gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 2; - } - else if (B_RECOIL_IF_MISS_DMG == GEN_4) - { - if ((gBattleMons[gBattlerTarget].maxHP / 2) < gBattleStruct->moveDamage[gBattlerTarget]) - gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerTarget) / 2; - } - else - { - gBattleStruct->moveDamage[gBattlerAttacker] = gBattleStruct->moveDamage[gBattlerTarget] /= 2; - } - if (gBattleStruct->moveDamage[gBattlerAttacker] == 0) - gBattleStruct->moveDamage[gBattlerAttacker] = 1; - break; case DMG_DOUBLED: gBattleStruct->moveDamage[gBattlerTarget] *= 2; break; @@ -11962,9 +11980,6 @@ static void Cmd_manipulatedamage(void) case DMG_CURR_ATTACKER_HP: gBattleStruct->moveDamage[gBattlerTarget] = GetNonDynamaxHP(gBattlerAttacker); break; - case DMG_RECOIL_FROM_IMMUNE: - gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerTarget) / 2; - break; } gBattlescriptCurrInstr = cmd->nextInstr; @@ -16744,6 +16759,8 @@ bool32 IsMoveAffectedByParentalBond(u32 move, u32 battler) && !IsMoveParentalBondBanned(move) && GetMoveCategory(move) != DAMAGE_CATEGORY_STATUS && GetMoveStrikeCount(move) < 2 + && GetMoveEffect(move) != EFFECT_SEMI_INVULNERABLE + && GetMoveEffect(move) != EFFECT_TWO_TURNS_ATTACK && GetMoveEffect(move) != EFFECT_MULTI_HIT) { if (IsDoubleBattle()) @@ -18658,7 +18675,6 @@ void BS_RestoreSavedMove(void) gBattlescriptCurrInstr = cmd->nextInstr; } - void BS_JumpIfCanGigantamax(void) { NATIVE_ARGS(u8 battler, const u8 *jumpInstr); diff --git a/src/battle_util.c b/src/battle_util.c index c1a7d99d66..2f7d027d9e 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -274,7 +274,7 @@ bool32 HandleMoveTargetRedirection(void) for (battler = 0; battler < gBattlersCount; battler++) { ability = GetBattlerAbility(battler); - if ((B_REDIRECT_ABILITY_ALLIES >= GEN_4 || !IsAlly(gBattlerAttacker, battler)) + if ((B_REDIRECT_ABILITY_ALLIES >= GEN_4 || !IsBattlerAlly(gBattlerAttacker, battler)) && battler != gBattlerAttacker && gBattleStruct->moveTarget[gBattlerAttacker] != battler && ((ability == ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC) @@ -494,8 +494,6 @@ void HandleAction_Switch(void) if (gBattleResults.playerSwitchesCounter < 255) gBattleResults.playerSwitchesCounter++; - if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_DYNAMAX) - UndoDynamax(gBattlerAttacker); // this is better performed here instead of SwitchInClearSetData TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_SWITCH); } @@ -3590,28 +3588,6 @@ static void CancellerDynamaxBlocked(u32 *effect) } } -static void CancellerPowderMove(u32 *effect) -{ - if (IsPowderMove(gCurrentMove) && (gBattlerAttacker != gBattlerTarget)) - { - if (B_POWDER_GRASS >= GEN_6 - && (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_GRASS) || GetBattlerAbility(gBattlerTarget) == ABILITY_OVERCOAT)) - { - gBattlerAbility = gBattlerTarget; - *effect = 1; - } - else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_SAFETY_GOGGLES) - { - RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_SAFETY_GOGGLES); - gLastUsedItem = gBattleMons[gBattlerTarget].item; - *effect = 1; - } - - if (*effect != 0) - gBattlescriptCurrInstr = BattleScript_PowderMoveNoEffect; - } -} - static void CancellerPowderStatus(u32 *effect) { if (TryActivatePowderStatus(gCurrentMove)) @@ -3844,7 +3820,6 @@ static const MoveSuccessOrderCancellers sMoveSuccessOrderCancellers[] = [CANCELLER_STANCE_CHANGE_2] = CancellerStanceChangeTwo, [CANCELLER_WEATHER_PRIMAL] = CancellerWeatherPrimal, [CANCELLER_DYNAMAX_BLOCKED] = CancellerDynamaxBlocked, - [CANCELLER_POWDER_MOVE] = CancellerPowderMove, [CANCELLER_POWDER_STATUS] = CancellerPowderStatus, [CANCELLER_PROTEAN] = CancellerProtean, [CANCELLER_PSYCHIC_TERRAIN] = CancellerPsychicTerrain, @@ -4243,7 +4218,7 @@ static void ChooseStatBoostAnimation(u32 battler) bool32 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 move, u32 abilityDef, enum AbilityEffectOptions option) { const u8 *battleScriptBlocksMove = NULL; - u32 atkPriority = AI_DATA->aiCalcInProgress ? GetBattleMovePriority(battlerAtk, move) : GetChosenMovePriority(battlerAtk); + s32 atkPriority = AI_DATA->aiCalcInProgress ? GetBattleMovePriority(battlerAtk, move) : GetChosenMovePriority(battlerAtk); u32 moveTarget = GetBattlerMoveTargetType(battlerAtk, move); u32 battlerAbility = battlerDef; @@ -6603,7 +6578,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 gDisableStructs[battler].terrainAbilityDone = TRUE; ChangeTypeBasedOnTerrain(battler); gBattlerAbility = gBattleScripting.battler = battler; - BattleScriptPushCursorAndCallback(BattleScript_MimicryActivates_End3); + BattleScriptPushCursorAndCallback(BattleScript_MimicryActivates); effect++; } break; @@ -10912,11 +10887,11 @@ s32 GetStealthHazardDamageByTypesAndHP(enum TypeSideHazard hazardType, u8 type1, s32 GetStealthHazardDamage(enum TypeSideHazard hazardType, u32 battler) { - u8 type1 = gBattleMons[battler].types[0]; - u8 type2 = gBattleMons[battler].types[1]; + u32 types[3]; + GetBattlerTypes(battler, FALSE, types); u32 maxHp = gBattleMons[battler].maxHP; - return GetStealthHazardDamageByTypesAndHP(hazardType, type1, type2, maxHp); + return GetStealthHazardDamageByTypesAndHP(hazardType, types[0], types[1], maxHp); } bool32 IsPartnerMonFromSameTrainer(u32 battler) @@ -12343,3 +12318,30 @@ bool32 HasWeatherEffect(void) return TRUE; } + +bool32 IsMovePowderBlocked(u32 battlerAtk, u32 battlerDef, u32 move) +{ + bool32 effect = FALSE; + + if (IsPowderMove(move) && (battlerAtk != battlerDef)) + { + if (B_POWDER_GRASS >= GEN_6 + && (IS_BATTLER_OF_TYPE(battlerDef, TYPE_GRASS) || GetBattlerAbility(battlerDef) == ABILITY_OVERCOAT)) + { + gBattlerAbility = battlerDef; + RecordAbilityBattle(gBattlerTarget, ABILITY_OVERCOAT); + effect = TRUE; + } + else if (GetBattlerHoldEffect(battlerDef, TRUE) == HOLD_EFFECT_SAFETY_GOGGLES) + { + RecordItemEffectBattle(battlerDef, HOLD_EFFECT_SAFETY_GOGGLES); + gLastUsedItem = gBattleMons[battlerDef].item; + effect = TRUE; + } + + if (effect) + gBattlescriptCurrInstr = BattleScript_PowderMoveNoEffect; + } + + return effect; +} diff --git a/src/data/battle_move_effects.h b/src/data/battle_move_effects.h index cf9814ac02..36529e5ca2 100644 --- a/src/data/battle_move_effects.h +++ b/src/data/battle_move_effects.h @@ -238,7 +238,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] = [EFFECT_RECOIL_IF_MISS] = { - .battleScript = BattleScript_EffectRecoilIfMiss, + .battleScript = BattleScript_EffectHit, .battleTvScore = 1, }, diff --git a/src/data/object_events/movement_action_func_tables.h b/src/data/object_events/movement_action_func_tables.h index dda5ff3991..4f5fd57a82 100755 --- a/src/data/object_events/movement_action_func_tables.h +++ b/src/data/object_events/movement_action_func_tables.h @@ -271,6 +271,14 @@ u8 MovementActionFunc_RunSlowUp_Step0(struct ObjectEvent *objectEvent, struct Sp u8 MovementActionFunc_RunSlowLeft_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite); u8 MovementActionFunc_RunSlowRight_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite); u8 MovementActionFunc_RunSlow_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite); +u8 MovementAction_WalkSlowStairsUp_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite); +u8 MovementAction_WalkSlowStairsUp_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite); +u8 MovementAction_WalkSlowStairsDown_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite); +u8 MovementAction_WalkSlowStairsDown_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite); +u8 MovementAction_WalkSlowStairsLeft_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite); +u8 MovementAction_WalkSlowStairsLeft_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite); +u8 MovementAction_WalkSlowStairsRight_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite); +u8 MovementAction_WalkSlowStairsRight_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite); u8 (*const gMovementActionFuncs_FaceDown[])(struct ObjectEvent *, struct Sprite *); u8 (*const gMovementActionFuncs_FaceUp[])(struct ObjectEvent *, struct Sprite *); @@ -438,6 +446,10 @@ u8 (*const gMovementActionFuncs_RunDownSlow[])(struct ObjectEvent *, struct Spri u8 (*const gMovementActionFuncs_RunUpSlow[])(struct ObjectEvent *, struct Sprite *); u8 (*const gMovementActionFuncs_RunLeftSlow[])(struct ObjectEvent *, struct Sprite *); u8 (*const gMovementActionFuncs_RunRightSlow[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_WalkSlowStairsDown[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_WalkSlowStairsUp[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_WalkSlowStairsLeft[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_WalkSlowStairsRight[])(struct ObjectEvent *, struct Sprite *); u8 (*const *const gMovementActionFuncs[])(struct ObjectEvent *, struct Sprite *) = { [MOVEMENT_ACTION_FACE_DOWN] = gMovementActionFuncs_FaceDown, @@ -606,6 +618,10 @@ u8 (*const *const gMovementActionFuncs[])(struct ObjectEvent *, struct Sprite *) [MOVEMENT_ACTION_RUN_UP_SLOW] = gMovementActionFuncs_RunUpSlow, [MOVEMENT_ACTION_RUN_LEFT_SLOW] = gMovementActionFuncs_RunLeftSlow, [MOVEMENT_ACTION_RUN_RIGHT_SLOW] = gMovementActionFuncs_RunRightSlow, + [MOVEMENT_ACTION_WALK_SLOW_STAIRS_DOWN] = gMovementActionFuncs_WalkSlowStairsDown, + [MOVEMENT_ACTION_WALK_SLOW_STAIRS_UP] = gMovementActionFuncs_WalkSlowStairsUp, + [MOVEMENT_ACTION_WALK_SLOW_STAIRS_LEFT] = gMovementActionFuncs_WalkSlowStairsLeft, + [MOVEMENT_ACTION_WALK_SLOW_STAIRS_RIGHT] = gMovementActionFuncs_WalkSlowStairsRight, }; u8 (*const gMovementActionFuncs_FaceDown[])(struct ObjectEvent *, struct Sprite *) = { @@ -1591,3 +1607,27 @@ u8 (*const gMovementActionFuncs_RunRightSlow[])(struct ObjectEvent *, struct Spr MovementActionFunc_RunSlow_Step1, MovementAction_PauseSpriteAnim, }; + +bool8 (*const gMovementActionFuncs_WalkSlowStairsUp[])(struct ObjectEvent *, struct Sprite *) = { + MovementAction_WalkSlowStairsUp_Step0, + MovementAction_WalkSlowStairsUp_Step1, + MovementAction_PauseSpriteAnim, +}; + +bool8 (*const gMovementActionFuncs_WalkSlowStairsDown[])(struct ObjectEvent *, struct Sprite *) = { + MovementAction_WalkSlowStairsDown_Step0, + MovementAction_WalkSlowStairsDown_Step1, + MovementAction_PauseSpriteAnim, +}; + +bool8 (*const gMovementActionFuncs_WalkSlowStairsLeft[])(struct ObjectEvent *, struct Sprite *) = { + MovementAction_WalkSlowStairsLeft_Step0, + MovementAction_WalkSlowStairsLeft_Step1, + MovementAction_PauseSpriteAnim, +}; + +bool8 (*const gMovementActionFuncs_WalkSlowStairsRight[])(struct ObjectEvent *, struct Sprite *) = { + MovementAction_WalkSlowStairsRight_Step0, + MovementAction_WalkSlowStairsRight_Step1, + MovementAction_PauseSpriteAnim, +}; diff --git a/src/data/object_events/object_event_pic_tables_followers.h b/src/data/object_events/object_event_pic_tables_followers.h index d77010c0c0..305fd6b74e 100644 --- a/src/data/object_events/object_event_pic_tables_followers.h +++ b/src/data/object_events/object_event_pic_tables_followers.h @@ -18,11 +18,13 @@ static const struct SpriteFrameImage sPicTable_VenusaurF[] = { overworld_ascending_frames(gObjectEventPic_VenusaurF, 4, 4), }; #endif //P_GENDER_DIFFERENCES +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_VenusaurMega[] = { overworld_ascending_frames(gObjectEventPic_VenusaurMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #if P_GIGANTAMAX_FORMS /*static const struct SpriteFrameImage sPicTable_VenusaurGmax[] = { overworld_ascending_frames(gObjectEventPic_VenusaurGmax, 4, 4), @@ -40,6 +42,7 @@ static const struct SpriteFrameImage sPicTable_Charmeleon[] = { static const struct SpriteFrameImage sPicTable_Charizard[] = { overworld_ascending_frames(gObjectEventPic_Charizard, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_CharizardMegaX[] = { overworld_ascending_frames(gObjectEventPic_CharizardMegaX, 4, 4), @@ -47,7 +50,8 @@ static const struct SpriteFrameImage sPicTable_CharizardMegaX[] = { static const struct SpriteFrameImage sPicTable_CharizardMegaY[] = { overworld_ascending_frames(gObjectEventPic_CharizardMegaY, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #if P_GIGANTAMAX_FORMS /*static const struct SpriteFrameImage sPicTable_CharizardGmax[] = { overworld_ascending_frames(gObjectEventPic_CharizardGmax, 4, 4), @@ -65,11 +69,13 @@ static const struct SpriteFrameImage sPicTable_Wartortle[] = { static const struct SpriteFrameImage sPicTable_Blastoise[] = { overworld_ascending_frames(gObjectEventPic_Blastoise, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_BlastoiseMega[] = { overworld_ascending_frames(gObjectEventPic_BlastoiseMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #if P_GIGANTAMAX_FORMS /*static const struct SpriteFrameImage sPicTable_BlastoiseGmax[] = { overworld_ascending_frames(gObjectEventPic_BlastoiseGmax, 4, 4), @@ -109,11 +115,13 @@ static const struct SpriteFrameImage sPicTable_Kakuna[] = { static const struct SpriteFrameImage sPicTable_Beedrill[] = { overworld_ascending_frames(gObjectEventPic_Beedrill, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_BeedrillMega[] = { overworld_ascending_frames(gObjectEventPic_BeedrillMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_WEEDLE #if P_FAMILY_PIDGEY @@ -126,11 +134,13 @@ static const struct SpriteFrameImage sPicTable_Pidgeotto[] = { static const struct SpriteFrameImage sPicTable_Pidgeot[] = { overworld_ascending_frames(gObjectEventPic_Pidgeot, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_PidgeotMega[] = { overworld_ascending_frames(gObjectEventPic_PidgeotMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_PIDGEY #if P_FAMILY_RATTATA @@ -547,11 +557,13 @@ static const struct SpriteFrameImage sPicTable_AlakazamF[] = { overworld_ascending_frames(gObjectEventPic_AlakazamF, 4, 4), }; #endif //P_GENDER_DIFFERENCES +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_AlakazamMega[] = { overworld_ascending_frames(gObjectEventPic_AlakazamMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_ABRA #if P_FAMILY_MACHOP @@ -645,11 +657,13 @@ static const struct SpriteFrameImage sPicTable_Slowking[] = { }; #endif //P_GEN_2_CROSS_EVOS +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_SlowbroMega[] = { overworld_ascending_frames(gObjectEventPic_SlowbroMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #if P_GALARIAN_FORMS static const struct SpriteFrameImage sPicTable_SlowpokeGalar[] = { @@ -758,11 +772,13 @@ static const struct SpriteFrameImage sPicTable_Haunter[] = { static const struct SpriteFrameImage sPicTable_Gengar[] = { overworld_ascending_frames(gObjectEventPic_Gengar, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_GengarMega[] = { overworld_ascending_frames(gObjectEventPic_GengarMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #if P_GIGANTAMAX_FORMS /*static const struct SpriteFrameImage sPicTable_GengarGmax[] = { overworld_ascending_frames(gObjectEventPic_GengarGmax, 4, 4), @@ -783,11 +799,13 @@ static const struct SpriteFrameImage sPicTable_SteelixF[] = { overworld_ascending_frames(gObjectEventPic_SteelixF, 4, 4), }; #endif //P_GENDER_DIFFERENCES +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_SteelixMega[] = { overworld_ascending_frames(gObjectEventPic_SteelixMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_GEN_2_CROSS_EVOS #endif //P_FAMILY_ONIX @@ -973,11 +991,13 @@ static const struct SpriteFrameImage sPicTable_TangrowthF[] = { static const struct SpriteFrameImage sPicTable_Kangaskhan[] = { overworld_ascending_frames(gObjectEventPic_Kangaskhan, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_KangaskhanMega[] = { overworld_ascending_frames(gObjectEventPic_KangaskhanMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_KANGASKHAN #if P_FAMILY_HORSEA @@ -1059,11 +1079,13 @@ static const struct SpriteFrameImage sPicTable_ScizorF[] = { overworld_ascending_frames(gObjectEventPic_ScizorF, 4, 4), }; #endif //P_GENDER_DIFFERENCES +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_ScizorMega[] = { overworld_ascending_frames(gObjectEventPic_ScizorMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_GEN_2_CROSS_EVOS #if P_GEN_8_CROSS_EVOS @@ -1120,11 +1142,13 @@ static const struct SpriteFrameImage sPicTable_Magmortar[] = { static const struct SpriteFrameImage sPicTable_Pinsir[] = { overworld_ascending_frames(gObjectEventPic_Pinsir, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_PinsirMega[] = { overworld_ascending_frames(gObjectEventPic_PinsirMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_PINSIR #if P_FAMILY_TAUROS @@ -1161,11 +1185,13 @@ static const struct SpriteFrameImage sPicTable_GyaradosF[] = { overworld_ascending_frames(gObjectEventPic_GyaradosF, 4, 4), }; #endif //P_GENDER_DIFFERENCES +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_GyaradosMega[] = { overworld_ascending_frames(gObjectEventPic_GyaradosMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_MAGIKARP #if P_FAMILY_LAPRAS @@ -1272,11 +1298,13 @@ static const struct SpriteFrameImage sPicTable_Kabutops[] = { static const struct SpriteFrameImage sPicTable_Aerodactyl[] = { overworld_ascending_frames(gObjectEventPic_Aerodactyl, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_AerodactylMega[] = { overworld_ascending_frames(gObjectEventPic_AerodactylMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_AERODACTYL #if P_FAMILY_SNORLAX @@ -1344,6 +1372,7 @@ static const struct SpriteFrameImage sPicTable_Dragonite[] = { static const struct SpriteFrameImage sPicTable_Mewtwo[] = { overworld_ascending_frames(gObjectEventPic_Mewtwo, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_MewtwoMegaX[] = { overworld_ascending_frames(gObjectEventPic_MewtwoMegaX, 4, 4), @@ -1351,7 +1380,8 @@ static const struct SpriteFrameImage sPicTable_MewtwoMegaX[] = { static const struct SpriteFrameImage sPicTable_MewtwoMegaY[] = { overworld_ascending_frames(gObjectEventPic_MewtwoMegaY, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_MEWTWO #if P_FAMILY_MEW @@ -1499,11 +1529,13 @@ static const struct SpriteFrameImage sPicTable_Flaaffy[] = { static const struct SpriteFrameImage sPicTable_Ampharos[] = { overworld_ascending_frames(gObjectEventPic_Ampharos, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_AmpharosMega[] = { overworld_ascending_frames(gObjectEventPic_AmpharosMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_MAREEP #if P_FAMILY_MARILL @@ -1841,11 +1873,13 @@ static const struct SpriteFrameImage sPicTable_HeracrossF[] = { overworld_ascending_frames(gObjectEventPic_HeracrossF, 4, 4), }; #endif //P_GENDER_DIFFERENCES +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_HeracrossMega[] = { overworld_ascending_frames(gObjectEventPic_HeracrossMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_HERACROSS #if P_FAMILY_SNEASEL @@ -2001,11 +2035,13 @@ static const struct SpriteFrameImage sPicTable_HoundoomF[] = { overworld_ascending_frames(gObjectEventPic_HoundoomF, 4, 4), }; #endif //P_GENDER_DIFFERENCES +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_HoundoomMega[] = { overworld_ascending_frames(gObjectEventPic_HoundoomMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_HOUNDOUR #if P_FAMILY_PHANPY @@ -2073,11 +2109,13 @@ static const struct SpriteFrameImage sPicTable_Pupitar[] = { static const struct SpriteFrameImage sPicTable_Tyranitar[] = { overworld_ascending_frames(gObjectEventPic_Tyranitar, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_TyranitarMega[] = { overworld_ascending_frames(gObjectEventPic_TyranitarMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_LARVITAR #if P_FAMILY_LUGIA @@ -2108,11 +2146,13 @@ static const struct SpriteFrameImage sPicTable_Grovyle[] = { static const struct SpriteFrameImage sPicTable_Sceptile[] = { overworld_ascending_frames(gObjectEventPic_Sceptile, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_SceptileMega[] = { overworld_ascending_frames(gObjectEventPic_SceptileMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_TREECKO #if P_FAMILY_TORCHIC @@ -2140,11 +2180,13 @@ static const struct SpriteFrameImage sPicTable_BlazikenF[] = { overworld_ascending_frames(gObjectEventPic_BlazikenF, 4, 4), }; #endif //P_GENDER_DIFFERENCES +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_BlazikenMega[] = { overworld_ascending_frames(gObjectEventPic_BlazikenMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_TORCHIC #if P_FAMILY_MUDKIP @@ -2157,11 +2199,13 @@ static const struct SpriteFrameImage sPicTable_Marshtomp[] = { static const struct SpriteFrameImage sPicTable_Swampert[] = { overworld_ascending_frames(gObjectEventPic_Swampert, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_SwampertMega[] = { overworld_ascending_frames(gObjectEventPic_SwampertMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_MUDKIP #if P_FAMILY_POOCHYENA @@ -2288,21 +2332,25 @@ static const struct SpriteFrameImage sPicTable_Kirlia[] = { static const struct SpriteFrameImage sPicTable_Gardevoir[] = { overworld_ascending_frames(gObjectEventPic_Gardevoir, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_GardevoirMega[] = { overworld_ascending_frames(gObjectEventPic_GardevoirMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #if P_GEN_4_CROSS_EVOS static const struct SpriteFrameImage sPicTable_Gallade[] = { overworld_ascending_frames(gObjectEventPic_Gallade, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_GalladeMega[] = { overworld_ascending_frames(gObjectEventPic_GalladeMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_GEN_4_CROSS_EVOS #endif //P_FAMILY_RALTS @@ -2393,22 +2441,26 @@ static const struct SpriteFrameImage sPicTable_Delcatty[] = { static const struct SpriteFrameImage sPicTable_Sableye[] = { overworld_ascending_frames(gObjectEventPic_Sableye, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_SableyeMega[] = { overworld_ascending_frames(gObjectEventPic_SableyeMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_SABLEYE #if P_FAMILY_MAWILE static const struct SpriteFrameImage sPicTable_Mawile[] = { overworld_ascending_frames(gObjectEventPic_Mawile, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_MawileMega[] = { overworld_ascending_frames(gObjectEventPic_MawileMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_MAWILE #if P_FAMILY_ARON @@ -2421,11 +2473,13 @@ static const struct SpriteFrameImage sPicTable_Lairon[] = { static const struct SpriteFrameImage sPicTable_Aggron[] = { overworld_ascending_frames(gObjectEventPic_Aggron, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_AggronMega[] = { overworld_ascending_frames(gObjectEventPic_AggronMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_ARON #if P_FAMILY_MEDITITE @@ -2445,11 +2499,13 @@ static const struct SpriteFrameImage sPicTable_MedichamF[] = { overworld_ascending_frames(gObjectEventPic_MedichamF, 4, 4), }; #endif //P_GENDER_DIFFERENCES +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_MedichamMega[] = { overworld_ascending_frames(gObjectEventPic_MedichamMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_MEDITITE #if P_FAMILY_ELECTRIKE @@ -2459,11 +2515,13 @@ static const struct SpriteFrameImage sPicTable_Electrike[] = { static const struct SpriteFrameImage sPicTable_Manectric[] = { overworld_ascending_frames(gObjectEventPic_Manectric, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_ManectricMega[] = { overworld_ascending_frames(gObjectEventPic_ManectricMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_ELECTRIKE #if P_FAMILY_PLUSLE @@ -2539,11 +2597,13 @@ static const struct SpriteFrameImage sPicTable_Carvanha[] = { static const struct SpriteFrameImage sPicTable_Sharpedo[] = { overworld_ascending_frames(gObjectEventPic_Sharpedo, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_SharpedoMega[] = { overworld_ascending_frames(gObjectEventPic_SharpedoMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_CARVANHA #if P_FAMILY_WAILMER @@ -2572,11 +2632,13 @@ static const struct SpriteFrameImage sPicTable_CameruptF[] = { overworld_ascending_frames(gObjectEventPic_CameruptF, 4, 4), }; #endif //P_GENDER_DIFFERENCES +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_CameruptMega[] = { overworld_ascending_frames(gObjectEventPic_CameruptMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_NUMEL #if P_FAMILY_TORKOAL @@ -2633,11 +2695,13 @@ static const struct SpriteFrameImage sPicTable_Swablu[] = { static const struct SpriteFrameImage sPicTable_Altaria[] = { overworld_ascending_frames(gObjectEventPic_Altaria, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_AltariaMega[] = { overworld_ascending_frames(gObjectEventPic_AltariaMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_SWABLU #if P_FAMILY_ZANGOOSE @@ -2751,11 +2815,13 @@ static const struct SpriteFrameImage sPicTable_Shuppet[] = { static const struct SpriteFrameImage sPicTable_Banette[] = { overworld_ascending_frames(gObjectEventPic_Banette, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_BanetteMega[] = { overworld_ascending_frames(gObjectEventPic_BanetteMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_SHUPPET #if P_FAMILY_DUSKULL @@ -2793,11 +2859,13 @@ static const struct SpriteFrameImage sPicTable_Chimecho[] = { static const struct SpriteFrameImage sPicTable_Absol[] = { overworld_ascending_frames(gObjectEventPic_Absol, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_AbsolMega[] = { overworld_ascending_frames(gObjectEventPic_AbsolMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_ABSOL #if P_FAMILY_SNORUNT @@ -2807,11 +2875,13 @@ static const struct SpriteFrameImage sPicTable_Snorunt[] = { static const struct SpriteFrameImage sPicTable_Glalie[] = { overworld_ascending_frames(gObjectEventPic_Glalie, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_GlalieMega[] = { overworld_ascending_frames(gObjectEventPic_GlalieMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #if P_GEN_4_CROSS_EVOS static const struct SpriteFrameImage sPicTable_Froslass[] = { @@ -2871,11 +2941,13 @@ static const struct SpriteFrameImage sPicTable_Shelgon[] = { static const struct SpriteFrameImage sPicTable_Salamence[] = { overworld_ascending_frames(gObjectEventPic_Salamence, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_SalamenceMega[] = { overworld_ascending_frames(gObjectEventPic_SalamenceMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_BAGON #if P_FAMILY_BELDUM @@ -2888,11 +2960,13 @@ static const struct SpriteFrameImage sPicTable_Metang[] = { static const struct SpriteFrameImage sPicTable_Metagross[] = { overworld_ascending_frames(gObjectEventPic_Metagross, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_MetagrossMega[] = { overworld_ascending_frames(gObjectEventPic_MetagrossMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_BELDUM #if P_FAMILY_REGIROCK @@ -2917,55 +2991,65 @@ static const struct SpriteFrameImage sPicTable_Registeel[] = { static const struct SpriteFrameImage sPicTable_Latias[] = { overworld_ascending_frames(gObjectEventPic_Latias, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_LatiasMega[] = { overworld_ascending_frames(gObjectEventPic_LatiasMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_LATIAS #if P_FAMILY_LATIOS static const struct SpriteFrameImage sPicTable_Latios[] = { overworld_ascending_frames(gObjectEventPic_Latios, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_LatiosMega[] = { overworld_ascending_frames(gObjectEventPic_LatiosMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_LATIOS #if P_FAMILY_KYOGRE static const struct SpriteFrameImage sPicTable_Kyogre[] = { overworld_ascending_frames(gObjectEventPic_Kyogre, 8, 8), }; +#if OW_BATTLE_ONLY_FORMS #if P_PRIMAL_REVERSIONS static const struct SpriteFrameImage sPicTable_KyogrePrimal[] = { overworld_ascending_frames(gObjectEventPic_KyogrePrimal, 4, 4), }; -#endif //P_PRIMAL_REVERSIONS +#endif // P_PRIMAL_REVERSIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_KYOGRE #if P_FAMILY_GROUDON static const struct SpriteFrameImage sPicTable_Groudon[] = { overworld_ascending_frames(gObjectEventPic_Groudon, 8, 8), }; +#if OW_BATTLE_ONLY_FORMS #if P_PRIMAL_REVERSIONS static const struct SpriteFrameImage sPicTable_GroudonPrimal[] = { overworld_ascending_frames(gObjectEventPic_GroudonPrimal, 4, 4), }; -#endif //P_PRIMAL_REVERSIONS +#endif // P_PRIMAL_REVERSIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_GROUDON #if P_FAMILY_RAYQUAZA static const struct SpriteFrameImage sPicTable_Rayquaza[] = { overworld_ascending_frames(gObjectEventPic_Rayquaza, 8, 8), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_RayquazaMega[] = { overworld_ascending_frames(gObjectEventPic_RayquazaMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_RAYQUAZA #if P_FAMILY_JIRACHI @@ -3246,11 +3330,13 @@ static const struct SpriteFrameImage sPicTable_Buneary[] = { static const struct SpriteFrameImage sPicTable_Lopunny[] = { overworld_ascending_frames(gObjectEventPic_Lopunny, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_LopunnyMega[] = { overworld_ascending_frames(gObjectEventPic_LopunnyMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_BUNEARY #if P_FAMILY_GLAMEOW @@ -3317,11 +3403,13 @@ static const struct SpriteFrameImage sPicTable_GarchompF[] = { overworld_ascending_frames(gObjectEventPic_GarchompF, 4, 4), }; #endif //P_GENDER_DIFFERENCES +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_GarchompMega[] = { overworld_ascending_frames(gObjectEventPic_GarchompMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_GIBLE #if P_FAMILY_RIOLU @@ -3331,11 +3419,13 @@ static const struct SpriteFrameImage sPicTable_Riolu[] = { static const struct SpriteFrameImage sPicTable_Lucario[] = { overworld_ascending_frames(gObjectEventPic_Lucario, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_LucarioMega[] = { overworld_ascending_frames(gObjectEventPic_LucarioMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_RIOLU #if P_FAMILY_HIPPOPOTAS @@ -3422,11 +3512,13 @@ static const struct SpriteFrameImage sPicTable_AbomasnowF[] = { overworld_ascending_frames(gObjectEventPic_AbomasnowF, 4, 4), }; #endif //P_GENDER_DIFFERENCES +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_AbomasnowMega[] = { overworld_ascending_frames(gObjectEventPic_AbomasnowMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_SNOVER #if P_FAMILY_ROTOM @@ -3769,11 +3861,13 @@ static const struct SpriteFrameImage sPicTable_Excadrill[] = { static const struct SpriteFrameImage sPicTable_Audino[] = { overworld_ascending_frames(gObjectEventPic_Audino, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_AudinoMega[] = { overworld_ascending_frames(gObjectEventPic_AudinoMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_AUDINO #if P_FAMILY_TIMBURR @@ -4959,11 +5053,13 @@ static const struct SpriteFrameImage sPicTable_ZygardeComplete[] = { static const struct SpriteFrameImage sPicTable_Diancie[] = { overworld_ascending_frames(gObjectEventPic_Diancie, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_MEGA_EVOLUTIONS static const struct SpriteFrameImage sPicTable_DiancieMega[] = { overworld_ascending_frames(gObjectEventPic_DiancieMega, 4, 4), }; -#endif //P_MEGA_EVOLUTIONS +#endif // P_MEGA_EVOLUTIONS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FAMILY_DIANCIE #if P_FAMILY_HOOPA @@ -5417,11 +5513,13 @@ static const struct SpriteFrameImage sPicTable_NecrozmaDuskMane[] = { static const struct SpriteFrameImage sPicTable_NecrozmaDawnWings[] = { overworld_ascending_frames(gObjectEventPic_NecrozmaDawnWings, 4, 4), }; +#if OW_BATTLE_ONLY_FORMS #if P_ULTRA_BURST_FORMS static const struct SpriteFrameImage sPicTable_NecrozmaUltra[] = { overworld_ascending_frames(gObjectEventPic_NecrozmaUltra, 4, 4), }; -#endif //P_ULTRA_BURST_FORMS +#endif // P_ULTRA_BURST_FORMS +#endif // OW_BATTLE_ONLY_FORMS #endif //P_FUSION_FORMS #endif //P_FAMILY_NECROZMA diff --git a/src/event_object_movement.c b/src/event_object_movement.c index bb546e1fa9..65b25c3faa 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -193,6 +193,7 @@ static void DoShadowFieldEffect(struct ObjectEvent *); static void SetJumpSpriteData(struct Sprite *, u8, u8, u8); static void SetWalkSlowSpriteData(struct Sprite *, u8); static bool8 UpdateWalkSlowAnim(struct Sprite *); +static bool8 UpdateWalkSlowStairs(struct ObjectEvent *objectEvent, struct Sprite *sprite); static u8 DoJumpSpriteMovement(struct Sprite *); static u8 DoJumpSpecialSpriteMovement(struct Sprite *); static void CreateLevitateMovementTask(struct ObjectEvent *); @@ -962,6 +963,13 @@ const u8 gFaceDirectionMovementActions[] = { [DIR_NORTHWEST] = MOVEMENT_ACTION_FACE_LEFT, [DIR_NORTHEAST] = MOVEMENT_ACTION_FACE_RIGHT }; +static const u8 gWalkSlowStairsMovementActions[] = { + [DIR_NONE] = MOVEMENT_ACTION_WALK_SLOW_STAIRS_DOWN, + [DIR_SOUTH] = MOVEMENT_ACTION_WALK_SLOW_STAIRS_DOWN, + [DIR_NORTH] = MOVEMENT_ACTION_WALK_SLOW_STAIRS_UP, + [DIR_WEST] = MOVEMENT_ACTION_WALK_SLOW_STAIRS_LEFT, + [DIR_EAST] = MOVEMENT_ACTION_WALK_SLOW_STAIRS_RIGHT, +}; const u8 gWalkSlowMovementActions[] = { [DIR_NONE] = MOVEMENT_ACTION_WALK_SLOW_DOWN, [DIR_SOUTH] = MOVEMENT_ACTION_WALK_SLOW_DOWN, @@ -5528,13 +5536,13 @@ bool8 FollowablePlayerMovement_Step(struct ObjectEvent *objectEvent, struct Spri direction = GetDirectionToFace(x, y, targetX, targetY); // During a script, if player sidesteps or backsteps, // mirror player's direction instead - if (ArePlayerFieldControlsLocked() - && gObjectEvents[gPlayerAvatar.objectEventId].facingDirection != gObjectEvents[gPlayerAvatar.objectEventId].movementDirection) + if (ArePlayerFieldControlsLocked() && + gObjectEvents[gPlayerAvatar.objectEventId].facingDirection != gObjectEvents[gPlayerAvatar.objectEventId].movementDirection) { direction = gObjectEvents[gPlayerAvatar.objectEventId].movementDirection; objectEvent->facingDirectionLocked = TRUE; } - + MoveCoords(direction, &x, &y); GetCollisionAtCoords(objectEvent, x, y, direction); // Sets directionOverwrite for stairs if (GetLedgeJumpDirection(x, y, direction) != DIR_NONE) @@ -5542,12 +5550,12 @@ bool8 FollowablePlayerMovement_Step(struct ObjectEvent *objectEvent, struct Spri // InitJumpRegular will set the proper speed ObjectEventSetSingleMovement(objectEvent, sprite, GetJump2MovementAction(direction)); } - else if (playerAction >= MOVEMENT_ACTION_WALK_SLOW_DOWN && playerAction <= MOVEMENT_ACTION_WALK_SLOW_RIGHT) + else if (playerAction >= MOVEMENT_ACTION_WALK_SLOW_STAIRS_DOWN && playerAction <= MOVEMENT_ACTION_WALK_SLOW_STAIRS_RIGHT) { if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_DASH)) // on sideways stairs objectEvent->movementActionId = GetWalkNormalMovementAction(direction); else - ObjectEventSetSingleMovement(objectEvent, sprite, GetWalkSlowMovementAction(direction)); + ObjectEventSetSingleMovement(objectEvent, sprite, GetWalkSlowStairsMovementAction(direction)); } else if (PlayerGetCopyableMovement() == COPY_MOVE_JUMP2) { @@ -6399,13 +6407,13 @@ static u8 TryUpdateMovementActionOnStairs(struct ObjectEvent *objectEvent, u8 mo switch (movementActionId) { case MOVEMENT_ACTION_WALK_NORMAL_DOWN: - return MOVEMENT_ACTION_WALK_SLOW_DOWN; + return MOVEMENT_ACTION_WALK_SLOW_STAIRS_DOWN; case MOVEMENT_ACTION_WALK_NORMAL_UP: - return MOVEMENT_ACTION_WALK_SLOW_UP; + return MOVEMENT_ACTION_WALK_SLOW_STAIRS_UP; case MOVEMENT_ACTION_WALK_NORMAL_LEFT: - return MOVEMENT_ACTION_WALK_SLOW_LEFT; + return MOVEMENT_ACTION_WALK_SLOW_STAIRS_LEFT; case MOVEMENT_ACTION_WALK_NORMAL_RIGHT: - return MOVEMENT_ACTION_WALK_SLOW_RIGHT; + return MOVEMENT_ACTION_WALK_SLOW_STAIRS_RIGHT; default: return movementActionId; } @@ -6534,6 +6542,7 @@ u8 name(u32 idx)\ } dirn_to_anim(GetFaceDirectionMovementAction, gFaceDirectionMovementActions); +dirn_to_anim(GetWalkSlowStairsMovementAction, gWalkSlowStairsMovementActions); dirn_to_anim(GetWalkSlowMovementAction, gWalkSlowMovementActions); dirn_to_anim(GetPlayerRunSlowMovementAction, gRunSlowMovementActions); dirn_to_anim(GetWalkNormalMovementAction, gWalkNormalMovementActions); @@ -10318,6 +10327,22 @@ static bool8 UpdateWalkSlowAnim(struct Sprite *sprite) return FALSE; } +bool8 UpdateWalkSlowStairsAnim(struct Sprite *sprite) +{ + if (++sprite->sTimer < 3) + { + Step1(sprite, sprite->sDirection); + sprite->sNumSteps++; + } + else + sprite->sTimer = 0; + + if (sprite->sNumSteps > 15) + return TRUE; + else + return FALSE; +} + #undef sTimer #undef sNumSteps @@ -11075,6 +11100,88 @@ bool8 MovementActionFunc_RunSlow_Step1(struct ObjectEvent *objectEvent, struct S return FALSE; } +static bool8 UpdateWalkSlowStairs(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + if (UpdateWalkSlowStairsAnim(sprite)) + { + ShiftStillObjectEventCoords(objectEvent); + objectEvent->triggerGroundEffectsOnStop = TRUE; + sprite->animPaused = TRUE; + return TRUE; + } + return FALSE; +} + +bool8 MovementAction_WalkSlowStairsUp_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + InitWalkSlow(objectEvent, sprite, DIR_NORTH); + return MovementAction_WalkSlowStairsUp_Step1(objectEvent, sprite); +} + +bool8 MovementAction_WalkSlowStairsUp_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + if (UpdateWalkSlowStairs(objectEvent, sprite)) + { + sprite->data[2] = 2; + return TRUE; + } + return FALSE; +} + +bool8 MovementAction_WalkSlowStairsDown_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + InitWalkSlow(objectEvent, sprite, DIR_SOUTH); + return MovementAction_WalkSlowStairsDown_Step1(objectEvent, sprite); +} + +bool8 MovementAction_WalkSlowStairsDown_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + if (UpdateWalkSlowStairs(objectEvent, sprite)) + { + sprite->data[2] = 2; + return TRUE; + } + return FALSE; +} + +bool8 MovementAction_WalkSlowStairsLeft_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + if (objectEvent->directionOverwrite) + InitWalkSlow(objectEvent, sprite, objectEvent->directionOverwrite); + else + InitWalkSlow(objectEvent, sprite, DIR_WEST); + return MovementAction_WalkSlowStairsLeft_Step1(objectEvent, sprite); +} + +bool8 MovementAction_WalkSlowStairsLeft_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + if (UpdateWalkSlowStairs(objectEvent, sprite)) + { + sprite->data[2] = 2; + return TRUE; + } + return FALSE; +} + +bool8 MovementAction_WalkSlowStairsRight_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + if (objectEvent->directionOverwrite) + InitWalkSlow(objectEvent, sprite, objectEvent->directionOverwrite); + else + InitWalkSlow(objectEvent, sprite, DIR_EAST); + return MovementAction_WalkSlowStairsRight_Step1(objectEvent, sprite); +} + +bool8 MovementAction_WalkSlowStairsRight_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + if (UpdateWalkSlowStairs(objectEvent, sprite)) + { + sprite->data[2] = 2; + return TRUE; + } + return FALSE; +} + static u16 GetGraphicsIdForMon(u32 species, bool32 shiny, bool32 female) { u16 graphicsId = species + OBJ_EVENT_MON; diff --git a/src/field_control_avatar.c b/src/field_control_avatar.c index a9be5b55a0..ecf78be0bb 100644 --- a/src/field_control_avatar.c +++ b/src/field_control_avatar.c @@ -497,6 +497,20 @@ static const u8 *GetInteractedMetatileScript(struct MapPosition *position, u8 me return EventScript_Questionnaire; if (MetatileBehavior_IsTrainerHillTimer(metatileBehavior) == TRUE) return EventScript_TrainerHillTimer; + if (MetatileBehavior_IsPokeMartSign(metatileBehavior) == TRUE) + { + if(direction != DIR_NORTH) + return NULL; + SetMsgSignPostAndVarFacing(direction); + return Common_EventScript_ShowPokemartSign; + } + if (MetatileBehavior_IsPokemonCenterSign(metatileBehavior) == TRUE) + { + if(direction != DIR_NORTH) + return NULL; + SetMsgSignPostAndVarFacing(direction); + return Common_EventScript_ShowPokemonCenterSign; + } elevation = position->elevation; if (elevation == MapGridGetElevationAt(position->x, position->y)) diff --git a/src/field_player_avatar.c b/src/field_player_avatar.c index e9cd3149f7..674fb7eddb 100644 --- a/src/field_player_avatar.c +++ b/src/field_player_avatar.c @@ -93,7 +93,8 @@ static bool8 PlayerAnimIsMultiFrameStationaryAndStateNotTurning(void); static bool8 PlayerIsAnimActive(void); static bool8 PlayerCheckIfAnimFinishedOrInactive(void); -static void PlayerWalkSlow(u8 direction); +static void PlayerWalkSlowStairs(u8 direction); +static void UNUSED PlayerWalkSlow(u8 direction); static void PlayerRunSlow(u8 direction); static void PlayerRun(u8); static void PlayerNotOnBikeCollide(u8); @@ -701,7 +702,7 @@ static void PlayerNotOnBikeMoving(u8 direction, u16 heldKeys) else { if (ObjectMovingOnRockStairs(&gObjectEvents[gPlayerAvatar.objectEventId], direction)) - PlayerWalkSlow(direction); + PlayerWalkSlowStairs(direction); else PlayerWalkNormal(direction); } @@ -1016,8 +1017,14 @@ void PlayerSetAnimId(u8 movementActionId, u8 copyableMovement) } } +// slow stairs (from FRLG--faster than slow) +static void PlayerWalkSlowStairs(u8 direction) +{ + PlayerSetAnimId(GetWalkSlowStairsMovementAction(direction), 2); +} + // slow -static void PlayerWalkSlow(u8 direction) +static void UNUSED PlayerWalkSlow(u8 direction) { PlayerSetAnimId(GetWalkSlowMovementAction(direction), 2); } diff --git a/src/party_menu.c b/src/party_menu.c index 5e79d74d45..9a74a466e1 100644 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -6182,6 +6182,27 @@ bool32 TryItemUseFusionChange(u8 taskId, TaskFunc task) } } +static void RestoreFusionMon(struct Pokemon *mon) +{ + s32 i; + + for (i = 0; i < PARTY_SIZE; i++) + { + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL) == SPECIES_NONE) + break; + } + + if (i >= PARTY_SIZE) + { + CopyMonToPC(mon); + } + else + { + CopyMon(&gPlayerParty[i], mon, sizeof(*mon)); + gPlayerPartyCount = i + 1; + } +} + static void Task_TryItemUseFusionChange(u8 taskId) { struct Pokemon *mon = &gPlayerParty[gTasks[taskId].firstFusionSlot]; @@ -6202,7 +6223,7 @@ static void Task_TryItemUseFusionChange(u8 taskId) else { mon2 = &gPokemonStoragePtr->fusions[gTasks[taskId].storageIndex]; - GiveMonToPlayer(mon2); + RestoreFusionMon(mon2); ZeroMonData(&gPokemonStoragePtr->fusions[gTasks[taskId].storageIndex]); } targetSpecies = gTasks[taskId].tTargetSpecies; diff --git a/test/battle/ability/dazzling.c b/test/battle/ability/dazzling.c index cc77e9a3bd..e248c9ce0b 100644 --- a/test/battle/ability/dazzling.c +++ b/test/battle/ability/dazzling.c @@ -50,3 +50,25 @@ DOUBLE_BATTLE_TEST("Dazzling, Queenly Majesty and Armor Tail protect users partn MESSAGE("Wobbuffet cannot use Quick Attack!"); } } + +DOUBLE_BATTLE_TEST("Dazzling, Queenly Majesty and Armor Tail don't protect the user from negative priority") +{ + u32 species, ability; + + PARAMETRIZE { species = SPECIES_BRUXISH; ability = ABILITY_DAZZLING; } + PARAMETRIZE { species = SPECIES_FARIGIRAF; ability = ABILITY_ARMOR_TAIL; } + PARAMETRIZE { species = SPECIES_TSAREENA; ability = ABILITY_QUEENLY_MAJESTY; } + + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(species) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_AVALANCHE, target: opponentLeft); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_AVALANCHE, playerLeft); + NOT ABILITY_POPUP(opponentLeft, ability); + } +} + diff --git a/test/battle/ability/forecast.c b/test/battle/ability/forecast.c index dae5326fd5..c462a3a634 100644 --- a/test/battle/ability/forecast.c +++ b/test/battle/ability/forecast.c @@ -110,10 +110,10 @@ DOUBLE_BATTLE_TEST("Forecast transforms all Castforms present in weather") PARAMETRIZE { move = MOVE_HAIL; } PARAMETRIZE { move = MOVE_SNOWSCAPE; } GIVEN { - PLAYER(SPECIES_CASTFORM_NORMAL) { Ability(ABILITY_FORECAST); } - PLAYER(SPECIES_CASTFORM_NORMAL) { Ability(ABILITY_FORECAST); } - OPPONENT(SPECIES_CASTFORM_NORMAL) { Ability(ABILITY_FORECAST); } - OPPONENT(SPECIES_CASTFORM_NORMAL) { Ability(ABILITY_FORECAST); } + PLAYER(SPECIES_CASTFORM_NORMAL) { Ability(ABILITY_FORECAST); Speed(10); } + PLAYER(SPECIES_CASTFORM_NORMAL) { Ability(ABILITY_FORECAST); Speed(5); } + OPPONENT(SPECIES_CASTFORM_NORMAL) { Ability(ABILITY_FORECAST); Speed(7); } + OPPONENT(SPECIES_CASTFORM_NORMAL) { Ability(ABILITY_FORECAST); Speed(1); } } WHEN { TURN { MOVE(playerRight, move); } } SCENE { diff --git a/test/battle/ability/neutralizing_gas.c b/test/battle/ability/neutralizing_gas.c new file mode 100644 index 0000000000..ef83483d32 --- /dev/null +++ b/test/battle/ability/neutralizing_gas.c @@ -0,0 +1,273 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Neutralizing Gas activates on switch-in") +{ + GIVEN { + PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { } + } SCENE { + ABILITY_POPUP(player, ABILITY_NEUTRALIZING_GAS); + MESSAGE("Neutralizing gas filled the area!"); + } +} + +SINGLE_BATTLE_TEST("Neutralizing Gas prevents opponent's switch-in ability from activating") +{ + GIVEN { + PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); } + OPPONENT(SPECIES_ZEKROM) { Ability(ABILITY_TERAVOLT); } + } WHEN { + TURN { } + } SCENE { + ABILITY_POPUP(player, ABILITY_NEUTRALIZING_GAS); + NONE_OF { + ABILITY_POPUP(opponent, ABILITY_TERAVOLT); + MESSAGE("The opposing Zekrom is radiating a bursting aura!"); + } + } +} + +DOUBLE_BATTLE_TEST("Neutralizing Gas prevents ally's switch-in ability from activating") +{ + GIVEN { + PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); } + PLAYER(SPECIES_ZEKROM) { Ability(ABILITY_TERAVOLT); } + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { } + } SCENE { + ABILITY_POPUP(playerLeft, ABILITY_NEUTRALIZING_GAS); + NONE_OF { + ABILITY_POPUP(playerRight, ABILITY_TERAVOLT); + MESSAGE("Zekrom is radiating a bursting aura!"); + } + } +} + +DOUBLE_BATTLE_TEST("Neutralizing Gas ignores all battlers' ability effects") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY); + PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); } + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); } + OPPONENT(SPECIES_LANTURN) { Ability(ABILITY_WATER_ABSORB); } + OPPONENT(SPECIES_BELLIBOLT) { Ability(ABILITY_ELECTROMORPHOSIS); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_SURF); MOVE(playerRight, MOVE_SURF); } + } SCENE { + ABILITY_POPUP(playerLeft, ABILITY_NEUTRALIZING_GAS); + MESSAGE("Neutralizing gas filled the area!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SURF, playerLeft); + NONE_OF { + ABILITY_POPUP(playerRight, ABILITY_TELEPATHY); + ABILITY_POPUP(opponentLeft, ABILITY_WATER_ABSORB); + ABILITY_POPUP(opponentRight, ABILITY_ELECTROMORPHOSIS); + } + HP_BAR(opponentLeft); + HP_BAR(playerRight); + HP_BAR(opponentRight); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SURF, playerRight); + NONE_OF { + ABILITY_POPUP(opponentLeft, ABILITY_WATER_ABSORB); + ABILITY_POPUP(opponentRight, ABILITY_ELECTROMORPHOSIS); + } + HP_BAR(playerLeft); + HP_BAR(opponentLeft); + HP_BAR(opponentRight); + } +} + +SINGLE_BATTLE_TEST("Neutralizing Gas ignores multipliers from attacker's ability", s16 damage) +{ + u32 ability; + PARAMETRIZE { ability = ABILITY_NEUTRALIZING_GAS; } + PARAMETRIZE { ability = ABILITY_LEVITATE; } + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + PLAYER(SPECIES_WEEZING) { Ability(ability); } + OPPONENT(SPECIES_AZUMARILL) { Ability(ABILITY_HUGE_POWER); } + } WHEN { + TURN { MOVE(opponent, MOVE_TACKLE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); + HP_BAR(player, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[1].damage); + } +} + +SINGLE_BATTLE_TEST("Neutralizing Gas ignores multipliers from target's ability", s16 damage) +{ + u32 ability; + PARAMETRIZE { ability = ABILITY_NEUTRALIZING_GAS; } + PARAMETRIZE { ability = ABILITY_LEVITATE; } + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].makesContact == TRUE); + ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL); + PLAYER(SPECIES_WEEZING) { Ability(ability); } + OPPONENT(SPECIES_BEWEAR) { Ability(ABILITY_FLUFFY); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, Q_4_12(0.5), results[1].damage); + } +} + +DOUBLE_BATTLE_TEST("Neutralizing Gas ignores multipliers from target's ally's ability", s16 damage) +{ + u32 ability; + PARAMETRIZE { ability = ABILITY_NEUTRALIZING_GAS; } + PARAMETRIZE { ability = ABILITY_LEVITATE; } + GIVEN { + PLAYER(SPECIES_WEEZING) { Ability(ability); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); } + OPPONENT(SPECIES_CLEFAIRY) { Ability(ABILITY_FRIEND_GUARD); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_TACKLE, target: opponentLeft); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerLeft); + HP_BAR(opponentLeft, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, Q_4_12(0.75), results[1].damage); + } +} + +DOUBLE_BATTLE_TEST("Neutralizing Gas ignores multipliers from ally's ability", s16 damage) +{ + u32 ability; + PARAMETRIZE { ability = ABILITY_NEUTRALIZING_GAS; } + PARAMETRIZE { ability = ABILITY_LEVITATE; } + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + PLAYER(SPECIES_WEEZING) { Ability(ability); } + PLAYER(SPECIES_WO_CHIEN) { Ability(ABILITY_TABLETS_OF_RUIN); } + OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_TACKLE, target: opponentLeft); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerLeft); + HP_BAR(opponentLeft, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, Q_4_12(0.75), results[1].damage); + } +} + +DOUBLE_BATTLE_TEST("Neutralizing Gas leaving the field allows abilities to activate in turn order") +{ + u32 speedPlayerRight, speedOppLeft, speedOppRight; + PARAMETRIZE { speedPlayerRight = 5; speedOppLeft = 3; speedOppRight = 2; } + PARAMETRIZE { speedPlayerRight = 3; speedOppLeft = 5; speedOppRight = 2; } + PARAMETRIZE { speedPlayerRight = 2; speedOppLeft = 3; speedOppRight = 5; } + PARAMETRIZE { speedPlayerRight = 3; speedOppLeft = 2; speedOppRight = 5; } + PARAMETRIZE { speedPlayerRight = 2; speedOppLeft = 5; speedOppRight = 3; } + PARAMETRIZE { speedPlayerRight = 5; speedOppLeft = 2; speedOppRight = 3; } + GIVEN { + PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); Speed(4); } + PLAYER(SPECIES_ZACIAN) { Ability(ABILITY_INTREPID_SWORD); Speed(speedPlayerRight); } + PLAYER(SPECIES_WOBBUFFET) { Speed(4); } + OPPONENT(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); Speed(speedOppLeft); } + OPPONENT(SPECIES_ZEKROM) { Ability(ABILITY_TERAVOLT); Speed(speedOppRight); } + } WHEN { + TURN { SWITCH(playerLeft, 2); } + } SCENE { + ABILITY_POPUP(playerLeft, ABILITY_NEUTRALIZING_GAS); + MESSAGE("Neutralizing gas filled the area!"); + SWITCH_OUT_MESSAGE("Weezing"); + MESSAGE("The effects of the neutralizing gas wore off!"); + if (speedPlayerRight > speedOppLeft) + { + if (speedPlayerRight > speedOppRight) { + ABILITY_POPUP(playerRight, ABILITY_INTREPID_SWORD); + if (speedOppRight > speedOppLeft) { + ABILITY_POPUP(opponentRight, ABILITY_TERAVOLT); + ABILITY_POPUP(opponentLeft, ABILITY_INTIMIDATE); + } else { + ABILITY_POPUP(opponentLeft, ABILITY_INTIMIDATE); + ABILITY_POPUP(opponentRight, ABILITY_TERAVOLT); + } + } else { + ABILITY_POPUP(opponentRight, ABILITY_TERAVOLT); + ABILITY_POPUP(playerRight, ABILITY_INTREPID_SWORD); + ABILITY_POPUP(opponentLeft, ABILITY_INTIMIDATE); + } + + } else { + if (speedOppLeft > speedOppRight) { + ABILITY_POPUP(opponentLeft, ABILITY_INTIMIDATE); + if (speedOppRight > speedPlayerRight) { + ABILITY_POPUP(opponentRight, ABILITY_TERAVOLT); + ABILITY_POPUP(playerRight, ABILITY_INTREPID_SWORD); + } else { + ABILITY_POPUP(playerRight, ABILITY_INTREPID_SWORD); + ABILITY_POPUP(opponentRight, ABILITY_TERAVOLT); + } + } else { + ABILITY_POPUP(opponentRight, ABILITY_TERAVOLT); + ABILITY_POPUP(opponentLeft, ABILITY_INTIMIDATE); + ABILITY_POPUP(playerRight, ABILITY_INTREPID_SWORD); + } + } + SEND_IN_MESSAGE("Wobbuffet"); + } +} + +SINGLE_BATTLE_TEST("Neutralizing Gas prevents Insomnia from blocking Rest") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST); + PLAYER(SPECIES_DROWZEE) { Ability(ABILITY_INSOMNIA); HP(1); } + OPPONENT(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); } + } WHEN { + TURN { MOVE(player, MOVE_REST); } + } SCENE { + NOT ABILITY_POPUP(player, ABILITY_INSOMNIA); + // ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + // STATUS_ICON(player, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_REST, player); + HP_BAR(player); + } +} + +SINGLE_BATTLE_TEST("Neutralizing Gas prevents Trace from copying it") +{ + GIVEN { + PLAYER(SPECIES_RALTS) { Ability(ABILITY_TRACE); } + OPPONENT(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); } + } WHEN { + TURN { } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_NEUTRALIZING_GAS); + NONE_OF { + ABILITY_POPUP(player, ABILITY_TRACE); + ABILITY_POPUP(player, ABILITY_NEUTRALIZING_GAS); + } + } +} + +SINGLE_BATTLE_TEST("Neutralizing Gas prevents Contrary inverting stat boosts") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST); + PLAYER(SPECIES_INKAY) { Ability(ABILITY_CONTRARY); } + OPPONENT(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); } + } WHEN { + TURN { MOVE(player, MOVE_SWORDS_DANCE); MOVE(opponent, MOVE_LEER); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SWORDS_DANCE, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_LEER, opponent); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + } THEN { + EXPECT_GT(player->statStages[STAT_ATK], DEFAULT_STAT_STAGE); + EXPECT_LT(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE); + } +} diff --git a/test/battle/ability/parental_bond.c b/test/battle/ability/parental_bond.c index 40f70252f9..9bd6570490 100644 --- a/test/battle/ability/parental_bond.c +++ b/test/battle/ability/parental_bond.c @@ -318,6 +318,40 @@ SINGLE_BATTLE_TEST("Parental Bond only triggers Dragon Tail's target switch out } } +SINGLE_BATTLE_TEST("Parental Bond does not trigger on semi-invulnerable moves") +{ + GIVEN { + ASSUME(GetMoveCategory(MOVE_FLY) != DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveStrikeCount(MOVE_FLY) < 2); + ASSUME(GetMoveEffect(MOVE_FLY) == EFFECT_SEMI_INVULNERABLE); + PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_FLY, gimmick: GIMMICK_MEGA); MOVE(opponent, MOVE_CELEBRATE); } + TURN { SKIP_TURN(player); } + } SCENE { + HP_BAR(opponent); + NOT HP_BAR(opponent); + } +} + +SINGLE_BATTLE_TEST("Parental Bond does not trigger on two turn attacks") +{ + GIVEN { + ASSUME(GetMoveCategory(MOVE_RAZOR_WIND) != DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveStrikeCount(MOVE_RAZOR_WIND) < 2); + ASSUME(GetMoveEffect(MOVE_RAZOR_WIND) == EFFECT_TWO_TURNS_ATTACK); + PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_RAZOR_WIND, gimmick: GIMMICK_MEGA); MOVE(opponent, MOVE_CELEBRATE); } + TURN { SKIP_TURN(player); } + } SCENE { + HP_BAR(opponent); + NOT HP_BAR(opponent); + } +} + TO_DO_BATTLE_TEST("Parental Bond tests"); // Temporary TODO: Convert Bulbapedia description into tests. diff --git a/test/battle/ai/ai.c b/test/battle/ai/ai.c index cc9582a4bd..783c951d1c 100644 --- a/test/battle/ai/ai.c +++ b/test/battle/ai/ai.c @@ -883,4 +883,19 @@ AI_SINGLE_BATTLE_TEST("AI score for Mean Look will be decreased if target can es } WHEN { TURN { SCORE_EQ_VAL(opponent, MOVE_MEAN_LOOK, 90); } } -} \ No newline at end of file +} + +AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI considers Focus Sash when determining if it should switch out") +{ + GIVEN { + ASSUME(gItemsInfo[ITEM_FOCUS_SASH].holdEffect == HOLD_EFFECT_FOCUS_SASH); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_SMART_SWITCHING | AI_FLAG_OMNISCIENT); + PLAYER(SPECIES_BEAUTIFLY) { Speed(10); Moves(MOVE_AIR_SLASH); } + OPPONENT(SPECIES_CACNEA) { Speed(1); Moves(MOVE_TACKLE); } + OPPONENT(SPECIES_COMBUSKEN) { Speed(1); Moves(MOVE_FLAMETHROWER); Item(ITEM_FOCUS_SASH); } + OPPONENT(SPECIES_CROBAT) { Speed(11); Moves(MOVE_SLUDGE); } + } WHEN { + TURN { MOVE(player, MOVE_AIR_SLASH); EXPECT_MOVE(opponent, MOVE_TACKLE); EXPECT_SEND_OUT(opponent, 1); } + TURN { MOVE(player, MOVE_AIR_SLASH); EXPECT_MOVE(opponent, MOVE_FLAMETHROWER); } + } +} diff --git a/test/battle/gimmick/dynamax.c b/test/battle/gimmick/dynamax.c index 809e0f65d3..791973f893 100644 --- a/test/battle/gimmick/dynamax.c +++ b/test/battle/gimmick/dynamax.c @@ -2,7 +2,7 @@ #include "test/battle.h" // ============= DYNAMAX AND MAX MOVE INTERACTIONS =================== -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax increases HP and max HP by 1.5x", u16 hp) +SINGLE_BATTLE_TEST("Dynamax: Dynamax increases HP and max HP by 1.5x", u16 hp) { u32 dynamax; PARAMETRIZE { dynamax = GIMMICK_NONE; } @@ -25,7 +25,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax increases HP and max HP by 1.5x", u16 hp) } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax Level increases HP and max HP multipliers by 0.05 for each level", u16 hp) +SINGLE_BATTLE_TEST("Dynamax: Dynamax Level increases HP and max HP multipliers by 0.05 for each level", u16 hp) { u32 dynamax, level; PARAMETRIZE { dynamax = GIMMICK_NONE; level = 0; } @@ -68,7 +68,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax Level increases HP and max HP multipliers } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax expires after three turns", u16 hp) +SINGLE_BATTLE_TEST("Dynamax: Dynamax expires after three turns", u16 hp) { u32 dynamax; PARAMETRIZE { dynamax = GIMMICK_NONE; } @@ -98,7 +98,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax expires after three turns", u16 hp) } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax expires after three turns and correctly converts HP according to Dynamax Level") +SINGLE_BATTLE_TEST("Dynamax: Dynamax expires after three turns and correctly converts HP according to Dynamax Level") { u32 dynamaxLevel, dynamax; u16 capturedHP, finalHP; @@ -141,7 +141,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax expires after three turns and correctly co } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be flinched") +SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon cannot be flinched") { GIVEN { ASSUME(GetMoveEffect(MOVE_FAKE_OUT) == EFFECT_FIRST_TURN_ONLY); @@ -156,7 +156,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be flinched") } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be hit by weight-based moves") +SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon cannot be hit by weight-based moves") { GIVEN { ASSUME(GetMoveEffect(MOVE_HEAVY_SLAM) == EFFECT_HEAT_CRASH); @@ -172,7 +172,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be hit by weight-based mo } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be hit by OHKO moves") +SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon cannot be hit by OHKO moves") { GIVEN { ASSUME(GetMoveEffect(MOVE_FISSURE) == EFFECT_OHKO); @@ -188,7 +188,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be hit by OHKO moves") } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are affected by Grudge") +SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon are affected by Grudge") { GIVEN { PLAYER(SPECIES_WOBBUFFET) { Speed(50); }; @@ -203,7 +203,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are affected by Grudge") } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by phazing moves, but still take damage") +SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon are not affected by phazing moves, but still take damage") { GIVEN { ASSUME(GetMoveEffect(MOVE_DRAGON_TAIL) == EFFECT_HIT_SWITCH_TARGET); @@ -225,7 +225,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by phazing move } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by phazing moves but no block message is printed if they faint") +SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon are not affected by phazing moves but no block message is printed if they faint") { GIVEN { ASSUME(GetMoveEffect(MOVE_DRAGON_TAIL) == EFFECT_HIT_SWITCH_TARGET); @@ -243,7 +243,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by phazing move } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by Red Card") +SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon are not affected by Red Card") { GIVEN { ASSUME(gItemsInfo[ITEM_RED_CARD].holdEffect == HOLD_EFFECT_RED_CARD); @@ -262,7 +262,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by Red Card") } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can be switched out by Eject Button") +SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon can be switched out by Eject Button") { GIVEN { ASSUME(gItemsInfo[ITEM_EJECT_BUTTON].holdEffect == HOLD_EFFECT_EJECT_BUTTON); @@ -281,7 +281,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can be switched out by Eject But } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot have their ability swapped to another Pokemon's") +SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon cannot have their ability swapped to another Pokemon's") { GIVEN { PLAYER(SPECIES_MILTANK) { Ability(ABILITY_SCRAPPY); } @@ -297,7 +297,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot have their ability swappe } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can have their ability changed or suppressed") +SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon can have their ability changed or suppressed") { GIVEN { PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_SHADOW_TAG); } @@ -314,7 +314,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can have their ability changed o } // Max Moves don't make contact, so Cursed Body doesn't need to be tested, but it is coded for. -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon's Max Moves cannot be disabled") +SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon's Max Moves cannot be disabled") { GIVEN { PLAYER(SPECIES_WOBBUFFET); @@ -328,7 +328,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon's Max Moves cannot be disabled") } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can have base moves disabled on their first turn") +SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon can have base moves disabled on their first turn") { GIVEN { ASSUME(B_DISABLE_TURNS >= GEN_5); @@ -349,7 +349,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can have base moves disabled on } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are immune to Torment") +SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon are immune to Torment") { GIVEN { PLAYER(SPECIES_WOBBUFFET); @@ -364,7 +364,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are immune to Torment") } // This is true for all item-removing moves. -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not immune to Knock Off") +SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon are not immune to Knock Off") { GIVEN { PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_POTION); } @@ -380,7 +380,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not immune to Knock Off") } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon lose their substitutes") +SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon lose their substitutes") { GIVEN { PLAYER(SPECIES_WOBBUFFET); @@ -397,7 +397,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon lose their substitutes") } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon that changes forms does not gain HP") +SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon that changes forms does not gain HP") { u16 capturedHP, finalHP; GIVEN { @@ -418,7 +418,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon that changes forms does not gain } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon that changes forms does not gain HP unless the new form gains Max HP") +SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon that changes forms does not gain HP unless the new form gains Max HP") { u32 hp = 1, maxHP = 200; u32 species; @@ -438,7 +438,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon that changes forms does not gain } } -SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves deal 1/4 damage through protect", s16 damage) +SINGLE_BATTLE_TEST("Dynamax: Max Moves deal 1/4 damage through protect", s16 damage) { bool32 protected; PARAMETRIZE { protected = TRUE; } @@ -458,7 +458,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves deal 1/4 damage through protect", s16 da } } -SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves don't bypass Max Guard") +SINGLE_BATTLE_TEST("Dynamax: Max Moves don't bypass Max Guard") { GIVEN { PLAYER(SPECIES_WOBBUFFET); @@ -470,7 +470,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves don't bypass Max Guard") } } -DOUBLE_BATTLE_TEST("(DYNAMAX) Feint bypasses Max Guard but doesn't break it") +DOUBLE_BATTLE_TEST("Dynamax: Feint bypasses Max Guard but doesn't break it") { GIVEN { PLAYER(SPECIES_WOBBUFFET); @@ -491,7 +491,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) Feint bypasses Max Guard but doesn't break it") } } -DOUBLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are immune to Instruct") +DOUBLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon are immune to Instruct") { GIVEN { PLAYER(SPECIES_WOBBUFFET); @@ -509,7 +509,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are immune to Instruct") } } -SINGLE_BATTLE_TEST("(DYNAMAX) Pokemon with Gigantamax forms change upon Dynamaxing") +SINGLE_BATTLE_TEST("Dynamax: Pokemon with Gigantamax forms change upon Dynamaxing") { u32 species; bool32 gigantamaxFactor; @@ -525,7 +525,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Pokemon with Gigantamax forms change upon Dynamaxi } } -SINGLE_BATTLE_TEST("(DYNAMAX) Pokemon with Gigantamax forms revert upon switching") +SINGLE_BATTLE_TEST("Dynamax: Pokemon with Gigantamax forms revert upon switching") { GIVEN { PLAYER(SPECIES_VENUSAUR); @@ -540,7 +540,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Pokemon with Gigantamax forms revert upon switchin } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by Choice items", s16 damage) +SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon are not affected by Choice items", s16 damage) { u16 item; PARAMETRIZE { item = ITEM_CHOICE_BAND; } @@ -561,7 +561,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by Choice items } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot use Max Guard while holding Assault Vest") +SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon cannot use Max Guard while holding Assault Vest") { GIVEN { ASSUME(gItemsInfo[ITEM_ASSAULT_VEST].holdEffect == HOLD_EFFECT_ASSAULT_VEST); @@ -582,7 +582,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot use Max Guard while holdi // Anything that is conditional based off max HP still uses gBattleMons[battler].maxHP. // Below are some tests, but very far from all encompassing: -SINGLE_BATTLE_TEST("(DYNAMAX) Endeavor uses a Pokemon's non-Dynamax HP", s16 damage) +SINGLE_BATTLE_TEST("Dynamax: Endeavor uses a Pokemon's non-Dynamax HP", s16 damage) { u32 dynamax; PARAMETRIZE { dynamax = GIMMICK_NONE; } @@ -601,7 +601,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Endeavor uses a Pokemon's non-Dynamax HP", s16 dam } } -SINGLE_BATTLE_TEST("(DYNAMAX) Super Fang uses a Pokemon's non-Dynamax HP", s16 damage) +SINGLE_BATTLE_TEST("Dynamax: Super Fang uses a Pokemon's non-Dynamax HP", s16 damage) { u32 dynamax; PARAMETRIZE { dynamax = GIMMICK_NONE; } @@ -620,7 +620,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Super Fang uses a Pokemon's non-Dynamax HP", s16 d } } -SINGLE_BATTLE_TEST("(DYNAMAX) Pain Split uses a Pokemon's non-Dynamax HP", s16 damage) +SINGLE_BATTLE_TEST("Dynamax: Pain Split uses a Pokemon's non-Dynamax HP", s16 damage) { u32 dynamax; PARAMETRIZE { dynamax = GIMMICK_NONE; } @@ -639,7 +639,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Pain Split uses a Pokemon's non-Dynamax HP", s16 d } } -SINGLE_BATTLE_TEST("(DYNAMAX) Sitrus Berries heal based on a Pokemon's non-Dynamax HP", s16 damage) +SINGLE_BATTLE_TEST("Dynamax: Sitrus Berries heal based on a Pokemon's non-Dynamax HP", s16 damage) { u32 dynamax; PARAMETRIZE { dynamax = GIMMICK_NONE; } @@ -659,7 +659,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Sitrus Berries heal based on a Pokemon's non-Dynam } } -SINGLE_BATTLE_TEST("(DYNAMAX) Heal Pulse heals based on a Pokemon's non-Dynamax HP", s16 damage) +SINGLE_BATTLE_TEST("Dynamax: Heal Pulse heals based on a Pokemon's non-Dynamax HP", s16 damage) { u32 dynamax; PARAMETRIZE { dynamax = GIMMICK_NONE; } @@ -679,7 +679,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Heal Pulse heals based on a Pokemon's non-Dynamax } // ============= MAX MOVE EFFECTS ========================================== -SINGLE_BATTLE_TEST("(DYNAMAX) Max Strike lowers single opponent's speed") +SINGLE_BATTLE_TEST("Dynamax: Max Strike lowers single opponent's speed") { GIVEN { // Fails?: ASSUME(GetMaxMove(B_POSITION_PLAYER_LEFT, MOVE_TACKLE) == MOVE_MAX_STRIKE); @@ -704,7 +704,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Strike lowers single opponent's speed") } // This test should apply to all stat-lowering Max Moves, including G-Max Foam Burst and G-Max Tartness. -DOUBLE_BATTLE_TEST("(DYNAMAX) Max Strike lowers both opponents' speed") +DOUBLE_BATTLE_TEST("Dynamax: Max Strike lowers both opponents' speed") { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_MAX_STRIKE, MOVE_EFFECT_LOWER_SPEED_SIDE)); @@ -740,7 +740,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) Max Strike lowers both opponents' speed") } // This test should apply to all stat-boosting Max Moves, too. -DOUBLE_BATTLE_TEST("(DYNAMAX) Max Knuckle raises both allies' attack") +DOUBLE_BATTLE_TEST("Dynamax: Max Knuckle raises both allies' attack") { s16 damage[4]; GIVEN { @@ -783,7 +783,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) Max Knuckle raises both allies' attack") } } -SINGLE_BATTLE_TEST("(DYNAMAX) Max Flare sets up sunlight") +SINGLE_BATTLE_TEST("Dynamax: Max Flare sets up sunlight") { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_MAX_FLARE, MOVE_EFFECT_SUN)); @@ -799,7 +799,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Flare sets up sunlight") } } -SINGLE_BATTLE_TEST("(DYNAMAX) Max Geyser sets up heavy rain") +SINGLE_BATTLE_TEST("Dynamax: Max Geyser sets up heavy rain") { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_MAX_GEYSER, MOVE_EFFECT_RAIN)); @@ -815,7 +815,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Geyser sets up heavy rain") } } -SINGLE_BATTLE_TEST("(DYNAMAX) Max Hailstorm sets up hail") +SINGLE_BATTLE_TEST("Dynamax: Max Hailstorm sets up hail") { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_MAX_HAILSTORM, MOVE_EFFECT_HAIL)); @@ -831,7 +831,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Hailstorm sets up hail") } } -SINGLE_BATTLE_TEST("(DYNAMAX) Max Rockfall sets up a sandstorm") +SINGLE_BATTLE_TEST("Dynamax: Max Rockfall sets up a sandstorm") { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_MAX_ROCKFALL, MOVE_EFFECT_SANDSTORM)); @@ -847,7 +847,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Rockfall sets up a sandstorm") } } -SINGLE_BATTLE_TEST("(DYNAMAX) Max Overgrowth sets up Grassy Terrain") +SINGLE_BATTLE_TEST("Dynamax: Max Overgrowth sets up Grassy Terrain") { s32 maxHP = 490; // Because of recalculated stats upon Dynamaxing GIVEN { @@ -868,7 +868,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Overgrowth sets up Grassy Terrain") } } -SINGLE_BATTLE_TEST("(DYNAMAX) Max Mindstorm sets up Psychic Terrain") +SINGLE_BATTLE_TEST("Dynamax: Max Mindstorm sets up Psychic Terrain") { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_MAX_MINDSTORM, MOVE_EFFECT_PSYCHIC_TERRAIN)); @@ -885,7 +885,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Mindstorm sets up Psychic Terrain") } } -SINGLE_BATTLE_TEST("(DYNAMAX) Max Lightning sets up Electric Terrain") +SINGLE_BATTLE_TEST("Dynamax: Max Lightning sets up Electric Terrain") { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_MAX_LIGHTNING, MOVE_EFFECT_ELECTRIC_TERRAIN)); @@ -900,7 +900,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Lightning sets up Electric Terrain") } } -SINGLE_BATTLE_TEST("(DYNAMAX) Max Starfall sets up Misty Terrain") +SINGLE_BATTLE_TEST("Dynamax: Max Starfall sets up Misty Terrain") { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_MAX_STARFALL, MOVE_EFFECT_MISTY_TERRAIN)); @@ -915,7 +915,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Starfall sets up Misty Terrain") } } -SINGLE_BATTLE_TEST("(DYNAMAX) G-Max Stonesurge sets up Stealth Rocks") +SINGLE_BATTLE_TEST("Dynamax: G-Max Stonesurge sets up Stealth Rocks") { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_G_MAX_STONESURGE, MOVE_EFFECT_STEALTH_ROCK)); @@ -935,7 +935,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) G-Max Stonesurge sets up Stealth Rocks") } // The test below also tests that sharp steel does type-based damage and can be Defogged away. -SINGLE_BATTLE_TEST("(DYNAMAX) G-Max Steelsurge sets up sharp steel") +SINGLE_BATTLE_TEST("Dynamax: G-Max Steelsurge sets up sharp steel") { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_G_MAX_STEELSURGE, MOVE_EFFECT_STEELSURGE)); @@ -963,7 +963,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) G-Max Steelsurge sets up sharp steel") } // The test below should apply to G-Max Fireball and G-Max Drum Solo, too. -SINGLE_BATTLE_TEST("(DYNAMAX) G-Max Hydrosnipe has fixed power and ignores abilities", s16 damage) +SINGLE_BATTLE_TEST("Dynamax: G-Max Hydrosnipe has fixed power and ignores abilities", s16 damage) { u16 move; PARAMETRIZE { move = MOVE_WATER_GUN; } @@ -982,7 +982,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) G-Max Hydrosnipe has fixed power and ignores abili } } -DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Volt Crash paralyzes both opponents") +DOUBLE_BATTLE_TEST("Dynamax: G-Max Volt Crash paralyzes both opponents") { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_G_MAX_VOLT_CRASH, MOVE_EFFECT_PARALYZE_SIDE)); @@ -1005,7 +1005,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Volt Crash paralyzes both opponents") // G-Max Stun Shock can apply different statuses to each opponent, but this isn't // compatible with the test RNG set-up. -DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Stun Shock paralyzes or poisons both opponents") +DOUBLE_BATTLE_TEST("Dynamax: G-Max Stun Shock paralyzes or poisons both opponents") { u8 statusAnim; u32 rng; @@ -1046,7 +1046,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Stun Shock paralyzes or poisons both opponen } // This test extends to G-Max Befuddle, too. -DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Stun Shock chooses statuses before considering immunities") +DOUBLE_BATTLE_TEST("Dynamax: G-Max Stun Shock chooses statuses before considering immunities") { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_G_MAX_STUN_SHOCK, MOVE_EFFECT_POISON_PARALYZE_SIDE)); @@ -1074,7 +1074,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Stun Shock chooses statuses before consideri } } -DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Befuddle paralyzes, poisons, or sleeps both opponents") +DOUBLE_BATTLE_TEST("Dynamax: G-Max Befuddle paralyzes, poisons, or sleeps both opponents") { u8 statusAnim; u32 rng; @@ -1123,7 +1123,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Befuddle paralyzes, poisons, or sleeps both } } -DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Gold Rush confuses both opponents and generates money") +DOUBLE_BATTLE_TEST("Dynamax: G-Max Gold Rush confuses both opponents and generates money") { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_G_MAX_GOLD_RUSH, MOVE_EFFECT_CONFUSE_PAY_DAY_SIDE)); @@ -1143,7 +1143,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Gold Rush confuses both opponents and genera } } -DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Smite confuses both opponents") +DOUBLE_BATTLE_TEST("Dynamax: G-Max Smite confuses both opponents") { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_G_MAX_SMITE, MOVE_EFFECT_CONFUSE_SIDE)); @@ -1162,7 +1162,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Smite confuses both opponents") } } -DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Cuddle infatuates both opponents, if possible") +DOUBLE_BATTLE_TEST("Dynamax: G-Max Cuddle infatuates both opponents, if possible") { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_G_MAX_CUDDLE, MOVE_EFFECT_INFATUATE_SIDE)); @@ -1183,7 +1183,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Cuddle infatuates both opponents, if possibl } } -DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Terror traps both opponents") +DOUBLE_BATTLE_TEST("Dynamax: G-Max Terror traps both opponents") { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_G_MAX_TERROR, MOVE_EFFECT_PREVENT_ESCAPE_SIDE)); @@ -1202,7 +1202,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Terror traps both opponents") } } -SINGLE_BATTLE_TEST("(DYNAMAX) Baton Pass passes G-Max Terror's escape prevention effect") +SINGLE_BATTLE_TEST("Dynamax: Baton Pass passes G-Max Terror's escape prevention effect") { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_G_MAX_TERROR, MOVE_EFFECT_PREVENT_ESCAPE_SIDE)); @@ -1219,7 +1219,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Baton Pass passes G-Max Terror's escape prevention } } -DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Meltdown torments both opponents for 3 turns") +DOUBLE_BATTLE_TEST("Dynamax: G-Max Meltdown torments both opponents for 3 turns") { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_G_MAX_MELTDOWN, MOVE_EFFECT_TORMENT_SIDE)); @@ -1255,7 +1255,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Meltdown torments both opponents for 3 turns } // This test applies to G-Max Cannonade, G-Max Vine Lash, and G-Max Volcalith, too. -DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Wildfire sets a field effect that damages non-Fire types") +DOUBLE_BATTLE_TEST("Dynamax: G-Max Wildfire sets a field effect that damages non-Fire types") { s16 damage; GIVEN { @@ -1301,7 +1301,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Wildfire sets a field effect that damages no } } -DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Replenish recycles allies' berries 50\% of the time") +DOUBLE_BATTLE_TEST("Dynamax: G-Max Replenish recycles allies' berries 50\% of the time") { PASSES_RANDOMLY(1, 2, RNG_G_MAX_REPLENISH); GIVEN { @@ -1329,7 +1329,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Replenish recycles allies' berries 50\% of t } } -DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Snooze makes only the target drowsy") +DOUBLE_BATTLE_TEST("Dynamax: G-Max Snooze makes only the target drowsy") { PASSES_RANDOMLY(1, 2, RNG_G_MAX_SNOOZE); GIVEN { @@ -1353,7 +1353,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Snooze makes only the target drowsy") } } -DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Finale heals allies by 1/6 of their health") +DOUBLE_BATTLE_TEST("Dynamax: G-Max Finale heals allies by 1/6 of their health") { s16 damage1, damage2; GIVEN { @@ -1374,7 +1374,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Finale heals allies by 1/6 of their health") } } -DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Sweetness cures allies' status conditions") +DOUBLE_BATTLE_TEST("Dynamax: G-Max Sweetness cures allies' status conditions") { u32 j; GIVEN { @@ -1400,7 +1400,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Sweetness cures allies' status conditions") } // This test applies to G-Max Sandblast, too. -DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Centiferno traps both opponents in Fire Spin") +DOUBLE_BATTLE_TEST("Dynamax: G-Max Centiferno traps both opponents in Fire Spin") { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_G_MAX_CENTIFERNO, MOVE_EFFECT_FIRE_SPIN_SIDE)); @@ -1427,7 +1427,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Centiferno traps both opponents in Fire Spin } } -DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Chi Strike boosts allies' crit chance by 1 stage") +DOUBLE_BATTLE_TEST("Dynamax: G-Max Chi Strike boosts allies' crit chance by 1 stage") { u32 j; GIVEN { @@ -1458,9 +1458,9 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Chi Strike boosts allies' crit chance by 1 s } } -TO_DO_BATTLE_TEST("(DYNAMAX) Baton Pass doesn't pass G-Max Chi Strike's effect"); +TO_DO_BATTLE_TEST("Dynamax: Baton Pass doesn't pass G-Max Chi Strike's effect"); -DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Depletion takes away 2 PP from the target's last move") +DOUBLE_BATTLE_TEST("Dynamax: G-Max Depletion takes away 2 PP from the target's last move") { GIVEN { ASSUME(GetMoveCategory(MOVE_DRAGON_CLAW) == DAMAGE_CATEGORY_PHYSICAL); // Otherwise Sableye faints. @@ -1483,7 +1483,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Depletion takes away 2 PP from the target's } // This test applies to G-Max Rapid Flow, too. -DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max One Blow bypasses Max Guard for full damage", s16 damage) +DOUBLE_BATTLE_TEST("Dynamax: G-Max One Blow bypasses Max Guard for full damage", s16 damage) { bool32 protect; PARAMETRIZE { protect = TRUE; } @@ -1513,7 +1513,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max One Blow bypasses Max Guard for full damage" // Bug Testing // This test will fail if it's the first test a thread runs -DOUBLE_BATTLE_TEST("(DYNAMAX) Max Flare doesn't softlock the game when fainting player partner") +DOUBLE_BATTLE_TEST("Dynamax: Max Flare doesn't softlock the game when fainting player partner") { GIVEN { PLAYER(SPECIES_WOBBUFFET); @@ -1529,7 +1529,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) Max Flare doesn't softlock the game when fainting } } -SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves don't execute effects on fainted battlers") +SINGLE_BATTLE_TEST("Dynamax: Max Moves don't execute effects on fainted battlers") { GIVEN { PLAYER(SPECIES_WOBBUFFET); @@ -1544,7 +1544,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves don't execute effects on fainted battler } } -SINGLE_BATTLE_TEST("(DYNAMAX) Moxie clones can be triggered by Max Moves fainting opponents") +SINGLE_BATTLE_TEST("Dynamax: Moxie clones can be triggered by Max Moves fainting opponents") { GIVEN { ASSUME(GetMovePower(MOVE_WATERFALL) > 0); @@ -1560,7 +1560,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Moxie clones can be triggered by Max Moves faintin } } -SINGLE_BATTLE_TEST("(DYNAMAX) Max Attacks prints a message when hitting into Max Guard") +SINGLE_BATTLE_TEST("Dynamax: Max Attacks prints a message when hitting into Max Guard") { GIVEN { PLAYER(SPECIES_WOBBUFFET); @@ -1573,7 +1573,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Attacks prints a message when hitting into Max } } -SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves don't bypass absorbing abilities") +SINGLE_BATTLE_TEST("Dynamax: Max Moves don't bypass absorbing abilities") { u32 move, ability, species; PARAMETRIZE { move = MOVE_SPARK; ability = ABILITY_VOLT_ABSORB; species = SPECIES_LANTURN; } @@ -1609,3 +1609,18 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves don't bypass absorbing abilities") ABILITY_POPUP(opponent, ability); } } + +SINGLE_BATTLE_TEST("Dynamax: Dynamax is reverted before switch out") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_EJECT_BUTTON); } + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_TACKLE, gimmick: GIMMICK_DYNAMAX); MOVE(opponent, MOVE_TACKLE); SEND_OUT(player, 1); } + TURN { SWITCH(player, 0); } + TURN { MOVE(player, MOVE_TACKLE); } + } SCENE { + MESSAGE("Wobbuffet used Tackle!"); + } +} diff --git a/test/battle/hold_effect/seeds.c b/test/battle/hold_effect/seeds.c index 11aa9037db..e70d302f75 100644 --- a/test/battle/hold_effect/seeds.c +++ b/test/battle/hold_effect/seeds.c @@ -137,3 +137,61 @@ SINGLE_BATTLE_TEST("Psychic Seed raises the holder's Sp. Defense on Psychic Terr EXPECT_EQ(player->statStages[STAT_SPDEF], DEFAULT_STAT_STAGE + 1); } } + +SINGLE_BATTLE_TEST("Seeds get consumed in Terrain even if holder is not affected by Terrain") +{ + u32 species, ability, item; + PARAMETRIZE { species = SPECIES_TAPU_KOKO; ability = ABILITY_ELECTRIC_SURGE; item = ITEM_ELECTRIC_SEED; } + PARAMETRIZE { species = SPECIES_TAPU_BULU; ability = ABILITY_GRASSY_SURGE; item = ITEM_GRASSY_SEED; } + PARAMETRIZE { species = SPECIES_TAPU_FINI; ability = ABILITY_MISTY_SURGE; item = ITEM_MISTY_SEED; } + PARAMETRIZE { species = SPECIES_TAPU_LELE; ability = ABILITY_PSYCHIC_SURGE; item = ITEM_PSYCHIC_SEED; } + GIVEN { + ASSUME(gSpeciesInfo[SPECIES_PIDGEY].types[0] == TYPE_FLYING || gSpeciesInfo[SPECIES_PIDGEY].types[1] == TYPE_FLYING); + PLAYER(SPECIES_PIDGEY) { Item(item); } + OPPONENT(species) { Ability(ability); } + } WHEN { + TURN { } + } SCENE { + ABILITY_POPUP(opponent, ability); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + } THEN { + EXPECT_EQ(player->item, ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Electric Seed is consumed on Electric Terrain before other abilities change the terrain") +{ + GIVEN { + PLAYER(SPECIES_TAPU_BULU) { Ability(ABILITY_GRASSY_SURGE); Item(ITEM_ELECTRIC_SEED); Speed(5); } + OPPONENT(SPECIES_TAPU_KOKO) { Ability(ABILITY_ELECTRIC_SURGE); Item(ITEM_ELECTRIC_SEED); Speed(10); } + } WHEN { + TURN { } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_ELECTRIC_SURGE); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Using Electric Seed, the Defense of the opposing Tapu Koko rose!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Using Electric Seed, the Defense of Tapu Bulu rose!"); + ABILITY_POPUP(player, ABILITY_GRASSY_SURGE); + } +} + +SINGLE_BATTLE_TEST("Electric Seed doesn't activate on existing Electric Terrain before user's ability changes the terrain") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_TAPU_BULU) { Ability(ABILITY_GRASSY_SURGE); Item(ITEM_ELECTRIC_SEED); } + OPPONENT(SPECIES_TAPU_KOKO) { Ability(ABILITY_ELECTRIC_SURGE); } + } WHEN { + TURN { SWITCH(player, 1); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_ELECTRIC_SURGE); + SWITCH_OUT_MESSAGE("Wobbuffet"); + SEND_IN_MESSAGE("Tapu Bulu"); + NONE_OF { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Using Electric Seed, the Defense of Tapu Bulu rose!"); + } + ABILITY_POPUP(player, ABILITY_GRASSY_SURGE); + } +} diff --git a/test/battle/move_effect/hit_switch_target.c b/test/battle/move_effect/hit_switch_target.c index 61c92d227e..e0d6548ec3 100644 --- a/test/battle/move_effect/hit_switch_target.c +++ b/test/battle/move_effect/hit_switch_target.c @@ -119,3 +119,48 @@ SINGLE_BATTLE_TEST("Dragon Tail effect fails against target with Suction Cups") NOT MESSAGE("The opposing Charmander was dragged out!"); } } + +SINGLE_BATTLE_TEST("Dragon Tail switches target out and incoming mon has Immunity negated by Mold Breaker") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_TOXIC_SPIKES) == EFFECT_TOXIC_SPIKES); + PLAYER(SPECIES_PANCHAM) { Ability(ABILITY_MOLD_BREAKER); } + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_SNORLAX) { Ability(ABILITY_IMMUNITY); } + } WHEN { + TURN { MOVE(player, MOVE_TOXIC_SPIKES); } + TURN { MOVE(player, MOVE_DRAGON_TAIL); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TOXIC_SPIKES, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_TAIL, player); + HP_BAR(opponent); + MESSAGE("The opposing Snorlax was dragged out!"); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent); + STATUS_ICON(opponent, poison: TRUE); + } +} + +SINGLE_BATTLE_TEST("Dragon Tail switches target out and incoming mon has Levitate negated by Mold Breaker") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_TOXIC_SPIKES) == EFFECT_TOXIC_SPIKES); + ASSUME(GetMoveEffect(MOVE_SPIKES) == EFFECT_SPIKES); + ASSUME(gSpeciesInfo[SPECIES_WEEZING].types[0] == TYPE_POISON || gSpeciesInfo[SPECIES_WEEZING].types[1] == TYPE_POISON); + PLAYER(SPECIES_PANCHAM) { Ability(ABILITY_MOLD_BREAKER); } + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WEEZING) { Ability(ABILITY_LEVITATE); } + } WHEN { + TURN { MOVE(player, MOVE_TOXIC_SPIKES); } + TURN { MOVE(player, MOVE_SPIKES); } + TURN { MOVE(player, MOVE_DRAGON_TAIL); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TOXIC_SPIKES, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPIKES, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_TAIL, player); + HP_BAR(opponent); + MESSAGE("The opposing Weezing was dragged out!"); + HP_BAR(opponent); + NOT STATUS_ICON(opponent, poison: TRUE); + MESSAGE("The poison spikes disappeared from the ground around the opposing team!"); + } +} diff --git a/test/battle/move_effect/magic_coat.c b/test/battle/move_effect/magic_coat.c index 561d15a532..343322408d 100644 --- a/test/battle/move_effect/magic_coat.c +++ b/test/battle/move_effect/magic_coat.c @@ -11,13 +11,23 @@ SINGLE_BATTLE_TEST("Magic Coat prints the correct message when bouncing back a m GIVEN { ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_ZIGZAGOON); - OPPONENT(SPECIES_WYNAUT); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); } WHEN { TURN { MOVE(player, MOVE_MAGIC_COAT); MOVE(opponent, MOVE_SPORE); } + TURN { SWITCH(opponent, 1); } + TURN { MOVE(player, MOVE_MAGIC_COAT); MOVE(opponent, MOVE_SPORE); } } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_MAGIC_COAT, player); - MESSAGE("Zigzagoon bounced the Spore back!");; - MESSAGE("The opposing Wynaut fell asleep!"); + MESSAGE("Zigzagoon bounced the Spore back!"); + MESSAGE("The opposing Zigzagoon fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_MAGIC_COAT, player); + MESSAGE("Zigzagoon bounced the Spore back!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Zigzagoon fell asleep!"); STATUS_ICON(opponent, sleep: TRUE); } } diff --git a/test/battle/move_effect/recoil_if_miss.c b/test/battle/move_effect/recoil_if_miss.c index 8695156dd0..0b65eb8541 100644 --- a/test/battle/move_effect/recoil_if_miss.c +++ b/test/battle/move_effect/recoil_if_miss.c @@ -6,7 +6,7 @@ ASSUMPTIONS ASSUME(GetMoveEffect(MOVE_JUMP_KICK) == EFFECT_RECOIL_IF_MISS); } -SINGLE_BATTLE_TEST("Jump Kick has 50% recoil on miss") +SINGLE_BATTLE_TEST("Recoil if miss: Jump Kick has 50% recoil on miss") { GIVEN { PLAYER(SPECIES_WOBBUFFET); @@ -22,7 +22,7 @@ SINGLE_BATTLE_TEST("Jump Kick has 50% recoil on miss") } } -SINGLE_BATTLE_TEST("Jump Kick has 50% recoil on protect") +SINGLE_BATTLE_TEST("Recoil if miss: Jump Kick has 50% recoil on protect") { GIVEN { ASSUME(!MoveIgnoresProtect(MOVE_JUMP_KICK)); @@ -38,7 +38,7 @@ SINGLE_BATTLE_TEST("Jump Kick has 50% recoil on protect") } } -SINGLE_BATTLE_TEST("Jump Kick has no recoil if no target") +SINGLE_BATTLE_TEST("Recoil if miss: Jump Kick has no recoil if no target") { GIVEN { ASSUME(B_HEALING_WISH_SWITCH >= GEN_5); @@ -54,7 +54,7 @@ SINGLE_BATTLE_TEST("Jump Kick has no recoil if no target") } } -SINGLE_BATTLE_TEST("Jump Kick's recoil happens after Spiky Shield damage and Pokemon can faint from either of these") +SINGLE_BATTLE_TEST("Recoil if miss: Jump Kick's recoil happens after Spiky Shield damage and Pokemon can faint from either of these") { s16 hp, maxHp = 256; bool32 faintOnSpiky = FALSE, faintOnJumpKick = FALSE; @@ -98,3 +98,60 @@ SINGLE_BATTLE_TEST("Jump Kick's recoil happens after Spiky Shield damage and Pok } } } + +SINGLE_BATTLE_TEST("Recoil if miss: Jump Kick recoil happens after Spiky Shield damage") +{ + GIVEN { + ASSUME(!gMovesInfo[MOVE_JUMP_KICK].ignoresProtect); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_SPIKY_SHIELD); MOVE(player, MOVE_JUMP_KICK); } + } SCENE { + s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPIKY_SHIELD, opponent); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_JUMP_KICK, player); + MESSAGE("Wobbuffet was hurt by the opposing Wobbuffet's Spiky Shield!"); + MESSAGE("Wobbuffet kept going and crashed!"); + HP_BAR(player, damage: maxHP / 2); + } +} + +SINGLE_BATTLE_TEST("Recoil if miss: Supercell Slam causes recoil if it is absorbed") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_PIKACHU) { Ability(ABILITY_LIGHTNING_ROD); } + } WHEN { + TURN { MOVE(player, MOVE_SUPERCELL_SLAM); } + } SCENE { + s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP); + ABILITY_POPUP(opponent, ABILITY_LIGHTNING_ROD); + MESSAGE("Wobbuffet kept going and crashed!"); + HP_BAR(player, damage: maxHP / 2); + } +} + +SINGLE_BATTLE_TEST("Recoil if miss: Disguise doesn't prevent crash damage from Jump Kick into ghost types") +{ + u32 ability; + PARAMETRIZE { ability = ABILITY_EARLY_BIRD; } + PARAMETRIZE { ability = ABILITY_SCRAPPY; } + + GIVEN { + PLAYER(SPECIES_KANGASKHAN) { Ability(ability); }; + OPPONENT(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); } + } WHEN { + TURN { MOVE(player, MOVE_JUMP_KICK); } + } SCENE { + s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP); + MESSAGE("Kangaskhan used Jump Kick!"); + if (ability == ABILITY_SCRAPPY) { + NONE_OF { + MESSAGE("Kangaskhan kept going and crashed!"); + HP_BAR(player, damage: maxHP / 2); + } + } + } +} + diff --git a/test/battle/move_effect/shell_side_arm.c b/test/battle/move_effect/shell_side_arm.c index 13458e39ae..4a6be08f18 100644 --- a/test/battle/move_effect/shell_side_arm.c +++ b/test/battle/move_effect/shell_side_arm.c @@ -1,6 +1,12 @@ #include "global.h" #include "test/battle.h" +ASSUMPTIONS +{ + ASSUME(GetMoveEffect(MOVE_MIRROR_COAT) == EFFECT_MIRROR_COAT); + ASSUME(GetMoveEffect(MOVE_COUNTER) == EFFECT_COUNTER); +} + SINGLE_BATTLE_TEST("Shell Side Arm can be countered if it is physical") { GIVEN { @@ -31,28 +37,30 @@ SINGLE_BATTLE_TEST("Shell Side Arm can be mirror coated if it is special") } } -SINGLE_BATTLE_TEST("Shell Side Arm does not change category mid-turn") +DOUBLE_BATTLE_TEST("Shell Side Arm does not change category mid-turn") { - s16 damage[3]; - GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_SHELL_SIDE_ARM); } - OPPONENT(SPECIES_WOBBUFFET) { Defense(100); SpDefense(120); } + ASSUME(GetMoveEffect(MOVE_SCREECH) == EFFECT_DEFENSE_DOWN_2); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_SHUCKLE) { Ability(ABILITY_CONTRARY); Defense(100); SpDefense(120); } + OPPONENT(SPECIES_WYNAUT); } WHEN { - TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_SHELL_SIDE_ARM); } - TURN { MOVE(opponent, MOVE_LIGHT_SCREEN); MOVE(player, MOVE_SHELL_SIDE_ARM); } - TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_SHELL_SIDE_ARM); } + TURN { MOVE(playerLeft, MOVE_SHELL_SIDE_ARM, target: opponentLeft); MOVE(opponentLeft, MOVE_MIRROR_COAT, target: opponentLeft); } + TURN { MOVE(playerRight, MOVE_SCREECH, target: opponentLeft); MOVE(playerLeft, MOVE_SHELL_SIDE_ARM, target: opponentLeft); MOVE(opponentLeft, MOVE_MIRROR_COAT, target: opponentLeft); } + TURN { MOVE(playerLeft, MOVE_SHELL_SIDE_ARM, target: opponentLeft); MOVE(opponentLeft, MOVE_MIRROR_COAT, target: opponentLeft); } } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_SHELL_SIDE_ARM, player); - HP_BAR(opponent, captureDamage: &damage[0]); - ANIMATION(ANIM_TYPE_MOVE, MOVE_LIGHT_SCREEN, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SHELL_SIDE_ARM, player); - HP_BAR(opponent, captureDamage: &damage[1]); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SHELL_SIDE_ARM, player); - HP_BAR(opponent, captureDamage: &damage[2]); - } THEN { - EXPECT_EQ(damage[0], damage[1]); - EXPECT_EQ(damage[1], damage[2]); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SHELL_SIDE_ARM, playerLeft); + HP_BAR(opponentLeft); + NOT HP_BAR(playerLeft); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCREECH, playerRight); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SHELL_SIDE_ARM, playerLeft); + HP_BAR(opponentLeft); + NOT HP_BAR(playerLeft); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SHELL_SIDE_ARM, playerLeft); + HP_BAR(opponentLeft); + ANIMATION(ANIM_TYPE_MOVE, MOVE_MIRROR_COAT, opponentLeft); + HP_BAR(playerLeft); } } @@ -77,24 +85,3 @@ DOUBLE_BATTLE_TEST("Shell Side Arm chooses its category for each battler on the HP_BAR(playerLeft); } } - -DOUBLE_BATTLE_TEST("Shell Side Arm does not change category mid-turn") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Speed(10); Moves(MOVE_SHELL_SIDE_ARM); } - PLAYER(SPECIES_WOBBUFFET) { Speed(20); } - OPPONENT(SPECIES_WOBBUFFET) { Speed(30); Defense(200); SpDefense(190); } - OPPONENT(SPECIES_WOBBUFFET) { Speed(40); } - } WHEN { - TURN { MOVE(playerLeft, MOVE_SHELL_SIDE_ARM, target: opponentLeft); - MOVE(opponentRight, MOVE_LIGHT_SCREEN); - MOVE(opponentLeft, MOVE_MIRROR_COAT); - } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_LIGHT_SCREEN, opponentRight); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SHELL_SIDE_ARM, playerLeft); - HP_BAR(opponentLeft); - ANIMATION(ANIM_TYPE_MOVE, MOVE_MIRROR_COAT, opponentLeft); - HP_BAR(playerLeft); - } -} diff --git a/test/battle/move_effect/speed_down.c b/test/battle/move_effect/speed_down.c new file mode 100644 index 0000000000..a3b5e26be8 --- /dev/null +++ b/test/battle/move_effect/speed_down.c @@ -0,0 +1,31 @@ +#include "global.h" +#include "test/battle.h" + +DOUBLE_BATTLE_TEST("Speed Down: Cotton Spore does not fail if it is blocked by one target") +{ + u32 abilityOne, abilityTwo; + + PARAMETRIZE { abilityOne = ABILITY_OVERCOAT; abilityTwo = ABILITY_SKILL_LINK; } + PARAMETRIZE { abilityOne = ABILITY_SKILL_LINK; abilityTwo = ABILITY_OVERCOAT; } + + GIVEN { + ASSUME(GetMoveEffect(MOVE_COTTON_SPORE) == EFFECT_SPEED_DOWN_2); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_SHELLDER) { Ability(abilityOne); } + OPPONENT(SPECIES_SHELLDER) { Ability(abilityTwo); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_COTTON_SPORE); } + } SCENE { + if (abilityOne == ABILITY_OVERCOAT) { + ABILITY_POPUP(opponentLeft, ABILITY_OVERCOAT); + ANIMATION(ANIM_TYPE_MOVE, MOVE_COTTON_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight); + } + else if (abilityTwo == ABILITY_OVERCOAT) { + ANIMATION(ANIM_TYPE_MOVE, MOVE_COTTON_SPORE, playerLeft); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft); + ABILITY_POPUP(opponentRight, ABILITY_OVERCOAT); + } + } +} diff --git a/test/battle/move_effect/stealth_rock.c b/test/battle/move_effect/stealth_rock.c index d4399a2d0f..67441367a6 100644 --- a/test/battle/move_effect/stealth_rock.c +++ b/test/battle/move_effect/stealth_rock.c @@ -73,3 +73,30 @@ DOUBLE_BATTLE_TEST("Stealth Rock damages the correct pokemon when Eject Button i EXPECT_EQ(opponentLeft->hp, opponentLeft->maxHP); } } + +SINGLE_BATTLE_TEST("Stealth Rock damage terastalized mons with the correct amount of damage", s16 damage) +{ + u32 tera; + + PARAMETRIZE { tera = FALSE; } + PARAMETRIZE { tera = TRUE; } + + GIVEN { + PLAYER(SPECIES_CHARIZARD) { TeraType(TYPE_NORMAL); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + if (tera == TRUE) + TURN { MOVE(opponent, MOVE_STEALTH_ROCK); MOVE(player, MOVE_CELEBRATE, gimmick: GIMMICK_TERA); } + else + TURN { MOVE(opponent, MOVE_STEALTH_ROCK); MOVE(player, MOVE_CELEBRATE); } + TURN { SWITCH(player, 1); } + TURN { SWITCH(player, 0); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_STEALTH_ROCK, opponent); + HP_BAR(player); + HP_BAR(player, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_GT(results[0].damage, results[1].damage); + } +} diff --git a/test/battle/move_effect/tera_starstorm.c b/test/battle/move_effect/tera_starstorm.c index 3077b38df9..c1d8794576 100644 --- a/test/battle/move_effect/tera_starstorm.c +++ b/test/battle/move_effect/tera_starstorm.c @@ -40,23 +40,26 @@ DOUBLE_BATTLE_TEST("Tera Starstorm targets both opponents in a double battle if } } -SINGLE_BATTLE_TEST("Tera Starstorm becomes a physical move if the user is Terapagos-Stellar, is Terastallized, and has a higher Attack stat", s16 damage) +SINGLE_BATTLE_TEST("Tera Starstorm becomes a physical move if the user is Terapagos-Stellar, is Terastallized, and has a higher Attack stat") { - bool32 tera; - PARAMETRIZE { tera = GIMMICK_NONE; } - PARAMETRIZE { tera = GIMMICK_TERA; } GIVEN { + ASSUME(GetMoveEffect(MOVE_COUNTER) == EFFECT_COUNTER); + ASSUME(GetMoveEffect(MOVE_MIRROR_COAT) == EFFECT_MIRROR_COAT); ASSUME(GetMoveCategory(MOVE_TERA_STARSTORM) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_TERAPAGOS_STELLAR) { Attack(100); SpAttack(50); } OPPONENT(SPECIES_WOBBUFFET) { Defense(200); SpDefense(200); } } WHEN { - TURN { MOVE(player, MOVE_TERA_STARSTORM, gimmick: tera); } + TURN { MOVE(player, MOVE_TERA_STARSTORM); MOVE(opponent, MOVE_MIRROR_COAT); } + TURN { MOVE(player, MOVE_TERA_STARSTORM, gimmick: GIMMICK_TERA); MOVE(opponent, MOVE_COUNTER); } } SCENE { MESSAGE("Terapagos used Tera Starstorm!"); ANIMATION(ANIM_TYPE_MOVE, MOVE_TERA_STARSTORM, player); - HP_BAR(opponent, captureDamage: &results[i].damage); - } FINALLY { - EXPECT_MUL_EQ(results[0].damage, UQ_4_12(2.5), results[1].damage); + ANIMATION(ANIM_TYPE_MOVE, MOVE_MIRROR_COAT, opponent); + HP_BAR(player); + MESSAGE("Terapagos used Tera Starstorm!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TERA_STARSTORM, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_COUNTER, opponent); + HP_BAR(player); } } diff --git a/test/battle/sleep_clause.c b/test/battle/sleep_clause.c index 7537fb437a..678accb585 100644 --- a/test/battle/sleep_clause.c +++ b/test/battle/sleep_clause.c @@ -1390,7 +1390,6 @@ SINGLE_BATTLE_TEST("Sleep Clause: Suppressing and then sleeping Vital Spirit / I SINGLE_BATTLE_TEST("Sleep Clause: Mold Breaker Pokémon sleeping Vital Spirit / Insomnia activates sleep clause") { - KNOWN_FAILING; // Interaction between Mold Breaker and Vital Spirit / Insomnia is broken. Issue #5578 https://github.com/rh-hideout/pokeemerald-expansion/issues/5578 u32 ability; PARAMETRIZE { ability = ABILITY_VITAL_SPIRIT; } PARAMETRIZE { ability = ABILITY_INSOMNIA; } @@ -1410,7 +1409,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Mold Breaker Pokémon sleeping Vital Spirit / ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); MESSAGE("The opposing Delibird fell asleep!"); STATUS_ICON(opponent, sleep: TRUE); - MESSAGE("Sleep Clause kept the opposing Delibird awake!"); + ABILITY_POPUP(opponent, ability); ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); MESSAGE("The opposing Zigzagoon fell asleep!"); @@ -1518,7 +1517,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Reflection moves (ie. Magic Coat) fail if slee MESSAGE("The opposing Zigzagoon fell asleep!"); STATUS_ICON(opponent, sleep: TRUE); ANIMATION(ANIM_TYPE_MOVE, MOVE_MAGIC_COAT, player); - MESSAGE("The opposing Zigzagoon bounced the Spore back!"); // Should be MESSAGE("Zigzagoon bounced the Spore back!"); Issue #5579 https://github.com/rh-hideout/pokeemerald-expansion/issues/5579 + MESSAGE("Zigzagoon bounced the Spore back!"); MESSAGE("Sleep Clause kept the opposing Zigzagoon awake!"); } } diff --git a/test/test_runner_battle.c b/test/test_runner_battle.c index 41ea06b67d..fce7a6d0e3 100644 --- a/test/test_runner_battle.c +++ b/test/test_runner_battle.c @@ -2038,8 +2038,7 @@ s32 MoveGetTarget(s32 battlerId, u32 moveId, struct MoveContext *ctx, u32 source || move->target == MOVE_TARGET_BOTH || move->target == MOVE_TARGET_DEPENDS || move->target == MOVE_TARGET_FOES_AND_ALLY - || move->target == MOVE_TARGET_OPPONENTS_FIELD - || move->target == MOVE_TARGET_ALL_BATTLERS) + || move->target == MOVE_TARGET_OPPONENTS_FIELD) { target = BATTLE_OPPOSITE(battlerId); } @@ -2053,7 +2052,7 @@ s32 MoveGetTarget(s32 battlerId, u32 moveId, struct MoveContext *ctx, u32 source target = BATTLE_OPPOSITE(battlerId); } - else if (move->target == MOVE_TARGET_USER) + else if (move->target == MOVE_TARGET_USER || move->target == MOVE_TARGET_ALL_BATTLERS) { target = battlerId; }