diff --git a/include/pokemon.h b/include/pokemon.h index 8d2a17522..6ca390a48 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -865,6 +865,8 @@ bool32 IsSpeciesEnabled(u16 species); u32 GetUnownSpeciesId(u32 personality); u8 CalculatePartyCount(struct Pokemon *party); u16 GetFirstPartnerMove(u16 species); +void HealPokemon(struct Pokemon *mon); +void HealBoxPokemon(struct BoxPokemon *boxMon); const u8 *GetMoveName(u16 moveId); const u8 *GetMoveAnimationScript(u16 moveId); u16 KantoNumToSpecies(u16 kantoNum); diff --git a/include/pokemon_storage_system_internal.h b/include/pokemon_storage_system_internal.h index 9bd3434a2..95bc35c1b 100644 --- a/include/pokemon_storage_system_internal.h +++ b/include/pokemon_storage_system_internal.h @@ -16,9 +16,19 @@ enum { +#if OW_PC_MOVE_ORDER <= GEN_3 OPTION_WITHDRAW, OPTION_DEPOSIT, OPTION_MOVE_MONS, +#elif OW_PC_MOVE_ORDER >= GEN_4 && OW_PC_MOVE_ORDER <= GEN_6_XY + OPTION_DEPOSIT, + OPTION_WITHDRAW, + OPTION_MOVE_MONS, +#elif OW_PC_MOVE_ORDER >= GEN_7 + OPTION_MOVE_MONS, + OPTION_DEPOSIT, + OPTION_WITHDRAW, +#endif OPTION_MOVE_ITEMS, OPTION_EXIT, OPTIONS_COUNT @@ -494,6 +504,7 @@ void UnkUtil_Init(struct UnkUtil *arg0, struct UnkUtilData *arg1, u32 arg2); void UnkUtil_Run(void); void AddMenu(void); bool8 CanMovePartyMon(void); +bool8 CanPlaceMon(void); bool8 CanShiftMon(void); bool8 DoMonPlaceChange(void); bool8 DoWallpaperGfxChange(void); diff --git a/src/berry.c b/src/berry.c index 5c29b1794..5523d7cd1 100644 --- a/src/berry.c +++ b/src/berry.c @@ -90,6 +90,24 @@ static const u8 sBerryDescriptionPart2_Starf[] = _("せかいの はてに す static const u8 sBerryDescriptionPart1_Enigma[] = _("しょうたい ふめいの きのみ."); static const u8 sBerryDescriptionPart2_Enigma[] = _("ほしの ちからを もっている らしい."); +// Check include/config/overworld.h configs and throw an error if illegal +#if OW_BERRY_GROWTH_RATE < GEN_3 || (OW_BERRY_GROWTH_RATE > GEN_7 && OW_BERRY_GROWTH_RATE != GEN_6_ORAS) +#error "OW_BERRY_GROWTH_RATE must be between GEN_3 and GEN_7!" +#endif + +#if OW_BERRY_YIELD_RATE < GEN_3 || (OW_BERRY_YIELD_RATE > GEN_6 && OW_BERRY_YIELD_RATE != GEN_6_ORAS) +#error "OW_BERRY_YIELD_RATE must be between GEN_3 and GEN_6!" +#elif OW_BERRY_YIELD_RATE == GEN_5 +#error "OW_BERRY_YIELD_RATE can not be GEN_5!" +#endif + +#if OW_BERRY_MOISTURE && OW_BERRY_DRAIN_RATE != GEN_4 && OW_BERRY_DRAIN_RATE != GEN_6_XY && OW_BERRY_DRAIN_RATE != GEN_6_ORAS +#error "OW_BERRY_DRAIN_RATE must be GEN_5, GEN_6_XY or GEN_6_ORAS!" +#endif + +#define GROWTH_DURATION(g3, g4, g5, xy, oras, g7) OW_BERRY_GROWTH_RATE == GEN_3 ? g3 : OW_BERRY_GROWTH_RATE == GEN_4 ? g4 : OW_BERRY_GROWTH_RATE == GEN_5 ? g5 : OW_BERRY_GROWTH_RATE == GEN_6_XY ? xy : OW_BERRY_GROWTH_RATE == GEN_6_ORAS ? oras : g7 +#define YIELD_RATE(g3, g4, xy, oras) OW_BERRY_YIELD_RATE == GEN_3 ? g3 : OW_BERRY_YIELD_RATE == GEN_4 ? g4 : OW_BERRY_YIELD_RATE == GEN_6_XY ? xy : oras + const struct Berry gBerries[] = { [ITEM_CHERI_BERRY - FIRST_BERRY_INDEX] = { diff --git a/src/pokemon.c b/src/pokemon.c index 1addc9aa3..59e11332b 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -4667,6 +4667,32 @@ u16 HoennNumToSpecies(u16 hoennNum) return NationalDexNumToSpecies(HoennToNationalDexNum(hoennNum)); } +void HealPokemon(struct Pokemon *mon) +{ + u32 data; + + data = GetMonData(mon, MON_DATA_MAX_HP); + SetMonData(mon, MON_DATA_HP, &data); + + data = STATUS1_NONE; + SetMonData(mon, MON_DATA_STATUS, &data); + + MonRestorePP(mon); +} + +void HealBoxPokemon(struct BoxPokemon *boxMon) +{ + u32 data; + + data = 0; + SetBoxMonData(boxMon, MON_DATA_HP_LOST, &data); + + data = STATUS1_NONE; + SetBoxMonData(boxMon, MON_DATA_STATUS, &data); + + BoxMonRestorePP(boxMon); +} + u16 GetCryIdBySpecies(u16 species) { species = SanitizeSpeciesId(species); diff --git a/src/pokemon_storage_system_data.c b/src/pokemon_storage_system_data.c index 2e34ec5dc..f29d2ed4e 100644 --- a/src/pokemon_storage_system_data.c +++ b/src/pokemon_storage_system_data.c @@ -624,6 +624,9 @@ static void SetMovedMonData(u8 boxId, u8 position) static void SetPlacedMonData(u8 boxId, u8 position) { + if (OW_PC_HEAL <= GEN_7) + HealPokemon(&gStorage->movingMon); + if (boxId == TOTAL_BOXES_COUNT) gPlayerParty[position] = gStorage->movingMon; else @@ -716,6 +719,7 @@ bool8 TryHideReleaseMon(void) void ReleaseMon(void) { u8 boxId; + u16 item = ITEM_NONE; DestroyReleaseMonIcon(); if (sIsMonBeingMoved) @@ -723,11 +727,21 @@ void ReleaseMon(void) else { if (sCursorArea == CURSOR_AREA_IN_PARTY) + { boxId = TOTAL_BOXES_COUNT; + if (OW_PC_RELEASE_ITEM >= GEN_8) + item = GetMonData(&gPlayerParty[sCursorPosition], MON_DATA_HELD_ITEM); + } else + { boxId = StorageGetCurrentBox(); + if (OW_PC_RELEASE_ITEM >= GEN_8) + item = GetBoxMonDataAt(boxId, sCursorPosition, MON_DATA_HELD_ITEM); + } PurgeMonOrBoxMon(boxId, sCursorPosition); + if (item != ITEM_NONE) + AddBagItem(item, 1); } TrySetDisplayMonData(); } @@ -946,6 +960,20 @@ bool8 CanMovePartyMon(void) return FALSE; } +bool8 CanPlaceMon(void) +{ + if (sIsMonBeingMoved) + { + if (sCursorArea == CURSOR_AREA_IN_PARTY && GetMonData(&gPlayerParty[sCursorPosition], MON_DATA_SPECIES) == SPECIES_NONE) + return TRUE; + else if (sCursorArea == CURSOR_AREA_IN_BOX && GetBoxMonDataAt(StorageGetCurrentBox(), sCursorPosition, MON_DATA_SPECIES_OR_EGG) == SPECIES_NONE) + return TRUE; + else + return FALSE; + } + return FALSE; +} + bool8 CanShiftMon(void) { if (sIsMonBeingMoved) diff --git a/src/pokemon_storage_system_misc.c b/src/pokemon_storage_system_misc.c index 4cfc5170b..4c3ef768e 100644 --- a/src/pokemon_storage_system_misc.c +++ b/src/pokemon_storage_system_misc.c @@ -525,6 +525,8 @@ static void MultiMove_SetPlacedMonData(void) u8 boxPosition = (IN_BOX_COLUMNS * i) + sMultiMove->minColumn; for (j = sMultiMove->minColumn; j < columnCount; j++) { + if (OW_PC_HEAL <= GEN_7) + HealBoxPokemon(&sMultiMove->boxMons[monArrayId]); if (GetBoxMonData(&sMultiMove->boxMons[monArrayId], MON_DATA_SANITY_HAS_SPECIES)) SetBoxMonAt(boxId, boxPosition, &sMultiMove->boxMons[monArrayId]); boxPosition++; diff --git a/src/pokemon_storage_system_tasks.c b/src/pokemon_storage_system_tasks.c index fc28cbc5d..d45101592 100644 --- a/src/pokemon_storage_system_tasks.c +++ b/src/pokemon_storage_system_tasks.c @@ -1992,9 +1992,21 @@ static void Task_OnBPressed(u8 taskId) case 0: if (IsMonBeingMoved()) { - PlaySE(SE_FAILURE); - PrintStorageMessage(MSG_HOLDING_POKE); - gStorage->state = 1; + if (OW_PC_PRESS_B < GEN_4) + { + PlaySE(SE_FAILURE); + PrintStorageMessage(MSG_HOLDING_POKE); + gStorage->state = 1; + } + else if (CanPlaceMon()) + { + PlaySE(SE_SELECT); + SetPokeStorageTask(Task_PlaceMon); + } + else + { + SetPokeStorageTask(Task_PokeStorageMain); + } } else if (IsActiveItemMoving()) SetPokeStorageTask(Task_CloseBoxWhileHoldingItem); diff --git a/src/script_pokemon_util.c b/src/script_pokemon_util.c index 36509c005..5c6f413d7 100644 --- a/src/script_pokemon_util.c +++ b/src/script_pokemon_util.c @@ -11,6 +11,7 @@ #include "party_menu.h" #include "pokedex.h" #include "pokemon.h" +#include "pokemon_storage_system.h" #include "random.h" #include "script.h" #include "script_pokemon_util.h" @@ -21,42 +22,37 @@ static void CB2_ReturnFromChooseHalfParty(void); static void CB2_ReturnFromChooseBattleTowerParty(void); +static void HealPlayerBoxes(void); void HealPlayerParty(void) { - u8 i, j; - u8 ppBonuses; - u8 arg[4]; - - // restore HP. - for(i = 0; i < gPlayerPartyCount; i++) - { - u16 maxHP = GetMonData(&gPlayerParty[i], MON_DATA_MAX_HP); - arg[0] = maxHP; - arg[1] = maxHP >> 8; - SetMonData(&gPlayerParty[i], MON_DATA_HP, arg); - ppBonuses = GetMonData(&gPlayerParty[i], MON_DATA_PP_BONUSES); - - // restore PP. - for(j = 0; j < MAX_MON_MOVES; j++) - { - arg[0] = CalculatePPWithBonus(GetMonData(&gPlayerParty[i], MON_DATA_MOVE1 + j), ppBonuses, j); - SetMonData(&gPlayerParty[i], MON_DATA_PP1 + j, arg); - } - - // since status is u32, the four 0 assignments here are probably for safety to prevent undefined data from reaching SetMonData. - arg[0] = 0; - arg[1] = 0; - arg[2] = 0; - arg[3] = 0; - SetMonData(&gPlayerParty[i], MON_DATA_STATUS, arg); - } + u32 i; + for (i = 0; i < gPlayerPartyCount; i++) + HealPokemon(&gPlayerParty[i]); + if (OW_PC_HEAL >= GEN_8) + HealPlayerBoxes(); // Recharge Tera Orb, if possible. if (B_FLAG_TERA_ORB_CHARGED != 0 && CheckBagHasItem(ITEM_TERA_ORB, 1)) FlagSet(B_FLAG_TERA_ORB_CHARGED); } +static void HealPlayerBoxes(void) +{ + int boxId, boxPosition; + struct BoxPokemon *boxMon; + + for (boxId = 0; boxId < TOTAL_BOXES_COUNT; boxId++) + { + for (boxPosition = 0; boxPosition < IN_BOX_COUNT; boxPosition++) + { + boxMon = &gPokemonStoragePtr->boxes[boxId][boxPosition]; + if (GetBoxMonData(boxMon, MON_DATA_SANITY_HAS_SPECIES)) + HealBoxPokemon(boxMon); + } + } +} + void CanHyperTrain(struct ScriptContext *ctx) { u32 stat = ScriptReadByte(ctx);