Showing with 363 additions and 175 deletions.
  1. +93 −0 builtin/misc_helpers.lua
  2. +1 −1 builtin/misc_register.lua
  3. +6 −2 doc/lua_api.txt
  4. +2 −0 games/minimal/mods/default/init.lua
  5. +1 −1 src/clientserver.h
  6. +4 −2 src/content_abm.cpp
  7. +37 −13 src/content_mapblock.cpp
  8. +170 −121 src/map.cpp
  9. +34 −27 src/mapnode.cpp
  10. +2 −2 src/mapnode.h
  11. +2 −3 src/nodedef.cpp
  12. +10 −1 src/nodedef.h
  13. +1 −2 src/script/common/c_content.cpp
93 changes: 93 additions & 0 deletions builtin/misc_helpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,99 @@ if minetest then
end


--------------------------------------------------------------------------------
--Wrapper for rotate_and_place() to check for sneak and assume Creative mode
--implies infinite stacks when performing a 6d rotation.
--------------------------------------------------------------------------------


minetest.rotate_node = function(itemstack, placer, pointed_thing)
minetest.rotate_and_place(itemstack, placer, pointed_thing,
minetest.setting_getbool("creative_mode"),
{invert_wall = placer:get_player_control().sneak})
return itemstack
end
end

--------------------------------------------------------------------------------

if minetest then
local dirs1 = { 9, 18, 7, 12 }
local dirs2 = { 20, 23, 22, 21 }

function minetest.rotate_and_place(itemstack, placer, pointed_thing, infinitestacks, orient_flags)
orient_flags = orient_flags or {}

local node = minetest.get_node(pointed_thing.under)
if not minetest.registered_nodes[node.name]
or not minetest.registered_nodes[node.name].on_rightclick then

local above = pointed_thing.above
local under = pointed_thing.under
local pitch = placer:get_look_pitch()
local pname = minetest.get_node(under).name
local node = minetest.get_node(above)
local fdir = minetest.dir_to_facedir(placer:get_look_dir())
local wield_name = itemstack:get_name()
local reg_node = minetest.registered_nodes[pname]

if not reg_node or not reg_node.on_rightclick then

local iswall = (above.x ~= under.x) or (above.z ~= under.z)
local isceiling = (above.x == under.x) and (above.z == under.z)
and (pitch > 0)
local pos1 = above

if reg_node and reg_node.buildable_to then
pos1 = under
iswall = false
end

reg_node = minetest.registered_nodes[minetest.get_node(pos1).name]
if not reg_node or not reg_node.buildable_to then
return
end

if orient_flags.force_floor then
iswall = false
isceiling = false
elseif orient_flags.force_ceiling then
iswall = false
isceiling = true
elseif orient_flags.force_wall then
iswall = true
isceiling = false
elseif orient_flags.invert_wall then
iswall = not iswall
end

if iswall then
minetest.add_node(pos1, {name = wield_name, param2 = dirs1[fdir+1] })
elseif isceiling then
if orient_flags.force_facedir then
minetest.add_node(pos1, {name = wield_name, param2 = 20 })
else
minetest.add_node(pos1, {name = wield_name, param2 = dirs2[fdir+1] })
end
else -- place right side up
if orient_flags.force_facedir then
minetest.add_node(pos1, {name = wield_name, param2 = 0 })
else
minetest.add_node(pos1, {name = wield_name, param2 = fdir })
end
end

if not infinitestacks then
itemstack:take_item()
return itemstack
end
end
else
minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack)
end
end


--------------------------------------------------------------------------------
--Wrapper for rotate_and_place() to check for sneak and assume Creative mode
--implies infinite stacks when performing a 6d rotation.
Expand Down
2 changes: 1 addition & 1 deletion builtin/misc_register.lua
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ function minetest.register_item(name, itemdef)
end

-- Flowing liquid uses param2
if itemdef.type == "node" and itemdef.liquidtype == "flowing" then
if itemdef.type == "node" and itemdef.liquidtype == "flowing" and itemdef.paramtype2 == nil then
itemdef.paramtype2 = "flowingliquid"
end

