master
Maksim Gamarnik 2016-04-12 21:28:50 +03:00
commit 6d3bdc5a7d
32 changed files with 897 additions and 778 deletions

View File

@ -147,7 +147,7 @@ end
-- Some common functions
--
function nodeupdate_single(p, delay)
function nodeupdate_single(p)
local n = core.get_node(p)
if core.get_item_group(n.name, "falling_node") ~= 0 then
local p_bottom = {x = p.x, y = p.y - 1, z = p.z}
@ -160,36 +160,84 @@ function nodeupdate_single(p, delay)
core.get_node_level(p_bottom) < core.get_node_max_level(p_bottom))) and
(not core.registered_nodes[n_bottom.name].walkable or
core.registered_nodes[n_bottom.name].buildable_to) then
if delay then
core.after(0.1, nodeupdate_single, p, false)
else
n.level = core.get_node_level(p)
core.remove_node(p)
spawn_falling_node(p, n)
nodeupdate(p)
end
n.level = core.get_node_level(p)
core.remove_node(p)
spawn_falling_node(p, n)
return true
end
end
if core.get_item_group(n.name, "attached_node") ~= 0 then
if not check_attached_node(p, n) then
drop_attached_node(p)
nodeupdate(p)
return true
end
end
return false
end
function nodeupdate(p, delay)
-- Round p to prevent falling entities to get stuck
-- This table is specifically ordered.
-- We don't walk diagonals, only our direct neighbors, and self.
-- Down first as likely case, but always before self. The same with sides.
-- Up must come last, so that things above self will also fall all at once.
local nodeupdate_neighbors = {
{x = 0, y = -1, z = 0},
{x = -1, y = 0, z = 0},
{x = 1, y = 0, z = 0},
{x = 0, y = 0, z = 1},
{x = 0, y = 0, z = -1},
{x = 0, y = 0, z = 0},
{x = 0, y = 1, z = 0},
}
function nodeupdate(p)
-- Round p to prevent falling entities to get stuck.
p = vector.round(p)
for x = -1, 1 do
for y = -1, 1 do
for z = -1, 1 do
local d = vector.new(x, y, z)
nodeupdate_single(vector.add(p, d), delay or not (x == 0 and y == 0 and z == 0))
end
end
-- We make a stack, and manually maintain size for performance.
-- Stored in the stack, we will maintain tables with pos, and
-- last neighbor visited. This way, when we get back to each
-- node, we know which directions we have already walked, and
-- which direction is the next to walk.
local s = {}
local n = 0
-- The neighbor order we will visit from our table.
local v = 1
while true do
-- Push current pos onto the stack.
n = n + 1
s[n] = {p = p, v = v}
-- Select next node from neighbor list.
p = vector.add(p, nodeupdate_neighbors[v])
-- Now we check out the node. If it is in need of an update,
-- it will let us know in the return value (true = updated).
if not nodeupdate_single(p) then
-- If we don't need to "recurse" (walk) to it then pop
-- our previous pos off the stack and continue from there,
-- with the v value we were at when we last were at that
-- node
repeat
local pop = s[n]
p = pop.p
v = pop.v
s[n] = nil
n = n - 1
-- If there's nothing left on the stack, and no
-- more sides to walk to, we're done and can exit
if n == 0 and v == 7 then
return
end
until v < 7
-- The next round walk the next neighbor in list.
v = v + 1
else
-- If we did need to walk the neighbor, then
-- start walking it from the walk order start (1),
-- and not the order we just pushed up the stack.
v = 1
end
end
end

View File

@ -12,7 +12,7 @@ if core.print then
-- Override native print and use
-- terminal if that's turned on
function print(...)
local n, t = select("#", ...), { ... }
local n, t = select("#", ...), {...}
for i = 1, n do
t[i] = tostring(t[i])
end
@ -25,26 +25,26 @@ os.setlocale("C", "numeric")
minetest = core
-- Load other files
local scriptdir = core.get_builtin_path()..DIR_DELIM
local gamepath = scriptdir.."game"..DIR_DELIM
local commonpath = scriptdir.."common"..DIR_DELIM
local asyncpath = scriptdir.."async"..DIR_DELIM
local scriptdir = core.get_builtin_path() .. DIR_DELIM
local gamepath = scriptdir .. "game" .. DIR_DELIM
local commonpath = scriptdir .. "common" .. DIR_DELIM
local asyncpath = scriptdir .. "async" .. DIR_DELIM
dofile(commonpath.."strict.lua")
dofile(commonpath.."serialize.lua")
dofile(commonpath.."misc_helpers.lua")
dofile(commonpath .. "strict.lua")
dofile(commonpath .. "serialize.lua")
dofile(commonpath .. "misc_helpers.lua")
if INIT == "game" then
dofile(gamepath.."init.lua")
dofile(gamepath .. "init.lua")
elseif INIT == "mainmenu" then
local mainmenuscript = core.setting_get("main_menu_script")
if mainmenuscript ~= nil and mainmenuscript ~= "" then
dofile(mainmenuscript)
else
dofile(core.get_mainmenu_path()..DIR_DELIM.."init.lua")
dofile(core.get_mainmenu_path() .. DIR_DELIM .. "init.lua")
end
elseif INIT == "async" then
dofile(asyncpath.."init.lua")
dofile(asyncpath .. "init.lua")
else
error(("Unrecognized builtin initialization type %s!"):format(tostring(INIT)))
end

View File

