Merge branch 'master' into day_night_ratio
|
@ -109,6 +109,7 @@ These groups are used mostly for informational purposes
|
|||
* `flower_pot=2`: Flower pot with a plant or flower
|
||||
* `flower=1`: Flower
|
||||
* `place_flowerlike=1`: Node has placement rules like that of a flower
|
||||
* `place_flowerlike=2`: Node has placement rules like tall grass
|
||||
* `cake`: Cake (rating = slices left)
|
||||
* `book=1`: Book
|
||||
* `pane=1`: Node is a “pane”-like node glass pane or iron bars
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
An unofficial Minecraft-like game for Minetest. Forked from MineClone by daredevils.
|
||||
Developed by Wuzzy and contributors. Not developed or endorsed by Mojang AB.
|
||||
|
||||
Version: 0.29.2
|
||||
Version: 0.30.0
|
||||
|
||||
### Gameplay
|
||||
You start in a randomly-generated world made entirely of cubes. You can explore
|
||||
|
@ -149,6 +149,7 @@ Bonus features (not found in Minecraft 1.11):
|
|||
* Built-in crafting guide which shows you crafting and smelting recipes
|
||||
* In-game help system containing extensive help about gameplay basics, blocks, items and more
|
||||
* Temporary crafting recipes. They only exist to make some otherwise unaccessible items available when you're not in creative mode. These recipes will be removed as development goes on an more features become available
|
||||
* Saplings in chests (only in mapgen v6, because only 3 out of 6 tree species grow here)
|
||||
|
||||
Technical differences from Minecraft:
|
||||
|
||||
|
@ -161,7 +162,7 @@ Technical differences from Minecraft:
|
|||
* Different textures (Pixel Perfection)
|
||||
* Different sounds (various sources)
|
||||
* Different engine (Minetest)
|
||||
* Free software (“free” as in freedom *and* free beer)
|
||||
* Free software (“free” as in freedom)
|
||||
|
||||
## Reporting bugs
|
||||
Please report all bugs and missing Minecraft features here:
|
||||
|
|
|
@ -72,6 +72,8 @@ end
|
|||
mcl_vars.mg_end_min = -27073 -- Carefully chosen to be at a mapchunk border
|
||||
mcl_vars.mg_end_max_official = mcl_vars.mg_end_min + minecraft_height_limit
|
||||
mcl_vars.mg_end_max = mcl_vars.mg_overworld_min - 2000
|
||||
mcl_vars.mg_end_platform_pos = { x = 100, y = mcl_vars.mg_end_min + 80, z = 0 }
|
||||
|
||||
-- Realm barrier used to safely separate the End from the void below the Overworld
|
||||
mcl_vars.mg_realm_barrier_overworld_end_max = mcl_vars.mg_end_max
|
||||
mcl_vars.mg_realm_barrier_overworld_end_min = mcl_vars.mg_end_max - 11
|
||||
|
|
|
@ -134,3 +134,10 @@ function mcl_sounds.node_sound_water_defaults(table)
|
|||
mcl_sounds.node_sound_defaults(table)
|
||||
return table
|
||||
end
|
||||
|
||||
|
||||
-- Player death sound
|
||||
minetest.register_on_dieplayer(function(player)
|
||||
-- TODO: Add separate death sound
|
||||
minetest.sound_play({name="player_damage", gain = 1.0}, {pos=player:get_pos(), max_hear_distance=16})
|
||||
end)
|
||||
|
|
|
@ -411,10 +411,12 @@ end
|
|||
mcl_util.clock_works = mcl_util.compass_works
|
||||
|
||||
-- Returns a on_place function for plants
|
||||
-- * condition: function(pos, node)
|
||||
-- * condition: function(pos, node, itemstack)
|
||||
-- * A function which is called by the on_place function to check if the node can be placed
|
||||
-- * Must return true, if placement is allowed, false otherwise
|
||||
-- * Must return true, if placement is allowed, false otherwise.
|
||||
-- * If it returns a string, placement is allowed, but will place this itemstring as a node instead
|
||||
-- * pos, node: Position and node table of plant node
|
||||
-- * itemstack: Itemstack to place
|
||||
function mcl_util.generate_on_place_plant_function(condition)
|
||||
return function(itemstack, placer, pointed_thing)
|
||||
if pointed_thing.type ~= "node" then
|
||||
|
@ -445,9 +447,10 @@ function mcl_util.generate_on_place_plant_function(condition)
|
|||
end
|
||||
|
||||
-- Check placement rules
|
||||
if (condition(place_pos, node) == true) then
|
||||
local result, param2 = condition(place_pos, node, itemstack)
|
||||
if result == true then
|
||||
local idef = itemstack:get_definition()
|
||||
local new_itemstack, success = minetest.item_place_node(itemstack, placer, pointed_thing)
|
||||
local new_itemstack, success = minetest.item_place_node(itemstack, placer, pointed_thing, param2)
|
||||
|
||||
if success then
|
||||
if idef.sounds and idef.sounds.place then
|
||||
|
|
|
@ -241,6 +241,19 @@ mobs_mc.enderman_takable = {
|
|||
"nether:rack",
|
||||
}
|
||||
|
||||
--[[ Table of nodes to replace when an enderman takes it.
|
||||
If the enderman takes an indexed node, it the enderman will get the item in the value.
|
||||
Table indexes: Original node, taken by enderman.
|
||||
Table values: The item which the enderman *actually* gets
|
||||
Example:
|
||||
mobs_mc.enderman_node_replace = {
|
||||
["default:dirt_with_dry_grass"] = "default_dirt_with_grass",
|
||||
}
|
||||
-- This means, if the enderman takes a dirt with dry grass, he will get a dirt with grass
|
||||
-- on his hand instead.
|
||||
]]
|
||||
mobs_mc.enderman_replace_on_take = {} -- no replacements by default
|
||||
|
||||
-- A table which can be used to override block textures of blocks carried by endermen.
|
||||
-- Only works for cube-shaped nodes and nodeboxes.
|
||||
-- Key: itemstrings of the blocks to replace
|
||||
|
@ -307,6 +320,9 @@ if minetest.get_modpath("mobs_mc_gameconfig") and mobs_mc.override then
|
|||
if mobs_mc.override.enderman_takable then
|
||||
mobs_mc.enderman_takable = mobs_mc.override.enderman_takable
|
||||
end
|
||||
if mobs_mc.override.enderman_replace_on_take then
|
||||
mobs_mc.enderman_replace_on_take = mobs_mc.override.enderman_replace_on_take
|
||||
end
|
||||
if mobs_mc.enderman_block_texture_overrides then
|
||||
mobs_mc.enderman_block_texture_overrides = mobs_mc.override.enderman_block_texture_overrides
|
||||
end
|
||||
|
|
|
@ -213,7 +213,11 @@ mobs:register_mob("mobs_mc:enderman", {
|
|||
local node = minetest.get_node(take_pos)
|
||||
local dug = minetest.dig_node(take_pos)
|
||||
if dug then
|
||||
if mobs_mc.enderman_replace_on_take[node.name] then
|
||||
self._taken_node = mobs_mc.enderman_replace_on_take[node.name]
|
||||
else
|
||||
self._taken_node = node.name
|
||||
end
|
||||
local def = minetest.registered_nodes[self._taken_node]
|
||||
-- Update animation and texture accordingly (adds visibly carried block)
|
||||
local block_type
|
||||
|
|
|
@ -86,7 +86,8 @@ mobs_mc.override.items = {
|
|||
mycelium = "mcl_core:mycelium",
|
||||
carrot = "mcl_farming:carrot_item",
|
||||
golden_carrot = "mcl_farming:carrot_item_gold",
|
||||
fishing_rod = "mcl_fishing:fishing_rod",
|
||||
fishing_rod = "mcl_core:stick",
|
||||
--TODO: Re-enable: fishing_rod = "mcl_fishing:fishing_rod",
|
||||
fish_raw = "mcl_fishing:fish_raw",
|
||||
salmon_raw = "mcl_fishing:salmon_raw",
|
||||
clownfish_raw = "mcl_fishing:clownfish_raw",
|
||||
|
@ -150,6 +151,7 @@ mobs_mc.override.replace = {
|
|||
-- Sheep eat grass
|
||||
sheep = {
|
||||
{ "mcl_core:dirt_with_grass", "mcl_core:dirt", -1 },
|
||||
{ "mcl_core:dirt_with_dry_grass", "mcl_core:dirt", -1 },
|
||||
{ "mcl_flowers:tallgrass", "air", 0 },
|
||||
},
|
||||
-- Silverfish populate stone, etc. with monster eggs
|
||||
|
@ -168,7 +170,9 @@ mobs_mc.override.enderman_takable = {
|
|||
-- Generic handling, useful for entensions
|
||||
"group:enderman_takable",
|
||||
}
|
||||
|
||||
mobs_mc.override.enderman_replace_on_take = {
|
||||
["mcl_core:dirt_with_dry_grass"] = "mcl_core:dirt_with_grass",
|
||||
}
|
||||
|
||||
-- Texuture overrides for enderman block. Required for cactus because it's original is a nodebox
|
||||
-- and the textures have tranparent pixels.
|
||||
|
@ -190,18 +194,18 @@ mobs_mc.override.enderman_block_texture_overrides = {
|
|||
-- List of nodes on which mobs can spawn
|
||||
mobs_mc.override.spawn = {
|
||||
solid = { "group:solid", }, -- spawn on "solid" nodes
|
||||
grassland = { mobs_mc.override.items.grass_block },
|
||||
savanna = { "group:sand", "mcl_core:sandstone", "mcl_core:redsandstone" },
|
||||
grassland_savanna = { mobs_mc.override.items.grass_block, "group:sand", "mcl_core:sandstone", "mcl_core:redsandstone" },
|
||||
desert = { "group:sand" },
|
||||
grassland = { "mcl_core:dirt_with_grass" },
|
||||
savanna = { "mcl_core:dirt_with_dry_grass" },
|
||||
grassland_savanna = { "mcl_core:dirt_with_grass", "mcl_core:dirt_with_dry_grass" },
|
||||
desert = { "mcl_core:sand", "mcl_core:sandstone" },
|
||||
jungle = { "mcl_core:jungletree", "mcl_core:jungleleaves", "mcl_flowers:fern", "mcl_core:vine" },
|
||||
snow = { "mcl_core:snow", "mcl_core:snowblock", "mcl_core:dirt_with_grass_snow" },
|
||||
snow = { "mcl_core:snow", "mcl_core:snowblock", "mcl_core:dirt_with_grass_snow", "mcl_core:dirt_with_dry_grass_snow" },
|
||||
-- End stone added for shulkers because End cities don't generate yet
|
||||
end_city = { "mcl_end:end_stone", "mcl_end:purpur_block" },
|
||||
nether = { "mcl_nether:netherrack", "mcl_nether:quartz_ore" },
|
||||
-- Netherrack added because there are no Nether fortresses yet. TODO: Remove netherrac from list as soon they're available
|
||||
nether_fortress = { "mcl_nether:nether_brick", "mcl_nether:netherrack" },
|
||||
wolf = { mobs_mc.override.items.grass_block, "mcl_core:dirt", "mcl_core:dirt_with_grass_snow", "mcl_core:snow", "mcl_core:snowblock", "mcl_core:podzol" },
|
||||
wolf = { mobs_mc.override.items.grass_block, "mcl_core:dirt", "mcl_core:dirt_with_grass_snow", "mcl_core:dirt_with_dry_grass_snow", "mcl_core:snow", "mcl_core:snowblock", "mcl_core:podzol" },
|
||||
}
|
||||
|
||||
-- This table contains important spawn height references for the mob spawn height.
|
||||
|
|
|
@ -34,7 +34,7 @@ local revertsky = function(dtime)
|
|||
return
|
||||
end
|
||||
|
||||
skycolor.remove_layer("lightning")
|
||||
mcl_weather.skycolor.remove_layer("lightning")
|
||||
|
||||
ps = {}
|
||||
end
|
||||
|
@ -136,8 +136,8 @@ lightning.strike = function(pos)
|
|||
local name = player:get_player_name()
|
||||
if ps[name] == nil then
|
||||
ps[name] = {p = player, sky = sky}
|
||||
skycolor.add_layer("lightning", {{r=255,g=255,b=255}}, true)
|
||||
skycolor.active = true
|
||||
mcl_weather.skycolor.add_layer("lightning", {{r=255,g=255,b=255}}, true)
|
||||
mcl_weather.skycolor.active = true
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -184,7 +184,7 @@ lightning.strike = function(pos)
|
|||
if lua.name == "mobs_mc:pig" then
|
||||
local rot = obj:get_yaw()
|
||||
obj:remove()
|
||||
obj = minetest.add_entity(pos2, "mobs_mc:zombiepig")
|
||||
obj = minetest.add_entity(pos2, "mobs_mc:pigman")
|
||||
obj:set_yaw(rot)
|
||||
-- villager → witch
|
||||
elseif lua.name == "mobs_mc:villager" then
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
weather-pack
|
||||
`mcl_weather`
|
||||
=======================
|
||||
Weather mod for Minetest (http://minetest.net/)
|
||||
Weather mod for MineClone 2. Forked from `weather_pack`.
|
||||
|
||||
Weathers included
|
||||
-----------------------
|
||||
|
@ -10,13 +10,13 @@ Weathers included
|
|||
|
||||
Commands
|
||||
-----------------------
|
||||
`set_weather <weather>` requires `weather_manager` privilege.
|
||||
`weather <weather>`, requires `weather_manager` privilege.
|
||||
|
||||
Dependencies
|
||||
-----------------------
|
||||
Thunder weather requres [lightning](https://github.com/minetest-mods/lightning) mod.
|
||||
|
||||
Configuration properties
|
||||
Configuration prope, ties
|
||||
-----------------------
|
||||
Weather mod for indoor check depends on sunlight propogation check. Some nodes (e.g. glass block) propogates sunlight and thus weather particles will go through it. To change that set `weather_allow_override_nodes=true` in `minetest.conf` file. Be aware that just few nodes will be override and these blocks needs to be re-builded to take effect. Maybe in future other 'cheap' way to check indoor will be available.
|
||||
|
1
mods/ENVIRONMENT/mcl_weather/description.txt
Normal file
|
@ -0,0 +1 @@
|
|||
Weather: Rain, snow, thunderstorm.
|
|
@ -1,4 +1,4 @@
|
|||
local modpath = minetest.get_modpath("weather_pack");
|
||||
local modpath = minetest.get_modpath("mcl_weather");
|
||||
dofile(modpath.."/weather_core.lua")
|
||||
dofile(modpath.."/snow.lua")
|
||||
dofile(modpath.."/rain.lua")
|
1
mods/ENVIRONMENT/mcl_weather/mod.conf
Normal file
|
@ -0,0 +1 @@
|
|||
name = mcl_weather
|
|
@ -1,7 +1,7 @@
|
|||
local PARTICLES_COUNT_RAIN = 30
|
||||
local PARTICLES_COUNT_THUNDER = 45
|
||||
|
||||
rain = {
|
||||
mcl_weather.rain = {
|
||||
-- max rain particles created at time
|
||||
particles_count = PARTICLES_COUNT_RAIN,
|
||||
|
||||
|
@ -18,7 +18,7 @@ rain = {
|
|||
init_done = false,
|
||||
}
|
||||
|
||||
rain.sound_handler = function(player)
|
||||
mcl_weather.rain.sound_handler = function(player)
|
||||
return minetest.sound_play("weather_rain", {
|
||||
object = player,
|
||||
max_hear_distance = 2,
|
||||
|
@ -27,16 +27,16 @@ rain.sound_handler = function(player)
|
|||
end
|
||||
|
||||
-- set skybox based on time (uses skycolor api)
|
||||
rain.set_sky_box = function()
|
||||
if weather.state == "rain" then
|
||||
skycolor.add_layer(
|
||||
mcl_weather.rain.set_sky_box = function()
|
||||
if mcl_weather.state == "rain" then
|
||||
mcl_weather.skycolor.add_layer(
|
||||
"weather-pack-rain-sky",
|
||||
{{r=0, g=0, b=0},
|
||||
{r=85, g=86, b=98},
|
||||
{r=175, g=175, b=191},
|
||||
{r=85, g=86, b=98},
|
||||
{r=0, g=0, b=0}})
|
||||
skycolor.active = true
|
||||
mcl_weather.skycolor.active = true
|
||||
for _, player in pairs(minetest.get_connected_players()) do
|
||||
player:set_clouds({color="#5D5D5FE8"})
|
||||
end
|
||||
|
@ -45,13 +45,13 @@ end
|
|||
|
||||
-- creating manually parctiles instead of particles spawner because of easier to control
|
||||
-- spawn position.
|
||||
rain.add_rain_particles = function(player)
|
||||
mcl_weather.rain.add_rain_particles = function(player)
|
||||
|
||||
rain.last_rp_count = 0
|
||||
for i=rain.particles_count, 1,-1 do
|
||||
local random_pos_x, random_pos_y, random_pos_z = weather.get_random_pos_by_player_look_dir(player)
|
||||
if weather.is_outdoor({x=random_pos_x, y=random_pos_y, z=random_pos_z}) then
|
||||
rain.last_rp_count = rain.last_rp_count + 1
|
||||
mcl_weather.rain.last_rp_count = 0
|
||||
for i=mcl_weather.rain.particles_count, 1,-1 do
|
||||
local random_pos_x, random_pos_y, random_pos_z = mcl_weather.get_random_pos_by_player_look_dir(player)
|
||||
if mcl_weather.is_outdoor({x=random_pos_x, y=random_pos_y, z=random_pos_z}) then
|
||||
mcl_weather.rain.last_rp_count = mcl_weather.rain.last_rp_count + 1
|
||||
minetest.add_particle({
|
||||
pos = {x=random_pos_x, y=random_pos_y, z=random_pos_z},
|
||||
velocity = {x=0, y=-10, z=0},
|
||||
|
@ -61,7 +61,7 @@ rain.add_rain_particles = function(player)
|
|||
collisiondetection = true,
|
||||
collision_removal = true,
|
||||
vertical = true,
|
||||
texture = rain.get_texture(),
|
||||
texture = mcl_weather.rain.get_texture(),
|
||||
playername = player:get_player_name()
|
||||
})
|
||||
end
|
||||
|
@ -69,7 +69,7 @@ rain.add_rain_particles = function(player)
|
|||
end
|
||||
|
||||
-- Simple random texture getter
|
||||
rain.get_texture = function()
|
||||
mcl_weather.rain.get_texture = function()
|
||||
local texture_name
|
||||
local random_number = math.random()
|
||||
if random_number > 0.33 then
|
||||
|
@ -84,42 +84,42 @@ end
|
|||
|
||||
-- register player for rain weather.
|
||||
-- basically needs for origin sky reference and rain sound controls.
|
||||
rain.add_player = function(player)
|
||||
if weather.players[player:get_player_name()] == nil then
|
||||
mcl_weather.rain.add_player = function(player)
|
||||
if mcl_weather.players[player:get_player_name()] == nil then
|
||||
local player_meta = {}
|
||||
player_meta.origin_sky = {player:get_sky()}
|
||||
weather.players[player:get_player_name()] = player_meta
|
||||
mcl_weather.players[player:get_player_name()] = player_meta
|
||||
end
|
||||
end
|
||||
|
||||
-- remove player from player list effected by rain.
|
||||
-- be sure to remove sound before removing player otherwise soundhandler reference will be lost.
|
||||
rain.remove_player = function(player)
|
||||
local player_meta = weather.players[player:get_player_name()]
|
||||
mcl_weather.rain.remove_player = function(player)
|
||||
local player_meta = mcl_weather.players[player:get_player_name()]
|
||||
if player_meta ~= nil and player_meta.origin_sky ~= nil then
|
||||
player:set_sky(player_meta.origin_sky[1], player_meta.origin_sky[2], player_meta.origin_sky[3], true)
|
||||
player:set_clouds({color="#FFF0F0E5"})
|
||||
weather.players[player:get_player_name()] = nil
|
||||
mcl_weather.players[player:get_player_name()] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- adds and removes rain sound depending how much rain particles around player currently exist.
|
||||
-- have few seconds delay before each check to avoid on/off sound too often
|
||||
-- when player stay on 'edge' where sound should play and stop depending from random raindrop appearance.
|
||||
rain.update_sound = function(player)
|
||||
local player_meta = weather.players[player:get_player_name()]
|
||||
mcl_weather.rain.update_sound = function(player)
|
||||
local player_meta = mcl_weather.players[player:get_player_name()]
|
||||
if player_meta ~= nil then
|
||||
if player_meta.sound_updated ~= nil and player_meta.sound_updated + 5 > minetest.get_gametime() then
|
||||
return false
|
||||
end
|
||||
|
||||
if player_meta.sound_handler ~= nil then
|
||||
if rain.last_rp_count == 0 then
|
||||
if mcl_weather.rain.last_rp_count == 0 then
|
||||
minetest.sound_stop(player_meta.sound_handler)
|
||||
player_meta.sound_handler = nil
|
||||
end
|
||||
elseif rain.last_rp_count > 0 then
|
||||
player_meta.sound_handler = rain.sound_handler(player)
|
||||
elseif mcl_weather.rain.last_rp_count > 0 then
|
||||
player_meta.sound_handler = mcl_weather.rain.sound_handler(player)
|
||||
end
|
||||
|
||||
player_meta.sound_updated = minetest.get_gametime()
|
||||
|
@ -127,8 +127,8 @@ rain.update_sound = function(player)
|
|||
end
|
||||
|
||||
-- rain sound removed from player.
|
||||
rain.remove_sound = function(player)
|
||||
local player_meta = weather.players[player:get_player_name()]
|
||||
mcl_weather.rain.remove_sound = function(player)
|
||||
local player_meta = mcl_weather.players[player:get_player_name()]
|
||||
if player_meta ~= nil and player_meta.sound_handler ~= nil then
|
||||
minetest.sound_stop(player_meta.sound_handler)
|
||||
player_meta.sound_handler = nil
|
||||
|
@ -136,63 +136,55 @@ rain.remove_sound = function(player)
|
|||
end
|
||||
|
||||
-- callback function for removing rain
|
||||
rain.clear = function()
|
||||
rain.raining = false
|
||||
rain.sky_last_update = -1
|
||||
rain.init_done = false
|
||||
rain.set_particles_mode("rain")
|
||||
skycolor.remove_layer("weather-pack-rain-sky")
|
||||
mcl_weather.rain.clear = function()
|
||||
mcl_weather.rain.raining = false
|
||||
mcl_weather.rain.sky_last_update = -1
|
||||
mcl_weather.rain.init_done = false
|
||||
mcl_weather.rain.set_particles_mode("rain")
|
||||
mcl_weather.skycolor.remove_layer("weather-pack-rain-sky")
|
||||
for _, player in ipairs(minetest.get_connected_players()) do
|
||||
rain.remove_sound(player)
|
||||
rain.remove_player(player)
|
||||
mcl_weather.rain.remove_sound(player)
|
||||
mcl_weather.rain.remove_player(player)
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
if weather.state ~= "rain" then
|
||||
if mcl_weather.state ~= "rain" then
|
||||
return false
|
||||
end
|
||||
|
||||
rain.make_weather()
|
||||
mcl_weather.rain.make_weather()
|
||||
end)
|
||||
|
||||
rain.make_weather = function()
|
||||
if rain.init_done == false then
|
||||
rain.raining = true
|
||||
rain.set_sky_box()
|
||||
rain.init_done = true
|
||||
rain.set_particles_mode(weather.mode)
|
||||
mcl_weather.rain.make_weather = function()
|
||||
if mcl_weather.rain.init_done == false then
|
||||
mcl_weather.rain.raining = true
|
||||
mcl_weather.rain.set_sky_box()
|
||||
mcl_weather.rain.set_particles_mode(mcl_weather.mode)
|
||||
mcl_weather.rain.init_done = true
|
||||
end
|
||||
|
||||
for _, player in ipairs(minetest.get_connected_players()) do
|
||||
if (weather.is_underwater(player) or not mcl_util.has_weather(player:getpos())) then
|
||||
rain.remove_sound(player)
|
||||
if (mcl_weather.is_underwater(player) or not mcl_util.has_weather(player:getpos())) then
|
||||
mcl_weather.rain.remove_sound(player)
|
||||
return false
|
||||
end
|
||||
rain.add_player(player)
|
||||
rain.add_rain_particles(player)
|
||||
rain.update_sound(player)
|
||||
mcl_weather.rain.add_player(player)
|
||||
mcl_weather.rain.add_rain_particles(player)
|
||||
mcl_weather.rain.update_sound(player)
|
||||
end
|
||||
end
|
||||
|
||||
if weather.reg_weathers.rain == nil then
|
||||
weather.reg_weathers.rain = {
|
||||
chance = 15,
|
||||
light_factor = 0.7,
|
||||
clear = rain.clear
|
||||
}
|
||||
end
|
||||
|
||||
-- Switch the number of raindrops: "thunder" for many raindrops, otherwise for normal raindrops
|
||||
rain.set_particles_mode = function(mode)
|
||||
mcl_weather.rain.set_particles_mode = function(mode)
|
||||
if mode == "thunder" then
|
||||
rain.particles_count = PARTICLES_COUNT_THUNDER
|
||||
mcl_weather.rain.particles_count = PARTICLES_COUNT_THUNDER
|
||||
else
|
||||
rain.particles_count = PARTICLES_COUNT_RAIN
|
||||
mcl_weather.rain.particles_count = PARTICLES_COUNT_RAIN
|
||||
end
|
||||
end
|
||||
|
||||
if weather.allow_abm then
|
||||
if mcl_weather.allow_abm then
|
||||
-- ABM for extinguish fire
|
||||
minetest.register_abm({
|
||||
label = "Rain extinguishes fire",
|
||||
|
@ -200,8 +192,8 @@ if weather.allow_abm then
|
|||
interval = 4.0,
|
||||
chance = 2,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
if rain.raining and rain.extinguish_fire then
|
||||
if weather.is_outdoor(pos) then
|
||||
if mcl_weather.rain.raining and mcl_weather.rain.extinguish_fire then
|
||||
if mcl_weather.is_outdoor(pos) then
|
||||
minetest.remove_node(pos)
|
||||
minetest.sound_play("fire_extinguish_flame", {pos = pos, max_hear_distance = 16, gain = 0.15})
|
||||
end
|
||||
|
@ -216,7 +208,7 @@ if weather.allow_abm then
|
|||
interval = 56.0,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
if rain.raining and weather.is_outdoor(pos) then
|
||||
if mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) then
|
||||
if node.name == "mcl_cauldrons:cauldron" then
|
||||
minetest.set_node(pos, {name="mcl_cauldrons:cauldron_1"})
|
||||
elseif node.name == "mcl_cauldrons:cauldron_1" then
|
||||
|
@ -235,7 +227,7 @@ if weather.allow_abm then
|
|||
interval = 22.0,
|
||||
chance = 3,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
if rain.raining and weather.is_outdoor(pos) then
|
||||
if mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) then
|
||||
if node.name == "mcl_farming:soil" then
|
||||
minetest.set_node(pos, {name="mcl_farming:soil_wet"})
|
||||
end
|
||||
|
@ -243,3 +235,18 @@ if weather.allow_abm then
|
|||
end
|
||||
})
|
||||
end
|
||||
|
||||
if mcl_weather.reg_weathers.rain == nil then
|
||||
mcl_weather.reg_weathers.rain = {
|
||||
clear = mcl_weather.rain.clear,
|
||||
light_factor = 0.6,
|
||||
-- 10min - 20min
|
||||
min_duration = 600,
|
||||
max_duration = 1200,
|
||||
transitions = {
|
||||
[65] = "none",
|
||||
[70] = "snow",
|
||||
[100] = "thunder",
|
||||
}
|
||||
}
|
||||
end
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
@ -1,4 +1,4 @@
|
|||
skycolor = {
|
||||
mcl_weather.skycolor = {
|
||||
-- Should be activated before do any effect.
|
||||
active = true,
|
||||
|
||||
|
@ -38,26 +38,26 @@ skycolor = {
|
|||
|
||||
-- To layer to colors table
|
||||
add_layer = function(layer_name, layer_color, instant_update)
|
||||
skycolor.colors[layer_name] = layer_color
|
||||
table.insert(skycolor.layer_names, layer_name)
|
||||
mcl_weather.skycolor.colors[layer_name] = layer_color
|
||||
table.insert(mcl_weather.skycolor.layer_names, layer_name)
|
||||
if (instant_update ~= true) then
|
||||
skycolor.init_transition()
|
||||
mcl_weather.skycolor.init_transition()
|
||||
end
|
||||
skycolor.force_update = true
|
||||
mcl_weather.skycolor.force_update = true
|
||||
end,
|
||||
|
||||
-- Retrieve layer from colors table
|
||||
retrieve_layer = function()
|
||||
local last_layer = skycolor.layer_names[#skycolor.layer_names]
|
||||
return skycolor.colors[last_layer]
|
||||
local last_layer = mcl_weather.skycolor.layer_names[#mcl_weather.skycolor.layer_names]
|
||||
return mcl_weather.skycolor.colors[last_layer]
|
||||
end,
|
||||
|
||||
-- Remove layer from colors table
|
||||
remove_layer = function(layer_name)
|
||||
for k, name in ipairs(skycolor.layer_names) do
|
||||
for k, name in ipairs(mcl_weather.skycolor.layer_names) do
|
||||
if name == layer_name then
|
||||
table.remove(skycolor.layer_names, k)
|
||||
skycolor.force_update = true
|
||||
table.remove(mcl_weather.skycolor.layer_names, k)
|
||||
mcl_weather.skycolor.force_update = true
|
||||
return
|
||||
end
|
||||
end
|
||||
|
@ -65,22 +65,21 @@ skycolor = {
|
|||
|
||||
-- Update sky color. If players not specified update sky for all players.
|
||||
update_sky_color = function(players)
|
||||
local color = skycolor.current_sky_layer_color()
|
||||
local color = mcl_weather.skycolor.current_sky_layer_color()
|
||||
if (color == nil) then
|
||||
skycolor.set_default_sky()
|
||||
mcl_weather.skycolor.set_default_sky()
|
||||
return
|
||||
end
|
||||
|
||||
players = skycolor.utils.get_players(players)
|
||||
|
||||
-- Make everything darker for player
|
||||
players = mcl_weather.skycolor.utils.get_players(players)
|
||||
for _, player in ipairs(players) do
|
||||
local pos = player:getpos()
|
||||
local _, dim = mcl_util.y_to_layer(pos.y)
|
||||
if dim == "overworld" then
|
||||
player:set_sky(color, "plain", nil, true)
|
||||
|
||||
local lf = weather.get_current_light_factor()
|
||||
local lf = mcl_weather.get_current_light_factor()
|
||||
if lf then
|
||||
local w = minetest.get_timeofday()
|
||||
local light = (w * (lf*2))
|
||||
|
@ -102,34 +101,34 @@ skycolor = {
|
|||
|
||||
-- Returns current layer color in {r, g, b} format
|
||||
current_sky_layer_color = function()
|
||||
if #skycolor.layer_names == 0 then
|
||||
if #mcl_weather.skycolor.layer_names == 0 then
|
||||
return nil
|
||||
end
|
||||
|
||||
-- min timeofday value 0; max timeofday value 1. So sky color gradient range will be between 0 and 1 * skycolor.max_value.
|
||||
-- min timeofday value 0; max timeofday value 1. So sky color gradient range will be between 0 and 1 * mcl_weather.skycolor.max_val.
|
||||
local timeofday = minetest.get_timeofday()
|
||||
local rounded_time = math.floor(timeofday * skycolor.max_val)
|
||||
local color = skycolor.utils.convert_to_rgb(skycolor.min_val, skycolor.max_val, rounded_time, skycolor.retrieve_layer())
|
||||
local rounded_time = math.floor(timeofday * mcl_weather.skycolor.max_val)
|
||||
local color = mcl_weather.skycolor.utils.convert_to_rgb(mcl_weather.skycolor.min_val, mcl_weather.skycolor.max_val, rounded_time, mcl_weather.skycolor.retrieve_layer())
|
||||
return color
|
||||
end,
|
||||
|
||||
-- Initialy used only on
|
||||
update_transition_sky_color = function()
|
||||
if #skycolor.layer_names == 0 then
|
||||
skycolor.set_default_sky()
|
||||
if #mcl_weather.skycolor.layer_names == 0 then
|
||||
mcl_weather.skycolor.set_default_sky()
|
||||
return
|
||||
end
|
||||
|
||||
local multiplier = 100
|
||||
local rounded_time = math.floor(skycolor.transition_timer * multiplier)
|
||||
if rounded_time >= skycolor.transition_time * multiplier then
|
||||
skycolor.stop_transition()
|
||||
local rounded_time = math.floor(mcl_weather.skycolor.transition_timer * multiplier)
|
||||
if rounded_time >= mcl_weather.skycolor.transition_time * multiplier then
|
||||
mcl_weather.skycolor.stop_transition()
|
||||
return
|
||||
end
|
||||
|
||||
local color = skycolor.utils.convert_to_rgb(0, skycolor.transition_time * multiplier, rounded_time, skycolor.transition_colors)
|
||||
local color = mcl_weather.skycolor.utils.convert_to_rgb(0, mcl_weather.skycolor.transition_time * multiplier, rounded_time, mcl_weather.skycolor.transition_colors)
|
||||
|
||||
local players = skycolor.utils.get_players(nil)
|
||||
local players = mcl_weather.skycolor.utils.get_players(nil)
|
||||
for _, player in ipairs(players) do
|
||||
local pos = player:getpos()
|
||||
local _, dim = mcl_util.y_to_layer(pos.y)
|
||||
|
@ -143,12 +142,13 @@ skycolor = {
|
|||
-- Could be sometimes useful but not recomended to use in general case as there may be other color layers
|
||||
-- which needs to preserve.
|
||||
set_default_sky = function(players)
|
||||
local players = skycolor.utils.get_players(players)
|
||||
local players = mcl_weather.skycolor.utils.get_players(players)
|
||||
for _, player in ipairs(players) do
|
||||
local pos = player:getpos()
|
||||
local _, dim = mcl_util.y_to_layer(pos.y)
|
||||
if dim == "overworld" then
|
||||
player:set_sky(nil, "regular", nil, true)
|
||||
player:override_day_night_ratio(nil)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
@ -156,23 +156,23 @@ skycolor = {
|
|||
init_transition = function()
|
||||
-- sadly default sky returns unpredictible colors so transition mode becomes usable only for user defined color layers
|
||||
-- Here '2' means that one color layer existed before new added and transition is posible.
|
||||
if #skycolor.layer_names < 2 then
|
||||
if #mcl_weather.skycolor.layer_names < 2 then
|
||||
return
|
||||
end
|
||||
|
||||
local transition_start_color = skycolor.utils.get_current_bg_color()
|
||||
local transition_start_color = mcl_weather.skycolor.utils.get_current_bg_color()
|
||||
if (transition_start_color == nil) then
|
||||
return
|
||||
end
|
||||
local transition_end_color = skycolor.current_sky_layer_color()
|
||||
skycolor.transition_colors = {transition_start_color, transition_end_color}
|
||||
skycolor.transition_in_progress = true
|
||||
local transition_end_color = mcl_weather.skycolor.current_sky_layer_color()
|
||||
mcl_weather.skycolor.transition_colors = {transition_start_color, transition_end_color}
|
||||
mcl_weather.skycolor.transition_in_progress = true
|
||||
end,
|
||||
|
||||
stop_transition = function()
|
||||
skycolor.transition_in_progress = false
|
||||
skycolor.transition_colors = {}
|
||||
skycolor.transition_timer = 0
|
||||
mcl_weather.skycolor.transition_in_progress = false
|
||||
mcl_weather.skycolor.transition_colors = {}
|
||||
mcl_weather.skycolor.transition_timer = 0
|
||||
end,
|
||||
|
||||
utils = {
|
||||
|
@ -197,7 +197,7 @@ skycolor = {
|
|||
|
||||
-- Returns first player sky color. I assume that all players are in same color layout.
|
||||
get_current_bg_color = function()
|
||||
local players = skycolor.utils.get_players(nil)
|
||||
local players = mcl_weather.skycolor.utils.get_players(nil)
|
||||
for _, player in ipairs(players) do
|
||||
return player:get_sky()
|
||||
end
|
||||
|
@ -209,34 +209,34 @@ skycolor = {
|
|||
|
||||
local timer = 0
|
||||
minetest.register_globalstep(function(dtime)
|
||||
if skycolor.active ~= true or #minetest.get_connected_players() == 0 then
|
||||
if mcl_weather.skycolor.active ~= true or #minetest.get_connected_players() == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
if skycolor.smooth_transitions and skycolor.transition_in_progress then
|
||||
skycolor.transition_timer = skycolor.transition_timer + dtime
|
||||
skycolor.update_transition_sky_color()
|
||||
if mcl_weather.skycolor.smooth_transitions and mcl_weather.skycolor.transition_in_progress then
|
||||
mcl_weather.skycolor.transition_timer = mcl_weather.skycolor.transition_timer + dtime
|
||||
mcl_weather.skycolor.update_transition_sky_color()
|
||||
return
|
||||
end
|
||||
|
||||
if skycolor.force_update then
|
||||
skycolor.update_sky_color()
|
||||
skycolor.force_update = false
|
||||
if mcl_weather.skycolor.force_update then
|
||||
mcl_weather.skycolor.update_sky_color()
|
||||
mcl_weather.skycolor.force_update = false
|
||||
return
|
||||
end
|
||||
|
||||
-- regular updates based on iterval
|
||||
timer = timer + dtime;
|
||||
if timer >= skycolor.update_interval then
|
||||
skycolor.update_sky_color()
|
||||
if timer >= mcl_weather.skycolor.update_interval then
|
||||
mcl_weather.skycolor.update_sky_color()
|
||||
timer = 0
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
local initsky = function(player)
|
||||
if (skycolor.active) then
|
||||
skycolor.force_update = true
|
||||
if (mcl_weather.skycolor.active) then
|
||||
mcl_weather.skycolor.force_update = true
|
||||
end
|
||||
|
||||
-- MC-style clouds: Layer 127, thickness 4, fly to the “West”
|
|
@ -1,16 +1,16 @@
|
|||
snow = {}
|
||||
mcl_weather.snow = {}
|
||||
|
||||
snow.particles_count = 15
|
||||
snow.init_done = false
|
||||
mcl_weather.snow.particles_count = 15
|
||||
mcl_weather.snow.init_done = false
|
||||
|
||||
-- calculates coordinates and draw particles for snow weather
|
||||
snow.add_rain_particles = function(player)
|
||||
rain.last_rp_count = 0
|
||||
for i=snow.particles_count, 1,-1 do
|
||||
local random_pos_x, random_pos_y, random_pos_z = weather.get_random_pos_by_player_look_dir(player)
|
||||
mcl_weather.snow.add_snow_particles = function(player)
|
||||
mcl_weather.rain.last_rp_count = 0
|
||||
for i=mcl_weather.snow.particles_count, 1,-1 do
|
||||
local random_pos_x, random_pos_y, random_pos_z = mcl_weather.get_random_pos_by_player_look_dir(player)
|
||||
random_pos_y = math.random() + math.random(player:getpos().y - 1, player:getpos().y + 7)
|
||||
if minetest.get_node_light({x=random_pos_x, y=random_pos_y, z=random_pos_z}, 0.5) == 15 then
|
||||
rain.last_rp_count = rain.last_rp_count + 1
|
||||
mcl_weather.rain.last_rp_count = mcl_weather.rain.last_rp_count + 1
|
||||
minetest.add_particle({
|
||||
pos = {x=random_pos_x, y=random_pos_y, z=random_pos_z},
|
||||
velocity = {x = math.random(-1,-0.5), y = math.random(-2,-1), z = math.random(-1,-0.5)},
|
||||
|
@ -20,30 +20,30 @@ snow.add_rain_particles = function(player)
|
|||
collisiondetection = true,
|
||||
collision_removal = true,
|
||||
vertical = true,
|
||||
texture = snow.get_texture(),
|
||||
texture = mcl_weather.snow.get_texture(),
|
||||
playername = player:get_player_name()
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
snow.set_sky_box = function()
|
||||
skycolor.add_layer(
|
||||
mcl_weather.snow.set_sky_box = function()
|
||||
mcl_weather.skycolor.add_layer(
|
||||
"weather-pack-snow-sky",
|
||||
{{r=0, g=0, b=0},
|
||||
{r=241, g=244, b=249},
|
||||
{r=0, g=0, b=0}}
|
||||
)
|
||||
skycolor.active = true
|
||||
mcl_weather.skycolor.active = true
|
||||
end
|
||||
|
||||
snow.clear = function()
|
||||
skycolor.remove_layer("weather-pack-snow-sky")
|
||||
snow.init_done = false
|
||||
mcl_weather.snow.clear = function()
|
||||
mcl_weather.skycolor.remove_layer("weather-pack-snow-sky")
|
||||
mcl_weather.snow.init_done = false
|
||||
end
|
||||
|
||||
-- Simple random texture getter
|
||||
snow.get_texture = function()
|
||||
mcl_weather.snow.get_texture = function()
|
||||
local texture_name
|
||||
local random_number = math.random()
|
||||
if random_number > 0.5 then
|
||||
|
@ -56,7 +56,7 @@ end
|
|||
|
||||
local timer = 0
|
||||
minetest.register_globalstep(function(dtime)
|
||||
if weather.state ~= "snow" then
|
||||
if mcl_weather.state ~= "snow" then
|
||||
return false
|
||||
end
|
||||
|
||||
|
@ -67,25 +67,32 @@ minetest.register_globalstep(function(dtime)
|
|||
return
|
||||
end
|
||||
|
||||
if snow.init_done == false then
|
||||
snow.set_sky_box()
|
||||
snow.init_done = true
|
||||
if mcl_weather.snow.init_done == false then
|
||||
mcl_weather.snow.set_sky_box()
|
||||
mcl_weather.snow.init_done = true
|
||||
end
|
||||
|
||||
for _, player in ipairs(minetest.get_connected_players()) do
|
||||
if (weather.is_underwater(player) or not mcl_util.has_weather(player:getpos())) then
|
||||
if (mcl_weather.is_underwater(player) or not mcl_util.has_weather(player:getpos())) then
|
||||
return false
|
||||
end
|
||||
snow.add_rain_particles(player)
|
||||
mcl_weather.snow.add_snow_particles(player)
|
||||
end
|
||||
end)
|
||||
|
||||
-- register snow weather
|
||||
if weather.reg_weathers.snow == nil then
|
||||
weather.reg_weathers.snow = {
|
||||
chance = 10,
|
||||
light_factor = 0.7,
|
||||
clear = snow.clear
|
||||
if mcl_weather.reg_weathers.snow == nil then
|
||||
mcl_weather.reg_weathers.snow = {
|
||||
clear = mcl_weather.snow.clear,
|
||||
light_factor = 0.6,
|
||||
-- 10min - 20min
|
||||
min_duration = 600,
|
||||
max_duration = 1200,
|
||||
transitions = {
|
||||
[65] = "none",
|
||||
[80] = "rain",
|
||||
[100] = "thunder",
|
||||
}
|
||||
}
|
||||
end
|
||||
|
BIN
mods/ENVIRONMENT/mcl_weather/sounds/weather_rain.ogg
Normal file
Before Width: | Height: | Size: 296 B After Width: | Height: | Size: 296 B |
Before Width: | Height: | Size: 209 B After Width: | Height: | Size: 209 B |
Before Width: | Height: | Size: 220 B After Width: | Height: | Size: 220 B |
Before Width: | Height: | Size: 192 B After Width: | Height: | Size: 192 B |
Before Width: | Height: | Size: 195 B After Width: | Height: | Size: 195 B |
61
mods/ENVIRONMENT/mcl_weather/thunder.lua
Normal file
|
@ -0,0 +1,61 @@
|
|||
-- turn off lightning mod 'auto mode'
|
||||
lightning.auto = false
|
||||
|
||||
mcl_weather.thunder = {
|
||||
next_strike = 0,
|
||||
min_delay = 3,
|
||||
max_delay = 12,
|
||||
init_done = false,
|
||||
}
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
if mcl_weather.get_weather() ~= "thunder" then
|
||||
return false
|
||||
end
|
||||
|
||||
mcl_weather.rain.set_particles_mode("thunder")
|
||||
mcl_weather.rain.make_weather()
|
||||
|
||||
if mcl_weather.thunder.init_done == false then
|
||||
mcl_weather.skycolor.add_layer(
|
||||
"weather-pack-thunder-sky",
|
||||
{{r=0, g=0, b=0},
|
||||
{r=40, g=40, b=40},
|
||||
{r=85, g=86, b=86},
|
||||
{r=40, g=40, b=40},
|
||||
{r=0, g=0, b=0}})
|
||||
mcl_weather.skycolor.active = true
|
||||
for _, player in pairs(minetest.get_connected_players()) do
|
||||
player:set_clouds({color="#3D3D3FE8"})
|
||||
end
|
||||
mcl_weather.thunder.init_done = true
|
||||
end
|
||||
|
||||
if (mcl_weather.thunder.next_strike <= minetest.get_gametime()) then
|
||||
lightning.strike()
|
||||
local delay = math.random(mcl_weather.thunder.min_delay, mcl_weather.thunder.max_delay)
|
||||
mcl_weather.thunder.next_strike = minetest.get_gametime() + delay
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
mcl_weather.thunder.clear = function()
|
||||
mcl_weather.rain.clear()
|
||||
mcl_weather.skycolor.remove_layer("weather-pack-thunder-sky")
|
||||
mcl_weather.skycolor.remove_layer("lightning")
|
||||
mcl_weather.thunder.init_done = false
|
||||
end
|
||||
|
||||
-- register thunderstorm weather
|
||||
if mcl_weather.reg_weathers.thunder == nil then
|
||||
mcl_weather.reg_weathers.thunder = {
|
||||
clear = mcl_weather.thunder.clear,
|
||||
light_factor = 0.33333,
|
||||
-- 10min - 20min
|
||||
min_duration = 600,
|
||||
max_duration = 1200,
|
||||
transitions = {
|
||||
[100] = "rain",
|
||||
}
|
||||
}
|
||||
end
|
|
@ -1,21 +1,18 @@
|
|||
weather = {
|
||||
mcl_weather = {
|
||||
-- weather states, 'none' is default, other states depends from active mods
|
||||
state = "none",
|
||||
|
||||
-- player list for saving player meta info
|
||||
players = {},
|
||||
|
||||
-- time when weather should be re-calculated
|
||||
next_check = 0,
|
||||
|
||||
-- default weather recalculation interval
|
||||
check_interval = 300,
|
||||
|
||||
-- weather min duration
|
||||
min_duration = 240,
|
||||
min_duration = 600,
|
||||
|
||||
-- weather max duration
|
||||
max_duration = 3600,
|
||||
max_duration = 9000,
|
||||
|
||||
-- weather calculated end time
|
||||
end_time = nil,
|
||||
|
@ -30,26 +27,39 @@ weather = {
|
|||
allow_abm = true,
|
||||
}
|
||||
|
||||
weather.get_rand_end_time = function(min_duration, max_duration)
|
||||
mcl_weather.reg_weathers["none"] = {
|
||||
min_duration = mcl_weather.min_duration,
|
||||
max_duration = mcl_weather.max_duration,
|
||||
light_factor = nil,
|
||||
transitions = {
|
||||
[50] = "rain",
|
||||
[100] = "snow",
|
||||
},
|
||||
clear = function() end,
|
||||
}
|
||||
|
||||
mcl_weather.get_rand_end_time = function(min_duration, max_duration)
|
||||
local r
|
||||
if min_duration ~= nil and max_duration ~= nil then
|
||||
return minetest.get_gametime() + math.random(min_duration, max_duration);
|
||||
r = math.random(min_duration, max_duration);
|
||||
else
|
||||
return minetest.get_gametime() + math.random(weather.min_duration, weather.max_duration);
|
||||
r = math.random(mcl_weather.min_duration, mcl_weather.max_duration);
|
||||
end
|
||||
return minetest.get_gametime() + r
|
||||
end
|
||||
|
||||
weather.get_current_light_factor = function()
|
||||
if weather.state == "none" then
|
||||
mcl_weather.get_current_light_factor = function()
|
||||
if mcl_weather.state == "none" then
|
||||
return nil
|
||||
else
|
||||
return weather.reg_weathers[weather.state].light_factor
|
||||
return mcl_weather.reg_weathers[mcl_weather.state].light_factor
|
||||
end
|
||||
end
|
||||
|
||||
-- Returns true if pos is outdoor.
|
||||
-- Outdoor is defined as any node in the Overworld under open sky.
|
||||
-- FIXME: Nodes below glass also count as “outdoor”, this should not be the case.
|
||||
weather.is_outdoor = function(pos)
|
||||
mcl_weather.is_outdoor = function(pos)
|
||||
local cpos = {x=pos.x, y=pos.y+1, z=pos.z}
|
||||
local _, dim = mcl_util.y_to_layer(cpos.y)
|
||||
if minetest.get_node_light(cpos, 0.5) == 15 and dim == "overworld" then
|
||||
|
@ -60,7 +70,7 @@ end
|
|||
|
||||
-- checks if player is undewater. This is needed in order to
|
||||
-- turn off weather particles generation.
|
||||
weather.is_underwater = function(player)
|
||||
mcl_weather.is_underwater = function(player)
|
||||
local ppos = player:getpos()
|
||||
local offset = player:get_eye_offset()
|
||||
local player_eye_pos = {x = ppos.x + offset.x,
|
||||
|
@ -75,7 +85,7 @@ end
|
|||
|
||||
-- trying to locate position for particles by player look direction for performance reason.
|
||||
-- it is costly to generate many particles around player so goal is focus mainly on front view.
|
||||
weather.get_random_pos_by_player_look_dir = function(player)
|
||||
mcl_weather.get_random_pos_by_player_look_dir = function(player)
|
||||
local look_dir = player:get_look_dir()
|
||||
local player_pos = player:getpos()
|
||||
|
||||
|
@ -106,37 +116,53 @@ weather.get_random_pos_by_player_look_dir = function(player)
|
|||
end
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
if weather.auto_mode == false then
|
||||
if mcl_weather.auto_mode == false then
|
||||
return 0
|
||||
end
|
||||
|
||||
-- recalculate weather only when there aren't currently any
|
||||
if (weather.state ~= "none") then
|
||||
if (weather.end_time ~= nil and weather.end_time <= minetest.get_gametime()) then
|
||||
weather.reg_weathers[weather.state].clear()
|
||||
weather.state = "none"
|
||||
if mcl_weather.end_time == nil then
|
||||
mcl_weather.end_time = mcl_weather.get_rand_end_time()
|
||||
end
|
||||
elseif (weather.next_check <= minetest.get_gametime()) then
|
||||
for weather_name, weather_meta in pairs(weather.reg_weathers) do
|
||||
weather.set_random_weather(weather_name, weather_meta)
|
||||
end
|
||||
-- fallback next_check set, weather 'none' will be.
|
||||
weather.next_check = minetest.get_gametime() + weather.check_interval
|
||||
-- recalculate weather
|
||||
if mcl_weather.end_time <= minetest.get_gametime() then
|
||||
mcl_weather.set_random_weather(mcl_weather.state, mcl_weather.reg_weathers[mcl_weather.state])
|
||||
end
|
||||
end)
|
||||
|
||||
-- sets random weather (which could be 'regular' (no weather)).
|
||||
weather.set_random_weather = function(weather_name, weather_meta)
|
||||
if weather.next_check > minetest.get_gametime() then return 0 end
|
||||
|
||||
if (weather_meta ~= nil and weather_meta.chance ~= nil) then
|
||||
-- Sets random weather (which could be 'none' (no weather)).
|
||||
mcl_weather.set_random_weather = function(weather_name, weather_meta)
|
||||
if (weather_meta ~= nil) then
|
||||
local transitions = weather_meta.transitions
|
||||
local random_roll = math.random(0,100)
|
||||
if (random_roll <= weather_meta.chance) then
|
||||
weather.state = weather_name
|
||||
weather.end_time = weather.get_rand_end_time(weather_meta.min_duration, weather_meta.max_duration)
|
||||
weather.next_check = minetest.get_gametime() + weather.check_interval
|
||||
local new_weather
|
||||
for v, weather in pairs(transitions) do
|
||||
if random_roll < v then
|
||||
new_weather = weather
|
||||
break
|
||||
end
|
||||
end
|
||||
if new_weather then
|
||||
mcl_weather.change_weather(new_weather)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mcl_weather.change_weather = function(new_weather)
|
||||
if (mcl_weather.reg_weathers ~= nil and mcl_weather.reg_weathers[new_weather] ~= nil) then
|
||||
if (mcl_weather.state ~= nil and mcl_weather.reg_weathers[mcl_weather.state] ~= nil) then
|
||||
mcl_weather.reg_weathers[mcl_weather.state].clear()
|
||||
end
|
||||
mcl_weather.state = new_weather
|
||||
local weather_meta = mcl_weather.reg_weathers[mcl_weather.state]
|
||||
mcl_weather.end_time = mcl_weather.get_rand_end_time(weather_meta.min_duration, weather_meta.max_duration)
|
||||
mcl_weather.skycolor.update_sky_color()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
mcl_weather.get_weather = function()
|
||||
return mcl_weather.state
|
||||
end
|
||||
|
||||
minetest.register_privilege("weather_manager", {
|
||||
|
@ -151,27 +177,19 @@ minetest.register_chatcommand("weather", {
|
|||
privs = {weather_manager = true},
|
||||
func = function(name, param)
|
||||
if (param == "") then
|
||||
minetest.chat_send_player(name, "Error: No weather specified.")
|
||||
return
|
||||
return false, "Error: No weather specified."
|
||||
end
|
||||
local success = false
|
||||
if (param == "clear") then
|
||||
if (weather.state ~= nil and weather.reg_weathers[weather.state] ~= nil) then
|
||||
weather.reg_weathers[weather.state].clear()
|
||||
end
|
||||
weather.state = "none"
|
||||
success = true
|
||||
return
|
||||
end
|
||||
|
||||
if (weather.reg_weathers ~= nil and weather.reg_weathers[param] ~= nil) then
|
||||
if (weather.state ~= nil and weather.state ~= "none" and weather.reg_weathers[weather.state] ~= nil) then
|
||||
weather.reg_weathers[weather.state].clear()
|
||||
end
|
||||
weather.state = param
|
||||
return
|
||||
local new_weather
|
||||
if param == "clear" then
|
||||
new_weather = "none"
|
||||
else
|
||||
minetest.chat_send_player(name, "Error: Invalid weather specified. Use “clear”, “rain”, “snow” or “thunder”.")
|
||||
new_weather = param
|
||||
end
|
||||
local success = mcl_weather.change_weather(new_weather)
|
||||
if success then
|
||||
return true
|
||||
else
|
||||
return false, "Error: Invalid weather specified. Use “clear”, “rain”, “snow” or “thunder”."
|
||||
end
|
||||
end
|
||||
})
|
||||
|
@ -182,19 +200,14 @@ minetest.register_chatcommand("toggledownfall", {
|
|||
privs = {weather_manager = true},
|
||||
func = function(name, param)
|
||||
-- Currently rain/thunder/snow: Set weather to clear
|
||||
if weather.state ~= "none" then
|
||||
if (weather.state ~= nil and weather.state ~= "none" and weather.reg_weathers[weather.state] ~= nil) then
|
||||
weather.reg_weathers[weather.state].clear()
|
||||
end
|
||||
weather.state = "none"
|
||||
if mcl_weather.state ~= "none" then
|
||||
return mcl_weather.change_weather("none")
|
||||
|
||||
-- Currently clear: Set weather randomly to rain/thunder/snow
|
||||
else
|
||||
local new = { "rain", "thunder", "snow" }
|
||||
local r = math.random(1, #new)
|
||||
if (weather.state ~= nil and weather.state ~= "none" and weather.reg_weathers[weather.state] ~= nil) then
|
||||
weather.reg_weathers[weather.state].clear()
|
||||
end
|
||||
weather.state = new[r]
|
||||
return mcl_weather.change_weather(new[r])
|
||||
end
|
||||
end
|
||||
})
|
||||
|
@ -203,5 +216,5 @@ minetest.register_chatcommand("toggledownfall", {
|
|||
-- Weather mods expected to be use this flag before registering ABM.
|
||||
local weather_allow_abm = minetest.settings:get_bool("weather_allow_abm")
|
||||
if weather_allow_abm ~= nil and weather_allow_abm == false then
|
||||
weather.allow_abm = false
|
||||
mcl_weather.allow_abm = false
|
||||
end
|
|
@ -1 +0,0 @@
|
|||
Set of weathers for minetest.
|
|
@ -1 +0,0 @@
|
|||
name = weather_pack
|
|
@ -1,59 +0,0 @@
|
|||
-- turn off lightning mod 'auto mode'
|
||||
lightning.auto = false
|
||||
|
||||
thunder = {
|
||||
next_strike = 0,
|
||||
min_delay = 3,
|
||||
max_delay = 12,
|
||||
init_done = false,
|
||||
}
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
if weather.state ~= "thunder" then
|
||||
return false
|
||||
end
|
||||
|
||||
rain.set_particles_mode("thunder")
|
||||
rain.make_weather()
|
||||
|
||||
if thunder.init_done == false then
|
||||
skycolor.add_layer(
|
||||
"weather-pack-thunder-sky",
|
||||
{{r=0, g=0, b=0},
|
||||
{r=40, g=40, b=40},
|
||||
{r=85, g=86, b=86},
|
||||
{r=40, g=40, b=40},
|
||||
{r=0, g=0, b=0}})
|
||||
skycolor.active = true
|
||||
for _, player in pairs(minetest.get_connected_players()) do
|
||||
player:set_clouds({color="#3D3D3FE8"})
|
||||
|
||||
end
|
||||
thunder.init_done = true
|
||||
end
|
||||
|
||||
if (thunder.next_strike <= minetest.get_gametime()) then
|
||||
lightning.strike()
|
||||
local delay = math.random(thunder.min_delay, thunder.max_delay)
|
||||
thunder.next_strike = minetest.get_gametime() + delay
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
thunder.clear = function()
|
||||
rain.clear()
|
||||
skycolor.remove_layer("weather-pack-thunder-sky")
|
||||
skycolor.remove_layer("lightning")
|
||||
thunder.init_done = false
|
||||
end
|
||||
|
||||
-- register thunderstorm weather
|
||||
if weather.reg_weathers.thunder == nil then
|
||||
weather.reg_weathers.thunder = {
|
||||
chance = 5,
|
||||
light_factor = 0.33333,
|
||||
clear = thunder.clear,
|
||||
min_duration = 120,
|
||||
max_duration = 600,
|
||||
}
|
||||
end
|
|
@ -62,7 +62,9 @@ end)
|
|||
doc.sub.items.register_factoid("nodes", "groups", function(itemstring, def)
|
||||
local datastring = ""
|
||||
if def.groups.place_flowerlike == 1 then
|
||||
return "This plant can only grow on dirt, grass blocks and podzol. To survive, it needs to have an unobstructed view to the sky above or be exposed to a light level of 8 or higher."
|
||||
return "This plant can only grow on grass blocks and dirt. To survive, it needs to have an unobstructed view to the sky above or be exposed to a light level of 8 or higher."
|
||||
elseif def.groups.place_flowerlike == 2 then
|
||||
return "This plant can grow on grass blocks, podzol, dirt and coarse dirt. To survive, it needs to have an unobstructed view to the sky above or be exposed to a light level of 8 or higher."
|
||||
end
|
||||
return ""
|
||||
end)
|
||||
|
|
|
@ -139,18 +139,36 @@ local boffset = {} --
|
|||
local hoch = {}
|
||||
local bg = {}
|
||||
|
||||
noffset["blocks"] = {-0.29,-0.25}
|
||||
noffset["deco"] = {0.98,-0.25}
|
||||
noffset["redstone"] = {2.23,-0.25}
|
||||
noffset["rail"] = {3.495,-0.25}
|
||||
noffset["misc"] = {4.75,-0.25}
|
||||
noffset["nix"] = {8.99,-0.25}
|
||||
noffset["food"] = {-0.29,8.12}
|
||||
noffset["tools"] = {0.98,8.12}
|
||||
noffset["combat"] = {2.23,8.12}
|
||||
noffset["brew"] = {3.495,8.12}
|
||||
noffset["matr"] = {4.74,8.12}
|
||||
noffset["inv"] = {8.99,8.12}
|
||||
local noffset_x_start = -0.24
|
||||
local noffset_x = noffset_x_start
|
||||
local noffset_y = -0.25
|
||||
local next_noffset = function(id, right)
|
||||
if right then
|
||||
noffset[id] = { 8.94, noffset_y }
|
||||
else
|
||||
noffset[id] = { noffset_x, noffset_y }
|
||||
noffset_x = noffset_x + 1.25
|
||||
end
|
||||
end
|
||||
|
||||
-- Upper row
|
||||
next_noffset("blocks")
|
||||
next_noffset("deco")
|
||||
next_noffset("redstone")
|
||||
next_noffset("rail")
|
||||
next_noffset("misc")
|
||||
next_noffset("nix", true)
|
||||
|
||||
noffset_x = noffset_x_start
|
||||
noffset_y = 8.12
|
||||
|
||||
-- Lower row
|
||||
next_noffset("food")
|
||||
next_noffset("tools")
|
||||
next_noffset("combat")
|
||||
next_noffset("brew")
|
||||
next_noffset("matr")
|
||||
next_noffset("inv", true)
|
||||
|
||||
for k,v in pairs(noffset) do
|
||||
offset[k] = tostring(v[1]) .. "," .. tostring(v[2])
|
||||
|
@ -218,8 +236,14 @@ mcl_inventory.set_creative_formspec = function(player, start_i, pagenum, inv_siz
|
|||
"listring[current_player;main]"..
|
||||
"listring[detached:trash;main]"
|
||||
|
||||
if page ~= nil then name = page end
|
||||
if page ~= nil then
|
||||
name = page
|
||||
if players[playername] then
|
||||
players[playername].page = page
|
||||
end
|
||||
end
|
||||
bg[name] = "crafting_creative_bg.png"
|
||||
|
||||
local inv_bg = "crafting_inventory_creative.png"
|
||||
if name == "inv" then
|
||||
inv_bg = "crafting_inventory_creative_survival.png"
|
||||
|
@ -287,61 +311,67 @@ mcl_inventory.set_creative_formspec = function(player, start_i, pagenum, inv_siz
|
|||
"image[9.033," .. tostring(slider_pos) .. ";0.78,"..tostring(slider_height) .. ";crafting_slider.png]"..
|
||||
"image_button[9.02,6.15;"..tostring(arrow_height)..",0.6;crafting_creative_down.png;creative_next;]"
|
||||
end
|
||||
local function tab(current, check)
|
||||
local img
|
||||
if current == check then
|
||||
img = "crafting_creative_active.png"
|
||||
|
||||
local tab_icon = {
|
||||
blocks = "mcl_core:brick_block",
|
||||
deco = "mcl_flowers:peony",
|
||||
redstone = "mesecons:redstone",
|
||||
rail = "mcl_minecarts:golden_rail",
|
||||
misc = "mcl_buckets:bucket_lava",
|
||||
nix = "mcl_compass:compass",
|
||||
food = "mcl_core:apple",
|
||||
tools = "mcl_core:axe_iron",
|
||||
combat = "mcl_core:sword_gold",
|
||||
brew = "mcl_potions:potion_water",
|
||||
matr = "mcl_core:stick",
|
||||
inv = "mcl_chests:chest",
|
||||
}
|
||||
local function tab(current_tab, this_tab)
|
||||
local bg_img
|
||||
if current_tab == this_tab then
|
||||
bg_img = "crafting_creative_active.png"
|
||||
else
|
||||
img = "crafting_creative_inactive.png"
|
||||
bg_img = "crafting_creative_inactive.png"
|
||||
end
|
||||
return "image[" .. offset[check] .. ";1.5,1.44;" .. img .. hoch[check].. "]" ..
|
||||
"image[" .. boffset[check] .. ";1,1;crafting_creative_marker.png]"
|
||||
return
|
||||
"item_image_button[" .. boffset[this_tab] ..";1,1;"..tab_icon[this_tab]..";"..this_tab..";]"..
|
||||
"image[" .. offset[this_tab] .. ";1.5,1.44;" .. bg_img .. hoch[this_tab].. "]" ..
|
||||
"image[" .. boffset[this_tab] .. ";1,1;crafting_creative_marker.png]"
|
||||
end
|
||||
local fnt = ""
|
||||
if name ~= "inv" then
|
||||
fnt = "image[0,1;5,0.75;mcl_inventory_fnt_"..name..".png]"
|
||||
end
|
||||
|
||||
formspec = "size[10,9.3]"..
|
||||
mcl_vars.inventory_header..
|
||||
"background[-0.19,-0.25;10.5,9.87;"..inv_bg.."]"..
|
||||
"label[-5,-5;"..name.."]"..
|
||||
"item_image_button[-0.1,0;1,1;mcl_core:brick_block;blocks;]".. --build blocks
|
||||
tab(name, "blocks") ..
|
||||
"tooltip[blocks;Building Blocks]"..
|
||||
"item_image_button[1.15,0;1,1;mcl_flowers:peony;deco;]".. --decoration blocks
|
||||
tab(name, "deco") ..
|
||||
"tooltip[deco;Decoration Blocks]"..
|
||||
"item_image_button[2.415,0;1,1;mesecons:redstone;redstone;]".. --redstone
|
||||
tab(name, "redstone") ..
|
||||
"tooltip[redstone;Redstone]"..
|
||||
"item_image_button[3.693,0;1,1;mcl_minecarts:golden_rail;rail;]".. --transportation
|
||||
tab(name, "rail") ..
|
||||
"tooltip[rail;Transportation]"..
|
||||
"item_image_button[4.93,0;1,1;mcl_buckets:bucket_lava;misc;]".. --miscellaneous
|
||||
tab(name, "misc") ..
|
||||
"tooltip[misc;Miscellaneous]"..
|
||||
"item_image_button[9.19,0;1,1;mcl_compass:compass;nix;]".. --search
|
||||
tab(name, "nix") ..
|
||||
"tooltip[nix;Search Items]"..
|
||||
fnt..
|
||||
"list[current_player;main;0,7;9,1;]"..
|
||||
main_list..
|
||||
"item_image_button[-0.1,8.37;1,1;mcl_core:apple;food;]".. --foodstuff
|
||||
tab(name, "food") ..
|
||||
"tooltip[food;Foodstuffs]"..
|
||||
"item_image_button[1.15,8.37;1,1;mcl_core:axe_iron;tools;]".. --tools
|
||||
tab(name, "tools") ..
|
||||
"tooltip[tools;Tools]"..
|
||||
"item_image_button[2.415,8.37;1,1;mcl_core:sword_gold;combat;]".. --combat
|
||||
tab(name, "combat") ..
|
||||
"tooltip[combat;Combat]"..
|
||||
"item_image_button[3.693,8.37;1,1;mcl_potions:potion_water;brew;]".. --brewing
|
||||
tab(name, "brew") ..
|
||||
"tooltip[brew;Brewing]"..
|
||||
"item_image_button[4.938,8.37;1,1;mcl_core:stick;matr;]".. --materials
|
||||
tab(name, "matr") ..
|
||||
"tooltip[matr;Materials]"..
|
||||
"item_image_button[9.19,8.37;1,1;mcl_chests:chest;inv;]".. --inventory
|
||||
tab(name, "inv") ..
|
||||
"tooltip[inv;Survival Inventory]"..
|
||||
"list[detached:trash;main;9,7;1,1;]"..
|
||||
|
|
|
@ -85,9 +85,9 @@ local buttonuse = "Rightclick the button to push it."
|
|||
minetest.register_node("mesecons_button:button_stone_off", {
|
||||
drawtype = "nodebox",
|
||||
tiles = {"default_stone.png"},
|
||||
wield_image = "default_stone.png^[mask:mesecons_button_wield_mask.png",
|
||||
wield_image = "mesecons_button_wield_mask.png^default_stone.png^mesecons_button_wield_mask.png^[makealpha:255,126,126",
|
||||
-- FIXME: Use proper 3D inventory image
|
||||
inventory_image = "default_stone.png^[mask:mesecons_button_wield_mask.png",
|
||||
inventory_image = "mesecons_button_wield_mask.png^default_stone.png^mesecons_button_wield_mask.png^[makealpha:255,126,126",
|
||||
wield_scale = { x=1, y=1, z=1},
|
||||
paramtype = "light",
|
||||
paramtype2 = "wallmounted",
|
||||
|
@ -119,8 +119,8 @@ minetest.register_node("mesecons_button:button_stone_off", {
|
|||
minetest.register_node("mesecons_button:button_stone_on", {
|
||||
drawtype = "nodebox",
|
||||
tiles = {"default_stone.png"},
|
||||
wield_image = "default_stone.png^[mask:mesecons_button_wield_mask.png",
|
||||
inventory_image = "default_stone.png^[mask:mesecons_button_wield_mask.png",
|
||||
wield_image = "mesecons_button_wield_mask.png^default_stone.png^mesecons_button_wield_mask.png^[makealpha:255,126,126",
|
||||
inventory_image = "mesecons_button_wield_mask.png^default_stone.png^mesecons_button_wield_mask.png^[makealpha:255,126,126",
|
||||
wield_scale = { x=1, y=1, z=0.5},
|
||||
paramtype = "light",
|
||||
paramtype2 = "wallmounted",
|
||||
|
@ -145,8 +145,8 @@ minetest.register_node("mesecons_button:button_stone_on", {
|
|||
minetest.register_node("mesecons_button:button_wood_off", {
|
||||
drawtype = "nodebox",
|
||||
tiles = {"default_wood.png"},
|
||||
wield_image = "default_wood.png^[mask:mesecons_button_wield_mask.png",
|
||||
inventory_image = "default_wood.png^[mask:mesecons_button_wield_mask.png",
|
||||
wield_image = "mesecons_button_wield_mask.png^default_wood.png^mesecons_button_wield_mask.png^[makealpha:255,126,126",
|
||||
inventory_image = "mesecons_button_wield_mask.png^default_wood.png^mesecons_button_wield_mask.png^[makealpha:255,126,126",
|
||||
wield_scale = { x=1, y=1, z=1},
|
||||
paramtype = "light",
|
||||
paramtype2 = "wallmounted",
|
||||
|
@ -178,8 +178,8 @@ minetest.register_node("mesecons_button:button_wood_off", {
|
|||
minetest.register_node("mesecons_button:button_wood_on", {
|
||||
drawtype = "nodebox",
|
||||
tiles = {"default_wood.png"},
|
||||
wield_image = "default_wood.png^[mask:mesecons_button_wield_mask.png",
|
||||
inventory_image = "default_wood.png^[mask:mesecons_button_wield_mask.png",
|
||||
wield_image = "mesecons_button_wield_mask.png^default_wood.png^mesecons_button_wield_mask.png^[makealpha:255,126,126",
|
||||
inventory_image = "mesecons_button_wield_mask.png^default_wood.png^mesecons_button_wield_mask.png^[makealpha:255,126,126",
|
||||
wield_scale = { x=1, y=1, z=0.5},
|
||||
paramtype = "light",
|
||||
paramtype2 = "wallmounted",
|
||||
|
|
Before Width: | Height: | Size: 100 B After Width: | Height: | Size: 115 B |
|
@ -781,7 +781,7 @@ local piston_get_stopper = function (node, dir, stack, stackid)
|
|||
|
||||
if minetest.registered_nodes[node.name].mesecons_piston.pusher == pushernode.name then
|
||||
for _, s in ipairs(stack) do
|
||||
if mesecon.cmpPos(s.pos, pusherpos) -- pusher is also to be pushed
|
||||
if vector.equals(s.pos, pusherpos) -- pusher is also to be pushed
|
||||
and s.node.param2 == node.param2 then
|
||||
return false
|
||||
end
|
||||
|
|
|
@ -22,17 +22,17 @@ local function destruct_bed(pos, n)
|
|||
end
|
||||
end
|
||||
|
||||
local beddesc = "Beds allow you to sleep at night and waste some time. Survival in this world does not demand sleep, but sleeping might have some other uses. "
|
||||
local beduse = "Right-click on the bed to try to sleep in it. This only works when the sun sets or at night."
|
||||
local beddesc = "Beds allow you to sleep at night and make the time pass faster."
|
||||
local beduse = "Right-click on the bed to sleep in it. This only works when the sun sets, at night or during a thunderstorm."
|
||||
if minetest.settings:get_bool("enable_bed_respawn") == false then
|
||||
beddesc = beddesc .. "In local folklore, legends are told of other worlds where setting the start point for your next would be possible. But this world is not one of them. "
|
||||
beddesc = beddesc .. "\n" .. "In local folklore, legends are told of other worlds where setting the start point for your next would be possible. But this world is not one of them."
|
||||
else
|
||||
beddesc = beddesc .. "By sleeping in a bed, you set the starting point for your next life. "
|
||||
beddesc = beddesc .. "\n" .. "By sleeping in a bed, you set the starting point for your next life."
|
||||
end
|
||||
if minetest.settings:get_bool("enable_bed_night_skip") == false then
|
||||
beddesc = beddesc .. "In this strange world, the time will not pass faster for you when you sleep."
|
||||
beddesc = beddesc .. "\n" .. "In this strange world, going to bed won't skip the night, but you can skip thunderstorms."
|
||||
else
|
||||
beddesc = beddesc .. "Going into bed seems to make time pass faster: The night will be skipped when you go sleep and you're alone in this world. If you're not alone, the night is skipped when all players in this world went to sleep."
|
||||
beddesc = beddesc .. "\n" .. "Sleeping allows you to skip the night if you're the only player in this world. If you're not alone, the night is skipped when all players in this world went to sleep. Thunderstorms can be skipped in the same manner."
|
||||
end
|
||||
|
||||
local default_sounds
|
||||
|
|
|
@ -3,3 +3,4 @@ mcl_util?
|
|||
mcl_wool?
|
||||
mcl_dye?
|
||||
mcl_tnt?
|
||||
mcl_weather?
|
||||
|
|
|
@ -5,6 +5,7 @@ local enable_respawn = minetest.settings:get_bool("enable_bed_respawn")
|
|||
if enable_respawn == nil then
|
||||
enable_respawn = true
|
||||
end
|
||||
local weather_mod = minetest.get_modpath("mcl_weather") ~= nil
|
||||
|
||||
-- Helper functions
|
||||
|
||||
|
@ -121,9 +122,19 @@ local function update_formspecs(finished)
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
-- Public functions
|
||||
|
||||
-- Handle environment stuff related to sleeping: skip night and thunderstorm
|
||||
function mcl_beds.sleep()
|
||||
local storm_skipped = mcl_beds.skip_thunderstorm()
|
||||
if is_night_skip_enabled() then
|
||||
if not storm_skipped then
|
||||
mcl_beds.skip_night()
|
||||
end
|
||||
mcl_beds.kick_players()
|
||||
end
|
||||
end
|
||||
|
||||
function mcl_beds.kick_players()
|
||||
for name, _ in pairs(mcl_beds.player) do
|
||||
local player = minetest.get_player_by_name(name)
|
||||
|
@ -135,7 +146,22 @@ function mcl_beds.skip_night()
|
|||
minetest.set_timeofday(0.25) -- tod = 6000
|
||||
end
|
||||
|
||||
function mcl_beds.skip_thunderstorm()
|
||||
-- Skip thunderstorm
|
||||
if weather_mod and mcl_weather.get_weather() == "thunder" then
|
||||
mcl_weather.change_weather("none")
|
||||
-- Sleep for a half day (=minimum thunderstorm duration)
|
||||
minetest.set_timeofday((minetest.get_timeofday() + 0.5) % 1)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function mcl_beds.on_rightclick(pos, player)
|
||||
-- Anti-Inception: Don't allow to sleep while you're sleeping
|
||||
if player:get_attribute("mcl_beds:sleeping") == "true" then
|
||||
return
|
||||
end
|
||||
if minetest.get_modpath("mcl_init") then
|
||||
local _, dim = mcl_util.y_to_layer(pos.y)
|
||||
if dim == "nether" or dim == "end" then
|
||||
|
@ -152,11 +178,11 @@ function mcl_beds.on_rightclick(pos, player)
|
|||
local tod = minetest.get_timeofday() * 24000
|
||||
|
||||
-- Values taken from Minecraft Wiki with offset of +6000
|
||||
if tod < 18541 and tod > 5458 then
|
||||
if tod < 18541 and tod > 5458 and (not weather_mod or (mcl_weather.get_weather() ~= "thunder")) then
|
||||
if mcl_beds.player[name] then
|
||||
lay_down(player, nil, nil, false)
|
||||
end
|
||||
minetest.chat_send_player(name, "You can only sleep at night.")
|
||||
minetest.chat_send_player(name, "You can only sleep at night or during a thunderstorm.")
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -178,10 +204,7 @@ function mcl_beds.on_rightclick(pos, player)
|
|||
if not is_sp then
|
||||
update_formspecs(is_night_skip_enabled())
|
||||
end
|
||||
if is_night_skip_enabled() then
|
||||
mcl_beds.skip_night()
|
||||
mcl_beds.kick_players()
|
||||
end
|
||||
mcl_beds.sleep()
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
@ -207,10 +230,7 @@ minetest.register_on_leaveplayer(function(player)
|
|||
if check_in_beds() then
|
||||
minetest.after(2, function()
|
||||
update_formspecs(is_night_skip_enabled())
|
||||
if is_night_skip_enabled() then
|
||||
mcl_beds.skip_night()
|
||||
mcl_beds.kick_players()
|
||||
end
|
||||
mcl_beds.sleep()
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
@ -226,9 +246,6 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
|
||||
if fields.force then
|
||||
update_formspecs(is_night_skip_enabled())
|
||||
if is_night_skip_enabled() then
|
||||
mcl_beds.skip_night()
|
||||
mcl_beds.kick_players()
|
||||
end
|
||||
mcl_beds.sleep()
|
||||
end
|
||||
end)
|
||||
|
|
Before Width: | Height: | Size: 221 B After Width: | Height: | Size: 403 B |
|
@ -645,7 +645,7 @@ local grass_spread_randomizer = PseudoRandom(minetest.get_mapgen_setting("seed")
|
|||
minetest.register_abm({
|
||||
label = "Grass Block and Mycelium spread",
|
||||
nodenames = {"mcl_core:dirt"},
|
||||
neighbors = {"air", "mcl_core:dirt_with_grass", "mcl_core:mycelium"},
|
||||
neighbors = {"air", "group:grass_block_no_snow", "mcl_core:mycelium"},
|
||||
interval = 30,
|
||||
chance = 20,
|
||||
catch_up = false,
|
||||
|
@ -1190,12 +1190,22 @@ end
|
|||
-- of the snowed node.
|
||||
mcl_core.register_snowed_node = function(itemstring_snowed, itemstring_clear, tiles, sounds)
|
||||
local def = table.copy(minetest.registered_nodes[itemstring_clear])
|
||||
local create_doc_alias
|
||||
if def.description then
|
||||
create_doc_alias = true
|
||||
else
|
||||
create_doc_alias = false
|
||||
end
|
||||
-- Just some group clearing
|
||||
def.description = nil
|
||||
def._doc_items_longdesc = nil
|
||||
def._doc_items_usagehelp = nil
|
||||
def._doc_items_create_entry = false
|
||||
def.groups.not_in_creative_inventory = 1
|
||||
if def.groups.grass_block == 1 then
|
||||
def.groups.grass_block_no_snow = nil
|
||||
def.groups.grass_block_snow = 1
|
||||
end
|
||||
|
||||
-- Enderman must never take this because this block is supposed to be always buried below snow.
|
||||
def.groups.enderman_takable = nil
|
||||
|
@ -1224,7 +1234,7 @@ mcl_core.register_snowed_node = function(itemstring_snowed, itemstring_clear, ti
|
|||
-- Register stuff
|
||||
minetest.register_node(itemstring_snowed, def)
|
||||
|
||||
if minetest.get_modpath("doc") then
|
||||
if create_doc_alias and minetest.get_modpath("doc") then
|
||||
doc.add_entry_alias("nodes", itemstring_clear, "nodes", itemstring_snowed)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -295,6 +295,7 @@ minetest.register_node("mcl_core:diorite_smooth", {
|
|||
_mcl_hardness = 1.5,
|
||||
})
|
||||
|
||||
-- Grass Block
|
||||
minetest.register_node("mcl_core:dirt_with_grass", {
|
||||
description = "Grass Block",
|
||||
_doc_items_longdesc = "A grass block is dirt with a grass cover. Grass blocks are resourceful blocks which allow the growth of all sorts of plants. They can be turned into farmland with a hoe and turned into grass paths with a shovel. In light, the grass slowly spreads onto dirt nearby. Under an opaque block or a liquid, a grass block may turn back to dirt.",
|
||||
|
@ -302,17 +303,57 @@ minetest.register_node("mcl_core:dirt_with_grass", {
|
|||
tiles = {"default_grass.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
|
||||
is_ground_content = true,
|
||||
stack_max = 64,
|
||||
groups = {handy=1,shovely=1, soil=1, soil_sapling=2, soil_sugarcane=1, cultivatable=2, spreading_dirt_type=1, enderman_takable=1, building_block=1},
|
||||
groups = {handy=1,shovely=1, grass_block=1, grass_block_no_snow=1, soil=1, soil_sapling=2, soil_sugarcane=1, cultivatable=2, spreading_dirt_type=1, enderman_takable=1, building_block=1},
|
||||
drop = 'mcl_core:dirt',
|
||||
sounds = mcl_sounds.node_sound_dirt_defaults({
|
||||
footstep = {name="default_grass_footstep", gain=0.4},
|
||||
}),
|
||||
on_construct = function(pos)
|
||||
local _, dim = mcl_util.y_to_layer(pos.y)
|
||||
local dry
|
||||
if dim == "nether" then
|
||||
dry = true
|
||||
else
|
||||
local found_node = minetest.find_node_near(pos, 1, {"mcl_core:dirt_with_dry_grass", "mcl_core:dirt_with_dry_grass_snow"})
|
||||
if found_node then
|
||||
dry = true
|
||||
end
|
||||
end
|
||||
if dry then
|
||||
minetest.set_node(pos, {name="mcl_core:dirt_with_dry_grass"})
|
||||
end
|
||||
return mcl_core.on_snowable_construct(pos)
|
||||
end,
|
||||
_mcl_snowed = "mcl_core:dirt_with_grass_snow",
|
||||
_mcl_grass_palette_index = 0,
|
||||
_mcl_blast_resistance = 3,
|
||||
_mcl_hardness = 0.6,
|
||||
})
|
||||
mcl_core.register_snowed_node("mcl_core:dirt_with_grass_snow", "mcl_core:dirt_with_grass")
|
||||
|
||||
-- Grass Block variant for dry biomes
|
||||
minetest.register_node("mcl_core:dirt_with_dry_grass", {
|
||||
_doc_items_create_entry = false,
|
||||
tiles = {"default_dry_grass.png", "default_dirt.png", "default_dirt.png^default_dry_grass_side.png"},
|
||||
is_ground_content = true,
|
||||
stack_max = 64,
|
||||
groups = {handy=1,shovely=1, grass_block=1, grass_block_no_snow=1, soil=1, soil_sapling=2, soil_sugarcane=1, cultivatable=2, spreading_dirt_type=1, enderman_takable=1, building_block=1, not_in_creative_inventory=1},
|
||||
drop = 'mcl_core:dirt',
|
||||
sounds = mcl_sounds.node_sound_dirt_defaults({
|
||||
footstep = {name="default_grass_footstep", gain=0.4},
|
||||
}),
|
||||
on_construct = mcl_core.on_snowable_construct,
|
||||
_mcl_snowed = "mcl_core:dirt_with_grass_snow",
|
||||
_mcl_snowed = "mcl_core:dirt_with_dry_grass_snow",
|
||||
_mcl_grass_palette_index = 1,
|
||||
_mcl_blast_resistance = 3,
|
||||
_mcl_hardness = 0.6,
|
||||
})
|
||||
mcl_core.register_snowed_node("mcl_core:dirt_with_grass_snow", "mcl_core:dirt_with_grass")
|
||||
mcl_core.register_snowed_node("mcl_core:dirt_with_dry_grass_snow", "mcl_core:dirt_with_dry_grass")
|
||||
|
||||
if minetest.get_modpath("doc") then
|
||||
doc.add_entry_alias("nodes", "mcl_core:dirt_with_grass", "nodes", "mcl_core:dirt_with_dry_grass")
|
||||
doc.add_entry_alias("nodes", "mcl_core:dirt_with_grass", "nodes", "mcl_core:dirt_with_dry_grass_snow")
|
||||
end
|
||||
|
||||
minetest.register_node("mcl_core:grass_path", {
|
||||
tiles = {"mcl_core_grass_path_top.png", "default_dirt.png", "mcl_core_grass_path_side.png"},
|
||||
|
|
|
@ -89,7 +89,7 @@ minetest.register_node("mcl_core:deadbush", {
|
|||
walkable = false,
|
||||
stack_max = 64,
|
||||
buildable_to = true,
|
||||
groups = {dig_immediate=3, flammable=3,attached_node=1,plant=1,non_mycelium_plant=1,dig_by_water=1,destroy_by_lava_flow=1,deco_block=1},
|
||||
groups = {handy=1,shearsy=1, flammable=3,attached_node=1,plant=1,non_mycelium_plant=1,dig_by_water=1,destroy_by_lava_flow=1,deco_block=1},
|
||||
drop = {
|
||||
max_items = 1,
|
||||
items = {
|
||||
|
@ -107,7 +107,7 @@ minetest.register_node("mcl_core:deadbush", {
|
|||
sounds = mcl_sounds.node_sound_leaves_defaults(),
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-6/16, -8/16, -6/16, 6/16, 8/16, 6/16},
|
||||
fixed = {-5/16, -8/16, -5/16, 5/16, 1/16, 5/16},
|
||||
},
|
||||
_mcl_blast_resistance = 0,
|
||||
_mcl_hardness = 0,
|
||||
|
|
|
@ -112,7 +112,7 @@ local register_sapling = function(subname, description, longdesc, texture, selbo
|
|||
local node_below = minetest.get_node_or_nil({x=pos.x,y=pos.y-1,z=pos.z})
|
||||
if not node_below then return false end
|
||||
local nn = node_below.name
|
||||
return (nn=="mcl_core:dirt_with_grass" or nn=="mcl_core:dirt_with_grass_snow" or
|
||||
return ((minetest.get_item_group(nn, "grass_block") == 1) or
|
||||
nn=="mcl_core:podzol" or nn=="mcl_core:podzol_snow" or
|
||||
nn=="mcl_core:dirt")
|
||||
end),
|
||||
|
@ -165,12 +165,12 @@ register_wooden_planks("acaciawood", "Acacia Wood Planks", {"default_acacia_wood
|
|||
register_wooden_planks("birchwood", "Birch Wood Planks", {"mcl_core_planks_birch.png"})
|
||||
|
||||
|
||||
register_sapling("sapling", "Oak Sapling", "When placed on soil (such as dirt) and exposed to light, an oak sapling will grow into an oak after some time.", "default_sapling.png", {-6/16, -0.5, -6/16, 6/16, 0.5, 6/16})
|
||||
register_sapling("darksapling", "Dark Oak Sapling", "Dark oak saplings can grow into dark oaks, but only in groups. A lonely dark oak sapling won't grow. A group of four dark oak saplings grows into a dark oak after some time when they are placed on soil (such as dirt) in a 2×2 square and exposed to light.", "mcl_core_sapling_big_oak.png", {-5.5/16, -0.5, -5.5/16, 5.5/16, 0.5, 5.5/16})
|
||||
register_sapling("junglesapling", "Jungle Sapling", "When placed on soil (such as dirt) and exposed to light, a jungle sapling will grow into a jungle tree after some time. When there are 4 jungle saplings in a 2×2 square, they will grow to a huge jungle tree.", "default_junglesapling.png", {-4/16, -0.5, -4/16, 4/16, 0.5, 4/16})
|
||||
register_sapling("acaciasapling", "Acacia Sapling", "When placed on soil (such as dirt) and exposed to light, an acacia sapling will grow into an acacia after some time.", "default_acacia_sapling.png", {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3})
|
||||
register_sapling("sprucesapling", "Spruce Sapling", "When placed on soil (such as dirt) and exposed to light, a spruce sapling will grow into a spruce after some time. When there are 4 spruce saplings in a 2×2 square, they will grow to a huge spruce.", "mcl_core_sapling_spruce.png", {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3})
|
||||
register_sapling("birchsapling", "Birch Sapling", "When placed on soil (such as dirt) and exposed to light, a birch sapling will grow into a birch after some time.", "mcl_core_sapling_birch.png", {-6/16, -0.5, -6/16, 6/16, 0.5, 6/16})
|
||||
register_sapling("sapling", "Oak Sapling", "When placed on soil (such as dirt) and exposed to light, an oak sapling will grow into an oak after some time.", "default_sapling.png", {-5/16, -0.5, -5/16, 5/16, 0.5, 5/16})
|
||||
register_sapling("darksapling", "Dark Oak Sapling", "Dark oak saplings can grow into dark oaks, but only in groups. A lonely dark oak sapling won't grow. A group of four dark oak saplings grows into a dark oak after some time when they are placed on soil (such as dirt) in a 2×2 square and exposed to light.", "mcl_core_sapling_big_oak.png", {-5/16, -0.5, -5/16, 5/16, 7/16, 5/16})
|
||||
register_sapling("junglesapling", "Jungle Sapling", "When placed on soil (such as dirt) and exposed to light, a jungle sapling will grow into a jungle tree after some time. When there are 4 jungle saplings in a 2×2 square, they will grow to a huge jungle tree.", "default_junglesapling.png", {-5/16, -0.5, -5/16, 5/16, 0.5, 5/16})
|
||||
register_sapling("acaciasapling", "Acacia Sapling", "When placed on soil (such as dirt) and exposed to light, an acacia sapling will grow into an acacia after some time.", "default_acacia_sapling.png", {-5/16, -0.5, -5/16, 5/16, 4/16, 5/16})
|
||||
register_sapling("sprucesapling", "Spruce Sapling", "When placed on soil (such as dirt) and exposed to light, a spruce sapling will grow into a spruce after some time. When there are 4 spruce saplings in a 2×2 square, they will grow to a huge spruce.", "mcl_core_sapling_spruce.png", {-4/16, -0.5, -4/16, 4/16, 0.5, 4/16})
|
||||
register_sapling("birchsapling", "Birch Sapling", "When placed on soil (such as dirt) and exposed to light, a birch sapling will grow into a birch after some time.", "mcl_core_sapling_birch.png", {-4/16, -0.5, -4/16, 4/16, 0.5, 4/16})
|
||||
|
||||
|
||||
register_leaves("leaves", "Oak Leaves", "Oak leaves are grown from oak trees.", {"default_leaves.png"}, "mcl_core:sapling", 20, "mcl_core:apple", 200)
|
||||
|
|
BIN
mods/ITEMS/mcl_core/textures/default_dry_grass.png
Normal file
After Width: | Height: | Size: 171 B |
BIN
mods/ITEMS/mcl_core/textures/default_dry_grass_side.png
Normal file
After Width: | Height: | Size: 183 B |
Before Width: | Height: | Size: 171 B After Width: | Height: | Size: 428 B |
Before Width: | Height: | Size: 183 B After Width: | Height: | Size: 306 B |
BIN
mods/ITEMS/mcl_core/textures/mcl_core_palette_grass.png
Normal file
After Width: | Height: | Size: 93 B |
|
@ -205,7 +205,7 @@ function mcl_doors:register_door(name, def)
|
|||
end
|
||||
|
||||
minetest.register_node(name.."_b_1", {
|
||||
tiles = {tt[2].."^[transformFY", tt[2], tb[2].."^[transformFX", tb[2], tb[1], tb[1].."^[transformFX"},
|
||||
tiles = {"blank.png", tt[2].."^[transformFXR90", tb[2], tb[2].."^[transformFX", tb[1], tb[1].."^[transformFX"},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
sunlight_propagates = true,
|
||||
|
@ -252,7 +252,7 @@ function mcl_doors:register_door(name, def)
|
|||
end
|
||||
|
||||
minetest.register_node(name.."_t_1", {
|
||||
tiles = {tt[2].."^[transformFY", tt[2], tt[2].."^[transformFX", tt[2], tt[1], tt[1].."^[transformFX"},
|
||||
tiles = {tt[2].."^[transformR90", "blank.png", tt[2], tt[2].."^[transformFX", tt[1], tt[1].."^[transformFX"},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
sunlight_propagates = true,
|
||||
|
@ -295,7 +295,7 @@ function mcl_doors:register_door(name, def)
|
|||
end
|
||||
|
||||
minetest.register_node(name.."_b_2", {
|
||||
tiles = {tt[2].."^[transformFY", tt[2], tb[2].."^[transformFX", tb[2], tb[1].."^[transformFX", tb[1]},
|
||||
tiles = {"blank.png", tt[2].."^[transformFXR90", tb[2].."^[transformI", tb[2].."^[transformFX", tb[1].."^[transformFX", tb[1]},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
sunlight_propagates = true,
|
||||
|
@ -342,7 +342,7 @@ function mcl_doors:register_door(name, def)
|
|||
end
|
||||
|
||||
minetest.register_node(name.."_t_2", {
|
||||
tiles = {tt[2].."^[transformFY", tt[2], tt[2].."^[transformFX", tt[2], tt[1].."^[transformFX", tt[1]},
|
||||
tiles = {tt[2].."^[transformR90", "blank.png", tt[2].."^[transformI", tt[2].."^[transformFX", tt[1].."^[transformFX", tt[1]},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
sunlight_propagates = true,
|
||||
|
|
|
@ -1,3 +1,20 @@
|
|||
-- Wrapper around mintest.pointed_thing_to_face_pos.
|
||||
local function get_fpos(placer, pointed_thing)
|
||||
local fpos
|
||||
-- Workaround: minetest.pointed_thing_to_face_pos crashes in MT 0.4.16 if
|
||||
-- pointed_thing.under and pointed_thing.above are equal
|
||||
-- FIXME: Remove this when MT got fixed.
|
||||
if not vector.equals(pointed_thing.under, pointed_thing.above) then
|
||||
-- The happy case: Everything is normal
|
||||
local finepos = minetest.pointed_thing_to_face_pos(placer, pointed_thing)
|
||||
fpos = finepos.y % 1
|
||||
else
|
||||
-- Fallback if both above and under are equal
|
||||
fpos = 0
|
||||
end
|
||||
return fpos
|
||||
end
|
||||
|
||||
---- Trapdoor ----
|
||||
|
||||
function mcl_doors:register_trapdoor(name, def)
|
||||
|
@ -91,9 +108,7 @@ function mcl_doors:register_trapdoor(name, def)
|
|||
param2 = minetest.dir_to_facedir(vector.subtract(p1, placer_pos))
|
||||
end
|
||||
|
||||
local finepos = minetest.pointed_thing_to_face_pos(placer, pointed_thing)
|
||||
local fpos = finepos.y % 1
|
||||
|
||||
local fpos = get_fpos(placer, pointed_thing)
|
||||
|
||||
local origname = itemstack:get_name()
|
||||
if p0.y - 1 == p1.y or (fpos > 0 and fpos < 0.5)
|
||||
|
|