2017-09-03 00:47:51 +02:00
|
|
|
#include "global.h"
|
|
|
|
#include "item.h"
|
2018-01-19 19:49:08 +01:00
|
|
|
#include "berry.h"
|
2017-09-03 13:33:13 +02:00
|
|
|
#include "string_util.h"
|
|
|
|
#include "text.h"
|
|
|
|
#include "event_data.h"
|
2019-09-09 03:07:54 +02:00
|
|
|
#include "malloc.h"
|
2018-04-29 13:36:26 +02:00
|
|
|
#include "secret_base.h"
|
|
|
|
#include "item_menu.h"
|
2018-04-29 14:21:59 +02:00
|
|
|
#include "strings.h"
|
|
|
|
#include "load_save.h"
|
2018-12-03 13:37:32 +01:00
|
|
|
#include "item_use.h"
|
2018-11-18 17:52:22 +01:00
|
|
|
#include "battle_pyramid.h"
|
2018-08-30 20:10:57 +02:00
|
|
|
#include "battle_pyramid_bag.h"
|
2018-12-03 13:37:32 +01:00
|
|
|
#include "constants/items.h"
|
|
|
|
#include "constants/hold_effects.h"
|
2017-09-03 00:47:51 +02:00
|
|
|
|
2018-04-29 14:21:59 +02:00
|
|
|
extern u16 gUnknown_0203CF30[];
|
2017-09-03 00:47:51 +02:00
|
|
|
|
2018-04-29 13:36:26 +02:00
|
|
|
// this file's functions
|
|
|
|
static bool8 CheckPyramidBagHasItem(u16 itemId, u16 count);
|
|
|
|
static bool8 CheckPyramidBagHasSpace(u16 itemId, u16 count);
|
|
|
|
|
2018-04-29 14:21:59 +02:00
|
|
|
// EWRAM variables
|
|
|
|
EWRAM_DATA struct BagPocket gBagPockets[POCKETS_COUNT] = {0};
|
2017-09-03 00:47:51 +02:00
|
|
|
|
2018-12-03 13:37:32 +01:00
|
|
|
// rodata
|
|
|
|
#include "data/text/item_descriptions.h"
|
|
|
|
#include "data/items.h"
|
|
|
|
|
2018-04-29 14:21:59 +02:00
|
|
|
// code
|
|
|
|
static u16 GetBagItemQuantity(u16 *quantity)
|
2017-09-03 00:47:51 +02:00
|
|
|
{
|
|
|
|
return gSaveBlock2Ptr->encryptionKey ^ *quantity;
|
|
|
|
}
|
|
|
|
|
2018-04-29 14:21:59 +02:00
|
|
|
static void SetBagItemQuantity(u16 *quantity, u16 newValue)
|
2017-09-03 00:47:51 +02:00
|
|
|
{
|
|
|
|
*quantity = newValue ^ gSaveBlock2Ptr->encryptionKey;
|
|
|
|
}
|
|
|
|
|
2018-04-29 14:21:59 +02:00
|
|
|
static u16 GetPCItemQuantity(u16 *quantity)
|
2017-09-03 00:47:51 +02:00
|
|
|
{
|
2018-04-29 13:36:26 +02:00
|
|
|
return *quantity;
|
2017-09-03 00:47:51 +02:00
|
|
|
}
|
|
|
|
|
2018-04-29 14:21:59 +02:00
|
|
|
static void SetPCItemQuantity(u16 *quantity, u16 newValue)
|
2017-09-03 00:47:51 +02:00
|
|
|
{
|
2018-04-29 13:36:26 +02:00
|
|
|
*quantity = newValue;
|
2017-09-03 00:47:51 +02:00
|
|
|
}
|
|
|
|
|
2017-11-27 21:20:10 +01:00
|
|
|
void ApplyNewEncryptionKeyToBagItems(u32 newKey)
|
2017-09-03 00:47:51 +02:00
|
|
|
{
|
|
|
|
u32 pocket, item;
|
2018-04-29 13:36:26 +02:00
|
|
|
for (pocket = 0; pocket < POCKETS_COUNT; pocket++)
|
2017-09-03 00:47:51 +02:00
|
|
|
{
|
2017-09-03 13:33:13 +02:00
|
|
|
for (item = 0; item < gBagPockets[pocket].capacity; item++)
|
2017-11-27 21:20:10 +01:00
|
|
|
ApplyNewEncryptionKeyToHword(&(gBagPockets[pocket].itemSlots[item].quantity), newKey);
|
2017-09-03 00:47:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-27 21:20:10 +01:00
|
|
|
void ApplyNewEncryptionKeyToBagItems_(u32 newKey) // really GF?
|
2017-09-03 00:47:51 +02:00
|
|
|
{
|
2017-11-27 21:20:10 +01:00
|
|
|
ApplyNewEncryptionKeyToBagItems(newKey);
|
2017-09-03 00:47:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void SetBagItemsPointers(void)
|
|
|
|
{
|
2017-09-03 13:33:13 +02:00
|
|
|
gBagPockets[ITEMS_POCKET].itemSlots = gSaveBlock1Ptr->bagPocket_Items;
|
2018-04-29 13:36:26 +02:00
|
|
|
gBagPockets[ITEMS_POCKET].capacity = BAG_ITEMS_COUNT;
|
2017-09-03 00:47:51 +02:00
|
|
|
|
2017-09-03 13:33:13 +02:00
|
|
|
gBagPockets[KEYITEMS_POCKET].itemSlots = gSaveBlock1Ptr->bagPocket_KeyItems;
|
2018-04-29 13:36:26 +02:00
|
|
|
gBagPockets[KEYITEMS_POCKET].capacity = BAG_KEYITEMS_COUNT;
|
2017-09-03 00:47:51 +02:00
|
|
|
|
2017-09-03 13:33:13 +02:00
|
|
|
gBagPockets[BALLS_POCKET].itemSlots = gSaveBlock1Ptr->bagPocket_PokeBalls;
|
2018-04-29 13:36:26 +02:00
|
|
|
gBagPockets[BALLS_POCKET].capacity = BAG_POKEBALLS_COUNT;
|
2017-09-03 13:33:13 +02:00
|
|
|
|
|
|
|
gBagPockets[TMHM_POCKET].itemSlots = gSaveBlock1Ptr->bagPocket_TMHM;
|
2018-04-29 13:36:26 +02:00
|
|
|
gBagPockets[TMHM_POCKET].capacity = BAG_TMHM_COUNT;
|
2017-09-03 13:33:13 +02:00
|
|
|
|
|
|
|
gBagPockets[BERRIES_POCKET].itemSlots = gSaveBlock1Ptr->bagPocket_Berries;
|
2018-04-29 13:36:26 +02:00
|
|
|
gBagPockets[BERRIES_POCKET].capacity = BAG_BERRIES_COUNT;
|
2017-09-03 13:33:13 +02:00
|
|
|
}
|
|
|
|
|
2018-04-29 14:21:59 +02:00
|
|
|
void CopyItemName(u16 itemId, u8 *dst)
|
2017-09-03 13:33:13 +02:00
|
|
|
{
|
2018-04-29 14:21:59 +02:00
|
|
|
StringCopy(dst, ItemId_GetName(itemId));
|
2017-09-03 13:33:13 +02:00
|
|
|
}
|
2017-09-03 00:47:51 +02:00
|
|
|
|
2018-04-29 14:21:59 +02:00
|
|
|
void CopyItemNameHandlePlural(u16 itemId, u8 *dst, u32 quantity)
|
2017-09-03 13:33:13 +02:00
|
|
|
{
|
2017-09-13 11:16:26 +02:00
|
|
|
if (itemId == ITEM_POKE_BALL)
|
2017-09-03 13:33:13 +02:00
|
|
|
{
|
|
|
|
if (quantity < 2)
|
2018-04-29 14:21:59 +02:00
|
|
|
StringCopy(dst, ItemId_GetName(ITEM_POKE_BALL));
|
2017-09-03 13:33:13 +02:00
|
|
|
else
|
2018-04-29 14:21:59 +02:00
|
|
|
StringCopy(dst, gText_PokeBalls);
|
2017-09-03 13:33:13 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-01-19 19:39:18 +01:00
|
|
|
if (itemId >= FIRST_BERRY_INDEX && itemId <= LAST_BERRY_INDEX)
|
|
|
|
GetBerryCountString(dst, gBerries[itemId - FIRST_BERRY_INDEX].name, quantity);
|
2017-09-03 13:33:13 +02:00
|
|
|
else
|
2018-04-29 14:21:59 +02:00
|
|
|
StringCopy(dst, ItemId_GetName(itemId));
|
2017-09-03 13:33:13 +02:00
|
|
|
}
|
|
|
|
}
|
2017-09-03 00:47:51 +02:00
|
|
|
|
2018-04-29 13:36:26 +02:00
|
|
|
void GetBerryCountString(u8 *dst, const u8 *berryName, u32 quantity)
|
2017-09-03 13:33:13 +02:00
|
|
|
{
|
2018-04-29 13:36:26 +02:00
|
|
|
const u8 *berryString;
|
|
|
|
u8 *txtPtr;
|
2017-09-03 13:33:13 +02:00
|
|
|
|
|
|
|
if (quantity < 2)
|
2017-09-20 21:38:05 +02:00
|
|
|
berryString = gText_Berry;
|
2017-09-03 13:33:13 +02:00
|
|
|
else
|
2017-09-20 21:38:05 +02:00
|
|
|
berryString = gText_Berries;
|
2018-04-29 13:36:26 +02:00
|
|
|
|
2017-09-03 13:33:13 +02:00
|
|
|
txtPtr = StringCopy(dst, berryName);
|
|
|
|
*txtPtr = CHAR_SPACE;
|
|
|
|
StringCopy(txtPtr + 1, berryString);
|
2017-09-03 00:47:51 +02:00
|
|
|
}
|
2017-09-03 13:33:13 +02:00
|
|
|
|
|
|
|
bool8 IsBagPocketNonEmpty(u8 pocket)
|
|
|
|
{
|
|
|
|
u8 i;
|
|
|
|
|
|
|
|
for (i = 0; i < gBagPockets[pocket - 1].capacity; i++)
|
|
|
|
{
|
|
|
|
if (gBagPockets[pocket - 1].itemSlots[i].itemId != 0)
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 CheckBagHasItem(u16 itemId, u16 count)
|
|
|
|
{
|
|
|
|
u8 i;
|
|
|
|
u8 pocket;
|
|
|
|
|
|
|
|
if (ItemId_GetPocket(itemId) == 0)
|
|
|
|
return FALSE;
|
2019-10-18 01:22:03 +02:00
|
|
|
if (InBattlePyramid() || FlagGet(FLAG_STORING_ITEMS_IN_PYRAMID_BAG) == TRUE)
|
2017-09-03 13:33:13 +02:00
|
|
|
return CheckPyramidBagHasItem(itemId, count);
|
|
|
|
pocket = ItemId_GetPocket(itemId) - 1;
|
2018-04-29 13:36:26 +02:00
|
|
|
// Check for item slots that contain the item
|
2017-09-03 13:33:13 +02:00
|
|
|
for (i = 0; i < gBagPockets[pocket].capacity; i++)
|
|
|
|
{
|
|
|
|
if (gBagPockets[pocket].itemSlots[i].itemId == itemId)
|
|
|
|
{
|
|
|
|
u16 quantity;
|
2018-04-29 14:21:59 +02:00
|
|
|
// Does this item slot contain enough of the item?
|
2017-09-03 13:33:13 +02:00
|
|
|
quantity = GetBagItemQuantity(&gBagPockets[pocket].itemSlots[i].quantity);
|
|
|
|
if (quantity >= count)
|
|
|
|
return TRUE;
|
|
|
|
count -= quantity;
|
2018-04-29 14:21:59 +02:00
|
|
|
// Does this item slot and all previous slots contain enough of the item?
|
2017-09-03 13:33:13 +02:00
|
|
|
if (count == 0)
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 HasAtLeastOneBerry(void)
|
|
|
|
{
|
|
|
|
u16 i;
|
2018-04-29 13:36:26 +02:00
|
|
|
|
|
|
|
for (i = FIRST_BERRY_INDEX; i < ITEM_BRIGHT_POWDER; i++)
|
2017-09-03 13:33:13 +02:00
|
|
|
{
|
|
|
|
if (CheckBagHasItem(i, 1) == TRUE)
|
|
|
|
{
|
2018-04-29 13:36:26 +02:00
|
|
|
gSpecialVar_Result = TRUE;
|
2017-09-03 13:33:13 +02:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
2018-04-29 13:36:26 +02:00
|
|
|
gSpecialVar_Result = FALSE;
|
2017-09-03 13:33:13 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 CheckBagHasSpace(u16 itemId, u16 count)
|
|
|
|
{
|
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
|
|
|
u8 i;
|
2020-10-26 04:19:56 +01:00
|
|
|
u8 pocket;
|
|
|
|
u16 slotCapacity;
|
|
|
|
u16 ownedCount;
|
2017-09-03 13:33:13 +02:00
|
|
|
|
2018-04-29 13:36:26 +02:00
|
|
|
if (ItemId_GetPocket(itemId) == POCKET_NONE)
|
2017-09-03 13:33:13 +02:00
|
|
|
return FALSE;
|
2018-04-29 13:36:26 +02:00
|
|
|
|
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
|
|
|
if (InBattlePyramid() || FlagGet(FLAG_STORING_ITEMS_IN_PYRAMID_BAG) == TRUE)
|
2018-04-29 13:36:26 +02:00
|
|
|
{
|
2017-09-03 13:33:13 +02:00
|
|
|
return CheckPyramidBagHasSpace(itemId, count);
|
2018-04-29 13:36:26 +02:00
|
|
|
}
|
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
|
|
|
|
2020-10-26 04:19:56 +01:00
|
|
|
pocket = ItemId_GetPocket(itemId) - 1;
|
|
|
|
if (pocket != BERRIES_POCKET)
|
|
|
|
slotCapacity = MAX_BAG_ITEM_CAPACITY;
|
|
|
|
else
|
|
|
|
slotCapacity = MAX_BERRY_CAPACITY;
|
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
|
|
|
|
2020-10-26 04:19:56 +01:00
|
|
|
// 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)
|
2018-04-29 13:36:26 +02:00
|
|
|
{
|
2020-10-26 04:19:56 +01:00
|
|
|
ownedCount = GetBagItemQuantity(&gBagPockets[pocket].itemSlots[i].quantity);
|
|
|
|
if (ownedCount + count <= slotCapacity)
|
|
|
|
return TRUE;
|
|
|
|
if (pocket == TMHM_POCKET || pocket == BERRIES_POCKET)
|
|
|
|
return FALSE;
|
|
|
|
count -= (slotCapacity - ownedCount);
|
|
|
|
if (count == 0)
|
|
|
|
break; //should be return TRUE, but that doesn't match
|
2018-04-29 13:36:26 +02:00
|
|
|
}
|
2020-10-26 04:19:56 +01:00
|
|
|
}
|
2018-04-29 13:36:26 +02:00
|
|
|
|
2020-10-26 04:19:56 +01:00
|
|
|
// Check space in empty item slots
|
|
|
|
if (count > 0)
|
|
|
|
{
|
|
|
|
for (i = 0; i < gBagPockets[pocket].capacity; i++)
|
2018-04-29 13:36:26 +02:00
|
|
|
{
|
2020-10-26 04:19:56 +01:00
|
|
|
if (gBagPockets[pocket].itemSlots[i].itemId == 0)
|
2018-04-29 13:36:26 +02:00
|
|
|
{
|
2020-10-26 04:19:56 +01:00
|
|
|
if (count > slotCapacity)
|
2018-04-29 13:36:26 +02:00
|
|
|
{
|
|
|
|
if (pocket == TMHM_POCKET || pocket == BERRIES_POCKET)
|
|
|
|
return FALSE;
|
|
|
|
count -= slotCapacity;
|
|
|
|
}
|
2020-10-26 04:19:56 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
count = 0; //should be return TRUE, but that doesn't match
|
|
|
|
break;
|
|
|
|
}
|
2018-04-29 13:36:26 +02:00
|
|
|
}
|
|
|
|
}
|
2020-10-26 04:19:56 +01:00
|
|
|
if (count > 0)
|
|
|
|
return FALSE; // No more item slots. The bag is full
|
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
|
|
|
}
|
2020-10-26 04:19:56 +01:00
|
|
|
|
|
|
|
return TRUE;
|
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
|
|
|
}
|
2018-04-29 13:36:26 +02:00
|
|
|
|
|
|
|
bool8 AddBagItem(u16 itemId, u16 count)
|
|
|
|
{
|
|
|
|
u8 i;
|
|
|
|
|
|
|
|
if (ItemId_GetPocket(itemId) == POCKET_NONE)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
// check Battle Pyramid Bag
|
2019-10-18 01:22:03 +02:00
|
|
|
if (InBattlePyramid() || FlagGet(FLAG_STORING_ITEMS_IN_PYRAMID_BAG) == TRUE)
|
2017-09-03 13:33:13 +02:00
|
|
|
{
|
2018-04-29 13:36:26 +02:00
|
|
|
return AddPyramidBagItem(itemId, count);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
struct BagPocket *itemPocket;
|
|
|
|
struct ItemSlot *newItems;
|
|
|
|
u16 slotCapacity;
|
|
|
|
u16 ownedCount;
|
|
|
|
u8 pocket = ItemId_GetPocket(itemId) - 1;
|
|
|
|
|
|
|
|
itemPocket = &gBagPockets[pocket];
|
|
|
|
newItems = AllocZeroed(itemPocket->capacity * sizeof(struct ItemSlot));
|
|
|
|
memcpy(newItems, itemPocket->itemSlots, itemPocket->capacity * sizeof(struct ItemSlot));
|
|
|
|
|
|
|
|
if (pocket != BERRIES_POCKET)
|
2020-01-26 10:02:15 +01:00
|
|
|
slotCapacity = MAX_BAG_ITEM_CAPACITY;
|
2018-04-29 13:36:26 +02:00
|
|
|
else
|
2020-01-26 10:02:15 +01:00
|
|
|
slotCapacity = MAX_BERRY_CAPACITY;
|
2018-04-29 13:36:26 +02:00
|
|
|
|
|
|
|
for (i = 0; i < itemPocket->capacity; i++)
|
2017-09-03 13:33:13 +02:00
|
|
|
{
|
2018-04-29 13:36:26 +02:00
|
|
|
if (newItems[i].itemId == itemId)
|
|
|
|
{
|
|
|
|
ownedCount = GetBagItemQuantity(&newItems[i].quantity);
|
|
|
|
// check if won't exceed max slot capacity
|
|
|
|
if (ownedCount + count <= slotCapacity)
|
|
|
|
{
|
|
|
|
// successfully added to already existing item's count
|
|
|
|
SetBagItemQuantity(&newItems[i].quantity, ownedCount + count);
|
|
|
|
memcpy(itemPocket->itemSlots, newItems, itemPocket->capacity * sizeof(struct ItemSlot));
|
|
|
|
Free(newItems);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// try creating another instance of the item if possible
|
|
|
|
if (pocket == TMHM_POCKET || pocket == BERRIES_POCKET)
|
|
|
|
{
|
|
|
|
Free(newItems);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
count -= slotCapacity - ownedCount;
|
|
|
|
SetBagItemQuantity(&newItems[i].quantity, slotCapacity);
|
|
|
|
// don't create another instance of the item if it's at max slot capacity and count is equal to 0
|
|
|
|
if (count == 0)
|
|
|
|
{
|
2021-05-09 07:27:28 +02:00
|
|
|
break;
|
2018-04-29 13:36:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// we're done if quantity is equal to 0
|
|
|
|
if (count > 0)
|
|
|
|
{
|
|
|
|
// either no existing item was found or we have to create another instance, because the capacity was exceeded
|
|
|
|
for (i = 0; i < itemPocket->capacity; i++)
|
|
|
|
{
|
|
|
|
if (newItems[i].itemId == ITEM_NONE)
|
|
|
|
{
|
|
|
|
newItems[i].itemId = itemId;
|
|
|
|
if (count > slotCapacity)
|
|
|
|
{
|
|
|
|
// try creating a new slot with max capacity if duplicates are possible
|
|
|
|
if (pocket == TMHM_POCKET || pocket == BERRIES_POCKET)
|
|
|
|
{
|
|
|
|
Free(newItems);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
count -= slotCapacity;
|
|
|
|
SetBagItemQuantity(&newItems[i].quantity, slotCapacity);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// created a new slot and added quantity
|
|
|
|
SetBagItemQuantity(&newItems[i].quantity, count);
|
2021-05-09 07:27:28 +02:00
|
|
|
count = 0;
|
|
|
|
break;
|
2018-04-29 13:36:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (count > 0)
|
|
|
|
{
|
|
|
|
Free(newItems);
|
2017-09-03 13:33:13 +02:00
|
|
|
return FALSE;
|
2018-04-29 13:36:26 +02:00
|
|
|
}
|
|
|
|
}
|
2021-05-09 07:27:28 +02:00
|
|
|
memcpy(itemPocket->itemSlots, newItems, itemPocket->capacity * sizeof(struct ItemSlot));
|
|
|
|
Free(newItems);
|
|
|
|
return TRUE;
|
2018-04-29 13:36:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 RemoveBagItem(u16 itemId, u16 count)
|
|
|
|
{
|
|
|
|
u8 i;
|
|
|
|
u16 totalQuantity = 0;
|
|
|
|
|
|
|
|
if (ItemId_GetPocket(itemId) == POCKET_NONE || itemId == ITEM_NONE)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
// check Battle Pyramid Bag
|
2019-10-18 01:22:03 +02:00
|
|
|
if (InBattlePyramid() || FlagGet(FLAG_STORING_ITEMS_IN_PYRAMID_BAG) == TRUE)
|
2018-04-29 13:36:26 +02:00
|
|
|
{
|
|
|
|
return RemovePyramidBagItem(itemId, count);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
u8 pocket;
|
|
|
|
u8 var;
|
|
|
|
u16 ownedCount;
|
|
|
|
struct BagPocket *itemPocket;
|
|
|
|
|
|
|
|
pocket = ItemId_GetPocket(itemId) - 1;
|
|
|
|
itemPocket = &gBagPockets[pocket];
|
|
|
|
|
|
|
|
for (i = 0; i < itemPocket->capacity; i++)
|
|
|
|
{
|
|
|
|
if (itemPocket->itemSlots[i].itemId == itemId)
|
|
|
|
totalQuantity += GetBagItemQuantity(&itemPocket->itemSlots[i].quantity);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (totalQuantity < count)
|
|
|
|
return FALSE; // We don't have enough of the item
|
|
|
|
|
2019-04-05 23:11:24 +02:00
|
|
|
if (CurMapIsSecretBase() == TRUE)
|
2018-04-29 13:36:26 +02:00
|
|
|
{
|
2020-01-08 10:26:26 +01:00
|
|
|
VarSet(VAR_SECRET_BASE_LOW_TV_FLAGS, VarGet(VAR_SECRET_BASE_LOW_TV_FLAGS) | SECRET_BASE_USED_BAG);
|
2019-02-28 05:54:51 +01:00
|
|
|
VarSet(VAR_SECRET_BASE_LAST_ITEM_USED, itemId);
|
2018-04-29 13:36:26 +02:00
|
|
|
}
|
|
|
|
|
2018-12-15 19:08:13 +01:00
|
|
|
var = GetItemListPosition(pocket);
|
2018-04-29 13:36:26 +02:00
|
|
|
if (itemPocket->capacity > var
|
|
|
|
&& itemPocket->itemSlots[var].itemId == itemId)
|
|
|
|
{
|
|
|
|
ownedCount = GetBagItemQuantity(&itemPocket->itemSlots[var].quantity);
|
|
|
|
if (ownedCount >= count)
|
|
|
|
{
|
|
|
|
SetBagItemQuantity(&itemPocket->itemSlots[var].quantity, ownedCount - count);
|
|
|
|
count = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
count -= ownedCount;
|
|
|
|
SetBagItemQuantity(&itemPocket->itemSlots[var].quantity, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GetBagItemQuantity(&itemPocket->itemSlots[var].quantity) == 0)
|
|
|
|
itemPocket->itemSlots[var].itemId = ITEM_NONE;
|
|
|
|
|
2017-09-03 13:33:13 +02:00
|
|
|
if (count == 0)
|
|
|
|
return TRUE;
|
|
|
|
}
|
2018-04-29 13:36:26 +02:00
|
|
|
|
|
|
|
for (i = 0; i < itemPocket->capacity; i++)
|
|
|
|
{
|
|
|
|
if (itemPocket->itemSlots[i].itemId == itemId)
|
|
|
|
{
|
|
|
|
ownedCount = GetBagItemQuantity(&itemPocket->itemSlots[i].quantity);
|
|
|
|
if (ownedCount >= count)
|
|
|
|
{
|
|
|
|
SetBagItemQuantity(&itemPocket->itemSlots[i].quantity, ownedCount - count);
|
|
|
|
count = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
count -= ownedCount;
|
|
|
|
SetBagItemQuantity(&itemPocket->itemSlots[i].quantity, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GetBagItemQuantity(&itemPocket->itemSlots[i].quantity) == 0)
|
|
|
|
itemPocket->itemSlots[i].itemId = ITEM_NONE;
|
|
|
|
|
|
|
|
if (count == 0)
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
2017-09-03 13:33:13 +02:00
|
|
|
}
|
2018-04-29 13:36:26 +02:00
|
|
|
}
|
2017-09-03 13:33:13 +02:00
|
|
|
|
2018-04-29 13:36:26 +02:00
|
|
|
u8 GetPocketByItemId(u16 itemId)
|
|
|
|
{
|
|
|
|
return ItemId_GetPocket(itemId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ClearItemSlots(struct ItemSlot *itemSlots, u8 itemCount)
|
|
|
|
{
|
|
|
|
u16 i;
|
|
|
|
|
|
|
|
for (i = 0; i < itemCount; i++)
|
2017-09-03 13:33:13 +02:00
|
|
|
{
|
2018-04-29 13:36:26 +02:00
|
|
|
itemSlots[i].itemId = ITEM_NONE;
|
|
|
|
SetBagItemQuantity(&itemSlots[i].quantity, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static s32 FindFreePCItemSlot(void)
|
|
|
|
{
|
|
|
|
s8 i;
|
|
|
|
|
|
|
|
for (i = 0; i < PC_ITEMS_COUNT; i++)
|
|
|
|
{
|
|
|
|
if (gSaveBlock1Ptr->pcItems[i].itemId == ITEM_NONE)
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
u8 CountUsedPCItemSlots(void)
|
|
|
|
{
|
|
|
|
u8 usedSlots = 0;
|
|
|
|
u8 i;
|
|
|
|
|
|
|
|
for (i = 0; i < PC_ITEMS_COUNT; i++)
|
|
|
|
{
|
|
|
|
if (gSaveBlock1Ptr->pcItems[i].itemId != ITEM_NONE)
|
|
|
|
usedSlots++;
|
|
|
|
}
|
|
|
|
return usedSlots;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 CheckPCHasItem(u16 itemId, u16 count)
|
|
|
|
{
|
|
|
|
u8 i;
|
|
|
|
|
|
|
|
for (i = 0; i < PC_ITEMS_COUNT; i++)
|
|
|
|
{
|
|
|
|
if (gSaveBlock1Ptr->pcItems[i].itemId == itemId && GetPCItemQuantity(&gSaveBlock1Ptr->pcItems[i].quantity) >= count)
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 AddPCItem(u16 itemId, u16 count)
|
|
|
|
{
|
|
|
|
u8 i;
|
|
|
|
s8 freeSlot;
|
|
|
|
u16 ownedCount;
|
|
|
|
struct ItemSlot *newItems;
|
|
|
|
|
|
|
|
// Copy PC items
|
|
|
|
newItems = AllocZeroed(sizeof(gSaveBlock1Ptr->pcItems));
|
|
|
|
memcpy(newItems, gSaveBlock1Ptr->pcItems, sizeof(gSaveBlock1Ptr->pcItems));
|
|
|
|
|
|
|
|
// Use any item slots that already contain this item
|
|
|
|
for (i = 0; i < PC_ITEMS_COUNT; i++)
|
|
|
|
{
|
|
|
|
if (newItems[i].itemId == itemId)
|
2017-09-03 13:33:13 +02:00
|
|
|
{
|
2018-04-29 13:36:26 +02:00
|
|
|
ownedCount = GetPCItemQuantity(&newItems[i].quantity);
|
2020-01-26 10:02:15 +01:00
|
|
|
if (ownedCount + count <= MAX_PC_ITEM_CAPACITY)
|
2017-09-03 13:33:13 +02:00
|
|
|
{
|
2018-04-29 13:36:26 +02:00
|
|
|
SetPCItemQuantity(&newItems[i].quantity, ownedCount + count);
|
|
|
|
memcpy(gSaveBlock1Ptr->pcItems, newItems, sizeof(gSaveBlock1Ptr->pcItems));
|
|
|
|
Free(newItems);
|
|
|
|
return TRUE;
|
|
|
|
}
|
2020-01-26 10:02:15 +01:00
|
|
|
count += ownedCount - MAX_PC_ITEM_CAPACITY;
|
|
|
|
SetPCItemQuantity(&newItems[i].quantity, MAX_PC_ITEM_CAPACITY);
|
2018-04-29 13:36:26 +02:00
|
|
|
if (count == 0)
|
|
|
|
{
|
|
|
|
memcpy(gSaveBlock1Ptr->pcItems, newItems, sizeof(gSaveBlock1Ptr->pcItems));
|
|
|
|
Free(newItems);
|
|
|
|
return TRUE;
|
2017-09-03 13:33:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-29 13:36:26 +02:00
|
|
|
// Put any remaining items into a new item slot.
|
|
|
|
if (count > 0)
|
|
|
|
{
|
|
|
|
freeSlot = FindFreePCItemSlot();
|
|
|
|
if (freeSlot == -1)
|
|
|
|
{
|
|
|
|
Free(newItems);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
newItems[freeSlot].itemId = itemId;
|
|
|
|
SetPCItemQuantity(&newItems[freeSlot].quantity, count);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Copy items back to the PC
|
|
|
|
memcpy(gSaveBlock1Ptr->pcItems, newItems, sizeof(gSaveBlock1Ptr->pcItems));
|
|
|
|
Free(newItems);
|
2017-09-03 13:33:13 +02:00
|
|
|
return TRUE;
|
2018-04-29 13:36:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void RemovePCItem(u8 index, u16 count)
|
|
|
|
{
|
|
|
|
gSaveBlock1Ptr->pcItems[index].quantity -= count;
|
|
|
|
if (gSaveBlock1Ptr->pcItems[index].quantity == 0)
|
|
|
|
{
|
|
|
|
gSaveBlock1Ptr->pcItems[index].itemId = ITEM_NONE;
|
|
|
|
CompactPCItems();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CompactPCItems(void)
|
|
|
|
{
|
|
|
|
u16 i;
|
|
|
|
u16 j;
|
|
|
|
|
|
|
|
for (i = 0; i < PC_ITEMS_COUNT - 1; i++)
|
|
|
|
{
|
|
|
|
for (j = i + 1; j < PC_ITEMS_COUNT; j++)
|
|
|
|
{
|
|
|
|
if (gSaveBlock1Ptr->pcItems[i].itemId == 0)
|
|
|
|
{
|
|
|
|
struct ItemSlot temp = gSaveBlock1Ptr->pcItems[i];
|
|
|
|
gSaveBlock1Ptr->pcItems[i] = gSaveBlock1Ptr->pcItems[j];
|
|
|
|
gSaveBlock1Ptr->pcItems[j] = temp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SwapRegisteredBike(void)
|
|
|
|
{
|
|
|
|
switch (gSaveBlock1Ptr->registeredItem)
|
|
|
|
{
|
|
|
|
case ITEM_MACH_BIKE:
|
|
|
|
gSaveBlock1Ptr->registeredItem = ITEM_ACRO_BIKE;
|
|
|
|
break;
|
|
|
|
case ITEM_ACRO_BIKE:
|
|
|
|
gSaveBlock1Ptr->registeredItem = ITEM_MACH_BIKE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
u16 BagGetItemIdByPocketPosition(u8 pocketId, u16 pocketPos)
|
|
|
|
{
|
|
|
|
return gBagPockets[pocketId - 1].itemSlots[pocketPos].itemId;
|
|
|
|
}
|
|
|
|
|
|
|
|
u16 BagGetQuantityByPocketPosition(u8 pocketId, u16 pocketPos)
|
|
|
|
{
|
|
|
|
return GetBagItemQuantity(&gBagPockets[pocketId - 1].itemSlots[pocketPos].quantity);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void SwapItemSlots(struct ItemSlot *a, struct ItemSlot *b)
|
|
|
|
{
|
2018-08-30 15:01:07 +02:00
|
|
|
struct ItemSlot temp;
|
2018-08-30 21:28:03 +02:00
|
|
|
SWAP(*a, *b, temp);
|
2018-04-29 13:36:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void CompactItemsInBagPocket(struct BagPocket *bagPocket)
|
|
|
|
{
|
|
|
|
u16 i, j;
|
|
|
|
|
|
|
|
for (i = 0; i < bagPocket->capacity - 1; i++)
|
|
|
|
{
|
|
|
|
for (j = i + 1; j < bagPocket->capacity; j++)
|
|
|
|
{
|
|
|
|
if (GetBagItemQuantity(&bagPocket->itemSlots[i].quantity) == 0)
|
|
|
|
SwapItemSlots(&bagPocket->itemSlots[i], &bagPocket->itemSlots[j]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SortBerriesOrTMHMs(struct BagPocket *bagPocket)
|
|
|
|
{
|
|
|
|
u16 i, j;
|
|
|
|
|
|
|
|
for (i = 0; i < bagPocket->capacity - 1; i++)
|
|
|
|
{
|
|
|
|
for (j = i + 1; j < bagPocket->capacity; j++)
|
|
|
|
{
|
|
|
|
if (GetBagItemQuantity(&bagPocket->itemSlots[i].quantity) != 0)
|
|
|
|
{
|
|
|
|
if (GetBagItemQuantity(&bagPocket->itemSlots[j].quantity) == 0)
|
|
|
|
continue;
|
|
|
|
if (bagPocket->itemSlots[i].itemId <= bagPocket->itemSlots[j].itemId)
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
SwapItemSlots(&bagPocket->itemSlots[i], &bagPocket->itemSlots[j]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MoveItemSlotInList(struct ItemSlot* itemSlots_, u32 from, u32 to_)
|
|
|
|
{
|
|
|
|
// dumb assignments needed to match
|
|
|
|
struct ItemSlot *itemSlots = itemSlots_;
|
|
|
|
u32 to = to_;
|
|
|
|
|
|
|
|
if (from != to)
|
|
|
|
{
|
|
|
|
s16 i, count;
|
|
|
|
struct ItemSlot firstSlot = itemSlots[from];
|
|
|
|
|
|
|
|
if (to > from)
|
|
|
|
{
|
|
|
|
to--;
|
|
|
|
for (i = from, count = to; i < count; i++)
|
|
|
|
itemSlots[i] = itemSlots[i + 1];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (i = from, count = to; i > count; i--)
|
|
|
|
itemSlots[i] = itemSlots[i - 1];
|
|
|
|
}
|
|
|
|
itemSlots[to] = firstSlot;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ClearBag(void)
|
|
|
|
{
|
|
|
|
u16 i;
|
|
|
|
|
|
|
|
for (i = 0; i < POCKETS_COUNT; i++)
|
|
|
|
{
|
|
|
|
ClearItemSlots(gBagPockets[i].itemSlots, gBagPockets[i].capacity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
u16 CountTotalItemQuantityInBag(u16 itemId)
|
|
|
|
{
|
|
|
|
u16 i;
|
|
|
|
u16 ownedCount = 0;
|
|
|
|
struct BagPocket *bagPocket = &gBagPockets[ItemId_GetPocket(itemId) - 1];
|
|
|
|
|
|
|
|
for (i = 0; i < bagPocket->capacity; i++)
|
|
|
|
{
|
|
|
|
if (bagPocket->itemSlots[i].itemId == itemId)
|
|
|
|
ownedCount += GetBagItemQuantity(&bagPocket->itemSlots[i].quantity);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ownedCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool8 CheckPyramidBagHasItem(u16 itemId, u16 count)
|
|
|
|
{
|
|
|
|
u8 i;
|
2018-08-25 19:59:47 +02:00
|
|
|
u16 *items = gSaveBlock2Ptr->frontier.pyramidBag.itemId[gSaveBlock2Ptr->frontier.lvlMode];
|
|
|
|
u8 *quantities = gSaveBlock2Ptr->frontier.pyramidBag.quantity[gSaveBlock2Ptr->frontier.lvlMode];
|
2018-04-29 13:36:26 +02:00
|
|
|
|
|
|
|
for (i = 0; i < PYRAMID_BAG_ITEMS_COUNT; i++)
|
|
|
|
{
|
|
|
|
if (items[i] == itemId)
|
|
|
|
{
|
|
|
|
if (quantities[i] >= count)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
count -= quantities[i];
|
|
|
|
if (count == 0)
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool8 CheckPyramidBagHasSpace(u16 itemId, u16 count)
|
|
|
|
{
|
|
|
|
u8 i;
|
2018-08-25 19:59:47 +02:00
|
|
|
u16 *items = gSaveBlock2Ptr->frontier.pyramidBag.itemId[gSaveBlock2Ptr->frontier.lvlMode];
|
|
|
|
u8 *quantities = gSaveBlock2Ptr->frontier.pyramidBag.quantity[gSaveBlock2Ptr->frontier.lvlMode];
|
2018-04-29 13:36:26 +02:00
|
|
|
|
|
|
|
for (i = 0; i < PYRAMID_BAG_ITEMS_COUNT; i++)
|
|
|
|
{
|
|
|
|
if (items[i] == itemId || items[i] == ITEM_NONE)
|
|
|
|
{
|
2020-01-26 10:02:15 +01:00
|
|
|
if (quantities[i] + count <= MAX_BAG_ITEM_CAPACITY)
|
2018-04-29 13:36:26 +02:00
|
|
|
return TRUE;
|
|
|
|
|
2020-01-26 10:02:15 +01:00
|
|
|
count = (quantities[i] + count) - MAX_BAG_ITEM_CAPACITY;
|
2018-04-29 13:36:26 +02:00
|
|
|
if (count == 0)
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2018-04-29 14:21:59 +02:00
|
|
|
bool8 AddPyramidBagItem(u16 itemId, u16 count)
|
2018-04-29 13:36:26 +02:00
|
|
|
{
|
|
|
|
u16 i;
|
|
|
|
|
2018-08-25 19:59:47 +02:00
|
|
|
u16 *items = gSaveBlock2Ptr->frontier.pyramidBag.itemId[gSaveBlock2Ptr->frontier.lvlMode];
|
|
|
|
u8 *quantities = gSaveBlock2Ptr->frontier.pyramidBag.quantity[gSaveBlock2Ptr->frontier.lvlMode];
|
2018-04-29 13:36:26 +02:00
|
|
|
|
|
|
|
u16 *newItems = Alloc(PYRAMID_BAG_ITEMS_COUNT * sizeof(u16));
|
|
|
|
u8 *newQuantities = Alloc(PYRAMID_BAG_ITEMS_COUNT * sizeof(u8));
|
|
|
|
|
|
|
|
memcpy(newItems, items, PYRAMID_BAG_ITEMS_COUNT * sizeof(u16));
|
|
|
|
memcpy(newQuantities, quantities, PYRAMID_BAG_ITEMS_COUNT * sizeof(u8));
|
|
|
|
|
|
|
|
for (i = 0; i < PYRAMID_BAG_ITEMS_COUNT; i++)
|
|
|
|
{
|
2020-01-26 10:02:15 +01:00
|
|
|
if (newItems[i] == itemId && newQuantities[i] < MAX_BAG_ITEM_CAPACITY)
|
2018-04-29 13:36:26 +02:00
|
|
|
{
|
|
|
|
newQuantities[i] += count;
|
2020-01-26 10:02:15 +01:00
|
|
|
if (newQuantities[i] > MAX_BAG_ITEM_CAPACITY)
|
2018-04-29 13:36:26 +02:00
|
|
|
{
|
2020-01-26 10:02:15 +01:00
|
|
|
count = newQuantities[i] - MAX_BAG_ITEM_CAPACITY;
|
|
|
|
newQuantities[i] = MAX_BAG_ITEM_CAPACITY;
|
2018-04-29 13:36:26 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
count = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (count == 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (count > 0)
|
|
|
|
{
|
|
|
|
for (i = 0; i < PYRAMID_BAG_ITEMS_COUNT; i++)
|
|
|
|
{
|
|
|
|
if (newItems[i] == ITEM_NONE)
|
|
|
|
{
|
|
|
|
newItems[i] = itemId;
|
|
|
|
newQuantities[i] = count;
|
2020-01-26 10:02:15 +01:00
|
|
|
if (newQuantities[i] > MAX_BAG_ITEM_CAPACITY)
|
2018-04-29 13:36:26 +02:00
|
|
|
{
|
2020-01-26 10:02:15 +01:00
|
|
|
count = newQuantities[i] - MAX_BAG_ITEM_CAPACITY;
|
|
|
|
newQuantities[i] = MAX_BAG_ITEM_CAPACITY;
|
2018-04-29 13:36:26 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
count = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (count == 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (count == 0)
|
|
|
|
{
|
|
|
|
memcpy(items, newItems, PYRAMID_BAG_ITEMS_COUNT * sizeof(u16));
|
|
|
|
memcpy(quantities, newQuantities, PYRAMID_BAG_ITEMS_COUNT * sizeof(u8));
|
|
|
|
Free(newItems);
|
|
|
|
Free(newQuantities);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Free(newItems);
|
|
|
|
Free(newQuantities);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-29 14:21:59 +02:00
|
|
|
bool8 RemovePyramidBagItem(u16 itemId, u16 count)
|
2018-04-29 13:36:26 +02:00
|
|
|
{
|
|
|
|
u16 i;
|
|
|
|
|
2018-08-25 19:59:47 +02:00
|
|
|
u16 *items = gSaveBlock2Ptr->frontier.pyramidBag.itemId[gSaveBlock2Ptr->frontier.lvlMode];
|
|
|
|
u8 *quantities = gSaveBlock2Ptr->frontier.pyramidBag.quantity[gSaveBlock2Ptr->frontier.lvlMode];
|
2018-04-29 13:36:26 +02:00
|
|
|
|
2021-04-23 00:49:54 +02:00
|
|
|
i = gPyramidBagMenuState.cursorPosition + gPyramidBagMenuState.scrollPosition;
|
2018-04-29 13:36:26 +02:00
|
|
|
if (items[i] == itemId && quantities[i] >= count)
|
|
|
|
{
|
|
|
|
quantities[i] -= count;
|
|
|
|
if (quantities[i] == 0)
|
|
|
|
items[i] = ITEM_NONE;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
u16 *newItems = Alloc(PYRAMID_BAG_ITEMS_COUNT * sizeof(u16));
|
|
|
|
u8 *newQuantities = Alloc(PYRAMID_BAG_ITEMS_COUNT * sizeof(u8));
|
|
|
|
|
|
|
|
memcpy(newItems, items, PYRAMID_BAG_ITEMS_COUNT * sizeof(u16));
|
|
|
|
memcpy(newQuantities, quantities, PYRAMID_BAG_ITEMS_COUNT * sizeof(u8));
|
|
|
|
|
|
|
|
for (i = 0; i < PYRAMID_BAG_ITEMS_COUNT; i++)
|
|
|
|
{
|
|
|
|
if (newItems[i] == itemId)
|
|
|
|
{
|
|
|
|
if (newQuantities[i] >= count)
|
|
|
|
{
|
|
|
|
newQuantities[i] -= count;
|
|
|
|
count = 0;
|
|
|
|
if (newQuantities[i] == 0)
|
|
|
|
newItems[i] = ITEM_NONE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
count -= newQuantities[i];
|
|
|
|
newQuantities[i] = 0;
|
|
|
|
newItems[i] = ITEM_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (count == 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (count == 0)
|
|
|
|
{
|
|
|
|
memcpy(items, newItems, PYRAMID_BAG_ITEMS_COUNT * sizeof(u16));
|
|
|
|
memcpy(quantities, newQuantities, PYRAMID_BAG_ITEMS_COUNT * sizeof(u8));
|
|
|
|
Free(newItems);
|
|
|
|
Free(newQuantities);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Free(newItems);
|
|
|
|
Free(newQuantities);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static u16 SanitizeItemId(u16 itemId)
|
|
|
|
{
|
2018-07-07 14:24:19 +02:00
|
|
|
if (itemId >= ITEMS_COUNT)
|
2018-04-29 13:36:26 +02:00
|
|
|
return ITEM_NONE;
|
|
|
|
else
|
|
|
|
return itemId;
|
|
|
|
}
|
|
|
|
|
|
|
|
const u8 *ItemId_GetName(u16 itemId)
|
|
|
|
{
|
|
|
|
return gItems[SanitizeItemId(itemId)].name;
|
|
|
|
}
|
|
|
|
|
|
|
|
u16 ItemId_GetId(u16 itemId)
|
|
|
|
{
|
|
|
|
return gItems[SanitizeItemId(itemId)].itemId;
|
|
|
|
}
|
|
|
|
|
|
|
|
u16 ItemId_GetPrice(u16 itemId)
|
|
|
|
{
|
|
|
|
return gItems[SanitizeItemId(itemId)].price;
|
|
|
|
}
|
|
|
|
|
|
|
|
u8 ItemId_GetHoldEffect(u16 itemId)
|
|
|
|
{
|
|
|
|
return gItems[SanitizeItemId(itemId)].holdEffect;
|
|
|
|
}
|
|
|
|
|
|
|
|
u8 ItemId_GetHoldEffectParam(u16 itemId)
|
|
|
|
{
|
|
|
|
return gItems[SanitizeItemId(itemId)].holdEffectParam;
|
|
|
|
}
|
|
|
|
|
|
|
|
const u8 *ItemId_GetDescription(u16 itemId)
|
|
|
|
{
|
|
|
|
return gItems[SanitizeItemId(itemId)].description;
|
|
|
|
}
|
|
|
|
|
|
|
|
u8 ItemId_GetImportance(u16 itemId)
|
|
|
|
{
|
|
|
|
return gItems[SanitizeItemId(itemId)].importance;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unused
|
|
|
|
u8 ItemId_GetUnknownValue(u16 itemId)
|
|
|
|
{
|
|
|
|
return gItems[SanitizeItemId(itemId)].unk19;
|
|
|
|
}
|
|
|
|
|
|
|
|
u8 ItemId_GetPocket(u16 itemId)
|
|
|
|
{
|
|
|
|
return gItems[SanitizeItemId(itemId)].pocket;
|
|
|
|
}
|
|
|
|
|
|
|
|
u8 ItemId_GetType(u16 itemId)
|
|
|
|
{
|
|
|
|
return gItems[SanitizeItemId(itemId)].type;
|
|
|
|
}
|
|
|
|
|
|
|
|
ItemUseFunc ItemId_GetFieldFunc(u16 itemId)
|
|
|
|
{
|
|
|
|
return gItems[SanitizeItemId(itemId)].fieldUseFunc;
|
|
|
|
}
|
|
|
|
|
|
|
|
u8 ItemId_GetBattleUsage(u16 itemId)
|
|
|
|
{
|
|
|
|
return gItems[SanitizeItemId(itemId)].battleUsage;
|
|
|
|
}
|
|
|
|
|
|
|
|
ItemUseFunc ItemId_GetBattleFunc(u16 itemId)
|
|
|
|
{
|
|
|
|
return gItems[SanitizeItemId(itemId)].battleUseFunc;
|
|
|
|
}
|
|
|
|
|
|
|
|
u8 ItemId_GetSecondaryId(u16 itemId)
|
|
|
|
{
|
|
|
|
return gItems[SanitizeItemId(itemId)].secondaryId;
|
|
|
|
}
|
2020-12-20 05:58:23 +01:00
|
|
|
|
|
|
|
bool32 IsPinchBerryItemEffect(u16 holdEffect)
|
|
|
|
{
|
|
|
|
switch (holdEffect)
|
|
|
|
{
|
|
|
|
case HOLD_EFFECT_ATTACK_UP:
|
|
|
|
case HOLD_EFFECT_DEFENSE_UP:
|
|
|
|
case HOLD_EFFECT_SPEED_UP:
|
|
|
|
case HOLD_EFFECT_SP_ATTACK_UP:
|
|
|
|
case HOLD_EFFECT_SP_DEFENSE_UP:
|
|
|
|
case HOLD_EFFECT_CRITICAL_UP:
|
|
|
|
case HOLD_EFFECT_RANDOM_STAT_UP:
|
|
|
|
#ifdef HOLD_EFFECT_CUSTAP_BERRY
|
|
|
|
case HOLD_EFFECT_CUSTAP_BERRY:
|
|
|
|
#endif
|
|
|
|
#ifdef HOLD_EFFECT_MICLE_BERRY
|
|
|
|
case HOLD_EFFECT_MICLE_BERRY:
|
|
|
|
#endif
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|