@ -35,24 +35,31 @@ dofile(basepath .. DIR_DELIM .. "fstk" .. DIR_DELIM .. "tabview.lua")
dofile(basepath .. DIR_DELIM .. "fstk" .. DIR_DELIM .. "ui.lua")
dofile(menupath .. DIR_DELIM .. "common.lua")
dofile(menupath .. DIR_DELIM .. "gamemgr.lua")
dofile(menupath .. DIR_DELIM .. "store.lua")
dofile(menupath .. DIR_DELIM .. "dlg_config_world.lua")
dofile(menupath .. DIR_DELIM .. "tab_credits.lua")
if not (PLATFORM == "Android") then
if PLATFORM ~= "Android" then
dofile(menupath .. DIR_DELIM .. "modmgr.lua")
dofile(menupath .. DIR_DELIM .. "tab_settings.lua")
dofile(menupath .. DIR_DELIM .. "dlg_settings_advanced.lua")
dofile(menupath .. DIR_DELIM .. "tab_texturepacks.lua")
dofile(menupath .. DIR_DELIM .. "tab_mods.lua")
dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua")
dofile(menupath .. DIR_DELIM .. "dlg_delete_mod.lua")
dofile(menupath .. DIR_DELIM .. "store.lua")
end
dofile(menupath .. DIR_DELIM .. "dlg_create_world.lua")
--dofile(menupath .. DIR_DELIM .. "dlg_delete_mod.lua")
dofile(menupath .. DIR_DELIM .. "dlg_delete_world.lua")
dofile(menupath .. DIR_DELIM .. "tab_multiplayer.lua")
dofile(menupath .. DIR_DELIM .. "tab_server.lua")
dofile(menupath .. DIR_DELIM .. "tab_singleplayer.lua")
dofile(menupath .. DIR_DELIM .. "textures.lua")
--dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua")
dofile(menupath .. DIR_DELIM .. "dlg_config_world.lua")
if PLATFORM ~= "Android" then
dofile(menupath .. DIR_DELIM .. "dlg_settings_advanced.lua")
dofile(menupath .. DIR_DELIM .. "textures.lua")
end
local tabs = {}
--tabs.mods = dofile(menupath .. DIR_DELIM .. "tab_mods.lua")
tabs.credits = dofile(menupath .. DIR_DELIM .. "tab_credits.lua")
tabs.singleplayer = dofile(menupath .. DIR_DELIM .. "tab_singleplayer.lua")
tabs.multiplayer = dofile(menupath .. DIR_DELIM .. "tab_multiplayer.lua")
tabs.server = dofile(menupath .. DIR_DELIM .. "tab_server.lua")
if PLATFORM ~= "Android" then
tabs.settings = dofile(menupath .. DIR_DELIM .. "tab_settings.lua")
tabs.texturepacks = dofile(menupath .. DIR_DELIM .. "tab_texturepacks.lua")
end
--------------------------------------------------------------------------------
local function main_event_handler(tabview, event)
@ -67,66 +74,64 @@ local function init_globals()
-- Init gamedata
gamedata.worldindex = 0
menudata.worldlist = filterlist.create(
core.get_worlds,
compare_worlds,
-- Unique id comparison function
function(element, uid)
return element.name == uid
end,
-- Filter function
function(element, gameid)
return element.gameid == gameid
end
)
menudata.worldlist = filterlist.create(
core.get_worlds,
compare_worlds,
-- Unique id comparison function
function(element, uid)
return element.name == uid
end,
-- Filter function
function(element, gameid)
return element.gameid == gameid
end
)
menudata.worldlist:add_sort_mechanism("alphabetic", sort_worlds_alphabetic)
menudata.worldlist:set_sortmode("alphabetic")
menudata.worldlist:add_sort_mechanism("alphabetic", sort_worlds_alphabetic)
menudata.worldlist:set_sortmode("alphabetic")
core.setting_set("menu_last_game", "default")
core.setting_set("menu_last_game", "default")
mm_texture.init()
mm_texture.init()
-- Create main tabview
local tv_main = tabview_create("maintab",{x=12,y=5.2},{x=0,y=0})
local tv_main = tabview_create("maintab", {x = 12, y = 5.2}, {x = 0, y = 0})
--tv_main:set_autosave_tab(true)
tv_main:add(tabs.singleplayer)
tv_main:add(tabs.multiplayer)
tv_main:add(tabs.server)
if PLATFORM ~= "Android" then
tv_main:set_autosave_tab(true)
tv_main:add(tabs.settings)
tv_main:add(tabs.texturepacks)
end
tv_main:add(tab_singleplayer)
tv_main:add(tab_multiplayer)
tv_main:add(tab_server)
if PLATFORM ~= "Android" then
tv_main:add(tab_settings)
tv_main:add(tab_texturepacks)
--tv_main:add(tab_mods)
end
tv_main:add(tab_credits)
--tv_main:add(tabs.mods)
tv_main:add(tabs.credits)
tv_main:set_global_event_handler(main_event_handler)
tv_main:set_fixed_size(false)
if not (PLATFORM == "Android") then
tv_main:set_tab(core.setting_get("maintab_LAST"))
end
--if PLATFORM ~= "Android" then
-- tv_main:set_tab(core.setting_get("maintab_LAST"))
--end
ui.set_default("maintab")
tv_main:show()
-- Create modstore ui
if PLATFORM == "Android" then
modstore.init({x=12, y=6}, 3, 2)
modstore.init({x = 12, y = 6}, 3, 2)
else
modstore.init({x=12, y=8}, 4, 3)
modstore.init({x = 12, y = 8}, 4, 3)
end
ui.update()
core.sound_play("main_menu", false)
minetest.set_clouds(false)
core.set_background("background", defaulttexturedir .. "background.jpg");
end
init_globals()

View File

