redesign the api to have player individual weather
This commit is contained in:
parent
3d9c292590
commit
63a27f5fcc
|
@ -21,7 +21,6 @@ read_globals = {
|
||||||
|
|
||||||
globals = {
|
globals = {
|
||||||
"weather",
|
"weather",
|
||||||
"weather_mod"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exclude_files = {"weather/development/"}
|
exclude_files = {"weather/development/"}
|
||||||
|
|
162
weather/api.lua
162
weather/api.lua
|
@ -1,4 +1,6 @@
|
||||||
weather_mod.registered_downfalls = {}
|
local storage = minetest.get_mod_storage()
|
||||||
|
|
||||||
|
weather.registered_downfalls = {}
|
||||||
|
|
||||||
local function check_modname_prefix(name)
|
local function check_modname_prefix(name)
|
||||||
if name:sub(1,1) == ":" then
|
if name:sub(1,1) == ":" then
|
||||||
|
@ -66,10 +68,10 @@ local default_damage = {
|
||||||
time = 100
|
time = 100
|
||||||
}
|
}
|
||||||
|
|
||||||
function weather_mod.register_downfall(id,def)
|
function weather.register_downfall(id,def)
|
||||||
local name = check_modname_prefix(id)
|
local name = check_modname_prefix(id)
|
||||||
if name == "none" then error("\"none\" means none, thanks") end
|
if name == "none" then error("\"none\" means none, thanks") end
|
||||||
if weather_mod.registered_downfalls[name]~=nil then error(name.." is already registered") end
|
if weather.registered_downfalls[name]~=nil then error(name.." is already registered") end
|
||||||
local ndef = table.copy(def)
|
local ndef = table.copy(def)
|
||||||
--what the downfall looks like
|
--what the downfall looks like
|
||||||
if not ndef.texture then
|
if not ndef.texture then
|
||||||
|
@ -78,26 +80,26 @@ function weather_mod.register_downfall(id,def)
|
||||||
set_defaults(ndef,default_downfall)
|
set_defaults(ndef,default_downfall)
|
||||||
--when to delete the particles
|
--when to delete the particles
|
||||||
if not ndef.exptime then
|
if not ndef.exptime then
|
||||||
ndef.exptime = ndef.max_pos.y / (math.sqrt(ndef.falling_acceleration) + ndef.falling_speed)
|
ndef.exptime = ndef.max_pos.y / ndef.falling_speed
|
||||||
end
|
end
|
||||||
if ndef.damage_player then
|
if ndef.damage_player then
|
||||||
set_defaults(ndef.damage_player,default_damage)
|
set_defaults(ndef.damage_player,default_damage)
|
||||||
end
|
end
|
||||||
--actually register the downfall
|
--actually register the downfall
|
||||||
weather_mod.registered_downfalls[name]=ndef
|
weather.registered_downfalls[name]=ndef
|
||||||
end
|
end
|
||||||
|
|
||||||
function weather_mod.disable_downfall(id,disable)
|
function weather.disable_downfall(id,disable)
|
||||||
local state = disable
|
local state = disable
|
||||||
if disable == nil then
|
if disable == nil then
|
||||||
state = true
|
state = true
|
||||||
end
|
end
|
||||||
weather_mod.registered_downfalls[id].disabled = state
|
weather.registered_downfalls[id].disabled = state
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
if minetest.get_modpath("lightning") then
|
if minetest.get_modpath("lightning") then
|
||||||
lightning.auto = false
|
lightning.auto = false
|
||||||
--rawset(lightning,"auto",false)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function weather_mod.handle_lightning(current_weather)
|
function weather_mod.handle_lightning(current_weather)
|
||||||
|
@ -110,10 +112,47 @@ function weather_mod.handle_lightning(current_weather)
|
||||||
minetest.after(time, lightning.strike)
|
minetest.after(time, lightning.strike)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
]]
|
||||||
|
|
||||||
local do_raycasts = minetest.is_yes(minetest.settings:get_bool('raycast_hitcheck'))
|
local do_raycasts = minetest.is_yes(minetest.settings:get_bool('raycast_hitcheck'))
|
||||||
local damage_steps = 0
|
local damage_steps = 0
|
||||||
|
|
||||||
|
local function get_player_meta(player)
|
||||||
|
local p = player
|
||||||
|
if type(player) == "string" then
|
||||||
|
p = minetest.get_player_by_name(player)
|
||||||
|
end
|
||||||
|
return p:get_meta()
|
||||||
|
end
|
||||||
|
|
||||||
|
function weather.get_weather(player)
|
||||||
|
local meta = get_player_meta(player)
|
||||||
|
return meta:get_string("weather_type")
|
||||||
|
end
|
||||||
|
|
||||||
|
function weather.set_weather(player,type)
|
||||||
|
local meta = get_player_meta(player)
|
||||||
|
meta:set_string("weather_type",type)
|
||||||
|
end
|
||||||
|
|
||||||
|
function weather.get_wind()
|
||||||
|
return {
|
||||||
|
x = storage:get_float("wind_x"),
|
||||||
|
y = 0,
|
||||||
|
z = storage:get_float("wind_z")
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function weather.set_wind(x,z)
|
||||||
|
if type(x) == "table" then
|
||||||
|
storage:set_float("wind_x",x.x)
|
||||||
|
storage:set_float("wind_z",x.z)
|
||||||
|
else
|
||||||
|
storage:set_float("wind_x",x)
|
||||||
|
storage:set_float("wind_z",z)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function handle_damage(damage,player, downfall_origin)
|
local function handle_damage(damage,player, downfall_origin)
|
||||||
if not damage then return end
|
if not damage then return end
|
||||||
damage_steps = damage_steps +1
|
damage_steps = damage_steps +1
|
||||||
|
@ -143,64 +182,67 @@ local function handle_damage(damage,player, downfall_origin)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function weather_step()
|
local function weather_step(player,meta)
|
||||||
local current_downfall = weather_mod.registered_downfalls[weather.type]
|
local weather_type = meta:get_string("weather_type")
|
||||||
if current_downfall==nil then return end
|
if weather_type and weather_type ~= "" and weather_type ~= "none" then
|
||||||
for _, player in ipairs(minetest.get_connected_players()) do
|
local current_downfall = weather.registered_downfalls[weather_type]
|
||||||
local ppos = player:getpos()
|
if current_downfall then
|
||||||
|
local ppos = player:getpos()
|
||||||
|
|
||||||
|
if ppos.y > 120 then return end
|
||||||
|
|
||||||
|
local wind = weather.get_wind()
|
||||||
|
local wind_pos = vector.multiply(wind,-1)
|
||||||
|
|
||||||
if ppos.y > 120 then return end
|
local minp = vector.add(vector.add(ppos, current_downfall.min_pos),wind_pos)
|
||||||
|
local maxp = vector.add(vector.add(ppos, current_downfall.max_pos),wind_pos)
|
||||||
local wind_pos = vector.multiply(weather.wind,-1)
|
|
||||||
|
local vel = {x=wind.x,y=-current_downfall.falling_speed,z=wind.z}
|
||||||
local minp = vector.add(vector.add(ppos, current_downfall.min_pos),wind_pos)
|
local acc = {x=0, y=0, z=0}
|
||||||
local maxp = vector.add(vector.add(ppos, current_downfall.max_pos),wind_pos)
|
|
||||||
|
local exp = current_downfall.exptime
|
||||||
local vel = {x=weather.wind.x,y=-current_downfall.falling_speed,z=weather.wind.z}
|
|
||||||
local acc = {x=0, y=0, z=0}
|
minetest.add_particlespawner({
|
||||||
|
amount=current_downfall.amount, time=0.5,
|
||||||
local exp = current_downfall.exptime
|
minpos=minp, maxpos=maxp,
|
||||||
|
minvel=vel, maxvel=vel,
|
||||||
minetest.add_particlespawner({
|
minacc=acc, maxacc=acc,
|
||||||
amount=current_downfall.amount, time=0.5,
|
minexptime=exp, maxexptime=exp,
|
||||||
minpos=minp, maxpos=maxp,
|
minsize=current_downfall.size, maxsize=current_downfall.size,
|
||||||
minvel=vel, maxvel=vel,
|
collisiondetection=true, collision_removal=true,
|
||||||
minacc=acc, maxacc=acc,
|
vertical=true,
|
||||||
minexptime=exp, maxexptime=exp,
|
texture=current_downfall.texture, playername=player:get_player_name()
|
||||||
minsize=current_downfall.size, maxsize=current_downfall.size,
|
})
|
||||||
collisiondetection=true, collision_removal=true,
|
|
||||||
vertical=true,
|
local downfall_origin = vector.divide(vector.add(minp,maxp),2)
|
||||||
texture=current_downfall.texture, player=player:get_player_name()
|
handle_damage(current_downfall.damage_player,player,downfall_origin)
|
||||||
})
|
end
|
||||||
|
|
||||||
local downfall_origin = vector.divide(vector.add(minp,maxp),2)
|
|
||||||
handle_damage(current_downfall.damage_player,player,downfall_origin)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_globalstep(function()
|
minetest.register_globalstep(function()
|
||||||
if math.random(1, 10000) == 1 then
|
if math.random(1, 50000) == 1 then
|
||||||
weather.type = "none"
|
weather.set_wind(math.random(0,10),math.random(0,10))
|
||||||
if minetest.get_modpath("lightning") then
|
end
|
||||||
lightning.auto = false
|
for _, player in ipairs(minetest.get_connected_players()) do
|
||||||
--rawset(lightning,"auto",false)
|
local meta = get_player_meta(player)
|
||||||
end
|
if math.random(1, 10000) == 1 then
|
||||||
else
|
meta:set_string("weather_type","none")
|
||||||
for id,w in pairs(weather_mod.registered_downfalls) do
|
--[[if minetest.get_modpath("lightning") then
|
||||||
if math.random(1, 50000) == 1 then
|
lightning.auto = false
|
||||||
weather.wind = {
|
end]]
|
||||||
x = math.random(0,10),
|
else
|
||||||
y = 0,
|
for id,w in pairs(weather.registered_downfalls) do
|
||||||
z = math.random(0,10)
|
if math.random(1, 50000) == 1 then
|
||||||
}
|
if (not w.disabled) and vector.length(weather.get_wind()) >= w.min_wind then
|
||||||
if (not w.disabled) and vector.length(weather.wind) >= w.min_wind then
|
meta:set_string("weather_type",id)
|
||||||
weather.type = id
|
--weather_mod.handle_lightning(w)
|
||||||
weather_mod.handle_lightning(w)
|
break
|
||||||
break
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
weather_step()
|
weather_step(player,meta)
|
||||||
end)
|
end
|
||||||
|
end)
|
||||||
|
|
|
@ -3,29 +3,35 @@ minetest.register_privilege("weather", {
|
||||||
give_to_singleplayer = false
|
give_to_singleplayer = false
|
||||||
})
|
})
|
||||||
|
|
||||||
|
local function list_types()
|
||||||
|
local types="none"
|
||||||
|
for i,_ in pairs(weather.registered_downfalls) do
|
||||||
|
types=types..", "..i
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Set weather
|
-- Set weather
|
||||||
minetest.register_chatcommand("setweather", {
|
minetest.register_chatcommand("setweather", {
|
||||||
params = "<weather>",
|
params = "<weather>",
|
||||||
description = "Set weather to a registered type of downfall\
|
description = "Set weather to a registered type of downfall\
|
||||||
show all types when no parameters are given", -- full description
|
show all types when no parameters are given", -- full description
|
||||||
privs = {weather = true},
|
privs = {weather = true},
|
||||||
func = function(name, param)
|
func = function(name, param)
|
||||||
if param == nil or param == "" or param == "?" then
|
if param == nil or param == "" or param == "?" then
|
||||||
local types="none"
|
return false, "registered weather types: "..list_types()
|
||||||
for i,_ in pairs(weather_mod.registered_downfalls) do
|
end
|
||||||
types=types..", "..i
|
local w = weather.registered_downfalls[param]
|
||||||
end
|
if (not w) and param ~= "none" then
|
||||||
minetest.chat_send_player(name, "avalible weather types: "..types)
|
return false, "This type of weather is not registered.\n"..
|
||||||
else
|
"registered types: "..list_types()
|
||||||
if weather_mod.registered_downfalls[param] == nil and not param == "none" then
|
end
|
||||||
minetest.chat_send_player(name, "This type of weather is not registered.\n"..
|
if w.disabled then
|
||||||
"To list all types of weather run the command without parameters.")
|
minetest.chat_send_player(name,param.." is disabled.")
|
||||||
else
|
end
|
||||||
weather.type = param
|
weather.set_weather(name,param)
|
||||||
weather_mod.handle_lightning()
|
--weather_mod.handle_lightning()
|
||||||
end
|
return true
|
||||||
end
|
end
|
||||||
end
|
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Set wind
|
-- Set wind
|
||||||
|
@ -35,8 +41,7 @@ minetest.register_chatcommand("setwind", {
|
||||||
privs = {weather = true},
|
privs = {weather = true},
|
||||||
func = function(name, param)
|
func = function(name, param)
|
||||||
if param==nil or param=="" then
|
if param==nil or param=="" then
|
||||||
minetest.chat_send_player(name, "please provide two comma seperated numbers")
|
return false,"please provide two comma seperated numbers"
|
||||||
return
|
|
||||||
end
|
end
|
||||||
local x,z = string.match(param, "^([%d.-]+)[, ] *([%d.-]+)$")
|
local x,z = string.match(param, "^([%d.-]+)[, ] *([%d.-]+)$")
|
||||||
x=tonumber(x)
|
x=tonumber(x)
|
||||||
|
@ -45,9 +50,10 @@ minetest.register_chatcommand("setwind", {
|
||||||
x, z = string.match(param, "^%( *([%d.-]+)[, ] *([%d.-]+) *%)$")
|
x, z = string.match(param, "^%( *([%d.-]+)[, ] *([%d.-]+) *%)$")
|
||||||
end
|
end
|
||||||
if x and z then
|
if x and z then
|
||||||
weather.wind = vector.new(x,0,z)
|
weather.set_wind(x,z)
|
||||||
|
return true
|
||||||
else
|
else
|
||||||
minetest.chat_send_player(name, param.." are not two comma seperated numbers")
|
return false,param.." are not two comma seperated numbers"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,39 +1,11 @@
|
||||||
-- Weather:
|
|
||||||
-- * rain
|
|
||||||
-- * snow
|
|
||||||
-- * wind
|
|
||||||
|
|
||||||
assert(minetest.add_particlespawner, "Weather doesn't work with this really old minetest.")
|
assert(minetest.add_particlespawner, "Weather doesn't work with this really old minetest.")
|
||||||
|
|
||||||
weather_mod={
|
weather = {
|
||||||
modpath=minetest.get_modpath("weather"),
|
modpath = minetest.get_modpath("weather"),
|
||||||
}
|
}
|
||||||
|
|
||||||
weather = (function()
|
dofile(weather.modpath.."/api.lua")
|
||||||
local file_name = minetest.get_worldpath() .. "/weather"
|
dofile(weather.modpath.."/rain.lua")
|
||||||
|
dofile(weather.modpath.."/sand.lua")
|
||||||
minetest.register_on_shutdown(function()
|
dofile(weather.modpath.."/snow.lua")
|
||||||
local file = io.open(file_name, "w")
|
dofile(weather.modpath.."/command.lua")
|
||||||
file:write(minetest.serialize(weather))
|
|
||||||
file:close()
|
|
||||||
end)
|
|
||||||
|
|
||||||
local file = io.open(file_name, "r")
|
|
||||||
if file ~= nil then
|
|
||||||
local readweather = minetest.deserialize(file:read("*a"))
|
|
||||||
file:close()
|
|
||||||
if type(readweather)~="table" then
|
|
||||||
return {type = "none", wind = 0}
|
|
||||||
end
|
|
||||||
return readweather
|
|
||||||
end
|
|
||||||
return {type = "none", wind = vector.new(0,0,0)}
|
|
||||||
end) ()
|
|
||||||
|
|
||||||
dofile(weather_mod.modpath.."/api.lua")
|
|
||||||
dofile(weather_mod.modpath.."/rain.lua")
|
|
||||||
dofile(weather_mod.modpath.."/sand.lua")
|
|
||||||
dofile(weather_mod.modpath.."/snow.lua")
|
|
||||||
dofile(weather_mod.modpath.."/command.lua")
|
|
||||||
|
|
||||||
weather_mod.handle_lightning()
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
-- Rain
|
-- Rain
|
||||||
weather_mod.register_downfall("weather:rain",{
|
weather.register_downfall("weather:rain",{
|
||||||
min_pos = {x=-15, y=7, z=-15},
|
min_pos = {x=-15, y=7, z=-15},
|
||||||
max_pos = {x= 15, y=7, z= 15},
|
max_pos = {x= 15, y=7, z= 15},
|
||||||
falling_speed=10,
|
falling_speed=10,
|
||||||
|
@ -10,7 +10,7 @@ weather_mod.register_downfall("weather:rain",{
|
||||||
enable_lightning=true,
|
enable_lightning=true,
|
||||||
})
|
})
|
||||||
|
|
||||||
weather_mod.register_downfall("weather:storm",{
|
weather.register_downfall("weather:storm",{
|
||||||
min_pos = {x = -15, y = 7, z = -15},
|
min_pos = {x = -15, y = 7, z = -15},
|
||||||
max_pos = {x = 15, y = 7, z = 15},
|
max_pos = {x = 15, y = 7, z = 15},
|
||||||
falling_speed = 10,
|
falling_speed = 10,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
weather_mod.register_downfall("weather:sandstorm",{
|
weather.register_downfall("weather:sandstorm",{
|
||||||
min_pos = {x=-20, y=0, z=-20},
|
min_pos = {x=-20, y=0, z=-20},
|
||||||
max_pos = {x= 20, y=2, z= 20},
|
max_pos = {x= 20, y=2, z= 20},
|
||||||
falling_speed=-1,
|
falling_speed=-1,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
-- Snow
|
-- Snow
|
||||||
weather_mod.register_downfall("weather:snow",{
|
weather.register_downfall("weather:snow",{
|
||||||
min_pos = {x=-15, y=7, z=-15},
|
min_pos = {x=-15, y=7, z=-15},
|
||||||
max_pos = {x= 15, y=7, z= 15},
|
max_pos = {x= 15, y=7, z= 15},
|
||||||
falling_speed=5,
|
falling_speed=5,
|
||||||
|
@ -9,7 +9,7 @@ weather_mod.register_downfall("weather:snow",{
|
||||||
texture="weather_snow.png",
|
texture="weather_snow.png",
|
||||||
})
|
})
|
||||||
|
|
||||||
weather_mod.register_downfall("weather:hail",{
|
weather.register_downfall("weather:hail",{
|
||||||
min_pos = {x=-15, y=7, z=-15},
|
min_pos = {x=-15, y=7, z=-15},
|
||||||
max_pos = {x= 15, y=7, z= 15},
|
max_pos = {x= 15, y=7, z= 15},
|
||||||
falling_speed=25,
|
falling_speed=25,
|
||||||
|
@ -37,6 +37,25 @@ minetest.register_node("weather:snow_cover", {
|
||||||
drop = {}
|
drop = {}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
local function get_nearest_player(pos,range_distance)
|
||||||
|
local player, min_distance = nil, range_distance
|
||||||
|
local position = pos
|
||||||
|
|
||||||
|
local all_objects = minetest.get_objects_inside_radius(position, range_distance)
|
||||||
|
for _, object in pairs(all_objects) do
|
||||||
|
if object:is_player() then
|
||||||
|
local player_position = object:getpos()
|
||||||
|
local distance = vector.distance(position, player_position)
|
||||||
|
|
||||||
|
if distance < min_distance then
|
||||||
|
min_distance = distance
|
||||||
|
player = object
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return player
|
||||||
|
end
|
||||||
|
|
||||||
-- Snow cover ABM when snow_covers_abm setting is set to `true`
|
-- Snow cover ABM when snow_covers_abm setting is set to `true`
|
||||||
if minetest.is_yes(minetest.settings:get_bool('snow_covers_abm')) then
|
if minetest.is_yes(minetest.settings:get_bool('snow_covers_abm')) then
|
||||||
minetest.log('action', '[weather] Loaded fast computer ABM (snow covers when weather:snow is set)')
|
minetest.log('action', '[weather] Loaded fast computer ABM (snow covers when weather:snow is set)')
|
||||||
|
@ -46,16 +65,19 @@ if minetest.is_yes(minetest.settings:get_bool('snow_covers_abm')) then
|
||||||
interval = 10.0,
|
interval = 10.0,
|
||||||
chance = 80,
|
chance = 80,
|
||||||
action = function (pos, node)
|
action = function (pos, node)
|
||||||
if weather.type == "weather:snow" then
|
local player = get_nearest_player(pos,50)
|
||||||
if minetest.registered_nodes[node.name].drawtype == "normal"
|
if not player then return end
|
||||||
or minetest.registered_nodes[node.name].drawtype == "allfaces_optional" then
|
if weather.get_type(player) ~= "weather:snow" then
|
||||||
local np = vector.add(pos, {x=0, y=1, z=0})
|
return
|
||||||
if minetest.env:get_node_light(np, 0.5) == 15
|
end
|
||||||
and minetest.env:get_node(np).name == "air" then
|
if minetest.registered_nodes[node.name].drawtype == "normal"
|
||||||
minetest.env:add_node(np, {name="weather:snow_cover"})
|
or minetest.registered_nodes[node.name].drawtype == "allfaces_optional" then
|
||||||
end
|
local np = vector.add(pos, {x=0, y=1, z=0})
|
||||||
end
|
if minetest.env:get_node_light(np, 0.5) == 15
|
||||||
end
|
and minetest.env:get_node(np).name == "air" then
|
||||||
end
|
minetest.env:add_node(np, {name="weather:snow_cover"})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue