From aa027ec549e147b6edbf1251d909f62ca89a994b Mon Sep 17 00:00:00 2001 From: iProgramInCpp Date: Fri, 4 Aug 2023 09:54:39 +0300 Subject: [PATCH] * Improve the inventory. Prepare for survival mode inventory. --- source/GUI/Gui.cpp | 2 +- .../GUI/Screen/IngameBlockSelectionScreen.cpp | 101 +++--- .../GUI/Screen/IngameBlockSelectionScreen.hpp | 5 + source/Inventory.cpp | 322 ++++++++---------- source/Inventory.hpp | 30 +- source/Network/ClientSideNetworkHandler.cpp | 2 +- source/Network/ServerSideNetworkHandler.cpp | 2 +- source/World/Entity/Player.cpp | 3 + source/World/Item/ItemInstance.cpp | 6 + source/World/Item/ItemInstance.hpp | 1 + source/World/LevelData.cpp | 6 +- source/World/Renderer/ItemRenderer.cpp | 119 ++++--- 12 files changed, 290 insertions(+), 309 deletions(-) diff --git a/source/GUI/Gui.cpp b/source/GUI/Gui.cpp index fbad417..edc0aa2 100644 --- a/source/GUI/Gui.cpp +++ b/source/GUI/Gui.cpp @@ -315,7 +315,7 @@ void Gui::tick() void Gui::renderSlot(int slot, int x, int y, float f) { - int itemID = m_pMinecraft->m_pLocalPlayer->m_pInventory->getSelectionSlotItemId(slot); + int itemID = m_pMinecraft->m_pLocalPlayer->m_pInventory->getQuickSlotItemId(slot); if (itemID < 0) return; diff --git a/source/GUI/Screen/IngameBlockSelectionScreen.cpp b/source/GUI/Screen/IngameBlockSelectionScreen.cpp index 552ea2d..b8960de 100644 --- a/source/GUI/Screen/IngameBlockSelectionScreen.cpp +++ b/source/GUI/Screen/IngameBlockSelectionScreen.cpp @@ -9,16 +9,27 @@ #include "IngameBlockSelectionScreen.hpp" #include "ItemRenderer.hpp" -#define C_SLOTS_HEIGHT ((C_MAX_INVENTORY_ITEMS + 8) / 9) - std::string g_sNotAvailableInDemoVersion = "Not available in the demo version"; +Inventory* IngameBlockSelectionScreen::getInventory() +{ + return m_pMinecraft->m_pLocalPlayer->m_pInventory; +} + +int IngameBlockSelectionScreen::getBottomY() +{ + // -1 for some reason, -2 to make it align between top of screen and top of hotbar instead + return (m_height - 22 * (getSlotsHeight() - 2)) / 2; +} + int IngameBlockSelectionScreen::getSelectedSlot(int x, int y) { - int bottom = m_height - 151; + int slotsHeight = getSlotsHeight(); + int bottom = m_height - getBottomY(); + int top = bottom - slotsHeight * 22; int left = m_width / 2 - 87; - if (y < bottom) + if (y < top) return -1; if (x < left) return -1; @@ -27,7 +38,7 @@ int IngameBlockSelectionScreen::getSelectedSlot(int x, int y) if (idx > 8) return -1; - return idx + 36 - 9 * ((y - bottom) / 22); + return idx + 9 * slotsHeight - 9 * ((y - top) / 22); } int IngameBlockSelectionScreen::getSlotPosX(int x) @@ -37,27 +48,28 @@ int IngameBlockSelectionScreen::getSlotPosX(int x) int IngameBlockSelectionScreen::getSlotPosY(int y) { - return m_height - 63 - 22 * y; + return m_height - getBottomY() - 22 * y; +} + +int IngameBlockSelectionScreen::getSlotsHeight() +{ + return (getInventory()->getNumSlots() + 8) / 9; } bool IngameBlockSelectionScreen::isAllowed(int slot) { - if (slot < 0 || slot > C_MAX_INVENTORY_ITEMS-1) - return false; - -#ifdef DEMO - return slot > 17; -#endif - return true; + return slot >= 0 && slot < getInventory()->getNumSlots(); } void IngameBlockSelectionScreen::init() { - Inventory* pInv = m_pMinecraft->m_pLocalPlayer->m_pInventory; + Inventory* pInv = getInventory(); - for (int i = 9; i < C_MAX_HOTBAR_ITEMS + C_MAX_INVENTORY_ITEMS; i++) + int nItems = pInv->getNumItems(); + + for (int i = 0; i < nItems; i++) { - if (pInv->getSelectionSlotItemId(i) == pInv->getSelectedItemId()) + if (pInv->getItem(i)->m_itemID == pInv->getSelectedItemId()) { m_selectedSlot = i - 9; break; @@ -65,17 +77,16 @@ void IngameBlockSelectionScreen::init() } if (!isAllowed(m_selectedSlot)) - m_selectedSlot = 27; + m_selectedSlot = 0; } void IngameBlockSelectionScreen::renderSlot(int index, int x, int y, float f) { - int item = m_pMinecraft->m_pLocalPlayer->m_pInventory->getSelectionSlotItemId(index); - if (item < 0) + ItemInstance* pItem = getInventory()->getItem(index); + if (!pItem) return; - ItemInstance inst(item, 2, 0); - ItemRenderer::renderGuiItem(m_pMinecraft->m_pFont, m_pMinecraft->m_pTextures, &inst, x, y, item); + ItemRenderer::renderGuiItem(m_pMinecraft->m_pFont, m_pMinecraft->m_pTextures, pItem, x, y, pItem != nullptr); } void IngameBlockSelectionScreen::renderSlots() @@ -83,13 +94,13 @@ void IngameBlockSelectionScreen::renderSlots() glColor4f(1.0f, 1.0f, 1.0f, 1.0f); m_pMinecraft->m_pTextures->loadAndBindTexture("gui/gui.png"); - for (int y = 0; y != -22 * C_SLOTS_HEIGHT; y -= 22) - blit(m_width / 2 - 182 / 2, m_height - 66 + y, 0, 0, 182, 22, 0, 0); + for (int y = 0; y != -22 * getSlotsHeight(); y -= 22) + blit(m_width / 2 - 182 / 2, m_height - 3 - getBottomY() + y, 0, 0, 182, 22, 0, 0); if (m_selectedSlot >= 0) - blit(m_width / 2 - 92 + 20 * (m_selectedSlot % 9), m_height - 67 - 22 * (m_selectedSlot / 9), 0, 22, 24, 22, 0, 0); + blit(m_width / 2 - 92 + 20 * (m_selectedSlot % 9), m_height - 4 - getBottomY() - 22 * (m_selectedSlot / 9), 0, 22, 24, 22, 0, 0); - for (int y = 0, index = 9; y < C_SLOTS_HEIGHT; y++) + for (int y = 0, index = 0; y < getSlotsHeight(); y++) { int posY = getSlotPosY(y); for (int x = 0; x < 9; x++) @@ -151,44 +162,10 @@ void IngameBlockSelectionScreen::mouseReleased(int x, int y, int type) void IngameBlockSelectionScreen::selectSlotAndClose() { - Inventory* pInv = m_pMinecraft->m_pLocalPlayer->m_pInventory; - int item = pInv->getSelectionSlotItemId(m_selectedSlot + 9); - int idx = 0; - - // @TODO: Fix gotos -#ifdef ENH_ENABLE_9TH_SLOT -#define MAX_ITEMS (C_MAX_HOTBAR_ITEMS - 1) -#else -#define MAX_ITEMS (C_MAX_HOTBAR_ITEMS - 2) -#endif - - if (item == pInv->getSelectionSlotItemId(0)) - { - label_4: - if (!idx) - goto label_5; - } - else while (++idx != MAX_ITEMS) - { - if (item == pInv->getSelectionSlotItemId(idx)) - goto label_4; - } - - while (true) - { - int item = pInv->getSelectionSlotItemId(idx - 1); - pInv->setSelectionSlotItemId(idx, item); - - if (idx == 1) - break; - - --idx; - } -label_5: - pInv->setSelectionSlotItemId(0, item); - pInv->selectSlot(0); + Inventory* pInv = getInventory(); + + pInv->selectItem(m_selectedSlot); m_pMinecraft->m_pSoundEngine->play("random.click"); - m_pMinecraft->setScreen(nullptr); } diff --git a/source/GUI/Screen/IngameBlockSelectionScreen.hpp b/source/GUI/Screen/IngameBlockSelectionScreen.hpp index 5e8613b..c1cc70a 100644 --- a/source/GUI/Screen/IngameBlockSelectionScreen.hpp +++ b/source/GUI/Screen/IngameBlockSelectionScreen.hpp @@ -10,12 +10,17 @@ #include "Screen.hpp" +class Inventory; + class IngameBlockSelectionScreen : public Screen { public: + Inventory* getInventory(); + int getBottomY(); int getSelectedSlot(int x, int y); int getSlotPosX(int x); int getSlotPosY(int y); + int getSlotsHeight(); bool isAllowed(int slot); void renderSlots(); void renderDemoOverlay(); diff --git a/source/Inventory.cpp b/source/Inventory.cpp index 96aa305..bb081e7 100644 --- a/source/Inventory.cpp +++ b/source/Inventory.cpp @@ -1,85 +1,6 @@ #include "Inventory.hpp" #include "Item.hpp" -#ifdef DEMO - -static void MoveItemToSlot(int* pItems, int item, int index) -{ - if (index < 0 || index >= C_MAX_INVENTORY_ITEMS) - return; - - if (pItems[index] == item) - return; - - // search for the item, if it doesn't exist, return - - int i = 0; - for (; i < C_MAX_INVENTORY_ITEMS; i++) - { - if (pItems[i] == item) - break; - } - - if (i == C_MAX_INVENTORY_ITEMS) - return; - - // swap the slot where our `item` was, and the slot at the index - int oldItem = pItems[index]; - pItems[index] = pItems[i]; - pItems[i] = oldItem; - -#ifndef ORIGINAL_CODE - if (item > 0) -#endif - printf("adding item: %s to %d\n", Tile::tiles[item]->getDescriptionId().c_str(), index); -} - -static void ShuffleInventoryForDemo(int* pHotbar, int* pItems) -{ - pHotbar[0] = Tile::wood->m_ID; - pHotbar[1] = Tile::stoneBrick->m_ID; - pHotbar[2] = Tile::sandStone->m_ID; - pHotbar[3] = Tile::dirt->m_ID; - pHotbar[4] = Tile::redBrick->m_ID; - pHotbar[5] = Tile::rock->m_ID; - pHotbar[6] = Tile::torch->m_ID; - pHotbar[7] = Tile::ladder->m_ID; -#ifdef ENH_ENABLE_9TH_SLOT - pHotbar[8] = Tile::rose->m_ID; -#endif - - MoveItemToSlot(pItems, pHotbar[0], 27); - MoveItemToSlot(pItems, pHotbar[1], 28); - MoveItemToSlot(pItems, pHotbar[2], 29); - MoveItemToSlot(pItems, pHotbar[3], 30); - MoveItemToSlot(pItems, pHotbar[4], 31); - MoveItemToSlot(pItems, pHotbar[5], 32); - MoveItemToSlot(pItems, pHotbar[6], 33); - MoveItemToSlot(pItems, pHotbar[7], 34); - MoveItemToSlot(pItems, Tile::flower->m_ID, 35); - MoveItemToSlot(pItems, Tile::cloth_10->m_ID, 18); - MoveItemToSlot(pItems, Tile::cloth_20->m_ID, 19); - MoveItemToSlot(pItems, Tile::cloth_30->m_ID, 20); - MoveItemToSlot(pItems, Tile::cloth_40->m_ID, 21); - MoveItemToSlot(pItems, Tile::cloth_50->m_ID, 22); - MoveItemToSlot(pItems, Tile::cloth_60->m_ID, 23); - MoveItemToSlot(pItems, Tile::cloth_70->m_ID, 24); - MoveItemToSlot(pItems, Tile::sand->m_ID, 25); - MoveItemToSlot(pItems, Tile::glass->m_ID, 26); - MoveItemToSlot(pItems, Tile::mushroom1->m_ID, 1); - MoveItemToSlot(pItems, Tile::obsidian->m_ID, 8); - -#ifndef ORIGINAL_CODE - // @NOTE: For Testing - //pHotbar[1] = Item::camera->m_itemID; - //pHotbar[2] = Tile::tnt->m_ID; - //pHotbar[3] = Tile::water->m_ID; - //pHotbar[4] = Tile::lava->m_ID; -#endif -} - -#endif - Inventory::Inventory(Player* pPlayer) { m_pPlayer = pPlayer; @@ -87,116 +8,175 @@ Inventory::Inventory(Player* pPlayer) for (int i = 0; i < C_MAX_HOTBAR_ITEMS; i++) m_hotbar[i] = -1; - for (int i = 0; i < C_MAX_INVENTORY_ITEMS; i++) - m_items[i] = -1; - - // @NOTE: This layout of the hotbar and inventory can be seen in the following video, - // titled "Minecraft - Pocket Edition on Xperia Play". - // https://www.youtube.com/watch?v=jO-y5wzmK4E - - m_hotbar[0] = Tile::wood->m_ID; - m_hotbar[1] = Tile::cloth_10->m_ID; - m_hotbar[2] = Tile::cloth_20->m_ID; - m_hotbar[3] = Tile::cloth_30->m_ID; - m_hotbar[4] = Tile::cloth_40->m_ID; - m_hotbar[5] = Tile::cloth_50->m_ID; - m_hotbar[6] = Tile::cloth_60->m_ID; - m_hotbar[7] = Tile::ladder->m_ID; - - // slot 8 missing. I assume that's the "..." button - - m_items[0] = Tile::rock->m_ID; - m_items[1] = Tile::stoneBrick->m_ID; - m_items[2] = Tile::sandStone->m_ID; - m_items[3] = Tile::wood->m_ID; - m_items[4] = Tile::treeTrunk->m_ID; - m_items[5] = Tile::goldBlock->m_ID; - m_items[6] = Tile::ironBlock->m_ID; - m_items[7] = Tile::emeraldBlock->m_ID; - m_items[8] = Tile::redBrick->m_ID; - m_items[9] = Tile::leaves->m_ID; - m_items[10] = Tile::cloth_10->m_ID; - m_items[11] = Tile::cloth_20->m_ID; - m_items[12] = Tile::cloth_30->m_ID; - m_items[13] = Tile::cloth_40->m_ID; - m_items[14] = Tile::cloth_50->m_ID; - m_items[15] = Tile::cloth_60->m_ID; - m_items[16] = Tile::cloth_70->m_ID; - m_items[17] = Tile::glass->m_ID; - m_items[18] = Tile::cloth_01->m_ID; - m_items[19] = Tile::cloth_11->m_ID; - m_items[20] = Tile::cloth_21->m_ID; - m_items[21] = Tile::cloth_31->m_ID; - m_items[22] = Tile::cloth_41->m_ID; - m_items[23] = Tile::stairs_wood->m_ID; - m_items[24] = Tile::stairs_stone->m_ID; - m_items[25] = Tile::stoneSlabHalf->m_ID; - m_items[26] = Tile::sand->m_ID; - m_items[27] = Tile::ladder->m_ID; - m_items[28] = Tile::torch->m_ID; - m_items[29] = Tile::flower->m_ID; - m_items[30] = Tile::rose->m_ID; - m_items[31] = Tile::mushroom1->m_ID; - m_items[32] = Tile::mushroom2->m_ID; - m_items[33] = Tile::reeds->m_ID; - m_items[34] = Tile::obsidian->m_ID; - m_items[35] = Tile::dirt->m_ID; - -#ifdef DEMO - ShuffleInventoryForDemo(m_hotbar, m_items); -#endif - -#ifdef ENH_EXTRA_ITEMS_IN_INV - // populate the 5th row now with items that might be of interest - m_items[36] = Tile::tnt->m_ID; - m_items[37] = Item::camera->m_itemID; - m_items[38] = Item::door_wood->m_itemID; - m_items[39] = Tile::gravel->m_ID; - m_items[40] = Tile::cloth->m_ID; - m_items[41] = Tile::mossStone->m_ID; - m_items[42] = Tile::bookshelf->m_ID; - m_items[43] = Tile::sponge->m_ID; - m_items[44] = Tile::sapling->m_ID; -#endif } -#ifdef ENH_ENABLE_9TH_SLOT -#define HOTBAR_DIFF 0 -#else -#define HOTBAR_DIFF 1 -#endif - -int Inventory::getSelectionSize() +void Inventory::prepareCreativeInventory() { - return C_MAX_HOTBAR_ITEMS; + m_bIsSurvival = false; + + m_items.clear(); + + // add some items + addCreativeItem(Tile::rock->m_ID); + addCreativeItem(Tile::stoneBrick->m_ID); + addCreativeItem(Tile::sandStone->m_ID); + addCreativeItem(Tile::wood->m_ID); + addCreativeItem(Tile::treeTrunk->m_ID); + addCreativeItem(Tile::goldBlock->m_ID); + addCreativeItem(Tile::ironBlock->m_ID); + addCreativeItem(Tile::emeraldBlock->m_ID); + addCreativeItem(Tile::redBrick->m_ID); + addCreativeItem(Tile::leaves->m_ID); + addCreativeItem(Tile::cloth_10->m_ID); + addCreativeItem(Tile::cloth_20->m_ID); + addCreativeItem(Tile::cloth_30->m_ID); + addCreativeItem(Tile::cloth_40->m_ID); + addCreativeItem(Tile::cloth_50->m_ID); + addCreativeItem(Tile::cloth_60->m_ID); + addCreativeItem(Tile::cloth_70->m_ID); + addCreativeItem(Tile::glass->m_ID); + addCreativeItem(Tile::cloth_01->m_ID); + addCreativeItem(Tile::cloth_11->m_ID); + addCreativeItem(Tile::cloth_21->m_ID); + addCreativeItem(Tile::cloth_31->m_ID); + addCreativeItem(Tile::cloth_41->m_ID); + addCreativeItem(Tile::stairs_wood->m_ID); + addCreativeItem(Tile::stairs_stone->m_ID); + addCreativeItem(Tile::stoneSlabHalf->m_ID); + addCreativeItem(Tile::sand->m_ID); + addCreativeItem(Tile::ladder->m_ID); + addCreativeItem(Tile::torch->m_ID); + addCreativeItem(Tile::flower->m_ID); + addCreativeItem(Tile::rose->m_ID); + addCreativeItem(Tile::mushroom1->m_ID); + addCreativeItem(Tile::mushroom2->m_ID); + addCreativeItem(Tile::reeds->m_ID); + addCreativeItem(Tile::obsidian->m_ID); + addCreativeItem(Tile::dirt->m_ID); + addCreativeItem(Tile::tnt->m_ID); + addCreativeItem(Tile::gravel->m_ID); + addCreativeItem(Tile::cloth->m_ID); + addCreativeItem(Tile::mossStone->m_ID); + addCreativeItem(Tile::bookshelf->m_ID); + addCreativeItem(Tile::sponge->m_ID); + addCreativeItem(Tile::sapling->m_ID); + addCreativeItem(Tile::water->m_ID); + addCreativeItem(Tile::lava->m_ID); + addCreativeItem(Tile::fire->m_ID); + addCreativeItem(Item::camera->m_itemID); + addCreativeItem(Item::door_wood->m_itemID); + addCreativeItem(Item::door_iron->m_itemID); + + for (int i = C_MAX_HOTBAR_ITEMS - 1; i >= 0; i--) + selectItem(i); } -int Inventory::getSelectionSlotItemId(int slot) +void Inventory::prepareSurvivalInventory() { - if (slot >= 0 && slot < C_MAX_HOTBAR_ITEMS - HOTBAR_DIFF) - return m_hotbar[slot]; + m_bIsSurvival = true; + m_items.clear(); +} - if (slot > C_MAX_HOTBAR_ITEMS + C_MAX_INVENTORY_ITEMS - 1 || slot < 0) +int Inventory::getNumSlots() +{ + if (m_bIsSurvival) + return C_NUM_SURVIVAL_SLOTS; + + return getNumItems(); +} + +int Inventory::getNumItems() +{ + return int(m_items.size()); +} + +void Inventory::addCreativeItem(int itemID, int auxValue) +{ + m_items.emplace_back(ItemInstance(itemID, 1, auxValue)); +} + +ItemInstance* Inventory::getItem(int slotNo) +{ + if (slotNo < 0 || slotNo >= int(m_items.size())) + return nullptr; + + return &m_items[slotNo]; +} + +int Inventory::getQuickSlotItemId(int slotNo) +{ + if (slotNo < 0 || slotNo >= C_MAX_HOTBAR_ITEMS) + return -1; + + int idx = m_hotbar[slotNo]; + ItemInstance* pInst = getItem(idx); + if (!pInst) return -1; - return m_items[slot - C_MAX_HOTBAR_ITEMS]; -} - -void Inventory::setSelectionSlotItemId(int slotNo, int item) -{ - if (slotNo >= 0 && slotNo < C_MAX_HOTBAR_ITEMS - HOTBAR_DIFF) - m_hotbar[slotNo] = item; + return pInst->m_itemID; } int Inventory::getSelectedItemId() { - return getSelectionSlotItemId(m_SelectedHotbarSlot); + return getQuickSlotItemId(m_SelectedHotbarSlot); +} + +void Inventory::selectItem(int slotNo) +{ + if (slotNo < 0 || slotNo >= getNumItems()) + return; + + // look for it in the hotbar + for (int i = 0; i < C_MAX_HOTBAR_ITEMS; i++) + { + if (m_hotbar[i] == slotNo) + { + m_SelectedHotbarSlot = i; + return; + } + } + + for (int i = C_MAX_HOTBAR_ITEMS - 2; i >= 0; i--) + m_hotbar[i + 1] = m_hotbar[i]; + + m_hotbar[0] = slotNo; + m_SelectedHotbarSlot = 0; } void Inventory::selectSlot(int slotNo) { - if (slotNo < 0 || slotNo >= C_MAX_HOTBAR_ITEMS - HOTBAR_DIFF) + if (slotNo < 0 || slotNo >= C_MAX_HOTBAR_ITEMS) return; m_SelectedHotbarSlot = slotNo; } + +void Inventory::setQuickSlotIndexByItemId(int slotNo, int itemID) +{ + if (slotNo < 0 || slotNo >= C_MAX_HOTBAR_ITEMS) + return; + + // TODO: survival mode handling + for (int i = 0; i < getNumItems(); i++) + { + if (m_items[i].m_itemID == itemID) + { + m_hotbar[slotNo] = i; + return; + } + } + + m_hotbar[slotNo] = -1; +} + +void Inventory::selectItemById(int itemID) +{ + for (int i = 0; i < getNumItems(); i++) + { + if (m_items[i].m_itemID != itemID) + continue; + + selectItem(i); + return; + } +} diff --git a/source/Inventory.hpp b/source/Inventory.hpp index c0b1759..50322f3 100644 --- a/source/Inventory.hpp +++ b/source/Inventory.hpp @@ -1,33 +1,41 @@ #pragma once #include "Player.hpp" +#include "ItemInstance.hpp" class Player; // in case we're included from Player.hpp #define C_MAX_HOTBAR_ITEMS (9) -#ifdef ENH_EXTRA_ITEMS_IN_INV -#define C_MAX_INVENTORY_ITEMS (36+9) -#else -#define C_MAX_INVENTORY_ITEMS (36) -#endif +#define C_NUM_SURVIVAL_SLOTS (36) class Inventory { public: Inventory(Player*); + void prepareCreativeInventory(); + void prepareSurvivalInventory(); - int getSelectionSize(); - int getSelectionSlotItemId(int slotNo); + int getNumSlots(); + int getNumItems(); + + void addCreativeItem(int itemID, int auxValue = 0); + + ItemInstance* getItem(int slotNo); + int getQuickSlotItemId(int slotNo); int getSelectedItemId(); + void selectItem(int slotNo); // selects an item by slot number and puts it in the quick slots if needed void selectSlot(int slotNo); - void setSelectionSlotItemId(int slotNo, int item); + + void setQuickSlotIndexByItemId(int slotNo, int itemID); + void selectItemById(int itemID); public: - int m_SelectedHotbarSlot; - Player* m_pPlayer; + int m_SelectedHotbarSlot = 0; + Player* m_pPlayer = nullptr; + bool m_bIsSurvival = false; int m_hotbar[C_MAX_HOTBAR_ITEMS]; - int m_items [C_MAX_INVENTORY_ITEMS]; + std::vector m_items; }; diff --git a/source/Network/ClientSideNetworkHandler.cpp b/source/Network/ClientSideNetworkHandler.cpp index 9ceff72..2dcfc89 100644 --- a/source/Network/ClientSideNetworkHandler.cpp +++ b/source/Network/ClientSideNetworkHandler.cpp @@ -335,7 +335,7 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, PlayerE return; } - pPlayer->m_pInventory->setSelectionSlotItemId(0, pPlayerEquipmentPkt->m_itemID); + pPlayer->m_pInventory->selectItemById(pPlayerEquipmentPkt->m_itemID); pPlayer->m_pInventory->selectSlot(0); } diff --git a/source/Network/ServerSideNetworkHandler.cpp b/source/Network/ServerSideNetworkHandler.cpp index 52d8351..8ca16e0 100644 --- a/source/Network/ServerSideNetworkHandler.cpp +++ b/source/Network/ServerSideNetworkHandler.cpp @@ -200,7 +200,7 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& guid, PlayerEqui return; } - pPlayer->m_pInventory->setSelectionSlotItemId(0, packet->m_itemID); + pPlayer->m_pInventory->selectItemById(packet->m_itemID); pPlayer->m_pInventory->selectSlot(0); redistributePacket(packet, guid); diff --git a/source/World/Entity/Player.cpp b/source/World/Entity/Player.cpp index 38dff19..38d7b58 100644 --- a/source/World/Entity/Player.cpp +++ b/source/World/Entity/Player.cpp @@ -15,6 +15,9 @@ Player::Player(Level* pLevel) : Mob(pLevel) m_pInventory = new Inventory(this); + // @TODO: GameMode::prepareInventory + m_pInventory->prepareCreativeInventory(); + field_84 = 1.62f; Pos pos = m_pLevel->getSharedSpawnPos(); diff --git a/source/World/Item/ItemInstance.cpp b/source/World/Item/ItemInstance.cpp index d9073a3..b24c720 100644 --- a/source/World/Item/ItemInstance.cpp +++ b/source/World/Item/ItemInstance.cpp @@ -14,10 +14,16 @@ void ItemInstance::init(int itemID, int amount, int auxValue) { m_itemID = itemID; m_amount = amount; + m_auxValue = auxValue; //@BUG? Not using the auxValue. This is problematic in the case of wool and dyes. } +ItemInstance::ItemInstance() +{ + init(0, 0, 0); +} + ItemInstance::ItemInstance(Item* pItem) { init(pItem->m_itemID, 1, 0); diff --git a/source/World/Item/ItemInstance.hpp b/source/World/Item/ItemInstance.hpp index 92295c5..1a1aba0 100644 --- a/source/World/Item/ItemInstance.hpp +++ b/source/World/Item/ItemInstance.hpp @@ -20,6 +20,7 @@ class Player; class ItemInstance { public: + ItemInstance(); ItemInstance(Item*); ItemInstance(Item*, int amount); ItemInstance(Item*, int amount, int auxValue); diff --git a/source/World/LevelData.cpp b/source/World/LevelData.cpp index 7725d50..573ed81 100644 --- a/source/World/LevelData.cpp +++ b/source/World/LevelData.cpp @@ -70,8 +70,9 @@ void PlayerData::loadPlayer(Player* player) // @NOTE: Why are we updating m_pos, field_3C and field_98 above if we do this? player->setPos(m_pos.x, m_pos.y, m_pos.z); + // TODO: survival mode stuff for (int i = 0; i < C_MAX_HOTBAR_ITEMS; i++) - player->m_pInventory->setSelectionSlotItemId(i, m_hotbar[i]); + player->m_pInventory->setQuickSlotIndexByItemId(i, m_hotbar[i]); } void PlayerData::savePlayer(Player* player) @@ -85,6 +86,7 @@ void PlayerData::savePlayer(Player* player) field_26 = player->field_BC; field_28 = player->field_7C; + // TODO: survival mode stuff for (int i = 0; i < C_MAX_HOTBAR_ITEMS; i++) - m_hotbar[i] = player->m_pInventory->getSelectionSlotItemId(i); + m_hotbar[i] = player->m_pInventory->getQuickSlotItemId(i); } diff --git a/source/World/Renderer/ItemRenderer.cpp b/source/World/Renderer/ItemRenderer.cpp index aaee605..ce8f06f 100644 --- a/source/World/Renderer/ItemRenderer.cpp +++ b/source/World/Renderer/ItemRenderer.cpp @@ -165,87 +165,86 @@ void ItemRenderer::renderGuiItem(Font* font, Textures* textures, ItemInstance* i return; int itemID = instance->m_itemID; - if (b) - { - // @BUG: This is one of the reasons you can't actually hold items in early Minecraft. - // There's an attempt to index `Tile::tiles` out of bounds, which of course fails, and likely crashes the game. :( - // If only they'd placed the g_ItemFrames[itemID] check before the TileRenderer::canRender check... + if (!b) + return; + + // @BUG: This is one of the reasons you can't actually hold items in early Minecraft. + // There's an attempt to index `Tile::tiles` out of bounds, which of course fails, and likely crashes the game. :( + // If only they'd placed the g_ItemFrames[itemID] check before the TileRenderer::canRender check... #ifdef ORIGINAL_CODE #define COND_PRE #else #define COND_PRE (0 <= itemID && itemID < C_MAX_TILES) && #endif - bool bCanRenderAsIs = false; + bool bCanRenderAsIs = false; #ifdef ENH_3D_INVENTORY_TILES - // We don't need to care about g_ItemFrames at all since blocks will get 3D rendered and 2D props will use the terrain.png as the texture. - if (COND_PRE(TileRenderer::canRender(Tile::tiles[itemID]->getRenderShape()))) - { - bCanRenderAsIs = true; - } + // We don't need to care about g_ItemFrames at all since blocks will get 3D rendered and 2D props will use the terrain.png as the texture. + if (COND_PRE(TileRenderer::canRender(Tile::tiles[itemID]->getRenderShape()))) + { + bCanRenderAsIs = true; + } #else - if (COND_PRE(TileRenderer::canRender(Tile::tiles[itemID]->getRenderShape()) || g_ItemFrames[itemID] != 0)) - { - bCanRenderAsIs = true; - } + if (COND_PRE(TileRenderer::canRender(Tile::tiles[itemID]->getRenderShape()) || g_ItemFrames[itemID] != 0)) + { + bCanRenderAsIs = true; + } #endif - - - if (itemID < C_MAX_TILES && bCanRenderAsIs) - { + + if (itemID < C_MAX_TILES && bCanRenderAsIs) + { #ifndef ENH_3D_INVENTORY_TILES - textures->loadAndBindTexture(C_BLOCKS_NAME); + textures->loadAndBindTexture(C_BLOCKS_NAME); - float texU = float(g_ItemFrames[instance->m_itemID] % 10) * 48.0f; - float texV = float(g_ItemFrames[instance->m_itemID] / 10) * 48.0f; + float texU = float(g_ItemFrames[instance->m_itemID] % 10) * 48.0f; + float texV = float(g_ItemFrames[instance->m_itemID] / 10) * 48.0f; - Tesselator& t = Tesselator::instance; - // @NOTE: These do nothing, due to a previous t.voidBeginAndEndCalls call. - t.begin(); - t.vertexUV(float(x + 0), float(y + 16), 0.0f, texU / 512.0f, (texV + 48.0f) / 512.0f); - t.vertexUV(float(x + 16), float(y + 16), 0.0f, (texU + 48.0f) / 512.0f, (texV + 48.0f) / 512.0f); - t.vertexUV(float(x + 16), float(y + 0), 0.0f, (texU + 48.0f) / 512.0f, texV / 512.0f); - t.vertexUV(float(x + 0), float(y + 0), 0.0f, texU / 512.0f, texV / 512.0f); - t.draw(); + Tesselator& t = Tesselator::instance; + // @NOTE: These do nothing, due to a previous t.voidBeginAndEndCalls call. + t.begin(); + t.vertexUV(float(x + 0), float(y + 16), 0.0f, texU / 512.0f, (texV + 48.0f) / 512.0f); + t.vertexUV(float(x + 16), float(y + 16), 0.0f, (texU + 48.0f) / 512.0f, (texV + 48.0f) / 512.0f); + t.vertexUV(float(x + 16), float(y + 0), 0.0f, (texU + 48.0f) / 512.0f, texV / 512.0f); + t.vertexUV(float(x + 0), float(y + 0), 0.0f, texU / 512.0f, texV / 512.0f); + t.draw(); #else - textures->loadAndBindTexture(C_TERRAIN_NAME); + textures->loadAndBindTexture(C_TERRAIN_NAME); - //glDisable(GL_BLEND); - //glEnable(GL_DEPTH_TEST); + //glDisable(GL_BLEND); + //glEnable(GL_DEPTH_TEST); - glPushMatrix(); + glPushMatrix(); - // scale, rotate, and translate the tile onto the correct screen coordinate - glTranslatef((GLfloat)x + 8, (GLfloat)y + 8, -8); - glScalef(10, 10, 10); - glRotatef(210.0f, 1.0f, 0.0f, 0.0f); - glRotatef(45.0f, 0.0f, 1.0f, 0.0f); + // scale, rotate, and translate the tile onto the correct screen coordinate + glTranslatef((GLfloat)x + 8, (GLfloat)y + 8, -8); + glScalef(10, 10, 10); + glRotatef(210.0f, 1.0f, 0.0f, 0.0f); + glRotatef(45.0f, 0.0f, 1.0f, 0.0f); - #ifdef ENH_SHADE_HELD_TILES - # define PARM_HACK , 1 - #else - # define PARM_HACK - #endif - tileRenderer->renderTile(Tile::tiles[itemID], instance->m_auxValue PARM_HACK); - #undef PARM_HACK + #ifdef ENH_SHADE_HELD_TILES + # define PARM_HACK , 1 + #else + # define PARM_HACK + #endif + tileRenderer->renderTile(Tile::tiles[itemID], instance->m_auxValue PARM_HACK); + #undef PARM_HACK - glPopMatrix(); + glPopMatrix(); - //glDisable(GL_DEPTH_TEST); - //glEnable(GL_BLEND); + //glDisable(GL_DEPTH_TEST); + //glEnable(GL_BLEND); #endif - } - else if (instance->getIcon() >= 0) - { - // @BUG: The last bound texture will be the texture that ALL items will take. This is because begin and end calls - // have been void'ed by a t.voidBeginAndEndCalls call in Gui::render. - if (instance->m_itemID <= 255) - textures->loadAndBindTexture(C_TERRAIN_NAME); - else - textures->loadAndBindTexture(C_ITEMS_NAME); + } + else if (instance->getIcon() >= 0) + { + // @BUG: The last bound texture will be the texture that ALL items will take. This is because begin and end calls + // have been void'ed by a t.voidBeginAndEndCalls call in Gui::render. + if (instance->m_itemID <= 255) + textures->loadAndBindTexture(C_TERRAIN_NAME); + else + textures->loadAndBindTexture(C_ITEMS_NAME); - blit(x, y, 16 * (instance->getIcon() % 16), 16 * (instance->getIcon() / 16), 16, 16); - } + blit(x, y, 16 * (instance->getIcon() % 16), 16 * (instance->getIcon() / 16), 16, 16); } }