@ -74,7 +74,7 @@ local previous_contributors = {
"Zefram <zefram@fysh.org>",
}
tab_credits = {
return {
name = "credits",
caption = fgettext("Credits"),
cbf_formspec = function(tabview, name, tabdata)

View File

@ -163,7 +163,7 @@ local function handle_buttons(tabview, fields, tabname, tabdata)
end
--------------------------------------------------------------------------------
tab_mods = {
return {
name = "mods",
caption = fgettext("Mods"),
cbf_formspec = get_formspec,

View File

@ -256,10 +256,10 @@ local function on_change(type,old_tab,new_tab)
end
--------------------------------------------------------------------------------
tab_multiplayer = {
return {
name = "multiplayer",
caption = fgettext("Multi Player"),
cbf_formspec = get_formspec,
cbf_button_handler = main_button_handler,
on_change = on_change
}
}

View File

@ -186,10 +186,10 @@ local function main_button_handler(this, fields, name, tabdata)
end
--------------------------------------------------------------------------------
tab_server = {
return {
name = "server",
caption = fgettext("Create Server"),
cbf_formspec = get_formspec,
cbf_button_handler = main_button_handler,
on_change = nil
}
}

View File

@ -384,7 +384,7 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
return ddhandled
end
tab_settings = {
return {
name = "settings",
caption = fgettext("Settings"),
cbf_formspec = formspec,

View File

@ -145,9 +145,10 @@ end
--------------------------------------------------------------------------------
tab_singleplayer = {
return {
name = "singleplayer",
caption = fgettext("Single Player"),
cbf_formspec = get_formspec,
cbf_button_handler = main_button_handler,
}
on_change = on_change
}

View File

@ -123,10 +123,10 @@ local function main_button_handler(tabview, fields, name, tabdata)
end
--------------------------------------------------------------------------------
tab_texturepacks = {
return {
name = "texturepacks",
caption = fgettext("Texturepacks"),
cbf_formspec = get_formspec,
cbf_button_handler = main_button_handler,
on_change = nil
}
}

View File

@ -147,6 +147,21 @@ if(CURSES_USE_NCURSESW)
set(CURSES_HAVE_NCURSESW_CURSES_H "CURSES_HAVE_NCURSESW_CURSES_H-NOTFOUND")
endif()
endif()
if(NOT DEFINED CURSES_HAVE_NCURSES_H)
if(EXISTS "${CURSES_INCLUDE_PATH}/ncurses.h")
set(CURSES_HAVE_NCURSES_H "${CURSES_INCLUDE_PATH}/ncurses.h")
else()
set(CURSES_HAVE_NCURSES_H "CURSES_HAVE_NCURSES_H-NOTFOUND")
endif()
endif()
if(NOT DEFINED CURSES_HAVE_CURSES_H)
if(EXISTS "${CURSES_INCLUDE_PATH}/curses.h")
set(CURSES_HAVE_CURSES_H "${CURSES_INCLUDE_PATH}/curses.h")
else()
set(CURSES_HAVE_CURSES_H "CURSES_HAVE_CURSES_H-NOTFOUND")
endif()
endif()
find_library(CURSES_FORM_LIBRARY form HINTS "${_cursesLibDir}"
DOC "Path to libform.so or .lib or .a")

View File

@ -357,8 +357,13 @@ The mask is applied using binary AND.
#### `[colorize:<color>:<ratio>`
Colorize the textures with the given color.
`<color>` is specified as a `ColorString`.
`<ratio>` is an int ranging from 0 to 255, and specifies how much of the
color to apply. If ommitted, the alpha will be used.
`<ratio>` is an int ranging from 0 to 255 or the word "`alpha`". If
it is an int, then it specifies how far to interpolate between the
colors where 0 is only the texture color and 255 is only `<color>`. If
omitted, the alpha of `<color>` will be used as the ratio. If it is
the word "`alpha`", then each texture pixel will contain the RGB of
`<color>` and the alpha of `<color>` multiplied by the alpha of the
texture pixel.
Sounds
------
@ -940,6 +945,7 @@ Displays a horizontal bar made up of half-images.
* `number`: Number of items in the inventory to be displayed.
* `item`: Position of item that is selected.
* `direction`
* `offset`: offset in pixels from position.
### `waypoint`
Displays distance to selected world position.
@ -1865,6 +1871,7 @@ Call these functions only at load time!
* `modifier`: when true, the function should return the actual hp_change.
Note: modifiers only get a temporary hp_change that can be modified by later modifiers.
modifiers can return true as a second argument to stop the execution of further functions.
Non-modifiers receive the final hp change calculated by the modifiers.
* `minetest.register_on_respawnplayer(func(ObjectRef))`
* Called when player is to be respawned
* Called _before_ repositioning of player occurs

View File

@ -540,6 +540,12 @@ void Camera::drawNametags()
i = m_nametags.begin();
i != m_nametags.end(); ++i) {
Nametag *nametag = *i;
if (nametag->nametag_color.getAlpha() == 0) {
// Enforce hiding nametag,
// because if freetype is enabled, a grey
// shadow can remain.
continue;
}
v3f pos = nametag->parent_node->getPosition() + v3f(0.0, 1.1 * BS, 0.0);
f32 transformed_pos[4] = { pos.X, pos.Y, pos.Z, 1.0f };
trans.multiplyWith1x4Matrix(transformed_pos);

View File

@ -265,7 +265,7 @@ Client::Client(
m_cache_smooth_lighting = g_settings->getBool("smooth_lighting");
m_cache_enable_shaders = g_settings->getBool("enable_shaders");
m_cache_use_tangent_vertices = m_cache_enable_shaders && (
g_settings->getBool("enable_bumpmapping") ||
g_settings->getBool("enable_bumpmapping") ||
g_settings->getBool("enable_parallax_occlusion"));
}

View File

@ -553,10 +553,12 @@ static void blit_with_alpha(video::IImage *src, video::IImage *dst,
static void blit_with_alpha_overlay(video::IImage *src, video::IImage *dst,
v2s32 src_pos, v2s32 dst_pos, v2u32 size);
// Like blit_with_alpha overlay, but uses an int to calculate the ratio
// and modifies any destination pixels that are not fully transparent
static void blit_with_interpolate_overlay(video::IImage *src, video::IImage *dst,
v2s32 src_pos, v2s32 dst_pos, v2u32 size, int ratio);
// Apply a color to an image. Uses an int (0-255) to calculate the ratio.
// If the ratio is 255 or -1 and keep_alpha is true, then it multiples the
// color alpha with the destination alpha.
// Otherwise, any pixels that are not fully transparent get the color alpha.
static void apply_colorize(video::IImage *dst, v2u32 dst_pos, v2u32 size,
video::SColor color, int ratio, bool keep_alpha);
// Apply a mask to an image
static void apply_mask(video::IImage *mask, video::IImage *dst,
@ -1643,27 +1645,17 @@ bool TextureSource::generateImagePart(std::string part_of_name,
video::SColor color;
int ratio = -1;
bool keep_alpha = false;
if (!parseColorString(color_str, color, false))
return false;
if (is_number(ratio_str))
ratio = mystoi(ratio_str, 0, 255);
else if (ratio_str == "alpha")
keep_alpha = true;
core::dimension2d<u32> dim = baseimg->getDimension();
video::IImage *img = driver->createImage(video::ECF_A8R8G8B8, dim);
if (!img) {
errorstream << "generateImagePart(): Could not create image "
<< "for part_of_name=\"" << part_of_name
<< "\", cancelling." << std::endl;
return false;
}
img->fill(video::SColor(color));
// Overlay the colored image
blit_with_interpolate_overlay(img, baseimg, v2s32(0,0), v2s32(0,0), dim, ratio);
img->drop();
apply_colorize(baseimg, v2u32(0, 0), baseimg->getDimension(), color, ratio, keep_alpha);
}
else if (str_starts_with(part_of_name, "[applyfiltersformesh"))
{
@ -1760,6 +1752,9 @@ static void blit_with_alpha_overlay(video::IImage *src, video::IImage *dst,
}
}
// This function has been disabled because it is currently unused.
// Feel free to re-enable if you find it handy.
#if 0
/*
Draw an image on top of an another one, using the specified ratio
modify all partially-opaque pixels in the destination.
@ -1786,6 +1781,45 @@ static void blit_with_interpolate_overlay(video::IImage *src, video::IImage *dst
}
}
}
#endif
/*
Apply color to destination
*/
static void apply_colorize(video::IImage *dst, v2u32 dst_pos, v2u32 size,
video::SColor color, int ratio, bool keep_alpha)
{
u32 alpha = color.getAlpha();
video::SColor dst_c;
if ((ratio == -1 && alpha == 255) || ratio == 255) { // full replacement of color
if (keep_alpha) { // replace the color with alpha = dest alpha * color alpha
dst_c = color;
for (u32 y = dst_pos.Y; y < dst_pos.Y + size.Y; y++)
for (u32 x = dst_pos.X; x < dst_pos.X + size.X; x++) {
u32 dst_alpha = dst->getPixel(x, y).getAlpha();
if (dst_alpha > 0) {
dst_c.setAlpha(dst_alpha * alpha / 255);
dst->setPixel(x, y, dst_c);
}
}
} else { // replace the color including the alpha
for (u32 y = dst_pos.Y; y < dst_pos.Y + size.Y; y++)
for (u32 x = dst_pos.X; x < dst_pos.X + size.X; x++)
if (dst->getPixel(x, y).getAlpha() > 0)
dst->setPixel(x, y, color);
}
} else { // interpolate between the color and destination
float interp = (ratio == -1 ? color.getAlpha() / 255.0f : ratio / 255.0f);
for (u32 y = dst_pos.Y; y < dst_pos.Y + size.Y; y++)
for (u32 x = dst_pos.X; x < dst_pos.X + size.X; x++) {
dst_c = dst->getPixel(x, y);
if (dst_c.getAlpha() > 0) {
dst_c = color.getInterpolated(dst_c, interp);
dst->setPixel(x, y, dst_c);
}
}
}
}
/*
Apply mask to destination

View File

@ -332,8 +332,10 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
// Do not move if world has not loaded yet, since custom node boxes
// are not available for collision detection.
if (!any_position_valid)
if (!any_position_valid) {
*speed_f = v3f(0, 0, 0);
return result;
}
} // tt2

View File

@ -44,7 +44,7 @@ DungeonGen::DungeonGen(Mapgen *mapgen, DungeonParams *dparams)
this->vm = mapgen->vm;
#ifdef DGEN_USE_TORCHES
c_torch = ndef->getId("default:torch");
c_torch = mg->ndef->getId("default:torch");
#endif
if (dparams) {

View File

@ -41,7 +41,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
gui::IGUIEnvironment* guienv, IGameDef *gamedef, LocalPlayer *player,
Inventory *inventory) {
Inventory *inventory)
{
this->driver = driver;
this->smgr = smgr;
this->guienv = guienv;
@ -49,16 +50,15 @@ Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
this->player = player;
this->inventory = inventory;
m_hud_scaling = g_settings->getFloat("hud_scaling");
m_screensize = v2u32(0, 0);
m_displaycenter = v2s32(0, 0);
m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE * porting::getDisplayDensity() + 0.5);
m_hotbar_imagesize *= g_settings->getFloat("hud_scaling");
m_hotbar_imagesize *= m_hud_scaling;
m_padding = m_hotbar_imagesize / 12;
const video::SColor hbar_color(255, 255, 255, 255);
for (unsigned int i=0; i < 4; i++ ){
hbar_colors[i] = hbar_color;
}
for (unsigned int i = 0; i < 4; i++)
hbar_colors[i] = video::SColor(255, 255, 255, 255);
tsrc = gamedef->getTextureSource();
@ -102,7 +102,7 @@ Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
if (mode == "box") {
m_use_selection_mesh = false;
m_selection_material.Thickness =
rangelim(g_settings->getS16("selectionbox_width"), 1, 5);
rangelim(g_settings->getS16("selectionbox_width"), 1, 5);
} else if (mode == "halo") {
m_use_selection_mesh = true;
m_selection_material.setTexture(0, tsrc->getTextureForMesh("halo.png"));
@ -196,25 +196,30 @@ void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect,
}
//NOTE: selectitem = 0 -> no selected; selectitem 1-based
void Hud::drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
InventoryList *mainlist, u16 selectitem, u16 direction)
void Hud::drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount,
s32 inv_offset, InventoryList *mainlist, u16 selectitem, u16 direction)
{
#ifdef HAVE_TOUCHSCREENGUI
if ( (g_touchscreengui) && (offset == 0))
if (g_touchscreengui && inv_offset == 0)
g_touchscreengui->resetHud();
#endif
s32 height = m_hotbar_imagesize + m_padding * 2;
s32 width = (itemcount - offset) * (m_hotbar_imagesize + m_padding * 2);
s32 width = (itemcount - inv_offset) * (m_hotbar_imagesize + m_padding * 2);
if (direction == HUD_DIR_TOP_BOTTOM || direction == HUD_DIR_BOTTOM_TOP) {
width = m_hotbar_imagesize + m_padding * 2;
height = (itemcount - offset) * (m_hotbar_imagesize + m_padding * 2);
s32 tmp = height;
height = width;
width = tmp;
}
// Position of upper left corner of bar
v2s32 pos = upperleftpos;
v2s32 pos = screen_offset;
pos.X *= m_hud_scaling * porting::getDisplayDensity();
pos.Y *= m_hud_scaling * porting::getDisplayDensity();
pos += upperleftpos;
// Store hotbar_image in member variable, used by drawItem()
if (hotbar_image != player->hotbar_image) {
hotbar_image = player->hotbar_image;
if (hotbar_image != "")
@ -223,6 +228,7 @@ void Hud::drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
use_hotbar_image = false;
}
// Store hotbar_selected_image in member variable, used by drawItem()
if (hotbar_selected_image != player->hotbar_selected_image) {
hotbar_selected_image = player->hotbar_selected_image;
if (hotbar_selected_image != "")
@ -231,10 +237,10 @@ void Hud::drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
use_hotbar_selected_image = false;
}
/* draw customized item background */
// draw customized item background
if (use_hotbar_image) {
core::rect<s32> imgrect2(-m_padding/2, -m_padding/2,
width+m_padding/2, height+m_padding/2);
width+m_padding/2, height+m_padding/2);
core::rect<s32> rect2 = imgrect2 + pos;
video::ITexture *texture = tsrc->getTexture(hotbar_image);
core::dimension2di imgsize(texture->getOriginalSize());
@ -243,29 +249,28 @@ void Hud::drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
NULL, hbar_colors, true);
}
for (s32 i = offset; i < itemcount && (size_t)i < mainlist->getSize(); i++)
{
v2s32 steppos;
// Draw items
core::rect<s32> imgrect(0, 0, m_hotbar_imagesize, m_hotbar_imagesize);
for (s32 i = inv_offset; i < itemcount && (size_t)i < mainlist->getSize(); i++) {
s32 fullimglen = m_hotbar_imagesize + m_padding * 2;
core::rect<s32> imgrect(0, 0, m_hotbar_imagesize, m_hotbar_imagesize);
v2s32 steppos;
switch (direction) {
case HUD_DIR_RIGHT_LEFT:
steppos = v2s32(-(m_padding + (i - offset) * fullimglen), m_padding);
break;
case HUD_DIR_TOP_BOTTOM:
steppos = v2s32(m_padding, m_padding + (i - offset) * fullimglen);
break;
case HUD_DIR_BOTTOM_TOP:
steppos = v2s32(m_padding, -(m_padding + (i - offset) * fullimglen));
break;
default:
steppos = v2s32(m_padding + (i - offset) * fullimglen, m_padding);
break;
case HUD_DIR_RIGHT_LEFT:
steppos = v2s32(-(m_padding + (i - inv_offset) * fullimglen), m_padding);
break;
case HUD_DIR_TOP_BOTTOM:
steppos = v2s32(m_padding, m_padding + (i - inv_offset) * fullimglen);
break;
case HUD_DIR_BOTTOM_TOP:
steppos = v2s32(m_padding, -(m_padding + (i - inv_offset) * fullimglen));
break;
default:
steppos = v2s32(m_padding + (i - inv_offset) * fullimglen, m_padding);
break;
}
drawItem(mainlist->getItem(i), (imgrect + pos + steppos), (i +1) == selectitem );
drawItem(mainlist->getItem(i), (imgrect + pos + steppos), (i + 1) == selectitem);
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui)
@ -275,7 +280,8 @@ void Hud::drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
}
void Hud::drawLuaElements(const v3s16 &camera_offset) {
void Hud::drawLuaElements(const v3s16 &camera_offset)
{
u32 text_height = g_fontengine->getTextHeight();
irr::gui::IGUIFont* font = g_fontengine->getFont();
for (size_t i = 0; i != player->maxHudId(); i++) {
@ -326,7 +332,8 @@ void Hud::drawLuaElements(const v3s16 &camera_offset) {
break; }
case HUD_ELEM_INVENTORY: {
InventoryList *inv = inventory->getList(e->text);
drawItems(pos, e->number, 0, inv, e->item, e->dir);
drawItems(pos, v2s32(e->offset.X, e->offset.Y), e->number, 0,
inv, e->item, e->dir);
break; }
case HUD_ELEM_WAYPOINT: {
v3f p_pos = player->getPosition() / BS;
@ -379,8 +386,7 @@ void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture,
if (size == v2s32()) {
dstd = srcd;
} else {
double size_factor = g_settings->getFloat("hud_scaling") *
porting::getDisplayDensity();
float size_factor = m_hud_scaling * porting::getDisplayDensity();
dstd.Height = size.Y * size_factor;
dstd.Width = size.X * size_factor;
offset.X *= size_factor;
@ -448,25 +454,26 @@ void Hud::drawHotbar(u16 playeritem) {
if ( (float) width / (float) porting::getWindowSize().X <=
g_settings->getFloat("hud_hotbar_max_width")) {
if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
drawItems(pos, hotbar_itemcount, 0, mainlist, playeritem + 1, 0);
drawItems(pos, v2s32(0, 0), hotbar_itemcount, 0, mainlist, playeritem + 1, 0);
}
}
else {
} else {
pos.X += width/4;
v2s32 secondpos = pos;
pos = pos - v2s32(0, m_hotbar_imagesize + m_padding);
if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
drawItems(pos, hotbar_itemcount/2, 0, mainlist, playeritem + 1, 0);
drawItems(secondpos, hotbar_itemcount, hotbar_itemcount/2, mainlist, playeritem + 1, 0);
drawItems(pos, v2s32(0, 0), hotbar_itemcount / 2, 0,
mainlist, playeritem + 1, 0);
drawItems(secondpos, v2s32(0, 0), hotbar_itemcount,
hotbar_itemcount / 2, mainlist, playeritem + 1, 0);
}
}
}
void Hud::drawCrosshair() {
void Hud::drawCrosshair()
{
if (use_crosshair_image) {
video::ITexture *crosshair = tsrc->getTexture("crosshair.png");
v2u32 size = crosshair->getOriginalSize();
@ -489,9 +496,9 @@ void Hud::setSelectionPos(const v3f &pos, const v3s16 &camera_offset)
m_selection_pos = pos;
m_selection_pos_with_offset = pos - intToFloat(camera_offset, BS);
}
void Hud::drawSelectionMesh()
{
{
if (!m_use_selection_mesh) {
// Draw 3D selection boxes
video::SMaterial oldmaterial = driver->getMaterial2D();
@ -502,9 +509,9 @@ void Hud::drawSelectionMesh()
aabb3f box = aabb3f(
i->MinEdge + m_selection_pos_with_offset,
i->MaxEdge + m_selection_pos_with_offset);
u32 r = (selectionbox_argb.getRed() *
m_selection_mesh_color.getRed() / 255);
m_selection_mesh_color.getRed() / 255);
u32 g = (selectionbox_argb.getGreen() *
m_selection_mesh_color.getGreen() / 255);
u32 b = (selectionbox_argb.getBlue() *
@ -579,7 +586,7 @@ void Hud::updateSelectionMesh(const v3s16 &camera_offset)
void Hud::resizeHotbar() {
if (m_screensize != porting::getWindowSize()) {
m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE * porting::getDisplayDensity() + 0.5);
m_hotbar_imagesize *= g_settings->getFloat("hud_scaling");
m_hotbar_imagesize *= m_hud_scaling;
m_padding = m_hotbar_imagesize / 12;
m_screensize = porting::getWindowSize();
m_displaycenter = v2s32(m_screensize.X/2,m_screensize.Y/2);

View File

@ -130,7 +130,7 @@ public:
void drawCrosshair();
void drawSelectionMesh();
void updateSelectionMesh(const v3s16 &camera_offset);
std::vector<aabb3f> *getSelectionBoxes()
{ return &m_selection_boxes; }
@ -148,17 +148,18 @@ private:
void drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture,
s32 count, v2s32 offset, v2s32 size=v2s32());
void drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
InventoryList *mainlist, u16 selectitem, u16 direction);
void drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount,
s32 inv_offset, InventoryList *mainlist, u16 selectitem, u16 direction);
void drawItem(const ItemStack &item, const core::rect<s32>& rect,
bool selected);
float m_hud_scaling; // cached minetest setting
v3s16 m_camera_offset;
v2u32 m_screensize;
v2s32 m_displaycenter;
s32 m_hotbar_imagesize;
s32 m_padding;
s32 m_hotbar_imagesize; // Takes hud_scaling into account, updated by resizeHotbar()
s32 m_padding; // Takes hud_scaling into account, updated by resizeHotbar()
video::SColor hbar_colors[4];
std::vector<aabb3f> m_selection_boxes;

View File

@ -58,7 +58,8 @@ MapgenFlat::MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge
//// amount of elements to skip for the next index
//// for noise/height/biome maps (not vmanip)
this->ystride = csize.X;
this->zstride = csize.X * (csize.Y + 2);
// 1-down overgeneration
this->zstride_1d = csize.X * (csize.Y + 1);
this->biomemap = new u8[csize.X * csize.Z];
this->heightmap = new s16[csize.X * csize.Z];
@ -80,8 +81,9 @@ MapgenFlat::MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge
noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z);
//// 3D noise
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 2, csize.Z);
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 2, csize.Z);
// 1-down overgeneraion
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z);
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
//// Biome noise
noise_heat = new Noise(&params->np_biome_heat, seed, csize.X, csize.Z);
@ -566,19 +568,19 @@ void MapgenFlat::generateCaves(s16 max_stone_y)
for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
bool column_is_open = false; // Is column open to overground
bool is_tunnel = false; // Is tunnel or tunnel floor
u32 vi = vm->m_area.index(x, node_max.Y + 1, z);
u32 index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride +
u32 vi = vm->m_area.index(x, node_max.Y, z);
u32 index3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride +
(x - node_min.X);
// Biome of column
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
for (s16 y = node_max.Y + 1; y >= node_min.Y - 1;
y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) {
// Don't excavate the overgenerated stone at node_max.Y + 1,
// this creates a 'roof' over the tunnel, preventing light in
// tunnels at mapchunk borders when generating mapchunks upwards.
if (y > node_max.Y)
continue;
// Don't excavate the overgenerated stone at node_max.Y + 1,
// this creates a 'roof' over the tunnel, preventing light in
// tunnels at mapchunk borders when generating mapchunks upwards.
// This 'roof' is removed when the mapchunk above is generated.
for (s16 y = node_max.Y; y >= node_min.Y - 1; y--,
index3d -= ystride,
vm->m_area.add_y(em, vi, -1)) {
content_t c = vm->m_data[vi].getContent();
if (c == CONTENT_AIR || c == biome->c_water_top ||
@ -589,17 +591,18 @@ void MapgenFlat::generateCaves(s16 max_stone_y)
// Ground
float d1 = contour(noise_cave1->result[index3d]);
float d2 = contour(noise_cave2->result[index3d]);
if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
// In tunnel and ground content, excavate
vm->m_data[vi] = MapNode(CONTENT_AIR);
is_tunnel = true;
} else if (is_tunnel && column_is_open &&
(c == biome->c_filler || c == biome->c_stone)) {
// Tunnel entrance floor
vm->m_data[vi] = MapNode(biome->c_top);
column_is_open = false;
is_tunnel = false;
} else {
// Not in tunnel or not ground content
if (is_tunnel && column_is_open &&
(c == biome->c_filler || c == biome->c_stone))
// Tunnel entrance floor
vm->m_data[vi] = MapNode(biome->c_top);
column_is_open = false;
is_tunnel = false;
}

View File

@ -60,7 +60,7 @@ public:
BiomeManager *bmgr;
int ystride;
int zstride;
int zstride_1d;
u32 spflags;
v3s16 node_min;

View File

@ -56,7 +56,8 @@ MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager *
//// amount of elements to skip for the next index
//// for noise/height/biome maps (not vmanip)
this->ystride = csize.X;
this->zstride = csize.X * (csize.Y + 2);
// 1-down overgeneration
this->zstride_1d = csize.X * (csize.Y + 1);
this->biomemap = new u8[csize.X * csize.Z];
this->heightmap = new s16[csize.X * csize.Z];
@ -85,8 +86,9 @@ MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager *
noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z);
//// 3D terrain noise
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 2, csize.Z);
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 2, csize.Z);
// 1-down overgeneraion
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z);
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
//// Biome noise
noise_heat = new Noise(&params->np_biome_heat, seed, csize.X, csize.Z);
@ -694,19 +696,19 @@ void MapgenFractal::generateCaves(s16 max_stone_y)
for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
bool column_is_open = false; // Is column open to overground
bool is_tunnel = false; // Is tunnel or tunnel floor
u32 vi = vm->m_area.index(x, node_max.Y + 1, z);
u32 index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride +
u32 vi = vm->m_area.index(x, node_max.Y, z);
u32 index3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride +
(x - node_min.X);
// Biome of column
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
for (s16 y = node_max.Y + 1; y >= node_min.Y - 1;
y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) {
// Don't excavate the overgenerated stone at node_max.Y + 1,
// this creates a 'roof' over the tunnel, preventing light in
// tunnels at mapchunk borders when generating mapchunks upwards.
if (y > node_max.Y)
continue;
// Don't excavate the overgenerated stone at node_max.Y + 1,
// this creates a 'roof' over the tunnel, preventing light in
// tunnels at mapchunk borders when generating mapchunks upwards.
// This 'roof' is removed when the mapchunk above is generated.
for (s16 y = node_max.Y; y >= node_min.Y - 1; y--,
index3d -= ystride,
vm->m_area.add_y(em, vi, -1)) {
content_t c = vm->m_data[vi].getContent();
if (c == CONTENT_AIR || c == biome->c_water_top ||
@ -717,17 +719,18 @@ void MapgenFractal::generateCaves(s16 max_stone_y)
// Ground
float d1 = contour(noise_cave1->result[index3d]);
float d2 = contour(noise_cave2->result[index3d]);
if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
// In tunnel and ground content, excavate
vm->m_data[vi] = MapNode(CONTENT_AIR);
is_tunnel = true;
} else if (is_tunnel && column_is_open &&
(c == biome->c_filler || c == biome->c_stone)) {
// Tunnel entrance floor
vm->m_data[vi] = MapNode(biome->c_top);
column_is_open = false;
is_tunnel = false;
} else {
// Not in tunnel or not ground content
if (is_tunnel && column_is_open &&
(c == biome->c_filler || c == biome->c_stone))
// Tunnel entrance floor
vm->m_data[vi] = MapNode(biome->c_top);
column_is_open = false;
is_tunnel = false;
}

View File

@ -65,7 +65,7 @@ public:
BiomeManager *bmgr;
int ystride;
int zstride;
int zstride_1d;
u16 formula;
bool julia;

View File

@ -54,7 +54,8 @@ MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge)
// amount of elements to skip for the next index
// for noise/height/biome maps (not vmanip)
this->ystride = csize.X;
this->zstride = csize.X * (csize.Y + 2);
// 1-down overgeneration
this->zstride_1d = csize.X * (csize.Y + 1);
this->biomemap = new u8[csize.X * csize.Z];
this->heightmap = new s16[csize.X * csize.Z];
@ -70,9 +71,11 @@ MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge)
noise_height = new Noise(&sp->np_height, seed, csize.X, csize.Z);
// 3D terrain noise
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 2, csize.Z);
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 2, csize.Z);
// 1-up 1-down overgeneration
noise_ground = new Noise(&sp->np_ground, seed, csize.X, csize.Y + 2, csize.Z);
// 1-down overgeneraion
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z);
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
// Biome noise
noise_heat = new Noise(&params->np_biome_heat, seed, csize.X, csize.Z);
@ -505,50 +508,6 @@ MgStoneType MapgenV5::generateBiomes(float *heat_map, float *humidity_map)
}
void MapgenV5::generateCaves(int max_stone_y)
{
if (max_stone_y < node_min.Y)
return;
noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
u32 index = 0;
for (s16 z = node_min.Z; z <= node_max.Z; z++)
for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
u32 vi = vm->m_area.index(node_min.X, y, z);
for (s16 x = node_min.X; x <= node_max.X; x++, vi++, index++) {
// Don't excavate the overgenerated stone at node_max.Y + 1,
// this creates a 'roof' over the tunnel, preventing light in
// tunnels at mapchunk borders when generating mapchunks upwards.
if (y > node_max.Y)
continue;
float d1 = contour(noise_cave1->result[index]);
float d2 = contour(noise_cave2->result[index]);
if (d1 * d2 > 0.125f) {
content_t c = vm->m_data[vi].getContent();
if (!ndef->get(c).is_ground_content || c == CONTENT_AIR)
continue;
vm->m_data[vi] = MapNode(CONTENT_AIR);
}
}
}
if (node_max.Y > MGV5_LARGE_CAVE_DEPTH)
return;
PseudoRandom ps(blockseed + 21343);
u32 bruises_count = ps.range(0, 2);
for (u32 i = 0; i < bruises_count; i++) {
CaveV5 cave(this, &ps);
cave.makeCave(node_min, node_max, max_stone_y);
}
}
void MapgenV5::dustTopNodes()
{
if (node_max.Y < water_level)
@ -597,3 +556,72 @@ void MapgenV5::dustTopNodes()
}
}
}
void MapgenV5::generateCaves(int max_stone_y)
{
if (max_stone_y < node_min.Y)
return;
noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
v3s16 em = vm->m_area.getExtent();
u32 index2d = 0;
for (s16 z = node_min.Z; z <= node_max.Z; z++)
for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
bool column_is_open = false; // Is column open to overground
bool is_tunnel = false; // Is tunnel or tunnel floor
// Indexes at column top (node_max.Y)
u32 vi = vm->m_area.index(x, node_max.Y, z);
u32 index3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride +
(x - node_min.X);
// Biome of column
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
// Don't excavate the overgenerated stone at node_max.Y + 1,
// this creates a 'roof' over the tunnel, preventing light in
// tunnels at mapchunk borders when generating mapchunks upwards.
// This 'roof' is removed when the mapchunk above is generated.
for (s16 y = node_max.Y; y >= node_min.Y - 1; y--,
index3d -= ystride,
vm->m_area.add_y(em, vi, -1)) {
content_t c = vm->m_data[vi].getContent();
if (c == CONTENT_AIR || c == biome->c_water_top ||
c == biome->c_water) {
column_is_open = true;
continue;
}
// Ground
float d1 = contour(noise_cave1->result[index3d]);
float d2 = contour(noise_cave2->result[index3d]);
if (d1 * d2 > 0.125f && ndef->get(c).is_ground_content) {
// In tunnel and ground content, excavate
vm->m_data[vi] = MapNode(CONTENT_AIR);
is_tunnel = true;
} else {
// Not in tunnel or not ground content
if (is_tunnel && column_is_open &&
(c == biome->c_filler || c == biome->c_stone))
// Tunnel entrance floor
vm->m_data[vi] = MapNode(biome->c_top);
column_is_open = false;
is_tunnel = false;
}
}
}
if (node_max.Y > MGV5_LARGE_CAVE_DEPTH)
return;
PseudoRandom ps(blockseed + 21343);
u32 bruises_count = ps.range(0, 2);
for (u32 i = 0; i < bruises_count; i++) {
CaveV5 cave(this, &ps);
cave.makeCave(node_min, node_max, max_stone_y);
}
}

