revert to old version because of memory bug
parent
e6fd084b88
commit
e2554c0fe2
586
init.lua
586
init.lua
|
@ -1,146 +1,228 @@
|
||||||
|
local mod_storage = minetest.get_mod_storage()
|
||||||
local snow = {} --the class
|
local snow = {} --the class
|
||||||
|
|
||||||
snow.playertable = {} --the player table
|
snow.playertable = {} --the player table
|
||||||
|
|
||||||
local snowfallradius = 120
|
local is_snowing = false
|
||||||
local snowfallheight = 30
|
local is_raining = false
|
||||||
local snowchance = 0.95 --0.99 is best
|
local heavy_percip = false
|
||||||
|
--a note :
|
||||||
|
local changeupdate = 2 --checks if player position changed every x seconds
|
||||||
|
local snowrange = 40 --the visual of the snow and deposit spawn radius
|
||||||
|
local snowrange_height = 8 --the height of snow -y +y
|
||||||
|
local deposit_chance = 0.95 --uses math.random(deposit_chance) to deposit snow on each loop
|
||||||
|
|
||||||
--particles stuff
|
|
||||||
local radius = 15
|
|
||||||
local height = 10
|
|
||||||
local amountofsnow = 400
|
|
||||||
local snowvelocity = 0.5
|
|
||||||
local snowfallvelocity = {-1,-3}
|
|
||||||
|
|
||||||
local timer = 0
|
|
||||||
local timerexpire = 2
|
-----------------------------------------------------------------------------------------
|
||||||
|
--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},
|
||||||
|
})
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------------------------
|
||||||
|
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},
|
||||||
|
})
|
||||||
|
|
||||||
|
--------------------------------------------------------------------
|
||||||
|
|
||||||
|
--check if player has moved nodes
|
||||||
|
local changetimer = 0
|
||||||
|
local old_weather = 0
|
||||||
minetest.register_globalstep(function(dtime)
|
minetest.register_globalstep(function(dtime)
|
||||||
timer = timer + dtime
|
--add to timer to prevent extreme lag
|
||||||
if timer > timerexpire then
|
changetimer = changetimer + dtime
|
||||||
timer = 0
|
if changetimer >= changeupdate then
|
||||||
for _,player in pairs(minetest.get_connected_players()) do
|
for _,player in pairs(minetest.get_connected_players()) do
|
||||||
if player:get_player_name() then
|
if player:get_player_name() then
|
||||||
local playerpos = player:getpos()
|
--print("checking "..player:get_player_name())
|
||||||
local exactplayerpos = {x=math.floor(playerpos.x+0.5),y=math.floor(playerpos.y+0.5),z=math.floor(playerpos.z+0.5)}
|
changetimer = 0
|
||||||
local oldpos = snow.playertable[player:get_player_name()]
|
--only snow if snowing
|
||||||
|
--get required info
|
||||||
--make snow
|
--snow or rain
|
||||||
--if oldpos and (oldpos.x ~= exactplayerpos.x or oldpos.y ~= exactplayerpos.y or oldpos.z ~= exactplayerpos.z) then
|
local oldpos = snow.playertable[player:get_player_name()]
|
||||||
--CHANGE SPAWNERS
|
if is_snowing == true or is_raining == true then
|
||||||
--snow.check_nodes(playerpos, player:get_player_name())
|
local playerpos = player:getpos()
|
||||||
snow.make_snow_fall(playerpos)
|
local exactplayerpos = {x=math.floor(playerpos.x+0.5),y=math.floor(playerpos.y+0.5),z=math.floor(playerpos.z+0.5)}
|
||||||
--end
|
|
||||||
|
|
||||||
snow.playertable[player:get_player_name()] = exactplayerpos
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
|
|
||||||
minetest.register_on_joinplayer(function(player)
|
|
||||||
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)}
|
|
||||||
|
|
||||||
snow.playertable[player:get_player_name()] = exactplayerpos
|
|
||||||
|
|
||||||
player:set_sky("grey", "plain", "", false)
|
|
||||||
|
|
||||||
minetest.add_particlespawner({
|
|
||||||
amount = amountofsnow,
|
|
||||||
-- Number of particles spawned over the time period `time`.
|
|
||||||
|
|
||||||
time = 0,
|
|
||||||
-- Lifespan of spawner in seconds.
|
|
||||||
-- If time is 0 spawner has infinite lifespan and spawns the `amount` on
|
|
||||||
-- a per-second basis.
|
|
||||||
|
|
||||||
minpos = {x=-radius, y=0, z=-radius},
|
|
||||||
maxpos = {x=radius, y=height, z=radius},
|
|
||||||
minvel = {x=-snowvelocity, y=snowfallvelocity[1], z=-snowvelocity},
|
|
||||||
maxvel = {x=snowvelocity, y=snowfallvelocity[2], z=snowvelocity},
|
|
||||||
minacc = {x=0, y=0, z=0},
|
|
||||||
maxacc = {x=0, y=0, z=0},
|
|
||||||
minexptime = 1,
|
|
||||||
maxexptime = 1,
|
|
||||||
minsize = 1,
|
|
||||||
maxsize = 1,
|
|
||||||
-- The particles' properties are random values between the min and max
|
|
||||||
-- values.
|
|
||||||
-- pos, velocity, acceleration, expirationtime, size
|
|
||||||
|
|
||||||
collisiondetection = true,
|
|
||||||
-- If true collide with `walkable` nodes and, depending on the
|
|
||||||
-- `object_collision` field, objects too.
|
|
||||||
|
|
||||||
collision_removal = true,
|
|
||||||
-- If true particles are removed when they collide.
|
|
||||||
-- Requires collisiondetection = true to have any effect.
|
|
||||||
|
|
||||||
object_collision = true,
|
|
||||||
-- If true particles collide with objects that are defined as
|
|
||||||
-- `physical = true,` and `collide_with_objects = true,`.
|
|
||||||
-- Requires collisiondetection = true to have any effect.
|
|
||||||
|
|
||||||
attached = player,
|
|
||||||
-- If defined, particle positions, velocities and accelerations are
|
|
||||||
-- relative to this object's position and yaw
|
|
||||||
|
|
||||||
vertical = true,
|
|
||||||
-- If true face player using y axis only
|
|
||||||
|
|
||||||
texture = "snowflake.png",
|
|
||||||
|
|
||||||
playername = player:get_player_name(),
|
|
||||||
-- Optional, if specified spawns particles only on the player's client
|
|
||||||
|
|
||||||
|
|
||||||
glow = 0
|
|
||||||
-- Optional, specify particle self-luminescence in darkness.
|
|
||||||
-- Values 0-14.
|
|
||||||
})
|
|
||||||
|
|
||||||
end)
|
|
||||||
|
|
||||||
snow.check_nodes = function(pos,name)
|
|
||||||
--[[
|
|
||||||
for x=-snowfallradius,snowfallradius do
|
|
||||||
for z=-snowfallradius,snowfallradius do
|
|
||||||
if math.random() > snowchance then
|
|
||||||
local superpos = {x=pos.x+x,y=pos.y+snowfallheight,z=pos.z+z}
|
|
||||||
local lighttest = minetest.get_node_light(superpos, 0.5)
|
|
||||||
if lighttest and lighttest >= 15 then
|
|
||||||
--minetest.set_node(superpos, {name="snow:snow"})
|
|
||||||
--minetest.spawn_falling_node(superpos)
|
|
||||||
|
|
||||||
|
--if position moved clear old weather
|
||||||
|
if oldpos.x ~= exactplayerpos.x or oldpos.y ~= exactplayerpos.y or oldpos.z ~= exactplayerpos.z then
|
||||||
|
if oldpos.x then --stop crashes
|
||||||
|
snow.clear_old_snow(oldpos)
|
||||||
|
snow.set_ms_pos(exactplayerpos,player)
|
||||||
|
end
|
||||||
|
--print("clearing old weather")
|
||||||
end
|
end
|
||||||
end
|
--then make new weather
|
||||||
end
|
snow.make_snow_around_player(exactplayerpos)
|
||||||
|
--make weather form in world (snow on ground, puddles)
|
||||||
|
snow.make_snow_fall(exactplayerpos)
|
||||||
|
|
||||||
|
--this acts as old position
|
||||||
|
snow.playertable[player:get_player_name()] = exactplayerpos
|
||||||
|
|
||||||
|
old_weather = 1 --do this so that it doesn't try to clear weather every loop
|
||||||
|
--clear up snow
|
||||||
|
elseif old_weather == 1 then
|
||||||
|
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)}
|
||||||
|
snow.clear_old_snow(oldpos)
|
||||||
|
--this acts as old position
|
||||||
|
snow.playertable[player:get_player_name()] = exactplayerpos
|
||||||
|
old_weather = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
]]
|
end)
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--this checks and makes snow fall nodes
|
||||||
|
snow.make_snow_around_player = function(pos)
|
||||||
|
print("making snow")
|
||||||
|
|
||||||
|
local range = snowrange
|
||||||
|
local height = snowrange_height
|
||||||
|
local air = minetest.get_content_id("air")
|
||||||
|
local snowy = 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
|
||||||
|
|
||||||
|
--this sets if snow or rain
|
||||||
|
local percip
|
||||||
|
|
||||||
|
if is_snowing == true then
|
||||||
|
percip = snowy
|
||||||
|
elseif is_raining == true then
|
||||||
|
percip = rain
|
||||||
|
end
|
||||||
|
|
||||||
|
--this reconverts back to namestring for quick snow removal
|
||||||
|
local ctester = minetest.get_name_from_content_id(percip)
|
||||||
|
|
||||||
|
for x=-range, range do
|
||||||
|
for y=-height, height 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]
|
||||||
|
--sets the data
|
||||||
|
--also autoremove old weather
|
||||||
|
if (n == "air" or (ctester == "snow:snowfall" and n == "snow:rainfall") or (ctester == "snow:rainfall" and n == "snow:snowfall")) and l >= 15 then
|
||||||
|
local lightleveltest = minetest.get_node_light({x=pos.x+x,y=pos.y+y,z=pos.z+z}, 0.5)
|
||||||
|
--print(lightleveltest)
|
||||||
|
if lightleveltest and lightleveltest >= 15 then
|
||||||
|
data[p_pos] = percip
|
||||||
|
else
|
||||||
|
data[p_pos] = air
|
||||||
|
end
|
||||||
|
elseif (n == "snow:snowfall" and l < 15) or (n == "snow:rainfall" and l < 15) then
|
||||||
|
data[p_pos] = air --this makes the snow adapt to the environment
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
vm:set_data(data)
|
||||||
|
vm:write_to_map()
|
||||||
end
|
end
|
||||||
|
|
||||||
--this function actually puts snow and rain on the ground
|
--this function actually puts snow and rain on the ground
|
||||||
snow.make_snow_fall = function(pos)
|
snow.make_snow_fall = function(pos)
|
||||||
local range = snowfallradius
|
local range = snowrange
|
||||||
local height = snowfallheight
|
local height = snowrange_height
|
||||||
local air = minetest.get_content_id("air")
|
local air = minetest.get_content_id("air")
|
||||||
local snowblock = minetest.get_content_id("snow:snow")
|
local snowy = minetest.get_content_id("snow:snowfall")
|
||||||
|
local rain = minetest.get_content_id("snow:rainfall")
|
||||||
local water = minetest.get_content_id("default:water_source")
|
local water = minetest.get_content_id("default:water_source")
|
||||||
local ice = minetest.get_content_id("default:ice")
|
local snow_node = minetest.get_content_id("default:snow")
|
||||||
|
local water_node = minetest.get_content_id("default:water_flowing")
|
||||||
|
|
||||||
local min = {x=pos.x-range,y=pos.y-height,z=pos.z-range}
|
local min = {x=pos.x-range,y=pos.y-range,z=pos.z-range}
|
||||||
local max = {x=pos.x+range,y=pos.y+height,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 vm = minetest.get_voxel_manip()
|
||||||
local emin, emax = vm:read_from_map(min,max)
|
local emin, emax = vm:read_from_map(min,max)
|
||||||
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 lightdata = vm:get_light_data()
|
|
||||||
local content_id = minetest.get_name_from_content_id
|
local content_id = minetest.get_name_from_content_id
|
||||||
|
|
||||||
--this sets if snow or rain
|
--this sets if snow or rain
|
||||||
--[[
|
|
||||||
local percip
|
local percip
|
||||||
local deposit_block
|
local deposit_block
|
||||||
|
|
||||||
local param2er
|
local param2er
|
||||||
if is_snowing == true then
|
if is_snowing == true then
|
||||||
percip = snowy
|
percip = snowy
|
||||||
|
@ -155,107 +237,213 @@ snow.make_snow_fall = function(pos)
|
||||||
if param2er then
|
if param2er then
|
||||||
p2data = vm:get_param2_data()
|
p2data = vm:get_param2_data()
|
||||||
end
|
end
|
||||||
]]
|
|
||||||
----[[ minetest.set_node(pos,{name="default:water_flowing",param2=3}) THE PARAM2 OF WATER ]]-------------------------------HEY
|
----[[ minetest.set_node(pos,{name="default:water_flowing",param2=3}) THE PARAM2 OF WATER ]]-------------------------------HEY
|
||||||
|
|
||||||
|
|
||||||
--this reconverts back to namestring for quick snow removal
|
--this reconverts back to namestring for quick snow removal
|
||||||
--local ctester = minetest.get_name_from_content_id(percip)
|
local ctester = minetest.get_name_from_content_id(percip)
|
||||||
print("tying")
|
|
||||||
|
|
||||||
for x=-range, range do
|
for x=-range, range do
|
||||||
for y=-height, height do
|
for y=-height, height do
|
||||||
for z=-range, range do
|
for z=-range, range do
|
||||||
--if vector.distance(pos, vector.add(pos, {x=x, y=y, z=z})) <= range then
|
if vector.distance(pos, vector.add(pos, {x=x, y=y, z=z})) <= range then
|
||||||
--deposit snow randomly
|
--deposit snow randomly
|
||||||
local test_deposit_chance = snowchance
|
local test_deposit_chance = deposit_chance
|
||||||
--if heavy_percip == true then
|
if heavy_percip == true then
|
||||||
-- test_deposit_chance = test_deposit_chance - 0.25 -- heavy percip
|
test_deposit_chance = test_deposit_chance - 0.25 -- heavy percip
|
||||||
--end
|
end
|
||||||
if math.random() > test_deposit_chance then
|
if math.random() > test_deposit_chance then
|
||||||
|
|
||||||
--the actual node being indexed
|
--the actual node being indexed
|
||||||
local p_pos = area:index(pos.x+x,pos.y+y,pos.z+z)
|
local p_pos = area:index(pos.x+x,pos.y+y,pos.z+z)
|
||||||
local l = lightdata[p_pos]
|
local n = content_id(data[p_pos])
|
||||||
|
--the node above it (testing for place for snow and water)
|
||||||
|
local p_pos_above = area:index(pos.x+x,pos.y+y+1,pos.z+z)
|
||||||
|
local n_above = content_id(data[p_pos_above])
|
||||||
|
--also autoremove old weather
|
||||||
|
if n ~= ctester and n_above == ctester then
|
||||||
|
--print(lightleveltest)
|
||||||
|
--data[p_pos] = percip
|
||||||
|
|
||||||
if l ~= nil and l >= 15 then
|
if n ~= "air" and n ~= "snow:snowfall" and minetest.get_item_group(n, "liquid") == 0 and n ~= "default:snow" and minetest.registered_nodes[n]["buildable_to"] == false then
|
||||||
local n = content_id(data[p_pos])
|
data[p_pos_above] = deposit_block
|
||||||
--the node above it (testing for place for snow and water)
|
if param2er then
|
||||||
local p_pos_above = area:index(pos.x+x,pos.y+y+1,pos.z+z)
|
p2data[p_pos_above] = param2er
|
||||||
local n_above
|
end
|
||||||
if p_pos_above and data[p_pos_above] then
|
--replace node if buildable to
|
||||||
n_above = content_id(data[p_pos_above])
|
elseif n ~= "air" and n ~= "snow:snowfall" and minetest.get_item_group(n, "liquid") == 0 and n ~= "default:snow" and minetest.registered_nodes[n]["buildable_to"] == true then
|
||||||
end
|
data[p_pos] = deposit_block
|
||||||
|
if param2er then
|
||||||
local p_pos_below = area:index(pos.x+x,pos.y+y-1,pos.z+z)
|
p2data[p_pos] = param2er
|
||||||
local n_below
|
end
|
||||||
if p_pos_below and data[p_pos_below] then
|
end
|
||||||
n_below = content_id(data[p_pos_below])
|
|
||||||
end
|
|
||||||
|
|
||||||
if n ~= "air" and n ~= "snow:snow" and n_above == "air" and minetest.registered_nodes[n]["buildable_to"] == true then
|
|
||||||
data[p_pos] = snowblock
|
|
||||||
elseif n == "air" and n_below ~= "air" and minetest.get_item_group(n, "liquid") == 0 and n_below ~= "snow:snow" and minetest.registered_nodes[n_below]["buildable_to"] == false then
|
|
||||||
data[p_pos] = snowblock
|
|
||||||
elseif n == "air" and n_below == "default:water_source" then
|
|
||||||
data[p_pos_below] = ice
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
--end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
vm:set_data(data)
|
vm:set_data(data)
|
||||||
--if param2er then
|
if param2er then
|
||||||
-- vm:set_param2_data(p2data)
|
vm:set_param2_data(p2data)
|
||||||
--end
|
end
|
||||||
vm:write_to_map()
|
vm:write_to_map()
|
||||||
end
|
end
|
||||||
--override snow
|
--this checks and removes old nodes
|
||||||
--[[
|
snow.clear_old_snow = function(pos)
|
||||||
minetest.register_on_mods_loaded(function()
|
local range = snowrange
|
||||||
minetest.override_item("default:snow", {
|
local height = snowrange_height
|
||||||
on_construct = function(pos)
|
local air = minetest.get_content_id("air")
|
||||||
minetest.set_node(pos, {name = "snow:snow"})
|
local snowy = minetest.get_content_id("snow:snowfall")
|
||||||
end,
|
local rain = minetest.get_content_id("snow:rainfall")
|
||||||
})
|
|
||||||
|
|
||||||
|
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 content_id = minetest.get_name_from_content_id
|
||||||
|
|
||||||
|
for x=-range, range do
|
||||||
|
for y=-height, height 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])
|
||||||
|
--sets the data
|
||||||
|
if n == "snow:snowfall" or n == "snow:rainfall" then
|
||||||
|
data[p_pos] = air --this clears old snow
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
vm:set_data(data)
|
||||||
|
vm:write_to_map()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--commands
|
||||||
|
minetest.register_chatcommand("rain", {
|
||||||
|
params = "<text>",
|
||||||
|
description = "make it rain",
|
||||||
|
privs = {server = true},
|
||||||
|
func = function( _ , text)
|
||||||
|
is_raining = true
|
||||||
|
is_snowing = false
|
||||||
|
heavy_percip = false
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
minetest.register_chatcommand("snow", {
|
||||||
|
params = "<text>",
|
||||||
|
description = "make it rain",
|
||||||
|
privs = {server = true},
|
||||||
|
func = function( _ , text)
|
||||||
|
is_raining = false
|
||||||
|
is_snowing = true
|
||||||
|
heavy_percip = false
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
minetest.register_chatcommand("clear", {
|
||||||
|
params = "<text>",
|
||||||
|
description = "make it rain",
|
||||||
|
privs = {server = true},
|
||||||
|
func = function( _ , text)
|
||||||
|
is_raining = false
|
||||||
|
is_snowing = false
|
||||||
|
heavy_percip = false
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
minetest.register_chatcommand("snowstorm", {
|
||||||
|
params = "<text>",
|
||||||
|
description = "make it rain",
|
||||||
|
privs = {server = true},
|
||||||
|
func = function( _ , text)
|
||||||
|
is_raining = false
|
||||||
|
is_snowing = true
|
||||||
|
heavy_percip = true
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
minetest.register_chatcommand("rainstorm", {
|
||||||
|
params = "<text>",
|
||||||
|
description = "make it rain",
|
||||||
|
privs = {server = true},
|
||||||
|
func = function( _ , text)
|
||||||
|
is_raining = true
|
||||||
|
is_snowing = false
|
||||||
|
heavy_percip = true
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
------------------------------------- additional helpers
|
||||||
|
|
||||||
|
--remove snow when player leaves!
|
||||||
|
minetest.register_on_leaveplayer(function(player)
|
||||||
|
print("clearing "..player:get_player_name().."'s weather")
|
||||||
|
|
||||||
|
--clear old snow in current and last position(if there)
|
||||||
|
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)}
|
||||||
|
snow.clear_old_snow(exactplayerpos)
|
||||||
|
|
||||||
|
if snow.playertable[player:get_player_name()] then
|
||||||
|
snow.clear_old_snow(snow.playertable[player:get_player_name()])
|
||||||
|
end
|
||||||
|
snow.set_ms_pos(exactplayerpos,player)
|
||||||
end)
|
end)
|
||||||
]]--
|
|
||||||
minetest.register_lbm({
|
|
||||||
name = "snow:replacesnow",
|
|
||||||
nodenames = {"default:snow"},
|
|
||||||
action = function(pos, node)
|
|
||||||
minetest.set_node(pos, {name = "snow:snow"})
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
-------
|
|
||||||
|
|
||||||
minetest.register_node("snow:snow", {
|
--remove snow when player leaves!
|
||||||
description = "Snow",
|
--get player node position on joining
|
||||||
tiles = {"default_snow.png"},
|
minetest.register_on_joinplayer(function(player)
|
||||||
inventory_image = "default_snowball.png",
|
print("clearing "..player:get_player_name().."'s weather")
|
||||||
wield_image = "default_snowball.png",
|
|
||||||
paramtype = "light",
|
|
||||||
buildable_to = true,
|
|
||||||
floodable = true,
|
|
||||||
drawtype = "nodebox",
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = {
|
|
||||||
{-0.5, -0.5, -0.5, 0.5, -0.25, 0.5},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
collision_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = {
|
|
||||||
{-0.5, -0.5, -0.5, 0.5, -7 / 16, 0.5},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
groups = {crumbly = 3, falling_node = 1, snowy = 1},
|
|
||||||
sounds = default.node_sound_snow_defaults(),
|
|
||||||
|
|
||||||
on_construct = function(pos)
|
--clear old snow in current pos
|
||||||
minetest.set_node(pos, {name = "default:snow"})
|
local playerpos = player:getpos()
|
||||||
end,
|
local exactplayerpos = {x=math.floor(playerpos.x+0.5),y=math.floor(playerpos.y+0.5),z=math.floor(playerpos.z+0.5)}
|
||||||
})
|
snow.clear_old_snow(exactplayerpos)
|
||||||
|
|
||||||
|
|
||||||
|
--remove old snow in last position
|
||||||
|
|
||||||
|
if snow.get_ms_pos(player) then
|
||||||
|
snow.clear_old_snow(snow.get_ms_pos(player))
|
||||||
|
end
|
||||||
|
|
||||||
|
snow.set_ms_pos(exactplayerpos,player)
|
||||||
|
snow.playertable[player:get_player_name()] = exactplayerpos
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
--helpers for position in mod storage
|
||||||
|
snow.set_ms_pos = function(pos,player)
|
||||||
|
mod_storage:set_string(player:get_player_name().."_pos", minetest.pos_to_string(pos, 0))
|
||||||
|
end
|
||||||
|
|
||||||
|
snow.get_ms_pos = function(player)
|
||||||
|
return(minetest.string_to_pos(mod_storage:get_string(player:get_player_name().."_pos")))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--new snow (allows snow to pile up)
|
||||||
|
for i = 1,7 do
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
|
|
@ -0,0 +1,242 @@
|
||||||
|
local snow = {} --the class
|
||||||
|
snow.playertable = {} --the player table
|
||||||
|
|
||||||
|
local snowfallradius = 90
|
||||||
|
local snowfallheight = 50
|
||||||
|
local snowchance = 0.99 --0.99 is best
|
||||||
|
|
||||||
|
--particles stuff
|
||||||
|
local radius = 15
|
||||||
|
local height = 10
|
||||||
|
local amountofsnow = 400
|
||||||
|
local snowvelocity = 0.5
|
||||||
|
local snowfallvelocity = {-1,-3}
|
||||||
|
|
||||||
|
local timer = 0
|
||||||
|
local timerexpire = 5
|
||||||
|
minetest.register_globalstep(function(dtime)
|
||||||
|
timer = timer + dtime
|
||||||
|
if timer > timerexpire then
|
||||||
|
timer = 0
|
||||||
|
for _,player in pairs(minetest.get_connected_players()) do
|
||||||
|
if player:get_player_name() then
|
||||||
|
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 oldpos = snow.playertable[player:get_player_name()]
|
||||||
|
|
||||||
|
--make snow
|
||||||
|
--if oldpos and (oldpos.x ~= exactplayerpos.x or oldpos.y ~= exactplayerpos.y or oldpos.z ~= exactplayerpos.z) then
|
||||||
|
--CHANGE SPAWNERS
|
||||||
|
--snow.check_nodes(playerpos, player:get_player_name())
|
||||||
|
snow.make_snow_fall(playerpos)
|
||||||
|
--end
|
||||||
|
|
||||||
|
snow.playertable[player:get_player_name()] = exactplayerpos
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_on_joinplayer(function(player)
|
||||||
|
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)}
|
||||||
|
|
||||||
|
snow.playertable[player:get_player_name()] = exactplayerpos
|
||||||
|
|
||||||
|
player:set_sky("grey", "plain", "", false)
|
||||||
|
|
||||||
|
minetest.add_particlespawner({
|
||||||
|
amount = amountofsnow,
|
||||||
|
-- Number of particles spawned over the time period `time`.
|
||||||
|
|
||||||
|
time = 0,
|
||||||
|
-- Lifespan of spawner in seconds.
|
||||||
|
-- If time is 0 spawner has infinite lifespan and spawns the `amount` on
|
||||||
|
-- a per-second basis.
|
||||||
|
|
||||||
|
minpos = {x=-radius, y=0, z=-radius},
|
||||||
|
maxpos = {x=radius, y=height, z=radius},
|
||||||
|
minvel = {x=-snowvelocity, y=snowfallvelocity[1], z=-snowvelocity},
|
||||||
|
maxvel = {x=snowvelocity, y=snowfallvelocity[2], z=snowvelocity},
|
||||||
|
minacc = {x=0, y=0, z=0},
|
||||||
|
maxacc = {x=0, y=0, z=0},
|
||||||
|
minexptime = 1,
|
||||||
|
maxexptime = 1,
|
||||||
|
minsize = 1,
|
||||||
|
maxsize = 1,
|
||||||
|
-- The particles' properties are random values between the min and max
|
||||||
|
-- values.
|
||||||
|
-- pos, velocity, acceleration, expirationtime, size
|
||||||
|
|
||||||
|
collisiondetection = true,
|
||||||
|
-- If true collide with `walkable` nodes and, depending on the
|
||||||
|
-- `object_collision` field, objects too.
|
||||||
|
|
||||||
|
collision_removal = true,
|
||||||
|
-- If true particles are removed when they collide.
|
||||||
|
-- Requires collisiondetection = true to have any effect.
|
||||||
|
|
||||||
|
object_collision = true,
|
||||||
|
-- If true particles collide with objects that are defined as
|
||||||
|
-- `physical = true,` and `collide_with_objects = true,`.
|
||||||
|
-- Requires collisiondetection = true to have any effect.
|
||||||
|
|
||||||
|
attached = player,
|
||||||
|
-- If defined, particle positions, velocities and accelerations are
|
||||||
|
-- relative to this object's position and yaw
|
||||||
|
|
||||||
|
vertical = true,
|
||||||
|
-- If true face player using y axis only
|
||||||
|
|
||||||
|
texture = "snowflake.png",
|
||||||
|
|
||||||
|
playername = player:get_player_name(),
|
||||||
|
-- Optional, if specified spawns particles only on the player's client
|
||||||
|
|
||||||
|
|
||||||
|
glow = 0
|
||||||
|
-- Optional, specify particle self-luminescence in darkness.
|
||||||
|
-- Values 0-14.
|
||||||
|
})
|
||||||
|
|
||||||
|
end)
|
||||||
|
|
||||||
|
snow.check_nodes = function(pos,name)
|
||||||
|
--[[
|
||||||
|
for x=-snowfallradius,snowfallradius do
|
||||||
|
for z=-snowfallradius,snowfallradius do
|
||||||
|
if math.random() > snowchance then
|
||||||
|
local superpos = {x=pos.x+x,y=pos.y+snowfallheight,z=pos.z+z}
|
||||||
|
local lighttest = minetest.get_node_light(superpos, 0.5)
|
||||||
|
if lighttest and lighttest >= 15 then
|
||||||
|
--minetest.set_node(superpos, {name="snow:snow"})
|
||||||
|
--minetest.spawn_falling_node(superpos)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
]]
|
||||||
|
end
|
||||||
|
--this function actually puts snow and rain on the ground
|
||||||
|
local vm = {}
|
||||||
|
snow.make_snow_fall = function(pos)
|
||||||
|
local range = snowfallradius
|
||||||
|
local height = snowfallheight
|
||||||
|
local air = minetest.get_content_id("air")
|
||||||
|
local snowblock = minetest.get_content_id("snow:snow")
|
||||||
|
local water = minetest.get_content_id("default:water_source")
|
||||||
|
local ice = minetest.get_content_id("default:ice")
|
||||||
|
|
||||||
|
local min = {x=pos.x-range,y=pos.y-height,z=pos.z-range}
|
||||||
|
local max = {x=pos.x+range,y=pos.y+height,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
|
||||||
|
|
||||||
|
print("tying")
|
||||||
|
for x=-range, range do
|
||||||
|
for y=-height, height do
|
||||||
|
for z=-range, range do
|
||||||
|
--if vector.distance(pos, vector.add(pos, {x=x, y=y, z=z})) <= range then
|
||||||
|
--deposit snow randomly
|
||||||
|
local test_deposit_chance = snowchance
|
||||||
|
--if heavy_percip == true then
|
||||||
|
-- test_deposit_chance = test_deposit_chance - 0.25 -- heavy percip
|
||||||
|
--end
|
||||||
|
if math.random() > test_deposit_chance then
|
||||||
|
|
||||||
|
--the actual node being indexed
|
||||||
|
local p_pos = area:index(pos.x+x,pos.y+y,pos.z+z)
|
||||||
|
local l = lightdata[p_pos]
|
||||||
|
|
||||||
|
if l ~= nil and l >= 15 then
|
||||||
|
local n = content_id(data[p_pos])
|
||||||
|
--the node above it (testing for place for snow and water)
|
||||||
|
local p_pos_above = area:index(pos.x+x,pos.y+y+1,pos.z+z)
|
||||||
|
local n_above
|
||||||
|
if p_pos_above and data[p_pos_above] then
|
||||||
|
n_above = content_id(data[p_pos_above])
|
||||||
|
end
|
||||||
|
|
||||||
|
local p_pos_below = area:index(pos.x+x,pos.y+y-1,pos.z+z)
|
||||||
|
local n_below
|
||||||
|
if p_pos_below and data[p_pos_below] then
|
||||||
|
n_below = content_id(data[p_pos_below])
|
||||||
|
end
|
||||||
|
|
||||||
|
if n ~= "air" and n ~= "snow:snow" and n_above == "air" and minetest.registered_nodes[n]["buildable_to"] == true then
|
||||||
|
data[p_pos] = snowblock
|
||||||
|
elseif n == "air" and n_below ~= "air" and minetest.get_item_group(n, "liquid") == 0 and n_below ~= "snow:snow" and minetest.registered_nodes[n_below]["buildable_to"] == false then
|
||||||
|
data[p_pos] = snowblock
|
||||||
|
elseif n == "air" and n_below == "default:water_source" then
|
||||||
|
data[p_pos_below] = ice
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
vm:set_data(data)
|
||||||
|
--if param2er then
|
||||||
|
-- vm:set_param2_data(p2data)
|
||||||
|
--end
|
||||||
|
vm:write_to_map()
|
||||||
|
vm = nil
|
||||||
|
data = nil
|
||||||
|
lightdata = nil
|
||||||
|
|
||||||
|
end
|
||||||
|
--override snow
|
||||||
|
--[[
|
||||||
|
minetest.register_on_mods_loaded(function()
|
||||||
|
minetest.override_item("default:snow", {
|
||||||
|
on_construct = function(pos)
|
||||||
|
minetest.set_node(pos, {name = "snow:snow"})
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
]]--
|
||||||
|
minetest.register_lbm({
|
||||||
|
name = "snow:replacesnow",
|
||||||
|
nodenames = {"default:snow"},
|
||||||
|
action = function(pos, node)
|
||||||
|
minetest.set_node(pos, {name = "snow:snow"})
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
-------
|
||||||
|
|
||||||
|
minetest.register_node("snow:snow", {
|
||||||
|
description = "Snow",
|
||||||
|
tiles = {"default_snow.png"},
|
||||||
|
inventory_image = "default_snowball.png",
|
||||||
|
wield_image = "default_snowball.png",
|
||||||
|
paramtype = "light",
|
||||||
|
buildable_to = true,
|
||||||
|
floodable = true,
|
||||||
|
drawtype = "nodebox",
|
||||||
|
node_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {
|
||||||
|
{-0.5, -0.5, -0.5, 0.5, -0.25, 0.5},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
collision_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {
|
||||||
|
{-0.5, -0.5, -0.5, 0.5, -7 / 16, 0.5},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
groups = {crumbly = 3, falling_node = 1, snowy = 1},
|
||||||
|
sounds = default.node_sound_snow_defaults(),
|
||||||
|
|
||||||
|
on_construct = function(pos)
|
||||||
|
minetest.set_node(pos, {name = "default:snow"})
|
||||||
|
end,
|
||||||
|
})
|
Loading…
Reference in New Issue