From 19e45003ba0471074e7a584832cdf5c31f4cf06f Mon Sep 17 00:00:00 2001 From: KKNecmi Date: Wed, 27 May 2026 16:10:56 +0300 Subject: [PATCH] flower pots now tileentity --- Minecraft.Client/ClientConnection.cpp | 11 + .../SPU_Tasks/ChunkUpdate/FlowerPotTile_SPU.h | 26 +- Minecraft.Client/TileRenderer.cpp | 236 +++++++++--------- Minecraft.World/Class.h | 1 + Minecraft.World/FlowerPotTile.cpp | 196 ++++++--------- Minecraft.World/FlowerPotTile.h | 21 +- Minecraft.World/FlowerPotTileEntity.cpp | 70 ++++++ Minecraft.World/FlowerPotTileEntity.h | 25 ++ Minecraft.World/ScatteredFeaturePieces.cpp | 3 +- Minecraft.World/StructurePiece.cpp | 16 ++ Minecraft.World/StructurePiece.h | 1 + Minecraft.World/TileEntity.cpp | 1 + Minecraft.World/TileEntityDataPacket.h | 1 + Minecraft.World/cmake/sources/Common.cmake | 2 + .../net.minecraft.world.level.tile.entity.h | 1 + 15 files changed, 341 insertions(+), 270 deletions(-) create mode 100644 Minecraft.World/FlowerPotTileEntity.cpp create mode 100644 Minecraft.World/FlowerPotTileEntity.h diff --git a/Minecraft.Client/ClientConnection.cpp b/Minecraft.Client/ClientConnection.cpp index 361c2974..93acf8bf 100644 --- a/Minecraft.Client/ClientConnection.cpp +++ b/Minecraft.Client/ClientConnection.cpp @@ -3459,7 +3459,18 @@ void ClientConnection::handleTileEntityData(shared_ptr pac { dynamic_pointer_cast(te)->load(packet->tag); } + else if (packet->type == TileEntityDataPacket::TYPE_FLOWER_POT && dynamic_pointer_cast(te) != nullptr) + { + dynamic_pointer_cast(te)->load(packet->tag); + } } + else if (packet->type == TileEntityDataPacket::TYPE_FLOWER_POT) + { + auto newTe = std::make_shared(); + newTe->load(packet->tag); + newTe->setLevel(minecraft->level); + minecraft->level->setTileEntity(packet->x, packet->y, packet->z, newTe); + } } } diff --git a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/FlowerPotTile_SPU.h b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/FlowerPotTile_SPU.h index 1a75019d..fbf9463e 100644 --- a/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/FlowerPotTile_SPU.h +++ b/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/FlowerPotTile_SPU.h @@ -1,23 +1,12 @@ #pragma once #include "Tile_SPU.h" +#include "FlowerPotTileEntity.h" -class FlowerPotTile_SPU : public Tile_SPU +class FlowerPotTile_SPU : public EntityTile_SPU { public: - static const int TYPE_FLOWER_RED = 1; - static const int TYPE_FLOWER_YELLOW = 2; - static const int TYPE_SAPLING_DEFAULT = 3; - static const int TYPE_SAPLING_EVERGREEN = 4; - static const int TYPE_SAPLING_BIRCH = 5; - static const int TYPE_SAPLING_JUNGLE = 6; - static const int TYPE_MUSHROOM_RED = 7; - static const int TYPE_MUSHROOM_BROWN = 8; - static const int TYPE_CACTUS = 9; - static const int TYPE_DEAD_BUSH = 10; - static const int TYPE_FERN = 11; - - FlowerPotTile_SPU(int id) : Tile_SPU(id) {} + FlowerPotTile_SPU(int id) : EntityTile_SPU(id) {} void updateDefaultShape() { @@ -25,8 +14,15 @@ public: float half = size / 2; setShape(0.5f - half, 0, 0.5f - half, 0.5f + half, size, 0.5f + half); } - bool isSolidRender(bool isServerLevel = false) { return false; } int getRenderShape() { return SHAPE_FLOWER_POT; } bool isCubeShaped() { return false; } + virtual void updateShape(ChunkRebuildData *level, int x, int y, int z, int forceData = -1, TileEntity* forceEntity = nullptr) override + { + updateDefaultShape(); + if (forceEntity && forceEntity->GetType() == eTYPE_FLOWERPOTTILEENTITY) + { + // later + } + } }; \ No newline at end of file diff --git a/Minecraft.Client/TileRenderer.cpp b/Minecraft.Client/TileRenderer.cpp index 0dc19eb9..2ef95256 100644 --- a/Minecraft.Client/TileRenderer.cpp +++ b/Minecraft.Client/TileRenderer.cpp @@ -12,6 +12,7 @@ #include "Tesselator.h" #include "EntityTileRenderer.h" #include "Options.h" +#include "../Minecraft.World/FlowerPotTileEntity.h" bool TileRenderer::fancy = true; @@ -862,136 +863,133 @@ bool TileRenderer::tesselateCauldronInWorld(CauldronTile *tt, int x, int y, int bool TileRenderer::tesselateFlowerPotInWorld(FlowerPotTile *tt, int x, int y, int z) { - // bounding box first - tesselateBlockInWorld(tt, x, y, z); + tesselateBlockInWorld(tt, x, y, z); - Tesselator *t = Tesselator::getInstance(); + Tesselator *t = Tesselator::getInstance(); - float br; - if (SharedConstants::TEXTURE_LIGHTING) - { - t->tex2(tt->getLightColor(level, x, y, z)); - br = 1; - } - else - { - br = tt->getBrightness(level, x, y, z); - } - int col = tt->getColor(level, x, y, z); - Icon *tex = getTexture(tt, 0); - float r = ((col >> 16) & 0xff) / 255.0f; - float g = ((col >> 8) & 0xff) / 255.0f; - float b = ((col) & 0xff) / 255.0f; + float br; + if (SharedConstants::TEXTURE_LIGHTING) + { + t->tex2(tt->getLightColor(level, x, y, z)); + br = 1; + } + else + { + br = tt->getBrightness(level, x, y, z); + } + int col = tt->getColor(level, x, y, z); + Icon *tex = getTexture(tt, 0); + float r = ((col >> 16) & 0xff) / 255.0f; + float g = ((col >> 8) & 0xff) / 255.0f; + float b = ((col) & 0xff) / 255.0f; - if (GameRenderer::anaglyph3d) - { - float cr = (r * 30 + g * 59 + b * 11) / 100; - float cg = (r * 30 + g * 70) / (100); - float cb = (r * 30 + b * 70) / (100); + if (GameRenderer::anaglyph3d) + { + float cr = (r * 30 + g * 59 + b * 11) / 100; + float cg = (r * 30 + g * 70) / (100); + float cb = (r * 30 + b * 70) / (100); + r = cr; + g = cg; + b = cb; + } + t->color(br * r, br * g, br * b); - r = cr; - g = cg; - b = cb; - } - t->color(br * r, br * g, br * b); + float halfWidth = (6.0f / 16.0f) / 2 - 0.001f; + renderEast(tt, x - 0.5f + halfWidth, y, z, tex); + renderWest(tt, x + 0.5f - halfWidth, y, z, tex); + renderSouth(tt, x, y, z - 0.5f + halfWidth, tex); + renderNorth(tt, x, y, z + 0.5f - halfWidth, tex); + renderFaceUp(tt, x, y - 0.5f + halfWidth + 3.0f / 16.0f, z, getTexture(Tile::dirt)); - // render inside + bool hasPlant = false; + int plantItemId = 0; + int plantAux = 0; - float halfWidth = (6.0f / 16.0f) / 2 - 0.001f; - renderEast(tt, x - 0.5f + halfWidth, y, z, tex); - renderWest(tt, x + 0.5f - halfWidth, y, z, tex); - renderSouth(tt, x, y, z - 0.5f + halfWidth, tex); - renderNorth(tt, x, y, z + 0.5f - halfWidth, tex); + shared_ptr te = level->getTileEntity(x, y, z); + if (te && te->GetType() == eTYPE_FLOWERPOTTILEENTITY) + { + FlowerPotTileEntity *potTe = (FlowerPotTileEntity*)te.get(); + if (potTe->hasFlower()) + { + hasPlant = true; + plantItemId = potTe->getItemId(); + plantAux = potTe->getAux(); + } + } - renderFaceUp(tt, x, y - 0.5f + halfWidth + 3.0f / 16.0f, z, getTexture(Tile::dirt)); + if (!hasPlant) + { + int data = level->getData(x, y, z); + if (data != 0) + { + hasPlant = true; + switch (data) + { + case 1: plantItemId = Tile::rose_Id; plantAux = 0; break; + case 2: plantItemId = Tile::flower_Id; plantAux = 0; break; + case 3: plantItemId = Tile::sapling_Id; plantAux = Sapling::TYPE_DEFAULT; break; + case 4: plantItemId = Tile::sapling_Id; plantAux = Sapling::TYPE_EVERGREEN; break; + case 5: plantItemId = Tile::sapling_Id; plantAux = Sapling::TYPE_BIRCH; break; + case 6: plantItemId = Tile::sapling_Id; plantAux = Sapling::TYPE_JUNGLE; break; + case 7: plantItemId = Tile::mushroom_red_Id; plantAux = 0; break; + case 8: plantItemId = Tile::mushroom_brown_Id; plantAux = 0; break; + case 9: plantItemId = Tile::cactus_Id; plantAux = 0; break; + case 10: plantItemId = Tile::deadBush_Id; plantAux = 0; break; + case 11: plantItemId = Tile::tallgrass_Id; plantAux = TallGrass::FERN; break; + } + } + } - int type = level->getData(x, y, z); + if (hasPlant) + { + float xOff = 0; + float yOff = 4; + float zOff = 0; + t->addOffset(xOff / 16.0f, yOff / 16.0f, zOff / 16.0f); - if (type != 0) - { - float xOff = 0; - float yOff = 4; - float zOff = 0; - Tile *plant = nullptr; + if (plantItemId == Tile::rose_Id || plantItemId == Tile::flower_Id) + { + tesselateCrossTexture(Tile::tiles[plantItemId], plantAux, x, y, z, 0.75f); + } + else if (plantItemId == Tile::sapling_Id) + { + tesselateCrossTexture(Tile::sapling, plantAux, x, y, z, 0.75f); + } + else if (plantItemId == Tile::mushroom_red_Id || plantItemId == Tile::mushroom_brown_Id) + { + tesselateCrossTexture(Tile::tiles[plantItemId], 0, x, y, z, 0.75f); + } + else if (plantItemId == Tile::tallgrass_Id && plantAux == TallGrass::FERN) + { + col = Tile::tallgrass->getColor(level, x, y, z); + r = ((col >> 16) & 0xff) / 255.0f; + g = ((col >> 8) & 0xff) / 255.0f; + b = ((col) & 0xff) / 255.0f; + t->color(br * r, br * g, br * b); + tesselateCrossTexture(Tile::tallgrass, TallGrass::FERN, x, y, z, 0.75f); + } + else if (plantItemId == Tile::deadBush_Id) + { + tesselateCrossTexture(Tile::deadBush, 0, x, y, z, 0.75f); + } + else if (plantItemId == Tile::cactus_Id) + { + noCulling = true; + float halfSize = 0.25f / 2; + setShape(0.5f - halfSize, 0.0f, 0.5f - halfSize, 0.5f + halfSize, 0.25f, 0.5f + halfSize); + tesselateBlockInWorld(Tile::cactus, x, y, z); + setShape(0.5f - halfSize, 0.25f, 0.5f - halfSize, 0.5f + halfSize, 0.5f, 0.5f + halfSize); + tesselateBlockInWorld(Tile::cactus, x, y, z); + setShape(0.5f - halfSize, 0.5f, 0.5f - halfSize, 0.5f + halfSize, 0.75f, 0.5f + halfSize); + tesselateBlockInWorld(Tile::cactus, x, y, z); + noCulling = false; + setShape(0, 0, 0, 1, 1, 1); + } - switch (type) - { - case FlowerPotTile::TYPE_FLOWER_RED: - plant = Tile::rose; - break; - case FlowerPotTile::TYPE_FLOWER_YELLOW: - plant = Tile::flower; - break; - case FlowerPotTile::TYPE_MUSHROOM_BROWN: - plant = Tile::mushroom_brown; - break; - case FlowerPotTile::TYPE_MUSHROOM_RED: - plant = Tile::mushroom_red; - break; - } + t->addOffset(-xOff / 16.0f, -yOff / 16.0f, -zOff / 16.0f); + } - t->addOffset(xOff / 16.0f, yOff / 16.0f, zOff / 16.0f); - - if (plant != nullptr) - { - tesselateInWorld(plant, x, y, z); - } - else - { - if (type == FlowerPotTile::TYPE_CACTUS) - { - - // Force drawing of all faces else the cactus misses faces - // when a block is adjacent - noCulling = true; - - float halfSize = 0.25f / 2; - setShape(0.5f - halfSize, 0.0f, 0.5f - halfSize, 0.5f + halfSize, 0.25f, 0.5f + halfSize); - tesselateBlockInWorld(Tile::cactus, x, y, z); - setShape(0.5f - halfSize, 0.25f, 0.5f - halfSize, 0.5f + halfSize, 0.5f, 0.5f + halfSize); - tesselateBlockInWorld(Tile::cactus, x, y, z); - setShape(0.5f - halfSize, 0.5f, 0.5f - halfSize, 0.5f + halfSize, 0.75f, 0.5f + halfSize); - tesselateBlockInWorld(Tile::cactus, x, y, z); - - noCulling = false; - - setShape(0, 0, 0, 1, 1, 1); - } - else if (type == FlowerPotTile::TYPE_SAPLING_DEFAULT) - { - tesselateCrossTexture(Tile::sapling, Sapling::TYPE_DEFAULT, x, y, z, 0.75f); - } - else if (type == FlowerPotTile::TYPE_SAPLING_BIRCH) - { - tesselateCrossTexture(Tile::sapling, Sapling::TYPE_BIRCH, x, y, z, 0.75f); - } - else if (type == FlowerPotTile::TYPE_SAPLING_EVERGREEN) - { - tesselateCrossTexture(Tile::sapling, Sapling::TYPE_EVERGREEN, x, y, z, 0.75f); - } - else if (type == FlowerPotTile::TYPE_SAPLING_JUNGLE) - { - tesselateCrossTexture(Tile::sapling, Sapling::TYPE_JUNGLE, x, y, z, 0.75f); - } - else if (type == FlowerPotTile::TYPE_FERN) - { - col = Tile::tallgrass->getColor(level, x, y, z); - r = ((col >> 16) & 0xff) / 255.0f; - g = ((col >> 8) & 0xff) / 255.0f; - b = ((col) & 0xff) / 255.0f; - t->color(br * r, br * g, br * b); - tesselateCrossTexture(Tile::tallgrass, TallGrass::FERN, x, y, z, 0.75f); - } - else if (type == FlowerPotTile::TYPE_DEAD_BUSH) - { - tesselateCrossTexture(Tile::deadBush, TallGrass::FERN, x, y, z, 0.75f); - } - } - - t->addOffset(-xOff / 16.0f, -yOff / 16.0f, -zOff / 16.0f); - } - - return true; + return true; } bool TileRenderer::tesselateAnvilInWorld(AnvilTile *tt, int x, int y, int z) diff --git a/Minecraft.World/Class.h b/Minecraft.World/Class.h index 09107147..ae1b2178 100644 --- a/Minecraft.World/Class.h +++ b/Minecraft.World/Class.h @@ -318,6 +318,7 @@ enum eINSTANCEOF eTYPE_COMPARATORTILEENTITY = eTYPE_TILEENTITY | 0x0F, eTYPE_DAYLIGHTDETECTORTILEENTITY = eTYPE_TILEENTITY | 0x10, eTYPE_HOPPERTILEENTITY = eTYPE_TILEENTITY | 0x11, + eTYPE_FLOWERPOTTILEENTITY = eTYPE_TILEENTITY | 0x12, eTYPE_DISPENSERTILEENTITY = eTYPE_TILEENTITY | BIT_DISPENSERTILEENTITY, eTYPE_DROPPERTILEENTITY = eTYPE_DISPENSERTILEENTITY | 0x1, diff --git a/Minecraft.World/FlowerPotTile.cpp b/Minecraft.World/FlowerPotTile.cpp index 80fdf2e4..482ceaae 100644 --- a/Minecraft.World/FlowerPotTile.cpp +++ b/Minecraft.World/FlowerPotTile.cpp @@ -4,11 +4,12 @@ #include "net.minecraft.world.level.h" #include "net.minecraft.world.level.tile.h" #include "FlowerPotTile.h" +#include "FlowerPotTileEntity.h" -FlowerPotTile::FlowerPotTile(int id) : Tile(id, Material::decoration, isSolidRender() ) +FlowerPotTile::FlowerPotTile(int id) : BaseEntityTile(id, Material::decoration, isSolidRender()) { - updateDefaultShape(); - sendTileData(); + updateDefaultShape(); + sendTileData(); } void FlowerPotTile::updateDefaultShape() @@ -33,57 +34,74 @@ bool FlowerPotTile::isCubeShaped() return false; } -bool FlowerPotTile::use(Level *level, int x, int y, int z, shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly) +bool FlowerPotTile::isValidPlant(int itemId, int aux) { - shared_ptr item = player->inventory->getSelected(); - if (item == nullptr) return false; - if (level->getData(x, y, z) != 0) return false; - int type = getTypeFromItem(item); - - if (type > 0) - { - level->setData(x, y, z, type, Tile::UPDATE_CLIENTS); - - if (!player->abilities.instabuild) - { - if (--item->count <= 0) - { - player->inventory->setItem(player->inventory->selected, nullptr); - } - } - - return true; - } - - return false; + if (itemId == Tile::rose_Id || itemId == Tile::flower_Id) + return true; + if (itemId == Tile::sapling_Id && aux >= 0 && aux <= 6) return true; + if (itemId == Tile::mushroom_brown_Id || itemId == Tile::mushroom_red_Id) return true; + if (itemId == Tile::cactus_Id || itemId == Tile::deadBush_Id || + (itemId == Tile::tallgrass_Id && aux == TallGrass::FERN)) + return true; + return false; } -int FlowerPotTile::cloneTileId(Level *level, int x, int y, int z) +bool FlowerPotTile::use(Level* level, int x, int y, int z, shared_ptr player, + int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly) { - shared_ptr item = getItemFromType(level->getData(x, y, z)); + auto held = player->inventory->getSelected(); + if (!held) return false; + if (level->getData(x, y, z) != 0) return false; + int itemId = held->getItem()->id; + int aux = held->getAuxValue(); + if (!isValidPlant(itemId, aux)) return false; - if (item == nullptr) - { - return Item::flowerPot_Id; - } - else - { - return item->id; - } + auto te = level->getTileEntity(x, y, z); + if (!te) + { + return false; + } + auto potTe = std::dynamic_pointer_cast(te); + if (!potTe) return false; + potTe->setFlower(itemId, aux); + level->setData(x, y, z, 1, Tile::UPDATE_CLIENTS); + + if (!player->abilities.instabuild) + { + if (--held->count <= 0) + player->inventory->setItem(player->inventory->selected, nullptr); + } + return true; } -int FlowerPotTile::cloneTileData(Level *level, int x, int y, int z) +int FlowerPotTile::cloneTileId(Level* level, int x, int y, int z) { - shared_ptr item = getItemFromType(level->getData(x, y, z)); + auto te = level->getTileEntity(x, y, z); + if (te) + { + auto potTe = std::dynamic_pointer_cast(te); + if (potTe && potTe->hasFlower()) + { + auto item = potTe->getFlowerItem(); + if (item) return item->id; + } + } + return Item::flowerPot_Id; +} - if (item == nullptr) - { - return Item::flowerPot_Id; - } - else - { - return item->getAuxValue(); - } +int FlowerPotTile::cloneTileData(Level* level, int x, int y, int z) +{ + auto te = level->getTileEntity(x, y, z); + if (te) + { + auto potTe = std::dynamic_pointer_cast(te); + if (potTe && potTe->hasFlower()) + { + auto item = potTe->getFlowerItem(); + if (item) return item->getAuxValue(); + } + } + return 0; } bool FlowerPotTile::useOwnCloneData() @@ -106,15 +124,19 @@ void FlowerPotTile::neighborChanged(Level *level, int x, int y, int z, int type) } } -void FlowerPotTile::spawnResources(Level *level, int x, int y, int z, int data, float odds, int playerBonusLevel) +void FlowerPotTile::spawnResources(Level* level, int x, int y, int z, int data, float odds, int playerBonusLevel) { - Tile::spawnResources(level, x, y, z, data, odds, playerBonusLevel); - - if (data > 0) - { - shared_ptr item = getItemFromType(data); - if (item != nullptr) popResource(level, x, y, z, item); - } + Tile::spawnResources(level, x, y, z, data, odds, playerBonusLevel); + auto te = level->getTileEntity(x, y, z); + if (te) + { + auto potTe = std::dynamic_pointer_cast(te); + if (potTe && potTe->hasFlower()) + { + auto flowerItem = potTe->getFlowerItem(); + if (flowerItem) popResource(level, x, y, z, flowerItem); + } + } } int FlowerPotTile::getResource(int data, Random *random, int playerBonusLevel) @@ -122,71 +144,7 @@ int FlowerPotTile::getResource(int data, Random *random, int playerBonusLevel) return Item::flowerPot_Id; } -shared_ptr FlowerPotTile::getItemFromType(int type) +shared_ptr FlowerPotTile::newTileEntity(Level *level) { - switch (type) - { - case TYPE_FLOWER_RED: - return std::make_shared(Tile::rose); - case TYPE_FLOWER_YELLOW: - return std::make_shared(Tile::flower); - case TYPE_CACTUS: - return std::make_shared(Tile::cactus); - case TYPE_MUSHROOM_BROWN: - return std::make_shared(Tile::mushroom_brown); - case TYPE_MUSHROOM_RED: - return std::make_shared(Tile::mushroom_red); - case TYPE_DEAD_BUSH: - return std::make_shared(Tile::deadBush); - case TYPE_SAPLING_DEFAULT: - return std::make_shared(Tile::sapling, 1, Sapling::TYPE_DEFAULT); - case TYPE_SAPLING_BIRCH: - return std::make_shared(Tile::sapling, 1, Sapling::TYPE_BIRCH); - case TYPE_SAPLING_EVERGREEN: - return std::make_shared(Tile::sapling, 1, Sapling::TYPE_EVERGREEN); - case TYPE_SAPLING_JUNGLE: - return std::make_shared(Tile::sapling, 1, Sapling::TYPE_JUNGLE); - case TYPE_FERN: - return std::make_shared(Tile::tallgrass, 1, TallGrass::FERN); - } - - return nullptr; -} - -int FlowerPotTile::getTypeFromItem(shared_ptr item) -{ - int id = item->getItem()->id; - - if (id == Tile::rose_Id) return TYPE_FLOWER_RED; - if (id == Tile::flower_Id) return TYPE_FLOWER_YELLOW; - if (id == Tile::cactus_Id) return TYPE_CACTUS; - if (id == Tile::mushroom_brown_Id) return TYPE_MUSHROOM_BROWN; - if (id == Tile::mushroom_red_Id) return TYPE_MUSHROOM_RED; - if (id == Tile::deadBush_Id) return TYPE_DEAD_BUSH; - - if (id == Tile::sapling_Id) - { - switch (item->getAuxValue()) - { - case Sapling::TYPE_DEFAULT: - return TYPE_SAPLING_DEFAULT; - case Sapling::TYPE_BIRCH: - return TYPE_SAPLING_BIRCH; - case Sapling::TYPE_EVERGREEN: - return TYPE_SAPLING_EVERGREEN; - case Sapling::TYPE_JUNGLE: - return TYPE_SAPLING_JUNGLE; - } - } - - if (id == Tile::tallgrass_Id) - { - switch (item->getAuxValue()) - { - case TallGrass::FERN: - return TYPE_FERN; - } - } - - return 0; + return std::make_shared(); } \ No newline at end of file diff --git a/Minecraft.World/FlowerPotTile.h b/Minecraft.World/FlowerPotTile.h index 50dc18c4..1487a58a 100644 --- a/Minecraft.World/FlowerPotTile.h +++ b/Minecraft.World/FlowerPotTile.h @@ -1,28 +1,17 @@ #pragma once -#include "Tile.h" +#include "BaseEntityTile.h" -class FlowerPotTile : public Tile +class FlowerPotTile : public BaseEntityTile { public: - static const int TYPE_FLOWER_RED = 1; - static const int TYPE_FLOWER_YELLOW = 2; - static const int TYPE_SAPLING_DEFAULT = 3; - static const int TYPE_SAPLING_EVERGREEN = 4; - static const int TYPE_SAPLING_BIRCH = 5; - static const int TYPE_SAPLING_JUNGLE = 6; - static const int TYPE_MUSHROOM_RED = 7; - static const int TYPE_MUSHROOM_BROWN = 8; - static const int TYPE_CACTUS = 9; - static const int TYPE_DEAD_BUSH = 10; - static const int TYPE_FERN = 11; - FlowerPotTile(int id); void updateDefaultShape(); bool isSolidRender(bool isServerLevel = false); int getRenderShape(); bool isCubeShaped(); + bool isValidPlant(int itemId, int aux); bool use(Level *level, int x, int y, int z, shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly = false); int cloneTileId(Level *level, int x, int y, int z); int cloneTileData(Level *level, int x, int y, int z); @@ -32,6 +21,6 @@ public: using Tile::spawnResources; void spawnResources(Level *level, int x, int y, int z, int data, float odds, int playerBonusLevel); int getResource(int data, Random *random, int playerBonusLevel); - static shared_ptr getItemFromType(int type); - static int getTypeFromItem(shared_ptr item); + + virtual shared_ptr newTileEntity(Level *level) override; }; \ No newline at end of file diff --git a/Minecraft.World/FlowerPotTileEntity.cpp b/Minecraft.World/FlowerPotTileEntity.cpp new file mode 100644 index 00000000..e3d24d77 --- /dev/null +++ b/Minecraft.World/FlowerPotTileEntity.cpp @@ -0,0 +1,70 @@ +#include "stdafx.h" +#include "FlowerPotTileEntity.h" +#include "com.mojang.nbt.h" +#include "TileEntityDataPacket.h" + +FlowerPotTileEntity::FlowerPotTileEntity() +{ + m_itemId = 0; + m_aux = 0; +} + +void FlowerPotTileEntity::setFlower(int itemId, int aux) +{ + m_itemId = itemId; + m_aux = aux; + setChanged(); +} + +bool FlowerPotTileEntity::hasFlower() const +{ + return m_itemId != 0; +} + +shared_ptr FlowerPotTileEntity::getFlowerItem() const +{ + if (!hasFlower()) return nullptr; + return std::make_shared(m_itemId, 1, m_aux); +} + +void FlowerPotTileEntity::clearFlower() +{ + m_itemId = 0; + m_aux = 0; + setChanged(); +} + +void FlowerPotTileEntity::load(CompoundTag* tag) +{ + TileEntity::load(tag); + m_itemId = tag->getInt(L"ItemId"); + m_aux = tag->getInt(L"Aux"); +} + +void FlowerPotTileEntity::save(CompoundTag* tag) +{ + TileEntity::save(tag); + tag->putInt(L"ItemId", m_itemId); + tag->putInt(L"Aux", m_aux); +} + +shared_ptr FlowerPotTileEntity::clone() +{ + auto result = std::make_shared(); + TileEntity::clone(result); + result->m_itemId = m_itemId; + result->m_aux = m_aux; + return result; +} + +shared_ptr FlowerPotTileEntity::getUpdatePacket() +{ + CompoundTag* tag = new CompoundTag(); + save(tag); + return std::make_shared(x, y, z, TileEntityDataPacket::TYPE_FLOWER_POT, tag); +} + +void FlowerPotTileEntity::handleUpdateTag(CompoundTag* tag) +{ + load(tag); +} \ No newline at end of file diff --git a/Minecraft.World/FlowerPotTileEntity.h b/Minecraft.World/FlowerPotTileEntity.h new file mode 100644 index 00000000..af67517b --- /dev/null +++ b/Minecraft.World/FlowerPotTileEntity.h @@ -0,0 +1,25 @@ +#pragma once +#include "TileEntity.h" + +class FlowerPotTileEntity : public TileEntity +{ +public: + eINSTANCEOF GetType() { return eTYPE_FLOWERPOTTILEENTITY; } + static TileEntity* create() { return new FlowerPotTileEntity(); } + + FlowerPotTileEntity(); + void setFlower(int itemId, int aux); + bool hasFlower() const; + shared_ptr getFlowerItem() const; + int getItemId() const { return m_itemId; } + int getAux() const { return m_aux; } + void clearFlower(); + virtual void load(CompoundTag* tag) override; + virtual void save(CompoundTag* tag) override; + virtual shared_ptr clone() override; + virtual shared_ptr getUpdatePacket(); + virtual void handleUpdateTag(CompoundTag* tag); +private: + int m_itemId; + int m_aux; +}; \ No newline at end of file diff --git a/Minecraft.World/ScatteredFeaturePieces.cpp b/Minecraft.World/ScatteredFeaturePieces.cpp index 18082e46..204e761d 100644 --- a/Minecraft.World/ScatteredFeaturePieces.cpp +++ b/Minecraft.World/ScatteredFeaturePieces.cpp @@ -8,6 +8,7 @@ #include "net.minecraft.world.level.levelgen.structure.h" #include "WeighedTreasure.h" #include "ScatteredFeaturePieces.h" +#include "FlowerPotTileEntity.h" void ScatteredFeaturePieces::loadStatic() { @@ -695,7 +696,7 @@ bool ScatteredFeaturePieces::SwamplandHut::postProcess(Level *level, Random *ran placeBlock(level, 0, 0, 1, 3, 4, chunkBB); placeBlock(level, 0, 0, 5, 3, 4, chunkBB); placeBlock(level, 0, 0, 5, 3, 5, chunkBB); - placeBlock(level, Tile::flowerPot_Id, FlowerPotTile::TYPE_MUSHROOM_RED, 1, 3, 5, chunkBB); + placeFlowerPot(level, chunkBB, 1, 3, 5, Tile::mushroom_red_Id, 0); // decoration placeBlock(level, Tile::workBench_Id, 0, 3, 2, 6, chunkBB); diff --git a/Minecraft.World/StructurePiece.cpp b/Minecraft.World/StructurePiece.cpp index bb3887c0..0380ee39 100644 --- a/Minecraft.World/StructurePiece.cpp +++ b/Minecraft.World/StructurePiece.cpp @@ -12,6 +12,7 @@ #include "JavaMath.h" #include "Facing.h" #include "DoorItem.h" +#include "FlowerPotTileEntity.h" /** * @@ -553,6 +554,21 @@ void StructurePiece::placeBlock( Level* level, int block, int data, int x, int y level->setTileAndData( worldX, worldY, worldZ, block, data, Tile::UPDATE_CLIENTS); } +void StructurePiece::placeFlowerPot(Level *level, BoundingBox *chunkBB, int x, int y, int z, int flowerItemId, int aux) +{ + int worldX = getWorldX(x, z); + int worldY = getWorldY(y); + int worldZ = getWorldZ(x, z); + if (!chunkBB->isInside(worldX, worldY, worldZ)) return; + + placeBlock(level, Tile::flowerPot_Id, 0, worldX, worldY, worldZ, chunkBB); + auto te = std::make_shared(); + te->setLevel(level); + te->x = worldX; te->y = worldY; te->z = worldZ; + te->setFlower(flowerItemId, aux); + level->setTileEntity(worldX, worldY, worldZ, te); + level->setData(worldX, worldY, worldZ, 1, Tile::UPDATE_CLIENTS); +} /** * The purpose of this method is to wrap the getTile call on Level, in order diff --git a/Minecraft.World/StructurePiece.h b/Minecraft.World/StructurePiece.h index 2d5767f9..f36667a0 100644 --- a/Minecraft.World/StructurePiece.h +++ b/Minecraft.World/StructurePiece.h @@ -105,6 +105,7 @@ public: int getWorldZ(int x, int z); int getOrientationData(int tile, int data); virtual void placeBlock(Level *level, int block, int data, int x, int y, int z, BoundingBox *chunkBB); + void placeFlowerPot(Level *level, BoundingBox *chunkBB, int x, int y, int z, int flowerItemId, int aux); /** * The purpose of this method is to wrap the getTile call on Level, in order diff --git a/Minecraft.World/TileEntity.cpp b/Minecraft.World/TileEntity.cpp index 1fff44bb..b4af7add 100644 --- a/Minecraft.World/TileEntity.cpp +++ b/Minecraft.World/TileEntity.cpp @@ -32,6 +32,7 @@ void TileEntity::staticCtor() TileEntity::setId(DaylightDetectorTileEntity::create, eTYPE_DAYLIGHTDETECTORTILEENTITY, L"DLDetector"); TileEntity::setId(HopperTileEntity::create, eTYPE_HOPPERTILEENTITY, L"Hopper"); TileEntity::setId(ComparatorTileEntity::create, eTYPE_COMPARATORTILEENTITY, L"Comparator"); + TileEntity::setId(FlowerPotTileEntity::create, eTYPE_FLOWERPOTTILEENTITY, L"FlowerPot"); } void TileEntity::setId(tileEntityCreateFn createFn, eINSTANCEOF clas, wstring id) diff --git a/Minecraft.World/TileEntityDataPacket.h b/Minecraft.World/TileEntityDataPacket.h index 6fe3bf89..69e2cbdd 100644 --- a/Minecraft.World/TileEntityDataPacket.h +++ b/Minecraft.World/TileEntityDataPacket.h @@ -12,6 +12,7 @@ public: static const int TYPE_ADV_COMMAND = 2; static const int TYPE_BEACON = 3; static const int TYPE_SKULL = 4; + static const int TYPE_FLOWER_POT = 5; int x, y, z; int type; diff --git a/Minecraft.World/cmake/sources/Common.cmake b/Minecraft.World/cmake/sources/Common.cmake index 8c201c0b..4cd25f23 100644 --- a/Minecraft.World/cmake/sources/Common.cmake +++ b/Minecraft.World/cmake/sources/Common.cmake @@ -2092,6 +2092,8 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_TILE_ENTITY "${CMAKE_CURRENT_SOURCE_DIR}/TileEntity.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/TileEntity.h" "${CMAKE_CURRENT_SOURCE_DIR}/net.minecraft.world.level.tile.entity.h" + "${CMAKE_CURRENT_SOURCE_DIR}/FlowerPotTileEntity.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/FlowerPotTileEntity.h" ) source_group("net/minecraft/world/level/tile/entity" FILES ${_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_TILE_ENTITY}) diff --git a/Minecraft.World/net.minecraft.world.level.tile.entity.h b/Minecraft.World/net.minecraft.world.level.tile.entity.h index 1d6e7f76..1e924154 100644 --- a/Minecraft.World/net.minecraft.world.level.tile.entity.h +++ b/Minecraft.World/net.minecraft.world.level.tile.entity.h @@ -21,3 +21,4 @@ #include "SkullTileEntity.h" #include "EnderChestTileEntity.h" #include "ItemFrame.h" +#include "FlowerPotTileEntity.h"