View File

@ -53,7 +53,7 @@ public:
BiomeManager *bmgr;
int ystride;
int zstride;
int zstride_1d;
u32 spflags;
v3s16 node_min;

View File

@ -59,7 +59,8 @@ MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge)
//// amount of elements to skip for the next index
//// for noise/height/biome maps (not vmanip)
this->ystride = csize.X;
this->zstride = csize.X * (csize.Y + 2);
// 1-down overgeneration
this->zstride_1d = csize.X * (csize.Y + 1);
this->biomemap = new u8[csize.X * csize.Z];
this->heightmap = new s16[csize.X * csize.Z];
@ -80,10 +81,12 @@ MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge)
noise_ridge_uwater = new Noise(&sp->np_ridge_uwater, seed, csize.X, csize.Z);
//// 3d terrain noise
// 1-up 1-down overgeneration
noise_mountain = new Noise(&sp->np_mountain, seed, csize.X, csize.Y + 2, csize.Z);
noise_ridge = new Noise(&sp->np_ridge, seed, csize.X, csize.Y + 2, csize.Z);
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 2, csize.Z);
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 2, csize.Z);
// 1-down overgeneraion
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z);
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
//// Biome noise
noise_heat = new Noise(&params->np_biome_heat, seed, csize.X, csize.Z);
@ -199,7 +202,7 @@ void MapgenV7Params::writeParams(Settings *settings) const
}
///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
int MapgenV7::getSpawnLevelAtPoint(v2s16 p)
@ -451,41 +454,6 @@ bool MapgenV7::getMountainTerrainFromMap(int idx_xyz, int idx_xz, s16 y)
}
#if 0
void MapgenV7::carveRivers() {
MapNode n_air(CONTENT_AIR), n_water_source(c_water_source);
MapNode n_stone(c_stone);
u32 index = 0;
int river_depth = 4;
for (s16 z = node_min.Z; z <= node_max.Z; z++)
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
float terrain_mod = noise_terrain_mod->result[index];
NoiseParams *np = noise_terrain_river->np;
np.persist = noise_terrain_persist->result[index];
float terrain_river = NoisePerlin2DNoTxfm(np, x, z, seed);
float height = terrain_river * (1 - abs(terrain_mod)) *
noise_terrain_river->np.scale;
height = log(height * height); //log(h^3) is pretty interesting for terrain
s16 y = heightmap[index];
if (height < 1.0 && y > river_depth &&
y - river_depth >= node_min.Y && y <= node_max.Y) {
for (s16 ry = y; ry != y - river_depth; ry--) {
u32 vi = vm->m_area.index(x, ry, z);
vm->m_data[vi] = n_air;
}
u32 vi = vm->m_area.index(x, y - river_depth, z);
vm->m_data[vi] = n_water_source;
}
}
}
#endif
int MapgenV7::generateTerrain()
{
s16 stone_surface_min_y;
@ -765,6 +733,113 @@ void MapgenV7::dustTopNodes()
}
void MapgenV7::generateCaves(s16 max_stone_y)
{
if (max_stone_y < node_min.Y)
return;
noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
v3s16 em = vm->m_area.getExtent();
u32 index2d = 0;
for (s16 z = node_min.Z; z <= node_max.Z; z++)
for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
bool column_is_open = false; // Is column open to overground
bool is_tunnel = false; // Is tunnel or tunnel floor
// Indexes at column top (node_max.Y)
u32 vi = vm->m_area.index(x, node_max.Y, z);
u32 index3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride +
(x - node_min.X);
// Biome of column
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
// Don't excavate the overgenerated stone at node_max.Y + 1,
// this creates a 'roof' over the tunnel, preventing light in
// tunnels at mapchunk borders when generating mapchunks upwards.
// This 'roof' is removed when the mapchunk above is generated.
for (s16 y = node_max.Y; y >= node_min.Y - 1; y--,
index3d -= ystride,
vm->m_area.add_y(em, vi, -1)) {
content_t c = vm->m_data[vi].getContent();
if (c == CONTENT_AIR || c == biome->c_water_top ||
c == biome->c_water) {
column_is_open = true;
continue;
}
// Ground
float d1 = contour(noise_cave1->result[index3d]);
float d2 = contour(noise_cave2->result[index3d]);
if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
// In tunnel and ground content, excavate
vm->m_data[vi] = MapNode(CONTENT_AIR);
is_tunnel = true;
} else {
// Not in tunnel or not ground content
if (is_tunnel && column_is_open &&
(c == biome->c_filler || c == biome->c_stone))
// Tunnel entrance floor
vm->m_data[vi] = MapNode(biome->c_top);
column_is_open = false;
is_tunnel = false;
}
}
}
if (node_min.Y >= water_level)
return;
PseudoRandom ps(blockseed + 21343);
u32 bruises_count = ps.range(0, 2);
for (u32 i = 0; i < bruises_count; i++) {
CaveV7 cave(this, &ps);
cave.makeCave(node_min, node_max, max_stone_y);
}
}
///////////////////////////////////////////////////////////////
#if 0
void MapgenV7::carveRivers() {
MapNode n_air(CONTENT_AIR), n_water_source(c_water_source);
MapNode n_stone(c_stone);
u32 index = 0;
int river_depth = 4;
for (s16 z = node_min.Z; z <= node_max.Z; z++)
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
float terrain_mod = noise_terrain_mod->result[index];
NoiseParams *np = noise_terrain_river->np;
np.persist = noise_terrain_persist->result[index];
float terrain_river = NoisePerlin2DNoTxfm(np, x, z, seed);
float height = terrain_river * (1 - abs(terrain_mod)) *
noise_terrain_river->np.scale;
height = log(height * height); //log(h^3) is pretty interesting for terrain
s16 y = heightmap[index];
if (height < 1.0 && y > river_depth &&
y - river_depth >= node_min.Y && y <= node_max.Y) {
for (s16 ry = y; ry != y - river_depth; ry--) {
u32 vi = vm->m_area.index(x, ry, z);
vm->m_data[vi] = n_air;
}
u32 vi = vm->m_area.index(x, y - river_depth, z);
vm->m_data[vi] = n_water_source;
}
}
}
#endif
#if 0
void MapgenV7::addTopNodes()
{
@ -859,70 +934,3 @@ void MapgenV7::addTopNodes()
}
}
#endif
void MapgenV7::generateCaves(s16 max_stone_y)
{
if (max_stone_y < node_min.Y)
return;
noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
v3s16 em = vm->m_area.getExtent();
u32 index2d = 0;
for (s16 z = node_min.Z; z <= node_max.Z; z++)
for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
bool column_is_open = false; // Is column open to overground
bool is_tunnel = false; // Is tunnel or tunnel floor
u32 vi = vm->m_area.index(x, node_max.Y + 1, z);
u32 index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride +
(x - node_min.X);
// Biome of column
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
for (s16 y = node_max.Y + 1; y >= node_min.Y - 1;
y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) {
// Don't excavate the overgenerated stone at node_max.Y + 1,
// this creates a 'roof' over the tunnel, preventing light in
// tunnels at mapchunk borders when generating mapchunks upwards.
if (y > node_max.Y)
continue;
content_t c = vm->m_data[vi].getContent();
if (c == CONTENT_AIR || c == biome->c_water_top ||
c == biome->c_water) {
column_is_open = true;
continue;
}
// Ground
float d1 = contour(noise_cave1->result[index3d]);
float d2 = contour(noise_cave2->result[index3d]);
if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
// In tunnel and ground content, excavate
vm->m_data[vi] = MapNode(CONTENT_AIR);
is_tunnel = true;
} else if (is_tunnel && column_is_open &&
(c == biome->c_filler || c == biome->c_stone)) {
// Tunnel entrance floor
vm->m_data[vi] = MapNode(biome->c_top);
column_is_open = false;
is_tunnel = false;
} else {
column_is_open = false;
is_tunnel = false;
}
}
}
if (node_min.Y >= water_level)
return;
PseudoRandom ps(blockseed + 21343);
u32 bruises_count = ps.range(0, 2);
for (u32 i = 0; i < bruises_count; i++) {
CaveV7 cave(this, &ps);
cave.makeCave(node_min, node_max, max_stone_y);
}
}

