Merge
commit
6d3bdc5a7d
|
@ -147,7 +147,7 @@ end
|
||||||
-- Some common functions
|
-- Some common functions
|
||||||
--
|
--
|
||||||
|
|
||||||
function nodeupdate_single(p, delay)
|
function nodeupdate_single(p)
|
||||||
local n = core.get_node(p)
|
local n = core.get_node(p)
|
||||||
if core.get_item_group(n.name, "falling_node") ~= 0 then
|
if core.get_item_group(n.name, "falling_node") ~= 0 then
|
||||||
local p_bottom = {x = p.x, y = p.y - 1, z = p.z}
|
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
|
core.get_node_level(p_bottom) < core.get_node_max_level(p_bottom))) and
|
||||||
(not core.registered_nodes[n_bottom.name].walkable or
|
(not core.registered_nodes[n_bottom.name].walkable or
|
||||||
core.registered_nodes[n_bottom.name].buildable_to) then
|
core.registered_nodes[n_bottom.name].buildable_to) then
|
||||||
if delay then
|
n.level = core.get_node_level(p)
|
||||||
core.after(0.1, nodeupdate_single, p, false)
|
core.remove_node(p)
|
||||||
else
|
spawn_falling_node(p, n)
|
||||||
n.level = core.get_node_level(p)
|
return true
|
||||||
core.remove_node(p)
|
|
||||||
spawn_falling_node(p, n)
|
|
||||||
nodeupdate(p)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if core.get_item_group(n.name, "attached_node") ~= 0 then
|
if core.get_item_group(n.name, "attached_node") ~= 0 then
|
||||||
if not check_attached_node(p, n) then
|
if not check_attached_node(p, n) then
|
||||||
drop_attached_node(p)
|
drop_attached_node(p)
|
||||||
nodeupdate(p)
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function nodeupdate(p, delay)
|
-- This table is specifically ordered.
|
||||||
-- Round p to prevent falling entities to get stuck
|
-- 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)
|
p = vector.round(p)
|
||||||
|
|
||||||
for x = -1, 1 do
|
-- We make a stack, and manually maintain size for performance.
|
||||||
for y = -1, 1 do
|
-- Stored in the stack, we will maintain tables with pos, and
|
||||||
for z = -1, 1 do
|
-- last neighbor visited. This way, when we get back to each
|
||||||
local d = vector.new(x, y, z)
|
-- node, we know which directions we have already walked, and
|
||||||
nodeupdate_single(vector.add(p, d), delay or not (x == 0 and y == 0 and z == 0))
|
-- which direction is the next to walk.
|
||||||
end
|
local s = {}
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ if core.print then
|
||||||
-- Override native print and use
|
-- Override native print and use
|
||||||
-- terminal if that's turned on
|
-- terminal if that's turned on
|
||||||
function print(...)
|
function print(...)
|
||||||
local n, t = select("#", ...), { ... }
|
local n, t = select("#", ...), {...}
|
||||||
for i = 1, n do
|
for i = 1, n do
|
||||||
t[i] = tostring(t[i])
|
t[i] = tostring(t[i])
|
||||||
end
|
end
|
||||||
|
@ -25,26 +25,26 @@ os.setlocale("C", "numeric")
|
||||||
minetest = core
|
minetest = core
|
||||||
|
|
||||||
-- Load other files
|
-- Load other files
|
||||||
local scriptdir = core.get_builtin_path()..DIR_DELIM
|
local scriptdir = core.get_builtin_path() .. DIR_DELIM
|
||||||
local gamepath = scriptdir.."game"..DIR_DELIM
|
local gamepath = scriptdir .. "game" .. DIR_DELIM
|
||||||
local commonpath = scriptdir.."common"..DIR_DELIM
|
local commonpath = scriptdir .. "common" .. DIR_DELIM
|
||||||
local asyncpath = scriptdir.."async"..DIR_DELIM
|
local asyncpath = scriptdir .. "async" .. DIR_DELIM
|
||||||
|
|
||||||
dofile(commonpath.."strict.lua")
|
dofile(commonpath .. "strict.lua")
|
||||||
dofile(commonpath.."serialize.lua")
|
dofile(commonpath .. "serialize.lua")
|
||||||
dofile(commonpath.."misc_helpers.lua")
|
dofile(commonpath .. "misc_helpers.lua")
|
||||||
|
|
||||||
if INIT == "game" then
|
if INIT == "game" then
|
||||||
dofile(gamepath.."init.lua")
|
dofile(gamepath .. "init.lua")
|
||||||
elseif INIT == "mainmenu" then
|
elseif INIT == "mainmenu" then
|
||||||
local mainmenuscript = core.setting_get("main_menu_script")
|
local mainmenuscript = core.setting_get("main_menu_script")
|
||||||
if mainmenuscript ~= nil and mainmenuscript ~= "" then
|
if mainmenuscript ~= nil and mainmenuscript ~= "" then
|
||||||
dofile(mainmenuscript)
|
dofile(mainmenuscript)
|
||||||
else
|
else
|
||||||
dofile(core.get_mainmenu_path()..DIR_DELIM.."init.lua")
|
dofile(core.get_mainmenu_path() .. DIR_DELIM .. "init.lua")
|
||||||
end
|
end
|
||||||
elseif INIT == "async" then
|
elseif INIT == "async" then
|
||||||
dofile(asyncpath.."init.lua")
|
dofile(asyncpath .. "init.lua")
|
||||||
else
|
else
|
||||||
error(("Unrecognized builtin initialization type %s!"):format(tostring(INIT)))
|
error(("Unrecognized builtin initialization type %s!"):format(tostring(INIT)))
|
||||||
end
|
end
|
||||||
|
|
|
@ -35,24 +35,31 @@ dofile(basepath .. DIR_DELIM .. "fstk" .. DIR_DELIM .. "tabview.lua")
|
||||||
dofile(basepath .. DIR_DELIM .. "fstk" .. DIR_DELIM .. "ui.lua")
|
dofile(basepath .. DIR_DELIM .. "fstk" .. DIR_DELIM .. "ui.lua")
|
||||||
dofile(menupath .. DIR_DELIM .. "common.lua")
|
dofile(menupath .. DIR_DELIM .. "common.lua")
|
||||||
dofile(menupath .. DIR_DELIM .. "gamemgr.lua")
|
dofile(menupath .. DIR_DELIM .. "gamemgr.lua")
|
||||||
dofile(menupath .. DIR_DELIM .. "store.lua")
|
if PLATFORM ~= "Android" then
|
||||||
dofile(menupath .. DIR_DELIM .. "dlg_config_world.lua")
|
|
||||||
dofile(menupath .. DIR_DELIM .. "tab_credits.lua")
|
|
||||||
if not (PLATFORM == "Android") then
|
|
||||||
dofile(menupath .. DIR_DELIM .. "modmgr.lua")
|
dofile(menupath .. DIR_DELIM .. "modmgr.lua")
|
||||||
dofile(menupath .. DIR_DELIM .. "tab_settings.lua")
|
dofile(menupath .. DIR_DELIM .. "store.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")
|
|
||||||
end
|
end
|
||||||
dofile(menupath .. DIR_DELIM .. "dlg_create_world.lua")
|
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_delete_world.lua")
|
||||||
dofile(menupath .. DIR_DELIM .. "tab_multiplayer.lua")
|
--dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua")
|
||||||
dofile(menupath .. DIR_DELIM .. "tab_server.lua")
|
dofile(menupath .. DIR_DELIM .. "dlg_config_world.lua")
|
||||||
dofile(menupath .. DIR_DELIM .. "tab_singleplayer.lua")
|
if PLATFORM ~= "Android" then
|
||||||
dofile(menupath .. DIR_DELIM .. "textures.lua")
|
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)
|
local function main_event_handler(tabview, event)
|
||||||
|
@ -67,66 +74,64 @@ local function init_globals()
|
||||||
-- Init gamedata
|
-- Init gamedata
|
||||||
gamedata.worldindex = 0
|
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(
|
menudata.worldlist:add_sort_mechanism("alphabetic", sort_worlds_alphabetic)
|
||||||
core.get_worlds,
|
menudata.worldlist:set_sortmode("alphabetic")
|
||||||
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)
|
core.setting_set("menu_last_game", "default")
|
||||||
menudata.worldlist:set_sortmode("alphabetic")
|
|
||||||
|
|
||||||
core.setting_set("menu_last_game", "default")
|
mm_texture.init()
|
||||||
|
|
||||||
mm_texture.init()
|
|
||||||
|
|
||||||
-- Create main tabview
|
-- 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
|
if PLATFORM ~= "Android" then
|
||||||
tv_main:set_autosave_tab(true)
|
tv_main:add(tabs.settings)
|
||||||
|
tv_main:add(tabs.texturepacks)
|
||||||
end
|
end
|
||||||
tv_main:add(tab_singleplayer)
|
|
||||||
tv_main:add(tab_multiplayer)
|
--tv_main:add(tabs.mods)
|
||||||
tv_main:add(tab_server)
|
tv_main:add(tabs.credits)
|
||||||
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:set_global_event_handler(main_event_handler)
|
tv_main:set_global_event_handler(main_event_handler)
|
||||||
|
|
||||||
tv_main:set_fixed_size(false)
|
tv_main:set_fixed_size(false)
|
||||||
|
|
||||||
if not (PLATFORM == "Android") then
|
--if PLATFORM ~= "Android" then
|
||||||
tv_main:set_tab(core.setting_get("maintab_LAST"))
|
-- tv_main:set_tab(core.setting_get("maintab_LAST"))
|
||||||
end
|
--end
|
||||||
ui.set_default("maintab")
|
ui.set_default("maintab")
|
||||||
tv_main:show()
|
tv_main:show()
|
||||||
|
|
||||||
-- Create modstore ui
|
-- Create modstore ui
|
||||||
if PLATFORM == "Android" then
|
if PLATFORM == "Android" then
|
||||||
modstore.init({x=12, y=6}, 3, 2)
|
modstore.init({x = 12, y = 6}, 3, 2)
|
||||||
else
|
else
|
||||||
modstore.init({x=12, y=8}, 4, 3)
|
modstore.init({x = 12, y = 8}, 4, 3)
|
||||||
end
|
end
|
||||||
|
|
||||||
ui.update()
|
ui.update()
|
||||||
|
|
||||||
core.sound_play("main_menu", false)
|
core.sound_play("main_menu", false)
|
||||||
|
|
||||||
minetest.set_clouds(false)
|
minetest.set_clouds(false)
|
||||||
core.set_background("background", defaulttexturedir .. "background.jpg");
|
core.set_background("background", defaulttexturedir .. "background.jpg");
|
||||||
end
|
end
|
||||||
|
|
||||||
init_globals()
|
init_globals()
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ local previous_contributors = {
|
||||||
"Zefram <zefram@fysh.org>",
|
"Zefram <zefram@fysh.org>",
|
||||||
}
|
}
|
||||||
|
|
||||||
tab_credits = {
|
return {
|
||||||
name = "credits",
|
name = "credits",
|
||||||
caption = fgettext("Credits"),
|
caption = fgettext("Credits"),
|
||||||
cbf_formspec = function(tabview, name, tabdata)
|
cbf_formspec = function(tabview, name, tabdata)
|
||||||
|
|
|
@ -163,7 +163,7 @@ local function handle_buttons(tabview, fields, tabname, tabdata)
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
tab_mods = {
|
return {
|
||||||
name = "mods",
|
name = "mods",
|
||||||
caption = fgettext("Mods"),
|
caption = fgettext("Mods"),
|
||||||
cbf_formspec = get_formspec,
|
cbf_formspec = get_formspec,
|
||||||
|
|
|
@ -256,10 +256,10 @@ local function on_change(type,old_tab,new_tab)
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
tab_multiplayer = {
|
return {
|
||||||
name = "multiplayer",
|
name = "multiplayer",
|
||||||
caption = fgettext("Multi Player"),
|
caption = fgettext("Multi Player"),
|
||||||
cbf_formspec = get_formspec,
|
cbf_formspec = get_formspec,
|
||||||
cbf_button_handler = main_button_handler,
|
cbf_button_handler = main_button_handler,
|
||||||
on_change = on_change
|
on_change = on_change
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,10 +186,10 @@ local function main_button_handler(this, fields, name, tabdata)
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
tab_server = {
|
return {
|
||||||
name = "server",
|
name = "server",
|
||||||
caption = fgettext("Create Server"),
|
caption = fgettext("Create Server"),
|
||||||
cbf_formspec = get_formspec,
|
cbf_formspec = get_formspec,
|
||||||
cbf_button_handler = main_button_handler,
|
cbf_button_handler = main_button_handler,
|
||||||
on_change = nil
|
on_change = nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -384,7 +384,7 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
|
||||||
return ddhandled
|
return ddhandled
|
||||||
end
|
end
|
||||||
|
|
||||||
tab_settings = {
|
return {
|
||||||
name = "settings",
|
name = "settings",
|
||||||
caption = fgettext("Settings"),
|
caption = fgettext("Settings"),
|
||||||
cbf_formspec = formspec,
|
cbf_formspec = formspec,
|
||||||
|
|
|
@ -145,9 +145,10 @@ end
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
tab_singleplayer = {
|
return {
|
||||||
name = "singleplayer",
|
name = "singleplayer",
|
||||||
caption = fgettext("Single Player"),
|
caption = fgettext("Single Player"),
|
||||||
cbf_formspec = get_formspec,
|
cbf_formspec = get_formspec,
|
||||||
cbf_button_handler = main_button_handler,
|
cbf_button_handler = main_button_handler,
|
||||||
}
|
on_change = on_change
|
||||||
|
}
|
||||||
|
|
|
@ -123,10 +123,10 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
tab_texturepacks = {
|
return {
|
||||||
name = "texturepacks",
|
name = "texturepacks",
|
||||||
caption = fgettext("Texturepacks"),
|
caption = fgettext("Texturepacks"),
|
||||||
cbf_formspec = get_formspec,
|
cbf_formspec = get_formspec,
|
||||||
cbf_button_handler = main_button_handler,
|
cbf_button_handler = main_button_handler,
|
||||||
on_change = nil
|
on_change = nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,6 +147,21 @@ if(CURSES_USE_NCURSESW)
|
||||||
set(CURSES_HAVE_NCURSESW_CURSES_H "CURSES_HAVE_NCURSESW_CURSES_H-NOTFOUND")
|
set(CURSES_HAVE_NCURSESW_CURSES_H "CURSES_HAVE_NCURSESW_CURSES_H-NOTFOUND")
|
||||||
endif()
|
endif()
|
||||||
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}"
|
find_library(CURSES_FORM_LIBRARY form HINTS "${_cursesLibDir}"
|
||||||
DOC "Path to libform.so or .lib or .a")
|
DOC "Path to libform.so or .lib or .a")
|
||||||
|
|
|
@ -357,8 +357,13 @@ The mask is applied using binary AND.
|
||||||
#### `[colorize:<color>:<ratio>`
|
#### `[colorize:<color>:<ratio>`
|
||||||
Colorize the textures with the given color.
|
Colorize the textures with the given color.
|
||||||
`<color>` is specified as a `ColorString`.
|
`<color>` is specified as a `ColorString`.
|
||||||
`<ratio>` is an int ranging from 0 to 255, and specifies how much of the
|
`<ratio>` is an int ranging from 0 to 255 or the word "`alpha`". If
|
||||||
color to apply. If ommitted, the alpha will be used.
|
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
|
Sounds
|
||||||
------
|
------
|
||||||
|
@ -940,6 +945,7 @@ Displays a horizontal bar made up of half-images.
|
||||||
* `number`: Number of items in the inventory to be displayed.
|
* `number`: Number of items in the inventory to be displayed.
|
||||||
* `item`: Position of item that is selected.
|
* `item`: Position of item that is selected.
|
||||||
* `direction`
|
* `direction`
|
||||||
|
* `offset`: offset in pixels from position.
|
||||||
|
|
||||||
### `waypoint`
|
### `waypoint`
|
||||||
Displays distance to selected world position.
|
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.
|
* `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.
|
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.
|
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))`
|
* `minetest.register_on_respawnplayer(func(ObjectRef))`
|
||||||
* Called when player is to be respawned
|
* Called when player is to be respawned
|
||||||
* Called _before_ repositioning of player occurs
|
* Called _before_ repositioning of player occurs
|
||||||
|
|
|
@ -540,6 +540,12 @@ void Camera::drawNametags()
|
||||||
i = m_nametags.begin();
|
i = m_nametags.begin();
|
||||||
i != m_nametags.end(); ++i) {
|
i != m_nametags.end(); ++i) {
|
||||||
Nametag *nametag = *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);
|
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 };
|
f32 transformed_pos[4] = { pos.X, pos.Y, pos.Z, 1.0f };
|
||||||
trans.multiplyWith1x4Matrix(transformed_pos);
|
trans.multiplyWith1x4Matrix(transformed_pos);
|
||||||
|
|
|
@ -265,7 +265,7 @@ Client::Client(
|
||||||
m_cache_smooth_lighting = g_settings->getBool("smooth_lighting");
|
m_cache_smooth_lighting = g_settings->getBool("smooth_lighting");
|
||||||
m_cache_enable_shaders = g_settings->getBool("enable_shaders");
|
m_cache_enable_shaders = g_settings->getBool("enable_shaders");
|
||||||
m_cache_use_tangent_vertices = m_cache_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"));
|
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,
|
static void blit_with_alpha_overlay(video::IImage *src, video::IImage *dst,
|
||||||
v2s32 src_pos, v2s32 dst_pos, v2u32 size);
|
v2s32 src_pos, v2s32 dst_pos, v2u32 size);
|
||||||
|
|
||||||
// Like blit_with_alpha overlay, but uses an int to calculate the ratio
|
// Apply a color to an image. Uses an int (0-255) to calculate the ratio.
|
||||||
// and modifies any destination pixels that are not fully transparent
|
// If the ratio is 255 or -1 and keep_alpha is true, then it multiples the
|
||||||
static void blit_with_interpolate_overlay(video::IImage *src, video::IImage *dst,
|
// color alpha with the destination alpha.
|
||||||
v2s32 src_pos, v2s32 dst_pos, v2u32 size, int ratio);
|
// 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
|
// Apply a mask to an image
|
||||||
static void apply_mask(video::IImage *mask, video::IImage *dst,
|
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;
|
video::SColor color;
|
||||||
int ratio = -1;
|
int ratio = -1;
|
||||||
|
bool keep_alpha = false;
|
||||||
|
|
||||||
if (!parseColorString(color_str, color, false))
|
if (!parseColorString(color_str, color, false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (is_number(ratio_str))
|
if (is_number(ratio_str))
|
||||||
ratio = mystoi(ratio_str, 0, 255);
|
ratio = mystoi(ratio_str, 0, 255);
|
||||||
|
else if (ratio_str == "alpha")
|
||||||
|
keep_alpha = true;
|
||||||
|
|
||||||
core::dimension2d<u32> dim = baseimg->getDimension();
|
apply_colorize(baseimg, v2u32(0, 0), baseimg->getDimension(), color, ratio, keep_alpha);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
else if (str_starts_with(part_of_name, "[applyfiltersformesh"))
|
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
|
Draw an image on top of an another one, using the specified ratio
|
||||||
modify all partially-opaque pixels in the destination.
|
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
|
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
|
// Do not move if world has not loaded yet, since custom node boxes
|
||||||
// are not available for collision detection.
|
// are not available for collision detection.
|
||||||
if (!any_position_valid)
|
if (!any_position_valid) {
|
||||||
|
*speed_f = v3f(0, 0, 0);
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
} // tt2
|
} // tt2
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ DungeonGen::DungeonGen(Mapgen *mapgen, DungeonParams *dparams)
|
||||||
this->vm = mapgen->vm;
|
this->vm = mapgen->vm;
|
||||||
|
|
||||||
#ifdef DGEN_USE_TORCHES
|
#ifdef DGEN_USE_TORCHES
|
||||||
c_torch = ndef->getId("default:torch");
|
c_torch = mg->ndef->getId("default:torch");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (dparams) {
|
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,
|
Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
|
||||||
gui::IGUIEnvironment* guienv, IGameDef *gamedef, LocalPlayer *player,
|
gui::IGUIEnvironment* guienv, IGameDef *gamedef, LocalPlayer *player,
|
||||||
Inventory *inventory) {
|
Inventory *inventory)
|
||||||
|
{
|
||||||
this->driver = driver;
|
this->driver = driver;
|
||||||
this->smgr = smgr;
|
this->smgr = smgr;
|
||||||
this->guienv = guienv;
|
this->guienv = guienv;
|
||||||
|
@ -49,16 +50,15 @@ Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
|
||||||
this->player = player;
|
this->player = player;
|
||||||
this->inventory = inventory;
|
this->inventory = inventory;
|
||||||
|
|
||||||
|
m_hud_scaling = g_settings->getFloat("hud_scaling");
|
||||||
m_screensize = v2u32(0, 0);
|
m_screensize = v2u32(0, 0);
|
||||||
m_displaycenter = v2s32(0, 0);
|
m_displaycenter = v2s32(0, 0);
|
||||||
m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE * porting::getDisplayDensity() + 0.5);
|
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_padding = m_hotbar_imagesize / 12;
|
||||||
|
|
||||||
const video::SColor hbar_color(255, 255, 255, 255);
|
for (unsigned int i = 0; i < 4; i++)
|
||||||
for (unsigned int i=0; i < 4; i++ ){
|
hbar_colors[i] = video::SColor(255, 255, 255, 255);
|
||||||
hbar_colors[i] = hbar_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
tsrc = gamedef->getTextureSource();
|
tsrc = gamedef->getTextureSource();
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
|
||||||
if (mode == "box") {
|
if (mode == "box") {
|
||||||
m_use_selection_mesh = false;
|
m_use_selection_mesh = false;
|
||||||
m_selection_material.Thickness =
|
m_selection_material.Thickness =
|
||||||
rangelim(g_settings->getS16("selectionbox_width"), 1, 5);
|
rangelim(g_settings->getS16("selectionbox_width"), 1, 5);
|
||||||
} else if (mode == "halo") {
|
} else if (mode == "halo") {
|
||||||
m_use_selection_mesh = true;
|
m_use_selection_mesh = true;
|
||||||
m_selection_material.setTexture(0, tsrc->getTextureForMesh("halo.png"));
|
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
|
//NOTE: selectitem = 0 -> no selected; selectitem 1-based
|
||||||
void Hud::drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
|
void Hud::drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount,
|
||||||
InventoryList *mainlist, u16 selectitem, u16 direction)
|
s32 inv_offset, InventoryList *mainlist, u16 selectitem, u16 direction)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_TOUCHSCREENGUI
|
#ifdef HAVE_TOUCHSCREENGUI
|
||||||
if ( (g_touchscreengui) && (offset == 0))
|
if (g_touchscreengui && inv_offset == 0)
|
||||||
g_touchscreengui->resetHud();
|
g_touchscreengui->resetHud();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s32 height = m_hotbar_imagesize + m_padding * 2;
|
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) {
|
if (direction == HUD_DIR_TOP_BOTTOM || direction == HUD_DIR_BOTTOM_TOP) {
|
||||||
width = m_hotbar_imagesize + m_padding * 2;
|
s32 tmp = height;
|
||||||
height = (itemcount - offset) * (m_hotbar_imagesize + m_padding * 2);
|
height = width;
|
||||||
|
width = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Position of upper left corner of bar
|
// 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) {
|
if (hotbar_image != player->hotbar_image) {
|
||||||
hotbar_image = player->hotbar_image;
|
hotbar_image = player->hotbar_image;
|
||||||
if (hotbar_image != "")
|
if (hotbar_image != "")
|
||||||
|
@ -223,6 +228,7 @@ void Hud::drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
|
||||||
use_hotbar_image = false;
|
use_hotbar_image = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Store hotbar_selected_image in member variable, used by drawItem()
|
||||||
if (hotbar_selected_image != player->hotbar_selected_image) {
|
if (hotbar_selected_image != player->hotbar_selected_image) {
|
||||||
hotbar_selected_image = player->hotbar_selected_image;
|
hotbar_selected_image = player->hotbar_selected_image;
|
||||||
if (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;
|
use_hotbar_selected_image = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* draw customized item background */
|
// draw customized item background
|
||||||
if (use_hotbar_image) {
|
if (use_hotbar_image) {
|
||||||
core::rect<s32> imgrect2(-m_padding/2, -m_padding/2,
|
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;
|
core::rect<s32> rect2 = imgrect2 + pos;
|
||||||
video::ITexture *texture = tsrc->getTexture(hotbar_image);
|
video::ITexture *texture = tsrc->getTexture(hotbar_image);
|
||||||
core::dimension2di imgsize(texture->getOriginalSize());
|
core::dimension2di imgsize(texture->getOriginalSize());
|
||||||
|
@ -243,29 +249,28 @@ void Hud::drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
|
||||||
NULL, hbar_colors, true);
|
NULL, hbar_colors, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (s32 i = offset; i < itemcount && (size_t)i < mainlist->getSize(); i++)
|
// Draw items
|
||||||
{
|
core::rect<s32> imgrect(0, 0, m_hotbar_imagesize, m_hotbar_imagesize);
|
||||||
v2s32 steppos;
|
for (s32 i = inv_offset; i < itemcount && (size_t)i < mainlist->getSize(); i++) {
|
||||||
s32 fullimglen = m_hotbar_imagesize + m_padding * 2;
|
s32 fullimglen = m_hotbar_imagesize + m_padding * 2;
|
||||||
|
|
||||||
core::rect<s32> imgrect(0, 0, m_hotbar_imagesize, m_hotbar_imagesize);
|
v2s32 steppos;
|
||||||
|
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case HUD_DIR_RIGHT_LEFT:
|
case HUD_DIR_RIGHT_LEFT:
|
||||||
steppos = v2s32(-(m_padding + (i - offset) * fullimglen), m_padding);
|
steppos = v2s32(-(m_padding + (i - inv_offset) * fullimglen), m_padding);
|
||||||
break;
|
break;
|
||||||
case HUD_DIR_TOP_BOTTOM:
|
case HUD_DIR_TOP_BOTTOM:
|
||||||
steppos = v2s32(m_padding, m_padding + (i - offset) * fullimglen);
|
steppos = v2s32(m_padding, m_padding + (i - inv_offset) * fullimglen);
|
||||||
break;
|
break;
|
||||||
case HUD_DIR_BOTTOM_TOP:
|
case HUD_DIR_BOTTOM_TOP:
|
||||||
steppos = v2s32(m_padding, -(m_padding + (i - offset) * fullimglen));
|
steppos = v2s32(m_padding, -(m_padding + (i - inv_offset) * fullimglen));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
steppos = v2s32(m_padding + (i - offset) * fullimglen, m_padding);
|
steppos = v2s32(m_padding + (i - inv_offset) * fullimglen, m_padding);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawItem(mainlist->getItem(i), (imgrect + pos + steppos), (i +1) == selectitem );
|
drawItem(mainlist->getItem(i), (imgrect + pos + steppos), (i + 1) == selectitem);
|
||||||
|
|
||||||
#ifdef HAVE_TOUCHSCREENGUI
|
#ifdef HAVE_TOUCHSCREENGUI
|
||||||
if (g_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();
|
u32 text_height = g_fontengine->getTextHeight();
|
||||||
irr::gui::IGUIFont* font = g_fontengine->getFont();
|
irr::gui::IGUIFont* font = g_fontengine->getFont();
|
||||||
for (size_t i = 0; i != player->maxHudId(); i++) {
|
for (size_t i = 0; i != player->maxHudId(); i++) {
|
||||||
|
@ -326,7 +332,8 @@ void Hud::drawLuaElements(const v3s16 &camera_offset) {
|
||||||
break; }
|
break; }
|
||||||
case HUD_ELEM_INVENTORY: {
|
case HUD_ELEM_INVENTORY: {
|
||||||
InventoryList *inv = inventory->getList(e->text);
|
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; }
|
break; }
|
||||||
case HUD_ELEM_WAYPOINT: {
|
case HUD_ELEM_WAYPOINT: {
|
||||||
v3f p_pos = player->getPosition() / BS;
|
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()) {
|
if (size == v2s32()) {
|
||||||
dstd = srcd;
|
dstd = srcd;
|
||||||
} else {
|
} else {
|
||||||
double size_factor = g_settings->getFloat("hud_scaling") *
|
float size_factor = m_hud_scaling * porting::getDisplayDensity();
|
||||||
porting::getDisplayDensity();
|
|
||||||
dstd.Height = size.Y * size_factor;
|
dstd.Height = size.Y * size_factor;
|
||||||
dstd.Width = size.X * size_factor;
|
dstd.Width = size.X * size_factor;
|
||||||
offset.X *= size_factor;
|
offset.X *= size_factor;
|
||||||
|
@ -448,25 +454,26 @@ void Hud::drawHotbar(u16 playeritem) {
|
||||||
if ( (float) width / (float) porting::getWindowSize().X <=
|
if ( (float) width / (float) porting::getWindowSize().X <=
|
||||||
g_settings->getFloat("hud_hotbar_max_width")) {
|
g_settings->getFloat("hud_hotbar_max_width")) {
|
||||||
if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
|
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;
|
pos.X += width/4;
|
||||||
|
|
||||||
v2s32 secondpos = pos;
|
v2s32 secondpos = pos;
|
||||||
pos = pos - v2s32(0, m_hotbar_imagesize + m_padding);
|
pos = pos - v2s32(0, m_hotbar_imagesize + m_padding);
|
||||||
|
|
||||||
if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
|
if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
|
||||||
drawItems(pos, hotbar_itemcount/2, 0, mainlist, playeritem + 1, 0);
|
drawItems(pos, v2s32(0, 0), hotbar_itemcount / 2, 0,
|
||||||
drawItems(secondpos, hotbar_itemcount, hotbar_itemcount/2, mainlist, playeritem + 1, 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) {
|
if (use_crosshair_image) {
|
||||||
video::ITexture *crosshair = tsrc->getTexture("crosshair.png");
|
video::ITexture *crosshair = tsrc->getTexture("crosshair.png");
|
||||||
v2u32 size = crosshair->getOriginalSize();
|
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 = pos;
|
||||||
m_selection_pos_with_offset = pos - intToFloat(camera_offset, BS);
|
m_selection_pos_with_offset = pos - intToFloat(camera_offset, BS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hud::drawSelectionMesh()
|
void Hud::drawSelectionMesh()
|
||||||
{
|
{
|
||||||
if (!m_use_selection_mesh) {
|
if (!m_use_selection_mesh) {
|
||||||
// Draw 3D selection boxes
|
// Draw 3D selection boxes
|
||||||
video::SMaterial oldmaterial = driver->getMaterial2D();
|
video::SMaterial oldmaterial = driver->getMaterial2D();
|
||||||
|
@ -502,9 +509,9 @@ void Hud::drawSelectionMesh()
|
||||||
aabb3f box = aabb3f(
|
aabb3f box = aabb3f(
|
||||||
i->MinEdge + m_selection_pos_with_offset,
|
i->MinEdge + m_selection_pos_with_offset,
|
||||||
i->MaxEdge + m_selection_pos_with_offset);
|
i->MaxEdge + m_selection_pos_with_offset);
|
||||||
|
|
||||||
u32 r = (selectionbox_argb.getRed() *
|
u32 r = (selectionbox_argb.getRed() *
|
||||||
m_selection_mesh_color.getRed() / 255);
|
m_selection_mesh_color.getRed() / 255);
|
||||||
u32 g = (selectionbox_argb.getGreen() *
|
u32 g = (selectionbox_argb.getGreen() *
|
||||||
m_selection_mesh_color.getGreen() / 255);
|
m_selection_mesh_color.getGreen() / 255);
|
||||||
u32 b = (selectionbox_argb.getBlue() *
|
u32 b = (selectionbox_argb.getBlue() *
|
||||||
|
@ -579,7 +586,7 @@ void Hud::updateSelectionMesh(const v3s16 &camera_offset)
|
||||||
void Hud::resizeHotbar() {
|
void Hud::resizeHotbar() {
|
||||||
if (m_screensize != porting::getWindowSize()) {
|
if (m_screensize != porting::getWindowSize()) {
|
||||||
m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE * porting::getDisplayDensity() + 0.5);
|
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_padding = m_hotbar_imagesize / 12;
|
||||||
m_screensize = porting::getWindowSize();
|
m_screensize = porting::getWindowSize();
|
||||||
m_displaycenter = v2s32(m_screensize.X/2,m_screensize.Y/2);
|
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 drawCrosshair();
|
||||||
void drawSelectionMesh();
|
void drawSelectionMesh();
|
||||||
void updateSelectionMesh(const v3s16 &camera_offset);
|
void updateSelectionMesh(const v3s16 &camera_offset);
|
||||||
|
|
||||||
std::vector<aabb3f> *getSelectionBoxes()
|
std::vector<aabb3f> *getSelectionBoxes()
|
||||||
{ return &m_selection_boxes; }
|
{ return &m_selection_boxes; }
|
||||||
|
|
||||||
|
@ -148,17 +148,18 @@ private:
|
||||||
void drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture,
|
void drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture,
|
||||||
s32 count, v2s32 offset, v2s32 size=v2s32());
|
s32 count, v2s32 offset, v2s32 size=v2s32());
|
||||||
|
|
||||||
void drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
|
void drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount,
|
||||||
InventoryList *mainlist, u16 selectitem, u16 direction);
|
s32 inv_offset, InventoryList *mainlist, u16 selectitem, u16 direction);
|
||||||
|
|
||||||
void drawItem(const ItemStack &item, const core::rect<s32>& rect,
|
void drawItem(const ItemStack &item, const core::rect<s32>& rect,
|
||||||
bool selected);
|
bool selected);
|
||||||
|
|
||||||
|
float m_hud_scaling; // cached minetest setting
|
||||||
v3s16 m_camera_offset;
|
v3s16 m_camera_offset;
|
||||||
v2u32 m_screensize;
|
v2u32 m_screensize;
|
||||||
v2s32 m_displaycenter;
|
v2s32 m_displaycenter;
|
||||||
s32 m_hotbar_imagesize;
|
s32 m_hotbar_imagesize; // Takes hud_scaling into account, updated by resizeHotbar()
|
||||||
s32 m_padding;
|
s32 m_padding; // Takes hud_scaling into account, updated by resizeHotbar()
|
||||||
video::SColor hbar_colors[4];
|
video::SColor hbar_colors[4];
|
||||||
|
|
||||||
std::vector<aabb3f> m_selection_boxes;
|
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
|
//// amount of elements to skip for the next index
|
||||||
//// for noise/height/biome maps (not vmanip)
|
//// for noise/height/biome maps (not vmanip)
|
||||||
this->ystride = csize.X;
|
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->biomemap = new u8[csize.X * csize.Z];
|
||||||
this->heightmap = new s16[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);
|
noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z);
|
||||||
|
|
||||||
//// 3D noise
|
//// 3D noise
|
||||||
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 2, csize.Z);
|
// 1-down overgeneraion
|
||||||
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 2, csize.Z);
|
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
|
//// Biome noise
|
||||||
noise_heat = new Noise(¶ms->np_biome_heat, seed, csize.X, csize.Z);
|
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++) {
|
for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
|
||||||
bool column_is_open = false; // Is column open to overground
|
bool column_is_open = false; // Is column open to overground
|
||||||
bool is_tunnel = false; // Is tunnel or tunnel floor
|
bool is_tunnel = false; // Is tunnel or tunnel floor
|
||||||
u32 vi = vm->m_area.index(x, node_max.Y + 1, z);
|
u32 vi = vm->m_area.index(x, node_max.Y, z);
|
||||||
u32 index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride +
|
u32 index3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride +
|
||||||
(x - node_min.X);
|
(x - node_min.X);
|
||||||
// Biome of column
|
// Biome of column
|
||||||
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
|
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
|
||||||
|
|
||||||
for (s16 y = node_max.Y + 1; y >= node_min.Y - 1;
|
// Don't excavate the overgenerated stone at node_max.Y + 1,
|
||||||
y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) {
|
// this creates a 'roof' over the tunnel, preventing light in
|
||||||
// Don't excavate the overgenerated stone at node_max.Y + 1,
|
// tunnels at mapchunk borders when generating mapchunks upwards.
|
||||||
// this creates a 'roof' over the tunnel, preventing light in
|
// This 'roof' is removed when the mapchunk above is generated.
|
||||||
// tunnels at mapchunk borders when generating mapchunks upwards.
|
for (s16 y = node_max.Y; y >= node_min.Y - 1; y--,
|
||||||
if (y > node_max.Y)
|
index3d -= ystride,
|
||||||
continue;
|
vm->m_area.add_y(em, vi, -1)) {
|
||||||
|
|
||||||
content_t c = vm->m_data[vi].getContent();
|
content_t c = vm->m_data[vi].getContent();
|
||||||
if (c == CONTENT_AIR || c == biome->c_water_top ||
|
if (c == CONTENT_AIR || c == biome->c_water_top ||
|
||||||
|
@ -589,17 +591,18 @@ void MapgenFlat::generateCaves(s16 max_stone_y)
|
||||||
// Ground
|
// Ground
|
||||||
float d1 = contour(noise_cave1->result[index3d]);
|
float d1 = contour(noise_cave1->result[index3d]);
|
||||||
float d2 = contour(noise_cave2->result[index3d]);
|
float d2 = contour(noise_cave2->result[index3d]);
|
||||||
|
|
||||||
if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
|
if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
|
||||||
// In tunnel and ground content, excavate
|
// In tunnel and ground content, excavate
|
||||||
vm->m_data[vi] = MapNode(CONTENT_AIR);
|
vm->m_data[vi] = MapNode(CONTENT_AIR);
|
||||||
is_tunnel = true;
|
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 {
|
} 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;
|
column_is_open = false;
|
||||||
is_tunnel = false;
|
is_tunnel = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ public:
|
||||||
BiomeManager *bmgr;
|
BiomeManager *bmgr;
|
||||||
|
|
||||||
int ystride;
|
int ystride;
|
||||||
int zstride;
|
int zstride_1d;
|
||||||
u32 spflags;
|
u32 spflags;
|
||||||
|
|
||||||
v3s16 node_min;
|
v3s16 node_min;
|
||||||
|
|
|
@ -56,7 +56,8 @@ MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager *
|
||||||
//// amount of elements to skip for the next index
|
//// amount of elements to skip for the next index
|
||||||
//// for noise/height/biome maps (not vmanip)
|
//// for noise/height/biome maps (not vmanip)
|
||||||
this->ystride = csize.X;
|
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->biomemap = new u8[csize.X * csize.Z];
|
||||||
this->heightmap = new s16[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);
|
noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z);
|
||||||
|
|
||||||
//// 3D terrain noise
|
//// 3D terrain noise
|
||||||
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 2, csize.Z);
|
// 1-down overgeneraion
|
||||||
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 2, csize.Z);
|
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
|
//// Biome noise
|
||||||
noise_heat = new Noise(¶ms->np_biome_heat, seed, csize.X, csize.Z);
|
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++) {
|
for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
|
||||||
bool column_is_open = false; // Is column open to overground
|
bool column_is_open = false; // Is column open to overground
|
||||||
bool is_tunnel = false; // Is tunnel or tunnel floor
|
bool is_tunnel = false; // Is tunnel or tunnel floor
|
||||||
u32 vi = vm->m_area.index(x, node_max.Y + 1, z);
|
u32 vi = vm->m_area.index(x, node_max.Y, z);
|
||||||
u32 index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride +
|
u32 index3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride +
|
||||||
(x - node_min.X);
|
(x - node_min.X);
|
||||||
// Biome of column
|
// Biome of column
|
||||||
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
|
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
|
||||||
|
|
||||||
for (s16 y = node_max.Y + 1; y >= node_min.Y - 1;
|
// Don't excavate the overgenerated stone at node_max.Y + 1,
|
||||||
y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) {
|
// this creates a 'roof' over the tunnel, preventing light in
|
||||||
// Don't excavate the overgenerated stone at node_max.Y + 1,
|
// tunnels at mapchunk borders when generating mapchunks upwards.
|
||||||
// this creates a 'roof' over the tunnel, preventing light in
|
// This 'roof' is removed when the mapchunk above is generated.
|
||||||
// tunnels at mapchunk borders when generating mapchunks upwards.
|
for (s16 y = node_max.Y; y >= node_min.Y - 1; y--,
|
||||||
if (y > node_max.Y)
|
index3d -= ystride,
|
||||||
continue;
|
vm->m_area.add_y(em, vi, -1)) {
|
||||||
|
|
||||||
content_t c = vm->m_data[vi].getContent();
|
content_t c = vm->m_data[vi].getContent();
|
||||||
if (c == CONTENT_AIR || c == biome->c_water_top ||
|
if (c == CONTENT_AIR || c == biome->c_water_top ||
|
||||||
|
@ -717,17 +719,18 @@ void MapgenFractal::generateCaves(s16 max_stone_y)
|
||||||
// Ground
|
// Ground
|
||||||
float d1 = contour(noise_cave1->result[index3d]);
|
float d1 = contour(noise_cave1->result[index3d]);
|
||||||
float d2 = contour(noise_cave2->result[index3d]);
|
float d2 = contour(noise_cave2->result[index3d]);
|
||||||
|
|
||||||
if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
|
if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
|
||||||
// In tunnel and ground content, excavate
|
// In tunnel and ground content, excavate
|
||||||
vm->m_data[vi] = MapNode(CONTENT_AIR);
|
vm->m_data[vi] = MapNode(CONTENT_AIR);
|
||||||
is_tunnel = true;
|
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 {
|
} 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;
|
column_is_open = false;
|
||||||
is_tunnel = false;
|
is_tunnel = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ public:
|
||||||
BiomeManager *bmgr;
|
BiomeManager *bmgr;
|
||||||
|
|
||||||
int ystride;
|
int ystride;
|
||||||
int zstride;
|
int zstride_1d;
|
||||||
u16 formula;
|
u16 formula;
|
||||||
bool julia;
|
bool julia;
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,8 @@ MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge)
|
||||||
// amount of elements to skip for the next index
|
// amount of elements to skip for the next index
|
||||||
// for noise/height/biome maps (not vmanip)
|
// for noise/height/biome maps (not vmanip)
|
||||||
this->ystride = csize.X;
|
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->biomemap = new u8[csize.X * csize.Z];
|
||||||
this->heightmap = new s16[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);
|
noise_height = new Noise(&sp->np_height, seed, csize.X, csize.Z);
|
||||||
|
|
||||||
// 3D terrain noise
|
// 3D terrain noise
|
||||||
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 2, csize.Z);
|
// 1-up 1-down overgeneration
|
||||||
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 2, csize.Z);
|
|
||||||
noise_ground = new Noise(&sp->np_ground, seed, csize.X, csize.Y + 2, csize.Z);
|
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
|
// Biome noise
|
||||||
noise_heat = new Noise(¶ms->np_biome_heat, seed, csize.X, csize.Z);
|
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()
|
void MapgenV5::dustTopNodes()
|
||||||
{
|
{
|
||||||
if (node_max.Y < water_level)
|
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;
|
BiomeManager *bmgr;
|
||||||
|
|
||||||
int ystride;
|
int ystride;
|
||||||
int zstride;
|
int zstride_1d;
|
||||||
u32 spflags;
|
u32 spflags;
|
||||||
|
|
||||||
v3s16 node_min;
|
v3s16 node_min;
|
||||||
|
|
|
@ -59,7 +59,8 @@ MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge)
|
||||||
//// amount of elements to skip for the next index
|
//// amount of elements to skip for the next index
|
||||||
//// for noise/height/biome maps (not vmanip)
|
//// for noise/height/biome maps (not vmanip)
|
||||||
this->ystride = csize.X;
|
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->biomemap = new u8[csize.X * csize.Z];
|
||||||
this->heightmap = new s16[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);
|
noise_ridge_uwater = new Noise(&sp->np_ridge_uwater, seed, csize.X, csize.Z);
|
||||||
|
|
||||||
//// 3d terrain noise
|
//// 3d terrain noise
|
||||||
|
// 1-up 1-down overgeneration
|
||||||
noise_mountain = new Noise(&sp->np_mountain, seed, csize.X, csize.Y + 2, csize.Z);
|
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_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);
|
// 1-down overgeneraion
|
||||||
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 2, csize.Z);
|
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
|
//// Biome noise
|
||||||
noise_heat = new Noise(¶ms->np_biome_heat, seed, csize.X, csize.Z);
|
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)
|
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()
|
int MapgenV7::generateTerrain()
|
||||||
{
|
{
|
||||||
s16 stone_surface_min_y;
|
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
|
#if 0
|
||||||
void MapgenV7::addTopNodes()
|
void MapgenV7::addTopNodes()
|
||||||
{
|
{
|
||||||
|
@ -859,70 +934,3 @@ void MapgenV7::addTopNodes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
BiomeManager *bmgr;
|
||||||
|
|
||||||
int ystride;
|
int ystride;
|
||||||
int zstride;
|
int zstride_1d;
|
||||||
u32 spflags;
|
u32 spflags;
|
||||||
|
|
||||||
v3s16 node_min;
|
v3s16 node_min;
|
||||||
|
|
|
@ -74,6 +74,8 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *
|
||||||
//// for noise/height/biome maps (not vmanip)
|
//// for noise/height/biome maps (not vmanip)
|
||||||
this->ystride = csize.X;
|
this->ystride = csize.X;
|
||||||
this->zstride = csize.X * (csize.Y + 2);
|
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->biomemap = new u8[csize.X * csize.Z];
|
||||||
this->heightmap = new s16[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);
|
noise_valley_profile = new Noise(&sp->np_valley_profile, seed, csize.X, csize.Z);
|
||||||
|
|
||||||
//// 3D Terrain noise
|
//// 3D Terrain noise
|
||||||
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 2, csize.Z);
|
// 1-up 1-down overgeneration
|
||||||
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 2, csize.Z);
|
|
||||||
noise_inter_valley_fill = new Noise(&sp->np_inter_valley_fill, seed, csize.X, csize.Y + 2, csize.Z);
|
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
|
//// Biome noise
|
||||||
noise_heat_blend = new Noise(¶ms->np_biome_heat_blend, seed, csize.X, csize.Z);
|
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) {
|
if (node_max.Y <= massive_cave_depth) {
|
||||||
noise_massive_caves->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
|
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;
|
float tcave = massive_cave_threshold;
|
||||||
|
|
||||||
if (y < yblmin) {
|
if (y < yblmin) {
|
||||||
|
@ -917,35 +921,30 @@ void MapgenValleys::generateCaves(s16 max_stone_y)
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 index_2d = 0;
|
u32 index_2d = 0;
|
||||||
u32 index_3d = 0;
|
|
||||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||||
for (s16 x = node_min.X; x <= node_max.X; x++, index_2d++) {
|
for (s16 x = node_min.X; x <= node_max.X; x++, index_2d++) {
|
||||||
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index_2d]);
|
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index_2d]);
|
||||||
bool air_above = false;
|
bool tunnel_air_above = false;
|
||||||
bool underground = false;
|
bool underground = false;
|
||||||
u32 index_data = vm->m_area.index(x, node_max.Y + 1, z);
|
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);
|
||||||
index_3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + (x - node_min.X);
|
|
||||||
|
|
||||||
// Dig caves on down loop to check for air above.
|
// Dig caves on down loop to check for air above.
|
||||||
for (s16 y = node_max.Y + 1;
|
// Don't excavate the overgenerated stone at node_max.Y + 1,
|
||||||
y >= node_min.Y - 1;
|
// this creates a 'roof' over the tunnel, preventing light in
|
||||||
y--, index_3d -= ystride, vm->m_area.add_y(em, index_data, -1)) {
|
// tunnels at mapchunk borders when generating mapchunks upwards.
|
||||||
// Don't excavate the overgenerated stone at node_max.Y + 1,
|
// This 'roof' is removed when the mapchunk above is generated.
|
||||||
// this creates a 'roof' over the tunnel, preventing light in
|
for (s16 y = node_max.Y; y >= node_min.Y - 1; y--,
|
||||||
// tunnels at mapchunk borders when generating mapchunks upwards.
|
index_3d -= ystride,
|
||||||
if (y > node_max.Y)
|
vm->m_area.add_y(em, index_data, -1)) {
|
||||||
continue;
|
|
||||||
|
|
||||||
float terrain = noise_terrain_height->result[index_2d];
|
float terrain = noise_terrain_height->result[index_2d];
|
||||||
|
|
||||||
// Saves some time.
|
// Saves some time.
|
||||||
if (y > terrain + 10) {
|
if (y > terrain + 10)
|
||||||
air_above = true;
|
|
||||||
continue;
|
continue;
|
||||||
} else if (y < terrain - 40) {
|
else if (y < terrain - 40)
|
||||||
underground = true;
|
underground = true;
|
||||||
}
|
|
||||||
|
|
||||||
// Dig massive caves.
|
// Dig massive caves.
|
||||||
if (node_max.Y <= massive_cave_depth
|
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]) {
|
> tcave_cache[y - node_min.Y + 1]) {
|
||||||
vm->m_data[index_data] = n_air;
|
vm->m_data[index_data] = n_air;
|
||||||
made_a_big_one = true;
|
made_a_big_one = true;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
content_t c = vm->m_data[index_data].getContent();
|
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
|
// River water is not set as ground content
|
||||||
// in the default game. This can produce strange results
|
// 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.
|
// the mapgen to correct. Fix it in lua.
|
||||||
|
|
||||||
if (c == CONTENT_AIR) {
|
if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
|
||||||
air_above = true;
|
// in a tunnel
|
||||||
} else if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
|
|
||||||
// in a cave
|
|
||||||
vm->m_data[index_data] = n_air;
|
vm->m_data[index_data] = n_air;
|
||||||
air_above = true;
|
tunnel_air_above = true;
|
||||||
} else if (air_above && (c == biome->c_filler || c == biome->c_stone)) {
|
} else if (c == biome->c_filler || c == biome->c_stone) {
|
||||||
// at the cave floor
|
if (tunnel_air_above) {
|
||||||
s16 sr = ps.range(0,39);
|
// at the tunnel floor
|
||||||
u32 j = index_data;
|
s16 sr = ps.range(0, 39);
|
||||||
vm->m_area.add_y(em, j, 1);
|
u32 j = index_data;
|
||||||
|
vm->m_area.add_y(em, j, 1);
|
||||||
|
|
||||||
if (sr > terrain - y) {
|
if (sr > terrain - y) {
|
||||||
// Put dirt in caves near the surface.
|
// Put dirt in tunnels near the surface.
|
||||||
if (underground)
|
if (underground)
|
||||||
vm->m_data[index_data] = MapNode(biome->c_filler);
|
vm->m_data[index_data] = MapNode(biome->c_filler);
|
||||||
else
|
else
|
||||||
vm->m_data[index_data] = MapNode(biome->c_top);
|
vm->m_data[index_data] = MapNode(biome->c_top);
|
||||||
} else if (sr < 3 && underground) {
|
} else if (sr < 3 && underground) {
|
||||||
sr = abs(ps.next());
|
sr = abs(ps.next());
|
||||||
if (lava_features_lim > 0 && y <= lava_max_height
|
if (lava_features_lim > 0 && y <= lava_max_height
|
||||||
&& c == biome->c_stone && sr < lava_chance)
|
&& c == biome->c_stone && sr < lava_chance)
|
||||||
vm->m_data[j] = n_lava;
|
vm->m_data[j] = n_lava;
|
||||||
|
|
||||||
sr -= lava_chance;
|
sr -= lava_chance;
|
||||||
|
|
||||||
// If sr < 0 then we should have already placed lava --
|
// If sr < 0 then we should have already placed lava --
|
||||||
// don't immediately dump water on it.
|
// don't immediately dump water on it.
|
||||||
if (water_features_lim > 0 && y <= cave_water_max_height
|
if (water_features_lim > 0 && y <= cave_water_max_height
|
||||||
&& sr >= 0 && sr < water_chance)
|
&& sr >= 0 && sr < water_chance)
|
||||||
vm->m_data[j] = n_water;
|
vm->m_data[j] = n_water;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
air_above = false;
|
tunnel_air_above = false;
|
||||||
underground = true;
|
|
||||||
} else if (c == biome->c_filler || c == biome->c_stone) {
|
|
||||||
air_above = false;
|
|
||||||
underground = true;
|
underground = true;
|
||||||
} else {
|
} 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);
|
u32 bruises_count = ps.range(0, 2);
|
||||||
for (u32 i = 0; i < bruises_count; i++) {
|
for (u32 i = 0; i < bruises_count; i++) {
|
||||||
CaveV5 cave(this, &ps);
|
CaveV5 cave(this, &ps);
|
||||||
|
|
|
@ -106,6 +106,7 @@ private:
|
||||||
|
|
||||||
int ystride;
|
int ystride;
|
||||||
int zstride;
|
int zstride;
|
||||||
|
int zstride_1d;
|
||||||
|
|
||||||
float map_gen_limit;
|
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
|
#ifndef SRP_H
|
||||||
#define SRP_H
|
#define SRP_H
|
||||||
|
|
||||||
|
|
||||||
struct SRPVerifier;
|
struct SRPVerifier;
|
||||||
struct SRPUser;
|
struct SRPUser;
|
||||||
|
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
SRP_NG_1024,
|
SRP_NG_1024,
|
||||||
SRP_NG_2048,
|
SRP_NG_2048,
|
||||||
SRP_NG_4096,
|
SRP_NG_4096,
|
||||||
|
@ -69,8 +67,7 @@ typedef enum
|
||||||
SRP_NG_CUSTOM
|
SRP_NG_CUSTOM
|
||||||
} SRP_NGType;
|
} SRP_NGType;
|
||||||
|
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
/*SRP_SHA1,*/
|
/*SRP_SHA1,*/
|
||||||
/*SRP_SHA224,*/
|
/*SRP_SHA224,*/
|
||||||
SRP_SHA256,
|
SRP_SHA256,
|
||||||
|
@ -78,12 +75,13 @@ typedef enum
|
||||||
SRP_SHA512*/
|
SRP_SHA512*/
|
||||||
} SRP_HashAlgorithm;
|
} SRP_HashAlgorithm;
|
||||||
|
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
SRP_OK,
|
|
||||||
SRP_ERR,
|
SRP_ERR,
|
||||||
|
SRP_OK,
|
||||||
} SRP_Result;
|
} SRP_Result;
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
/* Sets the memory functions used by srp.
|
/* Sets the memory functions used by srp.
|
||||||
* Note: this doesn't set the memory functions used by gmp,
|
* Note: this doesn't set the memory functions used by gmp,
|
||||||
* but it is supported to have different functions for srp and 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.
|
* 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 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.
|
* Returns SRP_OK on success, and SRP_ERR on error.
|
||||||
* bytes_s might be in this case invalid, don't free it.
|
* 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,
|
SRP_NGType ng_type, const char *username_for_verifier,
|
||||||
const unsigned char *password, size_t len_password,
|
const unsigned char *password, size_t len_password,
|
||||||
unsigned char **bytes_s, size_t *len_s,
|
unsigned char **bytes_s, size_t *len_s,
|
||||||
unsigned char **bytes_v, size_t *len_v,
|
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.
|
/* 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,
|
unsigned char** bytes_B, size_t *len_B,
|
||||||
const char* n_hex, const char* g_hex);
|
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
|
// 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 */
|
/* key_length may be null */
|
||||||
const unsigned char* srp_verifier_get_session_key( struct SRPVerifier* ver,
|
const unsigned char *srp_verifier_get_session_key(
|
||||||
size_t *key_length );
|
struct SRPVerifier *ver, size_t *key_length);
|
||||||
|
|
||||||
|
|
||||||
size_t srp_verifier_get_session_key_length(struct SRPVerifier* ver);
|
|
||||||
|
|
||||||
|
size_t srp_verifier_get_session_key_length(struct SRPVerifier *ver);
|
||||||
|
|
||||||
/* Verifies session, on success, it writes bytes_HAMK.
|
/* Verifies session, on success, it writes bytes_HAMK.
|
||||||
* user_M must be exactly srp_verifier_get_session_key_length() bytes in size
|
* user_M must be exactly srp_verifier_get_session_key_length() bytes in size
|
||||||
*/
|
*/
|
||||||
void srp_verifier_verify_session( struct SRPVerifier* ver,
|
void srp_verifier_verify_session(
|
||||||
const unsigned char* user_M, unsigned char** bytes_HAMK );
|
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 */
|
/* 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,
|
struct SRPUser *srp_user_new(SRP_HashAlgorithm alg, SRP_NGType ng_type,
|
||||||
const char *username, const char *username_for_verifier,
|
const char *username, const char *username_for_verifier,
|
||||||
const unsigned char *bytes_password, size_t len_password,
|
const unsigned char *bytes_password, size_t len_password, const char *n_hex,
|
||||||
const char *n_hex, const char *g_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 */
|
/* 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. */
|
* If bytes_a == NULL, random data is used for a. */
|
||||||
SRP_Result srp_user_start_authentication(struct SRPUser* usr, char** username,
|
SRP_Result srp_user_start_authentication(struct SRPUser* usr, char **username,
|
||||||
const unsigned char* bytes_a, size_t len_a,
|
const unsigned char *bytes_a, size_t len_a,
|
||||||
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
|
/* Output: bytes_M, len_M (len_M may be null and will always be
|
||||||
* srp_user_get_session_key_length() bytes in size) */
|
* 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_s, size_t len_s,
|
||||||
const unsigned char *bytes_B, size_t len_B,
|
const unsigned char *bytes_B, size_t len_B,
|
||||||
unsigned char **bytes_M, size_t *len_M);
|
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 */
|
/* 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 */
|
#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