From d9a2776e21af5bd2d303ce936e08c3cedd5670ed Mon Sep 17 00:00:00 2001 From: Fireblade <72758695+Firebladedoge229@users.noreply.github.com> Date: Sun, 24 May 2026 21:39:15 -0400 Subject: [PATCH] feat: sunflower w/ dye recipies --- .../Common/UI/IUIScene_CreativeMenu.cpp | 2 +- .../Common/UI/UIComponent_Panorama.cpp | 2 +- Minecraft.Client/PreStitchedTextureMap.cpp | 4 + Minecraft.Client/TileRenderer.cpp | 124 ++++++++++++++++++ Minecraft.Client/TileRenderer.h | 1 + Minecraft.World/ClothDyeRecipes.cpp | 54 +++++++- Minecraft.World/HalfTransparentTile.cpp | 2 +- Minecraft.World/SlimeTile.cpp | 1 - Minecraft.World/TallGrass2.cpp | 29 +++- Minecraft.World/TallGrass2.h | 4 + Minecraft.World/Tile.cpp | 6 + 11 files changed, 219 insertions(+), 10 deletions(-) diff --git a/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp b/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp index 3bd3b244..fd813672 100644 --- a/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp +++ b/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp @@ -234,7 +234,7 @@ void IUIScene_CreativeMenu::staticCtor() ITEM_AUX(Tile::rose_Id, Rose::WHITE_TULIP) ITEM_AUX(Tile::rose_Id, Rose::PINK_TULIP) ITEM_AUX(Tile::rose_Id, Rose::OXEYE_DAISY) - // SUNFLOWER LOCATION + ITEM(Tile::tallgrass2_Id) ITEM_AUX(Tile::tallgrass2_Id, TallGrass2::LILAC) ITEM_AUX(Tile::tallgrass2_Id, TallGrass2::TALL_GRASS) ITEM_AUX(Tile::tallgrass2_Id, TallGrass2::LARGE_FERN) diff --git a/Minecraft.Client/Common/UI/UIComponent_Panorama.cpp b/Minecraft.Client/Common/UI/UIComponent_Panorama.cpp index 6700887a..606b1499 100644 --- a/Minecraft.Client/Common/UI/UIComponent_Panorama.cpp +++ b/Minecraft.Client/Common/UI/UIComponent_Panorama.cpp @@ -17,7 +17,7 @@ UIComponent_Panorama::UIComponent_Panorama(int iPad, void *initData, UILayer *pa } wstring UIComponent_Panorama::getMoviePath() -{ +{ switch( m_parentLayer->getViewport() ) { case C4JRender::VIEWPORT_TYPE_SPLIT_TOP: diff --git a/Minecraft.Client/PreStitchedTextureMap.cpp b/Minecraft.Client/PreStitchedTextureMap.cpp index 2f990f6e..d5d952d1 100644 --- a/Minecraft.Client/PreStitchedTextureMap.cpp +++ b/Minecraft.Client/PreStitchedTextureMap.cpp @@ -1078,6 +1078,10 @@ void PreStitchedTextureMap::loadUVs() ADD_ICON(20, 3, L"tallgrass2_rose_bush_upper"); ADD_ICON(21, 4, L"tallgrass2_lilac_lower"); ADD_ICON(20, 4, L"tallgrass2_lilac_upper"); + ADD_ICON(21, 6, L"tallgrass2_sunflower_lower"); + ADD_ICON(20, 6, L"tallgrass2_sunflower_upper"); + ADD_ICON(21, 7, L"tallgrass2_sunflower_head_front"); // dont ask me why these are flipped + ADD_ICON(20, 7, L"tallgrass2_sunflower_head_back"); // probably something to do with my slop code - Fireblade } } diff --git a/Minecraft.Client/TileRenderer.cpp b/Minecraft.Client/TileRenderer.cpp index 90ca451c..55a3a8a0 100644 --- a/Minecraft.Client/TileRenderer.cpp +++ b/Minecraft.Client/TileRenderer.cpp @@ -9,9 +9,11 @@ #include "../Minecraft.World/net.minecraft.world.level.material.h" #include "../Minecraft.World/net.minecraft.h" #include "../Minecraft.World/net.minecraft.world.h" +#include "../Minecraft.World/JavaMath.h" #include "Tesselator.h" #include "EntityTileRenderer.h" #include "Options.h" +#include "../Minecraft.World/TallGrass2.h" bool TileRenderer::fancy = true; @@ -4193,6 +4195,87 @@ bool TileRenderer::tesselateCrossInWorld( Tile* tt, int x, int y, int z ) zt += ((((seed >> 24) & 0xf) / 15.0f) - 0.5f) * 0.5f; } + if (tt == Tile::tallgrass2) + { + const int data = level->getData(x, y, z); + const bool isUpper = (data & TallGrass2::UPPER_BIT) != 0; + const int lowerData = isUpper ? level->getData(x, y - 1, z) : data; + const int variant = lowerData & ~TallGrass2::UPPER_BIT; + + if (isUpper && variant == TallGrass2::SUNFLOWER) + { + // cut off stem height (i think thats how it was in the original LCE?) + tesselateCrossStemHeight(tt, data, xt, yt, zt, 0.875f); + TallGrass2* tallGrass = static_cast(tt); + Icon* frontTex = tallGrass->getSunflowerHeadFrontIcon(); + Icon* backTex = tallGrass->getSunflowerHeadBackIcon(); + if (frontTex != nullptr && backTex != nullptr) + { + float fu0 = frontTex->getU0(true); + float fu1 = frontTex->getU1(true); + float fv0 = frontTex->getV0(true); + float fv1 = frontTex->getV1(true); + + float bu0 = backTex->getU0(true); + float bu1 = backTex->getU1(true); + float bv0 = backTex->getV0(true); + float bv1 = backTex->getV1(true); + + const float angle = 22.5f * (PI / 180.0f); + const float c = Mth::cos(angle); + const float s = Mth::sin(angle); + const float ox = xt + 0.5f; + const float oy = yt + 0.5f; + const float oz = zt + 0.5f; + + auto rotateZ = [&](float &px, float &py) + { + float dx = px - ox; + float dy = py - oy; + px = ox + (dx * c - dy * s); + py = oy + (dx * s + dy * c); + }; + + const float z0 = zt + (1.0f / 16.0f); + const float z1 = zt + (15.0f / 16.0f); + const float y0 = yt - (1.0f / 16.0f); + const float y1 = yt + (15.0f / 16.0f); + + const float xPlane = xt + (9.6f / 16.0f); + const float depth = 0.001f; + + float fx0 = xPlane + depth, fy0 = y1, fz0 = z0; + float fx1 = xPlane + depth, fy1 = y0, fz1 = z0; + float fx2 = xPlane + depth, fy2 = y0, fz2 = z1; + float fx3 = xPlane + depth, fy3 = y1, fz3 = z1; + rotateZ(fx0, fy0); + rotateZ(fx1, fy1); + rotateZ(fx2, fy2); + rotateZ(fx3, fy3); + + t->vertexUV(fx0, fy0, fz0, fu0, fv0); + t->vertexUV(fx1, fy1, fz1, fu0, fv1); + t->vertexUV(fx2, fy2, fz2, fu1, fv1); + t->vertexUV(fx3, fy3, fz3, fu1, fv0); + + float bx0 = xPlane - depth, by0 = y1, bz0 = z0; + float bx1 = xPlane - depth, by1 = y0, bz1 = z0; + float bx2 = xPlane - depth, by2 = y0, bz2 = z1; + float bx3 = xPlane - depth, by3 = y1, bz3 = z1; + rotateZ(bx0, by0); + rotateZ(bx1, by1); + rotateZ(bx2, by2); + rotateZ(bx3, by3); + + t->vertexUV(bx3, by3, bz3, bu0, bv0); + t->vertexUV(bx2, by2, bz2, bu0, bv1); + t->vertexUV(bx1, by1, bz1, bu1, bv1); + t->vertexUV(bx0, by0, bz0, bu1, bv0); + } + return true; + } + } + tesselateCrossTexture( tt, level->getData( x, y, z ), xt, yt, zt, 1 ); return true; } @@ -4372,6 +4455,47 @@ void TileRenderer::tesselateCrossTexture( Tile* tt, int data, float x, float y, } +void TileRenderer::tesselateCrossStemHeight( Tile* tt, int data, float x, float y, float z, float height ) +{ + Tesselator* t = Tesselator::getInstance(); + + Icon *tex = getTexture(tt, 0, data); + + if (hasFixedTexture()) tex = fixedTexture; + float u0 = tex->getU0(true); + float v0 = tex->getV0(true); + float u1 = tex->getU1(true); + float v1 = tex->getV(height * SharedConstants::WORLD_RESOLUTION, true); + + float width = 0.45f; + float x0 = x + 0.5f - width; + float x1 = x + 0.5f + width; + float z0 = z + 0.5f - width; + float z1 = z + 0.5f + width; + + float topY = y + height; + + t->vertexUV( x0, topY, z0, u0, v0 ); + t->vertexUV( x0, y + 0, z0, u0, v1 ); + t->vertexUV( x1, y + 0, z1, u1, v1 ); + t->vertexUV( x1, topY, z1, u1, v0 ); + + t->vertexUV( x1, topY, z1, u0, v0 ); + t->vertexUV( x1, y + 0, z1, u0, v1 ); + t->vertexUV( x0, y + 0, z0, u1, v1 ); + t->vertexUV( x0, topY, z0, u1, v0 ); + + t->vertexUV( x0, topY, z1, u0, v0 ); + t->vertexUV( x0, y + 0, z1, u0, v1 ); + t->vertexUV( x1, y + 0, z0, u1, v1 ); + t->vertexUV( x1, topY, z0, u1, v0 ); + + t->vertexUV( x1, topY, z0, u0, v0 ); + t->vertexUV( x1, y + 0, z0, u0, v1 ); + t->vertexUV( x0, y + 0, z1, u1, v1 ); + t->vertexUV( x0, topY, z1, u1, v0 ); +} + void TileRenderer::tesselateStemTexture( Tile* tt, int data, float h, float x, float y, float z ) { Tesselator* t = Tesselator::getInstance(); diff --git a/Minecraft.Client/TileRenderer.h b/Minecraft.Client/TileRenderer.h index 5e78d6d6..5d2c53c6 100644 --- a/Minecraft.Client/TileRenderer.h +++ b/Minecraft.Client/TileRenderer.h @@ -149,6 +149,7 @@ private: bool tesselateRowInWorld( Tile* tt, int x, int y, int z ); void tesselateTorch( Tile* tt, float x, float y, float z, float xxa, float zza, int data ); void tesselateCrossTexture( Tile* tt, int data, float x, float y, float z, float scale ); + void tesselateCrossStemHeight( Tile* tt, int data, float x, float y, float z, float height ); void tesselateStemTexture( Tile* tt, int data, float h, float x, float y, float z ); bool tesselateLilypadInWorld(Tile *tt, int x, int y, int z); void tesselateStemDirTexture( StemTile* tt, int data, int dir, float h, float x, float y, float z ); diff --git a/Minecraft.World/ClothDyeRecipes.cpp b/Minecraft.World/ClothDyeRecipes.cpp index 4662d604..26939243 100644 --- a/Minecraft.World/ClothDyeRecipes.cpp +++ b/Minecraft.World/ClothDyeRecipes.cpp @@ -1,6 +1,8 @@ #include "stdafx.h" #include "net.minecraft.world.item.h" #include "net.minecraft.world.level.tile.h" +#include "Rose.h" +#include "TallGrass2.h" #include "Recipy.h" #include "Recipes.h" #include "ClothDyeRecipes.h" @@ -38,18 +40,66 @@ void ClothDyeRecipes::addRecipes(Recipes *r) } // some dye recipes - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::YELLOW), + r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::YELLOW), L"tg", Tile::flower,L'D'); - r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::RED), + r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::RED), L"tg", Tile::rose,L'D'); + r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::LIGHT_BLUE), + L"zg", + new ItemInstance(Tile::rose, 1, Rose::BLUE_ORCHID),L'D'); + + r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::MAGENTA), + L"zg", + new ItemInstance(Tile::rose, 1, Rose::ALLIUM),L'D'); + + r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::SILVER), + L"zg", + new ItemInstance(Tile::rose, 1, Rose::AZURE_BLUET),L'D'); + + r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::RED), + L"zg", + new ItemInstance(Tile::rose, 1, Rose::RED_TULIP),L'D'); + + r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::ORANGE), + L"zg", + new ItemInstance(Tile::rose, 1, Rose::ORANGE_TULIP),L'D'); + + r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::SILVER), + L"zg", + new ItemInstance(Tile::rose, 1, Rose::WHITE_TULIP),L'D'); + + r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::PINK), + L"zg", + new ItemInstance(Tile::rose, 1, Rose::PINK_TULIP),L'D'); + + r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 1, DyePowderItem::SILVER), + L"zg", + new ItemInstance(Tile::rose, 1, Rose::OXEYE_DAISY),L'D'); + r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 3, DyePowderItem::WHITE), L"ig", Item::bone,L'D'); + r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::YELLOW), + L"zg", + new ItemInstance(Tile::tallgrass2, 1, TallGrass2::SUNFLOWER),L'D'); + + r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::MAGENTA), + L"zg", + new ItemInstance(Tile::tallgrass2, 1, TallGrass2::LILAC),L'D'); + + r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::RED), + L"zg", + new ItemInstance(Tile::tallgrass2, 1, TallGrass2::ROSE_BUSH),L'D'); + + r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::PINK), + L"zg", + new ItemInstance(Tile::tallgrass2, 1, TallGrass2::PEONY),L'D'); + r->addShapelessRecipy(new ItemInstance(Item::dye_powder, 2, DyePowderItem::PINK), // L"zzg", new ItemInstance(Item::dye_powder, 1, DyePowderItem::RED), diff --git a/Minecraft.World/HalfTransparentTile.cpp b/Minecraft.World/HalfTransparentTile.cpp index edcc8f16..93ffcab9 100644 --- a/Minecraft.World/HalfTransparentTile.cpp +++ b/Minecraft.World/HalfTransparentTile.cpp @@ -5,9 +5,9 @@ HalfTransparentTile::HalfTransparentTile(int id, const wstring &tex, Material *material, bool allowSame) : Tile(id,material,isSolidRender()) { + setLightBlock(0); this->allowSame = allowSame; this->texture = tex; - setLightBlock(0); } bool HalfTransparentTile::isSolidRender(bool isServerLevel) diff --git a/Minecraft.World/SlimeTile.cpp b/Minecraft.World/SlimeTile.cpp index 585f8011..3f7c0bd3 100644 --- a/Minecraft.World/SlimeTile.cpp +++ b/Minecraft.World/SlimeTile.cpp @@ -10,7 +10,6 @@ SlimeTile::SlimeTile(int id) : HalfTransparentTile(id, L"slime", Material::clay, false) { friction = 0.8f; - setLightBlock(0); } int SlimeTile::getRenderLayer() diff --git a/Minecraft.World/TallGrass2.cpp b/Minecraft.World/TallGrass2.cpp index 93c0538c..b9a2d9da 100644 --- a/Minecraft.World/TallGrass2.cpp +++ b/Minecraft.World/TallGrass2.cpp @@ -30,7 +30,7 @@ static const int DESCRIPTION_IDS[TallGrass2::VARIANT_COUNT] = { static const wstring TEXTURE_BOTTOM[TallGrass2::VARIANT_COUNT] = { - L"tallgrass2_tall_grass_lower", // Sunflower, not implemented yet + L"tallgrass2_sunflower_lower", L"tallgrass2_lilac_lower", L"tallgrass2_tall_grass_lower", L"tallgrass2_large_fern_lower", @@ -39,7 +39,25 @@ static const wstring TEXTURE_BOTTOM[TallGrass2::VARIANT_COUNT] = { }; static const wstring TEXTURE_TOP[TallGrass2::VARIANT_COUNT] = { - L"tallgrass2_tall_grass_upper", // Sunflower, not implemented yet + L"tallgrass2_sunflower_upper", + L"tallgrass2_lilac_upper", + L"tallgrass2_tall_grass_upper", + L"tallgrass2_large_fern_upper", + L"tallgrass2_rose_bush_upper", + L"tallgrass2_peony_upper" +}; + +static const wstring TEXTURE_HEAD_FRONT[TallGrass2::VARIANT_COUNT] = { + L"tallgrass2_sunflower_head_front", + L"tallgrass2_lilac_upper", + L"tallgrass2_tall_grass_upper", + L"tallgrass2_large_fern_upper", + L"tallgrass2_rose_bush_upper", + L"tallgrass2_peony_upper" +}; + +static const wstring TEXTURE_HEAD_BACK[TallGrass2::VARIANT_COUNT] = { + L"tallgrass2_sunflower_head_back", L"tallgrass2_lilac_upper", L"tallgrass2_tall_grass_upper", L"tallgrass2_large_fern_upper", @@ -79,9 +97,12 @@ void TallGrass2::registerIcons(IconRegister* iconRegister) { iconBottom[i] = iconRegister->registerIcon(TEXTURE_BOTTOM[i]); iconTop[i] = iconRegister->registerIcon(TEXTURE_TOP[i]); + iconHeadFront[i] = iconRegister->registerIcon(TEXTURE_HEAD_FRONT[i]); + iconHeadBack[i] = iconRegister->registerIcon(TEXTURE_HEAD_BACK[i]); } - icon = iconTop[TALL_GRASS]; + // sunflower item + icon = iconHeadFront[SUNFLOWER] != nullptr ? iconHeadFront[SUNFLOWER] : iconTop[TALL_GRASS]; } @@ -151,6 +172,7 @@ bool TallGrass2::mayPlace(Level* level, int x, int y, int z) && level->getTile(x, y, z) == 0 && level->getTile(x, y + 1, z) == 0; } + void TallGrass2::finalizePlacement(Level* level, int x, int y, int z, int data) { if ((data & UPPER_BIT) != 0) return; @@ -169,7 +191,6 @@ void TallGrass2::onPlace(Level* level, int x, int y, int z) level->setTilesDirty(x - 1, y - 1, z - 1, x + 1, y + 2, z + 1); } - bool TallGrass2::canSurvive(Level* level, int x, int y, int z) { int data = level->getData(x, y, z); diff --git a/Minecraft.World/TallGrass2.h b/Minecraft.World/TallGrass2.h index 1be2f485..00f8eafc 100644 --- a/Minecraft.World/TallGrass2.h +++ b/Minecraft.World/TallGrass2.h @@ -18,6 +18,8 @@ public: private: Icon* iconBottom[VARIANT_COUNT]; Icon* iconTop[VARIANT_COUNT]; + Icon* iconHeadFront[VARIANT_COUNT]; + Icon* iconHeadBack[VARIANT_COUNT]; protected: TallGrass2(int id); @@ -27,6 +29,8 @@ public: virtual Icon* getTexture(int face, int data) override; virtual Icon* getTexture(LevelSource* level, int x, int y, int z, int face) override; virtual void registerIcons(IconRegister* iconRegister) override; + Icon* getSunflowerHeadFrontIcon() const { return iconHeadFront[SUNFLOWER]; } + Icon* getSunflowerHeadBackIcon() const { return iconHeadBack[SUNFLOWER]; } virtual int getRenderShape() override; virtual bool blocksLight() override; virtual bool isSolidRender(bool isServerLevel = false) override; diff --git a/Minecraft.World/Tile.cpp b/Minecraft.World/Tile.cpp index a18a7396..e1a9b886 100644 --- a/Minecraft.World/Tile.cpp +++ b/Minecraft.World/Tile.cpp @@ -296,6 +296,12 @@ public: virtual Icon* getIcon(int auxValue) override { + if (auxValue == TallGrass2::SUNFLOWER) + { + TallGrass2* tile = static_cast(Tile::tiles[getTileId()]); + if (tile != nullptr) + return tile->getSunflowerHeadBackIcon(); + } return Tile::tiles[getTileId()]->getTexture(Facing::UP, auxValue); }