Initial commit

master
luk3yx 2020-07-26 22:57:41 +12:00
commit 2875526f02
7 changed files with 389 additions and 0 deletions

38
README.md Normal file
View File

@ -0,0 +1,38 @@
MultiCraft Game mod: weather_lite
=================================
Authors of source code
----------------------
Based on Weather mod
Copyright (C) Jeija (2013)
Copyright (C) HybridDog (2015)
Copyright (C) theFox6 (2018)
Copyright (C) MultiCraft Development Team (2019-2020)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3.0 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Authors of textures
-------------------
TeddyDesTodes (textures) CC-BY-SA 3.0:
* weather_lite_rain.png
* weather_lite_snow.png

2
depends.txt Normal file
View File

@ -0,0 +1,2 @@
default
sscsm?

272
init.lua Normal file
View File

@ -0,0 +1,272 @@
if not minetest.settings:get_bool("enable_weather") then
return
end
local vmultiply, vadd = vector.multiply, vector.add
local random = math.random
local snow_covers = minetest.settings:get_bool("weather_snow_covers") ~= false
local weather = {
type = "none",
wind = {x = 0, y = 0, z = 0}
}
--
-- Save and restore weather condition
--
local mod_storage = minetest.get_mod_storage()
do
local saved_weather = minetest.deserialize(
mod_storage:get_string("weather"))
if type(saved_weather) == "table" then
weather = saved_weather
end
end
minetest.register_on_shutdown(function()
mod_storage:set_string("weather", minetest.serialize(
({type = weather.type, wind = weather.wind})))
end)
--
-- Registration of weather types
--
weather.registered = {}
function weather.register(id, def)
local ndef = table.copy(def)
weather.registered[id] = ndef
end
-- Rain
weather.register("rain", {
falling_speed = 5,
amount = 7,
size = 25,
height = 3,
vertical = true,
texture = "weather_lite_rain.png"
})
-- Snow
weather.register("snow", {
falling_speed = 2,
amount = 5,
size = 35,
height = 2,
texture = "weather_lite_snow.png"
})
--
-- Change of weather
--
function weather.set(weather_type, wind)
weather.type = weather_type
if wind then
weather.wind = wind
end
if minetest.global_exists("sscsm") then
sscsm.com_send_all("weather_lite:set", {
type = weather_type,
wind = wind
})
end
end
local function weather_change()
if weather.type == "none" then
for id, _ in pairs(weather.registered) do
if random(3) == 1 then
weather.set(id, {
x = random(0, 8),
y = 0,
z = random(0, 8)
})
break
end
end
minetest.after(random(60, 300), weather_change)
else
weather.set("none")
minetest.after(random(1800, 3600), weather_change)
end
end
minetest.after(random(600, 1800), weather_change)
--
-- Processing players
--
local is_valid_pos = minetest.is_valid_pos
if not is_valid_pos then
is_valid_pos = function() return true end
end
-- This is a separate function to prevent "return" from breaking.
local function process_player(player, current_downfall)
local player_name = player:get_player_name()
if not player:is_player() or (sscsm and sscsm.has_sscsms_enabled(player_name)) then
return
end
local ppos = vector.round(player:get_pos())
ppos.y = ppos.y + 1.5
-- Higher than clouds
local cloud_height = player:get_clouds().height
cloud_height = cloud_height ~= 0 and cloud_height or 120
if not is_valid_pos(ppos) or ppos.y > cloud_height or ppos.y < -8 then return end
-- Inside liquid
local head_inside = minetest.get_node_or_nil(ppos)
local def_inside = head_inside and minetest.registered_nodes[head_inside.name]
if def_inside and def_inside.drawtype == "liquid" then return end
-- Too dark, probably not under the sky
local light = minetest.get_node_light(ppos, 0.5)
if light and light < 12 then return end
local wind_pos = vmultiply(weather.wind, -1)
local minp = vadd(vadd(ppos, {x = -8, y = current_downfall.height, z = -8}), wind_pos)
local maxp = vadd(vadd(ppos, {x = 8, y = current_downfall.height, z = 8}), wind_pos)
local vel = {x = weather.wind.x, y = -current_downfall.falling_speed, z = weather.wind.z}
local vert = current_downfall.vertical or false
minetest.add_particlespawner({
amount = current_downfall.amount,
time = 0.1,
minpos = minp,
maxpos = maxp,
minvel = vel,
maxvel = vel,
minsize = current_downfall.size,
maxsize = current_downfall.size,
collisiondetection = true,
collision_removal = true,
vertical = vert,
texture = current_downfall.texture,
glow = 1,
playername = player_name
})
end
minetest.register_globalstep(function()
local current_downfall = weather.registered[weather.type]
if current_downfall == nil then return end
for _, player in pairs(minetest.get_connected_players()) do
process_player(player, current_downfall)
end
end)
--
-- Snow will cover the blocks and melt after some time
--
if snow_covers then
-- Temp node to start the node timer
minetest.register_node("weather_lite:snow_cover", {
tiles = {"blank.png"},
drawtype = "signlike",
buildable_to = true,
groups = {not_in_creative_inventory = 1, dig_immediate = 3},
on_construct = function(pos)
minetest.get_node_timer(pos):start(random(60, 180))
minetest.swap_node(pos, {name = "default:snow"})
end
})
minetest.override_item("default:snow", {
on_timer = function(pos)
if weather and weather.type and weather.type == "snow" then
return true
end
minetest.remove_node(pos)
end
})
minetest.register_abm({
label = "Weather: snow cover",
nodenames = {"group:crumbly", "group:snappy", "group:cracky", "group:choppy"},
neighbors = {"air"},
interval = 15,
chance = 500,
catch_up = false,
action = function(pos, node)
if weather.type == "snow" then
if pos.y < -8 or pos.y > 120 then return end
if minetest.registered_nodes[node.name].drawtype == "normal"
or minetest.registered_nodes[node.name].drawtype == "allfaces_optional" then
pos.y = pos.y + 1
if minetest.get_node(pos).name ~= "air" then return end
local light_day = minetest.get_node_light(pos, 0.5)
local light_night = minetest.get_node_light(pos, 0)
if light_day and light_day == 15
and light_night and light_night < 10 then
minetest.add_node(pos, {name = "weather_lite:snow_cover"})
end
end
end
end
})
end
minetest.register_privilege("weather", {
description = "Allows changing the weather",
give_to_singleplayer = minetest.settings:get_bool("creative_mode")
})
minetest.register_chatcommand("weather", {
params = "<weather>",
description = "Set weather type",
privs = {weather = true},
func = function(name, param)
if param and (weather.registered[param] or param == "none") then
weather.set(param)
minetest.chat_send_player(name, "Set weather type: " .. param)
else
local types = "none"
for w, _ in pairs(weather.registered) do
types = types .. ", " .. w
end
minetest.chat_send_player(name, "Avalible weather types: " .. types)
end
end
})
if not minetest.global_exists("sscsm") then
return
end
sscsm.register({
name = "weather_lite",
file = minetest.get_modpath("weather_lite") .. "/sscsm.lua"
})
local liquids
sscsm.register_on_sscsms_loaded(function(name)
if not liquids then
liquids = {}
for node, def in pairs(minetest.registered_nodes) do
if def.drawtype == "liquid" then
liquids[node] = true
end
end
end
local player = minetest.get_player_by_name(name)
sscsm.com_send(name, "weather_lite:set", {
type = weather.type,
wind = weather.wind,
registered = weather.registered,
cloud_height = player:get_clouds().height,
liquids = liquids
})
end)

