123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542 |
- springs = {}
- local modpath = minetest.get_modpath("springs")
- dofile(modpath.."/pipes.lua")
- dofile(modpath.."/sluice.lua")
- dofile(modpath.."/pump.lua")
- dofile(modpath.."/wells.lua")
- --[[
- TODO:
- water filters
- pipe inlet/outlet pressure checks
- broken outlet sharing
- non-connected pipes and splitters
- fix wells
- better springs texture
- optimize static water
- pumps
- fix spout and intake nodeboxes
- crafts
- galvanized-ish pipes (coat in tin)
- ]]
- minetest.register_node("springs:spring", {
- description = "Spring",
- tiles = {"default_cobble.png^default_river_water.png"},
- --paramtype = "light",
- --leveled = 64,
- --alpha = 160,
- drop = "default:cobble",
- --drowning = 1,
- walkable = true, -- because viscosity doesn't work for regular nodes, and the liquid hack can't be leveled
-
- -- post_effect_color = {a = 103, r = 30, g = 76, b = 120},
- groups = { puts_out_fire = 1, cracky = 1, is_ground_content = 1, cools_lava = 1},
- sounds = default.node_sound_water_defaults(),
- })
- minetest.register_node("springs:water", {
- description = "node ",
- drawtype = "nodebox",
- paramtype = "light",
- paramtype2 = "leveled",
- tiles = {
- {
- name = "default_river_water_source_animated.png",
- animation = {
- type = "vertical_frames",
- aspect_w = 16,
- aspect_h = 16,
- length = 2.0,
- },
- },
- },
- special_tiles = {
- {
- name = "default_river_water_source_animated.png",
- animation = {
- type = "vertical_frames",
- aspect_w = 16,
- aspect_h = 16,
- length = 2.0,
- },
- backface_culling = false,
- },
- },
- leveled = 64,
- alpha = 160,
- drop = "",
- drowning = 1,
- walkable = false, -- because viscosity doesn't work for regular nodes, and the liquid hack can't be leveled
- climbable = true, -- because viscosity doesn't work for regular nodes, and the liquid hack can't be leveled
- pointable = false,
- diggable = false,
- buildable_to = true,
-
- -- liquid_viscosity = 14,
- -- liquidtype = "source",
- -- liquid_alternative_flowing = "springs:water",
- -- liquid_alternative_source = "springs:water",
- -- liquid_renewable = false,
- -- liquid_range = 0,
- -- groups = {crumbly=3,soil=1,falling_node=1},
- post_effect_color = {a = 103, r = 30, g = 76, b = 90},
- groups = { puts_out_fire = 1, liquid = 3, cools_lava = 1, fresh_water=1},
- sounds = default.node_sound_water_defaults(),
- node_box = {
- type = "leveled",
- fixed = {
- {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, -- NodeBox1
- }
- }
- })
- -- this is a special node used to optimize large pools of water
- -- its flowing abm runs much less frequently
- minetest.register_node("springs:water_full", {
- description = "node ",
- drawtype = "nodebox",
- paramtype = "light",
- tiles = {
- {
- name = "default_river_water_source_animated.png",
- animation = {
- type = "vertical_frames",
- aspect_w = 16,
- aspect_h = 16,
- length = 2.0,
- },
- },
- },
- special_tiles = {
- {
- name = "default_river_water_source_animated.png",
- animation = {
- type = "vertical_frames",
- aspect_w = 16,
- aspect_h = 16,
- length = 2.0,
- },
- backface_culling = false,
- },
- },
- leveled = 64,
- alpha = 160,
- drop = "",
- drowning = 1,
- walkable = false, -- because viscosity doesn't work for regular nodes, and the liquid hack can't be leveled
- climbable = true, -- because viscosity doesn't work for regular nodes, and the liquid hack can't be leveled
- pointable = false,
- diggable = false,
- buildable_to = true,
-
- -- liquid_viscosity = 14,
- -- liquidtype = "source",
- -- liquid_alternative_flowing = "springs:water",
- -- liquid_alternative_source = "springs:water",
- -- liquid_renewable = false,
- -- liquid_range = 0,
- -- groups = {crumbly=3,soil=1,falling_node=1},
- post_effect_color = {a = 103, r = 30, g = 76, b = 90},
- groups = { puts_out_fire = 1, liquid = 3, cools_lava = 1, fresh_water=1},
- sounds = default.node_sound_water_defaults(),
- node_box = {
- type = "leveled",
- fixed = {
- {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, -- NodeBox1
- }
- }
- })
- -- spring
- minetest.register_abm({
- nodenames = {"springs:spring"},
- neighbors = {"group:fresh_water", "air"},
- interval = 5,
- chance = 60,
- action = function(pos)
- -- local mylevel = minetest.get_node_level(pos)
-
- -- print("spring at: "..pos.x..","..pos.y..","..pos.z)
- local air_nodes = minetest.find_nodes_in_area(
- {x=pos.x - 1, y=pos.y - 1, z=pos.z - 1},
- {x=pos.x + 1, y=pos.y, z=pos.z + 1},
- {"group:fresh_water", "air"}
- )
-
- if nil == air_nodes or #air_nodes == 0 then
- return
- end
- local tpos = air_nodes[math.random(#air_nodes)]
-
- -- calculate flow rate based on absolute location
- local prate = (minetest.hash_node_position(pos) % 48)
- local amount = math.random(1, 16) + prate
-
- local t = minetest.get_node(tpos)
- if t.name == "air" then
- minetest.set_node(tpos, {name = "springs:water"})
- minetest.set_node_level(tpos, amount)
- else -- it's group:fresh_water
- local tlevel = minetest.get_node_level(tpos)
- minetest.set_node_level(tpos, math.min(64, tlevel + amount))
- end
-
- end
- })
- -- evaporation
- minetest.register_abm({
- nodenames = {"group:fresh_water"},
- neighbors = {"air"},
- interval = 5,
- chance = 10,
- action = function(pos)
- local mylevel = minetest.get_node_level(pos)
- if math.random(16 - minetest.get_node_light(pos)) == 1 then
- if mylevel > 1 then
- minetest.set_node_level(pos, mylevel - 1)
- else
- minetest.set_node(pos, {name = "air"})
- end
- end
- end
- })
- local soak = {
- ["default:cobble"] = 10,
- ["default:desert_cobble"] = 10,
- ["default:mossycobble"] = 9,
- ["default:dirt"] = 2,
- ["default:dirt_with_grass"] = 2,
- ["default:dirt_with_grass_footsteps"] = 2,
- ["default:dirt_with_dry_grass"] = 2,
- ["default:dirt_with_coniferous_litter"] = 2,
- ["default:dirt_with_rainforest_litter"] = 1,
- ["default:gravel"] = 8,
- ["default:coral_orange"] = 6,
- ["default:coral_brown"] = 6,
- ["default:coral_skeleton"] = 6,
- ["default:sand"] = 6,
- ["default:sand_with_kelp"] = 6,
- ["default:desert_sand"] = 7,
- ["default:silver_sand"] = 7,
- ["default:snow"] = 4,
- ["default:snowblock"] = 4,
- ["default:leaves"] = 60,
- ["default:bush_leaves"] = 60,
- ["default:jungleleaves"] = 60,
- ["default:pine_needles"] = 60,
- ["default:acacia_leaves"] = 60,
- ["default:acacia_bush_leaves"] = 60,
- ["default:aspen_leaves"] = 60,
-
- -- dilution
- ["default:water_source"] = 65,
- ["default:water_flowing"] = 65,
- ["default:river_water_source"] = 65,
- ["default:river_water_flowing"] = 65,
-
- -- boiling -- TODO: steam effect
- ["default:lava_source"] = 65,
- ["default:lava_flowing"] = 65,
-
- -- no ladder hacks
- ["default:ladder_wood"] = 65,
- -- ["default:ladder_steel"] = 65, -- need to figure out a way for water to flow through ladders
- ["default:sign_wall_wood"] = 65,
- ["default:sign_wall_steel"] = 65,
- ["default:fence_wood"] = 65,
- ["default:fence_acacia_wood"] = 65,
- ["default:fence_junglewood"] = 65,
- ["default:fence_pine_wood"] = 65,
- ["default:fence_aspen_wood"] = 65,
-
- ["default:torch"] = 65,
- ["carts:rail"] = 65,
- ["carts:brakerail"] = 65,
- ["carts:powerrail"] = 65,
- }
- local soak_names = {}
- for n,_ in pairs(soak) do
- table.insert(soak_names, n)
- end
- -- soaking sideways
- minetest.register_abm({
- nodenames = {"group:fresh_water"},
- neighbors = soak_names,
- interval = 4,
- chance = 10,
- action = function(pos)
- -- print("\nsoak ")
- local soak_nodes = minetest.find_nodes_in_area(
- {x=pos.x - 1, y=pos.y, z=pos.z - 1},
- {x=pos.x + 1, y=pos.y, z=pos.z + 1},
- soak_names
- )
-
- local mylevel = minetest.get_node_level(pos)
- local total_loss = 0
- for _,spos in ipairs(soak_nodes) do
- local sn = minetest.get_node(spos)
- total_loss = total_loss + soak[sn.name]
-
- if 1 == math.random(120 / mylevel) then
- minetest.set_node(spos, {name = "air"})
- end
-
- end
-
- if total_loss == 0 then
- return
- end
-
- --print("loss: ".. total_loss)
-
- local remain = mylevel - (total_loss * (mylevel / 64))
- if remain > 0 then
- minetest.set_node_level(pos, remain)
- else
- minetest.set_node(pos, {name="air"})
- end
- end
- })
- -- de-stagnation (faster flowing)
- minetest.register_abm({
- nodenames = {"springs:water_full"},
- neighbors = {"air"},
- interval = 6,
- chance = 1,
- action = function(pos)
- -- if it's near air it might flow
- minetest.set_node(pos, {name = "springs:water"})
- end
- })
-
- -- flowing
- minetest.register_abm({
- nodenames = {"springs:water"},
- neighbors = {"group:fresh_water", "air"},
- interval = 2,
- chance = 2,
- action = function(pos)
- local mylevel = minetest.get_node_level(pos)
- -- print("\n mylevel ".. mylevel)
-
- -- falling
- local below = {x=pos.x, y=pos.y - 1, z=pos.z}
- local nbelow = minetest.get_node(below).name
- if nbelow == "air" then
- minetest.set_node(below, {name="springs:water"})
- minetest.set_node_level(below, mylevel)
- minetest.set_node(pos, {name="air"})
- return
- elseif nbelow == "springs:water" then
- local blevel = minetest.get_node_level(below)
- if blevel < 64 then
- local sum = mylevel + blevel
- minetest.set_node_level(below, math.min(64, sum))
-
- if sum > 64 then
- mylevel = sum - 64
- minetest.set_node_level(pos, mylevel)
- -- keep flowing the liquid. this speeds up cascades
- else
- minetest.set_node(pos, {name="air"})
- return
- end
- end
- else -- check soaking
- local rate = soak[nbelow]
- if rate ~= nil then
- local remains = mylevel - rate
- if remains > 0 then
- minetest.set_node_level(pos, remains)
- else
- minetest.set_node(pos, {name="air"})
- end
-
- if 1 == math.random(120 / mylevel) then
- minetest.set_node(below, {name = "air"})
- end
-
- mylevel = remains
- --return -- keep the fluid mechanics
- end
- end
-
- local air_nodes = minetest.find_nodes_in_area(
- {x=pos.x - 1, y=pos.y - 1, z=pos.z - 1},
- {x=pos.x + 1, y=pos.y, z=pos.z + 1},
- "air"
- )
-
-
-
-
- -- print("x: "..pos.x.." y: "..pos.y.." z: "..pos.z)
- -- print("air list len ".. #air_nodes)
- local off = math.random(0, #air_nodes or 1)
- -- print("off "..off)
- for i = 1,#air_nodes do
- --local theirlevel = minetest.get_node_level(fp)
- local fp = air_nodes[((i + off) % #air_nodes) + 1]
- if mylevel >= 2 then
- local half = math.ceil(mylevel / 2)
-
- minetest.set_node_level(pos, mylevel - half)
- minetest.set_node(fp, {name= "springs:water"})
- minetest.set_node_level(fp, half)
- -- minetest.check_for_falling(fp)
- return
- end
- end
-
- local flow_nodes = minetest.find_nodes_in_area(
- {x=pos.x - 1, y=pos.y , z=pos.z - 1},
- {x=pos.x + 1, y=pos.y, z=pos.z + 1},
- "group:fresh_water"
- )
-
- -- print("x: "..pos.x.." y: "..pos.y.." z: "..pos.z)
- -- print("list len ".. #flow_nodes)
- local off = math.random(0, #flow_nodes or 1)
-
- for i = 1,#flow_nodes do
- local fp = flow_nodes[((i + off) % #flow_nodes) + 1]
- local theirlevel = minetest.get_node_level(fp)
- -- print("theirlevel "..theirlevel)
- if mylevel - theirlevel >= 2 then
- local diff = (mylevel - theirlevel)
- local half = math.ceil(diff / 2)
-
- minetest.set_node_level(pos, mylevel - half)
- minetest.set_node_level(fp, theirlevel + (diff - half))
- return
- end
- end
-
- -- local n = minetest.get_node(fp);
- -- -- check above to make sure it can get here
- -- local na = minetest.get_node({x=fp.x, y=fp.y+1, z=fp.z})
- --
- -- -- print("name: " .. na.name .. " l: " ..g)
- -- if na.name == "default:river_water_flowing" or na.name == "default:river_water_flowing" then
- -- minetest.set_node(fp, {name=node.name})
- -- minetest.set_node(pos, {name=n.name})
- -- return
- -- end
- -- end
-
-
- -- stagnation: this may not work
- if mylevel == 64 then
- --print("stagnating ".. pos.x .. ","..pos.y..","..pos.z)
- minetest.set_node(pos, {name = "springs:water_full"})
- end
- end
- })
- -- surface water
- minetest.register_ore({
- ore_type = "scatter",
- ore = "springs:spring",
- wherein = {"default:dirt_with_grass", "default:dirt_with_coniferous_litter", "default:dirt_with_rainforest_litter"},
- clust_scarcity = 64 * 64 * 64,
- clust_num_ores = 1,
- clust_size = 1,
- y_min = -20,
- y_max = 200,
- })
- minetest.register_ore({
- ore_type = "scatter",
- ore = "springs:spring",
- wherein = "default:dirt",
- clust_scarcity = 48 * 48 * 48,
- clust_num_ores = 1,
- clust_size = 1,
- y_min = -20,
- y_max = 200,
- })
- -- ground water
- minetest.register_ore({
- ore_type = "scatter",
- ore = "springs:spring",
- wherein = "default:stone",
- clust_scarcity = 16 * 16 * 16,
- clust_num_ores = 3,
- clust_size = 3,
- y_min = -50,
- y_max = -10,
- })
- minetest.register_ore({
- ore_type = "scatter",
- ore = "springs:spring",
- wherein = "default:stone",
- clust_scarcity = 8 * 8 * 8,
- clust_num_ores = 5,
- clust_size = 4,
- y_min = -50,
- y_max = -25,
- })
- -- deep water - rare but bountiful
- minetest.register_ore({
- ore_type = "scatter",
- ore = "springs:spring",
- wherein = "default:stone",
- clust_scarcity = 64 * 64 * 64,
- clust_num_ores = 12,
- clust_size = 6,
- y_min = -32000,
- y_max = -100,
- })
- -- minetest.register_ore({
- -- ore_type = "scatter",
- -- ore = "springs:spring",
- -- wherein = "default:stone",
- -- clust_scarcity = 8 * 8 * 8,
- -- clust_num_ores = 16,
- -- clust_size = 5,
- -- y_min = -50,
- -- y_max = -40,
- -- })
- -- TODO: desert stone, sandstone
|