-- Water Plus -- By Rubenwardy -- License: cc-by-sa lib_materials.waterplus={} -- Settings lib_materials.waterplus.finite_water_steps=32 --how many finite water steps lib_materials.waterplus.finite_water_inc_skip=1 --how many waters to skip before inc lib_materials.waterplus.base_fluid = "lib_materials:liquid_water_rushing_source" lib_materials.waterplus.base_fluid_flowing = "lib_materials:liquid_water_rushing_flowing" -- Setup Finite lib_materials.waterplus.finite_water_inc=1/(lib_materials.waterplus.finite_water_steps /(1+lib_materials.waterplus.finite_water_inc_skip)) lib_materials.waterplus.finite_water_max=math.floor(1.43/lib_materials.waterplus.finite_water_inc) --how many finite water values (give a new style water effect) -- Debug function dPrint(msg) -- uncomment the following line to show debug text --print(msg) end -- Debug log print settings dPrint("Water steps: "..lib_materials.waterplus.finite_water_steps) dPrint("Water max: "..lib_materials.waterplus.finite_water_max) dPrint("Water inc: "..lib_materials.waterplus.finite_water_inc) dPrint("Water inc_skip: "..lib_materials.waterplus.finite_water_inc_skip) -- Locals local h=lib_materials.waterplus.finite_water_inc local c=1 dPrint("C: "..c) dPrint("H: "..h) -- Block create function lib_materials.waterplus.finite_blocks = {} lib_materials.waterplus.register_step = function(a,height) print("Register finite block "..a.." with a height of "..height) minetest.register_node("lib_materials:fluid_finite_"..a, { description = "Finite Water "..a, tiles = { {name="lib_materials_fluid_water_rushing_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}} }, drawtype = "nodebox", paramtype = "light", use_texture_alpha = true, walkable = false, pointable = false, diggable = false, climbable = true, buildable_to = true, liquid_viscosity = 1, --added water-like viscosity liquidtype = "source", liquid_alternative_flowing = "lib_materials:fluid_finite_"..a, liquid_alternative_source = "lib_materials:fluid_finite_"..a, liquid_renewable = false, liquid_range = 0, post_effect_color = {a=64, r=100, g=100, b=200}, groups = {water=3,finite_water=((a/lib_materials.waterplus.finite_water_steps)*100), puts_out_fire=1}, node_box = { type="fixed", fixed={ {-0.5,-0.5,-0.5,0.5,height-0.5,0.5}, }, }, -- on_construct = function(pos) -- minetest.get_node_timer(pos):start(math.random(6,12)) -- end, -- on_timer = function(pos) -- if not lib_ecology.can_grow(pos) then -- -- try again 5 min later -- minetest.get_node_timer(pos):start(300) -- return -- end -- if string.find(grow, ",") then -- local new_node_schems = grow:split(",", true) -- local rnum = math.random(1,#new_node_schems) -- local rname = new_node_schems[rnum] -- minetest.place_schematic(pos, lib_ecology.schematics.select(rname), "random", nil, true, "place_center_x, place_center_z") -- end -- end, }) table.insert(lib_materials.waterplus.finite_blocks,"lib_materials:fluid_finite_"..a) lib_materials.register_liquid( "lib_materials:fluid_finite_"..a, "", "lib_materials:tool_bucket_water_finite_"..a, "lib_materials:tool_bucket_wood_water_finite_"..a, "lib_materials:tool_bucket_steel_water_finite_"..a, "lib_materials:tool_pot_clay_water_finite_"..a, "lib_materials_fluid_water_river.png" ) end --Create blocks for a=1, lib_materials.waterplus.finite_water_max do c=c+1 if c>lib_materials.waterplus.finite_water_inc_skip then c = 0 h = h + lib_materials.waterplus.finite_water_inc end lib_materials.waterplus.register_step(a,h) lib_materials.waterplus.finite_water_max_id = a end lib_materials.waterplus.finite_water_max_name="lib_materials:fluid_finite_"..lib_materials.waterplus.finite_water_max_id --The ABM minetest.register_abm({ nodenames = lib_materials.waterplus.finite_blocks, interval = 1/10, chance = 1, action = function(pos,node) local node_id = getNumberFromName(node.name) dPrint("") dPrint("Waterplus [finite] - Calculating for "..node_id.." at "..pos.x..","..pos.y..","..pos.z) local upc = {x=pos.x, y=pos.y+1, z=pos.z} -- recieve pressure from up local pressure = 1 if minetest.env:get_node(upc).name == lib_materials.waterplus.finite_water_max_name or minetest.env:get_node(upc).name == lib_materials.waterplus.base_fluid then --pressure = minetest.env:get_meta(upc):get_int('pressure') or 1 --pressure = pressure_get(pos) pressure = 2 end dPrint("Waterplus [finite] - Calculating for "..node_id.." at "..pos.x..","..pos.y..","..pos.z..' press='..pressure) local target = {x=pos.x,y=pos.y-1,z=pos.z} dPrint(target.x..","..target.z) --if performDrop(pos,target) then return end if performDrop(pos,target) then if minetest.env:get_node(upc).name == lib_materials.waterplus.base_fluid then minetest.env:set_node(upc,{name = lib_materials.waterplus.finite_water_max_name}) end pos=target end local source_name = minetest.env:get_node(pos).name local source_id = getNumberFromName(source_name) or 0 local coords = { {x=pos.x-1,y=pos.y-1,z=pos.z, f=1, d=1,}, -- vertical drop {x=pos.x+1,y=pos.y-1,z=pos.z, f=1, d=1,}, -- f= can flow or drop {x=pos.x,y=pos.y-1,z=pos.z-1, f=1, d=1,}, -- d= can drop {x=pos.x,y=pos.y-1,z=pos.z+1, f=1, d=1,}, {x=pos.x-1,y=pos.y,z=pos.z,h=1, f=1, wi=1, iw=1,}, -- h=horisontal flow {x=pos.x+1,y=pos.y,z=pos.z,h=1, f=1, wi=1, iw=1,}, -- wi= standard water infect {x=pos.x,y=pos.y,z=pos.z-1,h=1, f=1, wi=1, iw=1,}, -- iw= water infects us {x=pos.x,y=pos.y,z=pos.z+1,h=1, f=1, wi=1, iw=1,}, {x=pos.x,y=pos.y+1,z=pos.z, wi=1, u=1, b=1,}, -- look up b= bubble up } local can = 0 local can_water = 1 local can_max = 0 local can_min = 0 local infected = 0 --local high_nearby = 0; -- step1: calculate possibility of flow with volumes for i = 1,9 do local name = minetest.env:get_node(coords[i]).name coords[i].n = name local target_id = getNumberFromName(name) dPrint("test nei "..name ..' = '.. (target_id or 'NO')) if infected < 1 and coords[i].wi and name==lib_materials.waterplus.base_fluid and source_id Flow Calculation") local target = minetest.env:get_node(to).name local target_id = getNumberFromName(target) local source = minetest.env:get_node(from).name local id = getNumberFromName(source) if id == nil then id = 0 end if target ~= "air" and tonumber(target_id) == nil then dPrint(" > Exit on is not finite liquid") return end if target_id == nil then target_id=0 end dPrint(" > Testing Heights: "..id.." vs "..target_id) if id == 1 and target_id == 0 and math.random(1,4) == 1 then if performDrop(from, {x=to.x,y=to.y-1,z=to.z}) then return end end if id > target_id and id > 0 then dPrint(" > Flowing") local nh_to = "lib_materials:fluid_finite_"..(target_id+1) local nh_from = "lib_materials:fluid_finite_"..(id-1) if (id-1) < 1 or (target_id+1) > lib_materials.waterplus.finite_water_max then dPrint(" > Exit on too high, or too low") return end minetest.env:set_node(from,{name = nh_from}) minetest.env:set_node(to,{name = nh_to}) dPrint(" > Done") end end ]] --from (pos): position of the node the abm is being run on --to (pos): position of the node to check function performDrop(from,to) dPrint("> Drop Calculation") local target = minetest.env:get_node(to).name local target_id = getNumberFromName(target) local source = minetest.env:get_node(from).name local id = getNumberFromName(source) if target ~= "air" and tonumber(target_id) == nil then dPrint(" > Exit on is not finite liquid") return end if target_id == nil then target_id=0 end if target_id >= lib_materials.waterplus.finite_water_max_id then return end if id == nil then id = 0 end --dPrint('droptest '..target_id ..'+'.. id ..' maxid='.. lib_materials.waterplus.finite_water_max_id ..' max='.. lib_materials.waterplus.finite_water_max) target_id = target_id + id id=0 if target_id > lib_materials.waterplus.finite_water_max_id then id = target_id - lib_materials.waterplus.finite_water_max_id target_id = lib_materials.waterplus.finite_water_max_id end local nh_to = "lib_materials:fluid_finite_"..(target_id) local nh_from = "lib_materials:fluid_finite_"..(id) if id == 0 or id == nil then nh_from = "air" end --print("drop ".. nh_from ..'->'..nh_to ) minetest.env:set_node(from,{name = nh_from}) minetest.env:set_node(to,{name = nh_to}) return 1 end -- bug with set-get value, not used function pressure_get(pos, recalc) local node = minetest.env:get_node(pos) if not (node.name == lib_materials.waterplus.finite_water_max_name or node.name == lib_materials.waterplus.base_fluid) then return 0 end local p = minetest.env:get_meta(pos):get_int('pressure') or 0 --print('press read=' .. p .. ' xyz='..pos.x..","..pos.y..","..pos.z) if p > 0 and not recalc then return p end p = 1 + pressure_get({x=pos.x,y=pos.y+1,z=pos.z}) minetest.env:get_meta(pos):set_int('pressure', p) --print('press save=' .. p ..' xyz='..pos.x..","..pos.y..","..pos.z) return p; end --minetest.register_alias("lib_materials:fluid_water_finite_source","lib_materials:fluid_finite_20") --minetest.register_alias("lib_materials:fluid_water_finite_flowing","lib_materials:fluid_finite_10") minetest.register_abm({ nodenames = {lib_materials.waterplus.base_fluid_flowing}, interval = 1, chance = 1, action = function(pos,node) local level = math.floor((node.param2/15)*lib_materials.waterplus.finite_water_max_id) if level < 1 then level = 1 end if level > lib_materials.waterplus.finite_water_max_id-3 then level = lib_materials.waterplus.finite_water_max_id-3 end dPrint("Waterplus [finite] - transforming float water to finite ".." at "..pos.x..","..pos.y..","..pos.z .. ' p1='.. node.param1 .. ' p2='.. node.param2 .. ' level='.. level) minetest.env:set_node(pos,{name = "lib_materials:fluid_finite_"..level, param1=node.param1, param2=node.param2}) end }) minetest.register_craftitem("lib_materials:tool_bucket_fluid_water_finite", { inventory_image = "bucket_water.png", stack_max = 1, liquids_pointable = true, on_use = function(itemstack, user, pointed_thing) -- Must be pointing to node if pointed_thing.type ~= "node" then return end -- Check if pointing to a buildable node n = minetest.env:get_node(pointed_thing.under) if minetest.registered_nodes[n.name].buildable_to then -- buildable; replace the node minetest.env:add_node(pointed_thing.under, {name="lib_materials:fluid_finite_20"}) else -- not buildable to; place the liquid above -- check if the node above can be replaced n = minetest.env:get_node(pointed_thing.above) if minetest.registered_nodes[n.name].buildable_to then minetest.env:add_node(pointed_thing.above, {name="lib_materials:fluid_finite_20"}) else -- do not remove the bucket with the liquid return end end return {name="lib_materials:tool_bucket_empty"} end })