View File

@ -59,7 +59,7 @@ public:
BiomeManager *bmgr;
int ystride;
int zstride;
int zstride_1d;
u32 spflags;
v3s16 node_min;

View File

@ -74,6 +74,8 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *
//// for noise/height/biome maps (not vmanip)
this->ystride = csize.X;
this->zstride = csize.X * (csize.Y + 2);
// 1-down overgeneration
this->zstride_1d = csize.X * (csize.Y + 1);
this->biomemap = new u8[csize.X * csize.Z];
this->heightmap = new s16[csize.X * csize.Z];
@ -113,10 +115,12 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *
noise_valley_profile = new Noise(&sp->np_valley_profile, seed, csize.X, csize.Z);
//// 3D Terrain noise
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 2, csize.Z);
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 2, csize.Z);
// 1-up 1-down overgeneration
noise_inter_valley_fill = new Noise(&sp->np_inter_valley_fill, seed, csize.X, csize.Y + 2, csize.Z);
noise_massive_caves = new Noise(&sp->np_massive_caves, seed, csize.X, csize.Y + 2, csize.Z);
// 1-down overgeneraion
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z);
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
noise_massive_caves = new Noise(&sp->np_massive_caves, seed, csize.X, csize.Y + 1, csize.Z);
//// Biome noise
noise_heat_blend = new Noise(&params->np_biome_heat_blend, seed, csize.X, csize.Z);
@ -885,7 +889,7 @@ void MapgenValleys::generateCaves(s16 max_stone_y)
if (node_max.Y <= massive_cave_depth) {
noise_massive_caves->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
for (s16 y = node_min.Y - 1; y <= node_max.Y; y++) {
float tcave = massive_cave_threshold;
if (y < yblmin) {
@ -917,35 +921,30 @@ void MapgenValleys::generateCaves(s16 max_stone_y)
}
u32 index_2d = 0;
u32 index_3d = 0;
for (s16 z = node_min.Z; z <= node_max.Z; z++)
for (s16 x = node_min.X; x <= node_max.X; x++, index_2d++) {
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index_2d]);
bool air_above = false;
bool tunnel_air_above = false;
bool underground = false;
u32 index_data = vm->m_area.index(x, node_max.Y + 1, z);
index_3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + (x - node_min.X);
u32 index_data = vm->m_area.index(x, node_max.Y, z);
u32 index_3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride + (x - node_min.X);
// Dig caves on down loop to check for air above.
for (s16 y = node_max.Y + 1;
y >= node_min.Y - 1;
y--, index_3d -= ystride, vm->m_area.add_y(em, index_data, -1)) {
// Don't excavate the overgenerated stone at node_max.Y + 1,
// this creates a 'roof' over the tunnel, preventing light in
// tunnels at mapchunk borders when generating mapchunks upwards.
if (y > node_max.Y)
continue;
// Don't excavate the overgenerated stone at node_max.Y + 1,
// this creates a 'roof' over the tunnel, preventing light in
// tunnels at mapchunk borders when generating mapchunks upwards.
// This 'roof' is removed when the mapchunk above is generated.
for (s16 y = node_max.Y; y >= node_min.Y - 1; y--,
index_3d -= ystride,
vm->m_area.add_y(em, index_data, -1)) {
float terrain = noise_terrain_height->result[index_2d];
// Saves some time.
if (y > terrain + 10) {
air_above = true;
if (y > terrain + 10)
continue;
} else if (y < terrain - 40) {
else if (y < terrain - 40)
underground = true;
}
// Dig massive caves.
if (node_max.Y <= massive_cave_depth
@ -953,6 +952,7 @@ void MapgenValleys::generateCaves(s16 max_stone_y)
> tcave_cache[y - node_min.Y + 1]) {
vm->m_data[index_data] = n_air;
made_a_big_one = true;
continue;
}
content_t c = vm->m_data[index_data].getContent();
@ -961,54 +961,51 @@ void MapgenValleys::generateCaves(s16 max_stone_y)
// River water is not set as ground content
// in the default game. This can produce strange results
// when a cave undercuts a river. However, that's not for
// when a tunnel undercuts a river. However, that's not for
// the mapgen to correct. Fix it in lua.
if (c == CONTENT_AIR) {
air_above = true;
} else if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
// in a cave
if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
// in a tunnel
vm->m_data[index_data] = n_air;
air_above = true;
} else if (air_above && (c == biome->c_filler || c == biome->c_stone)) {
// at the cave floor
s16 sr = ps.range(0,39);
u32 j = index_data;
vm->m_area.add_y(em, j, 1);
tunnel_air_above = true;
} else if (c == biome->c_filler || c == biome->c_stone) {
if (tunnel_air_above) {
// at the tunnel floor
s16 sr = ps.range(0, 39);
u32 j = index_data;
vm->m_area.add_y(em, j, 1);
if (sr > terrain - y) {
// Put dirt in caves near the surface.
if (underground)
vm->m_data[index_data] = MapNode(biome->c_filler);
else
vm->m_data[index_data] = MapNode(biome->c_top);
} else if (sr < 3 && underground) {
sr = abs(ps.next());
if (lava_features_lim > 0 && y <= lava_max_height
&& c == biome->c_stone && sr < lava_chance)
vm->m_data[j] = n_lava;
if (sr > terrain - y) {
// Put dirt in tunnels near the surface.
if (underground)
vm->m_data[index_data] = MapNode(biome->c_filler);
else
vm->m_data[index_data] = MapNode(biome->c_top);
} else if (sr < 3 && underground) {
sr = abs(ps.next());
if (lava_features_lim > 0 && y <= lava_max_height
&& c == biome->c_stone && sr < lava_chance)
vm->m_data[j] = n_lava;
sr -= lava_chance;
sr -= lava_chance;
// If sr < 0 then we should have already placed lava --
// don't immediately dump water on it.
if (water_features_lim > 0 && y <= cave_water_max_height
&& sr >= 0 && sr < water_chance)
vm->m_data[j] = n_water;
// If sr < 0 then we should have already placed lava --
// don't immediately dump water on it.
if (water_features_lim > 0 && y <= cave_water_max_height
&& sr >= 0 && sr < water_chance)
vm->m_data[j] = n_water;
}
}
air_above = false;
underground = true;
} else if (c == biome->c_filler || c == biome->c_stone) {
air_above = false;
tunnel_air_above = false;
underground = true;
} else {
air_above = false;
tunnel_air_above = false;
}
}
}
if (node_max.Y <= large_cave_depth && (!made_a_big_one)) {
if (node_max.Y <= large_cave_depth && !made_a_big_one) {
u32 bruises_count = ps.range(0, 2);
for (u32 i = 0; i < bruises_count; i++) {
CaveV5 cave(this, &ps);

View File

@ -106,6 +106,7 @@ private:
int ystride;
int zstride;
int zstride_1d;
float map_gen_limit;

File diff suppressed because it is too large Load Diff

View File

@ -56,12 +56,10 @@
#ifndef SRP_H
#define SRP_H
struct SRPVerifier;
struct SRPUser;
typedef enum
{
typedef enum {
SRP_NG_1024,
SRP_NG_2048,
SRP_NG_4096,
@ -69,8 +67,7 @@ typedef enum
SRP_NG_CUSTOM
} SRP_NGType;
typedef enum
{
typedef enum {
/*SRP_SHA1,*/
/*SRP_SHA224,*/
SRP_SHA256,
@ -78,12 +75,13 @@ typedef enum
SRP_SHA512*/
} SRP_HashAlgorithm;
typedef enum
{
SRP_OK,
typedef enum {
SRP_ERR,
SRP_OK,
} SRP_Result;
// clang-format off
/* Sets the memory functions used by srp.
* Note: this doesn't set the memory functions used by gmp,
* but it is supported to have different functions for srp and gmp.
@ -101,17 +99,18 @@ void srp_set_memory_functions(
* The n_hex and g_hex parameters should be 0 unless SRP_NG_CUSTOM is used for ng_type.
* If provided, they must contain ASCII text of the hexidecimal notation.
*
* If bytes_s == NULL, it is filled with random data. The caller is responsible for freeing.
* If bytes_s == NULL, it is filled with random data.
* The caller is responsible for freeing.
*
* Returns SRP_OK on success, and SRP_ERR on error.
* bytes_s might be in this case invalid, don't free it.
*/
SRP_Result srp_create_salted_verification_key( SRP_HashAlgorithm alg,
SRP_Result srp_create_salted_verification_key(SRP_HashAlgorithm alg,
SRP_NGType ng_type, const char *username_for_verifier,
const unsigned char *password, size_t len_password,
unsigned char **bytes_s, size_t *len_s,
unsigned char **bytes_v, size_t *len_v,
const char * n_hex, const char *g_hex );
const char *n_hex, const char *g_hex);
/* Out: bytes_B, len_B.
*
@ -132,54 +131,54 @@ struct SRPVerifier* srp_verifier_new(SRP_HashAlgorithm alg, SRP_NGType ng_type,
unsigned char** bytes_B, size_t *len_B,
const char* n_hex, const char* g_hex);
// clang-format on
void srp_verifier_delete( struct SRPVerifier* ver );
void srp_verifier_delete(struct SRPVerifier *ver);
// srp_verifier_verify_session must have been called before
int srp_verifier_is_authenticated( struct SRPVerifier* ver );
int srp_verifier_is_authenticated(struct SRPVerifier *ver);
const char * srp_verifier_get_username( struct SRPVerifier* ver );
const char *srp_verifier_get_username(struct SRPVerifier *ver);
/* key_length may be null */
const unsigned char* srp_verifier_get_session_key( struct SRPVerifier* ver,
size_t *key_length );
size_t srp_verifier_get_session_key_length(struct SRPVerifier* ver);
const unsigned char *srp_verifier_get_session_key(
struct SRPVerifier *ver, size_t *key_length);
size_t srp_verifier_get_session_key_length(struct SRPVerifier *ver);
/* Verifies session, on success, it writes bytes_HAMK.
* user_M must be exactly srp_verifier_get_session_key_length() bytes in size
*/
void srp_verifier_verify_session( struct SRPVerifier* ver,
const unsigned char* user_M, unsigned char** bytes_HAMK );
void srp_verifier_verify_session(
struct SRPVerifier *ver, const unsigned char *user_M, unsigned char **bytes_HAMK);
/*******************************************************************************/
/* The n_hex and g_hex parameters should be 0 unless SRP_NG_CUSTOM is used for ng_type */
struct SRPUser *srp_user_new(SRP_HashAlgorithm alg, SRP_NGType ng_type,
const char *username, const char *username_for_verifier,
const unsigned char *bytes_password, size_t len_password,
const char *n_hex, const char *g_hex);
const unsigned char *bytes_password, size_t len_password, const char *n_hex,
const char *g_hex);
void srp_user_delete(struct SRPUser * usr);
void srp_user_delete(struct SRPUser *usr);
int srp_user_is_authenticated(struct SRPUser * usr);
int srp_user_is_authenticated(struct SRPUser *usr);
const char* srp_user_get_username(struct SRPUser * usr);
const char *srp_user_get_username(struct SRPUser *usr);
/* key_length may be null */
const unsigned char* srp_user_get_session_key(struct SRPUser* usr, size_t* key_length);
const unsigned char *srp_user_get_session_key(struct SRPUser *usr, size_t *key_length);
size_t srp_user_get_session_key_length(struct SRPUser* usr);
size_t srp_user_get_session_key_length(struct SRPUser *usr);
/* Output: username, bytes_A, len_A. If you don't want it get written, set username to NULL.
// clang-format off
/* Output: username, bytes_A, len_A.
* If you don't want it get written, set username to NULL.
* If bytes_a == NULL, random data is used for a. */
SRP_Result srp_user_start_authentication(struct SRPUser* usr, char** username,
const unsigned char* bytes_a, size_t len_a,
unsigned char** bytes_A, size_t* len_A);
SRP_Result srp_user_start_authentication(struct SRPUser* usr, char **username,
const unsigned char *bytes_a, size_t len_a,
unsigned char **bytes_A, size_t* len_A);
/* Output: bytes_M, len_M (len_M may be null and will always be
* srp_user_get_session_key_length() bytes in size) */
@ -187,8 +186,9 @@ void srp_user_process_challenge(struct SRPUser *usr,
const unsigned char *bytes_s, size_t len_s,
const unsigned char *bytes_B, size_t len_B,
unsigned char **bytes_M, size_t *len_M);
// clang-format on
/* bytes_HAMK must be exactly srp_user_get_session_key_length() bytes in size */
void srp_user_verify_session(struct SRPUser* usr, const unsigned char* bytes_HAMK);
void srp_user_verify_session(struct SRPUser *usr, const unsigned char *bytes_HAMK);
#endif /* Include Guard */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB