Skip to content

Commit c94d378

Browse files
Wuzzy2sfan5SmallJoker
authoredMay 19, 2020
Rework functionality of leveled nodes (#9852)
Co-authored-by: sfan5 <sfan5@live.de> Co-authored-by: SmallJoker <SmallJoker@users.noreply.github.com>
1 parent 7d3972a commit c94d378

File tree

8 files changed

+79
-34
lines changed

8 files changed

+79
-34
lines changed
 

Diff for: ‎builtin/game/falling.lua

+43-15
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ core.register_entity(":__builtin:falling_node", {
109109
if core.is_colored_paramtype(def.paramtype2) then
110110
itemstring = core.itemstring_with_palette(itemstring, node.param2)
111111
end
112+
-- FIXME: solution needed for paramtype2 == "leveled"
112113
local vsize
113114
if def.visual_scale then
114115
local s = def.visual_scale * SCALE
@@ -122,6 +123,24 @@ core.register_entity(":__builtin:falling_node", {
122123
})
123124
end
124125

126+
-- Set collision box (certain nodeboxes only for now)
127+
local nb_types = {fixed=true, leveled=true, connected=true}
128+
if def.drawtype == "nodebox" and def.node_box and
129+
nb_types[def.node_box.type] then
130+
local box = table.copy(def.node_box.fixed)
131+
if type(box[1]) == "table" then
132+
box = #box == 1 and box[1] or nil -- We can only use a single box
133+
end
134+
if box then
135+
if def.paramtype2 == "leveled" and (self.node.level or 0) > 0 then
136+
box[5] = -0.5 + self.node.level / 64
137+
end
138+
self.object:set_properties({
139+
collisionbox = box
140+
})
141+
end
142+
end
143+
125144
-- Rotate entity
126145
if def.drawtype == "torchlike" then
127146
self.object:set_yaw(math.pi*0.25)
@@ -196,13 +215,16 @@ core.register_entity(":__builtin:falling_node", {
196215
try_place = function(self, bcp, bcn)
197216
local bcd = core.registered_nodes[bcn.name]
198217
-- Add levels if dropped on same leveled node
199-
if bcd and bcd.leveled and
218+
if bcd and bcd.paramtype2 == "leveled" and
200219
bcn.name == self.node.name then
201220
local addlevel = self.node.level
202-
if not addlevel or addlevel <= 0 then
221+
if (addlevel or 0) <= 0 then
203222
addlevel = bcd.leveled
204223
end
205-
if core.add_node_level(bcp, addlevel) == 0 then
224+
if core.add_node_level(bcp, addlevel) < addlevel then
225+
return true
226+
elseif bcd.buildable_to then
227+
-- Node level has already reached max, don't place anything
206228
return true
207229
end
208230
end
@@ -351,6 +373,7 @@ local function convert_to_falling_node(pos, node)
351373
if not obj then
352374
return false
353375
end
376+
-- remember node level, the entities' set_node() uses this
354377
node.level = core.get_node_level(pos)
355378
local meta = core.get_meta(pos)
356379
local metatable = meta and meta:to_table() or {}
@@ -436,18 +459,23 @@ function core.check_single_for_falling(p)
436459
-- Only spawn falling node if node below is loaded
437460
local n_bottom = core.get_node_or_nil(p_bottom)
438461
local d_bottom = n_bottom and core.registered_nodes[n_bottom.name]
439-
if d_bottom and
440-
441-
(core.get_item_group(n.name, "float") == 0 or
442-
d_bottom.liquidtype == "none") and
443-
444-
(n.name ~= n_bottom.name or (d_bottom.leveled and
445-
core.get_node_level(p_bottom) <
446-
core.get_node_max_level(p_bottom))) and
447-
448-
(not d_bottom.walkable or d_bottom.buildable_to) then
449-
convert_to_falling_node(p, n)
450-
return true
462+
if d_bottom then
463+
local same = n.name == n_bottom.name
464+
-- Let leveled nodes fall if it can merge with the bottom node
465+
if same and d_bottom.paramtype2 == "leveled" and
466+
core.get_node_level(p_bottom) <
467+
core.get_node_max_level(p_bottom) then
468+
convert_to_falling_node(p, n)
469+
return true
470+
end
471+
-- Otherwise only if the bottom node is considered "fall through"
472+
if not same and
473+
(not d_bottom.walkable or d_bottom.buildable_to) and
474+
(core.get_item_group(n.name, "float") == 0 or
475+
d_bottom.liquidtype == "none") then
476+
convert_to_falling_node(p, n)
477+
return true
478+
end
451479
end
452480
end
453481

Diff for: ‎doc/lua_api.txt

+7-3
Original file line numberDiff line numberDiff line change
@@ -4882,7 +4882,7 @@ Environment access
48824882
* `minetest.add_node_level(pos, level)`
48834883
* increase level of leveled node by level, default `level` equals `1`
48844884
* if `totallevel > maxlevel`, returns rest (`total-max`)
4885-
* can be negative for decreasing
4885+
* `level` must be between -127 and 127
48864886
* `minetest.fix_light(pos1, pos2)`: returns `true`/`false`
48874887
* resets the light in a cuboid-shaped part of
48884888
the map and removes lighting bugs.
@@ -7012,11 +7012,15 @@ Used by `minetest.register_node`.
70127012
-- If true, a new liquid source can be created by placing two or more
70137013
-- sources nearby
70147014

7015-
leveled = 16,
7015+
leveled = 0,
70167016
-- Only valid for "nodebox" drawtype with 'type = "leveled"'.
70177017
-- Allows defining the nodebox height without using param2.
70187018
-- The nodebox height is 'leveled' / 64 nodes.
7019-
-- The maximum value of 'leveled' is 127.
7019+
-- The maximum value of 'leveled' is `leveled_max`.
7020+
7021+
leveled_max = 127,
7022+
-- Maximum value for `leveled` (0-127), enforced in
7023+
-- `minetest.set_node_level` and `minetest.add_node_level`.
70207024

70217025
liquid_range = 8, -- Number of flowing nodes around source (max. 8)
70227026

Diff for: ‎src/mapnode.cpp

+11-10
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ u8 MapNode::getMaxLevel(const NodeDefManager *nodemgr) const
584584
if( f.liquid_type == LIQUID_FLOWING || f.param_type_2 == CPT2_FLOWINGLIQUID)
585585
return LIQUID_LEVEL_MAX;
586586
if(f.leveled || f.param_type_2 == CPT2_LEVELED)
587-
return LEVELED_MAX;
587+
return f.leveled_max;
588588
return 0;
589589
}
590590

@@ -603,14 +603,15 @@ u8 MapNode::getLevel(const NodeDefManager *nodemgr) const
603603
if (level)
604604
return level;
605605
}
606-
if (f.leveled > LEVELED_MAX)
607-
return LEVELED_MAX;
606+
// Return static value from nodedef if param2 isn't used for level
607+
if (f.leveled > f.leveled_max)
608+
return f.leveled_max;
608609
return f.leveled;
609610
}
610611

611-
u8 MapNode::setLevel(const NodeDefManager *nodemgr, s8 level)
612+
s8 MapNode::setLevel(const NodeDefManager *nodemgr, s16 level)
612613
{
613-
u8 rest = 0;
614+
s8 rest = 0;
614615
const ContentFeatures &f = nodemgr->get(*this);
615616
if (f.param_type_2 == CPT2_FLOWINGLIQUID
616617
|| f.liquid_type == LIQUID_FLOWING
@@ -631,18 +632,18 @@ u8 MapNode::setLevel(const NodeDefManager *nodemgr, s8 level)
631632
if (level < 0) { // zero means default for a leveled nodebox
632633
rest = level;
633634
level = 0;
634-
} else if (level > LEVELED_MAX) {
635-
rest = level - LEVELED_MAX;
636-
level = LEVELED_MAX;
635+
} else if (level > f.leveled_max) {
636+
rest = level - f.leveled_max;
637+
level = f.leveled_max;
637638
}
638639
setParam2((level & LEVELED_MASK) | (getParam2() & ~LEVELED_MASK));
639640
}
640641
return rest;
641642
}
642643

643-
u8 MapNode::addLevel(const NodeDefManager *nodemgr, s8 add)
644+
s8 MapNode::addLevel(const NodeDefManager *nodemgr, s16 add)
644645
{
645-
s8 level = getLevel(nodemgr);
646+
s16 level = getLevel(nodemgr);
646647
level += add;
647648
return setLevel(nodemgr, level);
648649
}

Diff for: ‎src/mapnode.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -268,12 +268,12 @@ struct MapNode
268268
std::vector<aabb3f> *boxes, u8 neighbors = 0) const;
269269

270270
/*
271-
Liquid helpers
271+
Liquid/leveled helpers
272272
*/
273273
u8 getMaxLevel(const NodeDefManager *nodemgr) const;
274274
u8 getLevel(const NodeDefManager *nodemgr) const;
275-
u8 setLevel(const NodeDefManager *nodemgr, s8 level = 1);
276-
u8 addLevel(const NodeDefManager *nodemgr, s8 add = 1);
275+
s8 setLevel(const NodeDefManager *nodemgr, s16 level = 1);
276+
s8 addLevel(const NodeDefManager *nodemgr, s16 add = 1);
277277

278278
/*
279279
Serialization functions

Diff for: ‎src/nodedef.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ void ContentFeatures::reset()
368368
floodable = false;
369369
rightclickable = true;
370370
leveled = 0;
371+
leveled_max = LEVELED_MAX;
371372
liquid_type = LIQUID_NONE;
372373
liquid_alternative_flowing = "";
373374
liquid_alternative_source = "";
@@ -478,6 +479,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
478479
writeU8(os, legacy_wallmounted);
479480

480481
os << serializeString(node_dig_prediction);
482+
writeU8(os, leveled_max);
481483
}
482484

483485
void ContentFeatures::correctAlpha(TileDef *tiles, int length)
@@ -586,6 +588,10 @@ void ContentFeatures::deSerialize(std::istream &is)
586588

587589
try {
588590
node_dig_prediction = deSerializeString(is);
591+
u8 tmp_leveled_max = readU8(is);
592+
if (is.eof()) /* readU8 doesn't throw exceptions so we have to do this */
593+
throw SerializationError("");
594+
leveled_max = tmp_leveled_max;
589595
} catch(SerializationError &e) {};
590596
}
591597

