+ // todo: after update in all games leave only if (f.param_type_2 ==
+ if( f.liquid_type == LIQUID_FLOWING || f.param_type_2 == CPT2_FLOWINGLIQUID)
+ return LIQUID_LEVEL_MAX;
+ if(f.leveled || f.param_type_2 == CPT2_LEVELED)
+ return LEVELED_MAX;
+ return 0;
+}
+
+u8 MapNode::getLevel(INodeDefManager *nodemgr) const
+{
+ const ContentFeatures &f = nodemgr->get(*this);
+ // todo: after update in all games leave only if (f.param_type_2 ==
+ if(f.liquid_type == LIQUID_SOURCE)
+ return LIQUID_LEVEL_SOURCE;
+ if (f.param_type_2 == CPT2_FLOWINGLIQUID)
+ return getParam2() & LIQUID_LEVEL_MASK;
+ if(f.liquid_type == LIQUID_FLOWING) // can remove if all param_type_2 setted
+ return getParam2() & LIQUID_LEVEL_MASK;
+ if(f.leveled || f.param_type_2 == CPT2_LEVELED) {
+ u8 level = getParam2() & LEVELED_MASK;
+ if(level)
+ return level;
+ if(f.leveled > LEVELED_MAX)
+ return LEVELED_MAX;
+ return f.leveled; //default
+ }
+ return 0;
+}
+
+u8 MapNode::setLevel(INodeDefManager *nodemgr, s8 level)
+{
+ u8 rest = 0;
+ if (level < 1) {
+ setContent(CONTENT_AIR);
+ return 0;
+ }
+ const ContentFeatures &f = nodemgr->get(*this);
+ if (f.param_type_2 == CPT2_FLOWINGLIQUID
+ || f.liquid_type == LIQUID_FLOWING
+ || f.liquid_type == LIQUID_SOURCE) {
+ if (level >= LIQUID_LEVEL_SOURCE) {
+ rest = level - LIQUID_LEVEL_SOURCE;
+ setContent(nodemgr->getId(f.liquid_alternative_source));
+ } else {
+ setContent(nodemgr->getId(f.liquid_alternative_flowing));
+ setParam2(level & LIQUID_LEVEL_MASK);
+ }
+ } else if (f.leveled || f.param_type_2 == CPT2_LEVELED) {
+ if (level > LEVELED_MAX) {
+ rest = level - LEVELED_MAX;
+ level = LEVELED_MAX;
+ }
+ setParam2(level & LEVELED_MASK);
+ }
+ return rest;
+}
+
+u8 MapNode::addLevel(INodeDefManager *nodemgr, s8 add)
+{
+ s8 level = getLevel(nodemgr);
+ if (add == 0) level = 1;
+ level += add;
+ return setLevel(nodemgr, level);