Expand Down
8 changes: 6 additions & 2 deletions doc/lua_api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2126,8 +2126,12 @@ Node definition (register_node)
liquid_viscosity = 0, -- Higher viscosity = slower flow (max. 7)
liquid_renewable = true, -- Can new liquid source be created by placing two or more sources nearby?
freezemelt = "", -- water for snow/ice, ice/snow for water
leveled = 0, -- Block contain level in param2. value - default level, used for snow. Dont forget use "leveled" type nodebox
liquid_range = 8, -- number of flowing nodes arround source (max. 8)
leveled = 0, -- Block contain level in param2. value - default level, used for snow.
^ Dont forget use "leveled" type nodebox.
^ Special sense for liquids with paramtype2="leveled" and source :
^ defines maximum number of liquid levels in node (default=8)
^ Less levels -> faster flooding, more levels -> larger flood area, smoother and more cpu use for flow.
^ possible values for liquids 2..63; 1 - special value for sand or gravel
drowning = 0, -- Player will take this amount of damage if no bubbles are left
light_source = 0, -- Amount of light emitted by node
damage_per_second = 0, -- If player is inside node, this damage is caused
Expand Down
2 changes: 2 additions & 0 deletions games/minimal/mods/default/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,7 @@ minetest.register_node("default:water_flowing", {
},
alpha = WATER_ALPHA,
paramtype = "light",
paramtype2 = "flowingliquid",
walkable = false,
pointable = false,
diggable = false,
Expand Down Expand Up @@ -1052,6 +1053,7 @@ minetest.register_node("default:lava_flowing", {
},
},
paramtype = "light",
paramtype2 = "flowingliquid",
light_source = LIGHT_MAX - 1,
walkable = false,
pointable = false,
Expand Down
2 changes: 1 addition & 1 deletion src/clientserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
TOCLIENT_BREATH
TOSERVER_BREATH
range added to ItemDefinition
drowning, leveled and liquid_range added to ContentFeatures
drowning, leveled added to ContentFeatures
stepheight and collideWithObjects added to object properties
version, heat and humidity transfer in MapBock
automatic_face_movement_dir and automatic_face_movement_dir_offset
Expand Down
6 changes: 4 additions & 2 deletions src/content_abm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ class LiquidFlowABM : public ActiveBlockModifier {

public:
LiquidFlowABM(ServerEnvironment *env, INodeDefManager *nodemgr) {
std::set<content_t> liquids;
contents.insert("group:liquid_flow");
std::set<content_t> liquids; // todo: remove, make all via group:liquid_flow
nodemgr->getIds("group:liquid", liquids);
for(std::set<content_t>::const_iterator k = liquids.begin(); k != liquids.end(); k++)
contents.insert(nodemgr->get(*k).liquid_alternative_flowing);
Expand All @@ -64,7 +65,8 @@ class LiquidDropABM : public ActiveBlockModifier {

public:
LiquidDropABM(ServerEnvironment *env, INodeDefManager *nodemgr) {
std::set<content_t> liquids;
contents.insert("group:liquid_drop");
std::set<content_t> liquids; // todo: remove, make all via group:liquid_drop
nodemgr->getIds("group:liquid", liquids);
for(std::set<content_t>::const_iterator k = liquids.begin(); k != liquids.end(); k++)
contents.insert(nodemgr->get(*k).liquid_alternative_source);
Expand Down
50 changes: 37 additions & 13 deletions src/content_mapblock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,

// Don't draw any faces if neighbor same is liquid and top is
// same liquid
if(neighbor_is_same_liquid && !top_is_same_liquid)
if(neighbor_is_same_liquid && top_is_same_liquid)
continue;

// Use backface culled material if neighbor doesn't have a
Expand Down Expand Up @@ -370,11 +370,13 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
*/
TileSpec tile_liquid = f.special_tiles[0];
TileSpec tile_liquid_bfculled = f.special_tiles[1];
const TileSpec *current_tile = &tile_liquid;

bool top_is_same_liquid = false;
MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z));
content_t c_flowing = nodedef->getId(f.liquid_alternative_flowing);
content_t c_source = nodedef->getId(f.liquid_alternative_source);
TileSpec tile_liquid_source = nodedef->get(c_source).special_tiles[0];
if(ntop.getContent() == c_flowing || ntop.getContent() == c_source)
top_is_same_liquid = true;

Expand All @@ -394,8 +396,6 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
else
l = getInteriorLight(n, 0, data);
video::SColor c = MapBlock_LightColor(f.alpha, l, decode_light(f.light_source));

u8 range = rangelim(nodedef->get(c_flowing).liquid_range, 1, 8);

// Neighbor liquid levels (key = relative position)
// Includes current node
Expand Down Expand Up @@ -429,12 +429,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
if(n2.getContent() == c_source)
level = (-0.5+node_liquid_level) * BS;
else if(n2.getContent() == c_flowing){
u8 liquid_level = (n2.param2&LIQUID_LEVEL_MASK);
if (liquid_level <= LIQUID_LEVEL_MAX+1-range)
liquid_level = 0;
else
liquid_level -= (LIQUID_LEVEL_MAX+1-range);
level = (-0.5 + ((float)liquid_level+ 0.5) / (float)range * node_liquid_level) * BS;
level = (-0.5 + ((float)n2.getLevel(nodedef)
+ 0.5) / n2.getMaxLevel(nodedef) * node_liquid_level) * BS;
}

// Check node above neighbor.
Expand Down Expand Up @@ -498,7 +494,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
}
}
if(air_count >= 2)
cornerlevel = -0.5*BS+0.2;
cornerlevel = -0.5*BS+(float)1/f.getMaxLevel();
else if(valid_count > 0)
cornerlevel /= valid_count;
corner_levels[i] = cornerlevel;
Expand Down Expand Up @@ -545,12 +541,12 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
// Don't draw any faces if neighbor same is liquid and top is
// same liquid
if(neighbor_is_same_liquid == true
&& top_is_same_liquid == false)
&& top_is_same_liquid == true)
continue;

