diff --git a/data/images/gui/gui_blocks.png b/data/images/gui/gui_blocks.png index fa4df26..9fa2d85 100755 Binary files a/data/images/gui/gui_blocks.png and b/data/images/gui/gui_blocks.png differ diff --git a/data/images/terrain.png b/data/images/terrain.png index 7991d0a..39b7119 100755 Binary files a/data/images/terrain.png and b/data/images/terrain.png differ diff --git a/src/client/gui/components/GuiElementContainer.cpp b/src/client/gui/components/GuiElementContainer.cpp index 9cfbb09..4fdaf22 100755 --- a/src/client/gui/components/GuiElementContainer.cpp +++ b/src/client/gui/components/GuiElementContainer.cpp @@ -35,6 +35,17 @@ void GuiElementContainer::removeChild( GuiElement* element ) { children.erase(it); } +bool GuiElementContainer::containsPointInChildren(int x, int y) const { + for (std::vector::const_iterator it = children.begin(); it != children.end(); ++it) { + GuiElement* child = *it; + if (child == NULL || !child->visible) continue; + if (child->pointInside(x, y)) return true; + const GuiElementContainer* container = dynamic_cast(child); + if (container != NULL && container->containsPointInChildren(x, y)) return true; + } + return false; +} + void GuiElementContainer::tick( Minecraft* minecraft ) { for(std::vector::iterator it = children.begin(); it != children.end(); ++it) { (*it)->tick(minecraft); diff --git a/src/client/gui/components/GuiElementContainer.h b/src/client/gui/components/GuiElementContainer.h index d20f9d3..06df761 100755 --- a/src/client/gui/components/GuiElementContainer.h +++ b/src/client/gui/components/GuiElementContainer.h @@ -5,16 +5,17 @@ class Tesselator; class Minecraft; -class GuiElementContainer : public GuiElement { -public: - GuiElementContainer(bool active=false, bool visible=true, int x = 0, int y = 0, int width=24, int height=24); - virtual ~GuiElementContainer(); - virtual void render(Minecraft* minecraft, int xm, int ym); - virtual void setupPositions(); - virtual void addChild(GuiElement* element); - virtual void removeChild(GuiElement* element); - - virtual void tick( Minecraft* minecraft ); +class GuiElementContainer : public GuiElement { +public: + GuiElementContainer(bool active=false, bool visible=true, int x = 0, int y = 0, int width=24, int height=24); + virtual ~GuiElementContainer(); + virtual void render(Minecraft* minecraft, int xm, int ym); + virtual void setupPositions(); + virtual void addChild(GuiElement* element); + virtual void removeChild(GuiElement* element); + bool containsPointInChildren(int x, int y) const; + + virtual void tick( Minecraft* minecraft ); virtual void mouseClicked( Minecraft* minecraft, int x, int y, int buttonNum ); virtual void mouseReleased( Minecraft* minecraft, int x, int y, int buttonNum ); diff --git a/src/client/gui/components/OptionsGroup.cpp b/src/client/gui/components/OptionsGroup.cpp index 54212d5..b9c7264 100755 --- a/src/client/gui/components/OptionsGroup.cpp +++ b/src/client/gui/components/OptionsGroup.cpp @@ -6,14 +6,36 @@ #include "../../../locale/I18n.h" #include "TextOption.h" #include "KeyOption.h" +#include +#include "../Gui.h" +#include "../Screen.h" +#include "../../../platform/input/Mouse.h" +#include "../../../util/Mth.h" -OptionsGroup::OptionsGroup( std::string labelID ) { +OptionsGroup::OptionsGroup( std::string labelID ) +: contentHeight(0), + scrollOffsetY(0.0f), + maxScrollOffsetY(0.0f), + trackingScrollGesture(false), + scrollingGesture(false), + touchDispatched(false), + dragStartX(0), + dragStartY(0), + lastDragY(0), + touchStartX(0), + touchStartY(0) { label = I18n::get(labelID); } void OptionsGroup::setupPositions() { + const int labelHeight = 18; + const int bottomPadding = 36; + const float requestedScroll = scrollOffsetY; + const int scrollOffset = (int)requestedScroll; + int curY = y + labelHeight - scrollOffset; + const int contentStartY = y + labelHeight; + // First we write the header and then we add the items - int curY = y + 18; for(std::vector::iterator it = children.begin(); it != children.end(); ++it) { (*it)->width = width - 5; @@ -22,16 +44,109 @@ void OptionsGroup::setupPositions() { (*it)->setupPositions(); curY += (*it)->height + 3; } - height = curY; + curY += bottomPadding; + contentHeight = std::max(0, curY - contentStartY + scrollOffset); + maxScrollOffsetY = std::max(0, contentHeight - (height - labelHeight)); + const float clampedScroll = Mth::clamp(requestedScroll, 0.0f, maxScrollOffsetY); + if (clampedScroll != requestedScroll) { + scrollOffsetY = clampedScroll; + setupPositions(); + } } void OptionsGroup::render( Minecraft* minecraft, int xm, int ym ) { float padX = 10.0f; float padY = 5.0f; + const int labelHeight = 18; minecraft->font->draw(label, (float)x + padX, (float)y + padY, 0xffffffff, false); + glEnable2(GL_SCISSOR_TEST); + glScissor( + Gui::GuiScale * x, + minecraft->height - Gui::GuiScale * (y + height), + Gui::GuiScale * width, + Gui::GuiScale * (height - labelHeight) + ); + super::render(minecraft, xm, ym); + glDisable2(GL_SCISSOR_TEST); +} + +void OptionsGroup::tick(Minecraft* minecraft) { + int xm = Mouse::getX(); + int ym = Mouse::getY(); + if (minecraft->screen != NULL) { + minecraft->screen->toGUICoordinate(xm, ym); + } + + bool leftDown = Mouse::isButtonDown(MouseAction::ACTION_LEFT); + + if (trackingScrollGesture && leftDown) { + int dy = ym - lastDragY; + int dx = xm - dragStartX; + if (!scrollingGesture) { + int totalDx = xm - dragStartX; + int totalDy = ym - dragStartY; + if (std::abs(totalDx) >= ScrollStartThreshold || std::abs(totalDy) >= ScrollStartThreshold) { + if (std::abs(totalDy) >= std::abs(totalDx)) { + scrollingGesture = true; + } else if (!touchDispatched) { + super::mouseClicked(minecraft, touchStartX, touchStartY, MouseAction::ACTION_LEFT); + touchDispatched = true; + } + } + } + if (scrollingGesture && dy != 0) { + scrollByPixels((float)dy); + } + lastDragY = ym; + } + super::tick(minecraft); +} + +void OptionsGroup::mouseClicked(Minecraft* minecraft, int x, int y, int buttonNum) { + trackingScrollGesture = false; + scrollingGesture = false; + touchDispatched = false; + + if (buttonNum == MouseAction::ACTION_LEFT && pointInside(x, y)) { + trackingScrollGesture = true; + dragStartX = x; + dragStartY = y; + lastDragY = y; + touchStartX = x; + touchStartY = y; + return; + } + + super::mouseClicked(minecraft, x, y, buttonNum); +} + +void OptionsGroup::mouseReleased(Minecraft* minecraft, int x, int y, int buttonNum) { + bool wasScrolling = scrollingGesture; + bool wasTracking = trackingScrollGesture; + trackingScrollGesture = false; + scrollingGesture = false; + if (buttonNum == MouseAction::ACTION_LEFT && wasTracking && !touchDispatched && pointInside(touchStartX, touchStartY)) { + super::mouseClicked(minecraft, touchStartX, touchStartY, buttonNum); + touchDispatched = true; + } + + if (!wasScrolling) { + super::mouseReleased(minecraft, x, y, buttonNum); + } +} + +void OptionsGroup::scrollByPixels(float deltaY) { + if (deltaY == 0.0f || maxScrollOffsetY <= 0.0f) return; + + scrollOffsetY = Mth::clamp(scrollOffsetY - deltaY, 0.0f, maxScrollOffsetY); + setupPositions(); +} + +bool OptionsGroup::isScrollingGestureActive() const { + return trackingScrollGesture || scrollingGesture; } OptionsGroup& OptionsGroup::addOptionItem(OptionId optId, Minecraft* minecraft ) { @@ -112,4 +227,4 @@ void OptionsGroup::createKey(OptionId optId, Minecraft* minecraft) { OptionsItem* item = new OptionsItem(optId, itemLabel, element); addChild(item); setupPositions(); -} \ No newline at end of file +} diff --git a/src/client/gui/components/OptionsGroup.h b/src/client/gui/components/OptionsGroup.h index 24d28bd..ac90e3d 100755 --- a/src/client/gui/components/OptionsGroup.h +++ b/src/client/gui/components/OptionsGroup.h @@ -11,22 +11,39 @@ class Font; class Minecraft; -class OptionsGroup: public GuiElementContainer { - typedef GuiElementContainer super; -public: - OptionsGroup(std::string labelID); - virtual void setupPositions(); - virtual void render(Minecraft* minecraft, int xm, int ym); - OptionsGroup& addOptionItem(OptionId optId, Minecraft* minecraft); -protected: +class OptionsGroup: public GuiElementContainer { + typedef GuiElementContainer super; +public: + OptionsGroup(std::string labelID); + virtual void setupPositions(); + virtual void render(Minecraft* minecraft, int xm, int ym); + virtual void tick(Minecraft* minecraft); + virtual void mouseClicked(Minecraft* minecraft, int x, int y, int buttonNum); + virtual void mouseReleased(Minecraft* minecraft, int x, int y, int buttonNum); + OptionsGroup& addOptionItem(OptionId optId, Minecraft* minecraft); + void scrollByPixels(float deltaY); + bool isScrollingGestureActive() const; +protected: void createToggle(OptionId optId, Minecraft* minecraft); void createProgressSlider(OptionId optId, Minecraft* minecraft); void createStepSlider(OptionId optId, Minecraft* minecraft); void createTextbox(OptionId optId, Minecraft* minecraft); - void createKey(OptionId optId, Minecraft* minecraft); - - std::string label; -}; + void createKey(OptionId optId, Minecraft* minecraft); + + std::string label; + int contentHeight; + float scrollOffsetY; + float maxScrollOffsetY; + bool trackingScrollGesture; + bool scrollingGesture; + bool touchDispatched; + int dragStartX; + int dragStartY; + int lastDragY; + int touchStartX; + int touchStartY; + static const int ScrollStartThreshold = 5; +}; #endif /*NET_MINECRAFT_CLIENT_GUI_COMPONENTS__OptionsGroup_H__*/ diff --git a/src/client/gui/screens/OptionsScreen.cpp b/src/client/gui/screens/OptionsScreen.cpp index 77d5a5f..68a2875 100755 --- a/src/client/gui/screens/OptionsScreen.cpp +++ b/src/client/gui/screens/OptionsScreen.cpp @@ -121,6 +121,7 @@ void OptionsScreen::setupPositions() { (*it)->x = categoryButtons[0]->width; (*it)->y = bHeader->height; (*it)->width = width - categoryButtons[0]->width; + (*it)->height = height - bHeader->height; (*it)->setupPositions(); } @@ -258,6 +259,12 @@ void OptionsScreen::mouseReleased(int x, int y, int buttonNum) { super::mouseReleased(x, y, buttonNum); } +void OptionsScreen::mouseWheel(int dx, int dy, int xm, int ym) { + if (currentOptionsGroup != NULL && currentOptionsGroup->pointInside(xm, ym) && dy != 0) { + currentOptionsGroup->scrollByPixels((float)dy * 18.0f); + } +} + void OptionsScreen::keyPressed(int eventKey) { if (currentOptionsGroup != NULL) currentOptionsGroup->keyPressed(minecraft, eventKey); diff --git a/src/client/gui/screens/OptionsScreen.h b/src/client/gui/screens/OptionsScreen.h index b02c7b8..dd1e73e 100755 --- a/src/client/gui/screens/OptionsScreen.h +++ b/src/client/gui/screens/OptionsScreen.h @@ -27,6 +27,7 @@ public: virtual void mouseClicked(int x, int y, int buttonNum); virtual void mouseReleased(int x, int y, int buttonNum); + virtual void mouseWheel(int dx, int dy, int xm, int ym); virtual void keyPressed(int eventKey); virtual void charPressed(char inputChar); diff --git a/src/client/renderer/entity/ItemRenderer.cpp b/src/client/renderer/entity/ItemRenderer.cpp index d103fcc..c4e9de1 100755 --- a/src/client/renderer/entity/ItemRenderer.cpp +++ b/src/client/renderer/entity/ItemRenderer.cpp @@ -130,12 +130,13 @@ static const signed short _18[] = {79, 80, 81, -1, 79, 80, 81, -1, 79, 80, 81, - static const signed short _24[] = {11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; static const signed short _35[] = {52, 59, 58, 57, 56, 55, 54, 53, 67, 66, 65, 64, 63, 62, 61, 60}; static const signed short _44[] = {28, 32, 30, 29, 31, 33, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static const signed short _31[] = {37, 82, -1, 38, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; static const signed short _98[] = {1, 2, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; static const signed short _155[] = {34, 36, 35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; static const signed short _263[] = {230, 151, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; static const signed short _351[] = {-1, 152, 154, -1, 193, 215, 216, -1, -1, 217, 218, 219, 220, 221, 222, 144}; -static const signed short _mapper[] = {-1, 7, 9, 8, 0, 5, -2, -1, -1, -1, -1, -1, 14, 15, 39, 38, 37, -2, -2, -1, 49, 41, 46, -1, -2, -1, -1, -1, -1, -1, 235, -1, -1, -1, -1, -2, -1, 134, 135, 136, 137, 43, 44, -1, -2, 6, 76, 71, 4, 47, 129, -1, -1, 22, 74, -1, 40, 45, 72, -1, -1, 75, -1, -1, -1, 128, -1, 21, -1, -1, -1, -1, -1, 42, -1, -1, -1, -1, -1, -1, 48, 77, 10, 236, -1, 69, -1, 20, -1, 50, -1, -1, -1, -1, -1, -1, 68, -1, -2, -1, -1, -1, 130, 78, -1, -1, -1, 70, 23, 25, -1, -1, 19, -1, 26, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, 27, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 73, -1, 51, -1, -1, -1, -1, -1, 82, -1, -1, 174, 173, 175, 231, 234, 147, 190, -2, 153, 150, 149, 146, 185, 166, 164, 167, 186, 170, 169, 171, 187, 177, 176, 178, 165, 195, 194, 188, 181, 180, 182, 189, 191, 228, 168, 172, 145, 179, 183, 142, 233, 232, 198, 200, 201, 202, -1, -1, -1, -1, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 192, 156, 157, 133, -1, 148, 131, -1, -1, -1, -1, -1, -1, -1, 226, -1, 199, -1, 159, 158, 138, 224, 225, -1, -1, -1, -1, -1, -1, -1, 227, -1, -1, -2, 223, 229, -1, 132, -1, -1, -1, 184, 196, -1, 143, 160, 161, 162, 163, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 155, 197}; +static const signed short _mapper[] = {-1, 7, 9, 8, 0, 5, -2, -1, -1, -1, -1, -1, 14, 15, 39, 38, 37, -2, -2, -1, 49, 41, 46, -1, -2, -1, -1, -1, -1, -1, 235, -2, -1, -1, -1, -2, -1, 134, 135, 136, 137, 43, 44, -1, -2, 6, 76, 71, 4, 47, 129, -1, -1, 22, 74, -1, 40, 45, 72, -1, -1, 75, -1, -1, -1, 128, -1, 21, -1, -1, -1, -1, -1, 42, -1, -1, -1, -1, -1, -1, 48, 77, 10, 236, -1, 69, -1, 20, -1, 50, -1, -1, -1, -1, -1, -1, 68, -1, -2, -1, -1, -1, 130, 78, -1, -1, -1, 70, 23, 25, -1, -1, 19, -1, 26, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, 27, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 73, -1, 51, -1, -1, -1, -1, -1, 82, -1, -1, 174, 173, 175, 231, 234, 147, 190, -2, 153, 150, 149, 146, 185, 166, 164, 167, 186, 170, 169, 171, 187, 177, 176, 178, 165, 195, 194, 188, 181, 180, 182, 189, 191, 228, 168, 172, 145, 179, 183, 142, 233, 232, 198, 200, 201, 202, -1, -1, -1, -1, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 192, 156, 157, 133, -1, 148, 131, -1, -1, -1, -1, -1, -1, -1, 226, -1, 199, -1, 159, 158, 138, 224, 225, -1, -1, -1, -1, -1, -1, -1, 227, -1, -1, -2, 223, 229, -1, 132, -1, -1, -1, 184, 196, -1, 143, 160, 161, 162, 163, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 155, 197}; #define IRMAPCASE(x) case x: return _##x [item->getAuxValue() & 15] @@ -153,6 +154,7 @@ int ItemRenderer::getAtlasPos(const ItemInstance* item) { IRMAPCASE(17); IRMAPCASE(18); IRMAPCASE(24); + IRMAPCASE(31); IRMAPCASE(35); IRMAPCASE(44); IRMAPCASE(98); diff --git a/src/world/entity/player/Inventory.cpp b/src/world/entity/player/Inventory.cpp index 480627b..19ff6ad 100755 --- a/src/world/entity/player/Inventory.cpp +++ b/src/world/entity/player/Inventory.cpp @@ -1,11 +1,12 @@ #include "Inventory.h" #include "../../level/material/Material.h" -#include "../../level/tile/QuartzBlockTile.h" -#include "../../level/tile/TreeTile.h" -#include "../../level/tile/StoneSlabTile.h" -#include "../../item/DyePowderItem.h" -#include "../../item/crafting/Recipe.h" -#include "../../item/CoalItem.h" +#include "../../level/tile/QuartzBlockTile.h" +#include "../../level/tile/TreeTile.h" +#include "../../level/tile/StoneSlabTile.h" +#include "../../level/tile/TallGrass.h" +#include "../../item/DyePowderItem.h" +#include "../../item/crafting/Recipe.h" +#include "../../item/CoalItem.h" #include "../../level/tile/SandStoneTile.h" Inventory::Inventory( Player* player, bool creativeMode ) @@ -80,10 +81,10 @@ void Inventory::setupDefault() { addItem(new ItemInstance(Tile::chest)); addItem(new ItemInstance(Tile::furnace)); - addItem(new ItemInstance(((Tile*)Tile::flower))); - addItem(new ItemInstance(Tile::cactus)); - - // + addItem(new ItemInstance(((Tile*)Tile::flower))); + addItem(new ItemInstance(Tile::cactus)); + + // // Those below are inactive due to demo // addItem(new ItemInstance(Item::sword_stone)); @@ -227,9 +228,10 @@ void Inventory::setupDefault() { addItem(new ItemInstance(Tile::furnace)); addItem(new ItemInstance(Tile::tnt)); - addItem(new ItemInstance(((Tile*)Tile::flower))); - addItem(new ItemInstance(((Tile*)Tile::rose))); - addItem(new ItemInstance(((Tile*)Tile::mushroom1))); + addItem(new ItemInstance(((Tile*)Tile::flower))); + addItem(new ItemInstance(((Tile*)Tile::rose))); + addItem(new ItemInstance(Tile::tallgrass, 1, TallGrass::TALL_GRASS)); + addItem(new ItemInstance(((Tile*)Tile::mushroom1))); addItem(new ItemInstance(((Tile*)Tile::mushroom2))); addItem(new ItemInstance(Tile::cactus)); addItem(new ItemInstance(Tile::melon)); diff --git a/src/world/level/tile/Tile.cpp b/src/world/level/tile/Tile.cpp index a5acf7a..ea6f6ea 100755 --- a/src/world/level/tile/Tile.cpp +++ b/src/world/level/tile/Tile.cpp @@ -281,13 +281,14 @@ void Tile::initTiles() { Item::items[stoneBrickSmooth->id] = (new AuxDataTileItem(stoneBrickSmooth->id - 256, stoneBrickSmooth))->setCategory(ItemCategory::Structures)->setDescriptionId("stonebricksmooth"); Item::items[stoneSlabHalf->id] = (new StoneSlabTileItem(stoneSlabHalf->id - 256))->setCategory(ItemCategory::Structures)->setDescriptionId("stoneSlab"); Item::items[sapling->id] = (new SaplingTileItem(sapling->id - 256))->setCategory(ItemCategory::Structures)->setDescriptionId("sapling"); - Item::items[leaves->id] = (new LeafTileItem(leaves->id - 256))->setCategory(ItemCategory::Decorations)->setDescriptionId("leaves"); - Item::items[sandStone->id] = (new AuxDataTileItem(sandStone->id - 256, sandStone))->setCategory(ItemCategory::Structures)->setDescriptionId("sandStone"); - - Item::items[quartzBlock->id] = (new AuxDataTileItem(quartzBlock->id - 256, quartzBlock))->setCategory(ItemCategory::Structures)->setDescriptionId("quartzBlock"); - - for (int i = 0; i < 256; i++) { - if (Tile::tiles[i] != NULL) { + Item::items[leaves->id] = (new LeafTileItem(leaves->id - 256))->setCategory(ItemCategory::Decorations)->setDescriptionId("leaves"); + Item::items[sandStone->id] = (new AuxDataTileItem(sandStone->id - 256, sandStone))->setCategory(ItemCategory::Structures)->setDescriptionId("sandStone"); + + Item::items[quartzBlock->id] = (new AuxDataTileItem(quartzBlock->id - 256, quartzBlock))->setCategory(ItemCategory::Structures)->setDescriptionId("quartzBlock"); + Item::items[tallgrass->id] = (new AuxDataTileItem(tallgrass->id - 256, tallgrass))->setCategory(ItemCategory::Decorations); + + for (int i = 0; i < 256; i++) { + if (Tile::tiles[i] != NULL) { if (Item::items[i] == NULL) { Item::items[i] = new TileItem(i - 256); Item::items[i]->category = Tile::tiles[i]->category;