From e6ab1214af914d7f46ec980c3ef328d5fec9b8fd Mon Sep 17 00:00:00 2001 From: jonkadelic Date: Sun, 5 Nov 2023 16:19:41 +0000 Subject: [PATCH] Biome colour and grass side tint options (#98) * Added biome colour and grass side tint options * Moved GrassColor and FoliageColor to client/renderer/ * * Fix some build issues. * * Add the new files to the CMakeLists.txt --------- Co-authored-by: iProgramInCpp --- .gitignore | 2 + game/assets/patches/patch_data.txt | 4 + platforms/sdl/main.cpp | 4 + platforms/windows/main.cpp | 4 + .../windows/projects/Client/Client.vcxproj | 4 + .../projects/Client/Client.vcxproj.filters | 12 ++ source/CMakeLists.txt | 2 + source/client/app/Minecraft.cpp | 12 ++ source/client/gui/screens/OptionsScreen.cpp | 82 ++++++++---- source/client/gui/screens/OptionsScreen.hpp | 2 + source/client/options/Options.cpp | 24 ++++ source/client/options/Options.hpp | 4 +- source/client/renderer/FoliageColor.cpp | 37 ++++++ source/client/renderer/FoliageColor.hpp | 25 ++++ source/client/renderer/GrassColor.cpp | 22 ++++ source/client/renderer/GrassColor.hpp | 19 +++ source/client/renderer/LevelRenderer.cpp | 5 + source/client/renderer/PatchManager.cpp | 10 ++ source/client/renderer/PatchManager.hpp | 2 + source/client/renderer/TileRenderer.cpp | 123 +++++++++++++++++- source/client/renderer/TileRenderer.hpp | 5 + source/world/level/Level.hpp | 2 +- source/world/level/Region.cpp | 5 + source/world/level/Region.hpp | 1 + source/world/level/storage/LevelSource.hpp | 2 + source/world/tile/GrassTile.cpp | 4 +- source/world/tile/LeafTile.cpp | 2 + 27 files changed, 388 insertions(+), 32 deletions(-) create mode 100644 source/client/renderer/FoliageColor.cpp create mode 100644 source/client/renderer/FoliageColor.hpp create mode 100644 source/client/renderer/GrassColor.cpp create mode 100644 source/client/renderer/GrassColor.hpp diff --git a/.gitignore b/.gitignore index c466e3f..1ec873d 100644 --- a/.gitignore +++ b/.gitignore @@ -142,6 +142,8 @@ xcuserdata/ /game/assets/gui/items.png /game/assets/gui/title.png /game/assets/item/camera.png +/game/assets/misc/foliagecolor.png +/game/assets/misc/grasscolor.png /game/assets/mob/char.png /game/assets/particles.png /game/assets/terrain.png diff --git a/game/assets/patches/patch_data.txt b/game/assets/patches/patch_data.txt index 3c8bad8..77e902b 100644 --- a/game/assets/patches/patch_data.txt +++ b/game/assets/patches/patch_data.txt @@ -6,12 +6,16 @@ # - vegetation_tint|bool -- Enables default vegetation tint. (grass and leaves) # - metal_block_sides|int -- Makes metal blocks have separate side textures, and allows specification of their Y offset. -1 to disable. # - semi_transparent_glass|bool -- Makes glass render on the alpha layer (as opposed to the opaque layer). Allows it to be semi transparent like ice. +# - grass_sides_tint -- Allows grass sides to be tinted. # - stop_now -- Stops processing at that line. All further commands will be ignored. # * The filename parameter will be a PNG file that can be found relative to this directory. For example, '../quiver.png' will load it from assets/, 'chain.png' will load it from assets/patches/. # * The X and Y destination coordinates will be multiplied by 16. # * The texture doesn't have to be 16x16, all of it will be patched on to terrain.png. +#terrain|4|5|grass_side_transparent.png +#grass_sides_tint|true + # Stop now to ignore the below commands. They're for a patch I'm working on that I don't want to release yet. stop_now diff --git a/platforms/sdl/main.cpp b/platforms/sdl/main.cpp index 19b74bf..d906d05 100644 --- a/platforms/sdl/main.cpp +++ b/platforms/sdl/main.cpp @@ -274,6 +274,8 @@ static EM_BOOL main_loop(double time, void *user_data) extern bool g_bIsMenuBackgroundAvailable; // client/gui/Screen.cpp extern bool g_bAreCloudsAvailable; // client/renderer/LevelRenderer.cpp +extern bool g_bIsGrassColorAvailable; // world/level/GrassColor.cpp +extern bool g_bIsFoliageColorAvailable; // world/level/FoliageColor.cpp #ifdef __EMSCRIPTEN__ bool DoesAssetExist(const std::string & fileName) @@ -296,6 +298,8 @@ void CheckOptionalTextureAvailability() { g_bIsMenuBackgroundAvailable = DoesAssetExist("gui/background/panorama_0.png"); g_bAreCloudsAvailable = DoesAssetExist("environment/clouds.png"); + g_bIsGrassColorAvailable = DoesAssetExist("misc/grasscolor.png"); + g_bIsFoliageColorAvailable = DoesAssetExist("misc/foliagecolor.png"); } // Main diff --git a/platforms/windows/main.cpp b/platforms/windows/main.cpp index 2d31560..034d7c8 100644 --- a/platforms/windows/main.cpp +++ b/platforms/windows/main.cpp @@ -116,6 +116,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) extern bool g_bIsMenuBackgroundAvailable; // client/gui/Screen.cpp extern bool g_bAreCloudsAvailable; // client/renderer/LevelRenderer.cpp +extern bool g_bIsGrassColorAvailable; // world/level/GrassColor.cpp +extern bool g_bIsFoliageColorAvailable; // world/level/FoliageColor.cpp void CheckOptionalTextureAvailability() { @@ -123,6 +125,8 @@ void CheckOptionalTextureAvailability() // Optional features that you really should be able to get away with not including. g_bIsMenuBackgroundAvailable = XPL_ACCESS("assets/gui/background/panorama_0.png", 0) == 0; g_bAreCloudsAvailable = XPL_ACCESS("assets/environment/clouds.png", 0) == 0; + g_bIsGrassColorAvailable = XPL_ACCESS("assets/misc/grasscolor.png", 0) == 0; + g_bIsFoliageColorAvailable = XPL_ACCESS("assets/misc/foliagecolor.png", 0) == 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) diff --git a/platforms/windows/projects/Client/Client.vcxproj b/platforms/windows/projects/Client/Client.vcxproj index c3db2fd..9d2fe2d 100644 --- a/platforms/windows/projects/Client/Client.vcxproj +++ b/platforms/windows/projects/Client/Client.vcxproj @@ -315,6 +315,8 @@ + + @@ -410,6 +412,8 @@ + + diff --git a/platforms/windows/projects/Client/Client.vcxproj.filters b/platforms/windows/projects/Client/Client.vcxproj.filters index 435e791..c26469b 100644 --- a/platforms/windows/projects/Client/Client.vcxproj.filters +++ b/platforms/windows/projects/Client/Client.vcxproj.filters @@ -365,6 +365,12 @@ Header Files\Player\Input + + Header Files\Renderer + + + Header Files\Renderer + @@ -646,5 +652,11 @@ Source Files\Player\Input + + Source Files\Renderer + + + Source Files\Renderer + \ No newline at end of file diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 9fca09f..8e8b399 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -54,6 +54,8 @@ add_library(reminecraftpe-core STATIC client/renderer/LavaTexture.cpp client/renderer/LavaSideTexture.cpp client/renderer/FireTexture.cpp + client/renderer/FoliageColor.cpp + client/renderer/GrassColor.cpp client/sound/SoundData.cpp client/sound/SoundSystem.cpp client/sound/SoundRepository.cpp diff --git a/source/client/app/Minecraft.cpp b/source/client/app/Minecraft.cpp index a9af6d8..0fd68f6 100644 --- a/source/client/app/Minecraft.cpp +++ b/source/client/app/Minecraft.cpp @@ -28,6 +28,9 @@ #include "world/tile/SandTile.hpp" +#include "client/renderer/GrassColor.hpp" +#include "client/renderer/FoliageColor.hpp" + // custom: #include "client/renderer/PatchManager.hpp" @@ -805,6 +808,15 @@ void Minecraft::init() m_pFont = new Font(m_options, "font/default.png", m_pTextures); + if (GrassColor::isAvailable()) + { + GrassColor::init(m_pPlatform->loadTexture("misc/grasscolor.png", true)); + } + if (FoliageColor::isAvailable()) + { + FoliageColor::init(m_pPlatform->loadTexture("misc/foliagecolor.png", true)); + } + // Patch Manager GetPatchManager()->LoadPatchData(platform()->getPatchData()); diff --git a/source/client/gui/screens/OptionsScreen.cpp b/source/client/gui/screens/OptionsScreen.cpp index cfff614..7fc5190 100644 --- a/source/client/gui/screens/OptionsScreen.cpp +++ b/source/client/gui/screens/OptionsScreen.cpp @@ -10,6 +10,10 @@ #include "StartMenuScreen.hpp" #include "PauseScreen.hpp" +#include "client/renderer/PatchManager.hpp" +#include "client/renderer/GrassColor.hpp" +#include "client/renderer/FoliageColor.hpp" + // Note! This enum matches the order in the options screen constructor enum eOptionsButton { @@ -24,6 +28,8 @@ enum eOptionsButton OB_FLY_HAX, OB_AUTO_JUMP, OB_BLOCK_LINES, + OB_FANCY_GRASS, + OB_BIOME_COLORS }; OptionsScreen::OptionsScreen() @@ -38,7 +44,9 @@ OptionsScreen::OptionsScreen() m_viewDistButton (8, 0, 0, 150, 20, ""), m_flightHaxButton (9, 0, 0, 150, 20, ""), m_autoJumpButton (10, 0, 0, 150, 20, ""), - m_blockLinesButton(11, 0, 0, 150, 20, "") + m_blockLinesButton(11, 0, 0, 150, 20, ""), + m_fancyGrassButton(12, 0, 0, 150, 20, ""), + m_biomeColorsButton(13, 0, 0, 150, 20, "") #endif { } @@ -70,20 +78,31 @@ void OptionsScreen::updateTexts() { Options& o = *(m_pMinecraft->getOptions()); - m_AOButton.m_text = "Smooth lighting: " + BoolOptionStr(o.m_bAmbientOcclusion); - m_invertYButton.m_text = "Invert Y-axis: " + BoolOptionStr(o.m_bInvertMouse); - m_viewBobButton.m_text = "View bobbing: " + BoolOptionStr(o.m_bViewBobbing); - m_anaglyphsButton.m_text = "3d Anaglyphs: " + BoolOptionStr(o.m_bAnaglyphs); - m_fancyGfxButton.m_text = "Fancy graphics: " + BoolOptionStr(o.m_bFancyGraphics); - m_flightHaxButton.m_text = "Flight hax: " + BoolOptionStr(o.m_bFlyCheat); - m_autoJumpButton.m_text = "Auto Jump: " + BoolOptionStr(o.m_bAutoJump); - m_viewDistButton.m_text = "View distance: " + ViewDistanceStr(o.m_iViewDistance); - m_blockLinesButton.m_text = "Block outlines: " + BoolOptionStr(o.m_bBlockOutlines); + m_AOButton.m_text = "Smooth lighting: " + BoolOptionStr(o.m_bAmbientOcclusion); + m_invertYButton.m_text = "Invert Y-axis: " + BoolOptionStr(o.m_bInvertMouse); + m_viewBobButton.m_text = "View bobbing: " + BoolOptionStr(o.m_bViewBobbing); + m_anaglyphsButton.m_text = "3d Anaglyphs: " + BoolOptionStr(o.m_bAnaglyphs); + m_fancyGfxButton.m_text = "Fancy graphics: " + BoolOptionStr(o.m_bFancyGraphics); + m_flightHaxButton.m_text = "Flight hax: " + BoolOptionStr(o.m_bFlyCheat); + m_autoJumpButton.m_text = "Auto Jump: " + BoolOptionStr(o.m_bAutoJump); + m_viewDistButton.m_text = "View distance: " + ViewDistanceStr(o.m_iViewDistance); + m_blockLinesButton.m_text = "Block outlines: " + BoolOptionStr(o.m_bBlockOutlines); + m_fancyGrassButton.m_text = "Fancy grass: " + BoolOptionStr(o.m_bFancyGrass); + m_biomeColorsButton.m_text = "Biome colors: " + BoolOptionStr(o.m_bBiomeColors); if (!isCramped()) m_srvVisButton.m_text = "Server " + std::string(o.m_bServerVisibleDefault ? "visible" : "invisible") + " by default"; else m_srvVisButton.m_text = "Server " + std::string(o.m_bServerVisibleDefault ? "visible" : "invisible"); + + if (!(GetPatchManager()->IsGrassSidesTinted())) + { + m_fancyGrassButton.m_bEnabled = false; + } + if (!GrassColor::isAvailable() && !FoliageColor::isAvailable()) + { + m_biomeColorsButton.m_bEnabled = false; + } } bool OptionsScreen::isCramped() { @@ -101,7 +120,9 @@ void OptionsScreen::setWidthAllButtons(int width) m_anaglyphsButton.m_width = m_viewBobButton.m_width = m_flightHaxButton.m_width = - m_autoJumpButton.m_width = width; + m_autoJumpButton.m_width = + m_fancyGrassButton.m_width = + m_biomeColorsButton.m_width = width; } void OptionsScreen::init() @@ -140,19 +161,22 @@ void OptionsScreen::init() m_srvVisButton.m_xPos = m_fancyGfxButton.m_xPos = m_viewDistButton.m_xPos = - m_blockLinesButton.m_xPos = m_width / 2 - m_AOButton.m_width - 5; + m_blockLinesButton.m_xPos = + m_fancyGrassButton.m_xPos = m_width / 2 - m_AOButton.m_width - 5; - m_invertYButton.m_xPos = - m_anaglyphsButton.m_xPos = - m_viewBobButton.m_xPos = - m_flightHaxButton.m_xPos = - m_autoJumpButton.m_xPos = m_width / 2 + 5; + m_invertYButton.m_xPos = + m_anaglyphsButton.m_xPos = + m_viewBobButton.m_xPos = + m_flightHaxButton.m_xPos = + m_autoJumpButton.m_xPos = + m_biomeColorsButton.m_xPos = m_width / 2 + 5; - m_AOButton.m_yPos = m_invertYButton.m_yPos = yPos; yPos += incrementY; - m_srvVisButton.m_yPos = m_anaglyphsButton.m_yPos = yPos; yPos += incrementY; - m_fancyGfxButton.m_yPos = m_viewBobButton.m_yPos = yPos; yPos += incrementY; - m_viewDistButton.m_yPos = m_flightHaxButton.m_yPos = yPos; yPos += incrementY; - m_autoJumpButton.m_yPos = m_blockLinesButton.m_yPos = yPos; yPos += incrementY; + m_AOButton.m_yPos = m_invertYButton.m_yPos = yPos; yPos += incrementY; + m_srvVisButton.m_yPos = m_anaglyphsButton.m_yPos = yPos; yPos += incrementY; + m_fancyGfxButton.m_yPos = m_viewBobButton.m_yPos = yPos; yPos += incrementY; + m_viewDistButton.m_yPos = m_flightHaxButton.m_yPos = yPos; yPos += incrementY; + m_autoJumpButton.m_yPos = m_blockLinesButton.m_yPos = yPos; yPos += incrementY; + m_fancyGrassButton.m_yPos = m_biomeColorsButton.m_yPos = yPos; yPos += incrementY; m_buttons.push_back(&m_AOButton); m_buttons.push_back(&m_srvVisButton); @@ -164,6 +188,8 @@ void OptionsScreen::init() m_buttons.push_back(&m_flightHaxButton); m_buttons.push_back(&m_autoJumpButton); m_buttons.push_back(&m_blockLinesButton); + m_buttons.push_back(&m_fancyGrassButton); + m_buttons.push_back(&m_biomeColorsButton); m_buttonTabList.push_back(&m_AOButton); m_buttonTabList.push_back(&m_srvVisButton); @@ -175,6 +201,8 @@ void OptionsScreen::init() m_buttonTabList.push_back(&m_flightHaxButton); m_buttonTabList.push_back(&m_autoJumpButton); m_buttonTabList.push_back(&m_blockLinesButton); + m_buttonTabList.push_back(&m_fancyGrassButton); + m_buttonTabList.push_back(&m_biomeColorsButton); m_buttonTabList.push_back(&m_BackButton); @@ -262,6 +290,16 @@ void OptionsScreen::buttonClicked(Button* pButton) case OB_BLOCK_LINES: pOption = &o.m_bBlockOutlines; break; + case OB_FANCY_GRASS: + o.m_bFancyGrass ^= 1; + m_pMinecraft->m_pLevelRenderer->allChanged(); + updateTexts(); + return; + case OB_BIOME_COLORS: + o.m_bBiomeColors ^= 1; + m_pMinecraft->m_pLevelRenderer->allChanged(); + updateTexts(); + return; } if (!pOption) diff --git a/source/client/gui/screens/OptionsScreen.hpp b/source/client/gui/screens/OptionsScreen.hpp index e1591e2..730439a 100644 --- a/source/client/gui/screens/OptionsScreen.hpp +++ b/source/client/gui/screens/OptionsScreen.hpp @@ -37,6 +37,8 @@ private: Button m_flightHaxButton; Button m_autoJumpButton; Button m_blockLinesButton; + Button m_fancyGrassButton; + Button m_biomeColorsButton; #endif }; diff --git a/source/client/options/Options.cpp b/source/client/options/Options.cpp index 86e1e6e..41af512 100644 --- a/source/client/options/Options.cpp +++ b/source/client/options/Options.cpp @@ -13,6 +13,10 @@ #include "compat/KeyCodes.hpp" #include "client/app/Minecraft.hpp" +#include "client/renderer/PatchManager.hpp" +#include "client/renderer/GrassColor.hpp" +#include "client/renderer/FoliageColor.hpp" + Options::Option Options::Option::MUSIC (0, "options.music", true, false), Options::Option::SOUND (1, "options.sound", true, false), @@ -55,6 +59,8 @@ void Options::_initDefaultValues() m_bServerVisibleDefault = true; m_bDebugText = false; m_bBlockOutlines = false; + m_bFancyGrass = false; + m_bBiomeColors = false; field_19 = 1; // Win32 key codes are being used by default @@ -244,6 +250,22 @@ void Options::_load() m_iViewDistance = readInt(value); else if (key == "gfx_blockoutlines") m_bBlockOutlines = readBool(value); + else if (key == "gfx_fancygrass") + { + m_bFancyGrass = readBool(value); + if (!(GetPatchManager()->IsGrassSidesTinted())) + { + m_bFancyGrass = false; + } + } + else if (key == "gfx_biomecolors") + { + m_bBiomeColors = readBool(value); + if (!GrassColor::isAvailable() && !FoliageColor::isAvailable()) + { + m_bBiomeColors = false; + } + } } } @@ -359,6 +381,8 @@ std::vector Options::getOptionStrings() SO("gfx_smoothlighting", saveBool(m_bAmbientOcclusion)); SO("gfx_viewdistance", saveInt (m_iViewDistance)); SO("gfx_blockoutlines", saveBool(m_bBlockOutlines)); + SO("gfx_fancygrass", saveBool(m_bFancyGrass)); + SO("gfx_biomecolors", saveBool(m_bBiomeColors)); return vec; } diff --git a/source/client/options/Options.hpp b/source/client/options/Options.hpp index 6fb0891..d79785d 100644 --- a/source/client/options/Options.hpp +++ b/source/client/options/Options.hpp @@ -84,7 +84,7 @@ public: void save(); std::string getMessage(const Options::Option&); std::vector getOptionStrings(); - + int getKey(eKeyMappingIndex idx) { return m_keyMappings[idx].value; @@ -126,6 +126,8 @@ public: bool m_bAutoJump; bool m_bDebugText; bool m_bBlockOutlines; + bool m_bFancyGrass; + bool m_bBiomeColors; public: struct Option diff --git a/source/client/renderer/FoliageColor.cpp b/source/client/renderer/FoliageColor.cpp new file mode 100644 index 0000000..27b7059 --- /dev/null +++ b/source/client/renderer/FoliageColor.cpp @@ -0,0 +1,37 @@ +#include "FoliageColor.hpp" + +// TODO: This should be inside of an initialized "Minecraft" instance rather than the global namespace +bool g_bIsFoliageColorAvailable = false; + +Texture FoliageColor::texture; + +bool FoliageColor::isAvailable() +{ + return g_bIsFoliageColorAvailable; +} + +void FoliageColor::init(Texture texture) +{ + FoliageColor::texture = texture; +} + +uint32_t FoliageColor::get(double x, double y) +{ + y *= x; + return FoliageColor::texture.m_pixels[(int)((1.0 - y) * 255.0) << 8 | (int)((1.0 - x) * 255.0)]; +} + +uint32_t FoliageColor::getEvergreenColor() +{ + return 0x619961; +} + +uint32_t FoliageColor::getBirchColor() +{ + return 0x55A780; +} + +uint32_t FoliageColor::getDefaultColor() +{ + return 0x18B548; +} \ No newline at end of file diff --git a/source/client/renderer/FoliageColor.hpp b/source/client/renderer/FoliageColor.hpp new file mode 100644 index 0000000..ae1f97f --- /dev/null +++ b/source/client/renderer/FoliageColor.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include + +#include "client/renderer/Texture.hpp" + +class FoliageColor +{ +public: + static bool isAvailable(); + + static void init(Texture texture); + + static uint32_t get(double x, double y); + + static uint32_t getEvergreenColor(); + + static uint32_t getBirchColor(); + + static uint32_t getDefaultColor(); + +private: + static Texture texture; +}; + diff --git a/source/client/renderer/GrassColor.cpp b/source/client/renderer/GrassColor.cpp new file mode 100644 index 0000000..4cb6926 --- /dev/null +++ b/source/client/renderer/GrassColor.cpp @@ -0,0 +1,22 @@ +#include "GrassColor.hpp" + +// TODO: This should be inside of an initialized "Minecraft" instance rather than the global namespace +bool g_bIsGrassColorAvailable = false; + +Texture GrassColor::texture; + +bool GrassColor::isAvailable() +{ + return g_bIsGrassColorAvailable; +} + +void GrassColor::init(Texture texture) +{ + GrassColor::texture = texture; +} + +uint32_t GrassColor::get(double x, double y) +{ + y *= x; + return GrassColor::texture.m_pixels[(int)((1.0 - y) * 255.0) << 8 | (int)((1.0 - x) * 255.0)]; +} \ No newline at end of file diff --git a/source/client/renderer/GrassColor.hpp b/source/client/renderer/GrassColor.hpp new file mode 100644 index 0000000..2a1d6b3 --- /dev/null +++ b/source/client/renderer/GrassColor.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include + +#include "client/renderer/Texture.hpp" + +class GrassColor +{ +public: + static bool isAvailable(); + + static void init(Texture texture); + + static uint32_t get(double x, double y); + +private: + static Texture texture; +}; + diff --git a/source/client/renderer/LevelRenderer.cpp b/source/client/renderer/LevelRenderer.cpp index a174f65..5e88bb2 100644 --- a/source/client/renderer/LevelRenderer.cpp +++ b/source/client/renderer/LevelRenderer.cpp @@ -9,7 +9,9 @@ #include "LevelRenderer.hpp" #include "client/app/Minecraft.hpp" #include "renderer/GL/GL.hpp" + #include "world/tile/LeafTile.hpp" +#include "world/tile/GrassTile.hpp" LevelRenderer::LevelRenderer(Minecraft* pMC, Textures* pTexs) { @@ -136,6 +138,9 @@ void LevelRenderer::allChanged() pLeaves->m_bTransparent = m_pMinecraft->getOptions()->m_bFancyGraphics; pLeaves->m_TextureFrame = !pLeaves->m_bTransparent + pLeaves->field_74; + TileRenderer::m_bFancyGrass = m_pMinecraft->getOptions()->m_bFancyGrass; + TileRenderer::m_bBiomeColors = m_pMinecraft->getOptions()->m_bBiomeColors; + field_BC = m_pMinecraft->getOptions()->m_iViewDistance; int x1 = 64 << (3 - field_BC); diff --git a/source/client/renderer/PatchManager.cpp b/source/client/renderer/PatchManager.cpp index 0518f26..a24ded4 100644 --- a/source/client/renderer/PatchManager.cpp +++ b/source/client/renderer/PatchManager.cpp @@ -141,6 +141,11 @@ void PatchManager::LoadPatchData(const std::string& patchData) ReadInt(lineStream, m_nMetalSideYOffset); continue; } + if (command == "grass_sides_tint") + { + ReadBool(lineStream, m_bGrassSidesTinted); + continue; + } LOG_W("Unknown command %s from patch data.", command.c_str()); } @@ -217,6 +222,11 @@ bool PatchManager::IsGlassSemiTransparent() return m_bGlassSemiTransparent; } +bool PatchManager::IsGrassSidesTinted() +{ + return m_bGrassSidesTinted; +} + void PatchManager::ReadBool(std::istream& is, bool& b) { std::string flag; diff --git a/source/client/renderer/PatchManager.hpp b/source/client/renderer/PatchManager.hpp index 2d88eea..2628aa4 100644 --- a/source/client/renderer/PatchManager.hpp +++ b/source/client/renderer/PatchManager.hpp @@ -80,6 +80,7 @@ public: bool IsGrassTinted(); int GetMetalSideYOffset(); bool IsGlassSemiTransparent(); + bool IsGrassSidesTinted(); private: void ReadBool(std::istream& is, bool& b); @@ -89,6 +90,7 @@ private: bool m_bGrassTinted; bool m_bGlassSemiTransparent; int m_nMetalSideYOffset; + bool m_bGrassSidesTinted; std::vector m_patchData; }; diff --git a/source/client/renderer/TileRenderer.cpp b/source/client/renderer/TileRenderer.cpp index 883ad65..0e59321 100644 --- a/source/client/renderer/TileRenderer.cpp +++ b/source/client/renderer/TileRenderer.cpp @@ -11,6 +11,11 @@ #include "client/renderer/PatchManager.hpp" #include "world/tile/FireTile.hpp" #include "world/tile/LiquidTile.hpp" +#include "client/renderer/GrassColor.hpp" +#include "client/renderer/FoliageColor.hpp" + +bool TileRenderer::m_bFancyGrass = false; +bool TileRenderer::m_bBiomeColors = false; void TileRenderer::_init() { @@ -575,8 +580,14 @@ bool TileRenderer::tesselateBlockInWorld(Tile* tile, int x, int y, int z, float fLight = fLightHere; t.color(r * 0.8f * fLight, g * 0.8f * fLight, b * 0.8f * fLight); + int texture = tile->getTexture(m_pLevelSource, x, y, z, DIR_ZNEG); + renderNorth(tile, float(x), float(y), float(z), texture); - renderNorth(tile, float(x), float(y), float(z), tile->getTexture(m_pLevelSource, x, y, z, DIR_ZNEG)); + if (m_bFancyGrass && texture == TEXTURE_GRASS_SIDE && this->m_textureOverride < 0) + { + t.color(topR * 0.8f * fLight, topG * 0.8f * fLight, topB * 0.8f * fLight); + renderNorth(tile, float(x), float(y), float(z), TEXTURE_NONE84); + } } if (m_bDisableCulling || tile->shouldRenderFace(m_pLevelSource, x, y, z + 1, DIR_ZPOS)) @@ -588,8 +599,14 @@ bool TileRenderer::tesselateBlockInWorld(Tile* tile, int x, int y, int z, float fLight = fLightHere; t.color(r * 0.8f * fLight, g * 0.8f * fLight, b * 0.8f * fLight); + int texture = tile->getTexture(m_pLevelSource, x, y, z, DIR_ZPOS); + renderSouth(tile, float(x), float(y), float(z), texture); - renderSouth(tile, float(x), float(y), float(z), tile->getTexture(m_pLevelSource, x, y, z, DIR_ZPOS)); + if (m_bFancyGrass && texture == TEXTURE_GRASS_SIDE && this->m_textureOverride < 0) + { + t.color(topR * 0.8f * fLight, topG * 0.8f * fLight, topB * 0.8f * fLight); + renderSouth(tile, float(x), float(y), float(z), TEXTURE_NONE84); + } } if (m_bDisableCulling || tile->shouldRenderFace(m_pLevelSource, x - 1, y, z, DIR_XNEG)) @@ -601,8 +618,14 @@ bool TileRenderer::tesselateBlockInWorld(Tile* tile, int x, int y, int z, float fLight = fLightHere; t.color(r * 0.6f * fLight, g * 0.6f * fLight, b * 0.6f * fLight); - - renderWest(tile, float(x), float(y), float(z), tile->getTexture(m_pLevelSource, x, y, z, DIR_XNEG)); + int texture = tile->getTexture(m_pLevelSource, x, y, z, DIR_XNEG); + renderWest(tile, float(x), float(y), float(z), texture); + + if (m_bFancyGrass && texture == TEXTURE_GRASS_SIDE && this->m_textureOverride < 0) + { + t.color(topR * 0.6f * fLight, topG * 0.6f * fLight, topB * 0.6f * fLight); + renderWest(tile, float(x), float(y), float(z), TEXTURE_NONE84); + } } if (m_bDisableCulling || tile->shouldRenderFace(m_pLevelSource, x + 1, y, z, DIR_XPOS)) @@ -614,8 +637,14 @@ bool TileRenderer::tesselateBlockInWorld(Tile* tile, int x, int y, int z, float fLight = fLightHere; t.color(r * 0.6f * fLight, g * 0.6f * fLight, b * 0.6f * fLight); + int texture = tile->getTexture(m_pLevelSource, x, y, z, DIR_XPOS); + renderEast(tile, float(x), float(y), float(z), texture); - renderEast(tile, float(x), float(y), float(z), tile->getTexture(m_pLevelSource, x, y, z, DIR_XPOS)); + if (m_bFancyGrass && texture == TEXTURE_GRASS_SIDE && this->m_textureOverride < 0) + { + t.color(topR * 0.6f * fLight, topG * 0.6f * fLight, topB * 0.6f * fLight); + renderEast(tile, float(x), float(y), float(z), TEXTURE_NONE84); + } } return bDrewAnything; @@ -623,7 +652,7 @@ bool TileRenderer::tesselateBlockInWorld(Tile* tile, int x, int y, int z, float bool TileRenderer::tesselateBlockInWorld(Tile* tile, int x, int y, int z) { - int color = tile->getColor(m_pLevelSource, x, y, z); + int color = getTileColor(tile, x, y, z); float r = float(GET_RED (color)) / 255.0f; float g = float(GET_GREEN(color)) / 255.0f; @@ -2579,7 +2608,6 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusionV2(Tile* tile, int m_vtxBlue[i] = br; } - for (int i = 0; i < 4; i++) { m_vtxRed [i] *= fR * lightingMult[dir]; @@ -2610,9 +2638,90 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusionV2(Tile* tile, int break; } + if (TileRenderer::m_bFancyGrass && tile->getTexture(m_pLevelSource, x, y, z, dir) == TEXTURE_GRASS_SIDE && (dir == DIR_XNEG || dir == DIR_XPOS || dir == DIR_ZNEG || dir == DIR_ZPOS)) + { + for (int i = 0; i < 4; i++) + m_vtxRed[i] = m_vtxGreen[i] = m_vtxBlue[i] = 1.0f; + + for (int i = 0; i < 4; i++) + { + // average: the light at the tile the face's normal would point towards, and 3 other tiles + // chosen based on the vertex corner number + float br = lights[dirToEdir[dir]]; + for (int j = 0; j < 3; j++) + br += lights[table[j + i * 3]]; + + br *= 0.25f; + + m_vtxRed[i] = br; + m_vtxGreen[i] = br; + m_vtxBlue[i] = br; + } + + for (int i = 0; i < 4; i++) + { + m_vtxRed[i] *= topR * lightingMult[dir]; + m_vtxGreen[i] *= topG * lightingMult[dir]; + m_vtxBlue[i] *= topB * lightingMult[dir]; + } + + switch (dir) { + case DIR_YNEG: + renderFaceUp(tile, float(x), float(y), float(z), TEXTURE_NONE84); + break; + case DIR_YPOS: + renderFaceDown(tile, float(x), float(y), float(z), TEXTURE_NONE84); + break; + case DIR_ZNEG: + renderNorth(tile, float(x), float(y), float(z), TEXTURE_NONE84); + break; + case DIR_ZPOS: + renderSouth(tile, float(x), float(y), float(z), TEXTURE_NONE84); + break; + case DIR_XNEG: + renderWest(tile, float(x), float(y), float(z), TEXTURE_NONE84); + break; + case DIR_XPOS: + renderEast(tile, float(x), float(y), float(z), TEXTURE_NONE84); + break; + } + } + m_bAmbientOcclusion = false; } return true; } #endif + +int TileRenderer::getTileColor(Tile* tile, int x, int y, int z) +{ + if (tile == nullptr) + { + return 0xffffff; + } + + if (tile == Tile::grass && GrassColor::isAvailable() && m_bBiomeColors) + { + m_pLevelSource->getBiomeSource()->getBiomeBlock(x, z, 1, 1); + return GrassColor::get(m_pLevelSource->getBiomeSource()->field_4[0], m_pLevelSource->getBiomeSource()->field_8[0]); + } + if (tile == Tile::leaves && FoliageColor::isAvailable() && m_bBiomeColors) + { + int data = m_pLevelSource->getData(x, y, z); + + if ((data & 1) == 1) + { + return FoliageColor::getEvergreenColor(); + } + if ((data & 2) == 2) + { + return FoliageColor::getBirchColor(); + } + + m_pLevelSource->getBiomeSource()->getBiomeBlock(x, z, 1, 1); + return FoliageColor::get(m_pLevelSource->getBiomeSource()->field_4[0], m_pLevelSource->getBiomeSource()->field_8[0]); + } + + return tile->getColor(m_pLevelSource, x, y, z); +} diff --git a/source/client/renderer/TileRenderer.hpp b/source/client/renderer/TileRenderer.hpp index dd3025f..a92d229 100644 --- a/source/client/renderer/TileRenderer.hpp +++ b/source/client/renderer/TileRenderer.hpp @@ -59,8 +59,13 @@ public: bool tesselateBlockInWorldWithAmbienceOcclusionV2(Tile*, int x, int y, int z, float r, float g, float b); #endif + int getTileColor(Tile*, int x, int y, int z); + static bool canRender(int renderShape); + static bool m_bFancyGrass; + static bool m_bBiomeColors; + private: LevelSource* m_pLevelSource; int m_textureOverride; diff --git a/source/world/level/Level.hpp b/source/world/level/Level.hpp index e2ec60e..cde7352 100644 --- a/source/world/level/Level.hpp +++ b/source/world/level/Level.hpp @@ -150,7 +150,7 @@ public: Entity* getEntity(int id); EntityVector* getAllEntities(); EntityVector* getEntities(Entity* pAvoid, const AABB&); - BiomeSource* getBiomeSource(); + BiomeSource* getBiomeSource() override; LevelStorage* getLevelStorage(); LevelData* getLevelData(); AABBVector* getCubes(const Entity* pEnt, const AABB& aabb); diff --git a/source/world/level/Region.cpp b/source/world/level/Region.cpp index d9e781b..bea3a03 100644 --- a/source/world/level/Region.cpp +++ b/source/world/level/Region.cpp @@ -106,6 +106,11 @@ bool Region::isSolidTile(int x, int y, int z) return pTile->isSolidRender(); } +BiomeSource* Region::getBiomeSource() +{ + return m_pLevel->getBiomeSource(); +} + Region::~Region() { delete[] field_C; diff --git a/source/world/level/Region.hpp b/source/world/level/Region.hpp index 3def56b..b5f6466 100644 --- a/source/world/level/Region.hpp +++ b/source/world/level/Region.hpp @@ -20,6 +20,7 @@ public: int getData(int x, int y, int z) override; Material* getMaterial(int x, int y, int z) override; bool isSolidTile(int x, int y, int z) override; + BiomeSource* getBiomeSource() override; virtual ~Region(); Region(Level*, int x1, int y1, int z1, int x2, int y2, int z2); diff --git a/source/world/level/storage/LevelSource.hpp b/source/world/level/storage/LevelSource.hpp index 0773376..87cb388 100644 --- a/source/world/level/storage/LevelSource.hpp +++ b/source/world/level/storage/LevelSource.hpp @@ -10,6 +10,7 @@ #include "common/Utils.hpp" #include "world/level/Material.hpp" +#include "world/level/levelgen/biome/BiomeSource.hpp" class LevelSource { @@ -20,5 +21,6 @@ public: virtual int getData(int x, int y, int z) = 0; virtual Material* getMaterial(int x, int y, int z) = 0; virtual bool isSolidTile(int x, int y, int z) = 0; + virtual BiomeSource* getBiomeSource() = 0; }; diff --git a/source/world/tile/GrassTile.cpp b/source/world/tile/GrassTile.cpp index 3d9867a..80745d0 100644 --- a/source/world/tile/GrassTile.cpp +++ b/source/world/tile/GrassTile.cpp @@ -16,10 +16,12 @@ GrassTile::GrassTile(int id, Material* c) : Tile(id, c) setTicking(true); } -int GrassTile::getColor(LevelSource*, int x, int y, int z) +int GrassTile::getColor(LevelSource* levelSource, int x, int y, int z) { if (GetPatchManager()->IsGrassTinted()) + { return 0x339933; + } return 0xffffff; } diff --git a/source/world/tile/LeafTile.cpp b/source/world/tile/LeafTile.cpp index 6c427d2..5977783 100644 --- a/source/world/tile/LeafTile.cpp +++ b/source/world/tile/LeafTile.cpp @@ -35,7 +35,9 @@ void LeafTile::die(Level* level, int x, int y, int z) int LeafTile::getColor(LevelSource* level, int x, int y, int z) { if (GetPatchManager()->IsGrassTinted()) + { return 0x339933; + } return 0xffffff; }