From aa9fa659df31c8de4c88875e03d1e23252e35f4f Mon Sep 17 00:00:00 2001 From: Shredder Date: Sat, 11 Apr 2026 14:45:47 +0500 Subject: [PATCH] Extremely Big Update - fileshredder (MAJOR)Added Java Beta/Normal Shading, toggleble in settings Fixed and restored the unused Item Switching Animation, toggleble in tweaks too Added Dynamic Texture for Lava Added option to use Block Outline Selection which was unused normally Added Split Touch Controls into Options Mobs will now drop cooked variants of their meat if they died by fire Fixed Untranslated Strings in Settings (MAJOR) Ravines and Lava/Water pools have been fixed and renabled Tweaked BasicTree to hopefully speed up generation a bit, might disable them temporarily if they keep being slow You can now grow Fancy Oak Trees using saplings. --- data/lang/en_US.lang | 15 +- project/android/jni/Android.mk | 1 + project/android_java/jni/Android.mk | 1 + src/client/Minecraft.cpp | 3 + src/client/Options.cpp | 14 +- src/client/Options.h | 3 + src/client/gui/Gui.cpp | 6 +- src/client/gui/components/OptionsItem.cpp | 10 + src/client/gui/screens/CreditsScreen.cpp | 1 + .../screens/IngameBlockSelectionScreen.cpp | 9 +- src/client/gui/screens/OptionsScreen.cpp | 10 +- src/client/model/geom/ModelPart.cpp | 2 +- src/client/model/geom/Polygon.cpp | 12 + src/client/renderer/GameRenderer.cpp | 868 +++++++++-------- src/client/renderer/ItemInHandRenderer.cpp | 89 +- src/client/renderer/LevelRenderer.cpp | 8 +- src/client/renderer/Lighting.cpp | 48 + src/client/renderer/Lighting.h | 12 + src/client/renderer/Tesselator.cpp | 30 +- src/client/renderer/Tesselator.h | 2 +- src/client/renderer/TileRenderer.cpp | 117 ++- src/client/renderer/entity/EntityRenderer.cpp | 5 +- src/client/renderer/entity/ItemRenderer.cpp | 6 +- src/client/renderer/entity/PlayerRenderer.cpp | 8 +- src/client/renderer/gles.cpp | 35 + src/client/renderer/gles.h | 14 +- .../renderer/ptexture/DynamicTexture.cpp | 420 +++++--- src/client/renderer/ptexture/DynamicTexture.h | 38 + src/world/entity/animal/Chicken.cpp | 4 +- src/world/entity/animal/Cow.cpp | 8 +- src/world/entity/animal/Pig.cpp | 4 +- src/world/level/levelgen/CanyonFeature.cpp | 2 +- src/world/level/levelgen/CanyonFeature.h | 6 +- .../level/levelgen/RandomLevelSource.cpp | 918 +++++++++--------- src/world/level/levelgen/RandomLevelSource.h | 3 + src/world/level/levelgen/feature/BasicTree.h | 66 +- src/world/level/tile/Sapling.h | 7 +- 37 files changed, 1671 insertions(+), 1134 deletions(-) create mode 100644 src/client/renderer/Lighting.cpp create mode 100644 src/client/renderer/Lighting.h diff --git a/data/lang/en_US.lang b/data/lang/en_US.lang index 97ceaa2..46866c8 100755 --- a/data/lang/en_US.lang +++ b/data/lang/en_US.lang @@ -153,7 +153,20 @@ 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.foliagetint=Foliage Tinting +options.javaHud=Beta Java hotbar tweaks +options.blockOutline=Block Outline Selection +options.fogType=Fog/Sky Color +options.fogType.vanilla=Vanilla +options.fogType.java=Beta Java +options.fogType.unused=Unused + +options.restoredAnims=Restored Animations + +options.normalLighting=Java Beta/Normals Shading + +options.isJoyTouchArea=Use Split Controls + options.autoJump=Auto Jump options.thirdperson=Third Person options.servervisible=Server Visible diff --git a/project/android/jni/Android.mk b/project/android/jni/Android.mk index 07772aa..551ee31 100755 --- a/project/android/jni/Android.mk +++ b/project/android/jni/Android.mk @@ -98,6 +98,7 @@ LOCAL_SRC_FILES := ../../../src/main.cpp \ ../../../src/client/player/RemotePlayer.cpp \ ../../../src/client/player/input/KeyboardInput.cpp \ ../../../src/client/player/input/touchscreen/TouchscreenInput.cpp \ +../../../src/client/renderer/Lighting.cpp \ ../../../src/client/renderer/Chunk.cpp \ ../../../src/client/renderer/EntityTileRenderer.cpp \ ../../../src/client/renderer/GameRenderer.cpp \ diff --git a/project/android_java/jni/Android.mk b/project/android_java/jni/Android.mk index d472e34..a654801 100755 --- a/project/android_java/jni/Android.mk +++ b/project/android_java/jni/Android.mk @@ -75,6 +75,7 @@ LOCAL_SRC_FILES := ../../../src/main.cpp \ ../../../src/client/player/RemotePlayer.cpp \ ../../../src/client/player/input/KeyboardInput.cpp \ ../../../src/client/player/input/touchscreen/TouchscreenInput.cpp \ +../../../src/client/renderer/Lighting.cpp \ ../../../src/client/renderer/Chunk.cpp \ ../../../src/client/renderer/EntityTileRenderer.cpp \ ../../../src/client/renderer/GameRenderer.cpp \ diff --git a/src/client/Minecraft.cpp b/src/client/Minecraft.cpp index 9146abe..0ea8e9d 100755 --- a/src/client/Minecraft.cpp +++ b/src/client/Minecraft.cpp @@ -745,6 +745,7 @@ void Minecraft::tickInput() { int dst = options.getIntValue(OPTIONS_VIEW_DISTANCE); options.set(OPTIONS_VIEW_DISTANCE, (dst + 1) % 4); } + #ifdef CHEATS if (key == Keyboard::KEY_U) { onGraphicsReset(); @@ -1128,6 +1129,8 @@ void Minecraft::init() textures = new Textures(&options, platform()); textures->addDynamicTexture(new WaterTexture()); textures->addDynamicTexture(new WaterSideTexture()); + textures->addDynamicTexture(new LavaTexture()); + textures->addDynamicTexture(new LavaSideTexture()); textures->addDynamicTexture(new FireTexture()); gui.texturesLoaded(textures); diff --git a/src/client/Options.cpp b/src/client/Options.cpp index cf719b0..78cef1a 100755 --- a/src/client/Options.cpp +++ b/src/client/Options.cpp @@ -54,18 +54,24 @@ OptionBool limitFramerate("limitFramerate", false); OptionBool vsync("vsync", true); OptionBool fancyGraphics("fancyGraphics", true); OptionBool viewBobbing("viewBobbing", true); -OptionBool ambientOcclusion("ao", false); +OptionBool ambientOcclusion("ao", true); + +OptionBool useNormalLighting("normalLighting", true); OptionBool useTouchscreen("useTouchscreen", true); OptionBool serverVisible("servervisible", true); -OptionBool foliageTint("foliagetint", false); +OptionBool foliageTint("foliagetint", true); OptionInt fogType("fogType", 0, 0, 2); OptionBool javaHud("javaHud", false); +OptionBool blockOutline("blockOutline", false); + +OptionBool restoredAnims("restoredAnims", true); + OptionInt keyForward("key.forward", Keyboard::KEY_W); OptionInt keyLeft("key.left", Keyboard::KEY_A); OptionInt keyBack("key.back", Keyboard::KEY_S); @@ -142,7 +148,11 @@ void Options::initTable() { m_options[OPTIONS_USE_TOUCHSCREEN] = &useTouchscreen; + m_options[OPTIONS_BLOCK_OUTLINE] = &blockOutline; + m_options[OPTIONS_NORMAL_LIGHTING] = &useNormalLighting; + + m_options[OPTIONS_RESTORED_ANIMS] = &restoredAnims; m_options[OPTIONS_SERVER_VISIBLE] = &serverVisible; diff --git a/src/client/Options.h b/src/client/Options.h index f81734d..7d1d3b4 100755 --- a/src/client/Options.h +++ b/src/client/Options.h @@ -49,6 +49,7 @@ enum OptionId { OPTIONS_LIMIT_FRAMERATE, OPTIONS_VSYNC, OPTIONS_FANCY_GRAPHICS, + OPTIONS_NORMAL_LIGHTING, // Cheats / debug OPTIONS_FLY_SPEED, @@ -56,6 +57,7 @@ enum OptionId { OPTIONS_IS_FLYING, // Control + OPTIONS_BLOCK_OUTLINE, OPTIONS_USE_MOUSE_FOR_DIGGING, OPTIONS_IS_LEFT_HANDED, OPTIONS_IS_JOY_TOUCH_AREA, @@ -87,6 +89,7 @@ enum OptionId { OPTIONS_FOLIAGE_TINT, OPTIONS_FOG_TYPE, OPTIONS_JAVA_HUD, + OPTIONS_RESTORED_ANIMS, // Should be last! OPTIONS_COUNT }; diff --git a/src/client/gui/Gui.cpp b/src/client/gui/Gui.cpp index 0c5646e..c6e786a 100755 --- a/src/client/gui/Gui.cpp +++ b/src/client/gui/Gui.cpp @@ -382,6 +382,7 @@ void Gui::renderVignette(float br, int w, int h) { void Gui::renderSlot(int slot, int x, int y, float a) { ItemInstance* item = minecraft->player->inventory->getItem(slot); + if (!item) { //LOGW("Warning: item @ Gui::renderSlot is NULL\n"); return; @@ -595,8 +596,11 @@ void Gui::renderProgressIndicator( const bool isTouchInterface, const int screen ItemInstance* currentItem = minecraft->player->inventory->getSelected(); bool bowEquipped = currentItem != NULL ? currentItem->getItem() == Item::bow : false; bool itemInUse = currentItem != NULL ? currentItem->getItem() == minecraft->player->getUseItem()->getItem() : false; + //if ((!isTouchInterface || minecraft->options.getBooleanValue(OPTIONS_IS_JOY_TOUCH_AREA) + // || (bowEquipped && itemInUse)) && !minecraft->options.getBooleanValue(OPTIONS_HIDEGUI)) if ((!isTouchInterface || minecraft->options.getBooleanValue(OPTIONS_IS_JOY_TOUCH_AREA) - || (bowEquipped && itemInUse)) && !minecraft->options.getBooleanValue(OPTIONS_HIDEGUI)) { +|| (bowEquipped && itemInUse)) && !minecraft->options.getBooleanValue(OPTIONS_HIDEGUI)) + { minecraft->textures->loadAndBindTexture("gui/icons.png"); glEnable(GL_BLEND); glBlendFunc2(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR); diff --git a/src/client/gui/components/OptionsItem.cpp b/src/client/gui/components/OptionsItem.cpp index 1ee48e3..b9d5bbb 100755 --- a/src/client/gui/components/OptionsItem.cpp +++ b/src/client/gui/components/OptionsItem.cpp @@ -36,6 +36,16 @@ void OptionsItem::render( Minecraft* minecraft, int xm, int ym ) { } text += ": " + scaleText; } + if (m_optionId == OPTIONS_FOG_TYPE) { + int value = minecraft->options.getIntValue(OPTIONS_FOG_TYPE); + std::string scaleText; + switch (value) { + case 0: scaleText = I18n::get("options.fogType.vanilla"); break; + case 1: scaleText = I18n::get("options.fogType.java"); break; + case 2: scaleText = I18n::get("options.fogType.unused"); break; + } + text += ": " + scaleText; + } minecraft->font->draw(text, (float)x, (float)y + yOffset, 0x909090, false); super::render(minecraft, xm, ym); diff --git a/src/client/gui/screens/CreditsScreen.cpp b/src/client/gui/screens/CreditsScreen.cpp index 02114da..f0820af 100644 --- a/src/client/gui/screens/CreditsScreen.cpp +++ b/src/client/gui/screens/CreditsScreen.cpp @@ -41,6 +41,7 @@ void CreditsScreen::init() { _lines.push_back("karson"); _lines.push_back("deepfriedwaffles"); _lines.push_back("EpikIzCool"); + _lines.push_back("fileshredder"); _lines.push_back(""); // avoid color tags around the URL so it isn't mangled by the parser please _lines.push_back("Join our Discord server: https://discord.gg/c58YesBxve"); diff --git a/src/client/gui/screens/IngameBlockSelectionScreen.cpp b/src/client/gui/screens/IngameBlockSelectionScreen.cpp index 863b1f8..c1b72c7 100755 --- a/src/client/gui/screens/IngameBlockSelectionScreen.cpp +++ b/src/client/gui/screens/IngameBlockSelectionScreen.cpp @@ -1,5 +1,6 @@ #include "IngameBlockSelectionScreen.h" #include "../../renderer/TileRenderer.h" +#include "../../renderer/Lighting.h" #include "../../player/LocalPlayer.h" #include "../../renderer/gles.h" #include "../../Minecraft.h" @@ -80,10 +81,10 @@ void IngameBlockSelectionScreen::renderSlots() blitOffset = -90; - //glEnable2(GL_RESCALE_NORMAL); + glEnable2(GL_RESCALE_NORMAL); //glPushMatrix2(); //glRotatef2(180, 1, 0, 0); - //Lighting::turnOn(); + Lighting::turnOn(minecraft); //glPopMatrix2(); minecraft->textures->loadAndBindTexture("gui/gui.png"); @@ -122,8 +123,8 @@ void IngameBlockSelectionScreen::renderSlots() //w.stop(); //w.printEvery(1000, "render-blocksel"); - //glDisable2(GL_RESCALE_NORMAL); - //Lighting::turnOn(); + glDisable2(GL_RESCALE_NORMAL); + Lighting::turnOn(minecraft); } int IngameBlockSelectionScreen::getSlotPosX(int slotX) { diff --git a/src/client/gui/screens/OptionsScreen.cpp b/src/client/gui/screens/OptionsScreen.cpp index ce5db38..88fbb63 100755 --- a/src/client/gui/screens/OptionsScreen.cpp +++ b/src/client/gui/screens/OptionsScreen.cpp @@ -208,7 +208,9 @@ void OptionsScreen::generateOptionScreens() { // // Controls Pane optionPanes[2]->addOptionItem(OPTIONS_INVERT_Y_MOUSE, minecraft) .addOptionItem(OPTIONS_USE_TOUCHSCREEN, minecraft) - .addOptionItem(OPTIONS_AUTOJUMP, minecraft); + .addOptionItem(OPTIONS_AUTOJUMP, minecraft) + .addOptionItem(OPTIONS_BLOCK_OUTLINE, minecraft) + .addOptionItem(OPTIONS_IS_JOY_TOUCH_AREA, minecraft); for (int i = OPTIONS_KEY_FORWARD; i <= OPTIONS_KEY_USE; i++) { optionPanes[2]->addOptionItem((OptionId)i, minecraft); @@ -224,14 +226,16 @@ void OptionsScreen::generateOptionScreens() { .addOptionItem(OPTIONS_RENDER_DEBUG, minecraft) .addOptionItem(OPTIONS_ANAGLYPH_3D, minecraft) .addOptionItem(OPTIONS_VIEW_BOBBING, minecraft) - .addOptionItem(OPTIONS_AMBIENT_OCCLUSION, minecraft); + .addOptionItem(OPTIONS_AMBIENT_OCCLUSION, minecraft) + .addOptionItem(OPTIONS_NORMAL_LIGHTING, minecraft); optionPanes[4]->addOptionItem(OPTIONS_ALLOW_SPRINT, minecraft) .addOptionItem(OPTIONS_BAR_ON_TOP, minecraft) .addOptionItem(OPTIONS_RPI_CURSOR, minecraft) .addOptionItem(OPTIONS_FOLIAGE_TINT, minecraft) .addOptionItem(OPTIONS_JAVA_HUD, minecraft) - .addOptionItem(OPTIONS_FOG_TYPE, minecraft); + .addOptionItem(OPTIONS_FOG_TYPE, minecraft) + .addOptionItem(OPTIONS_RESTORED_ANIMS, minecraft); } diff --git a/src/client/model/geom/ModelPart.cpp b/src/client/model/geom/ModelPart.cpp index 7fa8f70..86ab82c 100755 --- a/src/client/model/geom/ModelPart.cpp +++ b/src/client/model/geom/ModelPart.cpp @@ -203,7 +203,7 @@ void ModelPart::compile( float scale ) void ModelPart::draw() { #ifdef OPENGL_ES - drawArrayVT_NoState(vboId, cubes.size() * 2 * 3 * 6, 24); + drawArrayVTN_NoState(vboId, cubes.size() * 2 * 3 * 6, 28); #else glCallList(list); #endif diff --git a/src/client/model/geom/Polygon.cpp b/src/client/model/geom/Polygon.cpp index bfb1467..b826f39 100755 --- a/src/client/model/geom/Polygon.cpp +++ b/src/client/model/geom/Polygon.cpp @@ -43,6 +43,18 @@ void PolygonQuad::mirror() { } void PolygonQuad::render(Tesselator& t, float scale, int vboId /* = -1 */) { + Vec3 v0 = vertices[0].pos - vertices[1].pos; + Vec3 v1 = vertices[2].pos - vertices[1].pos; + Vec3 n = v1.cross(v0).normalized(); + if (_flipNormal == true) + { + t.normal(-n.x , -n.y , -n.z ); + } + else + { + t.normal(n.x , n.y , n.z ); + } + for (int i = 0; i < 4; i++) { VertexPT& v = vertices[i]; t.vertexUV(v.pos.x * scale, v.pos.y * scale, v.pos.z * scale, v.u, v.v); diff --git a/src/client/renderer/GameRenderer.cpp b/src/client/renderer/GameRenderer.cpp index 1aa6a15..aab7f2a 100755 --- a/src/client/renderer/GameRenderer.cpp +++ b/src/client/renderer/GameRenderer.cpp @@ -1,7 +1,7 @@ #include "GameRenderer.h" #include "client/Options.h" #include "gles.h" - +#include "Lighting.h" #include "../../util/PerfTimer.h" #include "LevelRenderer.h" @@ -32,7 +32,7 @@ static int _shTicks = -1; GameRenderer::GameRenderer( Minecraft* mc ) -: mc(mc), + : mc(mc), renderDistance(0), _tick(0), _lastTickT(0), @@ -90,32 +90,32 @@ void renderCursor(float x, float y, Minecraft* minecraft) { /*private*/ void GameRenderer::setupCamera(float a, int eye) { - renderDistance = (float) (16 * 16 >> (mc->options.getIntValue(OPTIONS_VIEW_DISTANCE))); + renderDistance = (float) (16 * 16 >> (mc->options.getIntValue(OPTIONS_VIEW_DISTANCE))); #if defined(ANDROID) - if (mc->isPowerVR() && mc->options.getIntValue(OPTIONS_VIEW_DISTANCE) <= 2) + if (mc->isPowerVR() && mc->options.getIntValue(OPTIONS_VIEW_DISTANCE) <= 2) renderDistance *= 0.8f; #endif glMatrixMode(GL_PROJECTION); - glLoadIdentity2(); + glLoadIdentity2(); - float stereoScale = 0.07f; - if (mc->options.getBooleanValue(OPTIONS_ANAGLYPH_3D)) glTranslatef2(-(eye * 2 - 1) * stereoScale, 0, 0); - if (zoom != 1) { - glTranslatef2((float) zoom_x, (float) -zoom_y, 0); + float stereoScale = 0.07f; + if (mc->options.getBooleanValue(OPTIONS_ANAGLYPH_3D)) glTranslatef2(-(eye * 2 - 1) * stereoScale, 0, 0); + if (zoom != 1) { + glTranslatef2((float) zoom_x, (float) -zoom_y, 0); glScalef2(zoom, zoom, 1); - gluPerspective(_setupCameraFov = getFov(a, true), mc->width / (float) mc->height, 0.05f, renderDistance); - } else { - gluPerspective(_setupCameraFov = getFov(a, true), mc->width / (float) mc->height, 0.05f, renderDistance); - } + gluPerspective(_setupCameraFov = getFov(a, true), mc->width / (float) mc->height, 0.05f, renderDistance); + } else { + gluPerspective(_setupCameraFov = getFov(a, true), mc->width / (float) mc->height, 0.05f, renderDistance); + } - glMatrixMode(GL_MODELVIEW); - glLoadIdentity2(); - if (mc->options.getBooleanValue(OPTIONS_ANAGLYPH_3D)) glTranslatef2((eye * 2 - 1) * 0.10f, 0, 0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity2(); + if (mc->options.getBooleanValue(OPTIONS_ANAGLYPH_3D)) glTranslatef2((eye * 2 - 1) * 0.10f, 0, 0); + + bobHurt(a); + if (mc->options.getBooleanValue(OPTIONS_VIEW_BOBBING)) bobView(a); - bobHurt(a); - if (mc->options.getBooleanValue(OPTIONS_VIEW_BOBBING)) bobView(a); - moveCameraToPlayer(a); } @@ -125,13 +125,13 @@ extern int _t_keepPic; void GameRenderer::render(float a) { TIMER_PUSH("mouse"); if (mc->player && mc->mouseGrabbed) { - mc->mouseHandler.poll(); - //printf("Controller.x,y : %f,%f\n", Controller::getX(0), Controller::getY(0)); + mc->mouseHandler.poll(); + //printf("Controller.x,y : %f,%f\n", Controller::getX(0), Controller::getY(0)); - float ss = mc->options.getProgressValue(OPTIONS_SENSITIVITY) * 0.6f + 0.2f; - float sens = (ss * ss * ss) * 8; - float xo = mc->mouseHandler.xd * sens * 4.f; - float yo = mc->mouseHandler.yd * sens * 4.f; + float ss = mc->options.getProgressValue(OPTIONS_SENSITIVITY) * 0.6f + 0.2f; + float sens = (ss * ss * ss) * 8; + float xo = mc->mouseHandler.xd * sens * 4.f; + float yo = mc->mouseHandler.yd * sens * 4.f; const float now = _tick + a; float deltaT = now - _lastTickT; @@ -141,20 +141,20 @@ void GameRenderer::render(float a) { _rotX += xo; _rotY += yo; - int yAxis = -1; - if (mc->options.getBooleanValue(OPTIONS_INVERT_Y_MOUSE)) yAxis = 1; + int yAxis = -1; + if (mc->options.getBooleanValue(OPTIONS_INVERT_Y_MOUSE)) yAxis = 1; bool screenCovering = mc->screen && !mc->screen->passEvents; if (!screenCovering) { mc->player->turn(deltaT * _rotXlast, deltaT * _rotYlast * yAxis); } - } + } int xMouse = (int)(Mouse::getX() * Gui::InvGuiScale); int yMouse = (int)(Mouse::getY() * Gui::InvGuiScale); - if (mc->useTouchscreen()) { + if (mc->useTouchscreen()) { const int pid = Multitouch::getFirstActivePointerIdExThisUpdate(); if (pid >= 0) { xMouse = (int)(Multitouch::getX(pid) * Gui::InvGuiScale); @@ -173,33 +173,33 @@ void GameRenderer::render(float a) { TIMER_PUSH("level"); if (_t_keepPic < 0) { - if (!(mc->screen && !mc->screen->renderGameBehind())) { + if (!(mc->screen && !mc->screen->renderGameBehind())) { - if (mc->screen && mc->screen->hasClippingArea(screenScissorArea)) - useScreenScissor = true; + if (mc->screen && mc->screen->hasClippingArea(screenScissorArea)) + useScreenScissor = true; - renderLevel(a); - hasClearedColorBuffer = true; + renderLevel(a); + hasClearedColorBuffer = true; - if (!mc->options.getBooleanValue(OPTIONS_HIDEGUI)) { - TIMER_POP_PUSH("gui"); - setupGuiScreen(false); - hasSetupGuiScreen = true; - mc->gui.render(a, mc->screen != NULL, xMouse, yMouse); - } - }} + if (!mc->options.getBooleanValue(OPTIONS_HIDEGUI)) { + TIMER_POP_PUSH("gui"); + setupGuiScreen(false); + hasSetupGuiScreen = true; + mc->gui.render(a, mc->screen != NULL, xMouse, yMouse); + } + }} TIMER_POP(); } else { - glViewport(0, 0, mc->width, mc->height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity2(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity2(); - setupGuiScreen(true); + glViewport(0, 0, mc->width, mc->height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity2(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity2(); + setupGuiScreen(true); hasSetupGuiScreen = true; hasClearedColorBuffer = true; - } + } //@todo if (!hasSetupGuiScreen) setupGuiScreen(!hasClearedColorBuffer); @@ -209,26 +209,26 @@ void GameRenderer::render(float a) { if (mc->player->input) mc->player->input->render(a); } - if (mc->screen != NULL) { + if (mc->screen != NULL) { if (useScreenScissor) glDisable2(GL_SCISSOR_TEST); mc->screen->render(xMouse, yMouse, a); - mc->platform()->hideCursor(!mc->options.getBooleanValue(OPTIONS_RPI_CURSOR)); - if (mc->options.getBooleanValue(OPTIONS_RPI_CURSOR)) - renderCursor(xMouse, yMouse, mc); - - // Screen might have been removed, so check it again - if (mc->screen && !mc->screen->isInGameScreen()) - sleepMs(15); - } + mc->platform()->hideCursor(!mc->options.getBooleanValue(OPTIONS_RPI_CURSOR)); + if (mc->options.getBooleanValue(OPTIONS_RPI_CURSOR)) + renderCursor(xMouse, yMouse, mc); + + // Screen might have been removed, so check it again + if (mc->screen && !mc->screen->isInGameScreen()) + sleepMs(15); + } } /*public*/ void GameRenderer::renderLevel(float a) { - if (mc->cameraTargetPlayer == NULL) { + if (mc->cameraTargetPlayer == NULL) { if (mc->player) { mc->cameraTargetPlayer = mc->player; @@ -237,156 +237,162 @@ void GameRenderer::renderLevel(float a) { { return; } - } + } TIMER_PUSH("pick"); - pick(a); + pick(a); - Mob* cameraEntity = mc->cameraTargetPlayer; - LevelRenderer* levelRenderer = mc->levelRenderer; - ParticleEngine* particleEngine = mc->particleEngine; - float xOff = cameraEntity->xOld + (cameraEntity->x - cameraEntity->xOld) * a; - float yOff = cameraEntity->yOld + (cameraEntity->y - cameraEntity->yOld) * a; - float zOff = cameraEntity->zOld + (cameraEntity->z - cameraEntity->zOld) * a; + Mob* cameraEntity = mc->cameraTargetPlayer; + LevelRenderer* levelRenderer = mc->levelRenderer; + ParticleEngine* particleEngine = mc->particleEngine; + float xOff = cameraEntity->xOld + (cameraEntity->x - cameraEntity->xOld) * a; + float yOff = cameraEntity->yOld + (cameraEntity->y - cameraEntity->yOld) * a; + float zOff = cameraEntity->zOld + (cameraEntity->z - cameraEntity->zOld) * a; - for (int i = 0; i < 2; i++) { - if (mc->options.getBooleanValue(OPTIONS_ANAGLYPH_3D)) { - if (i == 0) glColorMask(false, true, true, false); - else glColorMask(true, false, false, false); - } + for (int i = 0; i < 2; i++) { + if (mc->options.getBooleanValue(OPTIONS_ANAGLYPH_3D)) { + if (i == 0) glColorMask(false, true, true, false); + else glColorMask(true, false, false, false); + } TIMER_POP_PUSH("clear"); glViewport(0, 0, mc->width, mc->height); setupClearColor(a); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnable2(GL_CULL_FACE); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable2(GL_CULL_FACE); TIMER_POP_PUSH("camera"); - setupCamera(a, i); + setupCamera(a, i); saveMatrices(); if (useScreenScissor) { glEnable2(GL_SCISSOR_TEST); glScissor( screenScissorArea.x, screenScissorArea.y, - screenScissorArea.w, screenScissorArea.h); + screenScissorArea.w, screenScissorArea.h); } - - if(mc->options.getBooleanValue(OPTIONS_FANCY_GRAPHICS)) { + + if(mc->options.getBooleanValue(OPTIONS_FANCY_GRAPHICS)) { setupFog(-1); TIMER_POP_PUSH("sky"); glFogf(GL_FOG_START, renderDistance * 0.2f); glFogf(GL_FOG_END, renderDistance *0.75); - levelRenderer->renderSky(a); + levelRenderer->renderSky(a); glFogf(GL_FOG_START, renderDistance * 0.6f); glFogf(GL_FOG_END, renderDistance); - } - glEnable2(GL_FOG); - setupFog(1); - - if (mc->options.getBooleanValue(OPTIONS_AMBIENT_OCCLUSION)) { - glShadeModel2(GL_SMOOTH); } - + glEnable2(GL_FOG); + setupFog(1); + + if (mc->options.getBooleanValue(OPTIONS_AMBIENT_OCCLUSION)) { + glShadeModel2(GL_SMOOTH); + } + TIMER_POP_PUSH("frustrum"); FrustumCuller frustum; - frustum.prepare(xOff, yOff, zOff); + frustum.prepare(xOff, yOff, zOff); TIMER_POP_PUSH("culling"); - mc->levelRenderer->cull(&frustum, a); - mc->levelRenderer->updateDirtyChunks(cameraEntity, false); + mc->levelRenderer->cull(&frustum, a); + mc->levelRenderer->updateDirtyChunks(cameraEntity, false); if(mc->options.getBooleanValue(OPTIONS_FANCY_GRAPHICS)) { prepareAndRenderClouds(levelRenderer, a); } - setupFog(0); - glEnable2(GL_FOG); + setupFog(0); + glEnable2(GL_FOG); mc->textures->loadAndBindTexture("terrain.png"); - glDisable2(GL_ALPHA_TEST); - glDisable2(GL_BLEND); - glEnable2(GL_CULL_FACE); + Lighting::turnOff(); + + glDisable2(GL_ALPHA_TEST); + glDisable2(GL_BLEND); + glEnable2(GL_CULL_FACE); TIMER_POP_PUSH("terrain-0"); - levelRenderer->render(cameraEntity, 0, a); + levelRenderer->render(cameraEntity, 0, a); TIMER_POP_PUSH("terrain-1"); - glEnable2(GL_ALPHA_TEST); - levelRenderer->render(cameraEntity, 1, a); - - glShadeModel2(GL_FLAT); + glEnable2(GL_ALPHA_TEST); + levelRenderer->render(cameraEntity, 1, a); + + glShadeModel2(GL_FLAT); + Lighting::turnOn(mc); TIMER_POP_PUSH("entities"); mc->levelRenderer->renderEntities(cameraEntity->getPos(a), &frustum, a); -// setupFog(0); + // setupFog(0); TIMER_POP_PUSH("particles"); - particleEngine->render(cameraEntity, a); - + particleEngine->render(cameraEntity, a); + Lighting::turnOff(); glDisable2(GL_BLEND); - glBlendFunc2(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - setupFog(0); - glEnable2(GL_BLEND); - glDisable2(GL_CULL_FACE); + glBlendFunc2(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + setupFog(0); + glEnable2(GL_BLEND); + glDisable2(GL_CULL_FACE); glDepthMask(GL_FALSE); - glDisable2(GL_ALPHA_TEST); + glDisable2(GL_ALPHA_TEST); mc->textures->loadAndBindTexture("terrain.png"); - //if (mc->options.fancyGraphics) { - // glColorMask(false, false, false, false); - // int visibleWaterChunks = levelRenderer->render(cameraEntity, 1, a); - // glColorMask(true, true, true, true); - // if (mc->options.anaglyph3d) { - // if (i == 0) glColorMask(false, true, true, false); - // else glColorMask(true, false, false, false); - // } - // if (visibleWaterChunks > 0) { - // levelRenderer->renderSameAsLast(1, a); - // } - //} else + //if (mc->options.fancyGraphics) { + // glColorMask(false, false, false, false); + // int visibleWaterChunks = levelRenderer->render(cameraEntity, 1, a); + // glColorMask(true, true, true, true); + // if (mc->options.anaglyph3d) { + // if (i == 0) glColorMask(false, true, true, false); + // else glColorMask(true, false, false, false); + // } + // if (visibleWaterChunks > 0) { + // levelRenderer->renderSameAsLast(1, a); + // } + //} else { //glDepthRangef(0.1f, 1.0f); //glDepthMask(GL_FALSE); TIMER_POP_PUSH("terrain-water"); glEnable2(GL_DEPTH_TEST); - levelRenderer->render(cameraEntity, 2, a); + levelRenderer->render(cameraEntity, 2, a); //glDepthRangef(0, 1); - } - + } + glDepthMask(GL_TRUE); - glEnable2(GL_CULL_FACE); - glDisable2(GL_BLEND); - glEnable2(GL_ALPHA_TEST); + glEnable2(GL_CULL_FACE); + glDisable2(GL_BLEND); + glEnable2(GL_ALPHA_TEST); if (/*!Minecraft::FLYBY_MODE &&*/ zoom == 1 && cameraEntity->isPlayer()) { if (mc->hitResult.isHit() && !cameraEntity->isUnderLiquid(Material::water)) { TIMER_POP_PUSH("select"); Player* player = (Player*) cameraEntity; // if (mc->useTouchscreen()) { - levelRenderer->renderHitSelect(player, mc->hitResult, 0, NULL, a); //player.inventory->getSelected(), a); - // } + if (mc->options.getBooleanValue(OPTIONS_BLOCK_OUTLINE)){ + levelRenderer->renderHitOutline(player, mc->hitResult, 0, NULL, a); //player.inventory->getSelected(), a); // java block outline one + } else { + levelRenderer->renderHitSelect(player, mc->hitResult, 0, NULL, a); //player.inventory->getSelected(), a); // normal pe one - shredder + } levelRenderer->renderHit(player, mc->hitResult, 0, NULL, a);//player->inventory.getSelected(), a); } } glDisable2(GL_FOG); -// -// setupFog(0); -// glEnable2(GL_FOG); -//// levelRenderer->renderClouds(a); -// glDisable2(GL_FOG); - setupFog(1); + // + // setupFog(0); + // glEnable2(GL_FOG); + //// levelRenderer->renderClouds(a); + // glDisable2(GL_FOG); + setupFog(1); - if (zoom == 1 && !mc->options.getBooleanValue(OPTIONS_HIDEGUI)) { + if (zoom == 1 && !mc->options.getBooleanValue(OPTIONS_HIDEGUI)) { TIMER_POP_PUSH("hand"); - glClear(GL_DEPTH_BUFFER_BIT); - renderItemInHand(a, i); - } + glClear(GL_DEPTH_BUFFER_BIT); + renderItemInHand(a, i); + } - if (!mc->options.getBooleanValue(OPTIONS_ANAGLYPH_3D)) { + if (!mc->options.getBooleanValue(OPTIONS_ANAGLYPH_3D)) { TIMER_POP(); - return; - } - } - glColorMask(true, true, true, false); + return; + } + } + glColorMask(true, true, true, false); TIMER_POP(); } @@ -400,34 +406,34 @@ void GameRenderer::tickFov() { /*private*/ float GameRenderer::getFov(float a, bool applyEffects) { - Mob* player = mc->cameraTargetPlayer; - float fov = 70; + Mob* player = mc->cameraTargetPlayer; + float fov = 70; if (applyEffects) fov *= this->oFov + (this->fov - this->oFov) * a; - if (player->isUnderLiquid(Material::water)) fov = 60; - if (player->health <= 0) { - float duration = player->deathTime + a; + if (player->isUnderLiquid(Material::water)) fov = 60; + if (player->health <= 0) { + float duration = player->deathTime + a; - fov /= ((1 - 500 / (duration + 500)) * 2.0f + 1); - } - return fov + fovOffsetO + (fovOffset - fovOffsetO) * a; + fov /= ((1 - 500 / (duration + 500)) * 2.0f + 1); + } + return fov + fovOffsetO + (fovOffset - fovOffsetO) * a; } /*private*/ void GameRenderer::moveCameraToPlayer(float a) { - Entity* player = mc->cameraTargetPlayer; + Entity* player = mc->cameraTargetPlayer; - float heightOffset = player->heightOffset - 1.62f; + float heightOffset = player->heightOffset - 1.62f; - float x = player->xo + (player->x - player->xo) * a; - float y = player->yo + (player->y - player->yo) * a - heightOffset; + float x = player->xo + (player->x - player->xo) * a; + float y = player->yo + (player->y - player->yo) * a - heightOffset; //printf("camera y: %f\n", y); - float z = player->zo + (player->z - player->zo) * a; + float z = player->zo + (player->z - player->zo) * a; //printf("rot: %f %f\n", cameraRollO, cameraRoll); - glRotatef2(cameraRollO + (cameraRoll - cameraRollO) * a, 0, 0, 1); + glRotatef2(cameraRollO + (cameraRoll - cameraRollO) * a, 0, 0, 1); //LOGI("player. alive, removed: %d, %d\n", player->isAlive(), player->removed); if(player->isPlayer() && ((Player*)player)->isSleeping()) { @@ -445,282 +451,282 @@ void GameRenderer::moveCameraToPlayer(float a) { glRotatef(player->xRotO + (player->xRot - player->xRotO) * a, -1, 0, 0); } } else if (mc->options.getBooleanValue(OPTIONS_THIRD_PERSON_VIEW)/* || (player->isPlayer() && !player->isAlive())*/) { - float cameraDist = thirdDistanceO + (thirdDistance - thirdDistanceO) * a; + float cameraDist = thirdDistanceO + (thirdDistance - thirdDistanceO) * a; - if (mc->options.getBooleanValue(OPTIONS_FIXED_CAMERA)) { + if (mc->options.getBooleanValue(OPTIONS_FIXED_CAMERA)) { - float rotationY = thirdRotationO + (thirdRotation - thirdRotationO) * a; - float xRot = thirdTiltO + (thirdTilt - thirdTiltO) * a; + float rotationY = thirdRotationO + (thirdRotation - thirdRotationO) * a; + float xRot = thirdTiltO + (thirdTilt - thirdTiltO) * a; - glTranslatef2(0, 0, (float) -cameraDist); - glRotatef2(xRot, 1, 0, 0); - glRotatef2(rotationY, 0, 1, 0); - } else { - float yRot = player->yRot; - float xRot = player->xRot/* + 180.0f*/; - float xd = -Mth::sin(yRot / 180 * Mth::PI) * Mth::cos(xRot / 180 * Mth::PI) * cameraDist; - float zd = Mth::cos(yRot / 180 * Mth::PI) * Mth::cos(xRot / 180 * Mth::PI) * cameraDist; - float yd = -Mth::sin(xRot / 180 * Mth::PI) * cameraDist; + glTranslatef2(0, 0, (float) -cameraDist); + glRotatef2(xRot, 1, 0, 0); + glRotatef2(rotationY, 0, 1, 0); + } else { + float yRot = player->yRot; + float xRot = player->xRot/* + 180.0f*/; + float xd = -Mth::sin(yRot / 180 * Mth::PI) * Mth::cos(xRot / 180 * Mth::PI) * cameraDist; + float zd = Mth::cos(yRot / 180 * Mth::PI) * Mth::cos(xRot / 180 * Mth::PI) * cameraDist; + float yd = -Mth::sin(xRot / 180 * Mth::PI) * cameraDist; - for (int i = 0; i < 8; i++) { - float xo = (float)((i & 1) * 2 - 1); - float yo = (float)(((i >> 1) & 1) * 2 - 1); - float zo = (float)(((i >> 2) & 1) * 2 - 1); + for (int i = 0; i < 8; i++) { + float xo = (float)((i & 1) * 2 - 1); + float yo = (float)(((i >> 1) & 1) * 2 - 1); + float zo = (float)(((i >> 2) & 1) * 2 - 1); - xo *= 0.1f; - yo *= 0.1f; - zo *= 0.1f; + xo *= 0.1f; + yo *= 0.1f; + zo *= 0.1f; - HitResult hr = mc->level->clip(Vec3(x + xo, y + yo, z + zo), Vec3(x - xd + xo + zo, y - yd + yo, z - zd + zo)); // newTemp + HitResult hr = mc->level->clip(Vec3(x + xo, y + yo, z + zo), Vec3(x - xd + xo + zo, y - yd + yo, z - zd + zo)); // newTemp if (hr.type != NO_HIT) { - float dist = hr.pos.distanceTo(Vec3(x, y, z)); // newTemp - if (dist < cameraDist) cameraDist = dist; - } - } + float dist = hr.pos.distanceTo(Vec3(x, y, z)); // newTemp + if (dist < cameraDist) cameraDist = dist; + } + } //glRotatef2(180, 0, 1, 0); glRotatef2(player->xRot - xRot, 1, 0, 0); - glRotatef2(player->yRot - yRot, 0, 1, 0); - glTranslatef2(0, 0, (float) -cameraDist); - glRotatef2(yRot - player->yRot, 0, 1, 0); - glRotatef2(xRot - player->xRot, 1, 0, 0); - } - } else { - glTranslatef2(0, 0, -0.1f); - } + glRotatef2(player->yRot - yRot, 0, 1, 0); + glTranslatef2(0, 0, (float) -cameraDist); + glRotatef2(yRot - player->yRot, 0, 1, 0); + glRotatef2(xRot - player->xRot, 1, 0, 0); + } + } else { + glTranslatef2(0, 0, -0.1f); + } - if (!mc->options.getBooleanValue(OPTIONS_FIXED_CAMERA)) { - glRotatef2(player->xRotO + (player->xRot - player->xRotO) * a, 1.0f, 0.0f, 0.0f); - glRotatef2(player->yRotO + (player->yRot - player->yRotO) * a + 180, 0, 1, 0); + if (!mc->options.getBooleanValue(OPTIONS_FIXED_CAMERA)) { + glRotatef2(player->xRotO + (player->xRot - player->xRotO) * a, 1.0f, 0.0f, 0.0f); + glRotatef2(player->yRotO + (player->yRot - player->yRotO) * a + 180, 0, 1, 0); //if (_t_keepPic > 0) } - glTranslatef2(0, heightOffset, 0); + glTranslatef2(0, heightOffset, 0); } /*private*/ void GameRenderer::bobHurt(float a) { - Mob* player = mc->cameraTargetPlayer; + Mob* player = mc->cameraTargetPlayer; - float hurt = player->hurtTime - a; + float hurt = player->hurtTime - a; - if (player->health <= 0) { - float duration = player->deathTime + a; - glRotatef2(40 - (40 * 200) / (duration + 200), 0, 0, 1); - } + if (player->health <= 0) { + float duration = player->deathTime + a; + glRotatef2(40 - (40 * 200) / (duration + 200), 0, 0, 1); + } - if (player->hurtTime <= 0) return; + if (player->hurtTime <= 0) return; hurt /= player->hurtDuration; - hurt = (float) Mth::sin(hurt * hurt * hurt * hurt * Mth::PI); + hurt = (float) Mth::sin(hurt * hurt * hurt * hurt * Mth::PI); - float rr = player->hurtDir; + float rr = player->hurtDir; - glRotatef2(-rr, 0, 1, 0); - glRotatef2(-hurt * 14, 0, 0, 1); - glRotatef2(+rr, 0, 1, 0); + glRotatef2(-rr, 0, 1, 0); + glRotatef2(-hurt * 14, 0, 0, 1); + glRotatef2(+rr, 0, 1, 0); } /*private*/ void GameRenderer::bobView(float a) { - //if (mc->options.thirdPersonView) return; + //if (mc->options.thirdPersonView) return; if (!(mc->cameraTargetPlayer->isPlayer())) { - return; - } - Player* player = (Player*) mc->cameraTargetPlayer; + return; + } + Player* player = (Player*) mc->cameraTargetPlayer; - float wda = player->walkDist - player->walkDistO; - float b = -(player->walkDist + wda * a); - float bob = player->oBob + (player->bob - player->oBob) * a; - float tilt = player->oTilt + (player->tilt - player->oTilt) * a; - glTranslatef2((float) Mth::sin(b * Mth::PI) * bob * 0.5f, -(float) std::abs(Mth::cos(b * Mth::PI) * bob), 0); - glRotatef2((float) Mth::sin(b * Mth::PI) * bob * 3, 0, 0, 1); - glRotatef2((float) std::abs(Mth::cos(b * Mth::PI - 0.2f) * bob) * 5, 1, 0, 0); - glRotatef2((float) tilt, 1, 0, 0); + float wda = player->walkDist - player->walkDistO; + float b = -(player->walkDist + wda * a); + float bob = player->oBob + (player->bob - player->oBob) * a; + float tilt = player->oTilt + (player->tilt - player->oTilt) * a; + glTranslatef2((float) Mth::sin(b * Mth::PI) * bob * 0.5f, -(float) std::abs(Mth::cos(b * Mth::PI) * bob), 0); + glRotatef2((float) Mth::sin(b * Mth::PI) * bob * 3, 0, 0, 1); + glRotatef2((float) std::abs(Mth::cos(b * Mth::PI - 0.2f) * bob) * 5, 1, 0, 0); + glRotatef2((float) tilt, 1, 0, 0); } /*private*/ void GameRenderer::setupFog(int i) { - Mob* player = mc->cameraTargetPlayer; + Mob* player = mc->cameraTargetPlayer; float fogBuffer[4] = {fr, fg, fb, 1}; - glFogfv(GL_FOG_COLOR, (GLfloat*)fogBuffer); - glColor4f2(1, 1, 1, 1); + glFogfv(GL_FOG_COLOR, (GLfloat*)fogBuffer); + glColor4f2(1, 1, 1, 1); - if (player->isUnderLiquid(Material::water)) { - glFogx(GL_FOG_MODE, GL_EXP); - glFogf(GL_FOG_DENSITY, 0.1f); // was 0.06 + if (player->isUnderLiquid(Material::water)) { + glFogx(GL_FOG_MODE, GL_EXP); + glFogf(GL_FOG_DENSITY, 0.1f); // was 0.06 -// float rr = 0.4f; -// float gg = 0.4f; -// float bb = 0.9f; -// -// if (mc->options.anaglyph3d) { -// float rrr = (rr * 30 + gg * 59 + bb * 11) / 100; -// float ggg = (rr * 30 + gg * 70) / (100); -// float bbb = (rr * 30 + bb * 70) / (100); -// -// rr = rrr; -// gg = ggg; -// bb = bbb; -// } - } else if (player->isUnderLiquid(Material::lava)) { - glFogx(GL_FOG_MODE, GL_EXP); - glFogf(GL_FOG_DENSITY, 2.f); // was 0.06 -// float rr = 0.4f; -// float gg = 0.3f; -// float bb = 0.3f; -// -// if (mc->options.anaglyph3d) { -// float rrr = (rr * 30 + gg * 59 + bb * 11) / 100; -// float ggg = (rr * 30 + gg * 70) / (100); -// float bbb = (rr * 30 + bb * 70) / (100); -// -// rr = rrr; -// gg = ggg; -// bb = bbb; -// } - } else { - glFogx(GL_FOG_MODE, GL_LINEAR); - glFogf(GL_FOG_START, renderDistance * 0.6f); - glFogf(GL_FOG_END, renderDistance); - if (i < 0) { - glFogf(GL_FOG_START, 0); - glFogf(GL_FOG_END, renderDistance * 1.0f); - } + // float rr = 0.4f; + // float gg = 0.4f; + // float bb = 0.9f; + // + // if (mc->options.anaglyph3d) { + // float rrr = (rr * 30 + gg * 59 + bb * 11) / 100; + // float ggg = (rr * 30 + gg * 70) / (100); + // float bbb = (rr * 30 + bb * 70) / (100); + // + // rr = rrr; + // gg = ggg; + // bb = bbb; + // } + } else if (player->isUnderLiquid(Material::lava)) { + glFogx(GL_FOG_MODE, GL_EXP); + glFogf(GL_FOG_DENSITY, 2.f); // was 0.06 + // float rr = 0.4f; + // float gg = 0.3f; + // float bb = 0.3f; + // + // if (mc->options.anaglyph3d) { + // float rrr = (rr * 30 + gg * 59 + bb * 11) / 100; + // float ggg = (rr * 30 + gg * 70) / (100); + // float bbb = (rr * 30 + bb * 70) / (100); + // + // rr = rrr; + // gg = ggg; + // bb = bbb; + // } + } else { + glFogx(GL_FOG_MODE, GL_LINEAR); + glFogf(GL_FOG_START, renderDistance * 0.6f); + glFogf(GL_FOG_END, renderDistance); + if (i < 0) { + glFogf(GL_FOG_START, 0); + glFogf(GL_FOG_END, renderDistance * 1.0f); + } - if (mc->level->dimension->foggy) { - glFogf(GL_FOG_START, 0); - } - } + if (mc->level->dimension->foggy) { + glFogf(GL_FOG_START, 0); + } + } - glEnable2(GL_COLOR_MATERIAL); - //glColorMaterial(GL_FRONT, GL_AMBIENT); + glEnable2(GL_COLOR_MATERIAL); + //glColorMaterial(GL_FRONT, GL_AMBIENT); } void GameRenderer::updateAllChunks() { - mc->levelRenderer->updateDirtyChunks(mc->cameraTargetPlayer, true); + mc->levelRenderer->updateDirtyChunks(mc->cameraTargetPlayer, true); } bool GameRenderer::updateFreeformPickDirection(float a, Vec3& outDir) { - if (!mc->inputHolder->allowPicking()) { - _shTicks = 1; - return false; - } + if (!mc->inputHolder->allowPicking()) { + _shTicks = 1; + return false; + } - Vec3 c = mc->cameraTargetPlayer->getPos(a); + Vec3 c = mc->cameraTargetPlayer->getPos(a); - bool firstPerson = !mc->options.getBooleanValue(OPTIONS_THIRD_PERSON_VIEW); - const float PickingDistance = firstPerson? 6.0f : 12.0f; + bool firstPerson = !mc->options.getBooleanValue(OPTIONS_THIRD_PERSON_VIEW); + const float PickingDistance = firstPerson? 6.0f : 12.0f; - _shTicks = -1; + _shTicks = -1; - int vp[4] = {0, 0, mc->width, mc->height}; - float pt[3]; - float x = mc->inputHolder->mousex; - float y = mc->height - mc->inputHolder->mousey; + int vp[4] = {0, 0, mc->width, mc->height}; + float pt[3]; + float x = mc->inputHolder->mousex; + float y = mc->height - mc->inputHolder->mousey; - //sw.start(); + //sw.start(); - if (!glhUnProjectf(x, y, 1, lastModelMatrix, lastProjMatrix, vp, pt)) { - return false; - } - Vec3 p1(pt[0] + c.x, pt[1] + c.y, pt[2] + c.z); + if (!glhUnProjectf(x, y, 1, lastModelMatrix, lastProjMatrix, vp, pt)) { + return false; + } + Vec3 p1(pt[0] + c.x, pt[1] + c.y, pt[2] + c.z); - glhUnProjectf(x, y, 0, lastModelMatrix, lastProjMatrix, vp, pt); - Vec3 p0(pt[0] + c.x, pt[1] + c.y, pt[2] + c.z); + glhUnProjectf(x, y, 0, lastModelMatrix, lastProjMatrix, vp, pt); + Vec3 p0(pt[0] + c.x, pt[1] + c.y, pt[2] + c.z); - outDir = (p1 - p0).normalized(); - p1 = p0 + outDir * PickingDistance; + outDir = (p1 - p0).normalized(); + p1 = p0 + outDir * PickingDistance; - //sw.stop(); - //sw.printEvery(30, "unproject "); + //sw.stop(); + //sw.printEvery(30, "unproject "); - const HitResult& hit = mc->hitResult = mc->level->clip(p0, p1, false); + const HitResult& hit = mc->hitResult = mc->level->clip(p0, p1, false); - // If in 3rd person view - verify that the hit target is within range - if (!firstPerson && hit.isHit()) { - const float MaxSqrDist = PickingDistance*PickingDistance; - if (mc->cameraTargetPlayer->distanceToSqr((float)hit.x, (float)hit.y, (float)hit.z) > MaxSqrDist) - mc->hitResult.type = NO_HIT; - } - return true; + // If in 3rd person view - verify that the hit target is within range + if (!firstPerson && hit.isHit()) { + const float MaxSqrDist = PickingDistance*PickingDistance; + if (mc->cameraTargetPlayer->distanceToSqr((float)hit.x, (float)hit.y, (float)hit.z) > MaxSqrDist) + mc->hitResult.type = NO_HIT; + } + return true; } /*public*/ void GameRenderer::pick(float a) { if (mc->level == NULL) return; - if (mc->cameraTargetPlayer == NULL) return; + if (mc->cameraTargetPlayer == NULL) return; if (!mc->cameraTargetPlayer->isAlive()) return; - float range = mc->gameMode->getPickRange(); - bool isPicking = true; + float range = mc->gameMode->getPickRange(); + bool isPicking = true; - bool freeform = mc->useTouchscreen(); //&& !mc->options.getBooleanValue(OPTIONS_IS_JOY_TOUCH_AREA); - - if (freeform) { - isPicking = updateFreeformPickDirection(a, pickDirection); - } else { - mc->hitResult = mc->cameraTargetPlayer->pick(range, a); - pickDirection = mc->cameraTargetPlayer->getViewVector(a); - } + bool freeform = mc->useTouchscreen(); //&& !mc->options.getBooleanValue(OPTIONS_IS_JOY_TOUCH_AREA); - Vec3 from = mc->cameraTargetPlayer->getPos(a); - float dist = range; + if (freeform) { + isPicking = updateFreeformPickDirection(a, pickDirection); + } else { + mc->hitResult = mc->cameraTargetPlayer->pick(range, a); + pickDirection = mc->cameraTargetPlayer->getViewVector(a); + } + + Vec3 from = mc->cameraTargetPlayer->getPos(a); + float dist = range; if (mc->hitResult.isHit()) { - dist = mc->hitResult.pos.distanceTo(from); - } + dist = mc->hitResult.pos.distanceTo(from); + } if (mc->gameMode->isCreativeType()) { - /*dist =*/ range = 12; - } else { - if (dist > 3) dist = 3; - range = dist; - } + /*dist =*/ range = 12; + } else { + if (dist > 3) dist = 3; + range = dist; + } - Vec3 pv = (pickDirection * range); - Vec3 to = from + pv; - mc->cameraTargetPlayer->aimDirection = pickDirection; + Vec3 pv = (pickDirection * range); + Vec3 to = from + pv; + mc->cameraTargetPlayer->aimDirection = pickDirection; - Entity* hovered = NULL; - const float g = 1; - AABB aabb = mc->cameraTargetPlayer->bb.expand(pv.x, pv.y, pv.z).grow(g, g, g); + Entity* hovered = NULL; + const float g = 1; + AABB aabb = mc->cameraTargetPlayer->bb.expand(pv.x, pv.y, pv.z).grow(g, g, g); EntityList& objects = mc->level->getEntities(mc->cameraTargetPlayer, aabb); - float nearest = 0; - for (unsigned int i = 0; i < objects.size(); i++) { - Entity* e = objects[i]; - if (!e->isPickable()) continue; + float nearest = 0; + for (unsigned int i = 0; i < objects.size(); i++) { + Entity* e = objects[i]; + if (!e->isPickable()) continue; - float rr = e->getPickRadius(); - AABB bb = e->bb.grow(rr, rr, rr); - HitResult p = bb.clip(from, to); + float rr = e->getPickRadius(); + AABB bb = e->bb.grow(rr, rr, rr); + HitResult p = bb.clip(from, to); //printf("Clip Hitresult %d (%d)\n", p.type, p.isHit()); - if (bb.contains(from)) { - //@todo: hovered = e; break; ? - if (nearest >= 0) { - hovered = e; - nearest = 0; - } + if (bb.contains(from)) { + //@todo: hovered = e; break; ? + if (nearest >= 0) { + hovered = e; + nearest = 0; + } } else if (p.isHit()) { - float dd = from.distanceTo(p.pos); - if (dd < nearest || nearest == 0) { - hovered = e; - nearest = dd; - } - } - } + float dd = from.distanceTo(p.pos); + if (dd < nearest || nearest == 0) { + hovered = e; + nearest = dd; + } + } + } - if (hovered != NULL) { + if (hovered != NULL) { if(nearest < dist) { mc->hitResult = HitResult(hovered); } - } + } else if (isPicking && !mc->hitResult.isHit()) { // if we don't have a hit result, attempt to hit the edge of the block we are standing on // (this is an pocket edition simplification to help building floors) - //LOGI("hovered : %d (%f)\n", mc->hitResult.type, viewVec.y); + //LOGI("hovered : %d (%f)\n", mc->hitResult.type, viewVec.y); if (pickDirection.y < -.7f) { // looking down by more than roughly 45 degrees, fetch a hit to the block standing on Vec3 to = from.add(0, -2.0f, 0); @@ -731,9 +737,9 @@ void GameRenderer::pick(float a) { mc->hitResult.indirectHit = true; // change face (not up) if (std::abs(pickDirection.x) > std::abs(pickDirection.z)) { - mc->hitResult.f = (pickDirection.x < 0)? 4 : 5; + mc->hitResult.f = (pickDirection.x < 0)? 4 : 5; } else { - mc->hitResult.f = (pickDirection.z < 0)? 2 : 3; + mc->hitResult.f = (pickDirection.z < 0)? 2 : 3; } } } @@ -756,93 +762,93 @@ void GameRenderer::tick(int nTick, int maxTick) { //LOGI("x: %f\n", _rotX); - if (nTick == maxTick) { - const float tickMult = 1.0f / (float)(1 + maxTick); - _rotXlast = 0.4f * std::pow(std::abs(_rotX), 1.2f) * tickMult; - if (_rotX < 0) _rotXlast = -_rotXlast; + if (nTick == maxTick) { + const float tickMult = 1.0f / (float)(1 + maxTick); + _rotXlast = 0.4f * std::pow(std::abs(_rotX), 1.2f) * tickMult; + if (_rotX < 0) _rotXlast = -_rotXlast; - _rotYlast = 0.4f * std::pow(std::abs(_rotY), 1.2f) * tickMult; - if (_rotY < 0) _rotYlast = -_rotYlast; + _rotYlast = 0.4f * std::pow(std::abs(_rotY), 1.2f) * tickMult; + if (_rotY < 0) _rotYlast = -_rotYlast; - _rotX = 0; - _rotY = 0; - } + _rotX = 0; + _rotY = 0; + } - fogBrO = fogBr; - thirdDistanceO = thirdDistance; - thirdRotationO = thirdRotation; - thirdTiltO = thirdTilt; - fovOffsetO = fovOffset; - cameraRollO = cameraRoll; + fogBrO = fogBr; + thirdDistanceO = thirdDistance; + thirdRotationO = thirdRotation; + thirdTiltO = thirdTilt; + fovOffsetO = fovOffset; + cameraRollO = cameraRoll; - if (mc->cameraTargetPlayer == NULL) { - mc->cameraTargetPlayer = mc->player; - } + if (mc->cameraTargetPlayer == NULL) { + mc->cameraTargetPlayer = mc->player; + } tickFov(); - float brr = mc->level->getBrightness( Mth::floor(mc->cameraTargetPlayer->x), - Mth::floor(mc->cameraTargetPlayer->y), - Mth::floor(mc->cameraTargetPlayer->z)); + float brr = mc->level->getBrightness( Mth::floor(mc->cameraTargetPlayer->x), + Mth::floor(mc->cameraTargetPlayer->y), + Mth::floor(mc->cameraTargetPlayer->z)); float whiteness = (3 - mc->options.getIntValue(OPTIONS_VIEW_DISTANCE)) / 3.0f; - float fogBrT = brr * (1 - whiteness) + whiteness; - fogBr += (fogBrT - fogBr) * 0.1f; + float fogBrT = brr * (1 - whiteness) + whiteness; + fogBr += (fogBrT - fogBr) * 0.1f; - _tick++; + _tick++; - itemInHandRenderer->tick(); -// if (mc->isRaining) tickRain(); + itemInHandRenderer->tick(); + // if (mc->isRaining) tickRain(); } /*private*/ void GameRenderer::setupClearColor(float a) { - Level* level = mc->level; - Mob* player = mc->cameraTargetPlayer; + Level* level = mc->level; + Mob* player = mc->cameraTargetPlayer; - float whiteness = 1.0f / (4 - mc->options.getIntValue(OPTIONS_VIEW_DISTANCE)); - whiteness = 1 - (float) pow(whiteness, 0.25f); + float whiteness = 1.0f / (4 - mc->options.getIntValue(OPTIONS_VIEW_DISTANCE)); + whiteness = 1 - (float) pow(whiteness, 0.25f); - Vec3 skyColor = level->getSkyColor(mc->cameraTargetPlayer, a); - float sr = (float) skyColor.x; - float sg = (float) skyColor.y; - float sb = (float) skyColor.z; + Vec3 skyColor = level->getSkyColor(mc->cameraTargetPlayer, a); + float sr = (float) skyColor.x; + float sg = (float) skyColor.y; + float sb = (float) skyColor.z; - Vec3 fogColor = level->getFogColor(a); - fr = (float) fogColor.x; - fg = (float) fogColor.y; - fb = (float) fogColor.z; + Vec3 fogColor = level->getFogColor(a); + fr = (float) fogColor.x; + fg = (float) fogColor.y; + fb = (float) fogColor.z; - fr += (sr - fr) * whiteness; - fg += (sg - fg) * whiteness; - fb += (sb - fb) * whiteness; + fr += (sr - fr) * whiteness; + fg += (sg - fg) * whiteness; + fb += (sb - fb) * whiteness; - if (player->isUnderLiquid(Material::water)) { - fr = 0.02f; - fg = 0.02f; - fb = 0.2f; - } else if (player->isUnderLiquid(Material::lava)) { - fr = 0.6f; - fg = 0.1f; - fb = 0.00f; - } + if (player->isUnderLiquid(Material::water)) { + fr = 0.02f; + fg = 0.02f; + fb = 0.2f; + } else if (player->isUnderLiquid(Material::lava)) { + fr = 0.6f; + fg = 0.1f; + fb = 0.00f; + } - float brr = fogBrO + (fogBr - fogBrO) * a; - fr *= brr; - fg *= brr; - fb *= brr; + float brr = fogBrO + (fogBr - fogBrO) * a; + fr *= brr; + fg *= brr; + fb *= brr; - if (mc->options.getBooleanValue(OPTIONS_ANAGLYPH_3D)) { - float frr = (fr * 30 + fg * 59 + fb * 11) / 100; - float fgg = (fr * 30 + fg * 70) / (100); - float fbb = (fr * 30 + fb * 70) / (100); + if (mc->options.getBooleanValue(OPTIONS_ANAGLYPH_3D)) { + float frr = (fr * 30 + fg * 59 + fb * 11) / 100; + float fgg = (fr * 30 + fg * 70) / (100); + float fbb = (fr * 30 + fb * 70) / (100); - fr = frr; - fg = fgg; - fb = fbb; - } + fr = frr; + fg = fgg; + fb = fbb; + } - glClearColor(fr, fg, fb, 1.0f); + glClearColor(fr, fg, fb, 1.0f); } void GameRenderer::zoomRegion( float zoom, float xa, float ya ) @@ -864,7 +870,7 @@ void GameRenderer::setupGuiScreen( bool clearColorBuffer ) // Setup GUI render mode GLbitfield clearBits = clearColorBuffer? - GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT + GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT : GL_DEPTH_BUFFER_BIT; glClear(clearBits); glMatrixMode(GL_PROJECTION); @@ -877,15 +883,15 @@ void GameRenderer::setupGuiScreen( bool clearColorBuffer ) /*private*/ void GameRenderer::renderItemInHand(float a, int eye) { - glLoadIdentity2(); - if (mc->options.getBooleanValue(OPTIONS_ANAGLYPH_3D)) glTranslatef2((eye * 2 - 1) * 0.10f, 0, 0); + glLoadIdentity2(); + if (mc->options.getBooleanValue(OPTIONS_ANAGLYPH_3D)) glTranslatef2((eye * 2 - 1) * 0.10f, 0, 0); - glPushMatrix2(); - bobHurt(a); - if (mc->options.getBooleanValue(OPTIONS_VIEW_BOBBING)) bobView(a); + glPushMatrix2(); + bobHurt(a); + if (mc->options.getBooleanValue(OPTIONS_VIEW_BOBBING)) bobView(a); - if (!mc->options.getBooleanValue(OPTIONS_THIRD_PERSON_VIEW) && (mc->cameraTargetPlayer->isPlayer() && !((Player*)mc->cameraTargetPlayer)->isSleeping())) { - if (!mc->options.getBooleanValue(OPTIONS_HIDEGUI)) { + if (!mc->options.getBooleanValue(OPTIONS_THIRD_PERSON_VIEW) && (mc->cameraTargetPlayer->isPlayer() && !((Player*)mc->cameraTargetPlayer)->isSleeping())) { + if (!mc->options.getBooleanValue(OPTIONS_HIDEGUI)) { float fov = getFov(a, false); if (fov != _setupCameraFov) { glMatrixMode(GL_PROJECTION); @@ -893,16 +899,16 @@ void GameRenderer::renderItemInHand(float a, int eye) { gluPerspective(fov, mc->width / (float) mc->height, 0.05f, renderDistance); glMatrixMode(GL_MODELVIEW); } - itemInHandRenderer->render(a); - } - } + itemInHandRenderer->render(a); + } + } - glPopMatrix2(); - if (!mc->options.getBooleanValue(OPTIONS_THIRD_PERSON_VIEW) && (mc->cameraTargetPlayer->isPlayer() && !((Player*)mc->cameraTargetPlayer)->isSleeping())) { - itemInHandRenderer->renderScreenEffect(a); - bobHurt(a); - } - if (mc->options.getBooleanValue(OPTIONS_VIEW_BOBBING)) bobView(a); + glPopMatrix2(); + if (!mc->options.getBooleanValue(OPTIONS_THIRD_PERSON_VIEW) && (mc->cameraTargetPlayer->isPlayer() && !((Player*)mc->cameraTargetPlayer)->isSleeping())) { + itemInHandRenderer->renderScreenEffect(a); + bobHurt(a); + } + if (mc->options.getBooleanValue(OPTIONS_VIEW_BOBBING)) bobView(a); } void GameRenderer::onGraphicsReset() @@ -912,9 +918,9 @@ void GameRenderer::onGraphicsReset() void GameRenderer::saveMatrices() { - #if defined(RPI) - return; - #endif +#if defined(RPI) + return; +#endif static bool saved = false; //if (saved) return; diff --git a/src/client/renderer/ItemInHandRenderer.cpp b/src/client/renderer/ItemInHandRenderer.cpp index f279a9c..fdd495b 100755 --- a/src/client/renderer/ItemInHandRenderer.cpp +++ b/src/client/renderer/ItemInHandRenderer.cpp @@ -21,11 +21,12 @@ #include "../../world/item/BowItem.h" #include "../../world/level/tile/LeafTile.h" #include "entity/HumanoidMobRenderer.h" +#include "Lighting.h" //static StopwatchHandler handler; ItemInHandRenderer::ItemInHandRenderer( Minecraft* mc ) -: mc(mc), + : mc(mc), lastSlot(-1), height(0), oHeight(0), @@ -49,21 +50,47 @@ ItemInHandRenderer::ItemInHandRenderer( Minecraft* mc ) void ItemInHandRenderer::tick() { oHeight = height; - item.id = 0; + //item.id = 0; ItemInstance* itemInHand = mc->player->inventory->getSelected(); - if (itemInHand && itemInHand->count > 0) { - item.id = itemInHand->id; - item.setAuxValue(itemInHand->getAuxValue()); + bool sameItem = (itemInHand && item.id == itemInHand->id && item.getAuxValue() == itemInHand->getAuxValue()); + + + + if (mc->options.getBooleanValue(OPTIONS_RESTORED_ANIMS)) // if enabled, restores and fixes item switching animation + { + if (!itemInHand && item.id == 0) sameItem = true; + float max = 0.4f; + float tHeight = sameItem ? 1 : 0; + float dd = tHeight - height; + if (dd < -max) dd = -max; + if (dd > max) dd = max; + + height += dd; + + if (height < 0.1){ + if (itemInHand && itemInHand->count > 0) { + item.id = itemInHand->id; + item.setAuxValue(itemInHand->getAuxValue()); + } else { + item.id = 0; + } + } + } else // otherwise use vanilla broken behaviour where it instantly switches items/blocks + { + if (itemInHand && itemInHand->count > 0) { + item.id = itemInHand->id; + item.setAuxValue(itemInHand->getAuxValue()); + } + + float max = 0.4f; + float tHeight = 1;//matches ? 1 : 0; + float dd = tHeight - height; + if (dd < -max) dd = -max; + if (dd > max) dd = max; + + height += dd; } - - float max = 0.4f; - float tHeight = 1;//matches ? 1 : 0; - float dd = tHeight - height; - if (dd < -max) dd = -max; - if (dd > max) dd = max; - - height += dd; } void ItemInHandRenderer::renderItem(Mob* mob, ItemInstance* item ) @@ -92,7 +119,7 @@ void ItemInHandRenderer::renderItem(Mob* mob, ItemInstance* item ) if(mob != NULL) { itemIcon = mob->getItemInHandIcon(item, 0); } - + bool reTesselate(false); if(itemIcon != lastIconRendered && lastItemRendered == itemId) reTesselate = true; @@ -139,9 +166,9 @@ void ItemInHandRenderer::renderItem(Mob* mob, ItemInstance* item ) float v1 = (vp * 16 + 15.99f) / 256.0f; float r = 1.0f; -// float xo = 0.0f; -// float yo = 0.3f; -/* + // float xo = 0.0f; + // float yo = 0.3f; + /* //glEnable2(GL_RESCALE_NORMAL); glTranslatef2(-xo, -yo, 0); float s = 1.5f; @@ -150,19 +177,28 @@ void ItemInHandRenderer::renderItem(Mob* mob, ItemInstance* item ) glRotatef2(50, 0, 1, 0); glRotatef2(45 + 290, 0, 0, 1); glTranslatef2(-15 / 16.0f, -1 / 16.0f, 0); -*/ + */ float dd = 1 / 16.0f; + float col = 1.0f; + float br = mc->player->getBrightness(0); + + t.color(col*br,col*br,col*br,1.0f); + t.normal(0.0f, 0.0f, 1.0f); t.vertexUV(0, 0, 0, u0, v1); t.vertexUV(r, 0, 0, u1, v1); t.vertexUV(r, 1, 0, u1, v0); t.vertexUV(0, 1, 0, u0, v0); + t.normal(0.0f, 0.0f, -1.0f); t.vertexUV(0, 1, 0 - dd, u0, v0); t.vertexUV(r, 1, 0 - dd, u1, v0); t.vertexUV(r, 0, 0 - dd, u1, v1); t.vertexUV(0, 0, 0 - dd, u0, v1); + col = 0.8f; + t.color(col*br,col*br,col*br,1.0f); + t.normal(-1.0f, 0.0f, 0.0f); for (int i = 0; i < 16; i++) { float p = i / 16.0f; float uu = u0 + (u1 - u0) * p - 0.5f / 256.0f; @@ -172,6 +208,7 @@ void ItemInHandRenderer::renderItem(Mob* mob, ItemInstance* item ) t.vertexUV(xx, 1, 0, uu, v0); t.vertexUV(xx, 1, 0 - dd, uu, v0); } + t.normal(1.0f, 0.0f, 0.0f); for (int i = 0; i < 16; i++) { float p = i / 16.0f; float uu = u0 + (u1 - u0) * p - 0.5f / 256.0f; @@ -181,6 +218,10 @@ void ItemInHandRenderer::renderItem(Mob* mob, ItemInstance* item ) t.vertexUV(xx, 0, 0, uu, v1); t.vertexUV(xx, 0, 0 - dd, uu, v1); } + + col = 0.6f; + t.color(col*br,col*br,col*br,1.0f); + t.normal(0.0f, 1.0f, 0.0f); for (int i = 0; i < 16; i++) { float p = i / 16.0f; float vv = v1 + (v0 - v1) * p - 0.5f / 256.0f; @@ -190,6 +231,7 @@ void ItemInHandRenderer::renderItem(Mob* mob, ItemInstance* item ) t.vertexUV(r, yy, 0 - dd, u1, vv); t.vertexUV(0, yy, 0 - dd, u0, vv); } + t.normal(0.0f, -1.0f, 0.0f); for (int i = 0; i < 16; i++) { float p = i / 16.0f; float vv = v1 + (v0 - v1) * p - 0.5f / 256.0f; @@ -219,7 +261,7 @@ void ItemInHandRenderer::renderItem(Mob* mob, ItemInstance* item ) } mc->textures->loadAndBindTexture(renderObject.texture); - drawArrayVT_NoState(renderObject.chunk.vboId, renderObject.chunk.vertexCount); + drawArrayVTN_NoState(renderObject.chunk.vboId, renderObject.chunk.vertexCount); if (renderObject.isFlat) glPopMatrix2(); } @@ -227,6 +269,7 @@ void ItemInHandRenderer::renderItem(Mob* mob, ItemInstance* item ) //handler.printEvery(100); } + void ItemInHandRenderer::render( float a ) { //return; @@ -241,6 +284,8 @@ void ItemInHandRenderer::render( float a ) glPushMatrix2(); glRotatef2(player->xRotO + (player->xRot - player->xRotO) * a, 1, 0, 0); glRotatef2(player->yRotO + (player->yRot - player->yRotO) * a, 0, 1, 0); + glEnable(GL_RESCALE_NORMAL); + Lighting::turnOn(mc); glPopMatrix2(); float br = mc->level->getBrightness(Mth::floor(player->x), Mth::floor(player->y), Mth::floor(player->z)); @@ -356,7 +401,7 @@ void ItemInHandRenderer::render( float a ) mc->textures->loadAndBindTexture(player->getTexture()); glTranslatef2(-1.0f, +3.6f, +3.5f); - glRotatef2(120, 0, 0, 1); + glRotatef2(120, 0, 0, 1); glRotatef2(180 + 20, 1, 0, 0); glRotatef2(-90 - 45, 0, 1, 0); glScalef2(1.5f / 24.0f * 16, 1.5f / 24.0f * 16, 1.5f / 24.0f * 16); @@ -369,8 +414,8 @@ void ItemInHandRenderer::render( float a ) playerRenderer->renderHand(); glPopMatrix2(); } - //glDisable2(GL_RESCALE_NORMAL); - //Lighting.turnOff(); + glDisable2(GL_RESCALE_NORMAL); + Lighting::turnOff(); //w.stop(); } diff --git a/src/client/renderer/LevelRenderer.cpp b/src/client/renderer/LevelRenderer.cpp index 439a443..0c77682 100755 --- a/src/client/renderer/LevelRenderer.cpp +++ b/src/client/renderer/LevelRenderer.cpp @@ -513,14 +513,14 @@ void LevelRenderer::render(const AABB& b) const { Tesselator& t = Tesselator::instance; - glColor4f2(1, 1, 1, 1); +// glColor4f2(1, 1, 1, 1); - textures->loadAndBindTexture("terrain.png"); +// textures->loadAndBindTexture("terrain.png"); // uh need to check java - shredder //t.begin(); - t.color(255, 255, 255, 255); +// t.color(255, 255, 255, 255); // again not needed, for some reason the vanilla source code tints it... white? maybe this was used for something else in MCPE's dev at one point? - shredder - t.offset(((Mob*)mc->player)->getPos(0).negated()); +// t.offset(((Mob*)mc->player)->getPos(0).negated()); // why does this even exist normally, it just makes the thing... not render t.begin(GL_LINE_STRIP); t.vertex(b.x0, b.y0, b.z0); diff --git a/src/client/renderer/Lighting.cpp b/src/client/renderer/Lighting.cpp new file mode 100644 index 0000000..5633f78 --- /dev/null +++ b/src/client/renderer/Lighting.cpp @@ -0,0 +1,48 @@ +#include "Lighting.h" +#include "gles.h" +#include "../Minecraft.h" + +void Lighting::turnOff() { + glDisable(GL_LIGHTING); + glDisable(GL_LIGHT0); + glDisable(GL_LIGHT1); + glDisable(GL_COLOR_MATERIAL); +} + +void Lighting::turnOn(Minecraft* minecraft) { + if (!minecraft->options.getBooleanValue(OPTIONS_NORMAL_LIGHTING)){ // if normal lighting is false, then just dont use the lighting system at all like in vanilla - shredder + turnOff(); + return; + } + // if normal lighting is true then enable GLES/OpenGL states to setup lighting + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHT1); + glEnable(GL_COLOR_MATERIAL); + glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); + + constexpr float a = 0.4f; + constexpr float d = 0.6f; + constexpr float s = 0.0f; + + + //Vec3 l = world::phys::Vec3{0.2, 1.0, -0.7}.normalize(); + constexpr float lightmodel_ambient[] = {a, a, a, 1.0f}; + constexpr float diffuse[] = {d, d, d, 1.0f}; + constexpr float ambient[] = {0.0f, 0.0f, 0.0f, 1.0f}; + constexpr float specular[] = {s, s, s, 1.0f}; + + constexpr float pos0[] = {(float)(0.16169041989141428), (float)(0.8084520874101966), (float)(-0.5659164515496377), 0.0f}; + glLightfv(GL_LIGHT0, GL_POSITION, pos0); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); + glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); + glLightfv(GL_LIGHT0, GL_SPECULAR, specular); + + constexpr float pos1[] = {(float)(-0.16169041989141428), (float)(0.8084520874101966), (float)(0.5659164515496377), 0.0f}; + glLightfv(GL_LIGHT1, GL_POSITION, pos1); + glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse); + glLightfv(GL_LIGHT1, GL_AMBIENT, ambient); + glLightfv(GL_LIGHT1, GL_SPECULAR, specular); + glShadeModel(GL_FLAT); + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightmodel_ambient); +} diff --git a/src/client/renderer/Lighting.h b/src/client/renderer/Lighting.h new file mode 100644 index 0000000..8dc5610 --- /dev/null +++ b/src/client/renderer/Lighting.h @@ -0,0 +1,12 @@ +#ifndef NET_MINECRAFT_CLIENT_RENDERER__Lighting_H__ +#define NET_MINECRAFT_CLIENT_RENDERER__Lighting_H__ + +class Minecraft; +class Lighting +{ +public: + static void turnOff(); + static void turnOn(Minecraft* minecraft); + +}; +#endif /*NET_MINECRAFT_CLIENT_RENDERER__Lighting_H__*/ \ No newline at end of file diff --git a/src/client/renderer/Tesselator.cpp b/src/client/renderer/Tesselator.cpp index dedaca3..7feff29 100755 --- a/src/client/renderer/Tesselator.cpp +++ b/src/client/renderer/Tesselator.cpp @@ -278,9 +278,9 @@ void Tesselator::vertex( float x, float y, float z ) if (hasColor) { dst.color = src.color; } - //if (hasNormal) { - // dst.normal = src.normal; - //} + if (hasNormal) { + dst.normal = src.normal; + } dst.x = src.x; dst.y = src.y; @@ -301,9 +301,9 @@ void Tesselator::vertex( float x, float y, float z ) if (hasColor) { vertex.color = _color; } - //if (hasNormal) { - // vertex.normal = _normal; - //} + if (hasNormal) { + vertex.normal = _normal; + } vertex.x = _sx * (x + xo); vertex.y = _sy * (y + yo); @@ -332,10 +332,10 @@ void Tesselator::setAccessMode(int mode) void Tesselator::normal( float x, float y, float z ) { - static int _warn_t = 0; - if ((++_warn_t & 32767) == 1) - LOGI("WARNING: Can't use normals (Tesselator::normal)\n"); - return; + //static int _warn_t = 0; + //if ((++_warn_t & 32767) == 1) + // LOGI("WARNING: Can't use normals (Tesselator::normal)\n"); + //return; if (!tesselating) printf("But.."); hasNormal = true; @@ -404,10 +404,10 @@ void Tesselator::draw() //glColorPointer2(4, GL_UNSIGNED_BYTE, VertexSizeBytes, (GLvoid*) &_varray->color); glEnableClientState2(GL_COLOR_ARRAY); } - //if (hasNormal) { - // glNormalPointer(GL_BYTE, VertexSizeBytes, (GLvoid*) (6 * 4)); - // glEnableClientState2(GL_NORMAL_ARRAY); - //} + if (hasNormal) { + glNormalPointer(GL_BYTE, VertexSizeBytes, (GLvoid*) (6 * 4)); + glEnableClientState2(GL_NORMAL_ARRAY); + } //glVertexPointer2(3, GL_FLOAT, VertexSizeBytes, (GLvoid*)&_varray); glVertexPointer2(3, GL_FLOAT, VertexSizeBytes, 0); glEnableClientState2(GL_VERTEX_ARRAY); @@ -421,7 +421,7 @@ void Tesselator::draw() glDisableClientState2(GL_VERTEX_ARRAY); if (hasTexture) glDisableClientState2(GL_TEXTURE_COORD_ARRAY); if (hasColor) glDisableClientState2(GL_COLOR_ARRAY); - //if (hasNormal) glDisableClientState2(GL_NORMAL_ARRAY); + if (hasNormal) glDisableClientState2(GL_NORMAL_ARRAY); } clear(); diff --git a/src/client/renderer/Tesselator.h b/src/client/renderer/Tesselator.h index 85bad5f..3ad1a64 100755 --- a/src/client/renderer/Tesselator.h +++ b/src/client/renderer/Tesselator.h @@ -10,7 +10,7 @@ extern const int VertexSizeBytes; -typedef VertexDeclPTC VERTEX; +typedef VertexDeclPTCN VERTEX; typedef std::map IntGLMap; diff --git a/src/client/renderer/TileRenderer.cpp b/src/client/renderer/TileRenderer.cpp index 0e53915..8c1c91c 100755 --- a/src/client/renderer/TileRenderer.cpp +++ b/src/client/renderer/TileRenderer.cpp @@ -225,7 +225,7 @@ bool TileRenderer::tesselateTorchInWorld( Tile* tt, int x, int y, int z ) bool TileRenderer::tesselateFireInWorld( Tile* tt, int x, int y, int z ) { - // @todo: fire alpha transparency seems to be scuffed, also it seems i might have messed up the second layer while porting from lce/java , need to look into it - shredder + // fire transparency has been fixed - shredder Tesselator& t = Tesselator::instance; @@ -2308,30 +2308,54 @@ void TileRenderer::renderEast( Tile* tt, float x, float y, float z, int tex ) void TileRenderer::renderTile( Tile* tile, int data ) { Tesselator& t = Tesselator::instance; - - t.color(0xff, 0xff, 0xff); + + t.color(0xff, 0xff, 0xff); // i disabled this, this is normally enabled in normal mcpe see if this fits OPTION_NORMAL_LIGHTING - shredder int shape = tile->getRenderShape(); if (shape == Tile::SHAPE_BLOCK) { tile->updateDefaultShape(); t.addOffset(-0.5f, -0.5f, -0.5f); t.begin(); + + t.normal(0.0f, -1.0f, 0.0f);// most normal calls in this file has been added me since they existed in java - shredder + renderFaceDown(tile, 0, 0, 0, tile->getTexture(0, data)); + + t.normal(0.0f, 1.0f, 0.0f); + renderFaceUp(tile, 0, 0, 0, tile->getTexture(1, data)); + + t.normal(0.0f, 0.0f, -1.0f); + renderNorth(tile, 0, 0, 0, tile->getTexture(2, data)); + + t.normal(0.0f, 0.0f, 1.0f); + renderSouth(tile, 0, 0, 0, tile->getTexture(3, data)); + + t.normal(-1.0f, 0.0f, 0.0f); + renderWest(tile, 0, 0, 0, tile->getTexture(4, data)); + + t.normal(1.0f, 0.0f, 0.0f); + renderEast(tile, 0, 0, 0, tile->getTexture(5, data)); t.draw(); t.addOffset(0.5f, 0.5f, 0.5f); - } else if (shape == Tile::SHAPE_CROSS_TEXTURE) { + } else if (shape == Tile::SHAPE_CROSS_TEXTURE) { // uhh java has this but is this even ever used??? - shredder t.begin(); + + t.normal(0.0f, -1.0f, 0.0f); + tesselateCrossTexture(tile, data, -0.5f, -0.5f, -0.5f); t.draw(); } else if(shape == Tile::SHAPE_STEM) { t.begin(); + + t.normal(0.0f, -1.0f, 0.0f); + tile->updateDefaultShape(); tesselateStemTexture(tile, data, tile->yy1, -0.5f, -0.5f, -0.5f); t.draw(); @@ -2340,16 +2364,39 @@ void TileRenderer::renderTile( Tile* tile, int data ) t.offset(-0.5f, -0.5f, -0.5f); float s = 1 / 16.0f; t.begin(); + + t.normal(0.0f, -1.0f, 0.0f); + renderFaceDown(tile, 0, 0, 0, tile->getTexture(0)); + + t.normal(0.0f, 1.0f, 0.0f); + renderFaceUp(tile, 0, 0, 0, tile->getTexture(1)); + + t.normal(0.0f, 0.0f, -1.0f); + t.addOffset(0, 0, s); + + renderNorth(tile, 0, 0, 0, tile->getTexture(2)); + + t.normal(0.0f, 0.0f, 1.0f); + t.addOffset(0, 0, -s); t.addOffset(0, 0, -s); + + + renderSouth(tile, 0, 0, 0, tile->getTexture(3)); + + t.normal(-1.0f, 0.0f, 0.0f); + t.addOffset(0, 0, s); t.addOffset(s, 0, 0); renderWest(tile, 0, 0, 0, tile->getTexture(4)); + + t.normal(1.0f, 0.0f, 0.0f); + t.addOffset(-s, 0, 0); t.addOffset(-s, 0, 0); renderEast(tile, 0, 0, 0, tile->getTexture(5)); @@ -2363,7 +2410,7 @@ void TileRenderer::renderTile( Tile* tile, int data ) //} else if (shape == Tile::SHAPE_TORCH) { //// t.begin(); //// t.normal(0, -1, 0); - //// tesselateTorch(tile, -0.5f, -0.5f, -0.5f, 0, 0); + /// tesselateTorch(tile, -0.5f, -0.5f, -0.5f, 0, 0); //// t.end(); } else if (shape == Tile::SHAPE_ENTITYTILE_ANIMATED) { EntityTileRenderer::instance->render(tile, data, 1.0f); @@ -2375,11 +2422,23 @@ void TileRenderer::renderTile( Tile* tile, int data ) if (i == 0) tile->setShape(0, 0, 0, 1, 1, 0.5f); if (i == 1) tile->setShape(0, 0, 0.5f, 1, 0.5f, 1); + + t.normal(0.0f, -1.0f, 0.0f); renderFaceDown(tile, 0, 0, 0, tile->getTexture(0)); + + t.normal(0.0f, 1.0f, 0.0f); renderFaceUp(tile, 0, 0, 0, tile->getTexture(1)); + + t.normal(0.0f, 0.0f, -1.0f); renderNorth(tile, 0, 0, 0, tile->getTexture(2)); + + t.normal(0.0f, 0.0f, 1.0f); renderSouth(tile, 0, 0, 0, tile->getTexture(3)); + + t.normal(-1.0f, 0.0f, 0.0f); renderWest(tile, 0, 0, 0, tile->getTexture(4)); + + t.normal(1.0f, 0.0f, 0.0f); renderEast(tile, 0, 0, 0, tile->getTexture(5)); } t.draw(); @@ -2396,12 +2455,23 @@ void TileRenderer::renderTile( Tile* tile, int data ) if (i == 2) tile->setShape(0.5f - w, 1 - w * 3, -w * 2, 0.5f + w, 1 - w, 1 + w * 2); if (i == 3) tile->setShape(0.5f - w, 0.5f - w * 3, -w * 2, 0.5f + w, 0.5f - w, 1 + w * 2); - renderFaceDown(tile, 0, 0, 0, tile->getTexture(0)); - renderFaceUp(tile, 0, 0, 0, tile->getTexture(1)); - renderNorth(tile, 0, 0, 0, tile->getTexture(2)); - renderSouth(tile, 0, 0, 0, tile->getTexture(3)); - renderWest(tile, 0, 0, 0, tile->getTexture(4)); - renderEast(tile, 0, 0, 0, tile->getTexture(5)); + t.normal(0.0f, -1.0f, 0.0f); + renderFaceDown(tile, 0, 0, 0, tile->getTexture(0)); + + t.normal(0.0f, 1.0f, 0.0f); + renderFaceUp(tile, 0, 0, 0, tile->getTexture(1)); + + t.normal(0.0f, 0.0f, -1.0f); + renderNorth(tile, 0, 0, 0, tile->getTexture(2)); + + t.normal(0.0f, 0.0f, 1.0f); + renderSouth(tile, 0, 0, 0, tile->getTexture(3)); + + t.normal(-1.0f, 0.0f, 0.0f); + renderWest(tile, 0, 0, 0, tile->getTexture(4)); + + t.normal(1.0f, 0.0f, 0.0f); + renderEast(tile, 0, 0, 0, tile->getTexture(5)); } t.draw(); t.addOffset(0.5f, 0.5f, 0.5f); @@ -2415,12 +2485,23 @@ void TileRenderer::renderTile( Tile* tile, int data ) if (i == 1) tile->setShape(0.5f - w, .3f, 1 - w * 2, 0.5f + w, 1, 1); if (i == 2) tile->setShape(0.5f - w, .5f, w * 2, 0.5f + w, 1 - w, 1 - w * 2); - renderFaceUp(tile, 0, 0, 0, tile->getTexture(0)); - renderFaceDown(tile, 0, 0, 0, tile->getTexture(1)); - renderNorth(tile, 0, 0, 0, tile->getTexture(2)); - renderSouth(tile, 0, 0, 0, tile->getTexture(3)); - renderWest(tile, 0, 0, 0, tile->getTexture(4)); - renderEast(tile, 0, 0, 0, tile->getTexture(5)); + t.normal(0.0f, -1.0f, 0.0f); + renderFaceDown(tile, 0, 0, 0, tile->getTexture(0)); + + t.normal(0.0f, 1.0f, 0.0f); + renderFaceUp(tile, 0, 0, 0, tile->getTexture(1)); + + t.normal(0.0f, 0.0f, -1.0f); + renderNorth(tile, 0, 0, 0, tile->getTexture(2)); + + t.normal(0.0f, 0.0f, 1.0f); + renderSouth(tile, 0, 0, 0, tile->getTexture(3)); + + t.normal(-1.0f, 0.0f, 0.0f); + renderWest(tile, 0, 0, 0, tile->getTexture(4)); + + t.normal(1.0f, 0.0f, 0.0f); + renderEast(tile, 0, 0, 0, tile->getTexture(5)); } t.draw(); t.addOffset(0.5f, 0.5f, 0.5f); @@ -2469,7 +2550,7 @@ void TileRenderer::renderGuiTile( Tile* tile, int data ) } else if (shape == Tile::SHAPE_CROSS_TEXTURE) { t.begin(); - //t.normal(0, -1, 0); + t.normal(0, -1, 0); tesselateCrossTexture(tile, data, -0.5f, -0.5f, -0.5f); //t.end(); t.draw(); diff --git a/src/client/renderer/entity/EntityRenderer.cpp b/src/client/renderer/entity/EntityRenderer.cpp index ad500b2..5538fda 100755 --- a/src/client/renderer/entity/EntityRenderer.cpp +++ b/src/client/renderer/entity/EntityRenderer.cpp @@ -12,6 +12,7 @@ #include "../../Minecraft.h" #include "../../Option.h" +#include "../Lighting.h" EntityRenderDispatcher* EntityRenderer::entityRenderDispatcher = NULL; EntityRenderer::EntityRenderer() @@ -134,7 +135,7 @@ void EntityRenderer::postRender(Entity* entity, float x, float y, float z, float } } void EntityRenderer::renderFlame(Entity* e, float x, float y, float z, float a) { - + glDisable(GL_LIGHTING); int tex = ((Tile*)Tile::fire)->tex; int xt = (tex & 0xf) << 4; @@ -176,7 +177,7 @@ void EntityRenderer::renderFlame(Entity* e, float x, float y, float z, float a) } t.draw(); glPopMatrix2(); - // glEnable2(GL_LIGHTING); + glEnable2(GL_LIGHTING); } void EntityRenderer::renderShadow(Entity* e, float x, float y, float z, float pow, float a) { // diff --git a/src/client/renderer/entity/ItemRenderer.cpp b/src/client/renderer/entity/ItemRenderer.cpp index 72ace60..d103fcc 100755 --- a/src/client/renderer/entity/ItemRenderer.cpp +++ b/src/client/renderer/entity/ItemRenderer.cpp @@ -45,7 +45,7 @@ void ItemRenderer::render(Entity* itemEntity_, float x, float y, float z, float else if (item->count > 1) count = 2; glTranslatef2((float) x, (float) y + bob, (float) z); - //glEnable2(GL_RESCALE_NORMAL); + glEnable2(GL_RESCALE_NORMAL); if (item->id < 256 && TileRenderer::canRender(Tile::tiles[item->id]->getRenderShape())) { glRotatef2(spin, 0, 1, 0); @@ -107,7 +107,7 @@ void ItemRenderer::render(Entity* itemEntity_, float x, float y, float z, float } glRotatef2(180 - entityRenderDispatcher->playerRotY, 0, 1, 0); t.begin(); - //t.normal(0, 1, 0); + t.normal(0, 1, 0); t.vertexUV(0 - xo, 0 - yo, 0, u0, v1); t.vertexUV(r - xo, 0 - yo, 0, u1, v1); t.vertexUV(r - xo, 1 - yo, 0, u1, v0); @@ -118,7 +118,7 @@ void ItemRenderer::render(Entity* itemEntity_, float x, float y, float z, float glPopMatrix2(); } } - //glDisable2(GL_RESCALE_NORMAL); + glDisable2(GL_RESCALE_NORMAL); glPopMatrix2(); } diff --git a/src/client/renderer/entity/PlayerRenderer.cpp b/src/client/renderer/entity/PlayerRenderer.cpp index 96ee2eb..13b2b3f 100755 --- a/src/client/renderer/entity/PlayerRenderer.cpp +++ b/src/client/renderer/entity/PlayerRenderer.cpp @@ -77,10 +77,10 @@ void PlayerRenderer::render(Entity* mob_, float x, float y, float z, float rot, model = desired; humanoidModel = desired; } - LOGI("[PlayerRenderer] %s: skin=%s, modelTex=%dx%d, desired=%s\n", - ((Player*)mob)->name.c_str(), mob->getTexture().c_str(), - humanoidModel->texWidth, humanoidModel->texHeight, - (desired == playerModel64 ? "64" : "32")); +// LOGI("[PlayerRenderer] %s: skin=%s, modelTex=%dx%d, desired=%s\n", // don't log it always, only for debug - shredder +// ((Player*)mob)->name.c_str(), mob->getTexture().c_str(), +// humanoidModel->texWidth, humanoidModel->texHeight, +// (desired == playerModel64 ? "64" : "32")); HumanoidMobRenderer::render(mob_, x, y, z, rot, a); } diff --git a/src/client/renderer/gles.cpp b/src/client/renderer/gles.cpp index 04ae3d3..6b06488 100755 --- a/src/client/renderer/gles.cpp +++ b/src/client/renderer/gles.cpp @@ -115,6 +115,41 @@ void drawArrayVTC_NoState(int bufferId, int vertices, int vertexSize /* = 24 */) } #endif +void drawArrayVTN(int bufferId, int vertices, int vertexSize /* = 24 */) { + //if (Options::debugGl) LOGI("drawArray\n"); + //LOGI("draw-vtc: %d, %d, %d\n", bufferId, vertices, vertexSize); + glEnableClientState2(GL_VERTEX_ARRAY); + glEnableClientState2(GL_TEXTURE_COORD_ARRAY); + //glEnableClientState2(GL_COLOR_ARRAY); + glEnableClientState2(GL_NORMAL_ARRAY); + + glBindBuffer2(GL_ARRAY_BUFFER, bufferId); + + glVertexPointer2( 3, GL_FLOAT, vertexSize, 0); + glTexCoordPointer2(2, GL_FLOAT, vertexSize, (GLvoid*) (3 * 4)); + //glColorPointer2(4, GL_UNSIGNED_BYTE, vertexSize, (GLvoid*) (5*4)); + glNormalPointer(GL_BYTE, vertexSize, (GLvoid*) (6 * 4)); + + glDrawArrays2(GL_TRIANGLES, 0, vertices); + + glDisableClientState2(GL_VERTEX_ARRAY); + glDisableClientState2(GL_TEXTURE_COORD_ARRAY); + //glDisableClientState2(GL_COLOR_ARRAY); + glDisableClientState2(GL_NORMAL_ARRAY); +} + +#ifndef drawArrayVTN_NoState +void drawArrayVTCN_NoState(int bufferId, int vertices, int vertexSize /* = 24 */) { + glBindBuffer2(GL_ARRAY_BUFFER, bufferId); + + glVertexPointer2( 3, GL_FLOAT, vertexSize, 0); + glTexCoordPointer2(2, GL_FLOAT, vertexSize, (GLvoid*) (3 * 4)); + //glColorPointer2(4, GL_UNSIGNED_BYTE, vertexSize, (GLvoid*) (5*4)); + glNormalPointer(GL_BYTE, vertexSize, (GLvoid*) (6 * 4)); + + glDrawArrays2(GL_TRIANGLES, 0, vertices); +} +#endif #endif diff --git a/src/client/renderer/gles.h b/src/client/renderer/gles.h index c6d4bec..adb36e5 100755 --- a/src/client/renderer/gles.h +++ b/src/client/renderer/gles.h @@ -55,13 +55,18 @@ void anGenBuffers(GLsizei n, GLuint* buffer); #ifdef USE_VBO #define drawArrayVT_NoState drawArrayVT #define drawArrayVTC_NoState drawArrayVTC -void drawArrayVT(int bufferId, int vertices, int vertexSize = 24, unsigned int mode = GL_TRIANGLES); +#define drawArrayVTN_NoState drawArrayVTN +void drawArrayVT(int bufferId, int vertices, int vertexSize = 28, unsigned int mode = GL_TRIANGLES); #ifndef drawArrayVT_NoState -//void drawArrayVT_NoState(int bufferId, int vertices, int vertexSize = 24); +//void drawArrayVT_NoState(int bufferId, int vertices, int vertexSize = 28); #endif -void drawArrayVTC(int bufferId, int vertices, int vertexSize = 24); +void drawArrayVTC(int bufferId, int vertices, int vertexSize = 28); #ifndef drawArrayVTC_NoState -void drawArrayVTC_NoState(int bufferId, int vertices, int vertexSize = 24); +void drawArrayVTC_NoState(int bufferId, int vertices, int vertexSize = 28); +#endif +void drawArrayVTN(int bufferId, int vertices, int vertexSize = 28); +#ifndef drawArrayVTN_NoState +void drawArrayVTCN_NoState(int bufferId, int vertices, int vertexSize = 28); #endif #endif @@ -114,6 +119,7 @@ int glhUnProjectf( float winx, float winy, float winz, #define glVertexPointer2 glVertexPointer #define glColorPointer2 glColorPointer #define glTexCoordPointer2 glTexCoordPointer + #define glNormalPointer2 glNormalPointer #define glEnableClientState2 glEnableClientState #define glDisableClientState2 glDisableClientState #define glDrawArrays2 glDrawArrays diff --git a/src/client/renderer/ptexture/DynamicTexture.cpp b/src/client/renderer/ptexture/DynamicTexture.cpp index c3436e4..23a6464 100755 --- a/src/client/renderer/ptexture/DynamicTexture.cpp +++ b/src/client/renderer/ptexture/DynamicTexture.cpp @@ -9,7 +9,7 @@ // DynamicTexture // DynamicTexture::DynamicTexture(int tex_) -: tex(tex_), + : tex(tex_), replicate(1) { memset(pixels, 0, 16*16*4); @@ -29,8 +29,8 @@ void DynamicTexture::bindTexture(Textures* tex) { /* WaterTexture::WaterTexture() : super(Tile::water->tex), - _tick(0), - _frame(0) +_tick(0), +_frame(0) { } @@ -39,7 +39,7 @@ void WaterTexture::tick() { */ WaterTexture::WaterTexture() -: super(Tile::water->tex), + : super(Tile::water->tex), _tick(0), _frame(0) { @@ -76,55 +76,55 @@ void WaterTexture::tick() next[x + y * 16] = pow / 3.3f + heat[x + y * 16] * 0.8f; } - for (int x = 0; x < 16; x++) - for (int y = 0; y < 16; y++) { - heat[x + y * 16] += heata[x + y * 16] * 0.05f; + for (int x = 0; x < 16; x++) + for (int y = 0; y < 16; y++) { + heat[x + y * 16] += heata[x + y * 16] * 0.05f; - if (heat[x + y * 16] < 0) heat[x + y * 16] = 0; - heata[x + y * 16] -= 0.1f; - if (Mth::random() < 0.05f) { - heata[x + y * 16] = 0.5f; + if (heat[x + y * 16] < 0) heat[x + y * 16] = 0; + heata[x + y * 16] -= 0.1f; + if (Mth::random() < 0.05f) { + heata[x + y * 16] = 0.5f; + } } - } - float* tmp = next; - next = current; - current = tmp; + float* tmp = next; + next = current; + current = tmp; - for (int i = 0; i < 256; i++) { - float pow = current[i]; - if (pow > 1) pow = 1; - if (pow < 0) pow = 0; + for (int i = 0; i < 256; i++) { + float pow = current[i]; + if (pow > 1) pow = 1; + if (pow < 0) pow = 0; - float pp = pow * pow; + float pp = pow * pow; - int r = (int) (32 + pp * 32); - int g = (int) (50 + pp * 64); - int b = (int) (255); - int a = (int) (146 + pp * 50); + int r = (int) (32 + pp * 32); + int g = (int) (50 + pp * 64); + int b = (int) (255); + int a = (int) (146 + pp * 50); - //if (anaglyph3d) { - // int rr = (r * 30 + g * 59 + b * 11) / 100; - // int gg = (r * 30 + g * 70) / (100); - // int bb = (r * 30 + b * 70) / (100); + //if (anaglyph3d) { + // int rr = (r * 30 + g * 59 + b * 11) / 100; + // int gg = (r * 30 + g * 70) / (100); + // int bb = (r * 30 + b * 70) / (100); - // r = rr; - // g = gg; - // b = bb; - //} + // r = rr; + // g = gg; + // b = bb; + //} - pixels[i * 4 + 0] = r; - pixels[i * 4 + 1] = g; - pixels[i * 4 + 2] = b; - pixels[i * 4 + 3] = a; - } + pixels[i * 4 + 0] = r; + pixels[i * 4 + 1] = g; + pixels[i * 4 + 2] = b; + pixels[i * 4 + 3] = a; + } } // // WaterSideTexture // WaterSideTexture::WaterSideTexture() -: super(Tile::water->tex + 1), + : super(Tile::water->tex + 1), _tick(0), _frame(0), _tickCount(0) @@ -164,51 +164,237 @@ void WaterSideTexture::tick() { next[x + y * 16] = pow / 3.2f + heat[x + y * 16] * 0.8f; } - for (int x = 0; x < 16; x++) - for (int y = 0; y < 16; y++) { - heat[x + y * 16] += heata[x + y * 16] * 0.05f; + for (int x = 0; x < 16; x++) + for (int y = 0; y < 16; y++) { + heat[x + y * 16] += heata[x + y * 16] * 0.05f; - if (heat[x + y * 16] < 0) heat[x + y * 16] = 0; - heata[x + y * 16] -= 0.3f; - if (Mth::random() < 0.2) { - heata[x + y * 16] = 0.5f; + if (heat[x + y * 16] < 0) heat[x + y * 16] = 0; + heata[x + y * 16] -= 0.3f; + if (Mth::random() < 0.2) { + heata[x + y * 16] = 0.5f; + } } - } - float* tmp = next; - next = current; - current = tmp; + float* tmp = next; + next = current; + current = tmp; - for (int i = 0; i < 256; i++) { - float pow = current[(i - _tickCount * 16) & 255]; - if (pow > 1) pow = 1; - if (pow < 0) pow = 0; + for (int i = 0; i < 256; i++) { + float pow = current[(i - _tickCount * 16) & 255]; + if (pow > 1) pow = 1; + if (pow < 0) pow = 0; - float pp = pow * pow; + float pp = pow * pow; - int r = (int) (32 + pp * 32); - int g = (int) (50 + pp * 64); - int b = (int) (255); - int a = (int) (146 + pp * 50); + int r = (int) (32 + pp * 32); + int g = (int) (50 + pp * 64); + int b = (int) (255); + int a = (int) (146 + pp * 50); - //if (anaglyph3d) { - // int rr = (r * 30 + g * 59 + b * 11) / 100; - // int gg = (r * 30 + g * 70) / (100); - // int bb = (r * 30 + b * 70) / (100); + //if (anaglyph3d) { + // int rr = (r * 30 + g * 59 + b * 11) / 100; + // int gg = (r * 30 + g * 70) / (100); + // int bb = (r * 30 + b * 70) / (100); - // r = rr; - // g = gg; - // b = bb; - //} + // r = rr; + // g = gg; + // b = bb; + //} - pixels[i * 4 + 0] = r; - pixels[i * 4 + 1] = g; - pixels[i * 4 + 2] = b; - pixels[i * 4 + 3] = a; + pixels[i * 4 + 0] = r; + pixels[i * 4 + 1] = g; + pixels[i * 4 + 2] = b; + pixels[i * 4 + 3] = a; + } +} + +/// +/// Lava Texture +/// + +LavaTexture::LavaTexture() + : super(Tile::lava->tex), + _tick(0), + _frame(0) +{ + current = new float[16*16]; + next = new float[16*16]; + heat = new float[16*16]; + heata = new float[16*16]; + + for (int i = 0; i < 256; ++i) { + current[i] = 0; + next[i] = 0; + heat[i] = 0; + heata[i] = 0; } } +LavaTexture::~LavaTexture() { + delete[] current; + delete[] next; + delete[] heat; + delete[] heata; +} + +void LavaTexture::tick() +{ + for (int x = 0; x < 16; x++) + for (int y = 0; y < 16; y++) { + float pow = 0; + int xxo = (int)(Mth::sin((float)(y) * (float)(Mth::PI) * 2.0f / 16.0f) * 1.2f); + int yyo = (int)(Mth::sin((float)(x) * (float)(Mth::PI) * 2.0f / 16.0f) * 1.2f); + for (int xx = x - 1; xx <= x + 1; xx++) { + for (int yy = y - 1; yy <= y + 1; yy++) { + int xi = xx + xxo & 15; + int yi = yy + yyo & 15; + pow += current[xi + yi * 16]; + } + } + next[x + y * 16] = pow / 10.0f + (heat[(x + 0 & 15) + (y + 0 & 15) * 16] + heat[(x + 1 & 15) + (y + 0 & 15) * 16] + heat[(x + 1 & 15) + (y + 1 & 15) * 16] + heat[(x + 0 & 15) + (y + 1 & 15) * 16]) / 4.0f * 0.8f; + heat[x + y * 16] = heat[x + y * 16] + heata[x + y * 16] * 0.01f; + if (heat[x + y * 16] < 0.0f) { + heat[x + y * 16] = 0.0f; + } + heata[x + y * 16] = heata[x + y * 16] - 0.06f; + if (Mth::random() < 0.005) { + heata[x + y * 16] = 1.5f; + } + } + + + float* tmp = next; + next = current; + current = tmp; + + for (int i = 0; i < 256; i++) { + float pow = current[i] * 2.0f; + if (pow > 1) pow = 1; + if (pow < 0) pow = 0; + + float pp = pow * pow; + + int r = (int) (pow * 100.0f + 155.0f); + int g = (int) (pp * 255.0f); + int b = (int) (pp * pp * 128.0f); + + //if (anaglyph3d) { + // int rr = (r * 30 + g * 59 + b * 11) / 100; + // int gg = (r * 30 + g * 70) / (100); + // int bb = (r * 30 + b * 70) / (100); + + // r = rr; + // g = gg; + // b = bb; + //} + + pixels[i * 4 + 0] = r; + pixels[i * 4 + 1] = g; + pixels[i * 4 + 2] = b; + pixels[i * 4 + 3] = -1; + } +} + +/// +/// Lava Side Texture +/// + +LavaSideTexture::LavaSideTexture() + : super(Tile::lava->tex + 1), + _tick(0), + _frame(0), + _tickCount(0) +{ + replicate = 2; + + current = new float[16*16]; + next = new float[16*16]; + heat = new float[16*16]; + heata = new float[16*16]; + + for (int i = 0; i < 256; ++i) { + current[i] = 0; + next[i] = 0; + heat[i] = 0; + heata[i] = 0; + } +} + +LavaSideTexture::~LavaSideTexture() { + delete[] current; + delete[] next; + delete[] heat; + delete[] heata; +} + +void LavaSideTexture::tick() { + ++_tickCount; + for (int x = 0; x < 16; x++) + for (int y = 0; y < 16; y++) { + float pow = 0; + int yl = (int)(Mth::sin((float)(y) * (float)(Mth::PI)* 2.0f / 16.0f) * 1.2f); // var2 is y + int xl = (int)(Mth::sin((float)(x) * (float)(Mth::PI)* 2.0f / 16.0f) * 1.2f); // var1 is x + for (int yy = x - 1; yy <= x + 1; yy++) { + for (int xx = y - 1; xx <= y + 1; xx++) { + int xi = (yy + yl) & 15; // var8 + int yi = (xx + xl) & 15; //var9 + pow += current[xi + yi * 16]; + } + } + next[x + y * 16] = + next[x + y * 16] = + pow / 10.0f + ( + heat[(x + 0 & 15) + (y + 0 & 15) * + 16] + heat[ + (x + 1 & 15) + (y + 0 & 15) * 16] + heat[(x + 1 & 15) + (y + 1 & 15) * + 16] + heat[ + (x + 0 & 15) + (y + 1 & 15) * 16]) / 4.0f + * 0.8f; + heat[x + y * 16] = heat[x + y * 16] + heata[x + y * 16] * 0.01f; + + if (heat[x + y * 16] < 0.0f) { + heat[x + y * 16] = 0.0f; + } + heata[x + y * 16] = heata[x + y * 16] - 0.06f; + + if (Mth::random() < 0.005) { + heata[x + y * 16] = 1.5f; + } + } + float* tmp = next; + next = current; + current = tmp; + + for (int i = 0; i < 256; i++) { + float pow = current[(i - _tickCount / 3 * 16) & 255] * 2.0f; + if (pow > 1) pow = 1; + if (pow < 0) pow = 0; + + float pp = pow * pow; + + int r = (int) (pow * 100.0f + 155.0f); + int g = (int) (pow * pow * 255.0f); + int b = (int) (pow * pow * pow * pow * 128.0f); +// int a = (int) (146 + pp * 50); + + //if (anaglyph3d) { + // int rr = (r * 30 + g * 59 + b * 11) / 100; + // int gg = (r * 30 + g * 70) / (100); + // int bb = (r * 30 + b * 70) / (100); + + // r = rr; + // g = gg; + // b = bb; + //} + + pixels[i * 4 + 0] = r; + pixels[i * 4 + 1] = g; + pixels[i * 4 + 2] = b; + pixels[i * 4 + 3] = -1; + } +} + FireTexture::FireTexture() -: super(((Tile*)Tile::fire)->tex), + : super(((Tile*)Tile::fire)->tex), _tick(0), _frame(0) { @@ -236,63 +422,63 @@ FireTexture::~FireTexture() { // oh boy time to implement fire textures, i am so fucked - shredder void FireTexture::tick() { -// loop generates fire texture on the empty texture grid, hopefully shouldnt be too taxing on older hardware - shredder - for (int x = 0; x < 16; x++) { - for (int y = 0; y < 20; y++) { - int count = 18; - float pow = this->current[x + (y + 1) % 20 * 16] * (float)(count); - for (int xx = x - 1; xx <= x + 1; xx++) { - for (int yy = y; yy <= y + 1; yy++) { - if (xx >= 0 && yy >= 0 && xx < 16 && yy < 20) { - pow += this->current[xx + yy * 16]; - } - count++; - } - } - this->next[x + y * 16] = pow / (float(count) * 1.06f); - if (y >= 19) { - this->next[x + y * 16] = float(Mth::random() * Mth::random() * Mth::random() * 4.0 + Mth::random() * 0.1f + 0.2f); - } - } - } + // loop generates fire texture on the empty texture grid, hopefully shouldnt be too taxing on older hardware - shredder + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 20; y++) { + int count = 18; + float pow = this->current[x + (y + 1) % 20 * 16] * (float)(count); + for (int xx = x - 1; xx <= x + 1; xx++) { + for (int yy = y; yy <= y + 1; yy++) { + if (xx >= 0 && yy >= 0 && xx < 16 && yy < 20) { + pow += this->current[xx + yy * 16]; + } + count++; + } + } + this->next[x + y * 16] = pow / (float(count) * 1.06f); + if (y >= 19) { + this->next[x + y * 16] = float(Mth::random() * Mth::random() * Mth::random() * 4.0 + Mth::random() * 0.1f + 0.2f); + } + } + } - // hopefully this doesn't cause any mysterious issues - shredder + // hopefully this doesn't cause any mysterious issues - shredder float* tmp = next; next = current; current = tmp; - for (int i = 0; i < 256; i++) { - float pow = this->current[i] * 1.8f; - if (pow > 1.0f) { - pow = 1.0f; - } - if (pow < 0.0f) { - pow = 0.0f; - } - - - int r = (int) (pow * 155.0f + 100.0f); - int g = (int)(pow * pow * 255.0f); - int b = (int)(pow * pow * pow * pow * pow * pow * pow * pow * pow * pow * 255.0f); - int a = 255; - if (pow < 0.5f) { - a = 0; - } + for (int i = 0; i < 256; i++) { + float pow = this->current[i] * 1.8f; + if (pow > 1.0f) { + pow = 1.0f; + } + if (pow < 0.0f) { + pow = 0.0f; + } + + + int r = (int) (pow * 155.0f + 100.0f); + int g = (int)(pow * pow * 255.0f); + int b = (int)(pow * pow * pow * pow * pow * pow * pow * pow * pow * pow * 255.0f); + int a = 255; + if (pow < 0.5f) { + a = 0; + } // @TODO: cant be arsed rn to implement the anaglyph3d check would be nice to check if it does - shredder - //if (this->anaglyph3d) { - // float rr = (r * 30 + g * 59 + b * 11) / 100; - // float gg = (r * 30 + g * 70) / 100; - // float bb = (r * 30 + b * 70) / 100; - // r = rr; - // g = gg; - // b = bb; - //} + //if (this->anaglyph3d) { + // float rr = (r * 30 + g * 59 + b * 11) / 100; + // float gg = (r * 30 + g * 70) / 100; + // float bb = (r * 30 + b * 70) / 100; + // r = rr; + // g = gg; + // b = bb; + //} pixels[i * 4 + 0] = r; pixels[i * 4 + 1] = g; pixels[i * 4 + 2] = b; pixels[i * 4 + 3] = a; - } + } } \ No newline at end of file diff --git a/src/client/renderer/ptexture/DynamicTexture.h b/src/client/renderer/ptexture/DynamicTexture.h index a28f75a..84b902e 100755 --- a/src/client/renderer/ptexture/DynamicTexture.h +++ b/src/client/renderer/ptexture/DynamicTexture.h @@ -56,6 +56,44 @@ public: void tick(); }; +class LavaTexture: public DynamicTexture +{ + typedef DynamicTexture super; + int _tick; + int _frame; + + float* current; + float* next; + float* heat; + float* heata; + +public: + LavaTexture(); + ~LavaTexture(); + + void tick(); +}; + +class LavaSideTexture: public DynamicTexture +{ + typedef DynamicTexture super; + int _tick; + int _frame; + int _tickCount; + + float* current; + float* next; + float* heat; + float* heata; + +public: + LavaSideTexture(); + ~LavaSideTexture(); + + void tick(); +}; + + class FireTexture: public DynamicTexture { typedef DynamicTexture super; diff --git a/src/world/entity/animal/Chicken.cpp b/src/world/entity/animal/Chicken.cpp index df331e3..ca08fa1 100755 --- a/src/world/entity/animal/Chicken.cpp +++ b/src/world/entity/animal/Chicken.cpp @@ -102,8 +102,8 @@ void Chicken::dropDeathLoot( /*bool wasKilledByPlayer, int playerBonusLevel*/ ) spawnAtLocation(Item::feather->id, 1); } //// and some meat - //if (isOnFire()) spawnAtLocation(Item::chicken_cooked->id, 1); //@fire - //else + if (isOnFire()) spawnAtLocation(Item::chicken_cooked->id, 1); //@fire + else spawnAtLocation(Item::chicken_raw->id, 1); } diff --git a/src/world/entity/animal/Cow.cpp b/src/world/entity/animal/Cow.cpp index 49df047..a08d39e 100755 --- a/src/world/entity/animal/Cow.cpp +++ b/src/world/entity/animal/Cow.cpp @@ -66,11 +66,11 @@ void Cow::dropDeathLoot( /*bool wasKilledByPlayer, int playerBonusLevel*/ ) { // and some meat count = random.nextInt(3) + 1; for (int i = 0; i < count; i++) { - // if (isOnFire()) { //@fire - // spawnAtLocation(Item::beef_cooked->id, 1); - // } else { + if (isOnFire()) { //@fire + spawnAtLocation(Item::beef_cooked->id, 1); + } else { spawnAtLocation(Item::beef_raw->id, 1); - // } + } } } diff --git a/src/world/entity/animal/Pig.cpp b/src/world/entity/animal/Pig.cpp index b6eb4c0..4c18b01 100755 --- a/src/world/entity/animal/Pig.cpp +++ b/src/world/entity/animal/Pig.cpp @@ -54,8 +54,8 @@ std::string Pig::getDeathSound() int Pig::getDeathLoot() { //@fire - //if (isOnFire()) - // return Item::porkChop_cooked->id; + if (isOnFire()) + return Item::porkChop_cooked->id; return Item::porkChop_raw->id; } diff --git a/src/world/level/levelgen/CanyonFeature.cpp b/src/world/level/levelgen/CanyonFeature.cpp index 095cd30..63f61d2 100755 --- a/src/world/level/levelgen/CanyonFeature.cpp +++ b/src/world/level/levelgen/CanyonFeature.cpp @@ -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,unsigned char* blocks) +void CanyonFeature::addFeature(Level* level, int x, int z, int xOffs, int zOffs, unsigned char* blocks, int blocksSize) { if (random.nextInt(15) != 0) return; diff --git a/src/world/level/levelgen/CanyonFeature.h b/src/world/level/levelgen/CanyonFeature.h index a187681..6b264a5 100755 --- a/src/world/level/levelgen/CanyonFeature.h +++ b/src/world/level/levelgen/CanyonFeature.h @@ -11,8 +11,12 @@ 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,unsigned char* blocks); + void addFeature(Level* level, int x, int z, int xOffs, int zOffs, unsigned char* blocks, int blocksSize); + + + }; diff --git a/src/world/level/levelgen/RandomLevelSource.cpp b/src/world/level/levelgen/RandomLevelSource.cpp index 99f8ce7..3868faa 100755 --- a/src/world/level/levelgen/RandomLevelSource.cpp +++ b/src/world/level/levelgen/RandomLevelSource.cpp @@ -17,7 +17,7 @@ const float RandomLevelSource::SNOW_SCALE = 0.3f; static const int MAX_BUFFER_SIZE = 1024; RandomLevelSource::RandomLevelSource(Level* level, long seed, int version, bool spawnMobs) -: random(seed), + : random(seed), level(level), lperlinNoise1(&random, 16), lperlinNoise2(&random, 16), @@ -32,8 +32,8 @@ RandomLevelSource::RandomLevelSource(Level* level, long seed, int version, bool //biomes(NULL) { for (int i=0; i<32; ++i) - for (int j=0; j<32; ++j) - waterDepths[i][j] = 0; + for (int j=0; j<32; ++j) + waterDepths[i][j] = 0; buffer = new float[MAX_BUFFER_SIZE]; @@ -63,155 +63,155 @@ RandomLevelSource::~RandomLevelSource() { /*public*/ void RandomLevelSource::prepareHeights(int xOffs, int zOffs, unsigned char* blocks, /*Biome*/void* biomes, float* temperatures) { - + int xChunks = 16 / CHUNK_WIDTH; - int waterHeight = Level::DEPTH - 64; + int waterHeight = Level::DEPTH - 64; - int xSize = xChunks + 1; - int ySize = 128 / CHUNK_HEIGHT + 1; - int zSize = xChunks + 1; - buffer = getHeights(buffer, xOffs * xChunks, 0, zOffs * xChunks, xSize, ySize, zSize); + int xSize = xChunks + 1; + int ySize = 128 / CHUNK_HEIGHT + 1; + int zSize = xChunks + 1; + buffer = getHeights(buffer, xOffs * xChunks, 0, zOffs * xChunks, xSize, ySize, zSize); - for (int xc = 0; xc < xChunks; xc++) { - for (int zc = 0; zc < xChunks; zc++) { - for (int yc = 0; yc < 128 / CHUNK_HEIGHT; yc++) { - float yStep = 1 / (float) CHUNK_HEIGHT; - float s0 = buffer[((xc + 0) * zSize + (zc + 0)) * ySize + (yc + 0)]; - float s1 = buffer[((xc + 0) * zSize + (zc + 1)) * ySize + (yc + 0)]; - float s2 = buffer[((xc + 1) * zSize + (zc + 0)) * ySize + (yc + 0)]; - float s3 = buffer[((xc + 1) * zSize + (zc + 1)) * ySize + (yc + 0)]; + for (int xc = 0; xc < xChunks; xc++) { + for (int zc = 0; zc < xChunks; zc++) { + for (int yc = 0; yc < 128 / CHUNK_HEIGHT; yc++) { + float yStep = 1 / (float) CHUNK_HEIGHT; + float s0 = buffer[((xc + 0) * zSize + (zc + 0)) * ySize + (yc + 0)]; + float s1 = buffer[((xc + 0) * zSize + (zc + 1)) * ySize + (yc + 0)]; + float s2 = buffer[((xc + 1) * zSize + (zc + 0)) * ySize + (yc + 0)]; + float s3 = buffer[((xc + 1) * zSize + (zc + 1)) * ySize + (yc + 0)]; - float s0a = (buffer[((xc + 0) * zSize + (zc + 0)) * ySize + (yc + 1)] - s0) * yStep; - float s1a = (buffer[((xc + 0) * zSize + (zc + 1)) * ySize + (yc + 1)] - s1) * yStep; - float s2a = (buffer[((xc + 1) * zSize + (zc + 0)) * ySize + (yc + 1)] - s2) * yStep; - float s3a = (buffer[((xc + 1) * zSize + (zc + 1)) * ySize + (yc + 1)] - s3) * yStep; + float s0a = (buffer[((xc + 0) * zSize + (zc + 0)) * ySize + (yc + 1)] - s0) * yStep; + float s1a = (buffer[((xc + 0) * zSize + (zc + 1)) * ySize + (yc + 1)] - s1) * yStep; + float s2a = (buffer[((xc + 1) * zSize + (zc + 0)) * ySize + (yc + 1)] - s2) * yStep; + float s3a = (buffer[((xc + 1) * zSize + (zc + 1)) * ySize + (yc + 1)] - s3) * yStep; - for (int y = 0; y < CHUNK_HEIGHT; y++) { - float xStep = 1 / (float) CHUNK_WIDTH; + for (int y = 0; y < CHUNK_HEIGHT; y++) { + float xStep = 1 / (float) CHUNK_WIDTH; - float _s0 = s0; - float _s1 = s1; - float _s0a = (s2 - s0) * xStep; - float _s1a = (s3 - s1) * xStep; + float _s0 = s0; + float _s1 = s1; + float _s0a = (s2 - s0) * xStep; + float _s1a = (s3 - s1) * xStep; - for (int x = 0; x < CHUNK_WIDTH; x++) { - int offs = (x + xc * CHUNK_WIDTH) << 11 | (0 + zc * CHUNK_WIDTH) << 7 | (yc * CHUNK_HEIGHT + y); - int step = 1 << 7; - float zStep = 1 / (float) CHUNK_WIDTH; + for (int x = 0; x < CHUNK_WIDTH; x++) { + int offs = (x + xc * CHUNK_WIDTH) << 11 | (0 + zc * CHUNK_WIDTH) << 7 | (yc * CHUNK_HEIGHT + y); + int step = 1 << 7; + float zStep = 1 / (float) CHUNK_WIDTH; - float val = _s0; - float vala = (_s1 - _s0) * zStep; - for (int z = 0; z < CHUNK_WIDTH; z++) { -// + (zc * CHUNK_WIDTH + z)]; - float temp = temperatures[(xc * CHUNK_WIDTH + x) * 16 + (zc * CHUNK_WIDTH + z)]; - int tileId = 0; - if (yc * CHUNK_HEIGHT + y < waterHeight) { - if (temp < SNOW_CUTOFF && yc * CHUNK_HEIGHT + y >= waterHeight - 1) { - tileId = Tile::ice->id; - } else { - tileId = Tile::calmWater->id; - } - } - if (val > 0) { - tileId = Tile::rock->id; - } else { - } + float val = _s0; + float vala = (_s1 - _s0) * zStep; + for (int z = 0; z < CHUNK_WIDTH; z++) { + // + (zc * CHUNK_WIDTH + z)]; + float temp = temperatures[(xc * CHUNK_WIDTH + x) * 16 + (zc * CHUNK_WIDTH + z)]; + int tileId = 0; + if (yc * CHUNK_HEIGHT + y < waterHeight) { + if (temp < SNOW_CUTOFF && yc * CHUNK_HEIGHT + y >= waterHeight - 1) { + tileId = Tile::ice->id; + } else { + tileId = Tile::calmWater->id; + } + } + if (val > 0) { + tileId = Tile::rock->id; + } else { + } - blocks[offs] = (unsigned char) tileId; - offs += step; - val += vala; - } - _s0 += _s0a; - _s1 += _s1a; - } + blocks[offs] = (unsigned char) tileId; + offs += step; + val += vala; + } + _s0 += _s0a; + _s1 += _s1a; + } - s0 += s0a; - s1 += s1a; - s2 += s2a; - s3 += s3a; - } - } - } - } + s0 += s0a; + s1 += s1a; + s2 += s2a; + s3 += s3a; + } + } + } + } } void RandomLevelSource::buildSurfaces(int xOffs, int zOffs, unsigned char* blocks, Biome** biomes) { - int waterHeight = Level::DEPTH - 64; + int waterHeight = Level::DEPTH - 64; - float s = 1 / 32.0f; - perlinNoise2.getRegion(sandBuffer, (float)(xOffs * 16), (float)(zOffs * 16), 0, 16, 16, 1, s, s, 1); - perlinNoise2.getRegion(gravelBuffer, (float)(xOffs * 16), 109.01340f, (float)(zOffs * 16), 16, 1, 16, s, 1, s); - perlinNoise3.getRegion(depthBuffer, (float)(xOffs * 16), (float)(zOffs * 16), 0, 16, 16, 1, s * 2, s * 2, s * 2); + float s = 1 / 32.0f; + perlinNoise2.getRegion(sandBuffer, (float)(xOffs * 16), (float)(zOffs * 16), 0, 16, 16, 1, s, s, 1); + perlinNoise2.getRegion(gravelBuffer, (float)(xOffs * 16), 109.01340f, (float)(zOffs * 16), 16, 1, 16, s, 1, s); + perlinNoise3.getRegion(depthBuffer, (float)(xOffs * 16), (float)(zOffs * 16), 0, 16, 16, 1, s * 2, s * 2, s * 2); - for (int x = 0; x < 16; x++) { - for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { float temp = 1; // @todo: read temp from BiomeSource - Biome* b = biomes[x + z * 16]; - bool sand = (sandBuffer[x + z * 16] + random.nextFloat() * 0.2f) > 0; - bool gravel = (gravelBuffer[x + z * 16] + random.nextFloat() * 0.2f) > 3; - int runDepth = (int) (depthBuffer[x + z * 16] / 3 + 3 + random.nextFloat() * 0.25f); + Biome* b = biomes[x + z * 16]; + bool sand = (sandBuffer[x + z * 16] + random.nextFloat() * 0.2f) > 0; + bool gravel = (gravelBuffer[x + z * 16] + random.nextFloat() * 0.2f) > 3; + int runDepth = (int) (depthBuffer[x + z * 16] / 3 + 3 + random.nextFloat() * 0.25f); - int run = -1; + int run = -1; char top = b->topMaterial; - char material = b->material; + char material = b->material; - for (int y = 127; y >= 0; y--) { - int offs = (z * 16 + x) * 128 + y; + for (int y = 127; y >= 0; y--) { + int offs = (z * 16 + x) * 128 + y; - if (y <= 0 + random.nextInt(5)) { - blocks[offs] = (char) Tile::unbreakable->id; - } else { - int old = blocks[offs]; + if (y <= 0 + random.nextInt(5)) { + blocks[offs] = (char) Tile::unbreakable->id; + } else { + int old = blocks[offs]; - if (old == 0) { - run = -1; - } else if (old == Tile::rock->id) { - if (run == -1) { - if (runDepth <= 0) { - top = 0; - material = (char) Tile::rock->id; - } else if (y >= waterHeight - 4 && y <= waterHeight + 1) { - top = b->topMaterial; + if (old == 0) { + run = -1; + } else if (old == Tile::rock->id) { + if (run == -1) { + if (runDepth <= 0) { + top = 0; + material = (char) Tile::rock->id; + } else if (y >= waterHeight - 4 && y <= waterHeight + 1) { + top = b->topMaterial; material = b->material; - + //@attn: ? - if (gravel) { + if (gravel) { top = 0; material = (char) Tile::gravel->id; } - if (sand) { + if (sand) { top = (char) Tile::sand->id; material = (char) Tile::sand->id; } - } + } - if (y < waterHeight && top == 0) { + if (y < waterHeight && top == 0) { if (temp < 0.15f) top = (char) Tile::ice->id; else top = (char) Tile::calmWater->id; } - run = runDepth; - if (y >= waterHeight - 1) blocks[offs] = top; - else blocks[offs] = material; - } else if (run > 0) { - run--; - blocks[offs] = material; + run = runDepth; + if (y >= waterHeight - 1) blocks[offs] = top; + else blocks[offs] = material; + } else if (run > 0) { + run--; + blocks[offs] = material; - // place a few sandstone blocks beneath sand - // runs - if (run == 0 && material == Tile::sand->id) { - run = random.nextInt(4); - material = (char) Tile::sandStone->id; - } - } - } - } - } - } - } + // place a few sandstone blocks beneath sand + // runs + if (run == 0 && material == Tile::sand->id) { + run = random.nextInt(4); + material = (char) Tile::sandStone->id; + } + } + } + } + } + } + } } @@ -220,286 +220,291 @@ void RandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) { level->isGeneratingTerrain = true; - HeavyTile::instaFall = true; - int xo = xt * 16; - int zo = zt * 16; + HeavyTile::instaFall = true; + int xo = xt * 16; + int zo = zt * 16; - Biome* biome = level->getBiomeSource()->getBiome(xo + 16, zo + 16); - // Biome* biome = Biome::forest; + Biome* biome = level->getBiomeSource()->getBiome(xo + 16, zo + 16); + // Biome* biome = Biome::forest; - random.setSeed(level->getSeed()); - int xScale = random.nextInt() / 2 * 2 + 1; - int zScale = random.nextInt() / 2 * 2 + 1; - random.setSeed(((xt * xScale) + (zt * zScale)) ^ level->getSeed()); + random.setSeed(level->getSeed()); + int xScale = random.nextInt() / 2 * 2 + 1; + int zScale = random.nextInt() / 2 * 2 + 1; + random.setSeed(((xt * xScale) + (zt * zScale)) ^ level->getSeed()); + + + // @todo - add generation options to enable or disable extra features like lava lakes or water lakes as they affect seed parity with the original vanilla game - shredder // //@todo: hide those chunks if they are aren't visible -// if (random.nextInt(4) == 0) { -// int x = xo + random.nextInt(16) + 8; -// int y = random.nextInt(128); -// int z = zo + random.nextInt(16) + 8; -// LakeFeature feature(Tile::calmWater->id); -// feature.place(level, &random, x, y, z); -// LOGI("Adding underground lake @ (%d,%d,%d)\n", x, y, z); -// } + if (random.nextInt(4) == 0) { + int x = xo + random.nextInt(16) + 8; + int y = random.nextInt(128); + int z = zo + random.nextInt(16) + 8; + LakeFeature feature(Tile::calmWater->id); + feature.place(level, &random, x, y, z); + // LOGI("Adding underground lake @ (%d,%d,%d)\n", x, y, z); + } ////@todo: hide those chunks if they are aren't visible - // if (random.nextInt(8) == 0) { - // int x = xo + random.nextInt(16) + 8; - // int y = random.nextInt(random.nextInt(120) + 8); - // int z = zo + random.nextInt(16) + 8; - // if (y < 64 || random.nextInt(10) == 0) { - // LakeFeature feature(Tile::calmLava->id); - // feature.place(level, &random, x, y, z); - // } - // } + if (random.nextInt(8) == 0) { + int x = xo + random.nextInt(16) + 8; + int y = random.nextInt(random.nextInt(120) + 8); + int z = zo + random.nextInt(16) + 8; + if (y < 64 || random.nextInt(10) == 0) { + LakeFeature feature(Tile::calmLava->id); + feature.place(level, &random, x, y, z); + } + } static float totalTime = 0; const float st = getTimeS(); - //for (int i = 0; i < 8; i++) { - // int x = xo + random.nextInt(16) + 8; - // int y = random.nextInt(128); - // int z = zo + random.nextInt(16) + 8; - // MonsterRoomFeature().place(level, random, x, y, z); - //} + //for (int i = 0; i < 8; i++) { + // int x = xo + random.nextInt(16) + 8; + // int y = random.nextInt(128); + // int z = zo + random.nextInt(16) + 8; + // MonsterRoomFeature().place(level, random, x, y, z); + //} - for (int i = 0; i < 10; i++) { - int x = xo + random.nextInt(16); - int y = random.nextInt(128); - int z = zo + random.nextInt(16); - ClayFeature feature(32); + for (int i = 0; i < 10; i++) { + int x = xo + random.nextInt(16); + int y = random.nextInt(128); + int z = zo + random.nextInt(16); + ClayFeature feature(32); feature.place(level, &random, x, y, z); - } + } - for (int i = 0; i < 20; i++) { - int x = xo + random.nextInt(16); - int y = random.nextInt(128); - int z = zo + random.nextInt(16); - OreFeature feature(Tile::dirt->id, 32); + for (int i = 0; i < 20; i++) { + int x = xo + random.nextInt(16); + int y = random.nextInt(128); + int z = zo + random.nextInt(16); + OreFeature feature(Tile::dirt->id, 32); feature.place(level, &random, x, y, z); - } + } - for (int i = 0; i < 10; i++) { - int x = xo + random.nextInt(16); - int y = random.nextInt(128); - int z = zo + random.nextInt(16); - OreFeature feature(Tile::gravel->id, 32); + for (int i = 0; i < 10; i++) { + int x = xo + random.nextInt(16); + int y = random.nextInt(128); + int z = zo + random.nextInt(16); + OreFeature feature(Tile::gravel->id, 32); feature.place(level, &random, x, y, z); - } + } - // Coal: common, wide Y range, moderate vein size - for (int i = 0; i < 16; i++) { - int x = xo + random.nextInt(16); - int y = random.nextInt(128); - int z = zo + random.nextInt(16); - OreFeature feature(Tile::coalOre->id, 14); - feature.place(level, &random, x, y, z); - } + // @todo - add generation options to enable or disable adjusted ore spawn rates as they affect seed parity with the original vanilla game - shredder - // Iron: common, limited to upper underground - for (int i = 0; i < 14; i++) { - int x = xo + random.nextInt(16); - int y = random.nextInt(64); - int z = zo + random.nextInt(16); - OreFeature feature(Tile::ironOre->id, 10); - feature.place(level, &random, x, y, z); - } + // Coal: common, wide Y range, moderate vein size + for (int i = 0; i < 16; i++) { + int x = xo + random.nextInt(16); + int y = random.nextInt(128); + int z = zo + random.nextInt(16); + OreFeature feature(Tile::coalOre->id, 14); + feature.place(level, &random, x, y, z); + } - // Gold: rarer and deeper - for (int i = 0; i < 2; i++) { - int x = xo + random.nextInt(16); - int y = random.nextInt(32); - int z = zo + random.nextInt(16); - OreFeature feature(Tile::goldOre->id, 9); - feature.place(level, &random, x, y, z); - } + // Iron: common, limited to upper underground + for (int i = 0; i < 14; i++) { + int x = xo + random.nextInt(16); + int y = random.nextInt(64); + int z = zo + random.nextInt(16); + OreFeature feature(Tile::ironOre->id, 10); + feature.place(level, &random, x, y, z); + } - // Redstone: somewhat common at low depths - for (int i = 0; i < 6; i++) { - int x = xo + random.nextInt(16); - int y = random.nextInt(16); - int z = zo + random.nextInt(16); - OreFeature feature(Tile::redStoneOre->id, 8); - feature.place(level, &random, x, y, z); - } + // Gold: rarer and deeper + for (int i = 0; i < 2; i++) { + int x = xo + random.nextInt(16); + int y = random.nextInt(32); + int z = zo + random.nextInt(16); + OreFeature feature(Tile::goldOre->id, 9); + feature.place(level, &random, x, y, z); + } - // Emerald (diamond-equivalent): still rare but slightly more than vanilla - for (int i = 0; i < 3; i++) { - int x = xo + random.nextInt(16); - int y = random.nextInt(16); - int z = zo + random.nextInt(16); - OreFeature feature(Tile::emeraldOre->id, 6); - feature.place(level, &random, x, y, z); - } + // Redstone: somewhat common at low depths + for (int i = 0; i < 6; i++) { + int x = xo + random.nextInt(16); + int y = random.nextInt(16); + int z = zo + random.nextInt(16); + OreFeature feature(Tile::redStoneOre->id, 8); + feature.place(level, &random, x, y, z); + } - // Lapis: rare and not in very high Y - for (int i = 0; i < 1; i++) { - int x = xo + random.nextInt(16); - int y = random.nextInt(16) + random.nextInt(16); - int z = zo + random.nextInt(16); - OreFeature feature(Tile::lapisOre->id, 6); - feature.place(level, &random, x, y, z); - } + // Emerald (diamond-equivalent): still rare but slightly more than vanilla + for (int i = 0; i < 3; i++) { + int x = xo + random.nextInt(16); + int y = random.nextInt(16); + int z = zo + random.nextInt(16); + OreFeature feature(Tile::emeraldOre->id, 6); + feature.place(level, &random, x, y, z); + } - const float ss = 0.5f; - int oFor = (int) ((forestNoise.getValue(xo * ss, zo * ss) / 8 + random.nextFloat() * 4 + 4) / 3); - int forests = 0;//1; (java: 0) - if (random.nextInt(10) == 0) forests += 1; + // Lapis: rare and not in very high Y + for (int i = 0; i < 1; i++) { + int x = xo + random.nextInt(16); + int y = random.nextInt(16) + random.nextInt(16); + int z = zo + random.nextInt(16); + OreFeature feature(Tile::lapisOre->id, 6); + feature.place(level, &random, x, y, z); + } - if (biome == Biome::forest) forests += oFor + 2; // + 5 - if (biome == Biome::rainForest) forests += oFor + 2; //+ 5 - if (biome == Biome::seasonalForest) forests += oFor + 1; // 2 - if (biome == Biome::taiga) { + const float ss = 0.5f; + int oFor = (int) ((forestNoise.getValue(xo * ss, zo * ss) / 8 + random.nextFloat() * 4 + 4) / 3); + int forests = 0;//1; (java: 0) + if (random.nextInt(10) == 0) forests += 1; + + if (biome == Biome::forest) forests += oFor + 2; // + 5 + if (biome == Biome::rainForest) forests += oFor + 2; //+ 5 + if (biome == Biome::seasonalForest) forests += oFor + 1; // 2 + if (biome == Biome::taiga) { forests += oFor + 1; // + 5 //LOGI("Biome is taiga!\n"); } - if (biome == Biome::desert) forests -= 20; - if (biome == Biome::tundra) forests -= 20; - if (biome == Biome::plains) forests -= 20; + if (biome == Biome::desert) forests -= 20; + if (biome == Biome::tundra) forests -= 20; + if (biome == Biome::plains) forests -= 20; - for (int i = 0; i < forests; i++) { - int x = xo + random.nextInt(16) + 8; - int z = zo + random.nextInt(16) + 8; + for (int i = 0; i < forests; i++) { + int x = xo + random.nextInt(16) + 8; + int z = zo + random.nextInt(16) + 8; int y = level->getHeightmap(x, z); - Feature* tree = biome->getTreeFeature(&random); + Feature* tree = biome->getTreeFeature(&random); if (tree) { - tree->init(1, 1, 1); - tree->place(level, &random, x, y, z); + tree->init(1, 1, 1); + tree->place(level, &random, x, y, z); delete tree; } //printf("placing tree at %d, %d, %d\n", x, y, z); - } - // for (int i = 0; i < forests; i++) { - // int x = xo + random.nextInt(16) + 8; - // int z = zo + random.nextInt(16) + 8; - //int y = level->getHeightmap(x, z); - // Feature* tree = biome->getBasicTreeFeature(&random); - //if (tree) { - // tree->init(1, 1, 1); - // tree->place(level, &random, x, y, z); - // delete tree; - //} - ////printf("placing tree at %d, %d, %d\n", x, y, z); - // } + } + // for (int i = 0; i < forests; i++) { + // int x = xo + random.nextInt(16) + 8; + // int z = zo + random.nextInt(16) + 8; + //int y = level->getHeightmap(x, z); + // Feature* tree = biome->getBasicTreeFeature(&random); + //if (tree) { + // tree->init(1, 1, 1); + // tree->place(level, &random, x, y, z); + // delete tree; + //} + ////printf("placing tree at %d, %d, %d\n", x, y, z); + // } - for (int i = 0; i < 2; i++) { - int x = xo + random.nextInt(16) + 8; - int y = random.nextInt(128); - int z = zo + random.nextInt(16) + 8; - FlowerFeature feature(Tile::flower->id); + for (int i = 0; i < 2; i++) { + int x = xo + random.nextInt(16) + 8; + int y = random.nextInt(128); + int z = zo + random.nextInt(16) + 8; + FlowerFeature feature(Tile::flower->id); feature.place(level, &random, x, y, z); - } + } - if (random.nextInt(2) == 0) { - int x = xo + random.nextInt(16) + 8; - int y = random.nextInt(128); - int z = zo + random.nextInt(16) + 8; + if (random.nextInt(2) == 0) { + int x = xo + random.nextInt(16) + 8; + int y = random.nextInt(128); + int z = zo + random.nextInt(16) + 8; FlowerFeature feature(Tile::rose->id); - feature.place(level, &random, x, y, z); - } - - if (random.nextInt(4) == 0) { - int x = xo + random.nextInt(16) + 8; - int y = random.nextInt(128); - int z = zo + random.nextInt(16) + 8; - FlowerFeature feature(Tile::mushroom1->id); feature.place(level, &random, x, y, z); - } + } - if (random.nextInt(8) == 0) { - int x = xo + random.nextInt(16) + 8; - int y = random.nextInt(128); - int z = zo + random.nextInt(16) + 8; - FlowerFeature feature(Tile::mushroom2->id); + if (random.nextInt(4) == 0) { + int x = xo + random.nextInt(16) + 8; + int y = random.nextInt(128); + int z = zo + random.nextInt(16) + 8; + FlowerFeature feature(Tile::mushroom1->id); feature.place(level, &random, x, y, z); - } + } + + if (random.nextInt(8) == 0) { + int x = xo + random.nextInt(16) + 8; + int y = random.nextInt(128); + int z = zo + random.nextInt(16) + 8; + FlowerFeature feature(Tile::mushroom2->id); + feature.place(level, &random, x, y, z); + } /*int grassCount = 1; for (int i = 0; i < grassCount; i++) { - int x = xo + random.nextInt(16) + 8; - int y = random.nextInt(Level::genDepth); - int z = zo + random.nextInt(16) + 8; - Feature* grassFeature = biome->getGrassFeature(&random); - if (grassFeature) { - grassFeature->place(level, &random, x, y, z); - delete grassFeature; - } + int x = xo + random.nextInt(16) + 8; + int y = random.nextInt(Level::genDepth); + int z = zo + random.nextInt(16) + 8; + Feature* grassFeature = biome->getGrassFeature(&random); + if (grassFeature) { + grassFeature->place(level, &random, x, y, z); + delete grassFeature; + } }*/ - for (int i = 0; i < 10; i++) { - int x = xo + random.nextInt(16) + 8; - int y = random.nextInt(128); - int z = zo + random.nextInt(16) + 8; - ReedsFeature feature; + for (int i = 0; i < 10; i++) { + int x = xo + random.nextInt(16) + 8; + int y = random.nextInt(128); + int z = zo + random.nextInt(16) + 8; + ReedsFeature feature; feature.place(level, &random, x, y, z); - } - + } - //if (random.nextInt(32) == 0) { - // int x = xo + random.nextInt(16) + 8; - // int y = random.nextInt(128); - // int z = zo + random.nextInt(16) + 8; - // PumpkinFeature().place(level, random, x, y, z); - //} - int cacti = 0; - if (biome == Biome::desert) cacti += 5; + //if (random.nextInt(32) == 0) { + // int x = xo + random.nextInt(16) + 8; + // int y = random.nextInt(128); + // int z = zo + random.nextInt(16) + 8; + // PumpkinFeature().place(level, random, x, y, z); + //} - for (int i = 0; i < cacti; i++) { - int x = xo + random.nextInt(16) + 8; - int y = random.nextInt(128); - int z = zo + random.nextInt(16) + 8; - CactusFeature feature; - //LOGI("Tried creating a cactus at %d, %d, %d\n", x, y, z); - feature.place(level, &random, x, y, z); - } + int cacti = 0; + if (biome == Biome::desert) cacti += 5; - for (int i = 0; i < 50; i++) { - int x = xo + random.nextInt(16) + 8; - int y = random.nextInt(random.nextInt(120) + 8); - int z = zo + random.nextInt(16) + 8; - SpringFeature feature(Tile::water->id); + for (int i = 0; i < cacti; i++) { + int x = xo + random.nextInt(16) + 8; + int y = random.nextInt(128); + int z = zo + random.nextInt(16) + 8; + CactusFeature feature; + //LOGI("Tried creating a cactus at %d, %d, %d\n", x, y, z); feature.place(level, &random, x, y, z); - } + } - for (int i = 0; i < 20; i++) { - int x = xo + random.nextInt(16) + 8; - int y = random.nextInt(random.nextInt(random.nextInt(112) + 8) + 8); - int z = zo + random.nextInt(16) + 8; - SpringFeature feature(Tile::lava->id); + for (int i = 0; i < 50; i++) { + int x = xo + random.nextInt(16) + 8; + int y = random.nextInt(random.nextInt(120) + 8); + int z = zo + random.nextInt(16) + 8; + SpringFeature feature(Tile::water->id); feature.place(level, &random, x, y, z); - } + } + + for (int i = 0; i < 20; i++) { + int x = xo + random.nextInt(16) + 8; + int y = random.nextInt(random.nextInt(random.nextInt(112) + 8) + 8); + int z = zo + random.nextInt(16) + 8; + SpringFeature feature(Tile::lava->id); + feature.place(level, &random, x, y, z); + } if (spawnMobs && !level->isClientSide) 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); - 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); - int zp = z - (zo + 8); - int y = level->getTopSolidBlock(x, z); - float temp = temperatures[xp * 16 + zp] - (y - 64) / 64.0f * SNOW_SCALE; - if (temp < SNOW_CUTOFF) { - if (y > 0 && y < 128 && level->isEmptyTile(x, y, z) && level->getMaterial(x, y - 1, z)->blocksMotion()) { - if (level->getMaterial(x, y - 1, z) != Material::ice) level->setTile(x, y, z, Tile::topSnow->id); - } - } - } - //LOGI("Reading temp: 0 END\n"); + 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); + int zp = z - (zo + 8); + int y = level->getTopSolidBlock(x, z); + float temp = temperatures[xp * 16 + zp] - (y - 64) / 64.0f * SNOW_SCALE; + if (temp < SNOW_CUTOFF) { + if (y > 0 && y < 128 && level->isEmptyTile(x, y, z) && level->getMaterial(x, y - 1, z)->blocksMotion()) { + if (level->getMaterial(x, y - 1, z) != Material::ice) level->setTile(x, y, z, Tile::topSnow->id); + } + } + } + //LOGI("Reading temp: 0 END\n"); - const float et = getTimeS(); - totalTime += (et-st); + const float et = getTimeS(); + totalTime += (et-st); - //printf("Time to place features: %f. Total %f\n", et - st, totalTime); + //printf("Time to place features: %f. Total %f\n", et - st, totalTime); - HeavyTile::instaFall = false; + HeavyTile::instaFall = false; - level->isGeneratingTerrain = false; + level->isGeneratingTerrain = false; } LevelChunk* RandomLevelSource::create(int x, int z) { - return getChunk(x, z); + return getChunk(x, z); } LevelChunk* RandomLevelSource::getChunk(int xOffs, int zOffs) { @@ -510,22 +515,23 @@ LevelChunk* RandomLevelSource::getChunk(int xOffs, int zOffs) { if (it != chunkMap.end()) return it->second; - random.setSeed((long)(xOffs * 341872712l + zOffs * 132899541l)); //@fix + random.setSeed((long)(xOffs * 341872712l + zOffs * 132899541l)); //@fix - unsigned char* blocks = new unsigned char[LevelChunk::ChunkBlockCount]; - LevelChunk* levelChunk = new LevelChunk(level, blocks, xOffs, zOffs); + unsigned char* blocks = new unsigned char[LevelChunk::ChunkBlockCount]; + LevelChunk* levelChunk = new LevelChunk(level, blocks, xOffs, zOffs); chunkMap.insert(std::make_pair(hashedPos, levelChunk)); Biome** biomes = level->getBiomeSource()->getBiomeBlock(/*biomes, */xOffs * 16, zOffs * 16, 16, 16); - float* temperatures = level->getBiomeSource()->temperatures; - prepareHeights(xOffs, zOffs, blocks, 0, temperatures);//biomes, temperatures); - buildSurfaces(xOffs, zOffs, blocks, biomes); + float* temperatures = level->getBiomeSource()->temperatures; + prepareHeights(xOffs, zOffs, blocks, 0, temperatures);//biomes, temperatures); + buildSurfaces(xOffs, zOffs, blocks, biomes); // Carve caves into the chunk caveFeature.apply(this, level, xOffs, zOffs, blocks, LevelChunk::ChunkBlockCount); - levelChunk->recalcHeightmap(); + canyonFeature.apply(this, level, xOffs, zOffs, blocks, LevelChunk::ChunkBlockCount); + levelChunk->recalcHeightmap(); - return levelChunk; + return levelChunk; } /*private*/ @@ -535,138 +541,138 @@ float* RandomLevelSource::getHeights(float* buffer, int x, int y, int z, int xSi LOGI("RandomLevelSource::getHeights: TOO LARGE BUFFER REQUESTED: %d (max %d)\n", size, MAX_BUFFER_SIZE); } - float s = 1 * 684.412f; - float hs = 1 * 684.412f; + float s = 1 * 684.412f; + float hs = 1 * 684.412f; - float* temperatures = level->getBiomeSource()->temperatures; - float* downfalls = level->getBiomeSource()->downfalls; - sr = scaleNoise.getRegion(sr, x, z, xSize, zSize, 1.121f, 1.121f, 0.5f); - dr = depthNoise.getRegion(dr, x, z, xSize, zSize, 200.0f, 200.0f, 0.5f); + float* temperatures = level->getBiomeSource()->temperatures; + float* downfalls = level->getBiomeSource()->downfalls; + sr = scaleNoise.getRegion(sr, x, z, xSize, zSize, 1.121f, 1.121f, 0.5f); + dr = depthNoise.getRegion(dr, x, z, xSize, zSize, 200.0f, 200.0f, 0.5f); - pnr = perlinNoise1.getRegion(pnr, (float)x, (float)y, (float)z, xSize, ySize, zSize, s / 80.0f, hs / 160.0f, s / 80.0f); - ar = lperlinNoise1.getRegion(ar, (float)x, (float)y, (float)z, xSize, ySize, zSize, s, hs, s); - br = lperlinNoise2.getRegion(br, (float)x, (float)y, (float)z, xSize, ySize, zSize, s, hs, s); + pnr = perlinNoise1.getRegion(pnr, (float)x, (float)y, (float)z, xSize, ySize, zSize, s / 80.0f, hs / 160.0f, s / 80.0f); + ar = lperlinNoise1.getRegion(ar, (float)x, (float)y, (float)z, xSize, ySize, zSize, s, hs, s); + br = lperlinNoise2.getRegion(br, (float)x, (float)y, (float)z, xSize, ySize, zSize, s, hs, s); - int p = 0; - int pp = 0; + int p = 0; + int pp = 0; - int wScale = 16 / xSize; - for (int xx = 0; xx < xSize; xx++) { - int xp = xx * wScale + wScale / 2; + int wScale = 16 / xSize; + for (int xx = 0; xx < xSize; xx++) { + int xp = xx * wScale + wScale / 2; - for (int zz = 0; zz < zSize; zz++) { - int zp = zz * wScale + wScale / 2; - float temperature = temperatures[xp * 16 + zp]; - float downfall = downfalls[xp * 16 + zp] * temperature; - float dd = 1 - downfall; - dd = dd * dd; - dd = dd * dd; - dd = 1 - dd; + for (int zz = 0; zz < zSize; zz++) { + int zp = zz * wScale + wScale / 2; + float temperature = temperatures[xp * 16 + zp]; + float downfall = downfalls[xp * 16 + zp] * temperature; + float dd = 1 - downfall; + dd = dd * dd; + dd = dd * dd; + dd = 1 - dd; - float scale = ((sr[pp] + 256.0f) / 512); - scale *= dd; - if (scale > 1) scale = 1; + float scale = ((sr[pp] + 256.0f) / 512); + scale *= dd; + if (scale > 1) scale = 1; - float depth = (dr[pp] / 8000.0f); - if (depth < 0) depth = -depth * 0.3f; - depth = depth * 3.0f - 2.0f; + float depth = (dr[pp] / 8000.0f); + if (depth < 0) depth = -depth * 0.3f; + depth = depth * 3.0f - 2.0f; - if (depth < 0) { - depth = depth / 2; - if (depth < -1) depth = -1; - depth = depth / 1.4f; - depth /= 2; - scale = 0; - } else { - if (depth > 1) depth = 1; - depth = depth / 8; - } + if (depth < 0) { + depth = depth / 2; + if (depth < -1) depth = -1; + depth = depth / 1.4f; + depth /= 2; + scale = 0; + } else { + if (depth > 1) depth = 1; + depth = depth / 8; + } - if (scale < 0) scale = 0; - scale = (scale) + 0.5f; - depth = depth * ySize / 16; + if (scale < 0) scale = 0; + scale = (scale) + 0.5f; + depth = depth * ySize / 16; - float yCenter = ySize / 2.0f + depth * 4; + float yCenter = ySize / 2.0f + depth * 4; - pp++; + pp++; - for (int yy = 0; yy < ySize; yy++) { - float val = 0; + for (int yy = 0; yy < ySize; yy++) { + float val = 0; - float yOffs = (yy - (yCenter)) * 12 / scale; - if (yOffs < 0) yOffs *= 4; + float yOffs = (yy - (yCenter)) * 12 / scale; + if (yOffs < 0) yOffs *= 4; - float bb = ar[p] / 512; - float cc = br[p] / 512; + float bb = ar[p] / 512; + float cc = br[p] / 512; - float v = (pnr[p] / 10 + 1) / 2; - if (v < 0) val = bb; - else if (v > 1) val = cc; - else val = bb + (cc - bb) * v; - val -= yOffs; + float v = (pnr[p] / 10 + 1) / 2; + if (v < 0) val = bb; + else if (v > 1) val = cc; + else val = bb + (cc - bb) * v; + val -= yOffs; - if (yy > ySize - 4) { - float slide = (yy - (ySize - 4)) / (4 - 1.0f); - val = val * (1 - slide) + -10 * slide; - } + if (yy > ySize - 4) { + float slide = (yy - (ySize - 4)) / (4 - 1.0f); + val = val * (1 - slide) + -10 * slide; + } - buffer[p] = val; - p++; - } - } - } - return buffer; + buffer[p] = val; + p++; + } + } + } + return buffer; } /*private*/ void RandomLevelSource::calcWaterDepths(ChunkSource* parent, int xt, int zt) { - int xo = xt * 16; - int zo = zt * 16; - for (int x = 0; x < 16; x++) { - int y = level->getSeaLevel(); - for (int z = 0; z < 16; z++) { - int xp = xo + x + 7; - int zp = zo + z + 7; - int h = level->getHeightmap(xp, zp); - if (h <= 0) { - if (level->getHeightmap(xp - 1, zp) > 0 || level->getHeightmap(xp + 1, zp) > 0 || level->getHeightmap(xp, zp - 1) > 0 || level->getHeightmap(xp, zp + 1) > 0) { - bool hadWater = false; - if (hadWater || (level->getTile(xp - 1, y, zp) == Tile::calmWater->id && level->getData(xp - 1, y, zp) < 7)) hadWater = true; - if (hadWater || (level->getTile(xp + 1, y, zp) == Tile::calmWater->id && level->getData(xp + 1, y, zp) < 7)) hadWater = true; - if (hadWater || (level->getTile(xp, y, zp - 1) == Tile::calmWater->id && level->getData(xp, y, zp - 1) < 7)) hadWater = true; - if (hadWater || (level->getTile(xp, y, zp + 1) == Tile::calmWater->id && level->getData(xp, y, zp + 1) < 7)) hadWater = true; - if (hadWater) { - for (int x2 = -5; x2 <= 5; x2++) { - for (int z2 = -5; z2 <= 5; z2++) { - int d = (x2 > 0 ? x2 : -x2) + (z2 > 0 ? z2 : -z2); + int xo = xt * 16; + int zo = zt * 16; + for (int x = 0; x < 16; x++) { + int y = level->getSeaLevel(); + for (int z = 0; z < 16; z++) { + int xp = xo + x + 7; + int zp = zo + z + 7; + int h = level->getHeightmap(xp, zp); + if (h <= 0) { + if (level->getHeightmap(xp - 1, zp) > 0 || level->getHeightmap(xp + 1, zp) > 0 || level->getHeightmap(xp, zp - 1) > 0 || level->getHeightmap(xp, zp + 1) > 0) { + bool hadWater = false; + if (hadWater || (level->getTile(xp - 1, y, zp) == Tile::calmWater->id && level->getData(xp - 1, y, zp) < 7)) hadWater = true; + if (hadWater || (level->getTile(xp + 1, y, zp) == Tile::calmWater->id && level->getData(xp + 1, y, zp) < 7)) hadWater = true; + if (hadWater || (level->getTile(xp, y, zp - 1) == Tile::calmWater->id && level->getData(xp, y, zp - 1) < 7)) hadWater = true; + if (hadWater || (level->getTile(xp, y, zp + 1) == Tile::calmWater->id && level->getData(xp, y, zp + 1) < 7)) hadWater = true; + if (hadWater) { + for (int x2 = -5; x2 <= 5; x2++) { + for (int z2 = -5; z2 <= 5; z2++) { + int d = (x2 > 0 ? x2 : -x2) + (z2 > 0 ? z2 : -z2); - if (d <= 5) { - d = 6 - d; - if (level->getTile(xp + x2, y, zp + z2) == Tile::calmWater->id) { - int od = level->getData(xp + x2, y, zp + z2); - if (od < 7 && od < d) { - level->setData(xp + x2, y, zp + z2, d); - } - } - } - } - } - if (hadWater) { - level->setTileAndDataNoUpdate(xp, y, zp, Tile::calmWater->id, 7); - for (int y2 = 0; y2 < y; y2++) { - level->setTileAndDataNoUpdate(xp, y2, zp, Tile::calmWater->id, 8); - } - } - } - } - } - } - } + if (d <= 5) { + d = 6 - d; + if (level->getTile(xp + x2, y, zp + z2) == Tile::calmWater->id) { + int od = level->getData(xp + x2, y, zp + z2); + if (od < 7 && od < d) { + level->setData(xp + x2, y, zp + z2, d); + } + } + } + } + } + if (hadWater) { + level->setTileAndDataNoUpdate(xp, y, zp, Tile::calmWater->id, 7); + for (int y2 = 0; y2 < y; y2++) { + level->setTileAndDataNoUpdate(xp, y2, zp, Tile::calmWater->id, 8); + } + } + } + } + } + } + } } bool RandomLevelSource::hasChunk(int x, int y) { - //return x >= 0 && x < 16 && y >= 0 && y < 16; + //return x >= 0 && x < 16 && y >= 0 && y < 16; return true; } @@ -687,18 +693,18 @@ std::string RandomLevelSource::gatherStats() { //} Biome::MobList RandomLevelSource::getMobsAt(const MobCategory& mobCategory, int x, int y, int z) { - BiomeSource* biomeSource = level->getBiomeSource(); - if (biomeSource == NULL) { - return Biome::MobList(); - } -// static Stopwatch sw; sw.start(); - Biome* biome = biomeSource->getBiome(x, z); -// sw.stop(); -// sw.printEvery(10, "getBiome::"); - if (biome == NULL) { - return Biome::MobList(); - } - return biome->getMobs(mobCategory); + BiomeSource* biomeSource = level->getBiomeSource(); + if (biomeSource == NULL) { + return Biome::MobList(); + } + // static Stopwatch sw; sw.start(); + Biome* biome = biomeSource->getBiome(x, z); + // sw.stop(); + // sw.printEvery(10, "getBiome::"); + if (biome == NULL) { + return Biome::MobList(); + } + return biome->getMobs(mobCategory); } diff --git a/src/world/level/levelgen/RandomLevelSource.h b/src/world/level/levelgen/RandomLevelSource.h index 7082990..e8b88e4 100755 --- a/src/world/level/levelgen/RandomLevelSource.h +++ b/src/world/level/levelgen/RandomLevelSource.h @@ -25,6 +25,7 @@ class LevelChunk; #include "../chunk/ChunkSource.h" #include "LargeCaveFeature.h" +#include "CanyonFeature.h" #include "synth/PerlinNoise.h" #include "../../../SharedConstants.h" @@ -63,6 +64,7 @@ private: public: //Biome** biomes; LargeCaveFeature caveFeature; + CanyonFeature canyonFeature; int waterDepths[16+16][16+16]; private: ChunkMap chunkMap; @@ -92,6 +94,7 @@ private: float* fi; float* fis; ///*private*/ float[] temperatures; + float* temperatures; // normally unused like above, but restored this maybe might come handy - shredder }; class PerformanceTestChunkSource : public ChunkSource diff --git a/src/world/level/levelgen/feature/BasicTree.h b/src/world/level/levelgen/feature/BasicTree.h index 46f3f7e..16c15ca 100644 --- a/src/world/level/levelgen/feature/BasicTree.h +++ b/src/world/level/levelgen/feature/BasicTree.h @@ -17,7 +17,7 @@ class BasicTree : public Feature typedef Feature super; private: - + unsigned char axisConversionArray[6]; Random *rnd; @@ -25,11 +25,11 @@ private: int origin[3]; int height; int trunkHeight; - double trunkHeightScale; - double branchDensity; - double branchSlope; - double widthScale; - double foliageDensity; + float trunkHeightScale; + float branchDensity; + float branchSlope; + float widthScale; + float foliageDensity; int trunkWidth; int heightVariance; int foliageHeight; @@ -38,7 +38,7 @@ private: void prepare(){ trunkHeight = (int) (height * trunkHeightScale); if (trunkHeight >= height) trunkHeight = height - 1; - int clustersPerY = (int) (1.382 + pow(foliageDensity * height / 13.0, 2)); + int clustersPerY = (int) (1.382f + pow(foliageDensity * height / 13.0, 2)); if (clustersPerY < 1) clustersPerY = 1; int **tempFoliageCoords = new int *[clustersPerY * height]; for( int i = 0; i < clustersPerY * height; i++ ) @@ -68,19 +68,19 @@ private: continue; } - double originOffset = 0.5; + float originOffset = 0.5f; while (num < clustersPerY) { - double radius = widthScale * (shapefac * (rnd->nextFloat() + 0.328)); - double angle = rnd->nextFloat() * 2.0 * 3.14159; + float radius = widthScale * (shapefac * (rnd->nextFloat() + 0.328f)); + float angle = rnd->nextFloat() * 2.0f * 3.14159f; int x = Mth::floor(radius * sin(angle) + origin[0] + originOffset); int z = Mth::floor(radius * cos(angle) + origin[2] + originOffset); int checkStart[] = { x, y, z }; int checkEnd[] = { x, y + foliageHeight, z }; if (checkLine(checkStart, checkEnd) == -1) { int checkBranchBase[] = { origin[0], origin[1], origin[2] }; - double distance = sqrt(pow(abs(origin[0] - checkStart[0]), 2.0) + pow(abs(origin[2] - checkStart[2]), 2.0)); - double branchHeight = distance * branchSlope; + float distance = sqrt(pow(abs(origin[0] - checkStart[0]), 2.0f) + pow(abs(origin[2] - checkStart[2]), 2.0f)); + float branchHeight = distance * branchSlope; if ((checkStart[1] - branchHeight) > trunkTop) { checkBranchBase[1] = trunkTop; @@ -134,7 +134,9 @@ private: offset2 = -rad; while (offset2 <= rad) { - double thisdistance = pow(abs(offset1) + 0.5, 2) + pow(abs(offset2) + 0.5, 2); + float off1 = (float)offset1 + 0.5f; + float off2 = (float)offset2 + 0.5f; + float thisdistance = (off1 * off1) + (off2 * off2); if (thisdistance > radius * radius) { offset2++; @@ -159,14 +161,14 @@ private: } float treeShape(int y){ - if (y < (((float) height) * 0.3)) return (float) -1.618; - float radius = ((float) height) / ((float) 2.0); - float adjacent = (((float) height) / ((float) 2.0)) - y; + if (y < (((float) height) * 0.3f)) return (float) -1.618f; + float radius = ((float) height) / ((float) 2.0f); + float adjacent = (((float) height) / ((float) 2.0f)) - y; float distance; if (adjacent == 0) distance = radius; - else if (abs(adjacent) >= radius) distance = (float) 0.0; + else if (abs(adjacent) >= radius) distance = (float) 0.0f; else distance = (float) sqrt(pow(abs(radius), 2) - pow(abs(adjacent), 2)); - distance *= (float) 0.5; + distance *= (float) 0.5f; return distance; } float foliageShape(int y){ @@ -207,8 +209,8 @@ private: char primsign; if (delta[primidx] > 0) primsign = 1; else primsign = -1; - double secfac1 = ((double) delta[secidx1]) / ((double) delta[primidx]); - double secfac2 = ((double) delta[secidx2]) / ((double) delta[primidx]); + float secfac1 = ((float) delta[secidx1]) / ((float) delta[primidx]); + float secfac2 = ((float) delta[secidx2]) / ((float) delta[primidx]); int coordinate[] = { 0, 0, 0 }; int primoffset = 0; int endoffset = delta[primidx] + primsign; @@ -312,8 +314,8 @@ private: char primsign; if (delta[primidx] > 0) primsign = 1; else primsign = -1; - double secfac1 = ((double) delta[secidx1]) / ((double) delta[primidx]); - double secfac2 = ((double) delta[secidx2]) / ((double) delta[primidx]); + float secfac1 = ((float) delta[secidx1]) / ((float) delta[primidx]); + float secfac2 = ((float) delta[secidx2]) / ((float) delta[primidx]); int coordinate[] = { 0, 0, 0 }; int primoffset = 0; int endoffset = delta[primidx] + primsign; @@ -331,19 +333,19 @@ private: } primoffset += primsign; } - + if (primoffset == endoffset) { return -1; } - + else { return abs(primoffset); } } bool checkLocation(){ - + int startPosition[] = { origin[0], origin[1], origin[2] }; int endPosition[] = { origin[0], origin[1] + height - 1, origin[2] }; @@ -373,11 +375,11 @@ private: public: BasicTree(bool doUpdate){ axisConversionArray[0] = 2; - axisConversionArray[1] = 0; - axisConversionArray[2] = 0; - axisConversionArray[3] = 1; - axisConversionArray[4] = 2; - axisConversionArray[5] = 1; + axisConversionArray[1] = 0; + axisConversionArray[2] = 0; + axisConversionArray[3] = 1; + axisConversionArray[4] = 2; + axisConversionArray[5] = 1; rnd = new Random(); origin[0] = 0; origin[1] = 0; @@ -405,7 +407,7 @@ public: delete [] foliageCoords; } - virtual void init(double heightInit, double widthInit, double foliageDensityInit){ + virtual void init(float heightInit, float widthInit, float foliageDensityInit){ heightVariance = (int) (heightInit * 12); if (heightInit > 0.5) foliageHeight = 5; @@ -430,7 +432,7 @@ public: return false; } - + prepare(); diff --git a/src/world/level/tile/Sapling.h b/src/world/level/tile/Sapling.h index d6fae0e..15877d7 100755 --- a/src/world/level/tile/Sapling.h +++ b/src/world/level/tile/Sapling.h @@ -8,6 +8,7 @@ #include "../levelgen/feature/SpruceFeature.h" #include "../levelgen/feature/BirchFeature.h" #include "../levelgen/feature/TreeFeature.h" +#include "../levelgen/feature/BasicTree.h" class Sapling: public Bush { @@ -90,9 +91,9 @@ public: // f = new TreeFeature(true, 4 + random.nextInt(7), TreeTile::JUNGLE_TRUNK, LeafTile::JUNGLE_LEAF, false); // } } else { - //if (random->nextInt(10) == 0) { - // f = new BasicTree(true); - //} else + if (random->nextInt(10) == 0) { + f = new BasicTree(true); + } else f = new TreeFeature(true); }