From ff5c57f6ba1bd450d76a692c9ca1f8e452a4b3c7 Mon Sep 17 00:00:00 2001 From: Shredder Date: Fri, 3 Apr 2026 14:55:33 +0500 Subject: [PATCH] Added Foliage and Grass Color tinting, Started Basic Work on restoring ravines, New Option to Toggle Tinting. --- data/images/environment/foliagecolor.png | Bin 0 -> 17693 bytes data/images/environment/grasscolor.png | Bin 0 -> 25237 bytes data/lang/en_US.lang | 1 + src/client/Minecraft.cpp | 19 ++++++ src/client/Options.cpp | 5 ++ src/client/Options.h | 1 + src/client/gui/screens/OptionsScreen.cpp | 3 +- src/client/renderer/Chunk.cpp | 7 +++ src/client/renderer/LevelRenderer.cpp | 11 ++++ src/client/renderer/Textures.cpp | 31 ++++++++++ src/client/renderer/Textures.h | 2 + src/world/level/FoliageColor.cpp | 13 ++++ src/world/level/FoliageColor.h | 58 ++++++++++++------ src/world/level/GrassColor.cpp | 13 ++++ src/world/level/GrassColor.h | 42 +++++++++++++ src/world/level/LevelSource.h | 5 +- src/world/level/Region.h | 2 + src/world/level/biome/Biome.cpp | 8 +-- src/world/level/biome/Biome.h | 1 - src/world/level/biome/BiomeSource.cpp | 22 +++---- src/world/level/biome/BiomeSource.h | 6 +- src/world/level/levelgen/CanyonFeature.cpp | 7 ++- src/world/level/levelgen/CanyonFeature.h | 6 +- .../level/levelgen/RandomLevelSource.cpp | 2 +- src/world/level/tile/GrassTile.cpp | 20 ++++-- src/world/level/tile/GrassTile.h | 1 + src/world/level/tile/LeafTile.h | 12 +++- 27 files changed, 241 insertions(+), 57 deletions(-) create mode 100644 data/images/environment/foliagecolor.png create mode 100644 data/images/environment/grasscolor.png create mode 100644 src/world/level/FoliageColor.cpp create mode 100644 src/world/level/GrassColor.cpp create mode 100644 src/world/level/GrassColor.h diff --git a/data/images/environment/foliagecolor.png b/data/images/environment/foliagecolor.png new file mode 100644 index 0000000000000000000000000000000000000000..81673caee3a2d26227d88215e08d7df8d9ccfe0b GIT binary patch literal 17693 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 U)zFOe5dZ)H07*qoM6N<$f@-qCsQ>@~ literal 0 HcmV?d00001 diff --git a/data/images/environment/grasscolor.png b/data/images/environment/grasscolor.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d9c2090c4d5723c3f01ffc3559ab248e9fcbc1 GIT binary patch literal 25237 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 Y(5}(#`*R6n1pa&zGJoEsIpVDU10aElA^-pY literal 0 HcmV?d00001 diff --git a/data/lang/en_US.lang b/data/lang/en_US.lang index 4bb15e2..97ceaa2 100755 --- a/data/lang/en_US.lang +++ b/data/lang/en_US.lang @@ -153,6 +153,7 @@ options.group.tweaks=Tweaks options.allowSprint=Allow sprint options.barOnTop=HUD above inventory options.rpiCursor=Show Raspberry PI cursor +options.foliageTint=Tint Grass and Leaves options.autoJump=Auto Jump options.thirdperson=Third Person options.servervisible=Server Visible diff --git a/src/client/Minecraft.cpp b/src/client/Minecraft.cpp index 341bea9..1127246 100755 --- a/src/client/Minecraft.cpp +++ b/src/client/Minecraft.cpp @@ -90,6 +90,7 @@ #include "../network/command/CommandServer.h" #include "gamemode/CreatorMode.h" +#include "../world/level/GrassColor.h" static void checkGlError(const char* tag) { #ifdef GLDEBUG while (1) { @@ -1132,6 +1133,24 @@ void Minecraft::init() gameRenderer = new GameRenderer(this); particleEngine = new ParticleEngine(level, textures); + // 4j's code for reference +// FoliageColor::init(textures->loadTexturePixels(L"misc/foliagecolor.png")); + + + // my code + TextureId foliageId = (textures->loadTexture("environment/foliagecolor.png")); // loading the uh png for foliage color + int* foliagePixels = textures->loadTexturePixels(foliageId, "environment/foliagecolor.png"); + // now i can finally initialize foliage color, probably not the best way to handle this but i cant be arsed rn + FoliageColor::init(foliagePixels); + + TextureId grassId = (textures->loadTexture("environment/grasscolor.png")); // loading the uh png for foliage color + int* grassPixels = textures->loadTexturePixels(grassId, "environment/grasscolor.png"); + GrassColor::init(grassPixels); + + bool tint = options.getBooleanValue(OPTIONS_FOLIAGE_TINT); // finally, toggleable foliage color + FoliageColor::setUseTint(tint); + GrassColor::setUseTint(tint); + // Platform specific initialization here font = new Font(&options, "font/default8.png", textures); diff --git a/src/client/Options.cpp b/src/client/Options.cpp index 2cacca0..68d6bae 100755 --- a/src/client/Options.cpp +++ b/src/client/Options.cpp @@ -60,6 +60,8 @@ OptionBool useTouchscreen("useTouchscreen", true); OptionBool serverVisible("servervisible", true); +OptionBool foliageTint("foliagetint", false); + OptionInt keyForward("key.forward", Keyboard::KEY_W); OptionInt keyLeft("key.left", Keyboard::KEY_A); OptionInt keyBack("key.back", Keyboard::KEY_S); @@ -136,6 +138,8 @@ void Options::initTable() { m_options[OPTIONS_USE_TOUCHSCREEN] = &useTouchscreen; + + m_options[OPTIONS_SERVER_VISIBLE] = &serverVisible; m_options[OPTIONS_KEY_FORWARD] = &keyForward; @@ -160,6 +164,7 @@ void Options::initTable() { m_options[OPTIONS_BAR_ON_TOP] = &barOnTop; m_options[OPTIONS_ALLOW_SPRINT] = &allowSprint; m_options[OPTIONS_RPI_CURSOR] = &rpiCursor; + m_options[OPTIONS_FOLIAGE_TINT] = &foliageTint; m_options[OPTIONS_AUTOJUMP] = &autoJump; m_options[OPTIONS_LAST_IP] = &lastIp; diff --git a/src/client/Options.h b/src/client/Options.h index f5a4393..96d6f3b 100755 --- a/src/client/Options.h +++ b/src/client/Options.h @@ -84,6 +84,7 @@ enum OptionId { OPTIONS_LAST_IP, OPTIONS_RPI_CURSOR, + OPTIONS_FOLIAGE_TINT, // Should be last! OPTIONS_COUNT }; diff --git a/src/client/gui/screens/OptionsScreen.cpp b/src/client/gui/screens/OptionsScreen.cpp index 11b87c1..02a7a62 100755 --- a/src/client/gui/screens/OptionsScreen.cpp +++ b/src/client/gui/screens/OptionsScreen.cpp @@ -225,7 +225,8 @@ void OptionsScreen::generateOptionScreens() { optionPanes[4]->addOptionItem(OPTIONS_ALLOW_SPRINT, minecraft) .addOptionItem(OPTIONS_BAR_ON_TOP, minecraft) - .addOptionItem(OPTIONS_RPI_CURSOR, minecraft); + .addOptionItem(OPTIONS_RPI_CURSOR, minecraft) + .addOptionItem(OPTIONS_FOLIAGE_TINT, minecraft); } void OptionsScreen::mouseClicked(int x, int y, int buttonNum) { diff --git a/src/client/renderer/Chunk.cpp b/src/client/renderer/Chunk.cpp index 13ac27c..2d28324 100755 --- a/src/client/renderer/Chunk.cpp +++ b/src/client/renderer/Chunk.cpp @@ -7,6 +7,10 @@ #include "../../world/level/Region.h" #include "../../world/level/chunk/LevelChunk.h" #include "../../util/Mth.h" + +#include "../../world/level/biome/BiomeSource.h" + +#include "../../world/level/Level.h" //#include "../../platform/time.h" /*static*/ int Chunk::updates = 0; @@ -260,3 +264,6 @@ void Chunk::resetUpdates() updates = 0; //swRebuild.reset(); } +BiomeSource* Region::getBiomeSource() { + return level->getBiomeSource(); +} \ No newline at end of file diff --git a/src/client/renderer/LevelRenderer.cpp b/src/client/renderer/LevelRenderer.cpp index 3520732..73670cd 100755 --- a/src/client/renderer/LevelRenderer.cpp +++ b/src/client/renderer/LevelRenderer.cpp @@ -25,6 +25,8 @@ #include "../../client/player/LocalPlayer.h" +#include "../../world/level/GrassColor.h" + #ifdef GFX_SMALLER_CHUNKS /* static */ const int LevelRenderer::CHUNK_SIZE = 8; #else @@ -143,6 +145,10 @@ void LevelRenderer::setLevel( Level* level ) level->addListener(this); allChanged(); } + if (mc->options.getBooleanValue(OPTIONS_AMBIENT_OCCLUSION)) { + mc->useAmbientOcclusion = !mc->useAmbientOcclusion; + allChanged(); + } } void LevelRenderer::allChanged() @@ -155,6 +161,11 @@ void LevelRenderer::allChanged() Tile::leaves_carried->setFancy(fancy); lastViewDistance = mc->options.getIntValue(OPTIONS_VIEW_DISTANCE); + bool tint = mc->options.getBooleanValue(OPTIONS_FOLIAGE_TINT); + FoliageColor::setUseTint(tint); + GrassColor::setUseTint(tint); + + int dist = (512 >> 3) << (3 - lastViewDistance); if (lastViewDistance <= 2 && mc->isPowerVR()) dist = (int)((float)dist * 0.8f); diff --git a/src/client/renderer/Textures.cpp b/src/client/renderer/Textures.cpp index 9fce411..b4b1676 100755 --- a/src/client/renderer/Textures.cpp +++ b/src/client/renderer/Textures.cpp @@ -249,6 +249,37 @@ int Textures::crispBlend( int c0, int c1 ) return (a << 24) | (r << 16) | (g << 8) | b; } +// shredder here, moved the code from minecraft.cpp bcus that isnt the right place +// had to implement this because i couldn't find a similar function in the code to do this +int* Textures::loadTexturePixels(TextureId texId, const std::string& resourceName){ + + const TextureData* texture = getTemporaryTextureData(texId); // storing raw pixels + + int size = texture->w * texture->h; // gets the size of our funny lil guy + int* pixels = new int[size]; // memory leaks be galore + unsigned char* raw = texture->data; // storing raw data into our beloved variable + for (int i = 0; i < (texture->w * texture->h); i++){ + // my head hurts i hate working with this + + + // uh since each pixel stores r g b a, aka the color channels which are each one byte, we multiply them by 4 to move from one pixel to another + + int r = raw[i * 4 + 0]; // gets us the first channel aka red + int g = raw[i * 4 + 1]; // gets us the second channel green + int b = raw[i * 4 + 2]; // gets us the third channel blue + int a = raw[i * 4 + 3]; // gets us the alpha channel + + // woohoo pixels uh should have been seperated into their colors now hopefully + + // r g b a + // ugh we now got to turn it into the AA RR GGBB format aak 0xAARRGGBB + // b gets 0 - 7 (8 bits), g gets 7 - 15 (8 bits), r gets 16 - 23 (8 bits), alpha gets the last ones 24 - 31 (8 bits), + pixels[i] = (a << 24) | (r << 16) | (g << 8) | (b); // shuld combine them into one 32 bit int unless i did something dumb + } + return pixels; // your meal has been prepared john colors +} + + ///*public*/ int loadHttpTexture(std::string url, std::string backup) { // HttpTexture texture = httpTextures.get(url); // if (texture != NULL) { diff --git a/src/client/renderer/Textures.h b/src/client/renderer/Textures.h index f5e2113..f4ab36e 100755 --- a/src/client/renderer/Textures.h +++ b/src/client/renderer/Textures.h @@ -44,6 +44,8 @@ public: TextureId assignTexture(const std::string& resourceName, const TextureData& img); const TextureData* getTemporaryTextureData(TextureId id); + int* loadTexturePixels(TextureId texId, const std::string& resourceName); + void tick(bool uploadToGraphicsCard); void clear(); diff --git a/src/world/level/FoliageColor.cpp b/src/world/level/FoliageColor.cpp new file mode 100644 index 0000000..018cd1f --- /dev/null +++ b/src/world/level/FoliageColor.cpp @@ -0,0 +1,13 @@ +#include "FoliageColor.h" + +// TODO: Probably move all the stuff from the header into here so it's a bit cleaner +bool FoliageColor::useTint = true; + +int FoliageColor::get(float temp, float rain) { + rain *= temp; + int x = (int) ((1 - temp) * 255); + int y = (int) ((1 - rain) * 255); + return pixels[y << 8 | x]; +} + +int* FoliageColor::pixels = nullptr; \ No newline at end of file diff --git a/src/world/level/FoliageColor.h b/src/world/level/FoliageColor.h index 6d7d024..98d77b7 100755 --- a/src/world/level/FoliageColor.h +++ b/src/world/level/FoliageColor.h @@ -6,31 +6,49 @@ class FoliageColor { public: -// static void init(int[] pixels) { -// FoliageColor::pixels = pixels; -// } -// -// static int get(float temp, float rain) { -// rain *= temp; -// int x = (int) ((1 - temp) * 255); -// int y = (int) ((1 - rain) * 255); -// return pixels[y << 8 | x]; -// } + static bool useTint; - static int getEvergreenColor() { - return 0x619961; - } + static void setUseTint(bool value) { + useTint = value; + } + /* + Shredder here, Ive converted the unused commented out code into their correct syntax, though if i did something incorrectly feel free to take reference from the + commented out code + */ - static int getBirchColor() { - return 0x80a755; - } + // static void init(int[] pixels) { + // FoliageColor::pixels = pixels; + // } + // + // static int get(float temp, float rain) { + // rain *= temp; + // int x = (int) ((1 - temp) * 255); + // int y = (int) ((1 - rain) * 255); + // return pixels[y << 8 | x]; + // } - static int getDefaultColor() { - return 0x48b518; - } + + static void init(int* p) { + pixels = p; + } + + static int get(float temp, float rain); + + static int getEvergreenColor() { + return 0x619961; + } + + static int getBirchColor() { + return 0x80a755; + } + + static int getDefaultColor() { + return 0xFFFFFF; + } private: - //static int pixels[256*256]; + // static int pixels[256*256]; + static int* pixels; }; #endif /*NET_MINECRAFT_WORLD_LEVEL__FoliageColor_H__*/ diff --git a/src/world/level/GrassColor.cpp b/src/world/level/GrassColor.cpp new file mode 100644 index 0000000..eb05bd4 --- /dev/null +++ b/src/world/level/GrassColor.cpp @@ -0,0 +1,13 @@ +#include "GrassColor.h" + +// TODO: Probably move all the stuff from the header into here so it's a bit cleaner +bool GrassColor::useTint = true; + +int GrassColor::get(float temp, float rain) { + rain *= temp; + int x = (int) ((1 - temp) * 255); + int y = (int) ((1 - rain) * 255); + return pixels[y << 8 | x]; +} + +int* GrassColor::pixels = nullptr; \ No newline at end of file diff --git a/src/world/level/GrassColor.h b/src/world/level/GrassColor.h new file mode 100644 index 0000000..08903c7 --- /dev/null +++ b/src/world/level/GrassColor.h @@ -0,0 +1,42 @@ +#ifndef NET_MINECRAFT_WORLD_LEVEL__GrassColor_H__ +#define NET_MINECRAFT_WORLD_LEVEL__GrassColor_H__ + +//package net.minecraft.world.level; + +class GrassColor +{ +public: + static bool useTint; + + static void setUseTint(bool value) { + useTint = value; + } +/* +Shredder here, Ive converted the unused commented out code into their correct syntax, though if i did something incorrectly feel free to take reference from the +commented out code +*/ + +// static void init(int[] pixels) { +// GrassColor::pixels = pixels; +// } +// +// static int get(float temp, float rain) { +// rain *= temp; +// int x = (int) ((1 - temp) * 255); +// int y = (int) ((1 - rain) * 255); +// return pixels[y << 8 | x]; +// } + + + static void init(int* p) { + pixels = p; + } + + static int get(float temp, float rain); + +private: + // static int pixels[256*256]; + static int* pixels; +}; + +#endif /*NET_MINECRAFT_WORLD_LEVEL__GrassColor_H__*/ diff --git a/src/world/level/LevelSource.h b/src/world/level/LevelSource.h index 5dc5896..a130ec1 100755 --- a/src/world/level/LevelSource.h +++ b/src/world/level/LevelSource.h @@ -3,8 +3,9 @@ //package net.minecraft.world.level; -/* + class BiomeSource; +/* class TileEntity; */ class Material; @@ -29,7 +30,7 @@ public: virtual bool isSolidRenderTile(int x, int i, int z) = 0; virtual bool isSolidBlockingTile(int x, int i, int z) = 0; - //virtual BiomeSource* getBiomeSource() = 0; + virtual BiomeSource* getBiomeSource() = 0; virtual Biome* getBiome(int x, int z) = 0; }; diff --git a/src/world/level/Region.h b/src/world/level/Region.h index b4c3e58..d699099 100755 --- a/src/world/level/Region.h +++ b/src/world/level/Region.h @@ -5,6 +5,7 @@ #include "LevelSource.h" + class Level; class Material; class LevelChunk; @@ -27,6 +28,7 @@ public: int getData(int x, int y, int z); const Material* getMaterial(int x, int y, int z); Biome* getBiome(int x, int z); + BiomeSource* getBiomeSource() override; private: int xc1, zc1; LevelChunk*** chunks; diff --git a/src/world/level/biome/Biome.cpp b/src/world/level/biome/Biome.cpp index 7ccbdfe..609ed52 100755 --- a/src/world/level/biome/Biome.cpp +++ b/src/world/level/biome/Biome.cpp @@ -149,13 +149,7 @@ Feature* Biome::getGrassFeature( Random* random ) { return new TallgrassFeature(Tile::tallgrass->id, TallGrass::TALL_GRASS); } -Feature* Biome::getBasicTreeFeature( Random* random ) -{ - if (random->nextInt(10) == 0) { - return new BasicTree(false); - } - -} + Biome* Biome::getBiome( float temperature, float downfall ) diff --git a/src/world/level/biome/Biome.h b/src/world/level/biome/Biome.h index 23fd495..48a49d5 100755 --- a/src/world/level/biome/Biome.h +++ b/src/world/level/biome/Biome.h @@ -71,7 +71,6 @@ public: virtual Feature* getTreeFeature(Random* random); virtual Feature* getGrassFeature(Random* random); - virtual Feature* getBasicTreeFeature(Random* random); static Biome* getBiome(float temperature, float downfall); static Biome* _getBiome(float temperature, float downfall); diff --git a/src/world/level/biome/BiomeSource.cpp b/src/world/level/biome/BiomeSource.cpp index ab7c3a4..395b5a9 100755 --- a/src/world/level/biome/BiomeSource.cpp +++ b/src/world/level/biome/BiomeSource.cpp @@ -69,11 +69,11 @@ Biome* BiomeSource::getBiome( int x, int z ) return getBiomeBlock(x, z, 1, 1)[0]; } -//float BiomeSource::getTemperature( int x, int z ) -//{ -// temperatures = temperatureMap->getRegion(temperatures, x, z, 1, 1, tempScale, tempScale, 0.5f); -// return temperatures[0]; -//} +float BiomeSource::getTemperature( int x, int z ) +{ + temperatures = temperatureMap->getRegion(temperatures, x, z, 1, 1, tempScale, tempScale, 0.5f); + return temperatures[0]; +} Biome** BiomeSource::getBiomeBlock( int x, int z, int w, int h ) { @@ -123,7 +123,7 @@ Biome** BiomeSource::getBiomeBlock( Biome** biomes__, int x, int z, int w, int h return biomes; } -float* BiomeSource::getTemperatureBlock( /*float* temperatures__, */int x, int z, int w, int h ) +float* BiomeSource::getTemperatureBlock( float* temperatures__, int x, int z, int w, int h ) { //LOGI("gTempBlock: 1\n"); //const int size = w * h; @@ -164,8 +164,8 @@ float* BiomeSource::getTemperatureBlock( /*float* temperatures__, */int x, int z return temperatures; } -//float* BiomeSource::getDownfallBlock( /*float* downfalls__,*/ int x, int z, int w, int h ) -//{ +float* BiomeSource::getDownfallBlock( float* downfalls__, int x, int z, int w, int h ) +{ // //const int size = w * h; // //if (lenDownfalls < size) { // // delete[] downfalls; @@ -173,6 +173,6 @@ float* BiomeSource::getTemperatureBlock( /*float* temperatures__, */int x, int z // // lenDownfalls = size; // //} // -// downfalls = downfallMap->getRegion(downfalls, x, z, w, w, downfallScale, downfallScale, 0.5f); -// return downfalls; -//} + downfalls = downfallMap->getRegion(downfalls, x, z, w, w, downfallScale, downfallScale, 0.5f); + return downfalls; +} diff --git a/src/world/level/biome/BiomeSource.h b/src/world/level/biome/BiomeSource.h index fb540c1..25a3e5f 100755 --- a/src/world/level/biome/BiomeSource.h +++ b/src/world/level/biome/BiomeSource.h @@ -31,13 +31,13 @@ public: virtual Biome* getBiome(const ChunkPos& chunk); virtual Biome* getBiome(int x, int z); - //virtual float getTemperature(int x, int z); + virtual float getTemperature(int x, int z); // Note: The arrays returned here are temporary in the meaning that their // contents might change in the future. If you need to SAVE the // values, do a shallow copy to an array of your own. - virtual float* getTemperatureBlock(/*float* temperatures, */ int x, int z, int w, int h); - //virtual float* getDownfallBlock(/*float* downfalls, */int x, int z, int w, int h); + virtual float* getTemperatureBlock(float* temperatures, int x, int z, int w, int h); + virtual float* getDownfallBlock(float* downfalls, int x, int z, int w, int h); virtual Biome** getBiomeBlock(int x, int z, int w, int h); private: diff --git a/src/world/level/levelgen/CanyonFeature.cpp b/src/world/level/levelgen/CanyonFeature.cpp index f7d9ca3..095cd30 100755 --- a/src/world/level/levelgen/CanyonFeature.cpp +++ b/src/world/level/levelgen/CanyonFeature.cpp @@ -1,4 +1,4 @@ -#if 0 + #include "CanyonFeature.h" @@ -138,7 +138,7 @@ void CanyonFeature::addTunnel( int xOffs, int zOffs, unsigned char* blocks, floa } } -void CanyonFeature::addFeature( Level level, int x, int z, int xOffs, int zOffs, char* blocks ) +void CanyonFeature::addFeature(Level* level, int x, int z, int xOffs, int zOffs,unsigned char* blocks) { if (random.nextInt(15) != 0) return; @@ -151,6 +151,7 @@ void CanyonFeature::addFeature( Level level, int x, int z, int xOffs, int zOffs, float thickness = (random.nextFloat() * 2 + random.nextFloat()) + 1; addTunnel(xOffs, zOffs, blocks, xCave, yCave, zCave, thickness, yRot, xRot, 0, 0, 5.0); + } /* //private @@ -165,4 +166,4 @@ void CanyonFeature::addFeature( Level level, int x, int z, int xOffs, int zOffs, for (int z = zOffs - r; z <= zOffs + r; z++) { random.setSeed((x * xScale + z * zScale) ^ level.seed);*/ -#endif + diff --git a/src/world/level/levelgen/CanyonFeature.h b/src/world/level/levelgen/CanyonFeature.h index bd60c71..a187681 100755 --- a/src/world/level/levelgen/CanyonFeature.h +++ b/src/world/level/levelgen/CanyonFeature.h @@ -1,7 +1,7 @@ #ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__CanyonFeature_H__ #define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__CanyonFeature_H__ -#if 0 + //package net.minecraft.world.level.levelgen; @@ -12,8 +12,8 @@ class CanyonFeature: public LargeFeature { /*protected*/ void addTunnel(int xOffs, int zOffs, unsigned char* blocks, float xCave, float yCave, float zCave, float thickness, float yRot, float xRot, int step, int dist, float yScale); /*protected*/ - void addFeature(Level level, int x, int z, int xOffs, int zOffs, char* blocks); + void addFeature(Level* level, int x, int z, int xOffs, int zOffs,unsigned char* blocks); }; -#endif + #endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__CanyonFeature_H__*/ diff --git a/src/world/level/levelgen/RandomLevelSource.cpp b/src/world/level/levelgen/RandomLevelSource.cpp index 56f5b8b..99f8ce7 100755 --- a/src/world/level/levelgen/RandomLevelSource.cpp +++ b/src/world/level/levelgen/RandomLevelSource.cpp @@ -473,7 +473,7 @@ void RandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) { MobSpawner::postProcessSpawnMobs(level, biome, xo + 8, zo + 8, 16, 16, &random); //LOGI("Reading temp: 1\n"); - float* temperatures = level->getBiomeSource()->getTemperatureBlock(/*NULL,*/ xo + 8, zo + 8, 16, 16); + float* temperatures = level->getBiomeSource()->getTemperatureBlock(NULL, xo + 8, zo + 8, 16, 16); for (int x = xo + 8; x < xo + 8 + 16; x++) for (int z = zo + 8; z < zo + 8 + 16; z++) { int xp = x - (xo + 8); diff --git a/src/world/level/tile/GrassTile.cpp b/src/world/level/tile/GrassTile.cpp index 7a293ea..1828966 100755 --- a/src/world/level/tile/GrassTile.cpp +++ b/src/world/level/tile/GrassTile.cpp @@ -1,6 +1,11 @@ #include "GrassTile.h" #include "../material/Material.h" #include "../../entity/item/ItemEntity.h" +#include "../GrassColor.h" +#include "../Level.h" +#include "../LevelSource.h" +#include "../biome/BiomeSource.h" +#include "../../../client/Minecraft.h" GrassTile::GrassTile(int id) : super(id, Material::dirt) @@ -24,11 +29,18 @@ int GrassTile::getTexture( int face, int data ) { } int GrassTile::getColor( LevelSource* level, int x, int y, int z ) { - //level.getBiomeSource().getBiomeBlock(x, z, 1, 1); - //float temp = level.getBiomeSource().temperatures[0]; - //float rain = level.getBiomeSource().downfalls[0]; - return 0x339933;//GrassColor.get(temp, rain); + if(!GrassColor::useTint){ + return 0x339933; + } + + level->getBiomeSource()->getBiomeBlock(x, z, 1, 1); + float temp = level->getBiomeSource()->temperatures[0]; + float rain = level->getBiomeSource()->downfalls[0]; + +// return 0x339933;//GrassColor.get(temp, rain); // we need to hook this up with OPTION_FOLIAGE_TINT + + return GrassColor::get(temp, rain); } void GrassTile::tick( Level* level, int x, int y, int z, Random* random ) { diff --git a/src/world/level/tile/GrassTile.h b/src/world/level/tile/GrassTile.h index bc62825..c97db84 100755 --- a/src/world/level/tile/GrassTile.h +++ b/src/world/level/tile/GrassTile.h @@ -14,6 +14,7 @@ class GrassTile: public Tile { typedef Tile super; public: + static const int MIN_BRIGHTNESS = 4; GrassTile(int id); diff --git a/src/world/level/tile/LeafTile.h b/src/world/level/tile/LeafTile.h index e1102ca..53d9884 100755 --- a/src/world/level/tile/LeafTile.h +++ b/src/world/level/tile/LeafTile.h @@ -9,6 +9,8 @@ #include "../../item/Item.h" #include "../../item/ItemInstance.h" #include "../FoliageColor.h" +#include "../LevelSource.h" +#include "../biome/BiomeSource.h" class Entity; @@ -54,8 +56,16 @@ public: if (data == BIRCH_LEAF) { return FoliageColor::getBirchColor(); } + if (!FoliageColor::useTint){ + return FoliageColor::getDefaultColor(); + } - return FoliageColor::getDefaultColor(); + // return FoliageColor::getDefaultColor(); we need to hook this up with OPTION_FOLIAGE_TINT + level->getBiomeSource()->getBiomeBlock(x, z, 1, 1); + float temperature = level->getBiomeSource()->temperatures[0]; + float rainfall = level->getBiomeSource()->downfalls[0]; + return FoliageColor::get(temperature, rainfall); + } void onRemove(Level* level, int x, int y, int z) {