247 lines
7.3 KiB
Lua
247 lines
7.3 KiB
Lua
is_snowing = false
|
|
is_raining = true
|
|
local changeupdate = 1 --checks if player position changed every x seconds
|
|
|
|
-----------------------------------------------------------------------------------------
|
|
--texture tile style (strange)
|
|
minetest.register_node("snow:snowfall", {
|
|
description = "H@CK3R",
|
|
drawtype = "plantlike",
|
|
visual_scale = 1.4,
|
|
waving = true,
|
|
--tiles = {"default_papyrus.png"},
|
|
tiles = {
|
|
{
|
|
name = "snowfallhd.png",
|
|
|
|
animation = {
|
|
type = "vertical_frames",
|
|
aspect_w = 64,
|
|
aspect_h = 64,
|
|
length = 3,
|
|
},
|
|
},
|
|
},
|
|
inventory_image = "default_papyrus.png",
|
|
wield_image = "default_papyrus.png",
|
|
paramtype = "light",
|
|
pointable = false,
|
|
diggable = false,
|
|
buildable_to = true,
|
|
floodable = true,
|
|
sunlight_propagates = true,
|
|
walkable = false,
|
|
selection_box = {
|
|
type = "fixed",
|
|
fixed = {0, 0, 0, 0, 0, 0},
|
|
},
|
|
groups = {snow=1},
|
|
})
|
|
--remove snow
|
|
|
|
minetest.register_abm{
|
|
label="removesnow",
|
|
nodenames = {"snow:snowfall"},
|
|
interval = 1,
|
|
chance = 50,
|
|
action=function(pos)
|
|
if is_snowing == false then
|
|
minetest.remove_node(pos)
|
|
end
|
|
end,
|
|
}
|
|
|
|
--make snow form
|
|
minetest.register_abm{
|
|
label = "snowfall",
|
|
nodenames = {"snow:snowfall"},
|
|
interval = 1,
|
|
chance = 300, --300 seems to be good
|
|
action = function(pos)
|
|
pos.y = pos.y - 1
|
|
local node = minetest.get_node(pos).name
|
|
--snow on top of node
|
|
if node ~= "air" and node ~= "snow:snowfall" and minetest.get_item_group(node, "liquid") == 0 and node ~= "default:snow" and minetest.registered_nodes[node]["buildable_to"] == false then
|
|
pos.y = pos.y + 1
|
|
minetest.set_node(pos,{name="default:snow"})
|
|
--replace node if buildable to
|
|
elseif node ~= "air" and node ~= "snow:snowfall" and minetest.get_item_group(node, "liquid") == 0 and node ~= "default:snow" and minetest.registered_nodes[node]["buildable_to"] == true then
|
|
minetest.set_node(pos,{name="default:snow"})
|
|
end
|
|
end,
|
|
}
|
|
-----------------------------------------------------------------------------------------------
|
|
minetest.register_node("snow:rainfall", {
|
|
description = "H@CK3R",
|
|
drawtype = "plantlike",
|
|
visual_scale = 1.4,
|
|
waving = true,
|
|
--tiles = {"default_papyrus.png"},
|
|
tiles = {
|
|
{
|
|
name = "rainfall.png",
|
|
|
|
animation = {
|
|
type = "vertical_frames",
|
|
aspect_w = 256,
|
|
aspect_h = 256,
|
|
length = 1,
|
|
},
|
|
},
|
|
},
|
|
inventory_image = "default_papyrus.png",
|
|
wield_image = "default_papyrus.png",
|
|
paramtype = "light",
|
|
pointable = false,
|
|
diggable = false,
|
|
buildable_to = true,
|
|
floodable = true,
|
|
sunlight_propagates = true,
|
|
walkable = false,
|
|
selection_box = {
|
|
type = "fixed",
|
|
fixed = {0, 0, 0, 0, 0, 0},
|
|
},
|
|
groups = {snow=1},
|
|
})
|
|
--make snow form
|
|
minetest.register_abm{
|
|
|
|
label="removerain",
|
|
nodenames = {"snow:rainfall"},
|
|
interval = 1,
|
|
chance = 50,
|
|
action=function(pos)
|
|
--print("removing")
|
|
if is_raining == false then
|
|
--print("removing")
|
|
minetest.remove_node(pos)
|
|
end
|
|
end,
|
|
}
|
|
|
|
minetest.register_abm{
|
|
label = "rainfall",
|
|
nodenames = {"snow:rainfall"},
|
|
interval = 1,
|
|
chance = 50,
|
|
action = function(pos)
|
|
pos.y = pos.y - 1
|
|
local node = minetest.get_node(pos).name
|
|
--water on top of node
|
|
if node ~= "air" and node ~= "snow:rainfall" and minetest.get_item_group(node, "liquid") == 0 and node ~= "default:snow" and minetest.registered_nodes[node]["buildable_to"] == false then
|
|
pos.y = pos.y + 1
|
|
minetest.set_node(pos,{name="default:water_flowing",param2=3})
|
|
--replace node if buildable to
|
|
elseif node ~= "air" and node ~= "snow:rainfall" and minetest.get_item_group(node, "liquid") == 0 and minetest.registered_nodes[node]["buildable_to"] == true then
|
|
minetest.set_node(pos,{name="default:water_flowing",param2=3})
|
|
end
|
|
end,
|
|
}
|
|
|
|
--------------------------------------------------------------------
|
|
local snow = {} --the class
|
|
snow.playertable = {} --the player table
|
|
|
|
--get player node position on joining
|
|
minetest.register_on_joinplayer(function(player)
|
|
local playerpos = player:getpos()
|
|
--get center of node
|
|
snow.playertable[player:get_player_name()] ={x=math.floor(playerpos.x+0.5),y=math.floor(playerpos.y+0.5),z=math.floor(playerpos.z+0.5)}
|
|
--print(dump(snow.playertable[player:get_player_name()]))
|
|
snow.make_snow_around_player(snow.playertable[player:get_player_name()])
|
|
end)
|
|
|
|
--check if player has moved nodes
|
|
local changetimer = 0
|
|
minetest.register_globalstep(function(dtime)
|
|
--add to timer to prevent extreme lag
|
|
changetimer = changetimer + dtime
|
|
if changetimer >= changeupdate then
|
|
for _,player in pairs(minetest.get_connected_players()) do
|
|
if player:get_player_name() then
|
|
--print("checking "..player:get_player_name())
|
|
changetimer = 0
|
|
--only snow if snowing
|
|
if is_snowing == true then
|
|
-- print("IT IS SNOWING")
|
|
--get required info
|
|
local playerpos = player:getpos()
|
|
local exactplayerpos = {x=math.floor(playerpos.x+0.5),y=math.floor(playerpos.y+0.5),z=math.floor(playerpos.z+0.5)}
|
|
local tablepos = snow.playertable[player:get_player_name()]
|
|
--do some maths and check if new position, if so, update
|
|
if tablepos.x ~= exactplayerpos.x or tablepos.y ~= exactplayerpos.y or tablepos.z ~= exactplayerpos.z then
|
|
-- print(player:get_player_name().."'s position has changed! updating!")
|
|
snow.playertable[player:get_player_name()] = exactplayerpos
|
|
snow.make_snow_around_player(exactplayerpos)
|
|
end
|
|
elseif is_raining == true then
|
|
--print("IT IS RAINING")
|
|
--get required info
|
|
local playerpos = player:getpos()
|
|
local exactplayerpos = {x=math.floor(playerpos.x+0.5),y=math.floor(playerpos.y+0.5),z=math.floor(playerpos.z+0.5)}
|
|
local tablepos = snow.playertable[player:get_player_name()]
|
|
--do some maths and check if new position, if so, update
|
|
if tablepos.x ~= exactplayerpos.x or tablepos.y ~= exactplayerpos.y or tablepos.z ~= exactplayerpos.z then
|
|
-- print(player:get_player_name().."'s position has changed! updating!")
|
|
snow.playertable[player:get_player_name()] = exactplayerpos
|
|
snow.make_snow_around_player(exactplayerpos)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
--this checks and makes snow fall
|
|
snow.make_snow_around_player = function(pos)
|
|
local range = 50
|
|
local air = minetest.get_content_id("air")
|
|
local snow = minetest.get_content_id("snow:snowfall")
|
|
local rain = minetest.get_content_id("snow:rainfall")
|
|
local water = minetest.get_content_id("default:water_source")
|
|
|
|
|
|
local min = {x=pos.x-range,y=pos.y-range,z=pos.z-range}
|
|
local max = {x=pos.x+range,y=pos.y+range,z=pos.z+range}
|
|
local vm = minetest.get_voxel_manip()
|
|
local emin, emax = vm:read_from_map(min,max)
|
|
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
|
|
local data = vm:get_data()
|
|
local lightdata = vm:get_light_data()
|
|
local content_id = minetest.get_name_from_content_id
|
|
|
|
local percip = 0
|
|
if is_snowing == true then
|
|
percip = snowing
|
|
elseif is_raining == true then
|
|
percip = rain
|
|
end
|
|
|
|
for x=-range, range do
|
|
for y=-range, range do
|
|
for z=-range, range do
|
|
if vector.distance(pos, vector.add(pos, {x=x, y=y, z=z})) <= range then
|
|
|
|
local p_pos = area:index(pos.x+x,pos.y+y,pos.z+z)
|
|
|
|
|
|
local n = content_id(data[p_pos])
|
|
local l = lightdata[p_pos]
|
|
|
|
--if n.name ~= "air" then
|
|
if n == "air" and l >= 15 then
|
|
data[p_pos] = percip
|
|
elseif n == "snow:snowfall" and l < 15 then
|
|
data[p_pos] = air
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
vm:set_data(data)
|
|
vm:write_to_map()
|
|
vm:update_map()
|
|
end
|