// Use backface culled material if neighbor doesn't have a
// solidness of 0
const TileSpec *current_tile = &tile_liquid;
current_tile = &tile_liquid;
if(n_feat.solidness != 0 || n_feat.visual_solidness != 0)
current_tile = &tile_liquid_bfculled;

Expand Down Expand Up @@ -631,6 +627,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,

if(top_is_same_liquid == false)
{
current_tile = &tile_liquid_source;
video::S3DVertex vertices[4] =
{
video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,1),
Expand All @@ -650,6 +647,9 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
//vertices[i].Pos.Y += neighbor_levels[v3s16(0,0,0)];
s32 j = corner_resolve[i];
vertices[i].Pos.Y += corner_levels[j];
if (neighbor_levels[neighbor_dirs[0]] > corner_levels[j] + 0.25 ||
neighbor_levels[neighbor_dirs[0]] < corner_levels[j] - 0.25)
current_tile = &tile_liquid;
vertices[i].Pos += intToFloat(p, BS);
}

Expand Down Expand Up @@ -689,8 +689,32 @@ void mapblock_mesh_generate_special(MeshMakeData *data,

u16 indices[] = {0,1,2,2,3,0};
// Add to mesh collector
collector.append(tile_liquid, vertices, 4, indices, 6);
collector.append(*current_tile, vertices, 4, indices, 6);
}

/*
Generate bottom side, if appropriate
*/
MapNode n_bottom = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y-1,z));
const ContentFeatures &f_bottom = nodedef->get(n_bottom);
if (!f_bottom.walkable && n_bottom.getContent() != c_flowing &&
n_bottom.getContent() != c_source) {
video::S3DVertex vertices[4] = {
video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,1),
video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, 1,1),
video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c, 1,0),
video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c, 0,0),
};

v3f offset(p.X*BS, p.Y*BS + -0.5*BS, p.Z*BS);
for(s32 i=0; i<4; i++) {
vertices[i].Pos += offset;
}

u16 indices[] = {0,1,2,2,3,0};
// Add to mesh collector
collector.append(tile_liquid, vertices, 4, indices, 6);
}
break;}
case NDT_GLASSLIKE:
{
Expand Down
Loading