Merge branch 'master' into master-to-upcoming
This commit is contained in:
commit
27da389d1e
@ -8198,15 +8198,12 @@ BattleScript_FlashFireBoost::
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_AbilityPreventsPhasingOut::
|
||||
pause B_WAIT_TIME_SHORT
|
||||
call BattleScript_AbilityPopUp
|
||||
printstring STRINGID_PKMNANCHORSITSELFWITH
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
call BattleScript_AbilityPreventsPhasingOutRet
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_AbilityPreventsPhasingOutRet::
|
||||
pause B_WAIT_TIME_SHORT
|
||||
call BattleScript_AbilityPopUp
|
||||
call BattleScript_AbilityPopUpTarget
|
||||
printstring STRINGID_PKMNANCHORSITSELFWITH
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
21
include/constants/regions.h
Normal file
21
include/constants/regions.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef GUARD_CONSTANTS_REGIONS_H
|
||||
#define GUARD_CONSTANTS_REGIONS_H
|
||||
|
||||
// Core-series regions
|
||||
enum Region
|
||||
{
|
||||
REGION_NONE,
|
||||
REGION_KANTO,
|
||||
REGION_JOHTO,
|
||||
REGION_HOENN,
|
||||
REGION_SINNOH,
|
||||
REGION_UNOVA,
|
||||
REGION_KALOS,
|
||||
REGION_ALOLA,
|
||||
REGION_GALAR,
|
||||
REGION_HISUI,
|
||||
REGION_PALDEA,
|
||||
REGIONS_COUNT,
|
||||
};
|
||||
|
||||
#endif // GUARD_CONSTANTS_REGIONS_H
|
||||
@ -34,6 +34,7 @@ void ShowDaycareLevelMenu(void);
|
||||
void ChooseSendDaycareMon(void);
|
||||
u8 GetEggMovesBySpecies(u16 species, u16 *eggMoves);
|
||||
bool8 SpeciesCanLearnEggMove(u16 species, u16 move);
|
||||
void StorePokemonInDaycare(struct Pokemon *mon, struct DaycareMon *daycareMon);
|
||||
u8 GetEggMoves(struct Pokemon *pokemon, u16 *eggMoves);
|
||||
|
||||
#endif // GUARD_DAYCARE_H
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
#include "sprite.h"
|
||||
#include "constants/items.h"
|
||||
#include "constants/regions.h"
|
||||
#include "constants/region_map_sections.h"
|
||||
#include "constants/map_groups.h"
|
||||
#include "contest_effect.h"
|
||||
@ -806,5 +807,7 @@ void UpdateDaysPassedSinceFormChange(u16 days);
|
||||
void TrySetDayLimitToFormChange(struct Pokemon *mon);
|
||||
u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler);
|
||||
uq4_12_t GetDynamaxLevelHPMultiplier(u32 dynamaxLevel, bool32 inverseMultiplier);
|
||||
u32 GetRegionalFormByRegion(u32 species, u32 region);
|
||||
bool32 IsSpeciesForeignRegionalForm(u32 species, u32 currentRegion);
|
||||
|
||||
#endif // GUARD_POKEMON_H
|
||||
|
||||
12
include/regions.h
Normal file
12
include/regions.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef GUARD_REGIONS_H
|
||||
#define GUARD_REGIONS_H
|
||||
|
||||
#include "constants/regions.h"
|
||||
|
||||
static inline u32 GetCurrentRegion(void)
|
||||
{
|
||||
// TODO: Since there's no current multi-region support, we have this constant for the purposes of regional form comparisons.
|
||||
return REGION_HOENN;
|
||||
}
|
||||
|
||||
#endif // GUARD_REGIONS_H
|
||||
@ -6792,8 +6792,7 @@ static void Cmd_moveend(void)
|
||||
if (redCardBattlers
|
||||
&& (moveEffect != EFFECT_HIT_SWITCH_TARGET || gBattleStruct->hitSwitchTargetFailed)
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& !TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)
|
||||
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_GUARD_DOG)
|
||||
&& !TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove))
|
||||
{
|
||||
// Since we check if battler was damaged, we don't need to check move result.
|
||||
// In fact, doing so actually prevents multi-target moves from activating red card properly
|
||||
@ -6818,7 +6817,8 @@ static void Cmd_moveend(void)
|
||||
if (moveEffect == EFFECT_HIT_ESCAPE)
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEnd; // Prevent user switch-in selection
|
||||
BattleScriptPushCursor();
|
||||
if (gBattleStruct->commanderActive[gBattlerAttacker] != SPECIES_NONE)
|
||||
if (gBattleStruct->commanderActive[gBattlerAttacker] != SPECIES_NONE
|
||||
|| GetBattlerAbility(gBattlerAttacker) == ABILITY_GUARD_DOG)
|
||||
{
|
||||
gBattlescriptCurrInstr = BattleScript_RedCardActivationNoSwitch;
|
||||
}
|
||||
@ -6972,7 +6972,7 @@ static void Cmd_moveend(void)
|
||||
gBattleScripting.moveendState++;
|
||||
break;
|
||||
case MOVEEND_SAME_MOVE_TURNS:
|
||||
if (gCurrentMove != gLastResultingMoves[gBattlerAttacker] || gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT)
|
||||
if (gCurrentMove != gLastResultingMoves[gBattlerAttacker] || gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT || gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
|
||||
gBattleStruct->sameMoveTurns[gBattlerAttacker] = 0;
|
||||
else if (gCurrentMove == gLastResultingMoves[gBattlerAttacker] && gSpecialStatuses[gBattlerAttacker].parentalBondState != PARENTAL_BOND_1ST_HIT)
|
||||
gBattleStruct->sameMoveTurns[gBattlerAttacker]++;
|
||||
|
||||
@ -1229,7 +1229,7 @@ bool32 IsBelchPreventingMove(u32 battler, u32 move)
|
||||
}
|
||||
|
||||
// Dynamax bypasses all selection prevention except Taunt and Assault Vest.
|
||||
#define DYNAMAX_BYPASS_CHECK (!IsGimmickSelected(gBattlerAttacker, GIMMICK_DYNAMAX) && GetActiveGimmick(gBattlerAttacker) != GIMMICK_DYNAMAX)
|
||||
#define DYNAMAX_BYPASS_CHECK (!IsGimmickSelected(battler, GIMMICK_DYNAMAX) && GetActiveGimmick(battler) != GIMMICK_DYNAMAX)
|
||||
|
||||
u32 TrySetCantSelectMoveBattleScript(u32 battler)
|
||||
{
|
||||
@ -1240,7 +1240,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
|
||||
u16 *choicedMove = &gBattleStruct->choicedMove[battler];
|
||||
u32 moveEffect = GetMoveEffect(move);
|
||||
|
||||
if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[battler].disabledMove == move && move != MOVE_NONE)
|
||||
if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(battler) != GIMMICK_Z_MOVE && gDisableStructs[battler].disabledMove == move && move != MOVE_NONE)
|
||||
{
|
||||
gBattleScripting.battler = battler;
|
||||
gCurrentMove = move;
|
||||
@ -1256,7 +1256,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
|
||||
}
|
||||
}
|
||||
|
||||
if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && move == gLastMoves[battler] && move != MOVE_STRUGGLE && (gBattleMons[battler].status2 & STATUS2_TORMENT))
|
||||
if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(battler) != GIMMICK_Z_MOVE && move == gLastMoves[battler] && move != MOVE_STRUGGLE && (gBattleMons[battler].status2 & STATUS2_TORMENT))
|
||||
{
|
||||
CancelMultiTurnMoves(battler);
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||
@ -1271,9 +1271,9 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
|
||||
}
|
||||
}
|
||||
|
||||
if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[battler].tauntTimer != 0 && IsBattleMoveStatus(move))
|
||||
if (GetActiveGimmick(battler) != GIMMICK_Z_MOVE && gDisableStructs[battler].tauntTimer != 0 && IsBattleMoveStatus(move))
|
||||
{
|
||||
if ((GetActiveGimmick(gBattlerAttacker) == GIMMICK_DYNAMAX))
|
||||
if ((GetActiveGimmick(battler) == GIMMICK_DYNAMAX))
|
||||
gCurrentMove = MOVE_MAX_GUARD;
|
||||
else
|
||||
gCurrentMove = move;
|
||||
@ -1289,7 +1289,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
|
||||
}
|
||||
}
|
||||
|
||||
if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[battler].throatChopTimer != 0 && IsSoundMove(move))
|
||||
if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(battler) != GIMMICK_Z_MOVE && gDisableStructs[battler].throatChopTimer != 0 && IsSoundMove(move))
|
||||
{
|
||||
gCurrentMove = move;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||
@ -1304,7 +1304,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
|
||||
}
|
||||
}
|
||||
|
||||
if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && GetImprisonedMovesCount(battler, move))
|
||||
if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(battler) != GIMMICK_Z_MOVE && GetImprisonedMovesCount(battler, move))
|
||||
{
|
||||
gCurrentMove = move;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||
@ -1319,7 +1319,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
|
||||
}
|
||||
}
|
||||
|
||||
if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && IsGravityPreventingMove(move))
|
||||
if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(battler) != GIMMICK_Z_MOVE && IsGravityPreventingMove(move))
|
||||
{
|
||||
gCurrentMove = move;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||
@ -1334,7 +1334,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
|
||||
}
|
||||
}
|
||||
|
||||
if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && IsHealBlockPreventingMove(battler, move))
|
||||
if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(battler) != GIMMICK_Z_MOVE && IsHealBlockPreventingMove(battler, move))
|
||||
{
|
||||
gCurrentMove = move;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||
@ -1349,7 +1349,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
|
||||
}
|
||||
}
|
||||
|
||||
if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && IsBelchPreventingMove(battler, move))
|
||||
if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(battler) != GIMMICK_Z_MOVE && IsBelchPreventingMove(battler, move))
|
||||
{
|
||||
gCurrentMove = move;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||
@ -1413,7 +1413,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
|
||||
}
|
||||
else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && IsBattleMoveStatus(move) && moveEffect != EFFECT_ME_FIRST)
|
||||
{
|
||||
if ((GetActiveGimmick(gBattlerAttacker) == GIMMICK_DYNAMAX))
|
||||
if ((GetActiveGimmick(battler) == GIMMICK_DYNAMAX))
|
||||
gCurrentMove = MOVE_MAX_GUARD;
|
||||
else
|
||||
gCurrentMove = move;
|
||||
@ -4828,6 +4828,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
case ABILITY_UNNERVE:
|
||||
if (!gSpecialStatuses[battler].switchInAbilityDone)
|
||||
{
|
||||
gBattlerTarget = GetBattlerAtPosition(BATTLE_OPPOSITE(GetBattlerAtPosition(battler)));
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SWITCHIN_UNNERVE;
|
||||
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
|
||||
BattleScriptPushCursorAndCallback(BattleScript_SwitchInAbilityMsg);
|
||||
@ -4838,6 +4839,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
case ABILITY_AS_ONE_SHADOW_RIDER:
|
||||
if (!gSpecialStatuses[battler].switchInAbilityDone)
|
||||
{
|
||||
gBattlerTarget = GetBattlerAtPosition(BATTLE_OPPOSITE(GetBattlerAtPosition(battler)));
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SWITCHIN_ASONE;
|
||||
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
|
||||
BattleScriptPushCursorAndCallback(BattleScript_ActivateAsOne);
|
||||
@ -8791,7 +8793,7 @@ bool32 IsBattlerProtected(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
else if (gProtectStructs[battlerDef].protected)
|
||||
isProtected = TRUE;
|
||||
else if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_WIDE_GUARD
|
||||
&& GetBattlerMoveTargetType(gBattlerAttacker, move) & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))
|
||||
&& GetBattlerMoveTargetType(battlerAtk, move) & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))
|
||||
isProtected = TRUE;
|
||||
else if (gProtectStructs[battlerDef].banefulBunkered)
|
||||
isProtected = TRUE;
|
||||
@ -8806,7 +8808,7 @@ bool32 IsBattlerProtected(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
else if (gProtectStructs[battlerDef].maxGuarded)
|
||||
isProtected = TRUE;
|
||||
else if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_QUICK_GUARD
|
||||
&& GetChosenMovePriority(gBattlerAttacker) > 0)
|
||||
&& GetChosenMovePriority(battlerAtk) > 0)
|
||||
isProtected = TRUE;
|
||||
else if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_MAT_BLOCK
|
||||
&& !IsBattleMoveStatus(move))
|
||||
@ -10564,7 +10566,7 @@ static inline bool32 IsFutureSightAttackerInParty(struct DamageCalculationData *
|
||||
if (GetMoveEffect(damageCalcData->move) != EFFECT_FUTURE_SIGHT)
|
||||
return FALSE;
|
||||
|
||||
struct Pokemon *party = GetSideParty(GetBattlerSide(gBattlerAttacker));
|
||||
struct Pokemon *party = GetSideParty(GetBattlerSide(damageCalcData->battlerAtk));
|
||||
return &party[gWishFutureKnock.futureSightPartyIndex[damageCalcData->battlerDef]]
|
||||
!= &party[gBattlerPartyIndexes[damageCalcData->battlerAtk]];
|
||||
}
|
||||
@ -11258,7 +11260,7 @@ bool32 CanBattlerGetOrLoseItem(u32 battler, u16 itemId)
|
||||
else if (holdEffect == HOLD_EFFECT_Z_CRYSTAL)
|
||||
return FALSE;
|
||||
else if (holdEffect == HOLD_EFFECT_BOOSTER_ENERGY
|
||||
&& (gSpeciesInfo[gBattleMons[gBattlerAttacker].species].isParadox || gSpeciesInfo[gBattleMons[gBattlerTarget].species].isParadox))
|
||||
&& (gSpeciesInfo[gBattleMons[battler].species].isParadox || gSpeciesInfo[gBattleMons[gBattlerTarget].species].isParadox))
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "list_menu.h"
|
||||
#include "overworld.h"
|
||||
#include "item.h"
|
||||
#include "regions.h"
|
||||
#include "constants/form_change_types.h"
|
||||
#include "constants/items.h"
|
||||
#include "constants/hold_effects.h"
|
||||
@ -243,7 +244,7 @@ static void TransferEggMoves(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void StorePokemonInDaycare(struct Pokemon *mon, struct DaycareMon *daycareMon)
|
||||
void StorePokemonInDaycare(struct Pokemon *mon, struct DaycareMon *daycareMon)
|
||||
{
|
||||
if (MonHasMail(mon))
|
||||
{
|
||||
@ -986,9 +987,12 @@ STATIC_ASSERT(P_SCATTERBUG_LINE_FORM_BREED == SPECIES_SCATTERBUG_ICY_SNOW || (P_
|
||||
|
||||
static u16 DetermineEggSpeciesAndParentSlots(struct DayCare *daycare, u8 *parentSlots)
|
||||
{
|
||||
u16 i;
|
||||
u16 species[DAYCARE_MON_COUNT];
|
||||
u16 eggSpecies;
|
||||
u32 i;
|
||||
u32 species[DAYCARE_MON_COUNT];
|
||||
u32 eggSpecies, parentSpecies;
|
||||
bool32 hasMotherEverstone, hasFatherEverstone, motherIsForeign, fatherIsForeign;
|
||||
bool32 motherEggSpecies, fatherEggSpecies;
|
||||
u32 currentRegion = GetCurrentRegion();
|
||||
|
||||
for (i = 0; i < DAYCARE_MON_COUNT; i++)
|
||||
{
|
||||
@ -1005,7 +1009,24 @@ static u16 DetermineEggSpeciesAndParentSlots(struct DayCare *daycare, u8 *parent
|
||||
}
|
||||
}
|
||||
|
||||
eggSpecies = GetEggSpecies(species[parentSlots[0]]);
|
||||
motherEggSpecies = GetEggSpecies(species[parentSlots[0]]);
|
||||
fatherEggSpecies = GetEggSpecies(species[parentSlots[1]]);
|
||||
hasMotherEverstone = ItemId_GetHoldEffect(GetBoxMonData(&daycare->mons[parentSlots[0]].mon, MON_DATA_HELD_ITEM)) == HOLD_EFFECT_PREVENT_EVOLVE;
|
||||
hasFatherEverstone = ItemId_GetHoldEffect(GetBoxMonData(&daycare->mons[parentSlots[1]].mon, MON_DATA_HELD_ITEM)) == HOLD_EFFECT_PREVENT_EVOLVE;
|
||||
motherIsForeign = IsSpeciesForeignRegionalForm(motherEggSpecies, currentRegion);
|
||||
fatherIsForeign = IsSpeciesForeignRegionalForm(fatherEggSpecies, currentRegion);
|
||||
|
||||
if (hasMotherEverstone)
|
||||
parentSpecies = motherEggSpecies;
|
||||
else if (fatherIsForeign && hasFatherEverstone)
|
||||
parentSpecies = fatherEggSpecies;
|
||||
else if (motherIsForeign)
|
||||
parentSpecies = GetRegionalFormByRegion(motherEggSpecies, currentRegion);
|
||||
else
|
||||
parentSpecies = motherEggSpecies;
|
||||
|
||||
eggSpecies = GetEggSpecies(parentSpecies);
|
||||
|
||||
if (eggSpecies == SPECIES_NIDORAN_F && daycare->offspringPersonality & EGG_GENDER_MALE)
|
||||
eggSpecies = SPECIES_NIDORAN_M;
|
||||
else if (eggSpecies == SPECIES_ILLUMISE && daycare->offspringPersonality & EGG_GENDER_MALE)
|
||||
@ -1050,6 +1071,9 @@ static void _GiveEggFromDaycare(struct DayCare *daycare)
|
||||
u8 parentSlots[DAYCARE_MON_COUNT] = {0};
|
||||
bool8 isEgg;
|
||||
|
||||
if (GetDaycareCompatibilityScore(daycare) == PARENTS_INCOMPATIBLE)
|
||||
return;
|
||||
|
||||
species = DetermineEggSpeciesAndParentSlots(daycare, parentSlots);
|
||||
if (P_INCENSE_BREEDING < GEN_9)
|
||||
AlterEggSpeciesWithIncenseItem(&species, daycare);
|
||||
|
||||
@ -59,6 +59,7 @@
|
||||
#include "constants/items.h"
|
||||
#include "constants/layouts.h"
|
||||
#include "constants/moves.h"
|
||||
#include "constants/regions.h"
|
||||
#include "constants/songs.h"
|
||||
#include "constants/trainers.h"
|
||||
#include "constants/union_room.h"
|
||||
@ -6987,3 +6988,70 @@ uq4_12_t GetDynamaxLevelHPMultiplier(u32 dynamaxLevel, bool32 inverseMultiplier)
|
||||
return UQ_4_12(1.0/(1.5 + 0.05 * dynamaxLevel));
|
||||
return UQ_4_12(1.5 + 0.05 * dynamaxLevel);
|
||||
}
|
||||
|
||||
bool32 IsSpeciesRegionalForm(u32 species)
|
||||
{
|
||||
return gSpeciesInfo[species].isAlolanForm
|
||||
|| gSpeciesInfo[species].isGalarianForm
|
||||
|| gSpeciesInfo[species].isHisuianForm
|
||||
|| gSpeciesInfo[species].isPaldeanForm;
|
||||
}
|
||||
|
||||
bool32 IsSpeciesRegionalFormFromRegion(u32 species, u32 region)
|
||||
{
|
||||
switch (region)
|
||||
{
|
||||
case REGION_ALOLA: return gSpeciesInfo[species].isAlolanForm;
|
||||
case REGION_GALAR: return gSpeciesInfo[species].isGalarianForm;
|
||||
case REGION_HISUI: return gSpeciesInfo[species].isHisuianForm;
|
||||
case REGION_PALDEA: return gSpeciesInfo[species].isPaldeanForm;
|
||||
default: return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
bool32 SpeciesHasRegionalForm(u32 species)
|
||||
{
|
||||
u32 formId;
|
||||
const u16 *formTable = GetSpeciesFormTable(species);
|
||||
for (formId = 0; formTable != NULL && formTable[formId] != FORM_SPECIES_END; formId++)
|
||||
{
|
||||
if (IsSpeciesRegionalForm(formTable[formId]))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
u32 GetRegionalFormByRegion(u32 species, u32 region)
|
||||
{
|
||||
u32 formId = 0;
|
||||
u32 firstFoundSpecies = 0;
|
||||
const u16 *formTable = GetSpeciesFormTable(species);
|
||||
|
||||
if (formTable != NULL)
|
||||
{
|
||||
for (formId = 0; formTable[formId] != FORM_SPECIES_END; formId++)
|
||||
{
|
||||
if (firstFoundSpecies == 0)
|
||||
firstFoundSpecies = formTable[formId];
|
||||
|
||||
if (IsSpeciesRegionalFormFromRegion(formTable[formId], region))
|
||||
return formTable[formId];
|
||||
}
|
||||
if (firstFoundSpecies != 0)
|
||||
return firstFoundSpecies;
|
||||
}
|
||||
return species;
|
||||
}
|
||||
|
||||
bool32 IsSpeciesForeignRegionalForm(u32 species, u32 currentRegion)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < REGIONS_COUNT; i++)
|
||||
{
|
||||
if (currentRegion != i && IsSpeciesRegionalFormFromRegion(species, i))
|
||||
return TRUE;
|
||||
else if (currentRegion == i && SpeciesHasRegionalForm(species) && !IsSpeciesRegionalFormFromRegion(species, i))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -2,5 +2,73 @@
|
||||
#include "test/battle.h"
|
||||
|
||||
// Remember to add a PARAMETRIZE for As One in the following tests:
|
||||
TO_DO_BATTLE_TEST("Unnerve prevents opposing Pokémon from eating their own berries");
|
||||
TO_DO_BATTLE_TEST("Unnerve doesn't prevent opposing Pokémon from using Natural Gift");
|
||||
SINGLE_BATTLE_TEST("Unnerve prevents opposing Pokémon from eating their own berries")
|
||||
{
|
||||
u16 mon;
|
||||
u16 ability;
|
||||
PARAMETRIZE { mon = SPECIES_JOLTIK, ability = ABILITY_UNNERVE; }
|
||||
PARAMETRIZE { mon = SPECIES_CALYREX_ICE, ability = ABILITY_AS_ONE_ICE_RIDER; }
|
||||
GIVEN {
|
||||
ASSUME(gItemsInfo[ITEM_RAWST_BERRY].holdEffect == HOLD_EFFECT_CURE_BRN);
|
||||
PLAYER(mon) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_RAWST_BERRY); Status1(STATUS1_BURN); }
|
||||
} WHEN {
|
||||
TURN { }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(player, ability);
|
||||
NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent);
|
||||
HP_BAR(opponent);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Unnerve doesn't prevent opposing Pokémon from using Natural Gift")
|
||||
{
|
||||
u16 mon;
|
||||
u16 ability;
|
||||
PARAMETRIZE { mon = SPECIES_JOLTIK, ability = ABILITY_UNNERVE; }
|
||||
PARAMETRIZE { mon = SPECIES_CALYREX_ICE, ability = ABILITY_AS_ONE_ICE_RIDER; }
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_NATURAL_GIFT].effect == EFFECT_NATURAL_GIFT);
|
||||
PLAYER(mon) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_ORAN_BERRY); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_NATURAL_GIFT); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(player, ability);
|
||||
HP_BAR(player);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Unnerve prints the correct string (player)")
|
||||
{
|
||||
u16 mon;
|
||||
u16 ability;
|
||||
PARAMETRIZE { mon = SPECIES_JOLTIK, ability = ABILITY_UNNERVE; }
|
||||
PARAMETRIZE { mon = SPECIES_CALYREX_ICE, ability = ABILITY_AS_ONE_ICE_RIDER; }
|
||||
GIVEN {
|
||||
PLAYER(mon) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN {}
|
||||
} SCENE {
|
||||
ABILITY_POPUP(player, ability);
|
||||
MESSAGE("The opposing team is too nervous to eat Berries!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Unnerve prints the correct string (opponent)")
|
||||
{
|
||||
u16 mon;
|
||||
u16 ability;
|
||||
PARAMETRIZE { mon = SPECIES_JOLTIK, ability = ABILITY_UNNERVE; }
|
||||
PARAMETRIZE { mon = SPECIES_CALYREX_ICE, ability = ABILITY_AS_ONE_ICE_RIDER; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(mon) { Ability(ability); }
|
||||
} WHEN {
|
||||
TURN {}
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponent, ability);
|
||||
MESSAGE("Your team is too nervous to eat Berries!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,12 +273,13 @@ DOUBLE_BATTLE_TEST("Red Card activates but fails if the attacker is rooted")
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerLeft);
|
||||
MESSAGE("Wobbuffet held up its Red Card against the opposing Wobbuffet!");
|
||||
MESSAGE("The opposing Wobbuffet anchored itself with its roots!");
|
||||
NOT MESSAGE("The opposing Unown was dragged out!");
|
||||
|
||||
// Red Card already consumed so cannot activate.
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponentRight);
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerRight);
|
||||
MESSAGE("Wynaut held up its Red Card against the opposing Wynaut!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerLeft);
|
||||
MESSAGE("Wobbuffet held up its Red Card against the opposing Wynaut!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -301,12 +302,41 @@ DOUBLE_BATTLE_TEST("Red Card activates but fails if the attacker has Suction Cup
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerLeft);
|
||||
MESSAGE("Wobbuffet held up its Red Card against the opposing Octillery!");
|
||||
MESSAGE("The opposing Octillery anchors itself with Suction Cups!");
|
||||
NOT MESSAGE("The opposing Unown was dragged out!");
|
||||
|
||||
// Red Card already consumed so cannot activate.
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponentRight);
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerRight);
|
||||
MESSAGE("Wynaut held up its Red Card against the opposing Wynaut!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerLeft);
|
||||
MESSAGE("Wobbuffet held up its Red Card against the opposing Wynaut!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Red Card activates but fails if the attacker has Guard Dog")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_OKIDOGI) { Ability(ABILITY_GUARD_DOG); }
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_UNOWN);
|
||||
} WHEN {
|
||||
TURN {
|
||||
MOVE(opponentLeft, MOVE_TACKLE, target: playerLeft);
|
||||
MOVE(opponentRight, MOVE_TACKLE, target: playerLeft);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerLeft);
|
||||
MESSAGE("Wobbuffet held up its Red Card against the opposing Okidogi!");
|
||||
NOT MESSAGE("The opposing Unown was dragged out!");
|
||||
|
||||
// Red Card already consumed so cannot activate.
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponentRight);
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerLeft);
|
||||
MESSAGE("Wobbuffet held up its Red Card against the opposing Wynaut!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,74 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
TO_DO_BATTLE_TEST("Electrify makes the target's move Electric-type for the remainder of the turn");
|
||||
TO_DO_BATTLE_TEST("Electrify can change status moves to Electric-type"); // Test type immunity
|
||||
SINGLE_BATTLE_TEST("Electrify makes the target's move Electric-type for the remainder of the turn (single move)")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gSpeciesInfo[SPECIES_SANDSLASH].types[0] == TYPE_GROUND || gSpeciesInfo[SPECIES_SANDSLASH].types[1] == TYPE_GROUND);
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].type != TYPE_ELECTRIC);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_SANDSLASH);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_ELECTRIFY); MOVE(player, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRIFY, opponent);
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Electrify makes the target's move Electric-type for the remainder of the turn (double move)")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
ASSUME(gSpeciesInfo[SPECIES_SANDSLASH].types[0] == TYPE_GROUND || gSpeciesInfo[SPECIES_SANDSLASH].types[1] == TYPE_GROUND);
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].type != TYPE_ELECTRIC);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_SANDSLASH);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_ELECTRIFY, target: playerLeft); MOVE(playerLeft, MOVE_TACKLE, target:opponentLeft); MOVE(playerRight, MOVE_INSTRUCT, target: playerLeft); MOVE(opponentRight, MOVE_CELEBRATE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRIFY, opponentLeft);
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_INSTRUCT, playerRight);
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerLeft);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Electrify can change status moves to Electric-type")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
ASSUME(gSpeciesInfo[SPECIES_SANDSLASH].types[0] == TYPE_GROUND || gSpeciesInfo[SPECIES_SANDSLASH].types[1] == TYPE_GROUND);
|
||||
ASSUME(gMovesInfo[MOVE_LEER].category == DAMAGE_CATEGORY_STATUS);
|
||||
ASSUME(gMovesInfo[MOVE_LEER].type != TYPE_ELECTRIC);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_SANDSLASH);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_ELECTRIFY); MOVE(player, MOVE_LEER); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRIFY, opponent);
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_LEER, player);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Electrify changes the type of foreseen moves")
|
||||
{
|
||||
KNOWN_FAILING;
|
||||
GIVEN {
|
||||
ASSUME(gSpeciesInfo[SPECIES_SANDSLASH].types[0] == TYPE_GROUND || gSpeciesInfo[SPECIES_SANDSLASH].types[1] == TYPE_GROUND);
|
||||
ASSUME(gMovesInfo[MOVE_FUTURE_SIGHT].effect == EFFECT_FUTURE_SIGHT);
|
||||
ASSUME(gMovesInfo[MOVE_FUTURE_SIGHT].type != TYPE_ELECTRIC);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_SANDSLASH);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_ELECTRIFY); MOVE(player, MOVE_FUTURE_SIGHT); }
|
||||
TURN {}
|
||||
TURN {}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRIFY, opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FUTURE_SIGHT, player);
|
||||
NOT HP_BAR(opponent);
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ SINGLE_BATTLE_TEST("Dragon Tail switches the target after Rocky Helmet and Iron
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dragon Tail effect will fails against Guard Dog ability")
|
||||
SINGLE_BATTLE_TEST("Dragon Tail effect fails against target with Guard Dog")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
@ -104,7 +104,7 @@ SINGLE_BATTLE_TEST("Dragon Tail effect will fails against Guard Dog ability")
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dragon Tail effect will fails against Suction Cups ability")
|
||||
SINGLE_BATTLE_TEST("Dragon Tail effect fails against target with Suction Cups")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
@ -114,6 +114,7 @@ SINGLE_BATTLE_TEST("Dragon Tail effect will fails against Suction Cups ability")
|
||||
TURN { MOVE(player, MOVE_DRAGON_TAIL); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_TAIL, player);
|
||||
ABILITY_POPUP(opponent, ABILITY_SUCTION_CUPS);
|
||||
MESSAGE("The opposing Octillery anchors itself with Suction Cups!");
|
||||
NOT MESSAGE("The opposing Charmander was dragged out!");
|
||||
}
|
||||
|
||||
@ -68,3 +68,38 @@ SINGLE_BATTLE_TEST("Roar fails if replacements fainted")
|
||||
MESSAGE("But it failed!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Roar fails against target with Guard Dog")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_OKIDOGI) { Ability(ABILITY_GUARD_DOG); }
|
||||
OPPONENT(SPECIES_CHARMANDER);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_ROAR); }
|
||||
} SCENE {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ROAR, player);
|
||||
MESSAGE("The opposing Charmander was dragged out!");
|
||||
}
|
||||
MESSAGE("Wobbuffet used Roar!");
|
||||
MESSAGE("But it failed!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Roar fails to switch out target with Suction Cups")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_OCTILLERY) { Ability(ABILITY_SUCTION_CUPS); }
|
||||
OPPONENT(SPECIES_CHARMANDER);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_ROAR); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Roar!");
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_ROAR, player);
|
||||
ABILITY_POPUP(opponent, ABILITY_SUCTION_CUPS);
|
||||
MESSAGE("The opposing Octillery anchors itself with Suction Cups!");
|
||||
NOT MESSAGE("The opposing Charmander was dragged out!");
|
||||
}
|
||||
}
|
||||
|
||||
164
test/daycare.c
Normal file
164
test/daycare.c
Normal file
@ -0,0 +1,164 @@
|
||||
#include "global.h"
|
||||
#include "daycare.h"
|
||||
#include "event_data.h"
|
||||
#include "malloc.h"
|
||||
#include "party_menu.h"
|
||||
#include "regions.h"
|
||||
#include "test/overworld_script.h"
|
||||
#include "test/test.h"
|
||||
|
||||
// We don't run the StoreSelectedPokemonInDaycare special because it relies on calling the
|
||||
// party select screen and the GetCursorSelectionMonId function, so we store directly to the struct.
|
||||
#define STORE_IN_DAYCARE_AND_GET_EGG() \
|
||||
StorePokemonInDaycare(&gPlayerParty[0], &gSaveBlock1Ptr->daycare.mons[0]); \
|
||||
StorePokemonInDaycare(&gPlayerParty[0], &gSaveBlock1Ptr->daycare.mons[1]); \
|
||||
RUN_OVERWORLD_SCRIPT( special GiveEggFromDaycare; );
|
||||
|
||||
TEST("(Daycare) Pokémon generate Eggs of the lowest member of the evolutionary family")
|
||||
{
|
||||
ASSUME(P_FAMILY_PIKACHU == TRUE);
|
||||
ASSUME(P_GEN_2_CROSS_EVOS == TRUE);
|
||||
|
||||
ZeroPlayerPartyMons();
|
||||
RUN_OVERWORLD_SCRIPT(
|
||||
givemon SPECIES_PIKACHU, 100, gender=MON_MALE;
|
||||
givemon SPECIES_PIKACHU, 100, gender=MON_FEMALE;
|
||||
);
|
||||
STORE_IN_DAYCARE_AND_GET_EGG();
|
||||
|
||||
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_PICHU);
|
||||
}
|
||||
|
||||
TEST("(Daycare) Pokémon offspring species is based off the mother's species")
|
||||
{
|
||||
u32 offspring = 0;
|
||||
ASSUME(P_FAMILY_PIKACHU == TRUE);
|
||||
ASSUME(P_GEN_2_CROSS_EVOS == TRUE);
|
||||
ASSUME(P_FAMILY_RIOLU == TRUE);
|
||||
|
||||
ZeroPlayerPartyMons();
|
||||
PARAMETRIZE { offspring = SPECIES_RIOLU; RUN_OVERWORLD_SCRIPT(givemon SPECIES_PIKACHU, 100, gender=MON_MALE; givemon SPECIES_LUCARIO, 100, gender=MON_FEMALE, item=ITEM_NONE; ); }
|
||||
PARAMETRIZE { offspring = SPECIES_PICHU; RUN_OVERWORLD_SCRIPT(givemon SPECIES_PIKACHU, 100, gender=MON_FEMALE; givemon SPECIES_LUCARIO, 100, gender=MON_MALE;); }
|
||||
STORE_IN_DAYCARE_AND_GET_EGG();
|
||||
|
||||
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), offspring);
|
||||
}
|
||||
|
||||
TEST("(Daycare) Pokémon can breed with Ditto if they don't belong to the Ditto or No Eggs Discovered group")
|
||||
{
|
||||
u32 j = 0;
|
||||
u32 parentSpecies = 0;
|
||||
|
||||
ZeroPlayerPartyMons();
|
||||
for (j = 1; j < NUM_SPECIES; j++)
|
||||
PARAMETRIZE { parentSpecies = j; }
|
||||
VarSet(VAR_TEMP_C, parentSpecies);
|
||||
RUN_OVERWORLD_SCRIPT(
|
||||
givemon SPECIES_DITTO, 100; givemon VAR_TEMP_C, 100;
|
||||
);
|
||||
STORE_IN_DAYCARE_AND_GET_EGG();
|
||||
|
||||
if (gSpeciesInfo[parentSpecies].eggGroups[0] != EGG_GROUP_NO_EGGS_DISCOVERED
|
||||
&& gSpeciesInfo[parentSpecies].eggGroups[0] != EGG_GROUP_DITTO)
|
||||
EXPECT_NE(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_NONE);
|
||||
else
|
||||
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_NONE);
|
||||
}
|
||||
|
||||
TEST("(Daycare) Shellos' form is always based on the mother's form")
|
||||
{
|
||||
u32 offspring = 0;
|
||||
ASSUME(P_FAMILY_MEOWTH == TRUE);
|
||||
ASSUME(P_ALOLAN_FORMS == TRUE);
|
||||
ASSUME(P_GALARIAN_FORMS == TRUE);
|
||||
|
||||
ZeroPlayerPartyMons();
|
||||
PARAMETRIZE { offspring = SPECIES_SHELLOS_WEST; RUN_OVERWORLD_SCRIPT(givemon SPECIES_SHELLOS_EAST, 1, gender=MON_MALE; givemon SPECIES_SHELLOS_WEST, 1, gender=MON_FEMALE, item=ITEM_NONE; ); }
|
||||
PARAMETRIZE { offspring = SPECIES_SHELLOS_WEST; RUN_OVERWORLD_SCRIPT(givemon SPECIES_SHELLOS_EAST, 1, gender=MON_MALE, item=ITEM_EVERSTONE; givemon SPECIES_SHELLOS_WEST, 1, gender=MON_FEMALE, item=ITEM_NONE; ); }
|
||||
PARAMETRIZE { offspring = SPECIES_SHELLOS_WEST; RUN_OVERWORLD_SCRIPT(givemon SPECIES_SHELLOS_EAST, 1, gender=MON_MALE; givemon SPECIES_SHELLOS_WEST, 1, gender=MON_FEMALE, item=ITEM_EVERSTONE;); }
|
||||
PARAMETRIZE { offspring = SPECIES_SHELLOS_EAST; RUN_OVERWORLD_SCRIPT(givemon SPECIES_SHELLOS_WEST, 1, gender=MON_MALE; givemon SPECIES_SHELLOS_EAST, 1, gender=MON_FEMALE, item=ITEM_NONE; ); }
|
||||
PARAMETRIZE { offspring = SPECIES_SHELLOS_EAST; RUN_OVERWORLD_SCRIPT(givemon SPECIES_SHELLOS_WEST, 1, gender=MON_MALE, item=ITEM_EVERSTONE; givemon SPECIES_SHELLOS_EAST, 1, gender=MON_FEMALE, item=ITEM_NONE; ); }
|
||||
PARAMETRIZE { offspring = SPECIES_SHELLOS_EAST; RUN_OVERWORLD_SCRIPT(givemon SPECIES_SHELLOS_WEST, 1, gender=MON_MALE; givemon SPECIES_SHELLOS_EAST, 1, gender=MON_FEMALE, item=ITEM_EVERSTONE;); }
|
||||
STORE_IN_DAYCARE_AND_GET_EGG();
|
||||
|
||||
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), offspring);
|
||||
}
|
||||
|
||||
TEST("(Daycare) Pokémon with regional forms give the correct offspring")
|
||||
{
|
||||
u32 region = 0, offspring = 0, species1 = 0, item1 = 0, species2 = 0, item2 = 0;
|
||||
|
||||
ZeroPlayerPartyMons();
|
||||
|
||||
region = GetCurrentRegion();
|
||||
if (region == REGION_ALOLA) {
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH_ALOLA; species1=SPECIES_MEOWTH; item1=ITEM_NONE; species2=SPECIES_MEOWTH_ALOLA; item2=ITEM_NONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH_ALOLA; species1=SPECIES_MEOWTH; item1=ITEM_NONE; species2=SPECIES_MEOWTH_ALOLA; item2=ITEM_EVERSTONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH_ALOLA; species1=SPECIES_MEOWTH; item1=ITEM_NONE; species2=SPECIES_MEOWTH_GALAR; item2=ITEM_NONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH_GALAR; species1=SPECIES_MEOWTH; item1=ITEM_NONE; species2=SPECIES_MEOWTH_GALAR; item2=ITEM_EVERSTONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH_ALOLA; species1=SPECIES_DIGLETT; item1=ITEM_NONE; species2=SPECIES_MEOWTH_GALAR; item2=ITEM_NONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH_GALAR; species1=SPECIES_DIGLETT; item1=ITEM_NONE; species2=SPECIES_MEOWTH_GALAR; item2=ITEM_EVERSTONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH_GALAR; species1=SPECIES_PERRSERKER; item1=ITEM_EVERSTONE; species2=SPECIES_PERSIAN; item2=ITEM_NONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH; species1=SPECIES_PERRSERKER; item1=ITEM_EVERSTONE; species2=SPECIES_PERSIAN; item2=ITEM_EVERSTONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH; species1=SPECIES_PERSIAN_ALOLA; item1=ITEM_EVERSTONE; species2=SPECIES_PERSIAN; item2=ITEM_EVERSTONE; }
|
||||
} else if (region == REGION_GALAR) {
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH_GALAR; species1=SPECIES_MEOWTH; item1=ITEM_NONE; species2=SPECIES_MEOWTH_ALOLA; item2=ITEM_NONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH_ALOLA; species1=SPECIES_MEOWTH; item1=ITEM_NONE; species2=SPECIES_MEOWTH_ALOLA; item2=ITEM_EVERSTONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH_GALAR; species1=SPECIES_MEOWTH; item1=ITEM_NONE; species2=SPECIES_MEOWTH_GALAR; item2=ITEM_NONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH_GALAR; species1=SPECIES_MEOWTH; item1=ITEM_NONE; species2=SPECIES_MEOWTH_GALAR; item2=ITEM_EVERSTONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH_GALAR; species1=SPECIES_DIGLETT; item1=ITEM_NONE; species2=SPECIES_MEOWTH_GALAR; item2=ITEM_NONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH_GALAR; species1=SPECIES_DIGLETT; item1=ITEM_NONE; species2=SPECIES_MEOWTH_GALAR; item2=ITEM_EVERSTONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH_GALAR; species1=SPECIES_PERRSERKER; item1=ITEM_EVERSTONE; species2=SPECIES_PERSIAN; item2=ITEM_NONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH; species1=SPECIES_PERRSERKER; item1=ITEM_EVERSTONE; species2=SPECIES_PERSIAN; item2=ITEM_EVERSTONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH; species1=SPECIES_PERSIAN_ALOLA; item1=ITEM_EVERSTONE; species2=SPECIES_PERSIAN; item2=ITEM_EVERSTONE; }
|
||||
} else {
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH; species1=SPECIES_MEOWTH; item1=ITEM_NONE; species2=SPECIES_MEOWTH_ALOLA, item2=ITEM_NONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH_ALOLA; species1=SPECIES_MEOWTH; item1=ITEM_NONE; species2=SPECIES_MEOWTH_ALOLA, item2=ITEM_EVERSTONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH; species1=SPECIES_MEOWTH; item1=ITEM_NONE; species2=SPECIES_MEOWTH_GALAR, item2=ITEM_NONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH_GALAR; species1=SPECIES_MEOWTH; item1=ITEM_NONE; species2=SPECIES_MEOWTH_GALAR, item2=ITEM_EVERSTONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH; species1=SPECIES_DIGLETT; item1=ITEM_NONE; species2=SPECIES_MEOWTH_GALAR, item2=ITEM_NONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH_GALAR; species1=SPECIES_DIGLETT; item1=ITEM_NONE; species2=SPECIES_MEOWTH_GALAR, item2=ITEM_EVERSTONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH_GALAR; species1=SPECIES_PERRSERKER; item1=ITEM_EVERSTONE; species2=SPECIES_PERSIAN, item2=ITEM_NONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH; species1=SPECIES_PERRSERKER; item1=ITEM_EVERSTONE; species2=SPECIES_PERSIAN, item2=ITEM_EVERSTONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_MEOWTH; species1=SPECIES_PERSIAN_ALOLA; item1=ITEM_EVERSTONE; species2=SPECIES_PERSIAN, item2=ITEM_EVERSTONE; }
|
||||
}
|
||||
|
||||
if (region == REGION_HISUI) {
|
||||
PARAMETRIZE { offspring=SPECIES_SNEASEL_HISUI; species1=SPECIES_SNEASEL; item1=ITEM_NONE; species2=SPECIES_SNEASEL_HISUI, item2=ITEM_NONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_SNEASEL; species1=SPECIES_SNEASEL; item1=ITEM_EVERSTONE; species2=SPECIES_SNEASEL_HISUI, item2=ITEM_NONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_SNEASEL_HISUI; species1=SPECIES_SNEASEL; item1=ITEM_NONE; species2=SPECIES_SNEASEL_HISUI, item2=ITEM_EVERSTONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_SNEASEL; species1=SPECIES_SNEASLER; item1=ITEM_EVERSTONE; species2=SPECIES_WEAVILE, item2=ITEM_EVERSTONE; }
|
||||
} else {
|
||||
PARAMETRIZE { offspring=SPECIES_SNEASEL; species1=SPECIES_SNEASEL; item1=ITEM_NONE; species2=SPECIES_SNEASEL_HISUI, item2=ITEM_NONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_SNEASEL; species1=SPECIES_SNEASEL; item1=ITEM_EVERSTONE; species2=SPECIES_SNEASEL_HISUI, item2=ITEM_NONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_SNEASEL_HISUI; species1=SPECIES_SNEASEL; item1=ITEM_NONE; species2=SPECIES_SNEASEL_HISUI, item2=ITEM_EVERSTONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_SNEASEL; species1=SPECIES_SNEASLER; item1=ITEM_EVERSTONE; species2=SPECIES_WEAVILE, item2=ITEM_EVERSTONE; }
|
||||
}
|
||||
|
||||
if (region == REGION_PALDEA) {
|
||||
PARAMETRIZE { offspring=SPECIES_WOOPER_PALDEA; species1=SPECIES_WOOPER; item1=ITEM_NONE; species2=SPECIES_WOOPER_PALDEA, item2=ITEM_NONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_WOOPER; species1=SPECIES_WOOPER; item1=ITEM_EVERSTONE; species2=SPECIES_WOOPER_PALDEA, item2=ITEM_NONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_WOOPER_PALDEA; species1=SPECIES_WOOPER; item1=ITEM_NONE; species2=SPECIES_WOOPER_PALDEA, item2=ITEM_EVERSTONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_WOOPER; species1=SPECIES_CLODSIRE; item1=ITEM_EVERSTONE; species2=SPECIES_QUAGSIRE, item2=ITEM_EVERSTONE; }
|
||||
} else {
|
||||
PARAMETRIZE { offspring=SPECIES_WOOPER; species1=SPECIES_WOOPER; item1=ITEM_NONE; species2=SPECIES_WOOPER_PALDEA, item2=ITEM_NONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_WOOPER; species1=SPECIES_WOOPER; item1=ITEM_EVERSTONE; species2=SPECIES_WOOPER_PALDEA, item2=ITEM_NONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_WOOPER_PALDEA; species1=SPECIES_WOOPER; item1=ITEM_NONE; species2=SPECIES_WOOPER_PALDEA, item2=ITEM_EVERSTONE; }
|
||||
PARAMETRIZE { offspring=SPECIES_WOOPER; species1=SPECIES_CLODSIRE; item1=ITEM_EVERSTONE; species2=SPECIES_QUAGSIRE, item2=ITEM_EVERSTONE; }
|
||||
}
|
||||
ASSUME(IsSpeciesEnabled(species1) == TRUE);
|
||||
ASSUME(IsSpeciesEnabled(species2) == TRUE);
|
||||
ASSUME(IsSpeciesEnabled(offspring) == TRUE);
|
||||
|
||||
VarSet(VAR_0x8000, species1);
|
||||
VarSet(VAR_0x8001, item1);
|
||||
VarSet(VAR_0x8002, species2);
|
||||
VarSet(VAR_0x8003, item2);
|
||||
|
||||
RUN_OVERWORLD_SCRIPT(givemon VAR_0x8000, 1, gender=MON_MALE, item=VAR_0x8001;);
|
||||
RUN_OVERWORLD_SCRIPT(givemon VAR_0x8002, 1, gender=MON_FEMALE, item=VAR_0x8003;);
|
||||
|
||||
STORE_IN_DAYCARE_AND_GET_EGG();
|
||||
|
||||
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), offspring);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user