Disable spawn, clear cloud options. Drift by 4 nodes. ABM node column at each corner. 48x48 rain area

This commit is contained in:
paramat 2014-09-27 10:00:57 +01:00
parent 0292acf978
commit ad70a57976
2 changed files with 171 additions and 93 deletions

View File

@ -1,4 +1,4 @@
rain 0.1.3 by paramat rain 0.1.4 by paramat
For latest stable Minetest back to 0.4.8 For latest stable Minetest back to 0.4.8
Depends default Depends default
Licenses: code WTFPL, textures CC BY-SA Licenses: code WTFPL, textures CC BY-SA

262
init.lua
View File

@ -1,13 +1,18 @@
-- rain 0.1.3 by paramat -- rain 0.1.4 by paramat
-- For latest stable Minetest and back to 0.4.8 -- For latest stable Minetest and back to 0.4.8
-- Depends default -- Depends default
-- License: code WTFPL, textures CC BY-SA -- License: code WTFPL, textures CC BY-SA
-- 64x64 XZ raincloud at y = 64 -- drift by 4 nodes
-- spawns over grass in more mgv6-humid areas, also away from deserts by biome noise -- abm node column at each corner
-- fix cloud eating floatlands -- larger rain area
-- TODO
-- move 16 nodes at a time less frequently -- Parameters
local SPAWN = true -- Spawn new rainclouds in humid areas away from deserts
local CLEAR = false -- Clear rainclouds when players are near
local DEST = 0.4 -- Desert noise threshold
local HUMT = -2 -- Humidity noise threshold
-- Nodes -- Nodes
@ -42,17 +47,42 @@ minetest.register_node("rain:rain", {
buildable_to = true, buildable_to = true,
}) })
minetest.register_node("rain:rainabm", { minetest.register_node("rain:abmne", {
description = "Rain", description = "ABM trigger NE",
drawtype = "plantlike", drawtype = "airlike",
tiles = { is_ground_content = false,
{ sunlight_propagates = true,
name="rain_rain.png", walkable = false,
animation={type="vertical_frames", pointable = false,
aspect_w=16, aspect_h=16, length=0.2} diggable = false,
} buildable_to = true,
}, })
paramtype = "light",
minetest.register_node("rain:abmnw", {
description = "ABM trigger NW",
drawtype = "airlike",
is_ground_content = false,
sunlight_propagates = true,
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
})
minetest.register_node("rain:abmse", {
description = "ABM trigger SE",
drawtype = "airlike",
is_ground_content = false,
sunlight_propagates = true,
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
})
minetest.register_node("rain:abmsw", {
description = "ABM trigger SW",
drawtype = "airlike",
is_ground_content = false, is_ground_content = false,
sunlight_propagates = true, sunlight_propagates = true,
walkable = false, walkable = false,
@ -67,28 +97,34 @@ minetest.register_node("rain:rainabm", {
minetest.register_abm({ minetest.register_abm({
nodenames = {"default:dirt_with_grass"}, nodenames = {"default:dirt_with_grass"},
interval = 61, interval = 11,
chance = 4096, chance = 4096,
action = function(pos, node) action = function(pos, node)
if not SPAWN then
return
end
local x = pos.x local x = pos.x
local y = pos.y local y = pos.y
local z = pos.z local z = pos.z
local desnoise = minetest.get_perlin(9130, 3, 0.5, 250) -- check biome and humidity local desnoise = minetest.get_perlin(9130, 3, 0.5, 250) -- check biome and humidity
local humnoise = minetest.get_perlin(72384, 4, 0.66, 500) local humnoise = minetest.get_perlin(72384, 4, 0.66, 500)
if not (desnoise:get2d({x=x+150,y=z+50}) < -0.4 if not (desnoise:get2d({x=x+150,y=z+50}) < DEST
and humnoise:get2d({x=x+250,y=z+250}) > 0.4) then and humnoise:get2d({x=x+250,y=z+250}) > HUMT) then
return return
end end
local c_air = minetest.get_content_id("air") local c_air = minetest.get_content_id("air")
local c_rain = minetest.get_content_id("rain:rain") local c_rain = minetest.get_content_id("rain:rain")
local c_rainabm = minetest.get_content_id("rain:rainabm") local c_abmne = minetest.get_content_id("rain:abmne")
local c_abmnw = minetest.get_content_id("rain:abmnw")
local c_abmse = minetest.get_content_id("rain:abmse")
local c_abmsw = minetest.get_content_id("rain:abmsw")
local c_cloud = minetest.get_content_id("rain:cloud") local c_cloud = minetest.get_content_id("rain:cloud")
local vm = minetest.get_voxel_manip() -- large flat volume for cloud check local vm = minetest.get_voxel_manip() -- large flat volume for cloud check
local pos1 = {x=x-160, y=64, z=z-144} local pos1 = {x=x-160, y=64, z=z-160}
local pos2 = {x=x+159, y=64, z=z+175} local pos2 = {x=x+159, y=64, z=z+159}
local emin, emax = vm:read_from_map(pos1, pos2) local emin, emax = vm:read_from_map(pos1, pos2)
local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax}) local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax})
local data = vm:get_data() local data = vm:get_data()
@ -100,33 +136,63 @@ minetest.register_abm({
end end
local vm = minetest.get_voxel_manip() -- spawn cloud and rain columns local vm = minetest.get_voxel_manip() -- spawn cloud and rain columns
local pos1 = {x=x-32, y=1, z=z-16} local pos1 = {x=x-32, y=1, z=z-32}
local pos2 = {x=x+31, y=95, z=z+47} local pos2 = {x=x+31, y=79, z=z+31}
local emin, emax = vm:read_from_map(pos1, pos2) local emin, emax = vm:read_from_map(pos1, pos2)
local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax}) local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax})
local data = vm:get_data() local data = vm:get_data()
local vvii = emax.x - emin.x + 1 -- vertical vi interval local vvii = emax.x - emin.x + 1 -- vertical vi interval
-- local nvii = (emax.y - emin.y + 1) * vvii -- local nvii = (emax.y - emin.y + 1) * vvii
for y = 64, 95 do for y = 64, 79 do
for k = -16, 47 do for k = -32, 31 do
local vi = area:index(x-32, y, z + k) local vi = area:index(x-32, y, z + k)
for i = -32, 31 do for i = -32, 31 do
if data[vi] == c_air then if data[vi] == c_air then
data[vi] = c_cloud data[vi] = c_cloud
end end
if y == 64 and k == 0 and i == 0 then -- rain abm column if y == 64 and k == 31 and i == 31 then -- abm column
local vir = vi - vvii local vir = vi - vvii
for fall = 1, 63 do for fall = 1, 63 do
if data[vir] == c_air then if data[vir] == c_air then
data[vir] = c_rainabm data[vir] = c_abmne
else else
break break
end end
vir = vir - vvii vir = vir - vvii
end end
elseif y == 64 and i >= -16 and i <= 15 -- rain columns elseif y == 64 and k == 31 and i == -32 then -- abm column
and k >= 0 and k <= 31 and math.random() < 0.25 then local vir = vi - vvii
for fall = 1, 63 do
if data[vir] == c_air then
data[vir] = c_abmnw
else
break
end
vir = vir - vvii
end
elseif y == 64 and k == -32 and i == 31 then -- abm column
local vir = vi - vvii
for fall = 1, 63 do
if data[vir] == c_air then
data[vir] = c_abmse
else
break
end
vir = vir - vvii
end
elseif y == 64 and k == -32 and i == -32 then -- abm column
local vir = vi - vvii
for fall = 1, 63 do
if data[vir] == c_air then
data[vir] = c_abmsw
else
break
end
vir = vir - vvii
end
elseif y == 64 and i >= -24 and i <= 23 -- rain columns
and k >= -24 and k <= 23 and math.random() < 0.25 then
local vir = vi - vvii local vir = vi - vvii
for fall = 1, 63 do for fall = 1, 63 do
if data[vir] == c_air then if data[vir] == c_air then
@ -151,39 +217,69 @@ minetest.register_abm({
-- Dissolve over desert or drift raincloud southward -- Dissolve over desert or drift raincloud southward
minetest.register_abm({ minetest.register_abm({
nodenames = {"rain:rainabm"}, nodenames = {"rain:abmne", "rain:abmnwx", "rain:abmse", "rain:abmsw"},
interval = 7, interval = 11,
chance = 64, chance = 64,
action = function(pos, node) action = function(pos, node)
local x = pos.x local x = pos.x
local z = pos.z local z = pos.z
local c_node = minetest.get_content_id(node.name)
local c_air = minetest.get_content_id("air") local c_air = minetest.get_content_id("air")
local c_desand = minetest.get_content_id("default:desert_sand") local c_desand = minetest.get_content_id("default:desert_sand")
local c_rain = minetest.get_content_id("rain:rain") local c_rain = minetest.get_content_id("rain:rain")
local c_rainabm = minetest.get_content_id("rain:rainabm") local c_abmne = minetest.get_content_id("rain:abmne")
local c_abmnw = minetest.get_content_id("rain:abmnw")
local c_abmse = minetest.get_content_id("rain:abmse")
local c_abmsw = minetest.get_content_id("rain:abmsw")
local c_cloud = minetest.get_content_id("rain:cloud") local c_cloud = minetest.get_content_id("rain:cloud")
local pos1 = {x=0, y=1, z=0}
local pos2 = {x=0, y=79, z=0}
if c_node == c_abmne then
pos1.x = x - 63
pos1.z = z - 67
pos2.x = x
pos2.z = z
elseif c_node == c_abmnw then
pos1.x = x
pos1.z = z - 67
pos2.x = x + 63
pos2.z = z
elseif c_node == c_abmse then
pos1.x = x - 63
pos1.z = z - 4
pos2.x = x
pos2.z = z + 63
elseif c_node == c_abmsw then
pos1.x = x
pos1.z = z - 4
pos2.x = x + 63
pos2.z = z + 63
end
local vm = minetest.get_voxel_manip() local vm = minetest.get_voxel_manip()
local pos1 = {x=x-32, y=1, z=z-16}
local pos2 = {x=x+31, y=95, z=z+47}
local emin, emax = vm:read_from_map(pos1, pos2) local emin, emax = vm:read_from_map(pos1, pos2)
local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax}) local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax})
local data = vm:get_data() local data = vm:get_data()
local vvii = emax.x - emin.x + 1 -- vertical vi interval local vvii = emax.x - emin.x + 1 -- vertical vi interval
local dissolve = false -- check ground for desert sand local desert = false -- check ground for desert sand
for vi in area:iterp(pos1, {x=x+31, y=47, z=z+47}) do for vi in area:iterp({x=pos1.x, y=1, z=pos1.z}, {x=pos2.x, y=47, z=pos2.z}) do
if data[vi] == c_desand then if data[vi] == c_desand then
dissolve = true desert = true
break break
end end
end end
if dissolve then -- erase cloud and rain if desert or CLEAR then -- erase cloud and rain
for vi in area:iterp(pos1, pos2) do for vi in area:iterp(pos1, pos2) do
if data[vi] == c_cloud if data[vi] == c_cloud
or data[vi] == c_rain or data[vi] == c_rain
or data[vi] == c_rainabm then or data[vi] == c_abmne
or data[vi] == c_abmnw
or data[vi] == c_abmse
or data[vi] == c_abmsw then
data[vi] = c_air data[vi] = c_air
end end
end end
@ -193,66 +289,48 @@ minetest.register_abm({
return return
end end
for y = 63, 95 do -- spawn and erase cloud and rain columns -- spawn/erase cloud, rain, abm columns
for k = -16, 47 do for zz = pos1.z, pos2.z do
local vi = area:index(x-32, y, z+k) for yy = 1, 79 do
for i = -32, 31 do local vi = area:index(pos1.x, yy, zz)
if k == -16 then for xx = pos1.x, pos2.x do
if y >= 64 and data[vi] == c_air then -- new cloud local nodid = data[vi]
if yy >= 64 then
if zz <= pos1.z + 3 and nodid == c_air then -- new cloud
data[vi] = c_cloud data[vi] = c_cloud
elseif zz >= pos2.z - 3 and nodid == c_cloud then -- erase previous cloud
data[vi] = c_air
end end
elseif k == -1 and y == 63 then elseif xx == pos2.x and zz == pos2.z - 4 and nodid == c_air then -- new abm columns
if i == 0 then -- new rain abm column data[vi] = c_abmne
local vir = vi elseif xx == pos1.x and zz == pos2.z - 4 and nodid == c_air then
for fall = 1, 63 do data[vi] = c_abmnw
if data[vir] == c_air then elseif xx == pos2.x and zz == pos1.z and nodid == c_air then
data[vir] = c_rainabm data[vi] = c_abmse
else elseif xx == pos1.x and zz == pos1.z and nodid == c_air then
break data[vi] = c_abmsw
end elseif yy == 63 and xx >= pos1.x + 8 and xx <= pos2.x - 8 -- new rain columns
vir = vir - vvii and zz >= pos1.z + 8 and zz <= pos1.z + 11
end and math.random() < 0.25 then
elseif i >= -16 and i <= 15
and math.random() < 0.25 then -- new rain
local vir = vi
for fall = 1, 63 do
if data[vir] == c_air then
data[vir] = c_rain
else
break
end
vir = vir - vvii
end
end
elseif k == 0 and y == 63 and i == 0 then -- erase previous rainabm column
local vir = vi local vir = vi
for fall = 1, 63 do for fall = 1, 63 do
if data[vir] == c_rainabm then if data[vir] == c_air then
data[vir] = c_air data[vir] = c_rain
else else
break break
end end
vir = vir - vvii vir = vir - vvii
end end
elseif k == 31 and y == 63 elseif xx == pos2.x and zz == pos2.z and nodid == c_abmne then -- erase previous abm columns
and i >= -16 and i <= 15 then -- erase previous rain data[vi] = c_air
local nodid = data[vi] elseif xx == pos1.x and zz == pos2.z and nodid == c_abmnw then
if nodid == c_rain then data[vi] = c_air
local vir = vi elseif xx == pos2.x and zz == pos1.z + 4 and nodid == c_abmse then
for fall = 1, 63 do data[vi] = c_air
if data[vir] == c_rain then elseif xx == pos1.x and zz == pos1.z + 4 and nodid == c_abmsw then
data[vir] = c_air data[vi] = c_air
else elseif zz >= pos2.z - 11 and nodid == c_rain then -- erase previous rain
break data[vi] = c_air
end
vir = vir - vvii
end
end
elseif k == 47 and y >= 64 then -- erase previous cloud
local nodid = data[vi]
if nodid == c_cloud then
data[vi] = c_air
end
end end
vi = vi + 1 vi = vi + 1
end end