diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 537d92ba52..a72e6617a4 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -4612,7 +4612,7 @@ BattleScript_EffectFutureSight:: goto BattleScript_MoveEnd BattleScript_EffectTeleport:: -.if B_TELEPORT_BEHAVIOR >= GEN_7 +.if B_TELEPORT_BEHAVIOR >= GEN_8 jumpifbattletype BATTLE_TYPE_TRAINER, BattleScript_EffectBatonPass jumpifside BS_ATTACKER, B_SIDE_PLAYER, BattleScript_EffectBatonPass .else diff --git a/include/config/battle.h b/include/config/battle.h index 5ec007e686..58ff0e764c 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -103,7 +103,7 @@ // Draining abilities will not heal but will prevent damage. In Gen6+, Heal Block prevents the use of most HP-draining moves. #define B_ROOTED_GROUNDING GEN_LATEST // In Gen4+, Ingrain causes the affected Pokémon to become grounded. #define B_METRONOME_MOVES GEN_LATEST // This config will determine up to which generation will Metronome pull moves from. -#define B_TELEPORT_BEHAVIOR GEN_LATEST // In Gen7+, starting with Pokémon LGPE, Teleport allows the user to swap out with another party member. +#define B_TELEPORT_BEHAVIOR GEN_LATEST // In LGPE onwards (Gen8+ here), Teleport allows the user to swap out with another party member. #define B_BEAT_UP GEN_LATEST // In Gen5+, Beat Up uses a different formula to calculate its damage, and deals Dark-type damage. Prior to Gen 5, each hit also announces the party member's name. #define B_DARK_VOID_FAIL GEN_LATEST // In Gen7+, only Darkrai can use Dark Void. #define B_BURN_HIT_THAW GEN_LATEST // In Gen6+, damaging moves with a chance of burn will thaw the target, regardless if they're fire-type moves or not. diff --git a/include/config/item.h b/include/config/item.h index 36b2fe7d25..9b2f4156d8 100644 --- a/include/config/item.h +++ b/include/config/item.h @@ -17,6 +17,7 @@ #define I_PRICE GEN_LATEST // Some items have varied in value across generations. #define I_BERRY_PRICE GEN_7 // Since Berries have become unplantable (Gen8+), their price has gone up. #define I_POWER_ITEM_BOOST GEN_LATEST // In Gen7+, Power Items grant 8 EVs instead of 4 EVs. +#define I_PREMIER_BALL_BONUS GEN_LATEST // In LGPE onwards (Gen8+ here), you are given a Premier Ball for every 10 Poké Balls of any type and in the same purchase. Previously, it only applied to regular Poké Balls and only 1 could be obtained per purchase. // TM config #define I_REUSABLE_TMS FALSE // In Gen5-8, TMs are reusable. Setting this to TRUE will make all vanilla TMs reusable, though they can also be cherry-picked by setting their importance to 1. diff --git a/include/item.h b/include/item.h index e3a91d333e..53121d1127 100644 --- a/include/item.h +++ b/include/item.h @@ -43,6 +43,7 @@ bool8 IsBagPocketNonEmpty(u8 pocket); bool8 CheckBagHasItem(u16 itemId, u16 count); bool8 HasAtLeastOneBerry(void); bool8 CheckBagHasSpace(u16 itemId, u16 count); +u32 GetFreeSpaceForItemInBag(u16 itemId); bool8 AddBagItem(u16 itemId, u16 count); bool8 RemoveBagItem(u16 itemId, u16 count); u8 GetPocketByItemId(u16 itemId); diff --git a/include/strings.h b/include/strings.h index 431f90df16..af0ee0bbba 100644 --- a/include/strings.h +++ b/include/strings.h @@ -1026,6 +1026,7 @@ extern const u8 gText_ThankYouIllSendItHome[]; extern const u8 gText_ThanksIllSendItHome[]; extern const u8 gText_SpaceForVar1Full[]; extern const u8 gText_ThrowInPremierBall[]; +extern const u8 gText_ThrowInPremierBalls[]; extern const u8 gText_ShopBuy[]; extern const u8 gText_ShopSell[]; extern const u8 gText_ShopQuit[]; diff --git a/src/item.c b/src/item.c index a90ed3aefa..c9318ee4a7 100644 --- a/src/item.c +++ b/src/item.c @@ -160,57 +160,39 @@ bool8 HasAtLeastOneBerry(void) bool8 CheckBagHasSpace(u16 itemId, u16 count) { - u8 i; - u8 pocket = ItemId_GetPocket(itemId) - 1; - u16 ownedCount; - if (ItemId_GetPocket(itemId) == POCKET_NONE) return FALSE; if (InBattlePyramid() || FlagGet(FLAG_STORING_ITEMS_IN_PYRAMID_BAG) == TRUE) return CheckPyramidBagHasSpace(itemId, count); + return GetFreeSpaceForItemInBag(itemId) >= count; +} + +u32 GetFreeSpaceForItemInBag(u16 itemId) +{ + u8 i; + u8 pocket = ItemId_GetPocket(itemId) - 1; + u16 ownedCount; + u32 spaceForItem = 0; + + if (ItemId_GetPocket(itemId) == POCKET_NONE) + return 0; + // Check space in any existing item slots that already contain this item for (i = 0; i < gBagPockets[pocket].capacity; i++) { if (gBagPockets[pocket].itemSlots[i].itemId == itemId) { ownedCount = GetBagItemQuantity(&gBagPockets[pocket].itemSlots[i].quantity); - if (ownedCount + count <= MAX_BAG_ITEM_CAPACITY) - return TRUE; - if (pocket == TMHM_POCKET || pocket == BERRIES_POCKET) - return FALSE; - count -= (MAX_BAG_ITEM_CAPACITY - ownedCount); - if (count == 0) - break; //should be return TRUE, but that doesn't match + spaceForItem += max(0, MAX_BAG_ITEM_CAPACITY - ownedCount); } - } - - // Check space in empty item slots - if (count > 0) - { - for (i = 0; i < gBagPockets[pocket].capacity; i++) + else if (gBagPockets[pocket].itemSlots[i].itemId == ITEM_NONE) { - if (gBagPockets[pocket].itemSlots[i].itemId == 0) - { - if (count > MAX_BAG_ITEM_CAPACITY) - { - if (pocket == TMHM_POCKET || pocket == BERRIES_POCKET) - return FALSE; - count -= MAX_BAG_ITEM_CAPACITY; - } - else - { - count = 0; //should be return TRUE, but that doesn't match - break; - } - } + spaceForItem += MAX_BAG_ITEM_CAPACITY; } - if (count > 0) - return FALSE; // No more item slots. The bag is full } - - return TRUE; + return spaceForItem; } bool8 AddBagItem(u16 itemId, u16 count) diff --git a/src/shop.c b/src/shop.c index b1557068b8..88d66a43e9 100644 --- a/src/shop.c +++ b/src/shop.c @@ -1159,13 +1159,31 @@ static void Task_ReturnToItemListAfterItemPurchase(u8 taskId) if (JOY_NEW(A_BUTTON | B_BUTTON)) { - PlaySE(SE_SELECT); - - // Purchasing 10+ Poke Balls gets the player a Premier Ball - if (tItemId == ITEM_POKE_BALL && tItemCount >= 10 && AddBagItem(ITEM_PREMIER_BALL, 1) == TRUE) - BuyMenuDisplayMessage(taskId, gText_ThrowInPremierBall, BuyMenuReturnToItemList); + u16 premierBallsToAdd = tItemCount / 10; + if (premierBallsToAdd >= 1 + && ((I_PREMIER_BALL_BONUS <= GEN_7 && tItemId == ITEM_POKE_BALL) + || (I_PREMIER_BALL_BONUS >= GEN_8 && (ItemId_GetPocket(tItemId) == POCKET_POKE_BALLS)))) + { + u32 spaceAvailable = GetFreeSpaceForItemInBag(ITEM_PREMIER_BALL); + if (spaceAvailable < premierBallsToAdd) + premierBallsToAdd = spaceAvailable; + } else + { + premierBallsToAdd = 0; + } + + PlaySE(SE_SELECT); + AddBagItem(ITEM_PREMIER_BALL, premierBallsToAdd); + if (premierBallsToAdd > 0) + { + ConvertIntToDecimalStringN(gStringVar1, premierBallsToAdd, STR_CONV_MODE_LEFT_ALIGN, MAX_ITEM_DIGITS); + BuyMenuDisplayMessage(taskId, (premierBallsToAdd >= 2 ? gText_ThrowInPremierBalls : gText_ThrowInPremierBall), BuyMenuReturnToItemList); + } + else + { BuyMenuReturnToItemList(taskId); + } } } diff --git a/src/strings.c b/src/strings.c index c98ff2519e..4fde380240 100644 --- a/src/strings.c +++ b/src/strings.c @@ -362,6 +362,7 @@ const u8 gText_SpaceForVar1Full[] = _("The space for {STR_VAR_1} is full.{PAUSE_ const u8 gText_AnythingElseICanHelp[] = _("Is there anything else I can help\nyou with?"); const u8 gText_CanIHelpWithAnythingElse[] = _("Can I help you with anything else?"); const u8 gText_ThrowInPremierBall[] = _("I'll throw in a PREMIER BALL, too.{PAUSE_UNTIL_PRESS}"); +const u8 gText_ThrowInPremierBalls[] = _("I'll throw in {STR_VAR_1} PREMIER BALLS, too.{PAUSE_UNTIL_PRESS}"); const u8 gText_CantBuyKeyItem[] = _("{STR_VAR_2}? Oh, no.\nI can't buy that.{PAUSE_UNTIL_PRESS}"); const u8 gText_HowManyToSell[] = _("{STR_VAR_2}?\nHow many would you like to sell?"); const u8 gText_ICanPayVar1[] = _("I can pay ¥{STR_VAR_1}.\nWould that be okay?");