From 48b6f1be2017d5cc39370c01b091fd0884bc0dae Mon Sep 17 00:00:00 2001 From: FaceDeer Date: Sun, 22 Jan 2017 23:45:00 -0700 Subject: [PATCH] Initial commit --- LICENSE.txt | 17 +++++++ README.txt | 14 ++++++ depends.txt | 1 + init.lua | 127 +++++++++++++++++++++++++++++++++++++++++++++++ mod.conf | 1 + settingtypes.txt | 18 +++++++ 6 files changed, 178 insertions(+) create mode 100644 LICENSE.txt create mode 100644 README.txt create mode 100644 depends.txt create mode 100644 init.lua create mode 100644 mod.conf create mode 100644 settingtypes.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..1688bbd --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,17 @@ +dynamic_liquid mod for Minetest + +Copyright (C) 2017 FaceDeer + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..83b22ef --- /dev/null +++ b/README.txt @@ -0,0 +1,14 @@ +This mod implements a simple but powerful approach to making the various liquid node types (water, lava) behave in a more realistic manner. In a nutshell, it sets an Active Block Modifier running for liquid nodes that implements the following behavior: + +* If there is a "flowing" node below the "source" liquid block, swap the liquid block with the flowing node (the liquid drops) +* Else if there is at least one "flowing" node beside the "source" liquid block, swap with a random flowing node beside it. + +This causes "source" blocks for liquids to randomly shuffle around when they don't completely fill a vertical layer, and causes them to drain rapidly down holes or flow rapidly down hillsides. The ABM only runs for blocks that are adjacent to flowing nodes and does very few calculations so it's reasonably lightweight. + +Each type of liquid can have this behaviour enabled independently of each other. By default lava is configured to flow more slowly than water, but this can be changed in the mod's settings. + +If basic water is set as dynamic, it loses its "renewability" - water nodes don't replicate like they normally do. If you are concerned about the global water level dropping over time as water pours down into undersea caverns, or just generally don't like the idea of water being a finite resource (even with an ocean's worth to start with), this mod includes an optional feature that turns natural clay deposits into "springs". Clay deposits get an Active Block Modifier that checks if there's air or shallow water above them and refills them with newly spawned water source blocks. + +If this clay is dug out by players and reconstituted into clay blocks elsewhere, the "spring" behaviour won't occur for these - it only happens for clay spawned by mapgen while this feature is enabled. (In technical terms, when clay springs are enabled the map generator replaces generated clay with an otherwise identical "damp clay" node type that drops regular clay when dug. The ABM only affects this "damp clay" node type.) + +Note that other than this clay spring feature and the override of water's "renewability" this mod doesn't affect any default node definitions, so any other mods and features dealing with liquids should still function as they did before. If you disable any of the liquid types they will just "freeze" in whatever position they were in at the time. \ No newline at end of file diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..331d858 --- /dev/null +++ b/depends.txt @@ -0,0 +1 @@ +default \ No newline at end of file diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..94c0f6c --- /dev/null +++ b/init.lua @@ -0,0 +1,127 @@ +local water = minetest.setting_getbool("dynamic_liquid_water") +water = water or water == nil -- default true + +local river_water = minetest.setting_getbool("dynamic_liquid_river_water") +river_water = river_water or river_water == nil -- default true + +local lava = minetest.setting_getbool("dynamic_liquid_lava") +lava = lava or lava == nil -- default true + +local lava_probability = tonumber(minetest.setting_get("dynamic_liquid_lava_flow_propability")) +if lava_probability == nil then + lava_probability = 5 +end + +local springs = minetest.setting_getbool("dynamic_liquid_springs") +springs = springs or springs == nil -- default true + +-- One must override a registered node definition with a new one, can't just twiddle with the parameters of the existing table +local duplicate_def = function (name) + local old_def = minetest.registered_nodes[name] + local new_def = {} + for param, value in pairs(old_def) do + new_def[param] = value + end + return new_def +end + +if water then + -- override water_source and water_flowing with liquid_renewable set to false + local new_water_def = duplicate_def("default:water_source") + new_water_def.liquid_renewable = false + minetest.register_node(":default:water_source", new_water_def) + + local new_water_flowing_def = duplicate_def("default:water_flowing") + new_water_flowing_def.liquid_renewable = false + minetest.register_node(":default:water_flowing", new_water_flowing_def) +end + +local rand_dir = function() + local dirs= { + {x=0,y=0,z=1}, + {x=0,y=0,z=-1}, + {x=1,y=0,z=0}, + {x=-1,y=0,z=0}, + } + return dirs[math.random(4)] +end + +local down = {x=0,y=-1,z=0} + +local liquid_abm = function(liquid, flowing_liquid, chance) + minetest.register_abm({ + nodenames = {liquid}, + neighbors = {flowing_liquid}, + interval = 1, + chance = chance or 1, + catch_up = false, + action = function(pos,node) + local check_pos = vector.add(pos, down) + local check_node = minetest.get_node(check_pos) + if check_node.name == flowing_liquid then + minetest.set_node(pos, check_node) + minetest.set_node(check_pos, node) + return + end + check_pos = vector.add(pos, rand_dir()) + check_node = minetest.get_node(check_pos) + if check_node.name == flowing_liquid then + minetest.set_node(pos, check_node) + minetest.set_node(check_pos, node) + end + end + }) +end + +if lava then + liquid_abm("default:lava_source", "default:lava_flowing", lava_probability) +end +if water then + liquid_abm("default:water_source", "default:water_flowing", nil) +end +if river_water then + liquid_abm("default:river_water_source", "default:river_water_flowing", nil) +end + +-- register damp clay whether we're going to set the ABM or not, if the user disables this feature we don't want existing +-- spring clay to turn into unknown nodes. +local clay_def = duplicate_def("default:clay") +clay_def.description = "Damp Clay" +minetest.register_node("dynamic_liquid:clay", clay_def) + +if springs then + local c_clay = minetest.get_content_id("default:clay") + local c_spring_clay = minetest.get_content_id("dynamic_liquid:clay") + + minetest.register_on_generated(function(minp, maxp, seed) + if minp.y >= 0 or maxp.y <= -15 then + return + end + local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") + local data = vm:get_data() + + for voxelpos, voxeldata in pairs(data) do + if voxeldata == c_clay then + data[voxelpos] = c_spring_clay + end + end + vm:set_data(data) + vm:write_to_map() + end) + + minetest.register_abm({ + nodenames = {"dynamic_liquid:clay"}, + neighbors = {"air"}, + interval = 1, + chance = 1, + catch_up = false, + action = function(pos,node) + local check_pos = {x=pos.x, y=pos.y+1, z=pos.z} + local check_node = minetest.get_node(check_pos) + if check_node.name == "air" or check_node.name == "default:water_flowing" then + minetest.set_node(check_pos, {name="default:water_source"}) + minetest.debug("generated spring water") + end + end + }) +end \ No newline at end of file diff --git a/mod.conf b/mod.conf new file mode 100644 index 0000000..875df42 --- /dev/null +++ b/mod.conf @@ -0,0 +1 @@ +name = dynamic_liquid \ No newline at end of file diff --git a/settingtypes.txt b/settingtypes.txt new file mode 100644 index 0000000..04d67ba --- /dev/null +++ b/settingtypes.txt @@ -0,0 +1,18 @@ +#Makes water limited (it doesn't spawn new blocks any more) and causes it to flow dynamically +dynamic_liquid_water (Dynamic water) bool true + +#Causes river water to flow dynamically +dynamic_liquid_river_water (Dynamic river water) bool true + +#Causes lava to flow dynamically +dynamic_liquid_lava (Dynamic lava) bool true + +#Sets the probability of the lava flow calculation per block per second. +#That is, if this is set to 5 then there's a 1/5 chance per second that a lava block +#will check if it should move. Increase this value to make lava flow slower. Set it to +#1 to make lava flow as fast as water does. +#This value only has an effect if dynamic lava is set to true +dynamic_liquid_lava_flow_propability (Lava flow probability) int 5 1 100 + +#Causes natural clay deposits to act as spring sources, seeping water into the block above them +dynamic_liquid_springs (Clay springs) bool true \ No newline at end of file