3
mod.conf Normal file
View File

@ -0,0 +1,3 @@
name = weather_lite
depends = default
optional_depends = sscsm

74
sscsm.lua Normal file
View File

@ -0,0 +1,74 @@
local vmultiply, vadd = vector.multiply, vector.add
local random = math.random
local weather = {
type = "none",
wind = {x = 0, y = 0, z = 0},
registered = {},
liquids = {}
}
local is_valid_pos = minetest.is_valid_pos
if not is_valid_pos then
is_valid_pos = function() return true end
end
--
-- Change of weather
--
sscsm.register_on_com_receive("weather_lite:set", function(msg)
for k, v in pairs(msg) do
weather[k] = v
end
end)
--
-- Processing players
--
assert(minetest.localplayer)
sscsm.every(0.09, function()
local current_downfall = weather.registered[weather.type]
if current_downfall == nil then return end
local ppos = vector.round(minetest.localplayer:get_pos())
ppos.y = ppos.y + 1.5
-- Higher than clouds
local cloud_height = weather.cloud_height
cloud_height = cloud_height ~= 0 and cloud_height or 120
if not is_valid_pos(ppos) or ppos.y > cloud_height or ppos.y < -8 then return end
-- Inside liquid
local head_inside = minetest.get_node_or_nil(ppos)
if head_inside and weather.liquids[head_inside.name] then return end
-- Too dark, probably not under the sky
if minetest.get_node_light then
local light = minetest.get_node_light(ppos, 0.5)
if light and light < 12 then return end
end
local wind_pos = vmultiply(weather.wind, -1)
local minp = vadd(vadd(ppos, {x = -8, y = current_downfall.height, z = -8}), wind_pos)
local maxp = vadd(vadd(ppos, {x = 8, y = current_downfall.height, z = 8}), wind_pos)
local vel = {x = weather.wind.x, y = -current_downfall.falling_speed, z = weather.wind.z}
local vert = current_downfall.vertical or false
minetest.add_particlespawner({
amount = current_downfall.amount,
time = 0.1,
minpos = minp,
maxpos = maxp,
minvel = vel,
maxvel = vel,
minsize = current_downfall.size,
maxsize = current_downfall.size,
collisiondetection = true,
collision_removal = true,
vertical = vert,
texture = current_downfall.texture,
glow = 1
})
end)

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 569 B