Merge
commit
6d3bdc5a7d
|
@ -147,7 +147,7 @@ end
|
|||
-- Some common functions
|
||||
--
|
||||
|
||||
function nodeupdate_single(p, delay)
|
||||
function nodeupdate_single(p)
|
||||
local n = core.get_node(p)
|
||||
if core.get_item_group(n.name, "falling_node") ~= 0 then
|
||||
local p_bottom = {x = p.x, y = p.y - 1, z = p.z}
|
||||
|
@ -160,36 +160,84 @@ function nodeupdate_single(p, delay)
|
|||
core.get_node_level(p_bottom) < core.get_node_max_level(p_bottom))) and
|
||||
(not core.registered_nodes[n_bottom.name].walkable or
|
||||
core.registered_nodes[n_bottom.name].buildable_to) then
|
||||
if delay then
|
||||
core.after(0.1, nodeupdate_single, p, false)
|
||||
else
|
||||
n.level = core.get_node_level(p)
|
||||
core.remove_node(p)
|
||||
spawn_falling_node(p, n)
|
||||
nodeupdate(p)
|
||||
end
|
||||
n.level = core.get_node_level(p)
|
||||
core.remove_node(p)
|
||||
spawn_falling_node(p, n)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
if core.get_item_group(n.name, "attached_node") ~= 0 then
|
||||
if not check_attached_node(p, n) then
|
||||
drop_attached_node(p)
|
||||
nodeupdate(p)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function nodeupdate(p, delay)
|
||||
-- Round p to prevent falling entities to get stuck
|
||||
-- This table is specifically ordered.
|
||||
-- We don't walk diagonals, only our direct neighbors, and self.
|
||||
-- Down first as likely case, but always before self. The same with sides.
|
||||
-- Up must come last, so that things above self will also fall all at once.
|
||||
local nodeupdate_neighbors = {
|
||||
{x = 0, y = -1, z = 0},
|
||||
{x = -1, y = 0, z = 0},
|
||||
{x = 1, y = 0, z = 0},
|
||||
{x = 0, y = 0, z = 1},
|
||||
{x = 0, y = 0, z = -1},
|
||||
{x = 0, y = 0, z = 0},
|
||||
{x = 0, y = 1, z = 0},
|
||||
}
|
||||
|
||||
function nodeupdate(p)
|
||||
-- Round p to prevent falling entities to get stuck.
|
||||
p = vector.round(p)
|
||||
|
||||
for x = -1, 1 do
|
||||
for y = -1, 1 do
|
||||
for z = -1, 1 do
|
||||
local d = vector.new(x, y, z)
|
||||
nodeupdate_single(vector.add(p, d), delay or not (x == 0 and y == 0 and z == 0))
|
||||
end
|
||||
end
|
||||
-- We make a stack, and manually maintain size for performance.
|
||||
-- Stored in the stack, we will maintain tables with pos, and
|
||||
-- last neighbor visited. This way, when we get back to each
|
||||
-- node, we know which directions we have already walked, and
|
||||
-- which direction is the next to walk.
|
||||
local s = {}
|
||||
local n = 0
|
||||
-- The neighbor order we will visit from our table.
|
||||
local v = 1
|
||||
|
||||
while true do
|
||||
-- Push current pos onto the stack.
|
||||
n = n + 1
|
||||
s[n] = {p = p, v = v}
|
||||
-- Select next node from neighbor list.
|
||||
p = vector.add(p, nodeupdate_neighbors[v])
|
||||
-- Now we check out the node. If it is in need of an update,
|
||||
-- it will let us know in the return value (true = updated).
|
||||
if not nodeupdate_single(p) then
|
||||
-- If we don't need to "recurse" (walk) to it then pop
|
||||
-- our previous pos off the stack and continue from there,
|
||||
-- with the v value we were at when we last were at that
|
||||
-- node
|
||||
repeat
|
||||
local pop = s[n]
|
||||
p = pop.p
|
||||
v = pop.v
|
||||
s[n] = nil
|
||||
n = n - 1
|
||||
-- If there's nothing left on the stack, and no
|
||||
-- more sides to walk to, we're done and can exit
|
||||
if n == 0 and v == 7 then
|
||||
return
|
||||
end
|
||||
until v < 7
|
||||
-- The next round walk the next neighbor in list.
|
||||
v = v + 1
|
||||
else
|
||||
-- If we did need to walk the neighbor, then
|
||||
-- start walking it from the walk order start (1),
|
||||
-- and not the order we just pushed up the stack.
|
||||
v = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -35,24 +35,31 @@ dofile(basepath .. DIR_DELIM .. "fstk" .. DIR_DELIM .. "tabview.lua")
|
|||
dofile(basepath .. DIR_DELIM .. "fstk" .. DIR_DELIM .. "ui.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "common.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "gamemgr.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "store.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "dlg_config_world.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "tab_credits.lua")
|
||||
if not (PLATFORM == "Android") then
|
||||
if PLATFORM ~= "Android" then
|
||||
dofile(menupath .. DIR_DELIM .. "modmgr.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "tab_settings.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "dlg_settings_advanced.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "tab_texturepacks.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "tab_mods.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "dlg_delete_mod.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "store.lua")
|
||||
end
|
||||
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 .. "tab_multiplayer.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "tab_server.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "tab_singleplayer.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "textures.lua")
|
||||
--dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "dlg_config_world.lua")
|
||||
if PLATFORM ~= "Android" then
|
||||
dofile(menupath .. DIR_DELIM .. "dlg_settings_advanced.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "textures.lua")
|
||||
end
|
||||
|
||||
local tabs = {}
|
||||
|
||||
--tabs.mods = dofile(menupath .. DIR_DELIM .. "tab_mods.lua")
|
||||
tabs.credits = dofile(menupath .. DIR_DELIM .. "tab_credits.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")
|
||||
if PLATFORM ~= "Android" then
|
||||
tabs.settings = dofile(menupath .. DIR_DELIM .. "tab_settings.lua")
|
||||
tabs.texturepacks = dofile(menupath .. DIR_DELIM .. "tab_texturepacks.lua")
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function main_event_handler(tabview, event)
|
||||
|
@ -67,66 +74,64 @@ local function init_globals()
|
|||
-- Init gamedata
|
||||
gamedata.worldindex = 0
|
||||
|
||||
menudata.worldlist = filterlist.create(
|
||||
core.get_worlds,
|
||||
compare_worlds,
|
||||
-- Unique id comparison function
|
||||
function(element, uid)
|
||||
return element.name == uid
|
||||
end,
|
||||
-- Filter function
|
||||
function(element, gameid)
|
||||
return element.gameid == gameid
|
||||
end
|
||||
)
|
||||
|
||||
menudata.worldlist = filterlist.create(
|
||||
core.get_worlds,
|
||||
compare_worlds,
|
||||
-- Unique id comparison function
|
||||
function(element, uid)
|
||||
return element.name == uid
|
||||
end,
|
||||
-- Filter function
|
||||
function(element, gameid)
|
||||
return element.gameid == gameid
|
||||
end
|
||||
)
|
||||
menudata.worldlist:add_sort_mechanism("alphabetic", sort_worlds_alphabetic)
|
||||
menudata.worldlist:set_sortmode("alphabetic")
|
||||
|
||||
menudata.worldlist:add_sort_mechanism("alphabetic", sort_worlds_alphabetic)
|
||||
menudata.worldlist:set_sortmode("alphabetic")
|
||||
core.setting_set("menu_last_game", "default")
|
||||
|
||||
core.setting_set("menu_last_game", "default")
|
||||
|
||||
mm_texture.init()
|
||||
mm_texture.init()
|
||||
|
||||
-- Create main tabview
|
||||
local tv_main = tabview_create("maintab",{x=12,y=5.2},{x=0,y=0})
|
||||
local tv_main = tabview_create("maintab", {x = 12, y = 5.2}, {x = 0, y = 0})
|
||||
|
||||
--tv_main:set_autosave_tab(true)
|
||||
tv_main:add(tabs.singleplayer)
|
||||
tv_main:add(tabs.multiplayer)
|
||||
tv_main:add(tabs.server)
|
||||
|
||||
if PLATFORM ~= "Android" then
|
||||
tv_main:set_autosave_tab(true)
|
||||
tv_main:add(tabs.settings)
|
||||
tv_main:add(tabs.texturepacks)
|
||||
end
|
||||
tv_main:add(tab_singleplayer)
|
||||
tv_main:add(tab_multiplayer)
|
||||
tv_main:add(tab_server)
|
||||
if PLATFORM ~= "Android" then
|
||||
tv_main:add(tab_settings)
|
||||
tv_main:add(tab_texturepacks)
|
||||
--tv_main:add(tab_mods)
|
||||
end
|
||||
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
|
||||
tv_main:set_tab(core.setting_get("maintab_LAST"))
|
||||
end
|
||||
--if PLATFORM ~= "Android" then
|
||||
-- tv_main:set_tab(core.setting_get("maintab_LAST"))
|
||||
--end
|
||||
ui.set_default("maintab")
|
||||
tv_main:show()
|
||||
|
||||
-- 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()
|
||||
|
||||
core.sound_play("main_menu", false)
|
||||
|
||||
|
||||
minetest.set_clouds(false)
|
||||
core.set_background("background", defaulttexturedir .. "background.jpg");
|
||||
end
|
||||
|
||||
init_globals()
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ local previous_contributors = {
|
|||
"Zefram <zefram@fysh.org>",
|
||||
}
|
||||
|
||||
tab_credits = {
|
||||
return {
|
||||
name = "credits",
|
||||
caption = fgettext("Credits"),
|
||||
cbf_formspec = function(tabview, name, tabdata)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -256,10 +256,10 @@ local function on_change(type,old_tab,new_tab)
|
|||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
tab_multiplayer = {
|
||||
return {
|
||||
name = "multiplayer",
|
||||
caption = fgettext("Multi Player"),
|
||||
cbf_formspec = get_formspec,
|
||||
cbf_button_handler = main_button_handler,
|
||||
on_change = on_change
|
||||
}
|
||||
}
|
||||
|
|
|
@ -186,10 +186,10 @@ local function main_button_handler(this, fields, name, tabdata)
|
|||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
tab_server = {
|
||||
return {
|
||||
name = "server",
|
||||
caption = fgettext("Create Server"),
|
||||
cbf_formspec = get_formspec,
|
||||
cbf_button_handler = main_button_handler,
|
||||
on_change = nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -145,9 +145,10 @@ end
|
|||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
tab_singleplayer = {
|
||||
return {
|
||||
name = "singleplayer",
|
||||
caption = fgettext("Single Player"),
|
||||
cbf_formspec = get_formspec,
|
||||
cbf_button_handler = main_button_handler,
|
||||
}
|
||||
on_change = on_change
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -357,8 +357,13 @@ The mask is applied using binary AND.
|
|||
#### `[colorize:<color>:<ratio>`
|
||||
Colorize the textures with the given color.
|
||||
`<color>` is specified as a `ColorString`.
|
||||
`<ratio>` is an int ranging from 0 to 255, and specifies how much of the
|
||||
color to apply. If ommitted, the alpha will be used.
|
||||
`<ratio>` is an int ranging from 0 to 255 or the word "`alpha`". If
|
||||
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 `<color>`. If
|
||||
omitted, the alpha of `<color>` will be used as the ratio. If it is
|
||||
the word "`alpha`", then each texture pixel will contain the RGB of
|
||||
`<color>` and the alpha of `<color>` multiplied by the alpha of the
|
||||
texture pixel.
|
||||
|
||||
Sounds
|
||||
------
|
||||
|
@ -940,6 +945,7 @@ Displays a horizontal bar made up of half-images.
|
|||
* `number`: Number of items in the inventory to be displayed.
|
||||
* `item`: Position of item that is selected.
|
||||
* `direction`
|
||||
* `offset`: offset in pixels from position.
|
||||
|
||||
### `waypoint`
|
||||
Displays distance to selected world position.
|
||||
|
@ -1865,6 +1871,7 @@ Call these functions only at load time!
|
|||
* `modifier`: when true, the function should return the actual hp_change.
|
||||
Note: modifiers only get a temporary hp_change that can be modified by later modifiers.
|
||||
modifiers can return true as a second argument to stop the execution of further functions.
|
||||
Non-modifiers receive the final hp change calculated by the modifiers.
|
||||
* `minetest.register_on_respawnplayer(func(ObjectRef))`
|
||||
* Called when player is to be respawned
|
||||
* Called _before_ repositioning of player occurs
|
||||
|
|
|
@ -540,6 +540,12 @@ void Camera::drawNametags()
|
|||
i = m_nametags.begin();
|
||||
i != m_nametags.end(); ++i) {
|
||||
Nametag *nametag = *i;
|
||||
if (nametag->nametag_color.getAlpha() == 0) {
|
||||
// Enforce hiding nametag,
|
||||
// because if freetype is enabled, a grey
|
||||
// shadow can remain.
|
||||
continue;
|
||||
}
|
||||
v3f pos = nametag->parent_node->getPosition() + v3f(0.0, 1.1 * BS, 0.0);
|
||||
f32 transformed_pos[4] = { pos.X, pos.Y, pos.Z, 1.0f };
|
||||
trans.multiplyWith1x4Matrix(transformed_pos);
|
||||
|
|
|
@ -265,7 +265,7 @@ Client::Client(
|
|||
m_cache_smooth_lighting = g_settings->getBool("smooth_lighting");
|
||||
m_cache_enable_shaders = g_settings->getBool("enable_shaders");
|
||||
m_cache_use_tangent_vertices = m_cache_enable_shaders && (
|
||||
g_settings->getBool("enable_bumpmapping") ||
|
||||
g_settings->getBool("enable_bumpmapping") ||
|
||||
g_settings->getBool("enable_parallax_occlusion"));
|
||||
}
|
||||
|
||||
|
|
|
@ -553,10 +553,12 @@ 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, v2u32 dst_pos, v2u32 size,
|
||||
video::SColor color, int ratio, bool keep_alpha);
|
||||
|
||||
// Apply a mask to an image
|
||||
static void apply_mask(video::IImage *mask, video::IImage *dst,
|
||||
|
@ -1643,27 +1645,17 @@ bool TextureSource::generateImagePart(std::string part_of_name,
|
|||
|
||||
video::SColor color;
|
||||
int ratio = -1;
|
||||
bool keep_alpha = false;
|
||||
|
||||
if (!parseColorString(color_str, color, false))
|
||||
return false;
|
||||
|
||||
if (is_number(ratio_str))
|
||||
ratio = mystoi(ratio_str, 0, 255);
|
||||
else if (ratio_str == "alpha")
|
||||
keep_alpha = true;
|
||||
|
||||
core::dimension2d<u32> dim = baseimg->getDimension();
|
||||
video::IImage *img = driver->createImage(video::ECF_A8R8G8B8, dim);
|
||||
|
||||
if (!img) {
|
||||
errorstream << "generateImagePart(): Could not create image "
|
||||
<< "for part_of_name=\"" << part_of_name
|
||||
<< "\", cancelling." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
img->fill(video::SColor(color));
|
||||
// Overlay the colored image
|
||||
blit_with_interpolate_overlay(img, baseimg, v2s32(0,0), v2s32(0,0), dim, ratio);
|
||||
img->drop();
|
||||
apply_colorize(baseimg, v2u32(0, 0), baseimg->getDimension(), color, ratio, keep_alpha);
|
||||
}
|
||||
else if (str_starts_with(part_of_name, "[applyfiltersformesh"))
|
||||
{
|
||||
|
@ -1760,6 +1752,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.
|
||||
|
@ -1786,6 +1781,45 @@ static void blit_with_interpolate_overlay(video::IImage *src, video::IImage *dst
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
Apply color to destination
|
||||
*/
|
||||
static void apply_colorize(video::IImage *dst, v2u32 dst_pos, v2u32 size,
|
||||
video::SColor color, int ratio, bool keep_alpha)
|
||||
{
|
||||
u32 alpha = color.getAlpha();
|
||||
video::SColor dst_c;
|
||||
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 (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);
|
||||
dst->setPixel(x, y, dst_c);
|
||||
}
|
||||
}
|
||||
} else { // replace the color including the alpha
|
||||
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 (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);
|
||||
dst->setPixel(x, y, dst_c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Apply mask to destination
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ DungeonGen::DungeonGen(Mapgen *mapgen, DungeonParams *dparams)
|
|||
this->vm = mapgen->vm;
|
||||
|
||||
#ifdef DGEN_USE_TORCHES
|
||||
c_torch = ndef->getId("default:torch");
|
||||
c_torch = mg->ndef->getId("default:torch");
|
||||
#endif
|
||||
|
||||
if (dparams) {
|
||||
|
|
107
src/hud.cpp
107
src/hud.cpp
|
@ -41,7 +41,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
|
||||
gui::IGUIEnvironment* guienv, IGameDef *gamedef, LocalPlayer *player,
|
||||
Inventory *inventory) {
|
||||
Inventory *inventory)
|
||||
{
|
||||
this->driver = driver;
|
||||
this->smgr = smgr;
|
||||
this->guienv = guienv;
|
||||
|
@ -49,16 +50,15 @@ Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
|
|||
this->player = player;
|
||||
this->inventory = inventory;
|
||||
|
||||
m_hud_scaling = g_settings->getFloat("hud_scaling");
|
||||
m_screensize = v2u32(0, 0);
|
||||
m_displaycenter = v2s32(0, 0);
|
||||
m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE * porting::getDisplayDensity() + 0.5);
|
||||
m_hotbar_imagesize *= g_settings->getFloat("hud_scaling");
|
||||
m_hotbar_imagesize *= m_hud_scaling;
|
||||
m_padding = m_hotbar_imagesize / 12;
|
||||
|
||||
const video::SColor hbar_color(255, 255, 255, 255);
|
||||
for (unsigned int i=0; i < 4; i++ ){
|
||||
hbar_colors[i] = hbar_color;
|
||||
}
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
hbar_colors[i] = video::SColor(255, 255, 255, 255);
|
||||
|
||||
tsrc = gamedef->getTextureSource();
|
||||
|
||||
|
@ -102,7 +102,7 @@ Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
|
|||
if (mode == "box") {
|
||||
m_use_selection_mesh = false;
|
||||
m_selection_material.Thickness =
|
||||
rangelim(g_settings->getS16("selectionbox_width"), 1, 5);
|
||||
rangelim(g_settings->getS16("selectionbox_width"), 1, 5);
|
||||
} else if (mode == "halo") {
|
||||
m_use_selection_mesh = true;
|
||||
m_selection_material.setTexture(0, tsrc->getTextureForMesh("halo.png"));
|
||||
|
@ -196,25 +196,30 @@ void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect,
|
|||
}
|
||||
|
||||
//NOTE: selectitem = 0 -> no selected; selectitem 1-based
|
||||
void Hud::drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
|
||||
InventoryList *mainlist, u16 selectitem, u16 direction)
|
||||
void Hud::drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount,
|
||||
s32 inv_offset, InventoryList *mainlist, u16 selectitem, u16 direction)
|
||||
{
|
||||
#ifdef HAVE_TOUCHSCREENGUI
|
||||
if ( (g_touchscreengui) && (offset == 0))
|
||||
if (g_touchscreengui && inv_offset == 0)
|
||||
g_touchscreengui->resetHud();
|
||||
#endif
|
||||
|
||||
s32 height = m_hotbar_imagesize + m_padding * 2;
|
||||
s32 width = (itemcount - offset) * (m_hotbar_imagesize + m_padding * 2);
|
||||
s32 width = (itemcount - inv_offset) * (m_hotbar_imagesize + m_padding * 2);
|
||||
|
||||
if (direction == HUD_DIR_TOP_BOTTOM || direction == HUD_DIR_BOTTOM_TOP) {
|
||||
width = m_hotbar_imagesize + m_padding * 2;
|
||||
height = (itemcount - offset) * (m_hotbar_imagesize + m_padding * 2);
|
||||
s32 tmp = height;
|
||||
height = width;
|
||||
width = tmp;
|
||||
}
|
||||
|
||||
// Position of upper left corner of bar
|
||||
v2s32 pos = upperleftpos;
|
||||
v2s32 pos = screen_offset;
|
||||
pos.X *= m_hud_scaling * porting::getDisplayDensity();
|
||||
pos.Y *= m_hud_scaling * porting::getDisplayDensity();
|
||||
pos += upperleftpos;
|
||||
|
||||
// Store hotbar_image in member variable, used by drawItem()
|
||||
if (hotbar_image != player->hotbar_image) {
|
||||
hotbar_image = player->hotbar_image;
|
||||
if (hotbar_image != "")
|
||||
|
@ -223,6 +228,7 @@ void Hud::drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
|
|||
use_hotbar_image = false;
|
||||
}
|
||||
|
||||
// Store hotbar_selected_image in member variable, used by drawItem()
|
||||
if (hotbar_selected_image != player->hotbar_selected_image) {
|
||||
hotbar_selected_image = player->hotbar_selected_image;
|
||||
if (hotbar_selected_image != "")
|
||||
|
@ -231,10 +237,10 @@ void Hud::drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
|
|||
use_hotbar_selected_image = false;
|
||||
}
|
||||
|
||||
/* draw customized item background */
|
||||
// draw customized item background
|
||||
if (use_hotbar_image) {
|
||||
core::rect<s32> imgrect2(-m_padding/2, -m_padding/2,
|
||||
width+m_padding/2, height+m_padding/2);
|
||||
width+m_padding/2, height+m_padding/2);
|
||||
core::rect<s32> rect2 = imgrect2 + pos;
|
||||
video::ITexture *texture = tsrc->getTexture(hotbar_image);
|
||||
core::dimension2di imgsize(texture->getOriginalSize());
|
||||
|
@ -243,29 +249,28 @@ void Hud::drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
|
|||
NULL, hbar_colors, true);
|
||||
}
|
||||
|
||||
for (s32 i = offset; i < itemcount && (size_t)i < mainlist->getSize(); i++)
|
||||
{
|
||||
v2s32 steppos;
|
||||
// Draw items
|
||||
core::rect<s32> imgrect(0, 0, m_hotbar_imagesize, m_hotbar_imagesize);
|
||||
for (s32 i = inv_offset; i < itemcount && (size_t)i < mainlist->getSize(); i++) {
|
||||
s32 fullimglen = m_hotbar_imagesize + m_padding * 2;
|
||||
|
||||
core::rect<s32> imgrect(0, 0, m_hotbar_imagesize, m_hotbar_imagesize);
|
||||
|
||||
v2s32 steppos;
|
||||
switch (direction) {
|
||||
case HUD_DIR_RIGHT_LEFT:
|
||||
steppos = v2s32(-(m_padding + (i - offset) * fullimglen), m_padding);
|
||||
break;
|
||||
case HUD_DIR_TOP_BOTTOM:
|
||||
steppos = v2s32(m_padding, m_padding + (i - offset) * fullimglen);
|
||||
break;
|
||||
case HUD_DIR_BOTTOM_TOP:
|
||||
steppos = v2s32(m_padding, -(m_padding + (i - offset) * fullimglen));
|
||||
break;
|
||||
default:
|
||||
steppos = v2s32(m_padding + (i - offset) * fullimglen, m_padding);
|
||||
break;
|
||||
case HUD_DIR_RIGHT_LEFT:
|
||||
steppos = v2s32(-(m_padding + (i - inv_offset) * fullimglen), m_padding);
|
||||
break;
|
||||
case HUD_DIR_TOP_BOTTOM:
|
||||
steppos = v2s32(m_padding, m_padding + (i - inv_offset) * fullimglen);
|
||||
break;
|
||||
case HUD_DIR_BOTTOM_TOP:
|
||||
steppos = v2s32(m_padding, -(m_padding + (i - inv_offset) * fullimglen));
|
||||
break;
|
||||
default:
|
||||
steppos = v2s32(m_padding + (i - inv_offset) * fullimglen, m_padding);
|
||||
break;
|
||||
}
|
||||
|
||||
drawItem(mainlist->getItem(i), (imgrect + pos + steppos), (i +1) == selectitem );
|
||||
drawItem(mainlist->getItem(i), (imgrect + pos + steppos), (i + 1) == selectitem);
|
||||
|
||||
#ifdef HAVE_TOUCHSCREENGUI
|
||||
if (g_touchscreengui)
|
||||
|
@ -275,7 +280,8 @@ void Hud::drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
|
|||
}
|
||||
|
||||
|
||||
void Hud::drawLuaElements(const v3s16 &camera_offset) {
|
||||
void Hud::drawLuaElements(const v3s16 &camera_offset)
|
||||
{
|
||||
u32 text_height = g_fontengine->getTextHeight();
|
||||
irr::gui::IGUIFont* font = g_fontengine->getFont();
|
||||
for (size_t i = 0; i != player->maxHudId(); i++) {
|
||||
|
@ -326,7 +332,8 @@ void Hud::drawLuaElements(const v3s16 &camera_offset) {
|
|||
break; }
|
||||
case HUD_ELEM_INVENTORY: {
|
||||
InventoryList *inv = inventory->getList(e->text);
|
||||
drawItems(pos, e->number, 0, inv, e->item, e->dir);
|
||||
drawItems(pos, v2s32(e->offset.X, e->offset.Y), e->number, 0,
|
||||
inv, e->item, e->dir);
|
||||
break; }
|
||||
case HUD_ELEM_WAYPOINT: {
|
||||
v3f p_pos = player->getPosition() / BS;
|
||||
|
@ -379,8 +386,7 @@ void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture,
|
|||
if (size == v2s32()) {
|
||||
dstd = srcd;
|
||||
} else {
|
||||
double size_factor = g_settings->getFloat("hud_scaling") *
|
||||
porting::getDisplayDensity();
|
||||
float size_factor = m_hud_scaling * porting::getDisplayDensity();
|
||||
dstd.Height = size.Y * size_factor;
|
||||
dstd.Width = size.X * size_factor;
|
||||
offset.X *= size_factor;
|
||||
|
@ -448,25 +454,26 @@ void Hud::drawHotbar(u16 playeritem) {
|
|||
if ( (float) width / (float) porting::getWindowSize().X <=
|
||||
g_settings->getFloat("hud_hotbar_max_width")) {
|
||||
if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
|
||||
drawItems(pos, hotbar_itemcount, 0, mainlist, playeritem + 1, 0);
|
||||
drawItems(pos, v2s32(0, 0), hotbar_itemcount, 0, mainlist, playeritem + 1, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
pos.X += width/4;
|
||||
|
||||
v2s32 secondpos = pos;
|
||||
pos = pos - v2s32(0, m_hotbar_imagesize + m_padding);
|
||||
|
||||
if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
|
||||
drawItems(pos, hotbar_itemcount/2, 0, mainlist, playeritem + 1, 0);
|
||||
drawItems(secondpos, hotbar_itemcount, hotbar_itemcount/2, mainlist, playeritem + 1, 0);
|
||||
drawItems(pos, v2s32(0, 0), hotbar_itemcount / 2, 0,
|
||||
mainlist, playeritem + 1, 0);
|
||||
drawItems(secondpos, v2s32(0, 0), hotbar_itemcount,
|
||||
hotbar_itemcount / 2, mainlist, playeritem + 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Hud::drawCrosshair() {
|
||||
|
||||
void Hud::drawCrosshair()
|
||||
{
|
||||
if (use_crosshair_image) {
|
||||
video::ITexture *crosshair = tsrc->getTexture("crosshair.png");
|
||||
v2u32 size = crosshair->getOriginalSize();
|
||||
|
@ -489,9 +496,9 @@ void Hud::setSelectionPos(const v3f &pos, const v3s16 &camera_offset)
|
|||
m_selection_pos = pos;
|
||||
m_selection_pos_with_offset = pos - intToFloat(camera_offset, BS);
|
||||
}
|
||||
|
||||
|
||||
void Hud::drawSelectionMesh()
|
||||
{
|
||||
{
|
||||
if (!m_use_selection_mesh) {
|
||||
// Draw 3D selection boxes
|
||||
video::SMaterial oldmaterial = driver->getMaterial2D();
|
||||
|
@ -502,9 +509,9 @@ void Hud::drawSelectionMesh()
|
|||
aabb3f box = aabb3f(
|
||||
i->MinEdge + m_selection_pos_with_offset,
|
||||
i->MaxEdge + m_selection_pos_with_offset);
|
||||
|
||||
|
||||
u32 r = (selectionbox_argb.getRed() *
|
||||
m_selection_mesh_color.getRed() / 255);
|
||||
m_selection_mesh_color.getRed() / 255);
|
||||
u32 g = (selectionbox_argb.getGreen() *
|
||||
m_selection_mesh_color.getGreen() / 255);
|
||||
u32 b = (selectionbox_argb.getBlue() *
|
||||
|
@ -579,7 +586,7 @@ void Hud::updateSelectionMesh(const v3s16 &camera_offset)
|
|||
void Hud::resizeHotbar() {
|
||||
if (m_screensize != porting::getWindowSize()) {
|
||||
m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE * porting::getDisplayDensity() + 0.5);
|
||||
m_hotbar_imagesize *= g_settings->getFloat("hud_scaling");
|
||||
m_hotbar_imagesize *= m_hud_scaling;
|
||||
m_padding = m_hotbar_imagesize / 12;
|
||||
m_screensize = porting::getWindowSize();
|
||||
m_displaycenter = v2s32(m_screensize.X/2,m_screensize.Y/2);
|
||||
|
|
11
src/hud.h
11
src/hud.h
|
@ -130,7 +130,7 @@ public:
|
|||
void drawCrosshair();
|
||||
void drawSelectionMesh();
|
||||
void updateSelectionMesh(const v3s16 &camera_offset);
|
||||
|
||||
|
||||
std::vector<aabb3f> *getSelectionBoxes()
|
||||
{ return &m_selection_boxes; }
|
||||
|
||||
|
@ -148,17 +148,18 @@ private:
|
|||
void drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture,
|
||||
s32 count, v2s32 offset, v2s32 size=v2s32());
|
||||
|
||||
void drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
|
||||
InventoryList *mainlist, u16 selectitem, u16 direction);
|
||||
void drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount,
|
||||
s32 inv_offset, InventoryList *mainlist, u16 selectitem, u16 direction);
|
||||
|
||||
void drawItem(const ItemStack &item, const core::rect<s32>& rect,
|
||||
bool selected);
|
||||
|
||||
float m_hud_scaling; // cached minetest setting
|
||||
v3s16 m_camera_offset;
|
||||
v2u32 m_screensize;
|
||||
v2s32 m_displaycenter;
|
||||
s32 m_hotbar_imagesize;
|
||||
s32 m_padding;
|
||||
s32 m_hotbar_imagesize; // Takes hud_scaling into account, updated by resizeHotbar()
|
||||
s32 m_padding; // Takes hud_scaling into account, updated by resizeHotbar()
|
||||
video::SColor hbar_colors[4];
|
||||
|
||||
std::vector<aabb3f> m_selection_boxes;
|
||||
|
|
|
@ -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 ||
|
||||
|
@ -589,17 +591,18 @@ void MapgenFlat::generateCaves(s16 max_stone_y)
|
|||
// 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 {
|
||||
// Not in tunnel or not ground content
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
BiomeManager *bmgr;
|
||||
|
||||
int ystride;
|
||||
int zstride;
|
||||
int zstride_1d;
|
||||
u32 spflags;
|
||||
|
||||
v3s16 node_min;
|
||||
|
|
|
@ -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 ||
|
||||
|
@ -717,17 +719,18 @@ void MapgenFractal::generateCaves(s16 max_stone_y)
|
|||
// 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 {
|
||||
// Not in tunnel or not ground content
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ public:
|
|||
BiomeManager *bmgr;
|
||||
|
||||
int ystride;
|
||||
int zstride;
|
||||
int zstride_1d;
|
||||
u16 formula;
|
||||
bool julia;
|
||||
|
||||
|
|
|
@ -54,7 +54,8 @@ MapgenV5::MapgenV5(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];
|
||||
|
@ -70,9 +71,11 @@ MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge)
|
|||
noise_height = new Noise(&sp->np_height, 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_ground = new Noise(&sp->np_ground, 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);
|
||||
|
@ -505,50 +508,6 @@ MgStoneType MapgenV5::generateBiomes(float *heat_map, float *humidity_map)
|
|||
}
|
||||
|
||||
|
||||
void MapgenV5::generateCaves(int 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);
|
||||
|
||||
u32 index = 0;
|
||||
|
||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||
for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
|
||||
u32 vi = vm->m_area.index(node_min.X, y, z);
|
||||
for (s16 x = node_min.X; x <= node_max.X; x++, vi++, index++) {
|
||||
// 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;
|
||||
|
||||
float d1 = contour(noise_cave1->result[index]);
|
||||
float d2 = contour(noise_cave2->result[index]);
|
||||
if (d1 * d2 > 0.125f) {
|
||||
content_t c = vm->m_data[vi].getContent();
|
||||
if (!ndef->get(c).is_ground_content || c == CONTENT_AIR)
|
||||
continue;
|
||||
|
||||
vm->m_data[vi] = MapNode(CONTENT_AIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (node_max.Y > MGV5_LARGE_CAVE_DEPTH)
|
||||
return;
|
||||
|
||||
PseudoRandom ps(blockseed + 21343);
|
||||
u32 bruises_count = ps.range(0, 2);
|
||||
for (u32 i = 0; i < bruises_count; i++) {
|
||||
CaveV5 cave(this, &ps);
|
||||
cave.makeCave(node_min, node_max, max_stone_y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MapgenV5::dustTopNodes()
|
||||
{
|
||||
if (node_max.Y < water_level)
|
||||
|
@ -597,3 +556,72 @@ void MapgenV5::dustTopNodes()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MapgenV5::generateCaves(int 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.125f && ndef->get(c).is_ground_content) {
|
||||
// In tunnel and ground content, excavate
|
||||
vm->m_data[vi] = MapNode(CONTENT_AIR);
|
||||
is_tunnel = true;
|
||||
} else {
|
||||
// Not in tunnel or not ground content
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (node_max.Y > MGV5_LARGE_CAVE_DEPTH)
|
||||
return;
|
||||
|
||||
PseudoRandom ps(blockseed + 21343);
|
||||
u32 bruises_count = ps.range(0, 2);
|
||||
for (u32 i = 0; i < bruises_count; i++) {
|
||||
CaveV5 cave(this, &ps);
|
||||
cave.makeCave(node_min, node_max, max_stone_y);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
BiomeManager *bmgr;
|
||||
|
||||
int ystride;
|
||||
int zstride;
|
||||
int zstride_1d;
|
||||
u32 spflags;
|
||||
|
||||
v3s16 node_min;
|
||||
|
|
|
@ -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,113 @@ 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 {
|
||||
// Not in tunnel or not ground content
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 +934,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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ public:
|
|||
BiomeManager *bmgr;
|
||||
|
||||
int ystride;
|
||||
int zstride;
|
||||
int zstride_1d;
|
||||
u32 spflags;
|
||||
|
||||
v3s16 node_min;
|
||||
|
|
|
@ -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) {
|
||||
|
@ -917,35 +921,30 @@ void MapgenValleys::generateCaves(s16 max_stone_y)
|
|||
}
|
||||
|
||||
u32 index_2d = 0;
|
||||
u32 index_3d = 0;
|
||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||
for (s16 x = node_min.X; x <= node_max.X; x++, index_2d++) {
|
||||
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index_2d]);
|
||||
bool air_above = false;
|
||||
bool tunnel_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);
|
||||
u32 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];
|
||||
|
||||
// Saves some time.
|
||||
if (y > terrain + 10) {
|
||||
air_above = true;
|
||||
if (y > terrain + 10)
|
||||
continue;
|
||||
} else if (y < terrain - 40) {
|
||||
else if (y < terrain - 40)
|
||||
underground = true;
|
||||
}
|
||||
|
||||
// Dig massive caves.
|
||||
if (node_max.Y <= massive_cave_depth
|
||||
|
@ -953,6 +952,7 @@ void MapgenValleys::generateCaves(s16 max_stone_y)
|
|||
> tcave_cache[y - node_min.Y + 1]) {
|
||||
vm->m_data[index_data] = n_air;
|
||||
made_a_big_one = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
content_t c = vm->m_data[index_data].getContent();
|
||||
|
@ -961,54 +961,51 @@ void MapgenValleys::generateCaves(s16 max_stone_y)
|
|||
|
||||
// River water is not set as ground content
|
||||
// in the default game. This can produce strange results
|
||||
// when a cave undercuts a river. However, that's not for
|
||||
// when a tunnel undercuts a river. However, that's not for
|
||||
// the mapgen to correct. Fix it in lua.
|
||||
|
||||
if (c == CONTENT_AIR) {
|
||||
air_above = true;
|
||||
} else if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
|
||||
// in a cave
|
||||
if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
|
||||
// in a tunnel
|
||||
vm->m_data[index_data] = n_air;
|
||||
air_above = true;
|
||||
} else if (air_above && (c == biome->c_filler || c == biome->c_stone)) {
|
||||
// at the cave floor
|
||||
s16 sr = ps.range(0,39);
|
||||
u32 j = index_data;
|
||||
vm->m_area.add_y(em, j, 1);
|
||||
tunnel_air_above = true;
|
||||
} else if (c == biome->c_filler || c == biome->c_stone) {
|
||||
if (tunnel_air_above) {
|
||||
// at the tunnel floor
|
||||
s16 sr = ps.range(0, 39);
|
||||
u32 j = index_data;
|
||||
vm->m_area.add_y(em, j, 1);
|
||||
|
||||
if (sr > terrain - y) {
|
||||
// Put dirt in caves near the surface.
|
||||
if (underground)
|
||||
vm->m_data[index_data] = MapNode(biome->c_filler);
|
||||
else
|
||||
vm->m_data[index_data] = MapNode(biome->c_top);
|
||||
} else if (sr < 3 && underground) {
|
||||
sr = abs(ps.next());
|
||||
if (lava_features_lim > 0 && y <= lava_max_height
|
||||
&& c == biome->c_stone && sr < lava_chance)
|
||||
vm->m_data[j] = n_lava;
|
||||
if (sr > terrain - y) {
|
||||
// Put dirt in tunnels near the surface.
|
||||
if (underground)
|
||||
vm->m_data[index_data] = MapNode(biome->c_filler);
|
||||
else
|
||||
vm->m_data[index_data] = MapNode(biome->c_top);
|
||||
} else if (sr < 3 && underground) {
|
||||
sr = abs(ps.next());
|
||||
if (lava_features_lim > 0 && y <= lava_max_height
|
||||
&& c == biome->c_stone && sr < lava_chance)
|
||||
vm->m_data[j] = n_lava;
|
||||
|
||||
sr -= lava_chance;
|
||||
sr -= lava_chance;
|
||||
|
||||
// If sr < 0 then we should have already placed lava --
|
||||
// don't immediately dump water on it.
|
||||
if (water_features_lim > 0 && y <= cave_water_max_height
|
||||
&& sr >= 0 && sr < water_chance)
|
||||
vm->m_data[j] = n_water;
|
||||
// If sr < 0 then we should have already placed lava --
|
||||
// don't immediately dump water on it.
|
||||
if (water_features_lim > 0 && y <= cave_water_max_height
|
||||
&& sr >= 0 && sr < water_chance)
|
||||
vm->m_data[j] = n_water;
|
||||
}
|
||||
}
|
||||
|
||||
air_above = false;
|
||||
underground = true;
|
||||
} else if (c == biome->c_filler || c == biome->c_stone) {
|
||||
air_above = false;
|
||||
tunnel_air_above = false;
|
||||
underground = true;
|
||||
} else {
|
||||
air_above = false;
|
||||
tunnel_air_above = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (node_max.Y <= large_cave_depth && (!made_a_big_one)) {
|
||||
if (node_max.Y <= large_cave_depth && !made_a_big_one) {
|
||||
u32 bruises_count = ps.range(0, 2);
|
||||
for (u32 i = 0; i < bruises_count; i++) {
|
||||
CaveV5 cave(this, &ps);
|
||||
|
|
|
@ -106,6 +106,7 @@ private:
|
|||
|
||||
int ystride;
|
||||
int zstride;
|
||||
int zstride_1d;
|
||||
|
||||
float map_gen_limit;
|
||||
|
||||
|
|
605
src/util/srp.cpp
605
src/util/srp.cpp
File diff suppressed because it is too large
Load Diff
|
@ -56,12 +56,10 @@
|
|||
#ifndef SRP_H
|
||||
#define SRP_H
|
||||
|
||||
|
||||
struct SRPVerifier;
|
||||
struct SRPUser;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
SRP_NG_1024,
|
||||
SRP_NG_2048,
|
||||
SRP_NG_4096,
|
||||
|
@ -69,8 +67,7 @@ typedef enum
|
|||
SRP_NG_CUSTOM
|
||||
} SRP_NGType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
/*SRP_SHA1,*/
|
||||
/*SRP_SHA224,*/
|
||||
SRP_SHA256,
|
||||
|
@ -78,12 +75,13 @@ typedef enum
|
|||
SRP_SHA512*/
|
||||
} SRP_HashAlgorithm;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SRP_OK,
|
||||
typedef enum {
|
||||
SRP_ERR,
|
||||
SRP_OK,
|
||||
} SRP_Result;
|
||||
|
||||
// clang-format off
|
||||
|
||||
/* Sets the memory functions used by srp.
|
||||
* Note: this doesn't set the memory functions used by gmp,
|
||||
* but it is supported to have different functions for srp and gmp.
|
||||
|
@ -101,17 +99,18 @@ void srp_set_memory_functions(
|
|||
* The n_hex and g_hex parameters should be 0 unless SRP_NG_CUSTOM is used for ng_type.
|
||||
* If provided, they must contain ASCII text of the hexidecimal notation.
|
||||
*
|
||||
* If bytes_s == NULL, it is filled with random data. The caller is responsible for freeing.
|
||||
* If bytes_s == NULL, it is filled with random data.
|
||||
* The caller is responsible for freeing.
|
||||
*
|
||||
* Returns SRP_OK on success, and SRP_ERR on error.
|
||||
* bytes_s might be in this case invalid, don't free it.
|
||||
*/
|
||||
SRP_Result srp_create_salted_verification_key( SRP_HashAlgorithm alg,
|
||||
SRP_Result srp_create_salted_verification_key(SRP_HashAlgorithm alg,
|
||||
SRP_NGType ng_type, const char *username_for_verifier,
|
||||
const unsigned char *password, size_t len_password,
|
||||
unsigned char **bytes_s, size_t *len_s,
|
||||
unsigned char **bytes_v, size_t *len_v,
|
||||
const char * n_hex, const char *g_hex );
|
||||
const char *n_hex, const char *g_hex);
|
||||
|
||||
/* Out: bytes_B, len_B.
|
||||
*
|
||||
|
@ -132,54 +131,54 @@ struct SRPVerifier* srp_verifier_new(SRP_HashAlgorithm alg, SRP_NGType ng_type,
|
|||
unsigned char** bytes_B, size_t *len_B,
|
||||
const char* n_hex, const char* g_hex);
|
||||
|
||||
// clang-format on
|
||||
|
||||
void srp_verifier_delete( struct SRPVerifier* ver );
|
||||
void srp_verifier_delete(struct SRPVerifier *ver);
|
||||
|
||||
// srp_verifier_verify_session must have been called before
|
||||
int srp_verifier_is_authenticated( struct SRPVerifier* ver );
|
||||
int srp_verifier_is_authenticated(struct SRPVerifier *ver);
|
||||
|
||||
|
||||
const char * srp_verifier_get_username( struct SRPVerifier* ver );
|
||||
const char *srp_verifier_get_username(struct SRPVerifier *ver);
|
||||
|
||||
/* key_length may be null */
|
||||
const unsigned char* srp_verifier_get_session_key( struct SRPVerifier* ver,
|
||||
size_t *key_length );
|
||||
|
||||
|
||||
size_t srp_verifier_get_session_key_length(struct SRPVerifier* ver);
|
||||
const unsigned char *srp_verifier_get_session_key(
|
||||
struct SRPVerifier *ver, size_t *key_length);
|
||||
|
||||
size_t srp_verifier_get_session_key_length(struct SRPVerifier *ver);
|
||||
|
||||
/* Verifies session, on success, it writes bytes_HAMK.
|
||||
* user_M must be exactly srp_verifier_get_session_key_length() bytes in size
|
||||
*/
|
||||
void srp_verifier_verify_session( struct SRPVerifier* ver,
|
||||
const unsigned char* user_M, unsigned char** bytes_HAMK );
|
||||
void srp_verifier_verify_session(
|
||||
struct SRPVerifier *ver, const unsigned char *user_M, unsigned char **bytes_HAMK);
|
||||
|
||||
/*******************************************************************************/
|
||||
|
||||
/* The n_hex and g_hex parameters should be 0 unless SRP_NG_CUSTOM is used for ng_type */
|
||||
struct SRPUser *srp_user_new(SRP_HashAlgorithm alg, SRP_NGType ng_type,
|
||||
const char *username, const char *username_for_verifier,
|
||||
const unsigned char *bytes_password, size_t len_password,
|
||||
const char *n_hex, const char *g_hex);
|
||||
const unsigned char *bytes_password, size_t len_password, const char *n_hex,
|
||||
const char *g_hex);
|
||||
|
||||
void srp_user_delete(struct SRPUser * usr);
|
||||
void srp_user_delete(struct SRPUser *usr);
|
||||
|
||||
int srp_user_is_authenticated(struct SRPUser * usr);
|
||||
int srp_user_is_authenticated(struct SRPUser *usr);
|
||||
|
||||
|
||||
const char* srp_user_get_username(struct SRPUser * usr);
|
||||
const char *srp_user_get_username(struct SRPUser *usr);
|
||||
|
||||
/* key_length may be null */
|
||||
const unsigned char* srp_user_get_session_key(struct SRPUser* usr, size_t* key_length);
|
||||
const unsigned char *srp_user_get_session_key(struct SRPUser *usr, size_t *key_length);
|
||||
|
||||
size_t srp_user_get_session_key_length(struct SRPUser* usr);
|
||||
size_t srp_user_get_session_key_length(struct SRPUser *usr);
|
||||
|
||||
/* Output: username, bytes_A, len_A. If you don't want it get written, set username to NULL.
|
||||
// clang-format off
|
||||
|
||||
/* Output: username, bytes_A, len_A.
|
||||
* If you don't want it get written, set username to NULL.
|
||||
* If bytes_a == NULL, random data is used for a. */
|
||||
SRP_Result srp_user_start_authentication(struct SRPUser* usr, char** username,
|
||||
const unsigned char* bytes_a, size_t len_a,
|
||||
unsigned char** bytes_A, size_t* len_A);
|
||||
SRP_Result srp_user_start_authentication(struct SRPUser* usr, char **username,
|
||||
const unsigned char *bytes_a, size_t len_a,
|
||||
unsigned char **bytes_A, size_t* len_A);
|
||||
|
||||
/* Output: bytes_M, len_M (len_M may be null and will always be
|
||||
* srp_user_get_session_key_length() bytes in size) */
|
||||
|
@ -187,8 +186,9 @@ void srp_user_process_challenge(struct SRPUser *usr,
|
|||
const unsigned char *bytes_s, size_t len_s,
|
||||
const unsigned char *bytes_B, size_t len_B,
|
||||
unsigned char **bytes_M, size_t *len_M);
|
||||
// clang-format on
|
||||
|
||||
/* bytes_HAMK must be exactly srp_user_get_session_key_length() bytes in size */
|
||||
void srp_user_verify_session(struct SRPUser* usr, const unsigned char* bytes_HAMK);
|
||||
void srp_user_verify_session(struct SRPUser *usr, const unsigned char *bytes_HAMK);
|
||||
|
||||
#endif /* Include Guard */
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 5.9 KiB |
Loading…
Reference in New Issue