From e2fdfb44cbd4cfc90fd908d0c262dd831bb26e6f Mon Sep 17 00:00:00 2001 From: Gael-de-Sailly Date: Wed, 1 Jul 2015 12:34:24 +0200 Subject: [PATCH] Added Watershed mod by Paramat --- mods/watershed/README.txt | 4 + mods/watershed/depends.txt | 3 + mods/watershed/functions.lua | 462 +++++++++++ mods/watershed/init.lua | 740 ++++++++++++++++++ mods/watershed/license.txt | 14 + mods/watershed/nodes.lua | 647 +++++++++++++++ .../textures/watershed_acacialeaf.png | Bin 0 -> 340 bytes .../textures/watershed_acacialing.png | Bin 0 -> 359 bytes .../textures/watershed_acaciatree.png | Bin 0 -> 682 bytes .../textures/watershed_acaciatreetop.png | Bin 0 -> 731 bytes .../textures/watershed_acaciawood.png | Bin 0 -> 364 bytes .../textures/watershed_bucketfreshwater.png | Bin 0 -> 330 bytes mods/watershed/textures/watershed_cloud.png | Bin 0 -> 136 bytes .../watershed/textures/watershed_drygrass.png | Bin 0 -> 771 bytes .../watershed/textures/watershed_freshice.png | Bin 0 -> 780 bytes .../textures/watershed_freshwater.png | Bin 0 -> 713 bytes .../textures/watershed_freshwateranim.png | Bin 0 -> 4927 bytes .../textures/watershed_freshwaterflowanim.png | Bin 0 -> 5819 bytes .../textures/watershed_goldengrass.png | Bin 0 -> 683 bytes mods/watershed/textures/watershed_icydirt.png | Bin 0 -> 746 bytes mods/watershed/textures/watershed_light.png | Bin 0 -> 155 bytes .../textures/watershed_luxcrystal.png | Bin 0 -> 207 bytes mods/watershed/textures/watershed_luxore.png | Bin 0 -> 311 bytes .../watershed/textures/watershed_mixwater.png | Bin 0 -> 716 bytes .../textures/watershed_mixwateranim.png | Bin 0 -> 4935 bytes .../textures/watershed_mixwaterflowanim.png | Bin 0 -> 5851 bytes mods/watershed/textures/watershed_needles.png | Bin 0 -> 860 bytes .../textures/watershed_permafrost.png | Bin 0 -> 897 bytes .../watershed/textures/watershed_pineling.png | Bin 0 -> 406 bytes .../watershed/textures/watershed_pinetree.png | Bin 0 -> 693 bytes .../textures/watershed_pinetreetop.png | Bin 0 -> 802 bytes .../watershed/textures/watershed_pinewood.png | Bin 0 -> 366 bytes .../textures/watershed_redcobble.png | Bin 0 -> 686 bytes 33 files changed, 1870 insertions(+) create mode 100644 mods/watershed/README.txt create mode 100644 mods/watershed/depends.txt create mode 100644 mods/watershed/functions.lua create mode 100644 mods/watershed/init.lua create mode 100644 mods/watershed/license.txt create mode 100644 mods/watershed/nodes.lua create mode 100644 mods/watershed/textures/watershed_acacialeaf.png create mode 100644 mods/watershed/textures/watershed_acacialing.png create mode 100644 mods/watershed/textures/watershed_acaciatree.png create mode 100644 mods/watershed/textures/watershed_acaciatreetop.png create mode 100644 mods/watershed/textures/watershed_acaciawood.png create mode 100644 mods/watershed/textures/watershed_bucketfreshwater.png create mode 100644 mods/watershed/textures/watershed_cloud.png create mode 100644 mods/watershed/textures/watershed_drygrass.png create mode 100644 mods/watershed/textures/watershed_freshice.png create mode 100644 mods/watershed/textures/watershed_freshwater.png create mode 100644 mods/watershed/textures/watershed_freshwateranim.png create mode 100644 mods/watershed/textures/watershed_freshwaterflowanim.png create mode 100644 mods/watershed/textures/watershed_goldengrass.png create mode 100644 mods/watershed/textures/watershed_icydirt.png create mode 100644 mods/watershed/textures/watershed_light.png create mode 100644 mods/watershed/textures/watershed_luxcrystal.png create mode 100644 mods/watershed/textures/watershed_luxore.png create mode 100644 mods/watershed/textures/watershed_mixwater.png create mode 100644 mods/watershed/textures/watershed_mixwateranim.png create mode 100644 mods/watershed/textures/watershed_mixwaterflowanim.png create mode 100644 mods/watershed/textures/watershed_needles.png create mode 100644 mods/watershed/textures/watershed_permafrost.png create mode 100644 mods/watershed/textures/watershed_pineling.png create mode 100644 mods/watershed/textures/watershed_pinetree.png create mode 100644 mods/watershed/textures/watershed_pinetreetop.png create mode 100644 mods/watershed/textures/watershed_pinewood.png create mode 100644 mods/watershed/textures/watershed_redcobble.png diff --git a/mods/watershed/README.txt b/mods/watershed/README.txt new file mode 100644 index 00000000..4fdfc160 --- /dev/null +++ b/mods/watershed/README.txt @@ -0,0 +1,4 @@ +watershed 0.6.6 by paramat +For latest stable Minetest back to 0.4.8 +Depends default stairs bucket +Licenses: code WTFPL, textures CC BY-SA diff --git a/mods/watershed/depends.txt b/mods/watershed/depends.txt new file mode 100644 index 00000000..9fc96490 --- /dev/null +++ b/mods/watershed/depends.txt @@ -0,0 +1,3 @@ +default +bucket +stairs diff --git a/mods/watershed/functions.lua b/mods/watershed/functions.lua new file mode 100644 index 00000000..a6940fc5 --- /dev/null +++ b/mods/watershed/functions.lua @@ -0,0 +1,462 @@ +function watershed_appletree(x, y, z, area, data) + local c_tree = minetest.get_content_id("default:tree") + local c_apple = minetest.get_content_id("default:apple") + local c_wsappleaf = minetest.get_content_id("watershed:appleleaf") + for j = -2, 4 do + if j == 3 or j == 4 then + for i = -2, 2 do + for k = -2, 2 do + local vil = area:index(x + i, y + j, z + k) + if math.random(64) == 2 then + data[vil] = c_apple + elseif math.random(5) ~= 2 then + data[vil] = c_wsappleaf + end + end + end + elseif j == 2 then + for i = -1, 1 do + for k = -1, 1 do + if math.abs(i) + math.abs(k) == 2 then + local vit = area:index(x + i, y + j, z + k) + data[vit] = c_tree + end + end + end + else + local vit = area:index(x, y + j, z) + data[vit] = c_tree + end + end +end + +function watershed_pinetree(x, y, z, area, data) + local c_wspitree = minetest.get_content_id("watershed:pinetree") + local c_wsneedles = minetest.get_content_id("watershed:needles") + local c_snowblock = minetest.get_content_id("default:snowblock") + for j = -4, 14 do + if j == 3 or j == 6 or j == 9 or j == 12 then + for i = -2, 2 do + for k = -2, 2 do + if math.abs(i) == 2 or math.abs(k) == 2 then + if math.random(7) ~= 2 then + local vil = area:index(x + i, y + j, z + k) + data[vil] = c_wsneedles + local vila = area:index(x + i, y + j + 1, z + k) + data[vila] = c_snowblock + end + end + end + end + elseif j == 4 or j == 7 or j == 10 then + for i = -1, 1 do + for k = -1, 1 do + if not (i == 0 and j == 0) then + if math.random(11) ~= 2 then + local vil = area:index(x + i, y + j, z + k) + data[vil] = c_wsneedles + local vila = area:index(x + i, y + j + 1, z + k) + data[vila] = c_snowblock + end + end + end + end + elseif j == 13 then + for i = -1, 1 do + for k = -1, 1 do + if not (i == 0 and j == 0) then + local vil = area:index(x + i, y + j, z + k) + data[vil] = c_wsneedles + local vila = area:index(x + i, y + j + 1, z + k) + data[vila] = c_wsneedles + local vilaa = area:index(x + i, y + j + 2, z + k) + data[vilaa] = c_snowblock + end + end + end + end + local vit = area:index(x, y + j, z) + data[vit] = c_wspitree + end + local vil = area:index(x, y + 15, z) + local vila = area:index(x, y + 16, z) + local vilaa = area:index(x, y + 17, z) + data[vil] = c_wsneedles + data[vila] = c_wsneedles + data[vilaa] = c_snowblock +end + +function watershed_jungletree(x, y, z, area, data) + local c_juntree = minetest.get_content_id("default:jungletree") + local c_wsjunleaf = minetest.get_content_id("watershed:jungleleaf") + local c_vine = minetest.get_content_id("watershed:vine") + local top = math.random(17,23) + local branch = math.floor(top * 0.6) + for j = -5, top do + if j == top or j == top - 1 or j == branch + 1 or j == branch + 2 then + for i = -2, 2 do -- leaves + for k = -2, 2 do + local vi = area:index(x + i, y + j, z + k) + if math.random(5) ~= 2 then + data[vi] = c_wsjunleaf + end + end + end + elseif j == top - 2 or j == branch then -- branches + for i = -1, 1 do + for k = -1, 1 do + if math.abs(i) + math.abs(k) == 2 then + local vi = area:index(x + i, y + j, z + k) + data[vi] = c_juntree + end + end + end + end + if j >= 0 and j <= top - 3 then -- climbable nodes + for i = -1, 1 do + for k = -1, 1 do + if math.abs(i) + math.abs(k) == 1 then + local vi = area:index(x + i, y + j, z + k) + data[vi] = c_vine + end + end + end + end + if j <= top - 3 then -- trunk + local vi = area:index(x, y + j, z) + data[vi] = c_juntree + end + end +end + +function watershed_acaciatree(x, y, z, area, data) + local c_wsactree = minetest.get_content_id("watershed:acaciatree") + local c_wsacleaf = minetest.get_content_id("watershed:acacialeaf") + for j = -3, 6 do + if j == 6 then + for i = -4, 4 do + for k = -4, 4 do + if not (i == 0 or k == 0) then + if math.random(7) ~= 2 then + local vil = area:index(x + i, y + j, z + k) + data[vil] = c_wsacleaf + end + end + end + end + elseif j == 5 then + for i = -2, 2, 4 do + for k = -2, 2, 4 do + local vit = area:index(x + i, y + j, z + k) + data[vit] = c_wsactree + end + end + elseif j == 4 then + for i = -1, 1 do + for k = -1, 1 do + if math.abs(i) + math.abs(k) == 2 then + local vit = area:index(x + i, y + j, z + k) + data[vit] = c_wsactree + end + end + end + else + local vit = area:index(x, y + j, z) + data[vit] = c_wsactree + end + end +end + +function watershed_flower(data, vi, noise) + local c_danwhi = minetest.get_content_id("flowers:dandelion_white") + local c_danyel = minetest.get_content_id("flowers:dandelion_yellow") + local c_rose = minetest.get_content_id("flowers:rose") + local c_tulip = minetest.get_content_id("flowers:tulip") + local c_geranium = minetest.get_content_id("flowers:geranium") + local c_viola = minetest.get_content_id("flowers:viola") + if noise > 0.8 then + data[vi] = c_danwhi + elseif noise > 0.4 then + data[vi] = c_rose + elseif noise > 0 then + data[vi] = c_tulip + elseif noise > -0.4 then + data[vi] = c_danyel + elseif noise > -0.8 then + data[vi] = c_geranium + else + data[vi] = c_viola + end +end + +function watershed_cactus(x, y, z, area, data) + local c_wscactus = minetest.get_content_id("watershed:cactus") + for j = -2, 4 do + for i = -2, 2 do + if i == 0 or j == 2 or (j == 3 and math.abs(i) == 2) then + local vic = area:index(x + i, y + j, z) + data[vic] = c_wscactus + end + end + end +end + +function watershed_papyrus(x, y, z, area, data) + local c_papyrus = minetest.get_content_id("default:papyrus") + local ph = math.random(1, 4) + for j = 0, ph do + local vip = area:index(x, y + j, z) + data[vip] = c_papyrus + end +end + +-- Singlenode option + +local SINGLENODE = true + +if SINGLENODE then + -- Set mapgen parameters + + minetest.register_on_mapgen_init(function(mgparams) + minetest.set_mapgen_params({mgname="singlenode", flags="nolight"}) + end) + + -- Spawn player function. Requires chunksize = 80 nodes (the default) + + function spawnplayer(player) + local TERCEN = -128 + local TERSCA = 512 + local XLSAMP = 0.1 + local BASAMP = 0.3 + local MIDAMP = 0.1 + local CANAMP = 0.4 + local ATANAMP = 1.1 + local BLENEXP = 2 + local xsp + local ysp + local zsp + + local np_terrain = { + offset = 0, + scale = 1, + spread = {x=384, y=192, z=384}, + seed = 593, + octaves = 5, + persist = 0.67 + } + local np_mid = { + offset = 0, + scale = 1, + spread = {x=768, y=768, z=1}, + seed = 85546, + octaves = 5, + persist = 0.5 + } + local np_base = { + offset = 0, + scale = 1, + spread = {x=4096, y=4096, z=1}, + seed = 8890, + octaves = 3, + persist = 0.33 + } + local np_xlscale = { + offset = 0, + scale = 1, + spread = {x=8192, y=8192, z=1}, + seed = -72, + octaves = 3, + persist = 0.33 + } + + local nobj_terrain = nil + local nobj_mid = nil + local nobj_base = nil + local nobj_xlscale = nil + + for chunk = 1, 64 do + print ("[watershed] searching for spawn "..chunk) + local x0 = 80 * math.random(-32, 32) - 32 + local z0 = 80 * math.random(-32, 32) - 32 + local y0 = -32 + local x1 = x0 + 79 + local z1 = z0 + 79 + local y1 = 47 + local sidelen = 80 + local chulensxyz = {x=sidelen, y=sidelen+2, z=sidelen} + local chulensxz = {x=sidelen, y=sidelen, z=1} + local minposxyz = {x=x0, y=y0-1, z=z0} + local minposxz = {x=x0, y=z0} + + nobj_terrain = nobj_terrain or minetest.get_perlin_map(np_terrain, chulensxyz) + nobj_mid = nobj_mid or minetest.get_perlin_map(np_mid, chulensxz) + nobj_base = nobj_base or minetest.get_perlin_map(np_base, chulensxz) + nobj_xlscale = nobj_xlscale or minetest.get_perlin_map(np_xlscale, chulensxz) + + local nvals_terrain = nobj_terrain:get3dMap_flat(minposxyz) + local nvals_mid = nobj_mid:get2dMap_flat(minposxz) + local nvals_base = nobj_base:get2dMap_flat(minposxz) + local nvals_xlscale = nobj_xlscale:get2dMap_flat(minposxz) + + local nixz = 1 + local nixyz = 1 + for z = z0, z1 do + for y = y0, y1 do + for x = x0, x1 do + local n_absterrain = math.abs(nvals_terrain[nixyz]) + local n_absmid = math.abs(nvals_mid[nixz]) + local n_absbase = math.abs(nvals_base[nixz]) + local n_xlscale = nvals_xlscale[nixz] + + local n_invbase = (1 - n_absbase) + local terblen = (math.max(n_invbase, 0)) ^ BLENEXP + local grad = math.atan((TERCEN - y) / TERSCA) * ATANAMP + local densitybase = n_invbase * BASAMP + n_xlscale * XLSAMP + grad + local densitymid = n_absmid * MIDAMP + densitybase + local canexp = 0.5 + terblen * 0.5 + local canamp = terblen * CANAMP + local density = n_absterrain ^ canexp * canamp * n_absmid + densitymid + + if y >= 1 and density > -0.005 and density < 0 then + ysp = y + 1 + xsp = x + zsp = z + break + end + nixz = nixz + 1 + nixyz = nixyz + 1 + end + if ysp then + break + end + nixz = nixz - 80 + end + if ysp then + break + end + nixz = nixz + 80 + end + if ysp then + break + end + end + print ("[watershed] spawn player ("..xsp.." "..ysp.." "..zsp..")") + player:setpos({x=xsp, y=ysp, z=zsp}) + end + + minetest.register_on_newplayer(function(player) + spawnplayer(player) + end) + + minetest.register_on_respawnplayer(function(player) + spawnplayer(player) + return true + end) +end + +-- ABM + +-- Lava-water cooling + +minetest.register_abm({ + nodenames = {"group:lava"}, + neighbors = {"group:water"}, + interval = 11, + chance = 64, + action = function(pos, node, active_object_count, active_object_count_wider) + minetest.add_node(pos, {name="default:obsidian"}) + minetest.sound_play("default_cool_lava", {pos = pos, gain = 0.25}) + end, +}) + +-- Appletree sapling + +minetest.register_abm({ + nodenames = {"watershed:appling"}, + interval = 57, + chance = 3, + action = function(pos, node) + local x = pos.x + local y = pos.y + local z = pos.z + local vm = minetest.get_voxel_manip() + local pos1 = {x=x-2, y=y-2, z=z-2} + local pos2 = {x=x+2, y=y+4, z=z+2} + local emin, emax = vm:read_from_map(pos1, pos2) + local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax}) + local data = vm:get_data() + watershed_appletree(x, y, z, area, data) + vm:set_data(data) + vm:write_to_map() + vm:update_map() + end, +}) + +-- Pine sapling + +minetest.register_abm({ + nodenames = {"watershed:pineling"}, + interval = 59, + chance = 3, + action = function(pos, node) + local x = pos.x + local y = pos.y + local z = pos.z + local vm = minetest.get_voxel_manip() + local pos1 = {x=x-2, y=y-4, z=z-2} + local pos2 = {x=x+2, y=y+17, z=z+2} + local emin, emax = vm:read_from_map(pos1, pos2) + local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax}) + local data = vm:get_data() + watershed_pinetree(x, y, z, area, data) + vm:set_data(data) + vm:write_to_map() + vm:update_map() + end, +}) + +-- Acacia sapling + +minetest.register_abm({ + nodenames = {"watershed:acacialing"}, + interval = 61, + chance = 3, + action = function(pos, node) + local x = pos.x + local y = pos.y + local z = pos.z + local vm = minetest.get_voxel_manip() + local pos1 = {x=x-4, y=y-3, z=z-4} + local pos2 = {x=x+4, y=y+6, z=z+4} + local emin, emax = vm:read_from_map(pos1, pos2) + local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax}) + local data = vm:get_data() + watershed_acaciatree(x, y, z, area, data) + vm:set_data(data) + vm:write_to_map() + vm:update_map() + end, +}) + +-- Jungletree sapling + +minetest.register_abm({ + nodenames = {"watershed:jungling"}, + interval = 63, + chance = 3, + action = function(pos, node) + local x = pos.x + local y = pos.y + local z = pos.z + local vm = minetest.get_voxel_manip() + local pos1 = {x=x-2, y=y-5, z=z-2} + local pos2 = {x=x+2, y=y+23, z=z+2} + local emin, emax = vm:read_from_map(pos1, pos2) + local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax}) + local data = vm:get_data() + watershed_jungletree(x, y, z, area, data) + vm:set_data(data) + vm:write_to_map() + vm:update_map() + end, +}) diff --git a/mods/watershed/init.lua b/mods/watershed/init.lua new file mode 100644 index 00000000..df36832e --- /dev/null +++ b/mods/watershed/init.lua @@ -0,0 +1,740 @@ +-- watershed 0.6.6 by paramat +-- For latest stable Minetest and back to 0.4.8 +-- Depends default stairs bucket +-- License: code WTFPL, textures CC BY-SA + +-- re-add z=1 for z component of 2D noisemap size to fix crashes + +-- Parameters + +local YMIN = -33000 -- Approximate base of realm stone +local YMAX = 33000 -- Approximate top of atmosphere / mountains / floatlands +local TERCEN = -128 -- Terrain zero level, average seabed +local YWAT = 1 -- Sea surface y +local YSAV = 5 -- Average sandline y, dune grasses above this +local SAMP = 3 -- Sandline amplitude +local YCLOMIN = 207 -- Minimum height of mod clouds +local CLOUDS = true -- Mod clouds? + +local TERSCA = 512 -- Vertical terrain scale +local XLSAMP = 0.1 -- Extra large scale height variation amplitude +local BASAMP = 0.3 -- Base terrain amplitude +local MIDAMP = 0.1 -- Mid terrain amplitude +local CANAMP = 0.4 -- Canyon terrain maximum amplitude +local ATANAMP = 1.1 -- Arctan function amplitude, smaller = more and larger floatlands above ridges +local BLENEXP = 2 -- Terrain blend exponent + +local TSTONE = 0.02 -- Density threshold for stone, depth of soil at TERCEN +local TRIVER = -0.028 -- Densitybase threshold for river surface +local TRSAND = -0.035 -- Densitybase threshold for river sand +local TSTREAM = -0.004 -- Densitymid threshold for stream surface +local TSSAND = -0.005 -- Densitymid threshold for stream sand +local TLAVA = 2 -- Maximum densitybase threshold for lava, small because grad is non-linear +local TFIS = 0.01 -- Fissure threshold, controls width +local TSEAM = 0.2 -- Seam threshold, width of seams +local ORESCA = 512 -- Seam system vertical scale +local ORETHI = 0.002 -- Ore seam thickness tuner +local BERGDEP = 32 -- Maximum iceberg depth +local TFOG = -0.04 -- Fog top densitymid threshold + +local HITET = 0.35 -- High temperature threshold +local LOTET = -0.35 -- Low .. +local ICETET = -0.7 -- Ice .. +local HIHUT = 0.35 -- High humidity threshold +local LOHUT = -0.35 -- Low .. +local FOGHUT = 1.0 -- Fog .. +local BLEND = 0.02 -- Biome blend randomness + +local flora = { + PINCHA = 36, -- Pine tree 1/x chance per node + APTCHA = 36, -- Appletree + FLOCHA = 289, -- Flower + GRACHA = 36, -- Grassland grasses + JUTCHA = 16, -- Jungletree + JUGCHA = 16, -- Junglegrass + CACCHA = 2209, -- Cactus + DRYCHA = 121, -- Dry shrub + ACACHA = 1369, -- Acacia tree + GOGCHA = 9, -- Golden grass + PAPCHA = 4, -- Papyrus + DUGCHA = 16, -- Dune grass +} + +-- 3D noises + +-- 3D noise for terrain + +local np_terrain = { + offset = 0, + scale = 1, + spread = {x=384, y=192, z=384}, + seed = 593, + octaves = 5, + persist = 0.67 +} + +-- 3D noise for fissures + +local np_fissure = { + offset = 0, + scale = 1, + spread = {x=256, y=512, z=256}, + seed = 20099, + octaves = 5, + persist = 0.5 +} + +-- 3D noise for temperature + +local np_temp = { + offset = 0, + scale = 1, + spread = {x=1024, y=1024, z=1024}, + seed = 9130, + octaves = 3, + persist = 0.5 +} + +-- 3D noise for humidity + +local np_humid = { + offset = 0, + scale = 1, + spread = {x=1024, y=1024, z=1024}, + seed = -55500, + octaves = 3, + persist = 0.5 +} + +-- 3D noise for ore seam networks + +local np_seam = { + offset = 0, + scale = 1, + spread = {x=512, y=512, z=512}, + seed = -992221, + octaves = 2, + persist = 0.5 +} + +-- 3D noise for rock strata inclination + +local np_strata = { + offset = 0, + scale = 1, + spread = {x=512, y=512, z=512}, + seed = 92219, + octaves = 3, + persist = 0.5 +} + +-- 2D noises + +-- 2D noise for mid terrain / streambed height + +local np_mid = { + offset = 0, + scale = 1, + spread = {x=768, y=768, z=768}, + seed = 85546, + octaves = 5, + persist = 0.5 +} + +-- 2D noise for base terrain / riverbed height + +local np_base = { + offset = 0, + scale = 1, + spread = {x=4096, y=4096, z=4096}, + seed = 8890, + octaves = 3, + persist = 0.33 +} + +-- 2D noise for extra large scale height variation + +local np_xlscale = { + offset = 0, + scale = 1, + spread = {x=8192, y=8192, z=8192}, + seed = -72, + octaves = 3, + persist = 0.33 +} + +-- 2D noise for magma surface + +local np_magma = { + offset = 0, + scale = 1, + spread = {x=128, y=128, z=128}, + seed = -13, + octaves = 2, + persist = 0.5 +} + + +-- Stuff + +-- initialize 3D and 2D noise objects to nil + +local nobj_terrain = nil +local nobj_fissure = nil +local nobj_temp = nil +local nobj_humid = nil +local nobj_seam = nil +local nobj_strata = nil + +local nobj_mid = nil +local nobj_base = nil +local nobj_xlscale = nil +local nobj_magma = nil + +dofile(minetest.get_modpath("watershed").."/nodes.lua") +dofile(minetest.get_modpath("watershed").."/functions.lua") + + +-- Mapchunk generation function + +function watershed_chunkgen(x0, y0, z0, x1, y1, z1, area, data) + local c_air = minetest.get_content_id("air") + local c_ignore = minetest.get_content_id("ignore") + local c_water = minetest.get_content_id("default:water_source") + local c_sand = minetest.get_content_id("default:sand") + local c_desand = minetest.get_content_id("default:desert_sand") + local c_snowblock = minetest.get_content_id("default:snowblock") + local c_ice = minetest.get_content_id("default:ice") + local c_dirtsnow = minetest.get_content_id("default:dirt_with_snow") + local c_jungrass = minetest.get_content_id("default:junglegrass") + local c_dryshrub = minetest.get_content_id("default:dry_shrub") + local c_danwhi = minetest.get_content_id("flowers:dandelion_white") + local c_danyel = minetest.get_content_id("flowers:dandelion_yellow") + local c_rose = minetest.get_content_id("flowers:rose") + local c_tulip = minetest.get_content_id("flowers:tulip") + local c_geranium = minetest.get_content_id("flowers:geranium") + local c_viola = minetest.get_content_id("flowers:viola") + local c_stodiam = minetest.get_content_id("default:stone_with_diamond") + local c_mese = minetest.get_content_id("default:mese") + local c_stogold = minetest.get_content_id("default:stone_with_gold") + local c_stocopp = minetest.get_content_id("default:stone_with_copper") + local c_stoiron = minetest.get_content_id("default:stone_with_iron") + local c_stocoal = minetest.get_content_id("default:stone_with_coal") + local c_sandstone = minetest.get_content_id("default:sandstone") + local c_gravel = minetest.get_content_id("default:gravel") + local c_clay = minetest.get_content_id("default:clay") + local c_grass5 = minetest.get_content_id("default:grass_5") + local c_obsidian = minetest.get_content_id("default:obsidian") + + local c_wsfreshwater = minetest.get_content_id("watershed:freshwater") + local c_wsmixwater = minetest.get_content_id("watershed:mixwater") + local c_wsstone = minetest.get_content_id("watershed:stone") + local c_wsredstone = minetest.get_content_id("watershed:redstone") + local c_wsgrass = minetest.get_content_id("watershed:grass") + local c_wsdrygrass = minetest.get_content_id("watershed:drygrass") + local c_wsgoldengrass = minetest.get_content_id("watershed:goldengrass") + local c_wsdirt = minetest.get_content_id("watershed:dirt") + local c_wspermafrost = minetest.get_content_id("watershed:permafrost") + local c_wslava = minetest.get_content_id("watershed:lava") + local c_wsfreshice = minetest.get_content_id("watershed:freshice") + local c_wscloud = minetest.get_content_id("watershed:cloud") + local c_wsluxore = minetest.get_content_id("watershed:luxore") + local c_wsicydirt = minetest.get_content_id("watershed:icydirt") + -- perlinmap stuff + local sidelen = x1 - x0 + 1 -- chunk sidelength + local chulensxyz = {x=sidelen, y=sidelen+2, z=sidelen} -- chunk dimensions, '+2' for overgeneration + local chulensxz = {x=sidelen, y=sidelen, z=1} -- here x = map x, y = map z + local minposxyz = {x=x0, y=y0-1, z=z0} + local minposxz = {x=x0, y=z0} -- here x = map x, y = map z + -- 3D and 2D noise objects created once on first mapchunk generation only + nobj_terrain = nobj_terrain or minetest.get_perlin_map(np_terrain, chulensxyz) + nobj_fissure = nobj_fissure or minetest.get_perlin_map(np_fissure, chulensxyz) + nobj_temp = nobj_temp or minetest.get_perlin_map(np_temp, chulensxyz) + nobj_humid = nobj_humid or minetest.get_perlin_map(np_humid, chulensxyz) + nobj_seam = nobj_seam or minetest.get_perlin_map(np_seam, chulensxyz) + nobj_strata = nobj_strata or minetest.get_perlin_map(np_strata, chulensxyz) + + nobj_mid = nobj_mid or minetest.get_perlin_map(np_mid, chulensxz) + nobj_base = nobj_base or minetest.get_perlin_map(np_base, chulensxz) + nobj_xlscale = nobj_xlscale or minetest.get_perlin_map(np_xlscale, chulensxz) + nobj_magma = nobj_magma or minetest.get_perlin_map(np_magma, chulensxz) + -- 3D and 2D perlinmaps created per mapchunk + local nvals_terrain = nobj_terrain:get3dMap_flat(minposxyz) + local nvals_fissure = nobj_fissure:get3dMap_flat(minposxyz) + local nvals_temp = nobj_temp:get3dMap_flat(minposxyz) + local nvals_humid = nobj_humid:get3dMap_flat(minposxyz) + local nvals_seam = nobj_seam:get3dMap_flat(minposxyz) + local nvals_strata = nobj_strata:get3dMap_flat(minposxyz) + + local nvals_mid = nobj_mid:get2dMap_flat(minposxz) + local nvals_base = nobj_base:get2dMap_flat(minposxz) + local nvals_xlscale = nobj_xlscale:get2dMap_flat(minposxz) + local nvals_magma = nobj_magma:get2dMap_flat(minposxz) + -- ungenerated chunk below? + local viu = area:index(x0, y0-1, z0) + local ungen = data[viu] == c_ignore + + -- mapgen loop + local nixyz = 1 -- 3D and 2D perlinmap indexes + local nixz = 1 + local stable = {} -- stability table of true/false. is node supported from below by 2 stone or nodes on 2 stone? + local under = {} -- biome table. biome number of previous fine material placed in column + for z = z0, z1 do -- for each xy plane progressing northwards + for y = y0 - 1, y1 + 1 do -- for each x row progressing upwards + local vi = area:index(x0, y, z) -- voxelmanip index for first node in this x row + local viu = area:index(x0, y-1, z) -- index for under node + for x = x0, x1 do -- for each node do + local si = x - x0 + 1 -- stable, under tables index + -- noise values for node + local n_absterrain = math.abs(nvals_terrain[nixyz]) + local n_fissure = nvals_fissure[nixyz] + local n_temp = nvals_temp[nixyz] + local n_humid = nvals_humid[nixyz] + local n_seam = nvals_seam[nixyz] + local n_strata = nvals_strata[nixyz] + + local n_absmid = math.abs(nvals_mid[nixz]) + local n_absbase = math.abs(nvals_base[nixz]) + local n_xlscale = nvals_xlscale[nixz] + local n_magma = nvals_magma[nixz] + -- get densities + local n_invbase = (1 - n_absbase) + local terblen = (math.max(n_invbase, 0)) ^ BLENEXP + local grad = math.atan((TERCEN - y) / TERSCA) * ATANAMP + local densitybase = n_invbase * BASAMP + n_xlscale * XLSAMP + grad + local densitymid = n_absmid * MIDAMP + densitybase + local canexp = 0.5 + terblen * 0.5 + local canamp = terblen * CANAMP + local density = n_absterrain ^ canexp * canamp * n_absmid + densitymid + -- other values + local triver = TRIVER * n_absbase -- river threshold + local trsand = TRSAND * n_absbase -- river sand + local tstream = TSTREAM * (1 - n_absmid) -- stream threshold + local tssand = TSSAND * (1 - n_absmid) -- stream sand + local tstone = TSTONE * (1 + grad) -- stone threshold + local tlava = TLAVA * (1 - n_magma ^ 4 * terblen ^ 16 * 0.6) -- lava threshold + local ysand = YSAV + n_fissure * SAMP + math.random() * 2 -- sandline + local bergdep = math.abs(n_seam) * BERGDEP -- iceberg depth + + local nofis = false -- set fissure bool + if math.abs(n_fissure) >= TFIS then + nofis = true + end + + local biome = false -- select biome for node + if n_temp < LOTET + (math.random() - 0.5) * BLEND then + if n_humid < LOHUT + (math.random() - 0.5) * BLEND then + biome = 1 -- tundra + elseif n_humid > HIHUT + (math.random() - 0.5) * BLEND then + biome = 3 -- taiga + else + biome = 2 -- snowy plains + end + elseif n_temp > HITET + (math.random() - 0.5) * BLEND then + if n_humid < LOHUT + (math.random() - 0.5) * BLEND then + biome = 7 -- desert + elseif n_humid > HIHUT + (math.random() - 0.5) * BLEND then + biome = 9 -- rainforest + else + biome = 8 -- savanna + end + else + if n_humid < LOHUT then + biome = 4 -- dry grassland + elseif n_humid > HIHUT then + biome = 6 -- deciduous forest + else + biome = 5 -- grassland + end + end + + -- overgeneration and in-chunk generation + if y == y0 - 1 then -- node layer below chunk, initialise tables + under[si] = 0 + if ungen then + if nofis and density >= 0 then -- if node solid + stable[si] = 2 + else + stable[si] = 0 + end + else -- scan top layer of chunk below + local nodid = data[vi] + if nodid == c_wsstone + or nodid == c_wsredstone + or nodid == c_wsdirt + or nodid == c_wspermafrost + or nodid == c_wsluxore + or nodid == c_sand + or nodid == c_desand + or nodid == c_mese + or nodid == c_stodiam + or nodid == c_stogold + or nodid == c_stocopp + or nodid == c_stoiron + or nodid == c_stocoal + or nodid == c_sandstone + or nodid == c_gravel + or nodid == c_clay + or nodid == c_obsidian then + stable[si] = 2 + else + stable[si] = 0 + end + end + elseif y >= y0 and y <= y1 then -- chunk + -- add nodes and flora + if densitybase >= tlava then -- lava + if densitybase >= 0 then + data[vi] = c_wslava + end + stable[si] = 0 + under[si] = 0 + elseif densitybase >= tlava - math.min(0.6 + density * 6, 0.6) + and density < tstone then -- obsidian + data[vi] = c_obsidian + stable[si] = 1 + under[si] = 0 + elseif density >= tstone and nofis -- stone cut by fissures + or (density >= tstone and density < TSTONE * 1.2 and y <= YWAT) -- stone around water + or (density >= tstone and density < TSTONE * 1.2 and densitybase >= triver ) -- stone around river + or (density >= tstone and density < TSTONE * 1.2 and densitymid >= tstream ) then -- stone around stream + local densitystr = n_strata * 0.25 + (TERCEN - y) / ORESCA + local densityper = densitystr - math.floor(densitystr) -- periodic strata 'density' + if (densityper >= 0.05 and densityper <= 0.09) -- sandstone strata + or (densityper >= 0.25 and densityper <= 0.28) + or (densityper >= 0.45 and densityper <= 0.47) + or (densityper >= 0.74 and densityper <= 0.76) + or (densityper >= 0.77 and densityper <= 0.79) + or (densityper >= 0.84 and densityper <= 0.87) + or (densityper >= 0.95 and densityper <= 0.98) then + data[vi] = c_sandstone + elseif biome == 7 and density < TSTONE * 3 then -- desert stone as surface layer + data[vi] = c_wsredstone + elseif math.abs(n_seam) < TSEAM then + if densityper >= 0 and densityper <= ORETHI * 4 then -- ore seams + data[vi] = c_stocoal + elseif densityper >= 0.3 and densityper <= 0.3 + ORETHI * 4 then + data[vi] = c_stocoal + elseif densityper >= 0.5 and densityper <= 0.5 + ORETHI * 4 then + data[vi] = c_stocoal + elseif densityper >= 0.8 and densityper <= 0.8 + ORETHI * 4 then + data[vi] = c_stocoal + elseif densityper >= 0.55 and densityper <= 0.55 + ORETHI * 2 then + data[vi] = c_gravel + elseif densityper >= 0.1 and densityper <= 0.1 + ORETHI * 2 then + data[vi] = c_wsluxore + elseif densityper >= 0.2 and densityper <= 0.2 + ORETHI * 2 + and math.random(2) == 2 then + data[vi] = c_stoiron + elseif densityper >= 0.65 and densityper <= 0.65 + ORETHI * 2 + and math.random(2) == 2 then + data[vi] = c_stoiron + elseif densityper >= 0.4 and densityper <= 0.4 + ORETHI * 2 + and math.random(3) == 2 then + data[vi] = c_stocopp + elseif densityper >= 0.6 and densityper <= 0.6 + ORETHI + and math.random(5) == 2 then + data[vi] = c_stogold + elseif densityper >= 0.7 and densityper <= 0.7 + ORETHI + and math.random(7) == 2 then + data[vi] = c_mese + elseif densityper >= 0.9 and densityper <= 0.9 + ORETHI + and math.random(11) == 2 then + data[vi] = c_stodiam + else + data[vi] = c_wsstone + end + else + data[vi] = c_wsstone + end + stable[si] = stable[si] + 1 + under[si] = 0 + elseif density >= 0 and density < tstone and stable[si] >= 2 then -- fine materials + if y == YWAT - 2 and math.abs(n_temp) < 0.05 then -- clay + data[vi] = c_clay + elseif y <= ysand then -- seabed/beach/dune sand not cut by fissures + data[vi] = c_sand + under[si] = 10 -- beach/dunes + elseif densitybase >= trsand + math.random() * 0.001 then -- river sand + data[vi] = c_sand + under[si] = 11 -- riverbank papyrus + elseif densitymid >= tssand + math.random() * 0.001 then -- stream sand + data[vi] = c_sand + under[si] = 0 + elseif nofis then -- fine materials cut by fissures + if biome == 1 then + data[vi] = c_wspermafrost + under[si] = 1 -- tundra + elseif biome == 2 then + data[vi] = c_wsdirt + under[si] = 2 -- snowy plains + elseif biome == 3 then + data[vi] = c_wsdirt + under[si] = 3 -- taiga + elseif biome == 4 then + data[vi] = c_wsdirt + under[si] = 4 -- dry grassland + elseif biome == 5 then + data[vi] = c_wsdirt + under[si] = 5 -- grassland + elseif biome == 6 then + data[vi] = c_wsdirt + under[si] = 6 -- forest + elseif biome == 7 then + data[vi] = c_desand + under[si] = 7 -- desert + elseif biome == 8 then + data[vi] = c_wsdirt + under[si] = 8 -- savanna + elseif biome == 9 then + data[vi] = c_wsdirt + under[si] = 9 -- rainforest + end + else -- fissure + stable[si] = 0 + under[si] = 0 + end + elseif y >= YWAT - bergdep and y <= YWAT + bergdep / 8 -- icesheet + and n_temp < ICETET and density < tstone + and math.abs(n_fissure) > 0.01 then + data[vi] = c_ice + under[si] = 12 + stable[si] = 0 + elseif y <= YWAT and density < tstone then -- sea water + data[vi] = c_water + under[si] = 0 + stable[si] = 0 + elseif densitybase >= triver and density < tstone then -- river water not in fissures + if n_temp < ICETET then + data[vi] = c_wsfreshice + else + if y == YWAT + 1 then + data[vi] = c_wsmixwater + else + data[vi] = c_wsfreshwater + end + end + stable[si] = 0 + under[si] = 0 + elseif densitymid >= tstream and density < tstone then -- stream water not in fissures + if n_temp < ICETET then + data[vi] = c_wsfreshice + else + if y == YWAT + 1 then + data[vi] = c_wsmixwater + else + data[vi] = c_wsfreshwater + end + end + stable[si] = 0 + under[si] = 0 + elseif density < 0 and y >= YWAT and under[si] ~= 0 then -- air above surface node + local fnoise = n_fissure -- noise for flower colours + if under[si] == 1 then + data[viu] = c_wsicydirt + if math.random(flora.DRYCHA) == 2 then + data[vi] = c_dryshrub + end + elseif under[si] == 2 then + data[viu] = c_dirtsnow + data[vi] = c_snowblock + elseif under[si] == 3 then + if math.random(flora.PINCHA) == 2 then + watershed_pinetree(x, y, z, area, data) + else + data[viu] = c_dirtsnow + data[vi] = c_snowblock + end + elseif under[si] == 4 then + data[viu] = c_wsdrygrass + if math.random(flora.DRYCHA) == 2 then + data[vi] = c_dryshrub + end + elseif under[si] == 5 then + data[viu] = c_wsgrass + if math.random(flora.FLOCHA) == 2 then + watershed_flower(data, vi, fnoise) + elseif math.random(flora.GRACHA) == 2 then + data[vi] = c_grass5 + end + elseif under[si] == 6 then + if math.random(flora.APTCHA) == 2 then + watershed_appletree(x, y, z, area, data) + else + data[viu] = c_wsgrass + if math.random(flora.FLOCHA) == 2 then + watershed_flower(data, vi, fnoise) + elseif math.random(flora.GRACHA) == 2 then + data[vi] = c_grass5 + end + end + elseif under[si] == 7 and n_temp < HITET + 0.1 then + if math.random(flora.CACCHA) == 2 then + watershed_cactus(x, y, z, area, data) + elseif math.random(flora.DRYCHA) == 2 then + data[vi] = c_dryshrub + end + elseif under[si] == 8 then + if math.random(flora.ACACHA) == 2 then + watershed_acaciatree(x, y, z, area, data) + else + data[viu] = c_wsdrygrass + if math.random(flora.GOGCHA) == 2 then + data[vi] = c_wsgoldengrass + end + end + elseif under[si] == 9 then + if math.random(flora.JUTCHA) == 2 then + watershed_jungletree(x, y, z, area, data) + else + data[viu] = c_wsgrass + if math.random(flora.JUGCHA) == 2 then + data[vi] = c_jungrass + end + end + elseif under[si] == 10 then -- dunes + if math.random(flora.DUGCHA) == 2 and y > YSAV + and biome >= 4 then + data[vi] = c_wsgoldengrass + end + elseif under[si] == 11 and n_temp > HITET then -- hot biome riverbank + if math.random(flora.PAPCHA) == 2 then + watershed_papyrus(x, y, z, area, data) + end + elseif under[si] == 12 + and n_humid > LOHUT + (math.random() - 0.5) * BLEND then -- snowy iceberg + data[vi] = c_snowblock + end + stable[si] = 0 + under[si] = 0 + elseif density < 0 and densitymid > TFOG and n_humid > FOGHUT then -- fog + data[vi] = c_wscloud + stable[si] = 0 + under[si] = 0 + elseif density < 0 and CLOUDS and y == y1 and y >= YCLOMIN then -- clouds + local xrq = 16 * math.floor((x - x0) / 16) -- quantise to 16x16 lattice + local zrq = 16 * math.floor((z - z0) / 16) + local yrq = 79 + local qixyz = zrq * 6400 + yrq * 80 + xrq + 1 -- quantised 3D index + if math.abs(nvals_fissure[qixyz]) < nvals_humid[qixyz] * 0.1 then + data[vi] = c_wscloud + end + stable[si] = 0 + under[si] = 0 + else -- air + stable[si] = 0 + under[si] = 0 + end + elseif y == y1 + 1 then -- plane of nodes above chunk + if density < 0 and y >= YWAT and under[si] ~= 0 then -- if air above fine materials + if under[si] == 1 then -- add surface nodes to chunk top layer + data[viu] = c_wsicydirt + elseif under[si] == 2 then + data[viu] = c_dirtsnow + data[vi] = c_snowblock -- snowblocks in chunk above + elseif under[si] == 3 then + data[viu] = c_dirtsnow + data[vi] = c_snowblock + elseif under[si] == 4 then + data[viu] = c_wsdrygrass + elseif under[si] == 5 then + data[viu] = c_wsgrass + elseif under[si] == 6 then + data[viu] = c_wsgrass + elseif under[si] == 8 then + data[viu] = c_wsdrygrass + elseif under[si] == 9 then + data[viu] = c_wsgrass + end + end + end + nixyz = nixyz + 1 -- increment perlinmap and voxelarea indexes along x row + nixz = nixz + 1 + vi = vi + 1 + viu = viu + 1 + end + nixz = nixz - sidelen + end + nixz = nixz + sidelen + end +end + + +-- Regenerate chunk by chat command. Dependant on chunksize = 5. + +minetest.register_chatcommand("regen",{ + description = "Regenerate player's current mapchunk", + privs = {server = true, rollback = true}, + func = function(name, params) + local t1 = os.clock() + + local player = minetest.get_player_by_name(name) + local pos = player:getpos() + local plax = math.floor(pos.x + 0.5) + local play = math.floor(pos.y + 0.5) + local plaz = math.floor(pos.z + 0.5) + local x0 = (80 * math.floor((plax + 32) / 80)) - 32 + local y0 = (80 * math.floor((play + 32) / 80)) - 32 + local z0 = (80 * math.floor((plaz + 32) / 80)) - 32 + local x1 = x0 + 79 + local y1 = y0 + 79 + local z1 = z0 + 79 + + if y0 < YMIN or y1 > YMAX then + return + end + + print ("[watershed] regenerate mapchunk") + + local vm = minetest.get_voxel_manip() + local pos1 = {x = x0, y = y0 - 1, z = z0} + local pos2 = {x = x1, y = y1 + 1, z = z1} + local emin, emax = vm:read_from_map(pos1, pos2) + local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax}) + local data = vm:get_data() + + watershed_chunkgen(x0, y0, z0, x1, y1, z1, area, data) + + vm:set_data(data) + vm:write_to_map() + vm:update_map() + + local chugent = math.ceil((os.clock() - t1) * 1000) + print ("[watershed] "..chugent.." ms") + end +}) + + +-- On generated function + +minetest.register_on_generated(function(minp, maxp, seed) + if minp.y < YMIN or maxp.y > YMAX then + return + end + + local t1 = os.clock() + + local x1 = maxp.x + local y1 = maxp.y + local z1 = maxp.z + local x0 = minp.x + local y0 = minp.y + local z0 = minp.z + + print ("[watershed] generate mapchunk minp ("..x0.." "..y0.." "..z0..")") + + local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") + local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax} + local data = vm:get_data() + + watershed_chunkgen(x0, y0, z0, x1, y1, z1, area, data) + + vm:set_data(data) + vm:calc_lighting() + vm:write_to_map(data) + vm:update_liquids() + + local chugent = math.ceil((os.clock() - t1) * 1000) + print ("[watershed] "..chugent.." ms") +end) + diff --git a/mods/watershed/license.txt b/mods/watershed/license.txt new file mode 100644 index 00000000..c73f8ae7 --- /dev/null +++ b/mods/watershed/license.txt @@ -0,0 +1,14 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. + diff --git a/mods/watershed/nodes.lua b/mods/watershed/nodes.lua new file mode 100644 index 00000000..c6b3524f --- /dev/null +++ b/mods/watershed/nodes.lua @@ -0,0 +1,647 @@ +minetest.register_node("watershed:appleleaf", { + description = "Appletree leaves", + drawtype = "allfaces_optional", + visual_scale = 1.3, + tiles = {"default_leaves.png"}, + paramtype = "light", + is_ground_content = false, + groups = {snappy=3, flammable=2, leaves=1}, + drop = { + max_items = 1, + items = { + {items = {"watershed:appling"},rarity = 20}, + {items = {"watershed:appleleaf"}} + } + }, + sounds = default.node_sound_leaves_defaults(), +}) + +minetest.register_node("watershed:appling", { + description = "Appletree sapling", + drawtype = "plantlike", + visual_scale = 1.0, + tiles = {"default_sapling.png"}, + inventory_image = "default_sapling.png", + wield_image = "default_sapling.png", + paramtype = "light", + walkable = false, + is_ground_content = false, + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} + }, + groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1}, + sounds = default.node_sound_leaves_defaults(), +}) + +minetest.register_node("watershed:acaciatree", { + description = "Acacia tree", + tiles = {"watershed_acaciatreetop.png", "watershed_acaciatreetop.png", "watershed_acaciatree.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {tree=1,choppy=2,oddly_breakable_by_hand=1,flammable=2}, + sounds = default.node_sound_wood_defaults(), + on_place = minetest.rotate_node +}) + +minetest.register_node("watershed:acacialeaf", { + description = "Acacia leaves", + drawtype = "allfaces_optional", + visual_scale = 1.3, + tiles = {"watershed_acacialeaf.png"}, + paramtype = "light", + is_ground_content = false, + groups = {snappy=3, flammable=2, leaves=1}, + drop = { + max_items = 1, + items = { + {items = {"watershed:acacialing"},rarity = 20}, + {items = {"watershed:acacialeaf"}} + } + }, + sounds = default.node_sound_leaves_defaults(), +}) + +minetest.register_node("watershed:acacialing", { + description = "Acacia tree sapling", + drawtype = "plantlike", + visual_scale = 1.0, + tiles = {"watershed_acacialing.png"}, + inventory_image = "watershed_acacialing.png", + wield_image = "watershed_acacialing.png", + paramtype = "light", + walkable = false, + is_ground_content = false, + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} + }, + groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1}, + sounds = default.node_sound_leaves_defaults(), +}) + +minetest.register_node("watershed:pinetree", { + description = "Pine tree", + tiles = {"watershed_pinetreetop.png", "watershed_pinetreetop.png", "watershed_pinetree.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {tree=1,choppy=2,oddly_breakable_by_hand=1,flammable=2}, + sounds = default.node_sound_wood_defaults(), + on_place = minetest.rotate_node +}) + +minetest.register_node("watershed:needles", { + description = "Pine needles", + drawtype = "allfaces_optional", + visual_scale = 1.3, + tiles = {"watershed_needles.png"}, + paramtype = "light", + is_ground_content = false, + groups = {snappy=3}, + drop = { + max_items = 1, + items = { + {items = {"watershed:pineling"},rarity = 20}, + {items = {"watershed:needles"}} + } + }, + sounds = default.node_sound_leaves_defaults(), +}) + +minetest.register_node("watershed:pineling", { + description = "Pine sapling", + drawtype = "plantlike", + visual_scale = 1.0, + tiles = {"watershed_pineling.png"}, + inventory_image = "watershed_pineling.png", + wield_image = "watershed_pineling.png", + paramtype = "light", + walkable = false, + is_ground_content = false, + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} + }, + groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1}, + sounds = default.node_sound_leaves_defaults(), +}) + +minetest.register_node("watershed:jungleleaf", { + description = "Jungletree leaves", + drawtype = "allfaces_optional", + visual_scale = 1.3, + tiles = {"default_jungleleaves.png"}, + paramtype = "light", + is_ground_content = false, + groups = {snappy=3, flammable=2, leaves=1}, + drop = { + max_items = 1, + items = { + {items = {"watershed:jungling"},rarity = 20}, + {items = {"watershed:jungleleaf"}} + } + }, + sounds = default.node_sound_leaves_defaults(), +}) + +minetest.register_node("watershed:jungling", { + description = "Jungletree sapling", + drawtype = "plantlike", + visual_scale = 1.0, + tiles = {"default_junglesapling.png"}, + inventory_image = "default_junglesapling.png", + wield_image = "default_junglesapling.png", + paramtype = "light", + walkable = false, + is_ground_content = false, + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} + }, + groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1}, + sounds = default.node_sound_leaves_defaults(), +}) + +minetest.register_node("watershed:dirt", { + description = "Dirt", + tiles = {"default_dirt.png"}, + is_ground_content = false, + groups = {crumbly=3,soil=1}, + drop = "default:dirt", + sounds = default.node_sound_dirt_defaults(), +}) + +minetest.register_node("watershed:icydirt", { + description = "Icy dirt", + tiles = {"watershed_icydirt.png"}, + is_ground_content = false, + groups = {crumbly=1}, + drop = "default:dirt", + sounds = default.node_sound_dirt_defaults({ + footstep = {name="default_snow_footstep", gain=0.15}, + dug = {name="default_snow_footstep", gain=0.45}, + }), +}) + +minetest.register_node("watershed:grass", { + description = "Grass", + tiles = {"default_grass.png", "default_dirt.png", "default_grass.png"}, + is_ground_content = false, + groups = {crumbly=3,soil=1}, + drop = "default:dirt", + sounds = default.node_sound_dirt_defaults({ + footstep = {name="default_grass_footstep", gain=0.25}, + }), +}) + +minetest.register_node("watershed:redstone", { + description = "Red stone", + tiles = {"default_desert_stone.png"}, + is_ground_content = false, + groups = {cracky=3}, + drop = "watershed:redcobble", + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("watershed:redcobble", { + description = "Red cobblestone", + tiles = {"watershed_redcobble.png"}, + is_ground_content = false, + groups = {cracky=3, stone=2}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("watershed:stone", { + description = "Stone", + tiles = {"default_stone.png"}, + is_ground_content = false, + groups = {cracky=3}, + drop = "default:cobble", + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("watershed:cactus", { + description = "Cactus", + tiles = {"default_cactus_top.png", "default_cactus_top.png", "default_cactus_side.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {snappy=1,choppy=3,flammable=2}, + drop = "default:cactus", + sounds = default.node_sound_wood_defaults(), + on_place = minetest.rotate_node +}) + +minetest.register_node("watershed:goldengrass", { + description = "Golden grass", + drawtype = "plantlike", + tiles = {"watershed_goldengrass.png"}, + inventory_image = "watershed_goldengrass.png", + wield_image = "watershed_goldengrass.png", + paramtype = "light", + walkable = false, + buildable_to = true, + is_ground_content = false, + groups = {snappy=3,flammable=3,flora=1,attached_node=1}, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}, + }, +}) + +minetest.register_node("watershed:drygrass", { + description = "Dry grass", + tiles = {"watershed_drygrass.png"}, + is_ground_content = false, + groups = {crumbly=1,soil=1}, + drop = "default:dirt", + sounds = default.node_sound_dirt_defaults({ + footstep = {name="default_grass_footstep", gain=0.4}, + }), +}) + +minetest.register_node("watershed:permafrost", { + description = "Permafrost", + tiles = {"watershed_permafrost.png"}, + is_ground_content = false, + groups = {crumbly=1}, + drop = "default:dirt", + sounds = default.node_sound_dirt_defaults(), +}) + +minetest.register_node("watershed:vine", { + description = "Jungletree vine", + drawtype = "airlike", + paramtype = "light", + walkable = false, + climbable = true, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + groups = {not_in_creative_inventory=1}, +}) + +minetest.register_node("watershed:freshice", { + description = "Fresh ice", + tiles = {"watershed_freshice.png"}, + is_ground_content = false, + paramtype = "light", + groups = {cracky=3}, + sounds = default.node_sound_glass_defaults(), +}) + +minetest.register_node("watershed:cloud", { + description = "Cloud", + drawtype = "glasslike", + tiles = {"watershed_cloud.png"}, + paramtype = "light", + is_ground_content = false, + sunlight_propagates = true, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + post_effect_color = {a=23, r=241, g=248, b=255}, +}) + +minetest.register_node("watershed:luxore", { + description = "Lux ore", + tiles = {"watershed_luxore.png"}, + paramtype = "light", + light_source = 14, + groups = {cracky=3}, + drop = "watershed:luxcrystal 8", + sounds = default.node_sound_glass_defaults(), +}) + +minetest.register_node("watershed:light", { + description = "Light", + tiles = {"watershed_light.png"}, + paramtype = "light", + light_source = 14, + groups = {cracky=3}, + sounds = default.node_sound_glass_defaults(), +}) + +minetest.register_node("watershed:acaciawood", { + description = "Acacia wood planks", + tiles = {"watershed_acaciawood.png"}, + groups = {choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1}, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node("watershed:pinewood", { + description = "Pine wood planks", + tiles = {"watershed_pinewood.png"}, + groups = {choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1}, + sounds = default.node_sound_wood_defaults(), +}) + + + +minetest.register_node("watershed:freshwater", { + description = "Freshwater source", + inventory_image = minetest.inventorycube("watershed_freshwater.png"), + drawtype = "liquid", + tiles = { + { + name="watershed_freshwateranim.png", + animation={type="vertical_frames", + aspect_w=16, aspect_h=16, length=2.0} + } + }, + special_tiles = { + { + name="watershed_freshwateranim.png", + animation={type="vertical_frames", + aspect_w=16, aspect_h=16, length=2.0}, + backface_culling = false, + } + }, + alpha = WATER_ALPHA, + paramtype = "light", + is_ground_content = false, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + drop = "", + drowning = 1, + liquidtype = "source", + liquid_alternative_flowing = "watershed:freshwaterflow", + liquid_alternative_source = "watershed:freshwater", + liquid_viscosity = WATER_VISC, + liquid_renewable = false, + liquid_range = 2, + post_effect_color = {a=64, r=100, g=150, b=200}, + groups = {water=3, liquid=3, puts_out_fire=1}, +}) + +minetest.register_node("watershed:freshwaterflow", { + description = "Flowing freshwater", + inventory_image = minetest.inventorycube("watershed_freshwater.png"), + drawtype = "flowingliquid", + tiles = {"watershed_freshwater.png"}, + special_tiles = { + { + image="watershed_freshwaterflowanim.png", + backface_culling=false, + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.8} + }, + { + image="watershed_freshwaterflowanim.png", + backface_culling=true, + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.8} + }, + }, + alpha = WATER_ALPHA, + paramtype = "light", + paramtype2 = "flowingliquid", + is_ground_content = false, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + drop = "", + drowning = 1, + liquidtype = "flowing", + liquid_alternative_flowing = "watershed:freshwaterflow", + liquid_alternative_source = "watershed:freshwater", + liquid_viscosity = WATER_VISC, + liquid_renewable = false, + liquid_range = 2, + post_effect_color = {a=64, r=100, g=150, b=200}, + groups = {water=3, liquid=3, puts_out_fire=1, not_in_creative_inventory=1}, +}) + +minetest.register_node("watershed:lava", { + description = "Lava source", + inventory_image = minetest.inventorycube("default_lava.png"), + drawtype = "liquid", + tiles = { + {name="default_lava_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}} + }, + special_tiles = { + { + name="default_lava_source_animated.png", + animation={type="vertical_frames", + aspect_w=16, aspect_h=16, length=3.0}, + backface_culling = false, + } + }, + paramtype = "light", + light_source = 14, + is_ground_content = false, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + drop = "", + drowning = 1, + liquidtype = "source", + liquid_alternative_flowing = "watershed:lavaflow", + liquid_alternative_source = "watershed:lava", + liquid_viscosity = LAVA_VISC, + liquid_renewable = false, + liquid_range = 2, + damage_per_second = 8, + post_effect_color = {a=192, r=255, g=64, b=0}, + groups = {lava=3, liquid=2, hot=3, igniter=1}, +}) + +minetest.register_node("watershed:lavaflow", { + description = "Flowing lava", + inventory_image = minetest.inventorycube("default_lava.png"), + drawtype = "flowingliquid", + tiles = {"default_lava.png"}, + special_tiles = { + { + image="default_lava_flowing_animated.png", + backface_culling=false, + animation={type="vertical_frames", + aspect_w=16, aspect_h=16, length=3.3} + }, + { + image="default_lava_flowing_animated.png", + backface_culling=true, + animation={type="vertical_frames", + aspect_w=16, aspect_h=16, length=3.3} + }, + }, + paramtype = "light", + paramtype2 = "flowingliquid", + light_source = 14, + is_ground_content = false, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + drop = "", + drowning = 1, + liquidtype = "flowing", + liquid_alternative_flowing = "watershed:lavaflow", + liquid_alternative_source = "watershed:lava", + liquid_viscosity = LAVA_VISC, + liquid_renewable = false, + liquid_range = 2, + damage_per_second = 8, + post_effect_color = {a=192, r=255, g=64, b=0}, + groups = {lava=3, liquid=2, hot=3, igniter=1, not_in_creative_inventory=1}, +}) + +minetest.register_node("watershed:mixwater", { + description = "Mixed water source", + inventory_image = minetest.inventorycube("watershed_mixwater.png"), + drawtype = "liquid", + tiles = { + { + name="watershed_mixwateranim.png", + animation={type="vertical_frames", + aspect_w=16, aspect_h=16, length=2.0} + } + }, + special_tiles = { + { + name="watershed_mixwateranim.png", + animation={type="vertical_frames", + aspect_w=16, aspect_h=16, length=2.0}, + backface_culling = false, + } + }, + alpha = WATER_ALPHA, + paramtype = "light", + is_ground_content = false, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + drop = "", + drowning = 1, + liquidtype = "source", + liquid_alternative_flowing = "watershed:mixwaterflow", + liquid_alternative_source = "watershed:mixwater", + liquid_viscosity = WATER_VISC, + liquid_renewable = false, + liquid_range = 2, + post_effect_color = {a=64, r=100, g=120, b=200}, + groups = {water=3, liquid=3, puts_out_fire=1}, +}) + +minetest.register_node("watershed:mixwaterflow", { + description = "Flowing mixed water", + inventory_image = minetest.inventorycube("watershed_mixwater.png"), + drawtype = "flowingliquid", + tiles = {"watershed_mixwater.png"}, + special_tiles = { + { + image="watershed_mixwaterflowanim.png", + backface_culling=false, + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.8} + }, + { + image="watershed_mixwaterflowanim.png", + backface_culling=true, + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.8} + }, + }, + alpha = WATER_ALPHA, + paramtype = "light", + paramtype2 = "flowingliquid", + is_ground_content = false, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + drop = "", + drowning = 1, + liquidtype = "flowing", + liquid_alternative_flowing = "watershed:mixwaterflow", + liquid_alternative_source = "watershed:mixwater", + liquid_viscosity = WATER_VISC, + liquid_renewable = false, + liquid_range = 2, + post_effect_color = {a=64, r=100, g=120, b=200}, + groups = {water=3, liquid=3, puts_out_fire=1, not_in_creative_inventory=1}, +}) + +-- Items + +minetest.register_craftitem("watershed:luxcrystal", { + description = "Lux crystal", + inventory_image = "watershed_luxcrystal.png", +}) + +-- Crafting + +minetest.register_craft({ + type = "cooking", + output = "default:desert_stone", + recipe = "watershed:redcobble", +}) + +minetest.register_craft({ + output = "watershed:light 8", + recipe = { + {"default:glass", "default:glass", "default:glass"}, + {"default:glass", "watershed:luxcrystal", "default:glass"}, + {"default:glass", "default:glass", "default:glass"}, + }, +}) + +minetest.register_craft({ + output = "watershed:acaciawood 4", + recipe = { + {"watershed:acaciatree"}, + } +}) + +minetest.register_craft({ + output = "watershed:pinewood 4", + recipe = { + {"watershed:pinetree"}, + } +}) + +-- Buckets + +bucket.register_liquid( + "watershed:freshwater", + "watershed:freshwaterflow", + "watershed:bucket_freshwater", + "watershed_bucketfreshwater.png", + "WS Fresh Water Bucket" +) + +bucket.register_liquid( + "watershed:lava", + "watershed:lavaflow", + "watershed:bucket_lava", + "bucket_lava.png", + "WS Lava Bucket" +) + +-- Fuel + +minetest.register_craft({ + type = "fuel", + recipe = "watershed:bucket_lava", + burntime = 60, + replacements = {{"watershed:bucket_lava", "bucket:bucket_empty"}}, +}) + +-- Register stairs and slabs + +stairs.register_stair_and_slab("acaciawood", "watershed:acaciawood", + {snappy=2,choppy=2,oddly_breakable_by_hand=2,flammable=3}, + {"watershed_acaciawood.png"}, + "Acaciawood stair", + "Acaciawood slab", + default.node_sound_wood_defaults()) + +stairs.register_stair_and_slab("pinewood", "watershed:pinewood", + {snappy=2,choppy=2,oddly_breakable_by_hand=2,flammable=3}, + {"watershed_pinewood.png"}, + "Pinewood stair", + "Pinewood slab", + default.node_sound_wood_defaults()) diff --git a/mods/watershed/textures/watershed_acacialeaf.png b/mods/watershed/textures/watershed_acacialeaf.png new file mode 100644 index 0000000000000000000000000000000000000000..08cf3998c0c8d47ae63ddcf51878b725faec497e GIT binary patch literal 340 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPggK7CvSv7MGoE(}6-)JY5_^EKaYT zq$|{HAkZp5w`r}@W3A+()`T67MU&?&INtG?!?b|aN0qPlkkCfaxvjEY%GsaHZ~p!E z_O#UcjJZW$-cFEQzH*K7Gd=e}*AKQX63bWSx1V8iWhgj&bO&R@nG@-ecP)I6_ZLr3 zmJAkH6TB}~XH`e)9ZiOYlNGjEMROm_2y}Zas;e9j^6`Cdsh2V9%#VM6<+!Zj&n|JB z*ml6e*Gxm}b;YgaA^SgeEzw^mY*JUQ@ICYJ`Yzrsl~&#^x%0J7o*eJ?B(l$A{eC`g e>b@O5A6QpKmzL{@-S7eWkHOQ`&t;ucLK6V4LxIx( literal 0 HcmV?d00001 diff --git a/mods/watershed/textures/watershed_acacialing.png b/mods/watershed/textures/watershed_acacialing.png new file mode 100644 index 0000000000000000000000000000000000000000..07170a03d4c81eeb0916263ec90d2d4b72326908 GIT binary patch literal 359 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPq8#l9sI!}?%bfC}|PZ!4!i_^&o3#CHpIZX;h`|j0S*NUspZZe7`b&YyDy=YI~pCvE66Yh%O2Hyj^}xBl)wo9a@{D8{VP z%6Nu*;^(jbo~Nozn8tTO^k7Vbzp?TiU4Eb;)_C#QaYseSe5kLJ6g7?zz$d&nHSBmn4t22WQ%mvv4FO#s8{k+1*& literal 0 HcmV?d00001 diff --git a/mods/watershed/textures/watershed_acaciatree.png b/mods/watershed/textures/watershed_acaciatree.png new file mode 100644 index 0000000000000000000000000000000000000000..169823d41612d29e16c7faa44baae5d51b842de3 GIT binary patch literal 682 zcmV;b0#*HqP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2i^n? z2^1XGbQyO500JsWL_t(I%Po^jj@(ELL?4+SWvZ%e_(Zdt?cDzk#sEfFNy;DTg=$9- zAQ=&ikpKSu$2CN1t!RjplF2EvY?1QD|G$6p^Vd&auY*zwL50`rK*V{!->3mGXL_HQ zP0Wlj2aXeia=c&Ul!-ACLI6?bnurQ4LscL~MWcc!tu@A6m>K4VnbCV^uZ6W1$9Vv- z<^lmll$au_O3;A2v({qGg*l{{Xst2lWQ~ED0elXC3eFspQVPo!b4+54_t5Cn=NHHO zAcVlxE*vL?z!(bvb$7;GhzM&f93iJjyG}+Q)V+czSL@8y*-PQ-9b5BWfG9}=DF&|N zz};_ds+{LZ*)oDtw#?$DH+n-wQ9#8VjY_*3W)ruChR9YQxH~R#i)K#B+oxVETNvDL zOet|37h9?H-ocF&!>4~RTPNqtUJI=c9?vh_*9QTPi*vkQl)9q|=FrZ@^ZDdF-;6l` zh$%Dsq}EEz$vWl2W)uRNy>L%D(gc z{mt|1$#GnS7{FoMD*)GZ0pRXj=RvI%$I)fZ`F^uMc6#fyF;L+)&RlG@^7!$^abBd9 zsC#A1MQPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2i^n? z2_zerR=Otu00LV{L_t(I%YBo}iW5N;hQF$=PSWl4WG)@eOmsjL2Nm3lYu`iNxYC_2 zUAS_od%*{BA-EPC5EK;^FE~otOkyW}tLiEjne>b!cs6zTDGulS7jgUMHOHY!h6w<1 zFK+rpEwH#3H<$vrfBk9$m@Gww5hhFLACB~g>)w;6^8o;_Zarjh`2>2VsejK99Ur;e z!B&=*uL!KeEO$_+HhKH(4Hxg;AQ>hH1GcX8nGQ2X-^U#51_)hIeH^2F&|#aI-@;2u zg1W=G3u~AxCGN$jWSC&Gl-lzdeHs&QA4jb%gO#vlP^&A5c7P`Z*1`1UYrK9)H;m>R z#JzZaTTxLffi;Hln=h=KJ&FD~L1!h(DokAwZfzojXt)9nHgMW8nK{~{jJy&=!Y8=2 zjSzz3*9iT2f|*SbN`SPeFe2{7$OQ*_lG0ljbT_+%fXORZ+vH4p-NWvDAVPAq0g1V+^_0*xXW%9OFW==X}ohBu;Cx zso|KJo2v1F3L~sB7;CAslC41pTT7OfBtc!X=^RRVqCQFf%f{nNk4?>^g3!i{96STMm$O!Ra#M1mO%vl4g{Vf#L``DbLvc& zR(~1i94~f8P4F5kKX`oSpCC1f+s78~U_Vq1iT9p7{cn^H$M|TR{{S1^LDaALQ)vJI N002ovPDHLkV1hvjGz9QL70(Y)*K0-AbW|YuPggKW_b=Z`PctV`+-8IJY5_^EKZ-D zw3qjgfk5kgTNp(cgNv;k(p^48eq|`ShTX(rIhW~uO z_xHP+1M8hb&Q-29?fZ2j(9}9esj>G?{k#|n?PXG{V6ef zzfTBaVwe(S@lO8gvNSf~qajW{0-M%LrOXZWI{PDGRQpA59?cFE`?326!#O4Q VpNY@^oB{fZ!PC{xWt~$(6994}g0BDo literal 0 HcmV?d00001 diff --git a/mods/watershed/textures/watershed_cloud.png b/mods/watershed/textures/watershed_cloud.png new file mode 100644 index 0000000000000000000000000000000000000000..239dedef86c52eab7f0627bed9f86c683d31f965 GIT binary patch literal 136 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zj({-ZRBb+KpdfpRr>`sfJr+)8Wya+V$3a3;o-U3d8t0R1e!Y@s)@bP0l+XkKts)~) literal 0 HcmV?d00001 diff --git a/mods/watershed/textures/watershed_drygrass.png b/mods/watershed/textures/watershed_drygrass.png new file mode 100644 index 0000000000000000000000000000000000000000..a2c553a3cb340199f92a9af4b4c7f109bb06a93a GIT binary patch literal 771 zcmV+e1N{7nP)Px#32;bRa{vGf6951U69E94oEQKA00(qQO+^RY2@w{Qg^QwIbI{ z&Kac?eog%R`4cG>uJ@T-GsnSkdOxGJ#I+3ogKN;!;`#B*6CoF#zkUND*;>ouBW5EL4ofN2O6W1QZP8jakC|t%=vO7mr83C zo$a{ID{{IA#_P=NJ$-99ZXH8s8K;@&uWxLfWet&eO&HzM+m4(wgKf}4BXg;oJ}zk0 zU>nEK4cwNM#Yc|YEmFYScqN2HPL-T1t{M2aE{Ix@)PhlllnX{HQc8UL7+F(fu$Ghy z$|!0T>^2>x7JLlUToFQ`_ijKbK^B7Bo+*t@G&jS!85cDzb0lMSbd~3io>pF zoIKjOhMQlZfX{`L5=PDlD)SofA@MLMHrB9&h*E;b{hm?^J_Pj3KO=o-u&v|h1hsZt zmW7wUU)eg#uRlB?wdC$2%m2{oBli%INOVO|s^q>bw5>r1$!_Rzwn0lt-x{O@StQfs z2_drP%o0~(%E;|7V6^XnV0?>9;X zJ0|>whJ^ZMiNp)IzHb zZKLR2$8A|TPj^C2^tQ#C23<3*v&fJFAp~;Cq>=!TQgRwE7-L8=QA*+Iu;XF3p^8l3 z8BC+tID`J_yCZ9ilv23OE7U^oTAa1KUnXLy?1qlsc7za6+Hturq?Bk|fwYaL(a;!; z5Q6>2G2SLh0bvwt%EX#M6z=Q7dAy*cpi)^v=3k1}dK(T07is_i002ovPDHLkV1m$b BUZMa1 literal 0 HcmV?d00001 diff --git a/mods/watershed/textures/watershed_freshice.png b/mods/watershed/textures/watershed_freshice.png new file mode 100644 index 0000000000000000000000000000000000000000..bc1c285da43d381f354e48ea62bf03a390873d42 GIT binary patch literal 780 zcmV+n1M~ceP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01m?d01m?e$8V@)00007bV*G`2i^n- z0x$)5d{4pv00N9jL_t(I%RQ4#ZyZGshM(&B?g2z>oK09`giw6q;GhJ{AdoEo%?R;F zA`TEt#KCKh;gs0PCQ5dJXs4&=qq{f^>yrA^Ri&z@-d7%7L{(L?MA*g{!MBbNYD*s= zH4t@rMy9`Q7~eWXgs(n!w7z50IF5E4)>_60-yaBFKad*GFfa@QWo5}ri-=&#%90vb ztSun~PVdz$)>H9b8F>7xK~TmBKYWpsWf@Un{-IFY3e)+PF+%5C&JJtNua$A=xmzo% zF2Pz$S>zn;IDUDd41GtQ!1X^pZ8uaZ{_Vi3RieVlzHqs&Ffsu{;QhQ-+`^bsdykQc$zp8@QE|@k-Dkp|>k^n4m@!TY133M%;QT5O z74o9wWMBCCuLj>b5+j@));zgVHjU$WE|ir;e!7g>^#c!PBNwX*-#W_5aPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2i^l8 z2NoAGKFo6f00K!#L_t(I%RQ6bcHA}$gg=0!DD6)+b<#R^k_Yc2k(o;bDF$A77J zC6OY~3pK&*0A~Qqj9h;C`X>OYNJ@Oj9e2&~rGgn=D=Z5#3|wzF92aA$g>BBfzP_Tm z-9d~lv9@h@LJKXBZ#1?d`f`_b5421 z%XsD=K)TFTPNWowdl61;0W)HkxsFP3M|00@GcHs)#Rz6FPb*O=+=jO#6=D?lkh@=N z{yh~W1l|YbheH$y?pO%W5BNMojBB$)yr~VFrsTK8|350JU&uk?X!g+<7VR{BXaju-Ot* z+K6KZxXhHPHD?8wQF+j%8WXs0z8~B1Qz~aWPt%G2qZ=p6fsaR!MLa vFf)9qhzMu^;L$;wbCHC{|3mj;2Ft>Kqp3wXzLE+_00000NkvXXu0mjfwsbHJ literal 0 HcmV?d00001 diff --git a/mods/watershed/textures/watershed_freshwateranim.png b/mods/watershed/textures/watershed_freshwateranim.png new file mode 100644 index 0000000000000000000000000000000000000000..ec359339e268dbd3785178e197ba83eb040760c8 GIT binary patch literal 4927 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 literal 0 HcmV?d00001 diff --git a/mods/watershed/textures/watershed_freshwaterflowanim.png b/mods/watershed/textures/watershed_freshwaterflowanim.png new file mode 100644 index 0000000000000000000000000000000000000000..bb1b2a3d389118a72fd3dba86160e3fbad4daaf2 GIT binary patch literal 5819 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 literal 0 HcmV?d00001 diff --git a/mods/watershed/textures/watershed_light.png b/mods/watershed/textures/watershed_light.png new file mode 100644 index 0000000000000000000000000000000000000000..43c1444ea332680eca2171ef5ad2e36f5403cb29 GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|I14-?iy0WW zg+Z8+Vb&Z8pdfpRr>`sfT~=N(VavMxPnH0MbUj@hLo7}w|M~y=PdytK!{cv9dH&nV voV=o2Hm|X>(a9j|zzW92Yzj}^ym%NG+>E(c+4+Bg%wq6#^>bP0l+XkKD1R!O literal 0 HcmV?d00001 diff --git a/mods/watershed/textures/watershed_luxcrystal.png b/mods/watershed/textures/watershed_luxcrystal.png new file mode 100644 index 0000000000000000000000000000000000000000..a36c93669bef6966b13ed2696f88f8609dd6f72f GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|I14-?iy0WW zg+Z8+Vb&Z8pdfpRr>`sfT~>Yu3;xpUvt@xoiJmTwAr_~T6C_x-u>P-~``_P#SJ`lu z`sfT~0YZF2&?sMj%s8db&7}+^pJ-xAX63eLl`7XMJM#B;J(Q)!*~7-u*hF$TGUb8uxfy1^uZ!0UNo!;ssx=dKu372Oa%ypp!7WRU zzI3(|S2G-aZnCR)W(mLddjIS8-47pS?%L$Ou)iq(n`Oo+(I4gOfSzLTboFyt=akR{ E087Dmt^fc4 literal 0 HcmV?d00001 diff --git a/mods/watershed/textures/watershed_mixwater.png b/mods/watershed/textures/watershed_mixwater.png new file mode 100644 index 0000000000000000000000000000000000000000..3b55c5f66f1f1ef780a89dedbd9f9e6a454626e1 GIT binary patch literal 716 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 J)|vYg{tMfXn)Uzy literal 0 HcmV?d00001 diff --git a/mods/watershed/textures/watershed_mixwaterflowanim.png b/mods/watershed/textures/watershed_mixwaterflowanim.png new file mode 100644 index 0000000000000000000000000000000000000000..536acc535b695c3d493e202c81c057964dc176b6 GIT binary patch literal 5851 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 literal 0 HcmV?d00001 diff --git a/mods/watershed/textures/watershed_needles.png b/mods/watershed/textures/watershed_needles.png new file mode 100644 index 0000000000000000000000000000000000000000..b8140575bf6a587ec533161d2880558b3ffe497d GIT binary patch literal 860 zcmV-i1Ec(jP)>zkBE9dBmQFW4mb^nu?}Tg+d4$Bv`-}*dTVS`8WI|7A)Eoh$vE3 zQDsw9r?s8NV|%dYap!Sa1c|dhNBYh=g7a7(lm+j5E+>-#O{clZ3bM3dJoH(-m&vQc zDLakYlmJM8QK-3H<=o~KeIE`2m!E$;{q#C3IR5rXk6Z`2s!8jHV9!C%OO$Hiq_3qD zSjf?kw$nVB49F_Ux>EeQT3y~NOMdz8EL3$%XBa#k4;b$C=vvJncJX~1!GH2TOLS2- zh*YuvBxG^BgH_AXX~LW37N!Np$fk7+jCTcXWO4i`#z@kxHz_f6oPeRfoF1clOad3$K$S`5nxFHvB`9nQEN@q2h)@=uc!>j{`er) zzu$N6RJ?B*41r{N+M0L`o- z>h~bAXavljzZYDj!nB2;S`_HWqq*mD^=^&p?f_V3cW+A~mu!=v>XymSXP#GB=ZSt0 z`^a2(v|6yu6+cADS>ReEo{ej?lwC*s#aL%$jj$vdn7^2bec$0Da^9p{gnvHN^-Yc% z^)Q7X+!l2EeagHhN0Vd)tAUG+pwxG>^bE;A5%lF@W m{J^nI0N&0r4xdG6Q}QphLRcP}nEqP;0000Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2i*(| z2rdo}{(^e|00RL@L_t(I%Po>iQ`=SmM$di7wk*r$RYO8}C4^_mq>q#`Nt;a;ndwXy zU3J;N+fD*WXs0bH1Snw3k_?uGEo5|W7xV|5#dp3VetiAPHm4@gN^M#WK1rxM;P>vK+lMH_O4{5n5@q(kP{f;x0$Wr#M>iXlVh@ zbIFDoe;xe8%ybi{`w}xoCF~KfHQr7v~>fjU^xDwAvv6)>@1)6sBNyW*R9a zI7F{4KjiS!30~D@bNw-6jXJLD@_zphCMPCI(*f!A0I%i|bV9tUi?x=y*?WwSHPAu` zj4`aOEYk`?ZVN+tJwOUc7{(Z5sCrc}27p!&qLe~An&XpGq_I#cmH73|9!WpN8Vf+9 z;nPd{Jl}bS?|ED%eR@fsFQ0x+mSvPn4y95F8AdUS3-grAWxCxf3R93I38PWL_OmaD z;x02YP3})O$+C=IuaE1xbUG1ADWtWQ!%rs+vl|TX_s2upL4>uIN~J;=U2^d8h~aQ} z2Zj+fuS&ZUQ4|F_in~ZDsgz4R+1kL-iue0}l3u5@S^>u1Z9ltc|L<84ia$US48rbDccTab1_qja9@iKmTMK zzDJUzjE&VfJG;Ola9x+66C#8_N{OQtNk3(BVjN>(WqFYxjL`tS{xxCLCFq3I{TjwX z>;FQL^6oYzdAqldTPf2DLf-6t;L*|oQVBsA##n1vUtc9j2jrt$wl-JsY98&NgE0nc zEseU*%E~g|KmUfBS0(6#cM{!7nZj7Cu{_;cqcE1;cfa42=4iq&ChlJ1C_$cOq=Nz9 zZhy`0-Usw|FLoG>MucI^(eWuYuS&Byg%E;X(g#3ELA6@t;nF;(XBS8*iQ+5n-<#n- Xz}kFTciJ;M00000NkvXXu0mjfcFv7^ literal 0 HcmV?d00001 diff --git a/mods/watershed/textures/watershed_pineling.png b/mods/watershed/textures/watershed_pineling.png new file mode 100644 index 0000000000000000000000000000000000000000..cd8167a25dd52a3c8d84417984165294e2962fa3 GIT binary patch literal 406 zcmV;H0crk;P)e-vd2O3fm9*zeI zmMTymd-}3FyF0V<0skI{YoG6$$ylE0hXe(-eFp&0_8p>}=g*l01)^fmcS>`cITtT{RREdB3zwEp~pWNQY**w$C$-K`jV-xOn?P_ z`J-{iBrcvrx+7k_2sCWsjnISwoQ@ltHgWPG7JZ^AnxVH&cm}a&F`bRacLMu15ePx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2i^n@ z11b`4D+M(G00K2hL_t(I%RQ4zjx1FS1;f7I%&h8uunnecfc>uoBqZpr%({OwNMLN~ zC>+O@-+ukY)JL{`BX~zjiJT&RPGZXZ`N!{k{`?c?>m=n3C&GE27{>WJ(FKGU=&jS| zWUWPQ9TCGj<^298$B1_x=NyRA$HY0o=0sH>B!@ahL@1@uduPtcvc)u`l*WGS*qU7B z0-*N^0&3!L?hXjfv4Ckt?~?_@5dRNtwXtjgV9Qtrsx0Q5Y&p^AWcH48j#3)ER`%xy z*LmTcQfgt@!aJqb4uF~&wM`IZj>$qvG0^J8XpLjvK$KD%qc)DbQEJ211p9Y|1s|bP$sM-Rj)Kan8S#zMyvmXx(!$dGM<}y-F04y6U zTP(P1Oet`lZ{oJoS_2kN9Wh2;*F`Ih7$e7i<3FFDEE_1Gf?;BuuWugvjyfzMtK)h73Tvn`nv@M zuCtJigRj58cz!%N&o@4JFeM!a0HwBDE=GA@Y}%0gdkaMQBL96X{U>Iu*+PkpUqSwlt6I3xXQV56$wN_G0j4_yfGR^K41jENn zX@j(FU`oyz?;@(oyHt+jKvkJ$_bljt4d4;IHJTBEC#Q%4$FX5z1aY*{Q0H$lz^lK1 b!YTg%;Xz=CmniwT00000NkvXXu0mjfhT1f1 literal 0 HcmV?d00001 diff --git a/mods/watershed/textures/watershed_pinetreetop.png b/mods/watershed/textures/watershed_pinetreetop.png new file mode 100644 index 0000000000000000000000000000000000000000..9e2f8647645e47ea52f0014e6d638b7751cc6f8f GIT binary patch literal 802 zcmV+-1Ks?IP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2i^n@ z11bUQl|<_R00N>(L_t(I%WacSYb#Y8hMzO%%uFW9}?gu4*D{=o}UTkMr2ZSKiTCUa)a9~VI@>brawKc3$MulV$n4u z7*p}@{MBn+{@p2nkKUg1)7tP(p%|Q8;?o>GKc%fZ5Dxpwu)Mw|goMp-#Lc#0Tqy4P z3}sA3x7U39!Mhwiy~4E}-tG`8Mdmrd2b5Bz@_j^>lTOaKd;W~iKl=h>DwNhGqiWCb zTUWH(n%#OuR!*SX(=OKtC6Refo1{pUlJ^PoH?BCJYo0IL1A%;fK|rzlW5xL5f^=9y zfOzat#gs&5BvKJ$r2hS91QX6K&e1o`!NGRdfOkX@iN2@0`;GDZ0#|SGoh1<&-dl>J zGlUQadu{vpf=?yUd-`g}epu1BJ!2HZ#hV}!Y<-X0Y;d-QBmo>@-vW>rQ!&yduC2*W zG{e~pr4-J#tbh5A=HU+4Y;m?l2tjZy-g!nRbF?l=0A$}|o1V?GqHAhoCb88$!8;yq zex=*jL}vl;y(RjH&r*!34hQZZ3~45rPKTsfjx`mDfP7LiT`Z6?1(6Y4OZ1)?Ji;AZ zD6LCOd%*KukN2L?HTXWqS6jMWhpl$Zo?H?`Pv2Mu8oWOcDPt;Ldr}g-BY20md&cJr zVi2gokhFA+&t^!au$5sjn?i8-c8}KOf#B<9%X^(=cs#}JTdLca$WcK$C=f~_Lc}!< z#gV2sJw=X2*!$JNfiV@kR`Bf0ZwO68=sHI8V+yTNnLp!9^GhD2*gd_(U%QA)baD}G!(AYJmf#%((0_PXMQ78tYo g-#Pzx%7+7g0#Pt$?Q?}=djJ3c07*qoM6N<$f-zxgssI20 literal 0 HcmV?d00001 diff --git a/mods/watershed/textures/watershed_pinewood.png b/mods/watershed/textures/watershed_pinewood.png new file mode 100644 index 0000000000000000000000000000000000000000..fa102ce3358067055657638232d8c6d1329ef061 GIT binary patch literal 366 zcmV-!0g?WRP)Px#32;bRa{vGi!vFvd!vV){sAK>D00(qQO+^RZ1P&4u8%ox1s{jB207*naR4C7N zQax|NKn#63S+GPj6y+8ab&nYOC;Bt`&-f>ux|OX1VsBA|bQT|pSgr#wm{`Z<`X-<4 zd-k)Pt(NcTam62i3?sD#;t|lZE%lMxTJ4|p$IIdkz}amOAlrQ{_0hE)#*F8P1psN1 z@jQ8q0p*Z|gy!J5sOl&d*13#JF=+1^(RA8A^s1u!88r6_)9TfDzKlyD%WW+x#WMs& zNnOk6QzuV}KO{rQW4SSOxO8?KtuC^X&>Y&k2ECwgqXXQzXlCbOKfmkGqWZTzO_qqtK*`FlA^JhePrIdus?Xq||)dCKzBx#;w<2RV4A zA)|KP8Jffd(`rlNPrrdf&xiGS?L|NbDG?+2At)=Qp3G!%Q(%Q!&|P1i`kR z2bum}eBJwkwwD0qN;O>gtqWuZ`au@vx{l*tVR^>DySx-XtxY+OE_~VjcbL3;bu1Eb zlRv_(1Ktw{rQ=|^BIE1l3xU?7!SUu|pAft!m5*z7==$b1EVeRhAy~8CJl7ewBb#H~ zhza|IF;@6J&QHK*bC3$b6O<~~+L4qt4t8S@er$P>@!f|{@|YH%%>EOoi@3D$^60