Merge branch 'master' into day_night_ratio

This commit is contained in:
Wuzzy 2017-11-22 01:41:23 +01:00
commit bccc7fa957
158 changed files with 2394 additions and 2049 deletions

@ -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
self._taken_node = node.name
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.

@ -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")

@ -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

Binary file not shown.

@ -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,39 +116,55 @@ 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"
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
if mcl_weather.end_time == nil then
mcl_weather.end_time = mcl_weather.get_rand_end_time()
end
-- 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", {
description = "Gives ability to control weather",
give_to_singleplayer = false
@ -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",

Binary file not shown.

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)

Binary file not shown.

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)

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 B

After

Width:  |  Height:  |  Size: 428 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 B

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

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)

Some files were not shown because too many files have changed in this diff Show More