mirror of
https://github.com/celisej567/mcpe.git
synced 2026-09-11 20:11:18 +03:00
* Improve the inventory. Prepare for survival mode inventory.
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<ItemInstance> m_items;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -20,6 +20,7 @@ class Player;
|
||||
class ItemInstance
|
||||
{
|
||||
public:
|
||||
ItemInstance();
|
||||
ItemInstance(Item*);
|
||||
ItemInstance(Item*, int amount);
|
||||
ItemInstance(Item*, int amount, int auxValue);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user