pmd-red/src/dungeon_items.c
2026-02-07 19:39:59 +00:00

946 lines
28 KiB
C

#include "global.h"
#include "globaldata.h"
#include "dungeon_items.h"
#include "dungeon_8041AD0.h"
#include "dungeon_range.h"
#include "dungeon_random.h"
#include "dungeon_util.h"
#include "pokemon.h"
#include "structs/str_dungeon.h"
#include "constants/item.h"
#include "dungeon_map_access.h"
#include "dungeon_message.h"
#include "dungeon_music.h"
#include "dungeon_map.h"
#include "dungeon_strings.h"
#include "dungeon_logic.h"
#include "dungeon_data.h"
#include "dungeon_pos_data.h"
#include "dungeon_floor_spawns.h"
#include "dungeon_cutscene.h"
#include "dungeon_boss_dialogue.h"
#include "string_format.h"
#include "items.h"
#include "structs/map.h"
#include "trap.h"
#include "math.h"
#include "structs/str_item_text.h"
#include "dungeon_vram.h"
#include "sprite.h"
static void MusicBoxCreation_Async(void);
static bool8 sub_8046D70(void);
static EWRAM_INIT u8 sUnkItemTileNums[8] = {0x15, 0x00, 0x16, 0x00, 0x15, 0x00, 0x16, 0x00};
static EWRAM_INIT u8 sUnkItemMatrixNums[8] = {0x02, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x02};
static void sub_8046734(Entity *entity, DungeonPos *pos);
static void sub_8046CE4(Item *item,s32 param_2);
static const struct unkStruct_8090F58 gUnknown_80F6990 = {1, 1, 0, 0, 1};
static const struct unkStruct_8090F58 gUnknown_80F699C = {0, 0, 0, 0, 1};
static const struct unkStruct_8090F58 gUnknown_80F69A8 = {0, 0, 0, 0, 0};
void sub_8045BF8(u8 *buffer, Item *item)
{
sub_8090E14(buffer, item, &gUnknown_80F699C);
}
void sub_8045C08(u8 *buffer, Item *item)
{
sub_8090E14(buffer, item, &gUnknown_80F69A8);
}
void sub_8045C18(u8 *buffer, Item *item)
{
sub_8090E14(buffer, item, &gUnknown_80F6990);
}
void CreateItemWithStickyChance(Item *item, u8 itemID, u32 forceSticky)
{
bool8 stickyFlag;
ItemIdToItem(item, itemID, FALSE);
stickyFlag = FALSE;
if (IsNotSpecialItem(itemID)) {
if (forceSticky == FORCE_STICKY_RANDOM) {
if (DungeonRandInt(100) < gDungeon->floorProperties.itemStickyChance)
stickyFlag = TRUE;
else
stickyFlag = FALSE;
}
else if (forceSticky == FORCE_STICKY_ALWAYS) {
stickyFlag = TRUE;
}
}
if (stickyFlag) {
item->flags |= ITEM_FLAG_STICKY;
}
if (GetItemCategory(itemID) == CATEGORY_POKE) {
sub_8046CE4(item, gDungeon->floorProperties.moneyUpperBound * 40);
}
}
void CreateFloorItems(void)
{
u8 itemID;
s32 yCounter, xCounter;
const Tile *tile;
s32 spawnType;
Item item;
u32 flag;
s32 x = DungeonRandInt(DUNGEON_MAX_SIZE_X);
s32 y = DungeonRandInt(DUNGEON_MAX_SIZE_Y);
gDungeon->numItems = 0;
for (yCounter = 0; yCounter < DUNGEON_MAX_SIZE_Y; yCounter++) {
y++;
if (y == DUNGEON_MAX_SIZE_Y) {
y = 0;
}
for (xCounter = 0; xCounter < DUNGEON_MAX_SIZE_X; xCounter++) {
x++;
flag = ITEM_FLAG_IN_SHOP;
if (x == DUNGEON_MAX_SIZE_X) {
x = 0;
}
tile = GetTile(x,y);
if (!(tile->terrainFlags & TERRAIN_TYPE_STAIRS) && (tile->spawnOrVisibilityFlags.spawn & SPAWN_FLAG_ITEM)) {
DungeonPos pos;
bool8 shopFlag = FALSE;
pos.x = x;
pos.y = y;
if (tile->terrainFlags & TERRAIN_TYPE_SHOP) {
shopFlag = TRUE;
spawnType = ITEM_SPAWN_IN_SHOP;
}
else
{
if (GetTerrainType(tile) == TERRAIN_TYPE_WALL) {
spawnType = ITEM_SPAWN_WALL;
}
else {
spawnType = (tile->terrainFlags & TERRAIN_TYPE_IN_MONSTER_HOUSE) ? ITEM_SPAWN_IN_MONSTER_HOUSE : ITEM_SPAWN_NORMAL;
}
}
itemID = GetRandomFloorItem(spawnType);
if (!IsShoppableItem(itemID)) {
shopFlag = FALSE;
}
CreateItemWithStickyChance(&item,itemID,FORCE_STICKY_RANDOM);
if (shopFlag) {
item.flags |= flag;
}
SpawnItem(&pos,&item,TRUE);
}
}
}
}
void TryLeaderItemPickUp_Async(struct DungeonPos *pos, bool8 printMsg)
{
Item *tileItem;
s32 inventoryIds[INVENTORY_SIZE + 1];
Item *inventoryItems[INVENTORY_SIZE + 1];
Entity *leader = GetLeader();
EntityInfo *leaderInfo = GetEntInfo(leader);
const Tile *tile = GetTile(pos->x,pos->y);
Entity *tileObject = tile->object;
if (tileObject == NULL) {
return;
}
if (GetEntityType(tileObject) != ENTITY_ITEM) {
return;
}
tileItem = GetItemInfo(tileObject);
if (leaderInfo->action.actionParameters[0].actionUseIndex == 0) {
if (!printMsg) {
return;
}
sub_8045BF8(gFormatBuffer_Items[0],tileItem);
SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0],leader,0);
LogMessageByIdWithPopupCheckUser_Async(leader,gMonSteppedOnItem);
}
else if (ShouldMonsterRunAwayAndShowEffect(leader,1)) {
if (!printMsg) {
return;
}
sub_8045BF8(gFormatBuffer_Items[0],tileItem);
SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0],leader,0);
LogMessageByIdWithPopupCheckUser_Async(leader,gMonTerrifiedCouldntPickUpItem);
}
else if (GetItemCategory(tileItem->id) == CATEGORY_POKE) {
PlaySoundEffect(0x14c);
AddToTeamMoney(GetMoneyValue(tileItem));
sub_8045BF8(gFormatBuffer_Items[0],tileItem);
RemoveGroundItem(pos,TRUE);
LogMessageByIdWithPopupCheckUser_Async(leader,gPickedUpItem);
DisplayItemTip(tileItem->id);
}
else {
s32 i, maxItems;
if (gDungeon->unk644.hasInventory) {
for (i = 0; i < INVENTORY_SIZE; i++) {
inventoryItems[i] = &gTeamInventoryRef->teamItems[i];
inventoryIds[i] = i;
}
maxItems = INVENTORY_SIZE;
}
else {
inventoryItems[0] = &leaderInfo->heldItem;
inventoryIds[0] = -1;
maxItems = 1;
}
if (tileItem->id <= ITEM_GEO_PEBBLE && !(tileItem->flags & ITEM_FLAG_IN_SHOP)) {
s32 index = -1;
s32 numberItems = -1;
s32 i;
for (i = 0; i < maxItems; i++) {
if (ItemExists(inventoryItems[i])
&& !(inventoryItems[i]->flags & ITEM_FLAG_IN_SHOP)
&& (tileItem->id == inventoryItems[i]->id)
&& (tileItem->flags & ITEM_FLAG_STICKY) == (inventoryItems[i]->flags & ITEM_FLAG_STICKY)
&& inventoryItems[i]->quantity != 99
&& numberItems < inventoryItems[i]->quantity)
{
numberItems = inventoryItems[i]->quantity;
index = i;
}
}
if (index == -1) {
s32 i;
numberItems = -1;
for (i = 0; i < maxItems; i++) {
if (ItemExists(inventoryItems[i])
&& !(inventoryItems[i]->flags & ITEM_FLAG_IN_SHOP)
&& tileItem->id == inventoryItems[i]->id
&& inventoryItems[i]->quantity != 99
&& numberItems < inventoryItems[i]->quantity)
{
numberItems = inventoryItems[i]->quantity;
index = i;
}
}
}
if (index != -1) {
struct Item *addedItem = inventoryItems[index];
s32 newQuantity = addedItem->quantity + tileItem->quantity;
if (newQuantity >= 99) {
newQuantity = 99;
}
addedItem->quantity = newQuantity;
if (tileItem->flags & ITEM_FLAG_STICKY) {
inventoryItems[index]->flags |= ITEM_FLAG_STICKY;
}
sub_8045BF8(gFormatBuffer_Items[0],tileItem);
RemoveGroundItem(pos,TRUE);
PlaySoundEffect(0x14a);
if (inventoryIds[index] < 0) {
LogMessageByIdWithPopupCheckUser_Async(leader,gPickedUpItem2);
}
else {
LogMessageByIdWithPopupCheckUser_Async(leader,gPickedUpItemToolbox);
}
DisplayItemTip(tileItem->id);
return;
}
}
for (i = 0; i < maxItems; i++) {
if (!ItemExists(inventoryItems[i]))
break;
}
if (i == maxItems) {
if (!printMsg) {
return;
}
sub_8045BF8(gFormatBuffer_Items[0],tileItem);
SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0],leader,0);
LogMessageByIdWithPopupCheckUser_Async(leader,gMonSteppedOnItem);
}
else {
PlaySoundEffect(0x14a);
if (inventoryIds[i] < 0) {
leaderInfo->heldItem = *tileItem;
sub_8045BF8(gFormatBuffer_Items[0],tileItem);
RemoveGroundItem(pos,TRUE);
LogMessageByIdWithPopupCheckUser_Async(leader,gPickedUpItem2);
}
else if (AddItemToInventory(tileItem) != 0) {
SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0],leader,0);
LogMessageByIdWithPopupCheckUser_Async(leader,gMonCouldntPickUpItem);
}
else {
sub_8045BF8(gFormatBuffer_Items[0],tileItem);
RemoveGroundItem(pos,TRUE);
LogMessageByIdWithPopupCheckUser_Async(leader,gPickedUpItemToolbox);
}
DisplayItemTip(tileItem->id);
}
}
}
bool8 SpawnItem(DungeonPos *pos, Item *item, bool8 a2)
{
s32 i, count;
Tile *tile;
Entity *itemEntity = SpawnItemEntity(pos);
if (itemEntity == NULL)
return FALSE;
*itemEntity->axObj.info.item = *item;
itemEntity->axObj.info.item->flags &= ~(ITEM_FLAG_SET);
itemEntity->isVisible = TRUE;
tile = GetTileMut(pos->x, pos->y);
tile->object = itemEntity;
if ((tile->terrainFlags & TERRAIN_TYPE_SHOP) && IsShoppableItem(item->id)) {
if (item->flags & ITEM_FLAG_IN_SHOP) {
if (a2) {
gDungeon->unk644.unk48 += GetActualBuyPrice(item);
}
}
else {
gDungeon->unk644.unk4C += GetActualSellPrice(item);
}
}
count = 0;
for (i = 0; i < DUNGEON_MAX_ITEMS; i++) {
if (EntityIsValid(gDungeon->items[i])) {
count = i + 1;
}
}
gDungeon->numItems = count;
return TRUE;
}
bool8 RemoveGroundItem(DungeonPos *pos, bool8 a2)
{
s32 i, count;
Item *item;
Tile *tile = GetTileMut(pos->x, pos->y);
Entity *tileObject = tile->object;
if (tileObject == NULL || GetEntityType(tileObject) != ENTITY_ITEM)
return FALSE;
item = GetItemInfo(tileObject);
if ((tile->terrainFlags & TERRAIN_TYPE_SHOP) && IsShoppableItem(item->id)) {
if (item->flags & ITEM_FLAG_IN_SHOP) {
if (a2) {
gDungeon->unk644.unk48 -= GetActualBuyPrice(item);
}
}
else {
gDungeon->unk644.unk4C -= GetActualSellPrice(item);
}
}
tile->object = NULL;
tileObject->type = ENTITY_NOTHING;
count = 0;
for (i = 0; i < DUNGEON_MAX_ITEMS; i++) {
if (EntityIsValid(gDungeon->items[i])) {
count = i + 1;
}
}
gDungeon->numItems = count;
return TRUE;
}
static s32 GetItemIconId(Item *item)
{
return gItemParametersData[item->id].icon;
}
bool8 sub_80462AC(Entity * entity, u8 hallucinating, u8 a2, u8 a3, u8 a4)
{
s32 x, y, y2;
s32 objMode = 0;
if (!EntityIsValid(entity))
return FALSE;
if (a2) {
s32 terrainFlags = GetTerrainType(GetTile(entity->pos.x, entity->pos.y));
if (terrainFlags == TERRAIN_TYPE_WALL)
return FALSE;
if (terrainFlags == TERRAIN_TYPE_SECONDARY) {
objMode = 1;
}
if (!ShouldDisplayEntity(entity))
return FALSE;
}
x = (entity->pixelPos.x / 256) - gDungeon->unk181e8.cameraPixelPos.x;
y = ((entity->pixelPos.y - entity->unk1C) / 256) - gDungeon->unk181e8.cameraPixelPos.y;
y2 = ((entity->pixelPos.y / 256) - gDungeon->unk181e8.cameraPixelPos.y) + 8;
y2 /= 2;
if (x >= -32 && y >= -32 && x <= 272 && y <= 192) {
s32 tileNum;
SpriteSetMatrixNum(&gUnknown_202EDC0, 0);
if (hallucinating) {
tileNum = 0x17;
SpriteSetPalNum(&gUnknown_202EDC0, 10);
}
else {
tileNum = GetItemIconId(entity->axObj.info.item);
if (a3 != 0xFF && tileNum == 0) {
tileNum = sUnkItemTileNums[a3];
SpriteSetMatrixNum(&gUnknown_202EDC0, sUnkItemMatrixNums[a3] * 8);
}
SpriteSetPalNum(&gUnknown_202EDC0, GetItemPalette(entity->axObj.info.item->id));
}
SpriteSetY(&gUnknown_202EDC0, y);
SpriteSetX(&gUnknown_202EDC0, x);
SpriteSetObjMode(&gUnknown_202EDC0, objMode);
SpriteSetPriority(&gUnknown_202EDC0, 3);
SpriteSetTileNum(&gUnknown_202EDC0, 0x1A0 + tileNum * 4);
if (!a4) {
y2 = 1;
}
AddSprite(&gUnknown_202EDC0, y2, NULL, NULL);
return TRUE;
}
return FALSE;
}
const u8 *sub_80464AC(Item *item)
{
return gActions[GetItemActionType(item->id)].desc;
}
void SpawnDroppedItemWrapper(Entity *entity, DungeonPos *pos, Item *item)
{
s32 x, y;
Entity itemEntity;
itemEntity.type = ENTITY_ITEM;
itemEntity.unk24 = 0;
itemEntity.isVisible = TRUE;
itemEntity.unk22 = 0;
itemEntity.axObj.info.item = item;
itemEntity.pos = *pos;
x = ((pos->x * 24) + 4) << 8;
y = ((pos->y * 24) + 4) << 8;
SetEntityPixelPos(&itemEntity, x, y);
itemEntity.spawnGenID = 0;
SpawnDroppedItem(entity, &itemEntity, item, TRUE, NULL);
}
void SpawnDroppedItem(Entity *entity1, Entity *entity2, Item *item, bool8 a3, DungeonPos *pos)
{
DungeonPos localPos;
DungeonPos localPos2;
s32 i;
const Tile *tile = GetTile(entity2->pos.x, entity2->pos.y);
Entity *tileObject = tile->object;
bool8 var_24 = FALSE;
if (tileObject != NULL && GetEntityType(tileObject) == ENTITY_TRAP) {
sub_8046734(entity2, &entity2->pos);
sub_807FE44(&entity2->pos, 1);
LogMessageByIdWithPopupCheckUser_Async(entity1, gUnknown_80FED30);
if (!ItemExists(item))
return;
}
localPos.x = entity2->pos.x;
localPos.y = entity2->pos.y;
localPos2 = localPos;
if (a3) {
i = 0;
}
else {
i = 1;
}
while (TRUE) {
if (gUnknown_80F4468[i].x == 99) {
var_24 = FALSE;
break;
}
localPos.x = entity2->pos.x + gUnknown_80F4468[i].x;
localPos.y = entity2->pos.y + gUnknown_80F4468[i].y;
tile = GetTile(localPos.x, localPos.y);
if (GetTerrainType(tile) != TERRAIN_TYPE_WALL && !(tile->terrainFlags & TERRAIN_TYPE_STAIRS) && tile->object == NULL) {
sub_8046734(entity2, &localPos);
localPos2 = localPos;
if (GetTerrainType(tile) == (TERRAIN_TYPE_SECONDARY | TERRAIN_TYPE_NORMAL) || (SpawnItem(&localPos, item, TRUE))) {
var_24 = TRUE;
}
break;
}
i++;
}
sub_8045BF8(gFormatBuffer_Items[0], item);
if (var_24) {
DrawMinimapTile(localPos.x, localPos.y);
switch (GetTerrainType(GetTile(localPos.x, localPos.y))) {
case TERRAIN_TYPE_NORMAL:
LogMessageByIdWithPopupCheckUserUnknown_Async(entity1, &localPos, gItemFellOnGround);
break;
case TERRAIN_TYPE_SECONDARY:
LogMessageByIdWithPopupCheckUserUnknown_Async(entity1, &localPos, gItemFellInWater);
break;
case TERRAIN_TYPE_WALL:
LogMessageByIdWithPopupCheckUserUnknown_Async(entity1, &localPos, gItemBuried);
break;
case TERRAIN_TYPE_SECONDARY | TERRAIN_TYPE_NORMAL:
LogMessageByIdWithPopupCheckUserUnknown_Async(entity1, &localPos, gItemFellOutOfSight);
break;
}
}
else {
PixelPos pixelPos;
pixelPos.x = X_POS_TO_PIXELPOS(localPos2.x);
pixelPos.y = X_POS_TO_PIXELPOS(localPos2.y); // Intentional or a typo(X vs Y)?
if (pos != NULL) {
pixelPos.x += pos->x << 8;
pixelPos.y += pos->y << 8;
}
sub_804219C(&pixelPos);
LogMessageByIdWithPopupCheckUserUnknown_Async(entity1, &localPos, gItemLost);
}
}
static void sub_8046734(Entity *entity, DungeonPos *pos)
{
PixelPos posPixel;
PixelPos calcPixelPos;
bool8 hallucinating = gDungeon->unk181e8.hallucinating;
posPixel.x = ((pos->x * 24) + 4) << 8;
posPixel.y = ((pos->y * 24) + 4) << 8;
if (abs(entity->pixelPos.x - posPixel.x) > 11 || abs(entity->pixelPos.y - posPixel.y) > 11) {
s32 i;
PixelPos add;
s32 unk = 0; // Direction?
s32 sinVal = 0;
calcPixelPos.x = entity->pixelPos.x;
calcPixelPos.y = entity->pixelPos.y;
add.x = (posPixel.x - calcPixelPos.x) / 24;
add.y = (posPixel.y - calcPixelPos.y) / 24;
for (i = 0; i < 24; i++) {
calcPixelPos.x += add.x;
calcPixelPos.y += add.y;
entity->unk1C = sin_4096(sinVal) * 12;
UpdateEntityPixelPos(entity, &calcPixelPos);
sub_80462AC(entity, hallucinating, 0, unk, 0);
DungeonRunFrameActions(0x13);
sinVal += 85;
if ((i & 3) == 0) {
unk++;
}
unk &= 7;
}
}
SetEntityPixelPos(entity, posPixel.x, posPixel.y);
entity->unk1C = 0;
sub_80462AC(entity, hallucinating, 1, 0xFF, 0);
DungeonRunFrameActions(0x13);
}
void sub_8046860(Entity *entity, DungeonPos *pos, Item *item, s32 a4)
{
sub_804687C(entity, pos, pos, item, a4);
}
void sub_804687C(Entity *entity, DungeonPos *pos1, DungeonPos *pos2, Item *item, s32 count)
{
Entity itemEntities[10];
DungeonPos targetTilePos[10];
PixelPos itemVelocity[10];
u8 targetTileUsed[30];
s32 sinVal;
s32 i;
bool8 r1, r9;
for (i = 0; i < 30; i++) {
targetTileUsed[i] = 0;
}
for (i = 0; i < count; i++) {
s32 j;
bool8 foundTile = FALSE;
DungeonPos pos;
pos.x = pos2->x;
pos.y = pos2->y;
for (j = 0; j < 30; j++) {
if (gUnknown_80F4468[j].x == 99)
break;
if (!targetTileUsed[j]) {
const Tile *tile;
pos.x = pos2->x + gUnknown_80F4468[j].x;
pos.y = pos2->y + gUnknown_80F4468[j].y;
tile = GetTile(pos.x, pos.y);
if (GetTerrainType(tile) != TERRAIN_TYPE_WALL && !(tile->terrainFlags & TERRAIN_TYPE_STAIRS) && tile->object == NULL) {
targetTilePos[i] = pos;
targetTileUsed[j] = TRUE;
foundTile = TRUE;
break;
}
}
}
if (!foundTile) {
targetTilePos[i].x = -1;
targetTilePos[i].y = -1;
}
}
r1 = FALSE;
r9 = FALSE;
for (i = 0; i < count; i++) {
if (targetTilePos[i].x < 0) {
itemEntities[i].type = ENTITY_NOTHING;
r9 = TRUE;
}
else {
s32 x, y;
itemEntities[i].type = ENTITY_ITEM;
itemEntities[i].unk24 = 0;
itemEntities[i].isVisible = TRUE;
itemEntities[i].unk22 = 0;
itemEntities[i].axObj.info.item = &item[i];
itemEntities[i].pos = targetTilePos[i];
x = ((pos1->x * 24) + 4) << 8;
y = ((pos1->y * 24) + 4) << 8;
SetEntityPixelPos(&itemEntities[i], x, y);
itemEntities[i].spawnGenID = 0;
itemVelocity[i].x = ((((targetTilePos[i].x * 24) + 4) << 8) - (itemEntities[i].pixelPos.x)) / 24;
itemVelocity[i].y = ((((targetTilePos[i].y * 24) + 4) << 8) - (itemEntities[i].pixelPos.y)) / 24;
r1 = TRUE;
}
}
if (!r1) {
if (count > 1) {
LogMessageByIdWithPopupCheckUser_Async(entity, gAllItemsLost);
}
else {
LogMessageByIdWithPopupCheckUser_Async(entity, gItemLost);
}
}
else {
s32 counter;
s32 dirMaybe;
bool8 hallucinating;
if (r9) {
LogMessageByIdWithPopupCheckUser_Async(entity, gSeveralItemsLost);
}
dirMaybe = 0;
hallucinating = gDungeon->unk181e8.hallucinating;
sinVal = 0;
for (counter = 0; counter < 24; counter++) {
for (i = 0; i < count; i++) {
if (EntityIsValid(&itemEntities[i])) {
IncreaseEntityPixelPos(&itemEntities[i], itemVelocity[i].x, itemVelocity[i].y);
itemEntities[i].unk1C = sin_4096(sinVal) * 12;
sub_80462AC(&itemEntities[i], hallucinating, 1, dirMaybe, 0);
}
}
DungeonRunFrameActions(0x13);
sinVal += 85;
if ((counter & 3) == 0) {
dirMaybe++;
}
dirMaybe &= 7;
}
for (i = 0; i < count; i++) {
if (targetTilePos[i].x >= 0) {
SpawnItem(&targetTilePos[i], &item[i], TRUE);
}
}
}
}
bool8 HasHeldItem(Entity *pokemon, u8 id)
{
EntityInfo *pokemonInfo = GetEntInfo(pokemon);
if (!ItemExists(&pokemonInfo->heldItem)) {
return FALSE;
}
if (pokemonInfo->heldItem.flags & ITEM_FLAG_STICKY) {
return FALSE;
}
if (pokemonInfo->heldItem.id != id) {
return FALSE;
}
return TRUE;
}
static void sub_8046CE4(Item *item,s32 param_2)
{
s32 i;
s32 rand = DungeonRandInt(100);
for (i = 0; i < 200; i++) {
if (gUnknown_810A3F0[rand] <= param_2) {
item->quantity = rand;
return;
}
rand /= 2;
}
item->quantity = 1;
}
void PotentiallyCreateMusicBox_Async(void)
{
bool8 b = gDungeon->unk8;
gDungeon->unk8 = sub_8046D70();
if (gDungeon->unk8 == TRUE && !b && DisplayDungeonYesNoMessage_Async(NULL, gUnknown_80FA408, TRUE) == TRUE) {
gDungeon->unk4 = 1;
gDungeon->unk11 = 2;
}
else {
MusicBoxCreation_Async();
}
}
static bool8 sub_8046D70(void)
{
// Insane
if (gDungeon->unk644.unk46)
return FALSE;
else
return FALSE;
}
static void MusicBoxCreation_Async(void)
{
bool8 musicBoxOnce;
bool8 createMusicBox;
s32 i;
s32 indexes[3];
createMusicBox = FALSE;
do {
musicBoxOnce = FALSE;
indexes[0] = -1;
indexes[1] = -1;
indexes[2] = -1;
for (i = 0; i < INVENTORY_SIZE; i++) {
Item *item = &gTeamInventoryRef->teamItems[i];
if (ItemExists(item)) {
if (item->id == ITEM_ROCK_PART) {
indexes[0] = i;
}
if (item->id == ITEM_ICE_PART) {
indexes[1] = i;
}
if (item->id == ITEM_STEEL_PART) {
indexes[2] = i;
}
}
}
if ((indexes[0] >= 0) && (indexes[1] >= 0) && (indexes[2] >= 0)) {
musicBoxOnce = TRUE;
createMusicBox = TRUE;
// clear out each of the parts
ZeroOutItem(&gTeamInventoryRef->teamItems[indexes[0]]);
ZeroOutItem(&gTeamInventoryRef->teamItems[indexes[1]]);
ZeroOutItem(&gTeamInventoryRef->teamItems[indexes[2]]);
// init the music box
ItemIdToItem(&gTeamInventoryRef->teamItems[indexes[0]], ITEM_MUSIC_BOX, 0);
}
} while (musicBoxOnce);
FillInventoryGaps();
if (createMusicBox) {
Entity *leader = GetLeader();
sub_80855E4(sub_80861A8);
gDungeon->unk1356C = TRUE;
DisplayDungeonMessage_Async(0,gUnknown_810531C,1);
DungeonWaitFrames_Async(0x3c,0x41);
DisplayDungeonMessage_Async(0,gUnknown_8105360,1);
CutsceneLookDir_Async(leader,4,DIR_TRANS_10,0);
sub_80416E0(&leader->pixelPos,0x10c,FALSE);
sub_80421C0(leader,0xd7);
DungeonWaitFrames_Async(0x3c,0x41);
SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0],leader,0);
DisplayDungeonMessage_Async(0,gUnknown_81053A8,1);
DungeonWaitFrames_Async(10,0x41);
PlaySoundEffect(0xd4);
DisplayDungeonMessage_Async(0,gUnknown_8105434,1);
DungeonWaitFrames_Async(10,0x41);
sub_804178C_Async(TRUE);
gDungeon->unk1356C = FALSE;
UpdateMinimap();
}
}
bool8 sub_8046F00(Item *item)
{
s32 i;
if (GetItemCategory(item->id) == CATEGORY_TMS_HMS) {
u16 moveID = GetItemMoveID(item->id);
if (!IsHMItem(item->id)) {
for (i = 0; i < MAX_TEAM_MEMBERS; i++) {
Entity *entity = gDungeon->teamPokemon[i];
if (EntityIsValid(entity)) {
bool8 canLearnMove = CanMonLearnMove(moveID, GetEntInfo(entity)->id);
bool8 cannotMove = CheckVariousStatuses2(entity, FALSE);
if (cannotMove) {
canLearnMove = FALSE;
}
if (canLearnMove)
return TRUE;
}
}
}
return FALSE;
}
return TRUE;
}
void ClearAllItemsWithFlag(s32 itemFlag)
{
s32 i;
for (i = 0; i < INVENTORY_SIZE; i++) {
Item *item = &gTeamInventoryRef->teamItems[i];
if ((item->flags & ITEM_FLAG_EXISTS) && (item->flags & itemFlag)) {
ZeroOutItem(item);
}
}
FillInventoryGaps();
for (i = 0; i < MAX_TEAM_MEMBERS; i++) {
Entity *entity = gDungeon->teamPokemon[i];
if (EntityIsValid(entity)) {
EntityInfo *entityInfo = GetEntInfo(entity);
Item *item = &entityInfo->heldItem;
if ((item->flags & ITEM_FLAG_EXISTS) && (item->flags & itemFlag)) {
ZeroOutItem(item);
}
}
}
}
void AllItemsToPlainSeed(void)
{
s32 i;
for (i = 0; i < INVENTORY_SIZE; i++)
{
Item *item = &gTeamInventoryRef->teamItems[i];
if ((item->flags & ITEM_FLAG_EXISTS)) {
ItemIdToItem(item, ITEM_PLAIN_SEED, FALSE);
}
}
FillInventoryGaps();
for (i = 0; i < MAX_TEAM_MEMBERS; i++) {
Entity *entity = gDungeon->teamPokemon[i];
if (EntityIsValid(entity)) {
EntityInfo *entityInfo = GetEntInfo(entity);
Item *item = &entityInfo->heldItem;
if ((item->flags & ITEM_FLAG_EXISTS)) {
ItemIdToItem(item, ITEM_PLAIN_SEED, FALSE);
}
}
}
}
bool8 PlayerHasItemWithFlag(s32 itemFlag)
{
s32 i;
for (i = 0; i < INVENTORY_SIZE; i++)
{
if ((ItemExists(&gTeamInventoryRef->teamItems[i])) && (gTeamInventoryRef->teamItems[i].flags & itemFlag)) {
return TRUE;
}
}
FillInventoryGaps();
for (i = 0; i < MAX_TEAM_MEMBERS; i++)
{
Entity *entity = gDungeon->teamPokemon[i];
if (EntityIsValid(entity)) {
EntityInfo *entityInfo = GetEntInfo(entity);
Item *item = &entityInfo->heldItem;
if ((ItemExists(item) & ITEM_FLAG_EXISTS) && (item->flags & itemFlag)) {
return TRUE;
}
}
}
return FALSE;
}
void CleanUpInventoryItems(void)
{
s32 i;
for (i = 0; i < INVENTORY_SIZE; i++) {
Item *item = &gTeamInventoryRef->teamItems[i];
if (item->flags & ITEM_FLAG_EXISTS) {
if (item->id == ITEM_POKE) {
AddToTeamMoney(GetMoneyValue(item));
ZeroOutItem(item);
}
if (item->flags & ITEM_FLAG_IN_SHOP) {
ZeroOutItem(item);
}
}
}
FillInventoryGaps();
}
void ClearUnpaidFlagFromAllItems(void)
{
s32 i;
for (i = 0; i < INVENTORY_SIZE; i++) {
Item *item = &gTeamInventoryRef->teamItems[i];
if (ItemExists(item) && item->flags & ITEM_FLAG_UNPAID) {
item->flags &= ~(ITEM_FLAG_UNPAID);
}
}
}