mirror of
https://github.com/pret/pokefirered.git
synced 2026-09-30 12:59:43 -05:00
daycare updates
This commit is contained in:
@@ -29,5 +29,6 @@ void EggHatch(void);
|
||||
u8 GetEggStepsToSubtract(void);
|
||||
bool8 ShouldEggHatch(void);
|
||||
u8 GetEggCyclesToSubtract(void);
|
||||
u8 GetEggMovesBySpecies(u16 species, u16 *eggMoves);
|
||||
|
||||
#endif // GUARD_DAYCARE_H
|
||||
|
||||
@@ -694,9 +694,11 @@ void CalculateMonStats(struct Pokemon *mon);
|
||||
void BoxMonToMon(const struct BoxPokemon *src, struct Pokemon *dest);
|
||||
u8 GetLevelFromBoxMonExp(struct BoxPokemon *boxMon);
|
||||
u16 GiveMoveToMon(struct Pokemon *mon, u16 move);
|
||||
u16 GiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move);
|
||||
u16 GiveMoveToBattleMon(struct BattlePokemon *mon, u16 move);
|
||||
void SetMonMoveSlot(struct Pokemon *mon, u16 move, u8 slot);
|
||||
void SetBattleMonMoveSlot(struct BattlePokemon *mon, u16 move, u8 slot);
|
||||
void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon);
|
||||
u16 MonTryLearningNewMove(struct Pokemon *mon, bool8 firstMove);
|
||||
u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove);
|
||||
void DeleteFirstMoveAndGiveMoveToMon(struct Pokemon *mon, u16 move);
|
||||
|
||||
177
src/daycare.c
177
src/daycare.c
@@ -1,4 +1,5 @@
|
||||
#include "global.h"
|
||||
#include "pokemon.h"
|
||||
#include "gflib.h"
|
||||
#include "data.h"
|
||||
#include "battle.h"
|
||||
@@ -61,6 +62,8 @@ static void SetInitialEggData(struct Pokemon *mon, u16 species, struct DayCare *
|
||||
static u8 GetDaycareCompatibilityScore(struct DayCare *daycare);
|
||||
static void DaycarePrintMonInfo(u8 windowId, u32 daycareSlotId, u8 y);
|
||||
static u8 ModifyBreedingScoreForOvalCharm(u8 score);
|
||||
static u8 GetEggMoves(struct Pokemon *pokemon, u16 *eggMoves);
|
||||
static u16 GetEggSpecies(u16 species);
|
||||
|
||||
static void Task_EggHatch(u8 taskID);
|
||||
static void CB2_EggHatch_0(void);
|
||||
@@ -126,6 +129,24 @@ static const struct ListMenuTemplate sDaycareListMenuLevelTemplate =
|
||||
.cursorKind = 0
|
||||
};
|
||||
|
||||
static const struct {
|
||||
u16 currSpecies;
|
||||
u16 item;
|
||||
u16 babySpecies;
|
||||
} sIncenseBabyTable[] =
|
||||
{
|
||||
// Regular offspring, Item, Incense Offspring
|
||||
{ SPECIES_WOBBUFFET, ITEM_LAX_INCENSE, SPECIES_WYNAUT },
|
||||
{ SPECIES_MARILL, ITEM_SEA_INCENSE, SPECIES_AZURILL },
|
||||
{ SPECIES_SNORLAX, ITEM_FULL_INCENSE, SPECIES_MUNCHLAX },
|
||||
{ SPECIES_CHANSEY, ITEM_LUCK_INCENSE, SPECIES_HAPPINY },
|
||||
{ SPECIES_MR_MIME, ITEM_ODD_INCENSE, SPECIES_MIME_JR },
|
||||
{ SPECIES_CHIMECHO, ITEM_PURE_INCENSE, SPECIES_CHINGLING },
|
||||
{ SPECIES_SUDOWOODO, ITEM_ROCK_INCENSE, SPECIES_BONSLY },
|
||||
{ SPECIES_ROSELIA, ITEM_ROSE_INCENSE, SPECIES_BUDEW },
|
||||
{ SPECIES_MANTINE, ITEM_WAVE_INCENSE, SPECIES_MANTYKE },
|
||||
};
|
||||
|
||||
static const u8 *const sCompatibilityMessages[] =
|
||||
{
|
||||
gDaycareText_GetAlongVeryWell,
|
||||
@@ -425,6 +446,71 @@ static s8 Daycare_FindEmptySpot(struct DayCare *daycare)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void ClearHatchedEggMoves(void)
|
||||
{
|
||||
u16 i;
|
||||
|
||||
for (i = 0; i < EGG_MOVES_ARRAY_COUNT; i++)
|
||||
sHatchedEggEggMoves[i] = MOVE_NONE;
|
||||
}
|
||||
|
||||
static void TransferEggMoves(void)
|
||||
{
|
||||
u32 i, j, k, l;
|
||||
u16 numEggMoves;
|
||||
|
||||
for (i = 0; i < DAYCARE_MON_COUNT; i++)
|
||||
{
|
||||
u16 moveLearnerSpecies = GetBoxMonData(&gSaveBlock1Ptr->daycare.mons[i].mon, MON_DATA_SPECIES);
|
||||
u16 eggSpecies = GetEggSpecies(moveLearnerSpecies);
|
||||
|
||||
if (!GetBoxMonData(&gSaveBlock1Ptr->daycare.mons[i].mon, MON_DATA_SANITY_HAS_SPECIES))
|
||||
continue;
|
||||
|
||||
// Prevent non-baby species from learning incense baby egg moves
|
||||
if (P_INCENSE_BREEDING < GEN_9 && eggSpecies != moveLearnerSpecies)
|
||||
{
|
||||
for (j = 0; j < ARRAY_COUNT(sIncenseBabyTable); j++)
|
||||
{
|
||||
if (sIncenseBabyTable[j].babySpecies == eggSpecies)
|
||||
{
|
||||
eggSpecies = sIncenseBabyTable[j].currSpecies;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ClearHatchedEggMoves();
|
||||
numEggMoves = GetEggMovesBySpecies(eggSpecies, sHatchedEggEggMoves);
|
||||
for (j = 0; j < numEggMoves; j++)
|
||||
{
|
||||
// Go through other Daycare mons
|
||||
for (k = 0; k < DAYCARE_MON_COUNT; k++)
|
||||
{
|
||||
u16 moveTeacherSpecies = GetBoxMonData(&gSaveBlock1Ptr->daycare.mons[k].mon, MON_DATA_SPECIES);
|
||||
|
||||
if (k == i || !GetBoxMonData(&gSaveBlock1Ptr->daycare.mons[k].mon, MON_DATA_SANITY_HAS_SPECIES))
|
||||
continue;
|
||||
|
||||
// Check if you can inherit from them
|
||||
if (GET_BASE_SPECIES_ID(moveTeacherSpecies) != GET_BASE_SPECIES_ID(moveLearnerSpecies)
|
||||
&& (P_EGG_MOVE_TRANSFER < GEN_9 || GetBoxMonData(&gSaveBlock1Ptr->daycare.mons[i].mon, MON_DATA_HELD_ITEM) != ITEM_MIRROR_HERB)
|
||||
)
|
||||
continue;
|
||||
|
||||
for (l = 0; l < MAX_MON_MOVES; l++)
|
||||
{
|
||||
if (GetBoxMonData(&gSaveBlock1Ptr->daycare.mons[k].mon, MON_DATA_MOVE1 + l) != sHatchedEggEggMoves[j])
|
||||
continue;
|
||||
|
||||
if (GiveMoveToBoxMon(&gSaveBlock1Ptr->daycare.mons[i].mon, sHatchedEggEggMoves[j]) == MON_HAS_MAX_MOVES)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void StorePokemonInDaycare(struct Pokemon *mon, struct DaycareMon *daycareMon)
|
||||
{
|
||||
if (MonHasMail(mon))
|
||||
@@ -433,20 +519,22 @@ static void StorePokemonInDaycare(struct Pokemon *mon, struct DaycareMon *daycar
|
||||
|
||||
StringCopy(daycareMon->mail.OT_name, gSaveBlock2Ptr->playerName);
|
||||
DayCare_GetMonNickname(mon, daycareMon->mail.monName);
|
||||
// StripExtCtrlCodes(daycareMon->mail.monName);
|
||||
// daycareMon->mail.gameLanguage = LANGUAGE_ENGLISH;
|
||||
// daycareMon->mail.monLanguage = GetMonData(mon, MON_DATA_LANGUAGE);
|
||||
StripExtCtrlCodes(daycareMon->mail.monName);
|
||||
daycareMon->mail.gameLanguage = GAME_LANGUAGE;
|
||||
daycareMon->mail.monLanguage = GetMonData(mon, MON_DATA_LANGUAGE);
|
||||
mailId = GetMonData(mon, MON_DATA_MAIL);
|
||||
daycareMon->mail.message = gSaveBlock1Ptr->mail[mailId];
|
||||
TakeMailFromMon(mon);
|
||||
}
|
||||
|
||||
daycareMon->mon = mon->box;
|
||||
BoxMonRestorePP(&daycareMon->mon);
|
||||
daycareMon->steps = 0;
|
||||
ZeroMonData(mon);
|
||||
CompactPartySlots();
|
||||
CalculatePlayerPartyCount();
|
||||
|
||||
if (P_EGG_MOVE_TRANSFER >= GEN_8)
|
||||
TransferEggMoves();
|
||||
}
|
||||
|
||||
static void StorePokemonInEmptyDaycareSlot(struct Pokemon *mon, struct DayCare *daycare)
|
||||
@@ -960,6 +1048,24 @@ static u8 GetEggMoves(struct Pokemon *pokemon, u16 *eggMoves)
|
||||
return numEggMoves;
|
||||
}
|
||||
|
||||
u8 GetEggMovesBySpecies(u16 species, u16 *eggMoves)
|
||||
{
|
||||
u16 numEggMoves;
|
||||
const u16 *eggMoveLearnset;
|
||||
u32 i;
|
||||
|
||||
numEggMoves = 0;
|
||||
eggMoveLearnset = GetSpeciesEggMoves(species);
|
||||
|
||||
for (i = 0; eggMoveLearnset[i] != MOVE_UNAVAILABLE; i++)
|
||||
{
|
||||
eggMoves[i] = eggMoveLearnset[i];
|
||||
numEggMoves++;
|
||||
}
|
||||
|
||||
return numEggMoves;
|
||||
}
|
||||
|
||||
static void BuildEggMoveset(struct Pokemon *egg, struct BoxPokemon *father, struct BoxPokemon *mother)
|
||||
{
|
||||
u16 numSharedParentMoves;
|
||||
@@ -974,8 +1080,7 @@ static void BuildEggMoveset(struct Pokemon *egg, struct BoxPokemon *father, stru
|
||||
sHatchedEggFatherMoves[i] = MOVE_NONE;
|
||||
sHatchedEggFinalMoves[i] = MOVE_NONE;
|
||||
}
|
||||
for (i = 0; i < EGG_MOVES_ARRAY_COUNT; i++)
|
||||
sHatchedEggEggMoves[i] = MOVE_NONE;
|
||||
ClearHatchedEggMoves();
|
||||
for (i = 0; i < EGG_LVL_UP_MOVES_ARRAY_COUNT; i++)
|
||||
sHatchedEggLevelUpMoves[i] = MOVE_NONE;
|
||||
|
||||
@@ -988,6 +1093,29 @@ static void BuildEggMoveset(struct Pokemon *egg, struct BoxPokemon *father, stru
|
||||
|
||||
numEggMoves = GetEggMoves(egg, sHatchedEggEggMoves);
|
||||
|
||||
if (P_MOTHER_EGG_MOVE_INHERITANCE >= GEN_6)
|
||||
{
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (sHatchedEggMotherMoves[i] != MOVE_NONE)
|
||||
{
|
||||
for (j = 0; j < numEggMoves; j++)
|
||||
{
|
||||
if (sHatchedEggMotherMoves[i] == sHatchedEggEggMoves[j])
|
||||
{
|
||||
if (GiveMoveToMon(egg, sHatchedEggMotherMoves[i]) == MON_HAS_MAX_MOVES)
|
||||
DeleteFirstMoveAndGiveMoveToMon(egg, sHatchedEggMotherMoves[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (sHatchedEggFatherMoves[i] != MOVE_NONE)
|
||||
@@ -1007,21 +1135,26 @@ static void BuildEggMoveset(struct Pokemon *egg, struct BoxPokemon *father, stru
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
|
||||
if (P_TM_INHERITANCE < GEN_6)
|
||||
{
|
||||
if (sHatchedEggFatherMoves[i] != MOVE_NONE)
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
for (j = 0; j < NUM_TECHNICAL_MACHINES + NUM_HIDDEN_MACHINES; j++)
|
||||
if (sHatchedEggFatherMoves[i] != MOVE_NONE)
|
||||
{
|
||||
u16 moveId = ItemIdToBattleMoveId(ITEM_TM01 + j);
|
||||
if (sHatchedEggFatherMoves[i] == moveId && CanLearnTeachableMove(GetMonData(egg, MON_DATA_SPECIES_OR_EGG), j))
|
||||
for (j = 0; j < NUM_TECHNICAL_MACHINES + NUM_HIDDEN_MACHINES; j++)
|
||||
{
|
||||
if (GiveMoveToMon(egg, sHatchedEggFatherMoves[i]) == MON_HAS_MAX_MOVES)
|
||||
DeleteFirstMoveAndGiveMoveToMon(egg, sHatchedEggFatherMoves[i]);
|
||||
u16 moveId = ItemIdToBattleMoveId(ITEM_TM01 + j);
|
||||
if (sHatchedEggFatherMoves[i] == moveId && CanLearnTeachableMove(GetMonData(egg, MON_DATA_SPECIES_OR_EGG), moveId))
|
||||
{
|
||||
if (GiveMoveToMon(egg, sHatchedEggFatherMoves[i]) == MON_HAS_MAX_MOVES)
|
||||
DeleteFirstMoveAndGiveMoveToMon(egg, sHatchedEggFatherMoves[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (sHatchedEggFatherMoves[i] == MOVE_NONE)
|
||||
@@ -1060,24 +1193,6 @@ void RejectEggFromDayCare(void)
|
||||
RemoveEggFromDayCare(&gSaveBlock1Ptr->daycare);
|
||||
}
|
||||
|
||||
static const struct {
|
||||
u16 currSpecies;
|
||||
u16 item;
|
||||
u16 babySpecies;
|
||||
} sIncenseBabyTable[] =
|
||||
{
|
||||
// Regular offspring, Item, Incense Offspring
|
||||
{ SPECIES_WOBBUFFET, ITEM_LAX_INCENSE, SPECIES_WYNAUT },
|
||||
{ SPECIES_MARILL, ITEM_SEA_INCENSE, SPECIES_AZURILL },
|
||||
{ SPECIES_SNORLAX, ITEM_FULL_INCENSE, SPECIES_MUNCHLAX },
|
||||
{ SPECIES_CHANSEY, ITEM_LUCK_INCENSE, SPECIES_HAPPINY },
|
||||
{ SPECIES_MR_MIME, ITEM_ODD_INCENSE, SPECIES_MIME_JR },
|
||||
{ SPECIES_CHIMECHO, ITEM_PURE_INCENSE, SPECIES_CHINGLING },
|
||||
{ SPECIES_SUDOWOODO, ITEM_ROCK_INCENSE, SPECIES_BONSLY },
|
||||
{ SPECIES_ROSELIA, ITEM_ROSE_INCENSE, SPECIES_BUDEW },
|
||||
{ SPECIES_MANTINE, ITEM_WAVE_INCENSE, SPECIES_MANTYKE },
|
||||
};
|
||||
|
||||
#if P_INCENSE_BREEDING < GEN_9
|
||||
static void AlterEggSpeciesWithIncenseItem(u16 *species, struct DayCare *daycare)
|
||||
{
|
||||
|
||||
@@ -64,9 +64,6 @@ static EWRAM_DATA struct MonSpritesGfxManager *sMonSpritesGfxManager = NULL;
|
||||
static union PokemonSubstruct *GetSubstruct(struct BoxPokemon *boxMon, u32 personality, u8 substructType);
|
||||
static bool8 IsPokemonStorageFull(void);
|
||||
static void EncryptBoxMon(struct BoxPokemon *boxMon);
|
||||
static void DeleteFirstMoveAndGiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move);
|
||||
static void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon);
|
||||
static u16 GiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move);
|
||||
static u8 GetLevelFromMonExp(struct Pokemon *mon);
|
||||
static u16 CalculateBoxMonChecksum(struct BoxPokemon *boxMon);
|
||||
static bool8 ShouldSkipFriendshipChange(void);
|
||||
@@ -1742,13 +1739,13 @@ u16 GiveMoveToMon(struct Pokemon *mon, u16 move)
|
||||
return GiveMoveToBoxMon(&mon->box, move);
|
||||
}
|
||||
|
||||
static u16 GiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move)
|
||||
u16 GiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move)
|
||||
{
|
||||
s32 i;
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
u16 existingMove = GetBoxMonData(boxMon, MON_DATA_MOVE1 + i, NULL);
|
||||
if (!existingMove)
|
||||
if (existingMove == MOVE_NONE)
|
||||
{
|
||||
SetBoxMonData(boxMon, MON_DATA_MOVE1 + i, &move);
|
||||
SetBoxMonData(boxMon, MON_DATA_PP1 + i, &gMovesInfo[move].pp);
|
||||
@@ -1800,21 +1797,53 @@ void SetBattleMonMoveSlot(struct BattlePokemon *mon, u16 move, u8 slot)
|
||||
mon->pp[slot] = gMovesInfo[move].pp;
|
||||
}
|
||||
|
||||
void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon)
|
||||
void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon) //Credit: AsparagusEduardo
|
||||
{
|
||||
u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL);
|
||||
s32 level = GetLevelFromBoxMonExp(boxMon);
|
||||
s32 i;
|
||||
u16 moves[MAX_MON_MOVES] = {MOVE_NONE};
|
||||
u8 addedMoves = 0;
|
||||
const struct LevelUpMove *learnset = GetSpeciesLevelUpLearnset(species);
|
||||
|
||||
for (i = 0; learnset[i].move != LEVEL_UP_MOVE_END; i++)
|
||||
{
|
||||
s32 j;
|
||||
bool32 alreadyKnown = FALSE;
|
||||
|
||||
if (learnset[i].level > level)
|
||||
break;
|
||||
if (learnset[i].level == 0)
|
||||
continue;
|
||||
if (GiveMoveToBoxMon(boxMon, learnset[i].move) == MON_HAS_MAX_MOVES)
|
||||
DeleteFirstMoveAndGiveMoveToBoxMon(boxMon, learnset[i].move);
|
||||
|
||||
for (j = 0; j < addedMoves; j++)
|
||||
{
|
||||
if (moves[j] == learnset[i].move)
|
||||
{
|
||||
alreadyKnown = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!alreadyKnown)
|
||||
{
|
||||
if (addedMoves < MAX_MON_MOVES)
|
||||
{
|
||||
moves[addedMoves] = learnset[i].move;
|
||||
addedMoves++;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; j < MAX_MON_MOVES - 1; j++)
|
||||
moves[j] = moves[j + 1];
|
||||
moves[MAX_MON_MOVES - 1] = learnset[i].move;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
SetBoxMonData(boxMon, MON_DATA_MOVE1 + i, &moves[i]);
|
||||
SetBoxMonData(boxMon, MON_DATA_PP1 + i, &gMovesInfo[moves[i]].pp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1905,33 +1934,6 @@ u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void DeleteFirstMoveAndGiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move)
|
||||
{
|
||||
s32 i;
|
||||
u16 moves[MAX_MON_MOVES];
|
||||
u8 pp[MAX_MON_MOVES];
|
||||
u8 ppBonuses;
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES - 1; i++)
|
||||
{
|
||||
moves[i] = GetBoxMonData(boxMon, MON_DATA_MOVE2 + i, NULL);
|
||||
pp[i] = GetBoxMonData(boxMon, MON_DATA_PP2 + i, NULL);
|
||||
}
|
||||
|
||||
ppBonuses = GetBoxMonData(boxMon, MON_DATA_PP_BONUSES, NULL);
|
||||
ppBonuses >>= 2;
|
||||
moves[MAX_MON_MOVES - 1] = move;
|
||||
pp[MAX_MON_MOVES - 1] = gMovesInfo[move].pp;
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
SetBoxMonData(boxMon, MON_DATA_MOVE1 + i, &moves[i]);
|
||||
SetBoxMonData(boxMon, MON_DATA_PP1 + i, &pp[i]);
|
||||
}
|
||||
|
||||
SetBoxMonData(boxMon, MON_DATA_PP_BONUSES, &ppBonuses);
|
||||
}
|
||||
|
||||
u8 CountAliveMonsInBattle(u8 caseId, u32 battler)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
Reference in New Issue
Block a user