diff --git a/builtin/init.lua b/builtin/init.lua index 6b27cf76e..4400a19d6 100644 --- a/builtin/init.lua +++ b/builtin/init.lua @@ -12,7 +12,7 @@ if core.print then -- Override native print and use -- terminal if that's turned on function print(...) - local n, t = select("#", ...), { ... } + local n, t = select("#", ...), {...} for i = 1, n do t[i] = tostring(t[i]) end @@ -25,26 +25,26 @@ os.setlocale("C", "numeric") minetest = core -- Load other files -local scriptdir = core.get_builtin_path()..DIR_DELIM -local gamepath = scriptdir.."game"..DIR_DELIM -local commonpath = scriptdir.."common"..DIR_DELIM -local asyncpath = scriptdir.."async"..DIR_DELIM +local scriptdir = core.get_builtin_path() .. DIR_DELIM +local gamepath = scriptdir .. "game" .. DIR_DELIM +local commonpath = scriptdir .. "common" .. DIR_DELIM +local asyncpath = scriptdir .. "async" .. DIR_DELIM -dofile(commonpath.."strict.lua") -dofile(commonpath.."serialize.lua") -dofile(commonpath.."misc_helpers.lua") +dofile(commonpath .. "strict.lua") +dofile(commonpath .. "serialize.lua") +dofile(commonpath .. "misc_helpers.lua") if INIT == "game" then - dofile(gamepath.."init.lua") + dofile(gamepath .. "init.lua") elseif INIT == "mainmenu" then local mainmenuscript = core.setting_get("main_menu_script") if mainmenuscript ~= nil and mainmenuscript ~= "" then dofile(mainmenuscript) else - dofile(core.get_mainmenu_path()..DIR_DELIM.."init.lua") + dofile(core.get_mainmenu_path() .. DIR_DELIM .. "init.lua") end elseif INIT == "async" then - dofile(asyncpath.."init.lua") + dofile(asyncpath .. "init.lua") else error(("Unrecognized builtin initialization type %s!"):format(tostring(INIT))) end diff --git a/builtin/mainmenu/init.lua b/builtin/mainmenu/init.lua index 69536630d..6dd345ff4 100644 --- a/builtin/mainmenu/init.lua +++ b/builtin/mainmenu/init.lua @@ -37,23 +37,29 @@ dofile(menupath .. DIR_DELIM .. "common.lua") dofile(menupath .. DIR_DELIM .. "gamemgr.lua") dofile(menupath .. DIR_DELIM .. "modmgr.lua") dofile(menupath .. DIR_DELIM .. "store.lua") +dofile(menupath .. DIR_DELIM .. "textures.lua") + dofile(menupath .. DIR_DELIM .. "dlg_config_world.lua") -dofile(menupath .. DIR_DELIM .. "tab_credits.lua") -dofile(menupath .. DIR_DELIM .. "tab_mods.lua") -dofile(menupath .. DIR_DELIM .. "tab_settings.lua") dofile(menupath .. DIR_DELIM .. "dlg_settings_advanced.lua") if PLATFORM ~= "Android" then dofile(menupath .. DIR_DELIM .. "dlg_create_world.lua") dofile(menupath .. DIR_DELIM .. "dlg_delete_mod.lua") dofile(menupath .. DIR_DELIM .. "dlg_delete_world.lua") dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua") - dofile(menupath .. DIR_DELIM .. "tab_multiplayer.lua") - dofile(menupath .. DIR_DELIM .. "tab_server.lua") - dofile(menupath .. DIR_DELIM .. "tab_singleplayer.lua") - dofile(menupath .. DIR_DELIM .. "tab_texturepacks.lua") - dofile(menupath .. DIR_DELIM .. "textures.lua") +end + +local tabs = {} + +tabs.settings = dofile(menupath .. DIR_DELIM .. "tab_settings.lua") +tabs.mods = dofile(menupath .. DIR_DELIM .. "tab_mods.lua") +tabs.credits = dofile(menupath .. DIR_DELIM .. "tab_credits.lua") +if PLATFORM == "Android" then + tabs.simple_main = dofile(menupath .. DIR_DELIM .. "tab_simple_main.lua") else - dofile(menupath .. DIR_DELIM .. "tab_simple_main.lua") + tabs.singleplayer = dofile(menupath .. DIR_DELIM .. "tab_singleplayer.lua") + tabs.multiplayer = dofile(menupath .. DIR_DELIM .. "tab_multiplayer.lua") + tabs.server = dofile(menupath .. DIR_DELIM .. "tab_server.lua") + tabs.texturepacks = dofile(menupath .. DIR_DELIM .. "tab_texturepacks.lua") end -------------------------------------------------------------------------------- @@ -69,8 +75,19 @@ local function init_globals() -- Init gamedata gamedata.worldindex = 0 + if PLATFORM == "Android" then + local world_list = core.get_worlds() + local world_index = table.indexof(world_list, "singleplayerworld") - if PLATFORM ~= "Android" then + if world_index == -1 then + core.create_world("singleplayerworld", 1) + + world_list = core.get_worlds() + world_index = table.indexof(world_list, "singleplayerworld") + end + + gamedata.worldindex = world_index + else menudata.worldlist = filterlist.create( core.get_worlds, compare_worlds, @@ -89,61 +106,34 @@ local function init_globals() if not core.setting_get("menu_last_game") then local default_game = core.setting_get("default_game") or "minetest" - core.setting_set("menu_last_game", default_game ) + core.setting_set("menu_last_game", default_game) end mm_texture.init() - else - local world_list = core.get_worlds() - - local found_singleplayerworld = false - - for i,world in pairs(world_list) do - if world.name == "singleplayerworld" then - found_singleplayerworld = true - gamedata.worldindex = i - break - end - end - - if not found_singleplayerworld then - core.create_world("singleplayerworld", 1) - - local world_list = core.get_worlds() - - for i,world in pairs(world_list) do - if world.name == "singleplayerworld" then - gamedata.worldindex = i - break - end - end - end end -- Create main tabview - local tv_main = tabview_create("maintab",{x=12,y=5.2},{x=0,y=0}) - if PLATFORM ~= "Android" then - tv_main:set_autosave_tab(true) - end - if PLATFORM ~= "Android" then - tv_main:add(tab_singleplayer) - tv_main:add(tab_multiplayer) - tv_main:add(tab_server) + local tv_main = tabview_create("maintab", {x = 12, y = 5.2}, {x = 0, y = 0}) + + if PLATFORM == "Android" then + tv_main:add(tabs.simple_main) + tv_main:add(tabs.settings) else - tv_main:add(tab_simple_main) + tv_main:set_autosave_tab(true) + tv_main:add(tabs.singleplayer) + tv_main:add(tabs.multiplayer) + tv_main:add(tabs.server) + tv_main:add(tabs.settings) + tv_main:add(tabs.texturepacks) end - tv_main:add(tab_settings) - if PLATFORM ~= "Android" then - tv_main:add(tab_texturepacks) - end - tv_main:add(tab_mods) - tv_main:add(tab_credits) + + tv_main:add(tabs.mods) + tv_main:add(tabs.credits) tv_main:set_global_event_handler(main_event_handler) - tv_main:set_fixed_size(false) - if not (PLATFORM == "Android") then + if PLATFORM ~= "Android" then tv_main:set_tab(core.setting_get("maintab_LAST")) end ui.set_default("maintab") @@ -151,9 +141,9 @@ local function init_globals() -- Create modstore ui if PLATFORM == "Android" then - modstore.init({x=12, y=6}, 3, 2) + modstore.init({x = 12, y = 6}, 3, 2) else - modstore.init({x=12, y=8}, 4, 3) + modstore.init({x = 12, y = 8}, 4, 3) end ui.update() diff --git a/builtin/mainmenu/init_simple.lua b/builtin/mainmenu/init_simple.lua index c3891d21c..298bd834e 100644 --- a/builtin/mainmenu/init_simple.lua +++ b/builtin/mainmenu/init_simple.lua @@ -1,4 +1,4 @@ -- helper file to be able to debug the simple menu on PC -- without messing around with actual menu code! -PLATFORM="Android" +PLATFORM = "Android" dofile("builtin/mainmenu/init.lua") diff --git a/builtin/mainmenu/tab_credits.lua b/builtin/mainmenu/tab_credits.lua index 5cb730b38..822f64844 100644 --- a/builtin/mainmenu/tab_credits.lua +++ b/builtin/mainmenu/tab_credits.lua @@ -69,7 +69,7 @@ local previous_contributors = { "Zefram ", } -tab_credits = { +return { name = "credits", caption = fgettext("Credits"), cbf_formspec = function(tabview, name, tabdata) diff --git a/builtin/mainmenu/tab_mods.lua b/builtin/mainmenu/tab_mods.lua index af758f8df..69027c015 100644 --- a/builtin/mainmenu/tab_mods.lua +++ b/builtin/mainmenu/tab_mods.lua @@ -163,7 +163,7 @@ local function handle_buttons(tabview, fields, tabname, tabdata) end -------------------------------------------------------------------------------- -tab_mods = { +return { name = "mods", caption = fgettext("Mods"), cbf_formspec = get_formspec, diff --git a/builtin/mainmenu/tab_multiplayer.lua b/builtin/mainmenu/tab_multiplayer.lua index 2072f8c38..06d8791f0 100644 --- a/builtin/mainmenu/tab_multiplayer.lua +++ b/builtin/mainmenu/tab_multiplayer.lua @@ -256,10 +256,10 @@ local function on_change(type,old_tab,new_tab) end -------------------------------------------------------------------------------- -tab_multiplayer = { +return { name = "multiplayer", caption = fgettext("Client"), cbf_formspec = get_formspec, cbf_button_handler = main_button_handler, on_change = on_change - } +} diff --git a/builtin/mainmenu/tab_server.lua b/builtin/mainmenu/tab_server.lua index d08eecc21..6b96825a0 100644 --- a/builtin/mainmenu/tab_server.lua +++ b/builtin/mainmenu/tab_server.lua @@ -186,10 +186,10 @@ local function main_button_handler(this, fields, name, tabdata) end -------------------------------------------------------------------------------- -tab_server = { +return { name = "server", caption = fgettext("Server"), cbf_formspec = get_formspec, cbf_button_handler = main_button_handler, on_change = nil - } +} diff --git a/builtin/mainmenu/tab_settings.lua b/builtin/mainmenu/tab_settings.lua index 6285968eb..2649a8a57 100644 --- a/builtin/mainmenu/tab_settings.lua +++ b/builtin/mainmenu/tab_settings.lua @@ -384,7 +384,7 @@ local function handle_settings_buttons(this, fields, tabname, tabdata) return ddhandled end -tab_settings = { +return { name = "settings", caption = fgettext("Settings"), cbf_formspec = formspec, diff --git a/builtin/mainmenu/tab_simple_main.lua b/builtin/mainmenu/tab_simple_main.lua index 434113b5f..b32418938 100644 --- a/builtin/mainmenu/tab_simple_main.lua +++ b/builtin/mainmenu/tab_simple_main.lua @@ -196,10 +196,10 @@ local function on_activate(type,old_tab,new_tab) end -------------------------------------------------------------------------------- -tab_simple_main = { +return { name = "main", caption = fgettext("Main"), cbf_formspec = get_formspec, cbf_button_handler = main_button_handler, on_change = on_activate - } +} diff --git a/builtin/mainmenu/tab_singleplayer.lua b/builtin/mainmenu/tab_singleplayer.lua index a40918af9..05060cbc6 100644 --- a/builtin/mainmenu/tab_singleplayer.lua +++ b/builtin/mainmenu/tab_singleplayer.lua @@ -241,10 +241,10 @@ local function on_change(type, old_tab, new_tab) end -------------------------------------------------------------------------------- -tab_singleplayer = { +return { name = "singleplayer", caption = fgettext("Singleplayer"), cbf_formspec = get_formspec, cbf_button_handler = main_button_handler, on_change = on_change - } +} diff --git a/builtin/mainmenu/tab_texturepacks.lua b/builtin/mainmenu/tab_texturepacks.lua index 2b0c77afc..a102fd61d 100644 --- a/builtin/mainmenu/tab_texturepacks.lua +++ b/builtin/mainmenu/tab_texturepacks.lua @@ -123,10 +123,10 @@ local function main_button_handler(tabview, fields, name, tabdata) end -------------------------------------------------------------------------------- -tab_texturepacks = { +return { name = "texturepacks", caption = fgettext("Texturepacks"), cbf_formspec = get_formspec, cbf_button_handler = main_button_handler, on_change = nil - } +} diff --git a/cmake/Modules/FindNcursesw.cmake b/cmake/Modules/FindNcursesw.cmake index dcb7cdda8..b8c7f78f2 100644 --- a/cmake/Modules/FindNcursesw.cmake +++ b/cmake/Modules/FindNcursesw.cmake @@ -147,6 +147,21 @@ if(CURSES_USE_NCURSESW) set(CURSES_HAVE_NCURSESW_CURSES_H "CURSES_HAVE_NCURSESW_CURSES_H-NOTFOUND") endif() endif() + if(NOT DEFINED CURSES_HAVE_NCURSES_H) + if(EXISTS "${CURSES_INCLUDE_PATH}/ncurses.h") + set(CURSES_HAVE_NCURSES_H "${CURSES_INCLUDE_PATH}/ncurses.h") + else() + set(CURSES_HAVE_NCURSES_H "CURSES_HAVE_NCURSES_H-NOTFOUND") + endif() + endif() + if(NOT DEFINED CURSES_HAVE_CURSES_H) + if(EXISTS "${CURSES_INCLUDE_PATH}/curses.h") + set(CURSES_HAVE_CURSES_H "${CURSES_INCLUDE_PATH}/curses.h") + else() + set(CURSES_HAVE_CURSES_H "CURSES_HAVE_CURSES_H-NOTFOUND") + endif() + endif() + find_library(CURSES_FORM_LIBRARY form HINTS "${_cursesLibDir}" DOC "Path to libform.so or .lib or .a") diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 4a4e345a9..a03a95d9e 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -361,9 +361,9 @@ Colorize the textures with the given color. it is an int, then it specifies how far to interpolate between the colors where 0 is only the texture color and 255 is only ``. If omitted, the alpha of `` will be used as the ratio. If it is -the word "`alpha`", then the alpha of the color will be multiplied with -the alpha of the texture with the RGB of the color replacing the RGB of -the texture. +the word "`alpha`", then each texture pixel will contain the RGB of +`` and the alpha of `` multiplied by the alpha of the +texture pixel. Sounds ------ diff --git a/src/client/tile.cpp b/src/client/tile.cpp index f0c0b4e9e..e6668063c 100644 --- a/src/client/tile.cpp +++ b/src/client/tile.cpp @@ -553,16 +553,11 @@ static void blit_with_alpha(video::IImage *src, video::IImage *dst, static void blit_with_alpha_overlay(video::IImage *src, video::IImage *dst, v2s32 src_pos, v2s32 dst_pos, v2u32 size); -// Like blit_with_alpha overlay, but uses an int to calculate the ratio -// and modifies any destination pixels that are not fully transparent -static void blit_with_interpolate_overlay(video::IImage *src, video::IImage *dst, - v2s32 src_pos, v2s32 dst_pos, v2u32 size, int ratio); - // Apply a color to an image. Uses an int (0-255) to calculate the ratio. // If the ratio is 255 or -1 and keep_alpha is true, then it multiples the // color alpha with the destination alpha. // Otherwise, any pixels that are not fully transparent get the color alpha. -static void apply_colorize(video::IImage *dst, v2s32 dst_pos, v2u32 size, +static void apply_colorize(video::IImage *dst, v2u32 dst_pos, v2u32 size, video::SColor color, int ratio, bool keep_alpha); // Apply a mask to an image @@ -1656,7 +1651,7 @@ bool TextureSource::generateImagePart(std::string part_of_name, else if (ratio_str == "alpha") keep_alpha = true; - apply_colorize(baseimg, v2s32(0, 0), baseimg->getDimension(), color, ratio, keep_alpha); + apply_colorize(baseimg, v2u32(0, 0), baseimg->getDimension(), color, ratio, keep_alpha); } else if (str_starts_with(part_of_name, "[applyfiltersformesh")) { @@ -1753,6 +1748,9 @@ static void blit_with_alpha_overlay(video::IImage *src, video::IImage *dst, } } +// This function has been disabled because it is currently unused. +// Feel free to re-enable if you find it handy. +#if 0 /* Draw an image on top of an another one, using the specified ratio modify all partially-opaque pixels in the destination. @@ -1779,11 +1777,12 @@ static void blit_with_interpolate_overlay(video::IImage *src, video::IImage *dst } } } +#endif /* Apply color to destination */ -static void apply_colorize(video::IImage *dst, v2s32 dst_pos, v2u32 size, +static void apply_colorize(video::IImage *dst, v2u32 dst_pos, v2u32 size, video::SColor color, int ratio, bool keep_alpha) { u32 alpha = color.getAlpha(); @@ -1791,8 +1790,8 @@ static void apply_colorize(video::IImage *dst, v2s32 dst_pos, v2u32 size, if ((ratio == -1 && alpha == 255) || ratio == 255) { // full replacement of color if (keep_alpha) { // replace the color with alpha = dest alpha * color alpha dst_c = color; - for (s32 y = dst_pos.Y; y < dst_pos.Y + size.Y; y++) - for (s32 x = dst_pos.X; x < dst_pos.X + size.X; x++) { + for (u32 y = dst_pos.Y; y < dst_pos.Y + size.Y; y++) + for (u32 x = dst_pos.X; x < dst_pos.X + size.X; x++) { u32 dst_alpha = dst->getPixel(x, y).getAlpha(); if (dst_alpha > 0) { dst_c.setAlpha(dst_alpha * alpha / 255); @@ -1800,15 +1799,15 @@ static void apply_colorize(video::IImage *dst, v2s32 dst_pos, v2u32 size, } } } else { // replace the color including the alpha - for (s32 y = dst_pos.Y; y < dst_pos.Y + size.Y; y++) - for (s32 x = dst_pos.X; x < dst_pos.X + size.X; x++) + for (u32 y = dst_pos.Y; y < dst_pos.Y + size.Y; y++) + for (u32 x = dst_pos.X; x < dst_pos.X + size.X; x++) if (dst->getPixel(x, y).getAlpha() > 0) dst->setPixel(x, y, color); } } else { // interpolate between the color and destination float interp = (ratio == -1 ? color.getAlpha() / 255.0f : ratio / 255.0f); - for (s32 y = dst_pos.Y; y < dst_pos.Y + size.Y; y++) - for (s32 x = dst_pos.X; x < dst_pos.X + size.X; x++) { + for (u32 y = dst_pos.Y; y < dst_pos.Y + size.Y; y++) + for (u32 x = dst_pos.X; x < dst_pos.X + size.X; x++) { dst_c = dst->getPixel(x, y); if (dst_c.getAlpha() > 0) { dst_c = color.getInterpolated(dst_c, interp); diff --git a/src/collision.cpp b/src/collision.cpp index 16db3310c..74c0c25c3 100644 --- a/src/collision.cpp +++ b/src/collision.cpp @@ -332,8 +332,10 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, // Do not move if world has not loaded yet, since custom node boxes // are not available for collision detection. - if (!any_position_valid) + if (!any_position_valid) { + *speed_f = v3f(0, 0, 0); return result; + } } // tt2 diff --git a/src/mapgen_flat.cpp b/src/mapgen_flat.cpp index 7a5302df0..ecfbe49ba 100644 --- a/src/mapgen_flat.cpp +++ b/src/mapgen_flat.cpp @@ -58,7 +58,8 @@ MapgenFlat::MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge //// amount of elements to skip for the next index //// for noise/height/biome maps (not vmanip) this->ystride = csize.X; - this->zstride = csize.X * (csize.Y + 2); + // 1-down overgeneration + this->zstride_1d = csize.X * (csize.Y + 1); this->biomemap = new u8[csize.X * csize.Z]; this->heightmap = new s16[csize.X * csize.Z]; @@ -80,8 +81,9 @@ MapgenFlat::MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z); //// 3D noise - noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 2, csize.Z); - noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 2, csize.Z); + // 1-down overgeneraion + noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z); + noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z); //// Biome noise noise_heat = new Noise(¶ms->np_biome_heat, seed, csize.X, csize.Z); @@ -566,19 +568,19 @@ void MapgenFlat::generateCaves(s16 max_stone_y) for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { bool column_is_open = false; // Is column open to overground bool is_tunnel = false; // Is tunnel or tunnel floor - u32 vi = vm->m_area.index(x, node_max.Y + 1, z); - u32 index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + + u32 vi = vm->m_area.index(x, node_max.Y, z); + u32 index3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride + (x - node_min.X); // Biome of column Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]); - for (s16 y = node_max.Y + 1; y >= node_min.Y - 1; - y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) { - // Don't excavate the overgenerated stone at node_max.Y + 1, - // this creates a 'roof' over the tunnel, preventing light in - // tunnels at mapchunk borders when generating mapchunks upwards. - if (y > node_max.Y) - continue; + // Don't excavate the overgenerated stone at node_max.Y + 1, + // this creates a 'roof' over the tunnel, preventing light in + // tunnels at mapchunk borders when generating mapchunks upwards. + // This 'roof' is removed when the mapchunk above is generated. + for (s16 y = node_max.Y; y >= node_min.Y - 1; y--, + index3d -= ystride, + vm->m_area.add_y(em, vi, -1)) { content_t c = vm->m_data[vi].getContent(); if (c == CONTENT_AIR || c == biome->c_water_top || diff --git a/src/mapgen_flat.h b/src/mapgen_flat.h index 282e42975..8ddfe708f 100644 --- a/src/mapgen_flat.h +++ b/src/mapgen_flat.h @@ -60,7 +60,7 @@ public: BiomeManager *bmgr; int ystride; - int zstride; + int zstride_1d; u32 spflags; v3s16 node_min; diff --git a/src/mapgen_fractal.cpp b/src/mapgen_fractal.cpp index 0430f92ff..810645abb 100644 --- a/src/mapgen_fractal.cpp +++ b/src/mapgen_fractal.cpp @@ -56,7 +56,8 @@ MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager * //// amount of elements to skip for the next index //// for noise/height/biome maps (not vmanip) this->ystride = csize.X; - this->zstride = csize.X * (csize.Y + 2); + // 1-down overgeneration + this->zstride_1d = csize.X * (csize.Y + 1); this->biomemap = new u8[csize.X * csize.Z]; this->heightmap = new s16[csize.X * csize.Z]; @@ -85,8 +86,9 @@ MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager * noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z); //// 3D terrain noise - noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 2, csize.Z); - noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 2, csize.Z); + // 1-down overgeneraion + noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z); + noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z); //// Biome noise noise_heat = new Noise(¶ms->np_biome_heat, seed, csize.X, csize.Z); @@ -694,19 +696,19 @@ void MapgenFractal::generateCaves(s16 max_stone_y) for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { bool column_is_open = false; // Is column open to overground bool is_tunnel = false; // Is tunnel or tunnel floor - u32 vi = vm->m_area.index(x, node_max.Y + 1, z); - u32 index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + + u32 vi = vm->m_area.index(x, node_max.Y, z); + u32 index3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride + (x - node_min.X); // Biome of column Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]); - for (s16 y = node_max.Y + 1; y >= node_min.Y - 1; - y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) { - // Don't excavate the overgenerated stone at node_max.Y + 1, - // this creates a 'roof' over the tunnel, preventing light in - // tunnels at mapchunk borders when generating mapchunks upwards. - if (y > node_max.Y) - continue; + // Don't excavate the overgenerated stone at node_max.Y + 1, + // this creates a 'roof' over the tunnel, preventing light in + // tunnels at mapchunk borders when generating mapchunks upwards. + // This 'roof' is removed when the mapchunk above is generated. + for (s16 y = node_max.Y; y >= node_min.Y - 1; y--, + index3d -= ystride, + vm->m_area.add_y(em, vi, -1)) { content_t c = vm->m_data[vi].getContent(); if (c == CONTENT_AIR || c == biome->c_water_top || diff --git a/src/mapgen_fractal.h b/src/mapgen_fractal.h index ffb2acfb9..8c21a8a4e 100644 --- a/src/mapgen_fractal.h +++ b/src/mapgen_fractal.h @@ -65,7 +65,7 @@ public: BiomeManager *bmgr; int ystride; - int zstride; + int zstride_1d; u16 formula; bool julia; diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp index 42fbe4423..54abba145 100644 --- a/src/mapgen_v7.cpp +++ b/src/mapgen_v7.cpp @@ -59,7 +59,8 @@ MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge) //// amount of elements to skip for the next index //// for noise/height/biome maps (not vmanip) this->ystride = csize.X; - this->zstride = csize.X * (csize.Y + 2); + // 1-down overgeneration + this->zstride_1d = csize.X * (csize.Y + 1); this->biomemap = new u8[csize.X * csize.Z]; this->heightmap = new s16[csize.X * csize.Z]; @@ -80,10 +81,12 @@ MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge) noise_ridge_uwater = new Noise(&sp->np_ridge_uwater, seed, csize.X, csize.Z); //// 3d terrain noise + // 1-up 1-down overgeneration noise_mountain = new Noise(&sp->np_mountain, seed, csize.X, csize.Y + 2, csize.Z); noise_ridge = new Noise(&sp->np_ridge, seed, csize.X, csize.Y + 2, csize.Z); - noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 2, csize.Z); - noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 2, csize.Z); + // 1-down overgeneraion + noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z); + noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z); //// Biome noise noise_heat = new Noise(¶ms->np_biome_heat, seed, csize.X, csize.Z); @@ -199,7 +202,7 @@ void MapgenV7Params::writeParams(Settings *settings) const } -/////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// int MapgenV7::getSpawnLevelAtPoint(v2s16 p) @@ -451,41 +454,6 @@ bool MapgenV7::getMountainTerrainFromMap(int idx_xyz, int idx_xz, s16 y) } -#if 0 -void MapgenV7::carveRivers() { - MapNode n_air(CONTENT_AIR), n_water_source(c_water_source); - MapNode n_stone(c_stone); - u32 index = 0; - - int river_depth = 4; - - for (s16 z = node_min.Z; z <= node_max.Z; z++) - for (s16 x = node_min.X; x <= node_max.X; x++, index++) { - float terrain_mod = noise_terrain_mod->result[index]; - NoiseParams *np = noise_terrain_river->np; - np.persist = noise_terrain_persist->result[index]; - float terrain_river = NoisePerlin2DNoTxfm(np, x, z, seed); - float height = terrain_river * (1 - abs(terrain_mod)) * - noise_terrain_river->np.scale; - height = log(height * height); //log(h^3) is pretty interesting for terrain - - s16 y = heightmap[index]; - if (height < 1.0 && y > river_depth && - y - river_depth >= node_min.Y && y <= node_max.Y) { - - for (s16 ry = y; ry != y - river_depth; ry--) { - u32 vi = vm->m_area.index(x, ry, z); - vm->m_data[vi] = n_air; - } - - u32 vi = vm->m_area.index(x, y - river_depth, z); - vm->m_data[vi] = n_water_source; - } - } -} -#endif - - int MapgenV7::generateTerrain() { s16 stone_surface_min_y; @@ -765,6 +733,112 @@ void MapgenV7::dustTopNodes() } +void MapgenV7::generateCaves(s16 max_stone_y) +{ + if (max_stone_y < node_min.Y) + return; + + noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); + noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); + + v3s16 em = vm->m_area.getExtent(); + u32 index2d = 0; + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { + bool column_is_open = false; // Is column open to overground + bool is_tunnel = false; // Is tunnel or tunnel floor + // Indexes at column top (node_max.Y) + u32 vi = vm->m_area.index(x, node_max.Y, z); + u32 index3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride + + (x - node_min.X); + // Biome of column + Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]); + + // Don't excavate the overgenerated stone at node_max.Y + 1, + // this creates a 'roof' over the tunnel, preventing light in + // tunnels at mapchunk borders when generating mapchunks upwards. + // This 'roof' is removed when the mapchunk above is generated. + for (s16 y = node_max.Y; y >= node_min.Y - 1; y--, + index3d -= ystride, + vm->m_area.add_y(em, vi, -1)) { + + content_t c = vm->m_data[vi].getContent(); + if (c == CONTENT_AIR || c == biome->c_water_top || + c == biome->c_water) { + column_is_open = true; + continue; + } + // Ground + float d1 = contour(noise_cave1->result[index3d]); + float d2 = contour(noise_cave2->result[index3d]); + if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) { + // In tunnel and ground content, excavate + vm->m_data[vi] = MapNode(CONTENT_AIR); + is_tunnel = true; + } else if (is_tunnel && column_is_open && + (c == biome->c_filler || c == biome->c_stone)) { + // Tunnel entrance floor + vm->m_data[vi] = MapNode(biome->c_top); + column_is_open = false; + is_tunnel = false; + } else { + column_is_open = false; + is_tunnel = false; + } + } + } + + if (node_min.Y >= water_level) + return; + + PseudoRandom ps(blockseed + 21343); + u32 bruises_count = ps.range(0, 2); + for (u32 i = 0; i < bruises_count; i++) { + CaveV7 cave(this, &ps); + cave.makeCave(node_min, node_max, max_stone_y); + } +} + + +/////////////////////////////////////////////////////////////// + + +#if 0 +void MapgenV7::carveRivers() { + MapNode n_air(CONTENT_AIR), n_water_source(c_water_source); + MapNode n_stone(c_stone); + u32 index = 0; + + int river_depth = 4; + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index++) { + float terrain_mod = noise_terrain_mod->result[index]; + NoiseParams *np = noise_terrain_river->np; + np.persist = noise_terrain_persist->result[index]; + float terrain_river = NoisePerlin2DNoTxfm(np, x, z, seed); + float height = terrain_river * (1 - abs(terrain_mod)) * + noise_terrain_river->np.scale; + height = log(height * height); //log(h^3) is pretty interesting for terrain + + s16 y = heightmap[index]; + if (height < 1.0 && y > river_depth && + y - river_depth >= node_min.Y && y <= node_max.Y) { + + for (s16 ry = y; ry != y - river_depth; ry--) { + u32 vi = vm->m_area.index(x, ry, z); + vm->m_data[vi] = n_air; + } + + u32 vi = vm->m_area.index(x, y - river_depth, z); + vm->m_data[vi] = n_water_source; + } + } +} +#endif + + #if 0 void MapgenV7::addTopNodes() { @@ -859,70 +933,3 @@ void MapgenV7::addTopNodes() } } #endif - - -void MapgenV7::generateCaves(s16 max_stone_y) -{ - if (max_stone_y < node_min.Y) - return; - - noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); - noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); - - v3s16 em = vm->m_area.getExtent(); - u32 index2d = 0; - - for (s16 z = node_min.Z; z <= node_max.Z; z++) - for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { - bool column_is_open = false; // Is column open to overground - bool is_tunnel = false; // Is tunnel or tunnel floor - u32 vi = vm->m_area.index(x, node_max.Y + 1, z); - u32 index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + - (x - node_min.X); - // Biome of column - Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]); - - for (s16 y = node_max.Y + 1; y >= node_min.Y - 1; - y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) { - // Don't excavate the overgenerated stone at node_max.Y + 1, - // this creates a 'roof' over the tunnel, preventing light in - // tunnels at mapchunk borders when generating mapchunks upwards. - if (y > node_max.Y) - continue; - - content_t c = vm->m_data[vi].getContent(); - if (c == CONTENT_AIR || c == biome->c_water_top || - c == biome->c_water) { - column_is_open = true; - continue; - } - // Ground - float d1 = contour(noise_cave1->result[index3d]); - float d2 = contour(noise_cave2->result[index3d]); - if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) { - // In tunnel and ground content, excavate - vm->m_data[vi] = MapNode(CONTENT_AIR); - is_tunnel = true; - } else if (is_tunnel && column_is_open && - (c == biome->c_filler || c == biome->c_stone)) { - // Tunnel entrance floor - vm->m_data[vi] = MapNode(biome->c_top); - column_is_open = false; - is_tunnel = false; - } else { - column_is_open = false; - is_tunnel = false; - } - } - } - - if (node_min.Y >= water_level) - return; - - PseudoRandom ps(blockseed + 21343); - u32 bruises_count = ps.range(0, 2); - for (u32 i = 0; i < bruises_count; i++) { - CaveV7 cave(this, &ps); - cave.makeCave(node_min, node_max, max_stone_y); - } -} diff --git a/src/mapgen_v7.h b/src/mapgen_v7.h index 82f89387b..9fdecf592 100644 --- a/src/mapgen_v7.h +++ b/src/mapgen_v7.h @@ -59,7 +59,7 @@ public: BiomeManager *bmgr; int ystride; - int zstride; + int zstride_1d; u32 spflags; v3s16 node_min; diff --git a/src/mapgen_valleys.cpp b/src/mapgen_valleys.cpp index 34a316abd..be122aace 100644 --- a/src/mapgen_valleys.cpp +++ b/src/mapgen_valleys.cpp @@ -74,6 +74,8 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager * //// for noise/height/biome maps (not vmanip) this->ystride = csize.X; this->zstride = csize.X * (csize.Y + 2); + // 1-down overgeneration + this->zstride_1d = csize.X * (csize.Y + 1); this->biomemap = new u8[csize.X * csize.Z]; this->heightmap = new s16[csize.X * csize.Z]; @@ -113,10 +115,12 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager * noise_valley_profile = new Noise(&sp->np_valley_profile, seed, csize.X, csize.Z); //// 3D Terrain noise - noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 2, csize.Z); - noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 2, csize.Z); + // 1-up 1-down overgeneration noise_inter_valley_fill = new Noise(&sp->np_inter_valley_fill, seed, csize.X, csize.Y + 2, csize.Z); - noise_massive_caves = new Noise(&sp->np_massive_caves, seed, csize.X, csize.Y + 2, csize.Z); + // 1-down overgeneraion + noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z); + noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z); + noise_massive_caves = new Noise(&sp->np_massive_caves, seed, csize.X, csize.Y + 1, csize.Z); //// Biome noise noise_heat_blend = new Noise(¶ms->np_biome_heat_blend, seed, csize.X, csize.Z); @@ -885,7 +889,7 @@ void MapgenValleys::generateCaves(s16 max_stone_y) if (node_max.Y <= massive_cave_depth) { noise_massive_caves->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); - for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { + for (s16 y = node_min.Y - 1; y <= node_max.Y; y++) { float tcave = massive_cave_threshold; if (y < yblmin) { @@ -923,19 +927,17 @@ void MapgenValleys::generateCaves(s16 max_stone_y) Biome *biome = (Biome *)bmgr->getRaw(biomemap[index_2d]); bool air_above = false; bool underground = false; - u32 index_data = vm->m_area.index(x, node_max.Y + 1, z); - - index_3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + (x - node_min.X); + u32 index_data = vm->m_area.index(x, node_max.Y, z); + index_3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride + (x - node_min.X); // Dig caves on down loop to check for air above. - for (s16 y = node_max.Y + 1; - y >= node_min.Y - 1; - y--, index_3d -= ystride, vm->m_area.add_y(em, index_data, -1)) { - // Don't excavate the overgenerated stone at node_max.Y + 1, - // this creates a 'roof' over the tunnel, preventing light in - // tunnels at mapchunk borders when generating mapchunks upwards. - if (y > node_max.Y) - continue; + // Don't excavate the overgenerated stone at node_max.Y + 1, + // this creates a 'roof' over the tunnel, preventing light in + // tunnels at mapchunk borders when generating mapchunks upwards. + // This 'roof' is removed when the mapchunk above is generated. + for (s16 y = node_max.Y; y >= node_min.Y - 1; y--, + index_3d -= ystride, + vm->m_area.add_y(em, index_data, -1)) { float terrain = noise_terrain_height->result[index_2d]; diff --git a/src/mapgen_valleys.h b/src/mapgen_valleys.h index 6b3eb9cfe..4ad2d2076 100644 --- a/src/mapgen_valleys.h +++ b/src/mapgen_valleys.h @@ -106,6 +106,7 @@ private: int ystride; int zstride; + int zstride_1d; float map_gen_limit;