forked from Mirrorlandia_minetest/minetest
Rework functionality of leveled nodes (#9852)
Co-authored-by: sfan5 <sfan5@live.de> Co-authored-by: SmallJoker <SmallJoker@users.noreply.github.com>
This commit is contained in:
parent
7d3972a504
commit
c94d37827d
@ -109,6 +109,7 @@ core.register_entity(":__builtin:falling_node", {
|
|||||||
if core.is_colored_paramtype(def.paramtype2) then
|
if core.is_colored_paramtype(def.paramtype2) then
|
||||||
itemstring = core.itemstring_with_palette(itemstring, node.param2)
|
itemstring = core.itemstring_with_palette(itemstring, node.param2)
|
||||||
end
|
end
|
||||||
|
-- FIXME: solution needed for paramtype2 == "leveled"
|
||||||
local vsize
|
local vsize
|
||||||
if def.visual_scale then
|
if def.visual_scale then
|
||||||
local s = def.visual_scale * SCALE
|
local s = def.visual_scale * SCALE
|
||||||
@ -122,6 +123,24 @@ core.register_entity(":__builtin:falling_node", {
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Set collision box (certain nodeboxes only for now)
|
||||||
|
local nb_types = {fixed=true, leveled=true, connected=true}
|
||||||
|
if def.drawtype == "nodebox" and def.node_box and
|
||||||
|
nb_types[def.node_box.type] then
|
||||||
|
local box = table.copy(def.node_box.fixed)
|
||||||
|
if type(box[1]) == "table" then
|
||||||
|
box = #box == 1 and box[1] or nil -- We can only use a single box
|
||||||
|
end
|
||||||
|
if box then
|
||||||
|
if def.paramtype2 == "leveled" and (self.node.level or 0) > 0 then
|
||||||
|
box[5] = -0.5 + self.node.level / 64
|
||||||
|
end
|
||||||
|
self.object:set_properties({
|
||||||
|
collisionbox = box
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Rotate entity
|
-- Rotate entity
|
||||||
if def.drawtype == "torchlike" then
|
if def.drawtype == "torchlike" then
|
||||||
self.object:set_yaw(math.pi*0.25)
|
self.object:set_yaw(math.pi*0.25)
|
||||||
@ -196,13 +215,16 @@ core.register_entity(":__builtin:falling_node", {
|
|||||||
try_place = function(self, bcp, bcn)
|
try_place = function(self, bcp, bcn)
|
||||||
local bcd = core.registered_nodes[bcn.name]
|
local bcd = core.registered_nodes[bcn.name]
|
||||||
-- Add levels if dropped on same leveled node
|
-- Add levels if dropped on same leveled node
|
||||||
if bcd and bcd.leveled and
|
if bcd and bcd.paramtype2 == "leveled" and
|
||||||
bcn.name == self.node.name then
|
bcn.name == self.node.name then
|
||||||
local addlevel = self.node.level
|
local addlevel = self.node.level
|
||||||
if not addlevel or addlevel <= 0 then
|
if (addlevel or 0) <= 0 then
|
||||||
addlevel = bcd.leveled
|
addlevel = bcd.leveled
|
||||||
end
|
end
|
||||||
if core.add_node_level(bcp, addlevel) == 0 then
|
if core.add_node_level(bcp, addlevel) < addlevel then
|
||||||
|
return true
|
||||||
|
elseif bcd.buildable_to then
|
||||||
|
-- Node level has already reached max, don't place anything
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -351,6 +373,7 @@ local function convert_to_falling_node(pos, node)
|
|||||||
if not obj then
|
if not obj then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
-- remember node level, the entities' set_node() uses this
|
||||||
node.level = core.get_node_level(pos)
|
node.level = core.get_node_level(pos)
|
||||||
local meta = core.get_meta(pos)
|
local meta = core.get_meta(pos)
|
||||||
local metatable = meta and meta:to_table() or {}
|
local metatable = meta and meta:to_table() or {}
|
||||||
@ -436,19 +459,24 @@ function core.check_single_for_falling(p)
|
|||||||
-- Only spawn falling node if node below is loaded
|
-- Only spawn falling node if node below is loaded
|
||||||
local n_bottom = core.get_node_or_nil(p_bottom)
|
local n_bottom = core.get_node_or_nil(p_bottom)
|
||||||
local d_bottom = n_bottom and core.registered_nodes[n_bottom.name]
|
local d_bottom = n_bottom and core.registered_nodes[n_bottom.name]
|
||||||
if d_bottom and
|
if d_bottom then
|
||||||
|
local same = n.name == n_bottom.name
|
||||||
(core.get_item_group(n.name, "float") == 0 or
|
-- Let leveled nodes fall if it can merge with the bottom node
|
||||||
d_bottom.liquidtype == "none") and
|
if same and d_bottom.paramtype2 == "leveled" and
|
||||||
|
|
||||||
(n.name ~= n_bottom.name or (d_bottom.leveled and
|
|
||||||
core.get_node_level(p_bottom) <
|
core.get_node_level(p_bottom) <
|
||||||
core.get_node_max_level(p_bottom))) and
|
core.get_node_max_level(p_bottom) then
|
||||||
|
|
||||||
(not d_bottom.walkable or d_bottom.buildable_to) then
|
|
||||||
convert_to_falling_node(p, n)
|
convert_to_falling_node(p, n)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
-- Otherwise only if the bottom node is considered "fall through"
|
||||||
|
if not same and
|
||||||
|
(not d_bottom.walkable or d_bottom.buildable_to) and
|
||||||
|
(core.get_item_group(n.name, "float") == 0 or
|
||||||
|
d_bottom.liquidtype == "none") then
|
||||||
|
convert_to_falling_node(p, n)
|
||||||
|
return true
|
||||||
|
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
|
||||||
|
@ -4882,7 +4882,7 @@ Environment access
|
|||||||
* `minetest.add_node_level(pos, level)`
|
* `minetest.add_node_level(pos, level)`
|
||||||
* increase level of leveled node by level, default `level` equals `1`
|
* increase level of leveled node by level, default `level` equals `1`
|
||||||
* if `totallevel > maxlevel`, returns rest (`total-max`)
|
* if `totallevel > maxlevel`, returns rest (`total-max`)
|
||||||
* can be negative for decreasing
|
* `level` must be between -127 and 127
|
||||||
* `minetest.fix_light(pos1, pos2)`: returns `true`/`false`
|
* `minetest.fix_light(pos1, pos2)`: returns `true`/`false`
|
||||||
* resets the light in a cuboid-shaped part of
|
* resets the light in a cuboid-shaped part of
|
||||||
the map and removes lighting bugs.
|
the map and removes lighting bugs.
|
||||||
@ -7012,11 +7012,15 @@ Used by `minetest.register_node`.
|
|||||||
-- If true, a new liquid source can be created by placing two or more
|
-- If true, a new liquid source can be created by placing two or more
|
||||||
-- sources nearby
|
-- sources nearby
|
||||||
|
|
||||||
leveled = 16,
|
leveled = 0,
|
||||||
-- Only valid for "nodebox" drawtype with 'type = "leveled"'.
|
-- Only valid for "nodebox" drawtype with 'type = "leveled"'.
|
||||||
-- Allows defining the nodebox height without using param2.
|
-- Allows defining the nodebox height without using param2.
|
||||||
-- The nodebox height is 'leveled' / 64 nodes.
|
-- The nodebox height is 'leveled' / 64 nodes.
|
||||||
-- The maximum value of 'leveled' is 127.
|
-- The maximum value of 'leveled' is `leveled_max`.
|
||||||
|
|
||||||
|
leveled_max = 127,
|
||||||
|
-- Maximum value for `leveled` (0-127), enforced in
|
||||||
|
-- `minetest.set_node_level` and `minetest.add_node_level`.
|
||||||
|
|
||||||
liquid_range = 8, -- Number of flowing nodes around source (max. 8)
|
liquid_range = 8, -- Number of flowing nodes around source (max. 8)
|
||||||
|
|
||||||
|
@ -584,7 +584,7 @@ u8 MapNode::getMaxLevel(const NodeDefManager *nodemgr) const
|
|||||||
if( f.liquid_type == LIQUID_FLOWING || f.param_type_2 == CPT2_FLOWINGLIQUID)
|
if( f.liquid_type == LIQUID_FLOWING || f.param_type_2 == CPT2_FLOWINGLIQUID)
|
||||||
return LIQUID_LEVEL_MAX;
|
return LIQUID_LEVEL_MAX;
|
||||||
if(f.leveled || f.param_type_2 == CPT2_LEVELED)
|
if(f.leveled || f.param_type_2 == CPT2_LEVELED)
|
||||||
return LEVELED_MAX;
|
return f.leveled_max;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,14 +603,15 @@ u8 MapNode::getLevel(const NodeDefManager *nodemgr) const
|
|||||||
if (level)
|
if (level)
|
||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
if (f.leveled > LEVELED_MAX)
|
// Return static value from nodedef if param2 isn't used for level
|
||||||
return LEVELED_MAX;
|
if (f.leveled > f.leveled_max)
|
||||||
|
return f.leveled_max;
|
||||||
return f.leveled;
|
return f.leveled;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 MapNode::setLevel(const NodeDefManager *nodemgr, s8 level)
|
s8 MapNode::setLevel(const NodeDefManager *nodemgr, s16 level)
|
||||||
{
|
{
|
||||||
u8 rest = 0;
|
s8 rest = 0;
|
||||||
const ContentFeatures &f = nodemgr->get(*this);
|
const ContentFeatures &f = nodemgr->get(*this);
|
||||||
if (f.param_type_2 == CPT2_FLOWINGLIQUID
|
if (f.param_type_2 == CPT2_FLOWINGLIQUID
|
||||||
|| f.liquid_type == LIQUID_FLOWING
|
|| f.liquid_type == LIQUID_FLOWING
|
||||||
@ -631,18 +632,18 @@ u8 MapNode::setLevel(const NodeDefManager *nodemgr, s8 level)
|
|||||||
if (level < 0) { // zero means default for a leveled nodebox
|
if (level < 0) { // zero means default for a leveled nodebox
|
||||||
rest = level;
|
rest = level;
|
||||||
level = 0;
|
level = 0;
|
||||||
} else if (level > LEVELED_MAX) {
|
} else if (level > f.leveled_max) {
|
||||||
rest = level - LEVELED_MAX;
|
rest = level - f.leveled_max;
|
||||||
level = LEVELED_MAX;
|
level = f.leveled_max;
|
||||||
}
|
}
|
||||||
setParam2((level & LEVELED_MASK) | (getParam2() & ~LEVELED_MASK));
|
setParam2((level & LEVELED_MASK) | (getParam2() & ~LEVELED_MASK));
|
||||||
}
|
}
|
||||||
return rest;
|
return rest;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 MapNode::addLevel(const NodeDefManager *nodemgr, s8 add)
|
s8 MapNode::addLevel(const NodeDefManager *nodemgr, s16 add)
|
||||||
{
|
{
|
||||||
s8 level = getLevel(nodemgr);
|
s16 level = getLevel(nodemgr);
|
||||||
level += add;
|
level += add;
|
||||||
return setLevel(nodemgr, level);
|
return setLevel(nodemgr, level);
|
||||||
}
|
}
|
||||||
|
@ -268,12 +268,12 @@ struct MapNode
|
|||||||
std::vector<aabb3f> *boxes, u8 neighbors = 0) const;
|
std::vector<aabb3f> *boxes, u8 neighbors = 0) const;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Liquid helpers
|
Liquid/leveled helpers
|
||||||
*/
|
*/
|
||||||
u8 getMaxLevel(const NodeDefManager *nodemgr) const;
|
u8 getMaxLevel(const NodeDefManager *nodemgr) const;
|
||||||
u8 getLevel(const NodeDefManager *nodemgr) const;
|
u8 getLevel(const NodeDefManager *nodemgr) const;
|
||||||
u8 setLevel(const NodeDefManager *nodemgr, s8 level = 1);
|
s8 setLevel(const NodeDefManager *nodemgr, s16 level = 1);
|
||||||
u8 addLevel(const NodeDefManager *nodemgr, s8 add = 1);
|
s8 addLevel(const NodeDefManager *nodemgr, s16 add = 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Serialization functions
|
Serialization functions
|
||||||
|
@ -368,6 +368,7 @@ void ContentFeatures::reset()
|
|||||||
floodable = false;
|
floodable = false;
|
||||||
rightclickable = true;
|
rightclickable = true;
|
||||||
leveled = 0;
|
leveled = 0;
|
||||||
|
leveled_max = LEVELED_MAX;
|
||||||
liquid_type = LIQUID_NONE;
|
liquid_type = LIQUID_NONE;
|
||||||
liquid_alternative_flowing = "";
|
liquid_alternative_flowing = "";
|
||||||
liquid_alternative_source = "";
|
liquid_alternative_source = "";
|
||||||
@ -478,6 +479,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
|
|||||||
writeU8(os, legacy_wallmounted);
|
writeU8(os, legacy_wallmounted);
|
||||||
|
|
||||||
os << serializeString(node_dig_prediction);
|
os << serializeString(node_dig_prediction);
|
||||||
|
writeU8(os, leveled_max);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentFeatures::correctAlpha(TileDef *tiles, int length)
|
void ContentFeatures::correctAlpha(TileDef *tiles, int length)
|
||||||
@ -586,6 +588,10 @@ void ContentFeatures::deSerialize(std::istream &is)
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
node_dig_prediction = deSerializeString(is);
|
node_dig_prediction = deSerializeString(is);
|
||||||
|
u8 tmp_leveled_max = readU8(is);
|
||||||
|
if (is.eof()) /* readU8 doesn't throw exceptions so we have to do this */
|
||||||
|
throw SerializationError("");
|
||||||
|
leveled_max = tmp_leveled_max;
|
||||||
} catch(SerializationError &e) {};
|
} catch(SerializationError &e) {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,8 +326,10 @@ struct ContentFeatures
|
|||||||
std::vector<content_t> connects_to_ids;
|
std::vector<content_t> connects_to_ids;
|
||||||
// Post effect color, drawn when the camera is inside the node.
|
// Post effect color, drawn when the camera is inside the node.
|
||||||
video::SColor post_effect_color;
|
video::SColor post_effect_color;
|
||||||
// Flowing liquid or snow, value = default level
|
// Flowing liquid or leveled nodebox, value = default level
|
||||||
u8 leveled;
|
u8 leveled;
|
||||||
|
// Maximum value for leveled nodes
|
||||||
|
u8 leveled_max;
|
||||||
|
|
||||||
// --- LIGHTING-RELATED ---
|
// --- LIGHTING-RELATED ---
|
||||||
|
|
||||||
|
@ -694,6 +694,8 @@ ContentFeatures read_content_features(lua_State *L, int index)
|
|||||||
f.liquid_range = getintfield_default(L, index,
|
f.liquid_range = getintfield_default(L, index,
|
||||||
"liquid_range", f.liquid_range);
|
"liquid_range", f.liquid_range);
|
||||||
f.leveled = getintfield_default(L, index, "leveled", f.leveled);
|
f.leveled = getintfield_default(L, index, "leveled", f.leveled);
|
||||||
|
f.leveled_max = getintfield_default(L, index,
|
||||||
|
"leveled_max", f.leveled_max);
|
||||||
|
|
||||||
getboolfield(L, index, "liquid_renewable", f.liquid_renewable);
|
getboolfield(L, index, "liquid_renewable", f.liquid_renewable);
|
||||||
f.drowning = getintfield_default(L, index,
|
f.drowning = getintfield_default(L, index,
|
||||||
@ -860,6 +862,8 @@ void push_content_features(lua_State *L, const ContentFeatures &c)
|
|||||||
lua_setfield(L, -2, "post_effect_color");
|
lua_setfield(L, -2, "post_effect_color");
|
||||||
lua_pushnumber(L, c.leveled);
|
lua_pushnumber(L, c.leveled);
|
||||||
lua_setfield(L, -2, "leveled");
|
lua_setfield(L, -2, "leveled");
|
||||||
|
lua_pushnumber(L, c.leveled_max);
|
||||||
|
lua_setfield(L, -2, "leveled_max");
|
||||||
lua_pushboolean(L, c.sunlight_propagates);
|
lua_pushboolean(L, c.sunlight_propagates);
|
||||||
lua_setfield(L, -2, "sunlight_propagates");
|
lua_setfield(L, -2, "sunlight_propagates");
|
||||||
lua_pushnumber(L, c.light_source);
|
lua_pushnumber(L, c.light_source);
|
||||||
|
@ -529,13 +529,13 @@ int ModApiEnvMod::l_set_node_level(lua_State *L)
|
|||||||
|
|
||||||
// add_node_level(pos, level)
|
// add_node_level(pos, level)
|
||||||
// pos = {x=num, y=num, z=num}
|
// pos = {x=num, y=num, z=num}
|
||||||
// level: 0..63
|
// level: -127..127
|
||||||
int ModApiEnvMod::l_add_node_level(lua_State *L)
|
int ModApiEnvMod::l_add_node_level(lua_State *L)
|
||||||
{
|
{
|
||||||
GET_ENV_PTR;
|
GET_ENV_PTR;
|
||||||
|
|
||||||
v3s16 pos = read_v3s16(L, 1);
|
v3s16 pos = read_v3s16(L, 1);
|
||||||
u8 level = 1;
|
s16 level = 1;
|
||||||
if(lua_isnumber(L, 2))
|
if(lua_isnumber(L, 2))
|
||||||
level = lua_tonumber(L, 2);
|
level = lua_tonumber(L, 2);
|
||||||
MapNode n = env->getMap().getNode(pos);
|
MapNode n = env->getMap().getNode(pos);
|
||||||
|
Loading…
Reference in New Issue
Block a user