Diff for: ‎src/nodedef.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -326,8 +326,10 @@ struct ContentFeatures
326326
std::vector<content_t> connects_to_ids;
327327
// Post effect color, drawn when the camera is inside the node.
328328
video::SColor post_effect_color;
329-
// Flowing liquid or snow, value = default level
329+
// Flowing liquid or leveled nodebox, value = default level
330330
u8 leveled;
331+
// Maximum value for leveled nodes
332+
u8 leveled_max;
331333

332334
// --- LIGHTING-RELATED ---
333335

Diff for: ‎src/script/common/c_content.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,8 @@ ContentFeatures read_content_features(lua_State *L, int index)
694694
f.liquid_range = getintfield_default(L, index,
695695
"liquid_range", f.liquid_range);
696696
f.leveled = getintfield_default(L, index, "leveled", f.leveled);
697+
f.leveled_max = getintfield_default(L, index,
698+
"leveled_max", f.leveled_max);
697699

698700
getboolfield(L, index, "liquid_renewable", f.liquid_renewable);
699701
f.drowning = getintfield_default(L, index,
@@ -860,6 +862,8 @@ void push_content_features(lua_State *L, const ContentFeatures &c)
860862
lua_setfield(L, -2, "post_effect_color");
861863
lua_pushnumber(L, c.leveled);
862864
lua_setfield(L, -2, "leveled");
865+
lua_pushnumber(L, c.leveled_max);
866+
lua_setfield(L, -2, "leveled_max");
863867
lua_pushboolean(L, c.sunlight_propagates);
864868
lua_setfield(L, -2, "sunlight_propagates");
865869
lua_pushnumber(L, c.light_source);

Diff for: ‎src/script/lua_api/l_env.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -529,13 +529,13 @@ int ModApiEnvMod::l_set_node_level(lua_State *L)
529529

530530
// add_node_level(pos, level)
531531
// pos = {x=num, y=num, z=num}
532-
// level: 0..63
532+
// level: -127..127
533533
int ModApiEnvMod::l_add_node_level(lua_State *L)
534534
{
535535
GET_ENV_PTR;
536536

537537
v3s16 pos = read_v3s16(L, 1);
538-
u8 level = 1;
538+
s16 level = 1;
539539
if(lua_isnumber(L, 2))
540540
level = lua_tonumber(L, 2);
541541
MapNode n = env->getMap().getNode(pos);

0 commit comments

Comments
 (0)
Please sign in to comment.