Compare commits
19 Commits
fix-dimens
...
master
Author | SHA1 | Date |
---|---|---|
|
23f1c51912 | |
|
4d02af8c94 | |
|
7ede0ca79a | |
|
e2e7e15b39 | |
|
93a0879b40 | |
|
0b5fa14041 | |
|
4f33f626f5 | |
|
df7bd78af5 | |
|
fe3e837e1b | |
|
6f811b3cee | |
|
dfa56f229f | |
|
ee77f33ea8 | |
|
5deaabdb47 | |
|
d77f31eab8 | |
|
10670d5c10 | |
|
609105e091 | |
|
f9e3c4fd6d | |
|
d70c05e92c | |
|
cacddd3fb4 |
|
@ -21,7 +21,7 @@ The basic digging time groups determine by which tools a node can be dug.
|
||||||
* `swordy=1`: Diggable by sword (any material), and this node is *not* a cobweb
|
* `swordy=1`: Diggable by sword (any material), and this node is *not* a cobweb
|
||||||
* `swordy_cobweb=1`: Diggable by sword (any material), and this node is a cobweb
|
* `swordy_cobweb=1`: Diggable by sword (any material), and this node is a cobweb
|
||||||
* `shearsy=1`: Diggable by shears, and this node is *not* wool
|
* `shearsy=1`: Diggable by shears, and this node is *not* wool
|
||||||
* `shearsy=wool=1`: Diggable by shears, and this node is wool
|
* `shearsy_wool=1`: Diggable by shears, and this node is wool
|
||||||
* `handy=1`: Breakable by hand and this node gives it useful drop when dug by hand. All nodes which are breakable by pickaxe, axe, shovel, sword or shears are also automatically breakable by hand, but not neccess
|
* `handy=1`: Breakable by hand and this node gives it useful drop when dug by hand. All nodes which are breakable by pickaxe, axe, shovel, sword or shears are also automatically breakable by hand, but not neccess
|
||||||
* `creative_breakable=1`: Block is breakable by hand in creative mode. This group is implied if the node belongs to any other digging group
|
* `creative_breakable=1`: Block is breakable by hand in creative mode. This group is implied if the node belongs to any other digging group
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,7 @@ local last_dimension = {}
|
||||||
-- * dimension: New dimension ("overworld", "nether", "end", "void")
|
-- * dimension: New dimension ("overworld", "nether", "end", "void")
|
||||||
function mcl_worlds.dimension_change(player, dimension)
|
function mcl_worlds.dimension_change(player, dimension)
|
||||||
for i=1, #mcl_worlds.registered_on_dimension_change do
|
for i=1, #mcl_worlds.registered_on_dimension_change do
|
||||||
mcl_worlds.registered_on_dimension_change[i](player, dimension, last_dimension[player:get_player_name()])
|
mcl_worlds.registered_on_dimension_change[i](player, dimension)
|
||||||
last_dimension[player:get_player_name()] = dimension
|
last_dimension[player:get_player_name()] = dimension
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,9 +7,102 @@ local function get_tool_name(item)
|
||||||
local def = item:get_definition()
|
local def = item:get_definition()
|
||||||
name=def._tt_original_description or def.description
|
name=def._tt_original_description or def.description
|
||||||
end
|
end
|
||||||
return name:gsub("[\r\n]"," ")
|
local sanitized_name, substitution_count = name:gsub("[\r\n]"," ")
|
||||||
|
return sanitized_name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local test_tool_1a = {
|
||||||
|
get_meta = function()
|
||||||
|
return {
|
||||||
|
get_string = function()
|
||||||
|
return "foo 1a"
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( get_tool_name(test_tool_1a) == "foo 1a" )
|
||||||
|
|
||||||
|
local test_tool_1b = {
|
||||||
|
get_meta = function()
|
||||||
|
return {
|
||||||
|
get_string = function()
|
||||||
|
return "bar\rbaz\n1b"
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( get_tool_name(test_tool_1b) == "bar baz 1b" )
|
||||||
|
|
||||||
|
local test_tool_2a = {
|
||||||
|
get_definition = function()
|
||||||
|
return {
|
||||||
|
_tt_original_description = "foo 2a"
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
get_meta = function()
|
||||||
|
return {
|
||||||
|
get_string = function()
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( get_tool_name(test_tool_2a) == "foo 2a" )
|
||||||
|
|
||||||
|
local test_tool_2b = {
|
||||||
|
get_definition = function()
|
||||||
|
return {
|
||||||
|
_tt_original_description = "bar\rbaz\n2b"
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
get_meta = function()
|
||||||
|
return {
|
||||||
|
get_string = function()
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( get_tool_name(test_tool_2b) == "bar baz 2b" )
|
||||||
|
|
||||||
|
local test_tool_3a = {
|
||||||
|
get_definition = function()
|
||||||
|
return {
|
||||||
|
description = "foo 3a"
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
get_meta = function()
|
||||||
|
return {
|
||||||
|
get_string = function()
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( get_tool_name(test_tool_3a) == "foo 3a" )
|
||||||
|
|
||||||
|
local test_tool_3b = {
|
||||||
|
get_definition = function()
|
||||||
|
return {
|
||||||
|
description = "bar\rbaz\n3b"
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
get_meta = function()
|
||||||
|
return {
|
||||||
|
get_string = function()
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( get_tool_name(test_tool_3b) == "bar baz 3b" )
|
||||||
|
|
||||||
mcl_death_messages = {}
|
mcl_death_messages = {}
|
||||||
|
|
||||||
-- Death messages
|
-- Death messages
|
||||||
|
|
|
@ -1,6 +1,41 @@
|
||||||
local S = minetest.get_translator("mcl_chests")
|
local S = minetest.get_translator("mcl_chests")
|
||||||
local mod_doc = minetest.get_modpath("doc")
|
local mod_doc = minetest.get_modpath("doc")
|
||||||
|
|
||||||
|
-- Christmas chest setup
|
||||||
|
local it_is_christmas = false
|
||||||
|
local date = os.date("*t")
|
||||||
|
if (
|
||||||
|
date.month == 12 and (
|
||||||
|
date.day == 24 or
|
||||||
|
date.day == 25 or
|
||||||
|
date.day == 26
|
||||||
|
)
|
||||||
|
) then
|
||||||
|
it_is_christmas = true
|
||||||
|
end
|
||||||
|
|
||||||
|
local tiles_chest_normal_small = {"mcl_chests_normal.png"}
|
||||||
|
local tiles_chest_normal_double = {"mcl_chests_normal_double.png"}
|
||||||
|
|
||||||
|
if it_is_christmas then
|
||||||
|
tiles_chest_normal_small = {"mcl_chests_normal_present.png^mcl_chests_noise.png"}
|
||||||
|
tiles_chest_normal_double = {"mcl_chests_normal_double_present.png^mcl_chests_noise_double.png"}
|
||||||
|
end
|
||||||
|
|
||||||
|
local tiles_chest_trapped_small = {"mcl_chests_trapped.png"}
|
||||||
|
local tiles_chest_trapped_double = {"mcl_chests_trapped_double.png"}
|
||||||
|
|
||||||
|
if it_is_christmas then
|
||||||
|
tiles_chest_trapped_small = {"mcl_chests_trapped_present.png^mcl_chests_noise.png"}
|
||||||
|
tiles_chest_trapped_double = {"mcl_chests_trapped_double_present.png^mcl_chests_noise_double.png"}
|
||||||
|
end
|
||||||
|
|
||||||
|
local tiles_chest_ender_small = {"mcl_chests_ender.png"}
|
||||||
|
|
||||||
|
if it_is_christmas then
|
||||||
|
tiles_chest_ender_small = {"mcl_chests_ender_present.png^mcl_chests_noise.png"}
|
||||||
|
end
|
||||||
|
|
||||||
-- Chest Entity
|
-- Chest Entity
|
||||||
local animate_chests = (minetest.settings:get_bool("animated_chests") ~= false)
|
local animate_chests = (minetest.settings:get_bool("animated_chests") ~= false)
|
||||||
local entity_animations = {
|
local entity_animations = {
|
||||||
|
@ -152,7 +187,10 @@ if minetest.get_modpath("screwdriver") then
|
||||||
local nodename = node.name
|
local nodename = node.name
|
||||||
local nodedef = minetest.registered_nodes[nodename]
|
local nodedef = minetest.registered_nodes[nodename]
|
||||||
local dir = minetest.facedir_to_dir(new_param2)
|
local dir = minetest.facedir_to_dir(new_param2)
|
||||||
find_or_create_entity(pos, nodename, nodedef._chest_entity_textures, new_param2, false, nodedef._chest_entity_sound, nodedef._chest_entity_mesh, nodedef._chest_entity_animation_type, dir):set_yaw(dir)
|
|
||||||
|
if animate_chests then
|
||||||
|
find_or_create_entity(pos, nodename, nodedef._chest_entity_textures, new_param2, false, nodedef._chest_entity_sound, nodedef._chest_entity_mesh, nodedef._chest_entity_animation_type, dir):set_yaw(dir)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
@ -181,6 +219,10 @@ local player_chest_open = function(player, pos, node_name, textures, param2, dou
|
||||||
local dir = minetest.facedir_to_dir(param2)
|
local dir = minetest.facedir_to_dir(param2)
|
||||||
local blocked = not shulker and (back_is_blocked(pos, dir) or double and back_is_blocked(mcl_util.get_double_container_neighbor_pos(pos, param2, node_name:sub(-4)), dir))
|
local blocked = not shulker and (back_is_blocked(pos, dir) or double and back_is_blocked(mcl_util.get_double_container_neighbor_pos(pos, param2, node_name:sub(-4)), dir))
|
||||||
find_or_create_entity(pos, node_name, textures, param2, double, sound, mesh, shulker and "shulker" or "chest", dir):open(name, blocked)
|
find_or_create_entity(pos, node_name, textures, param2, double, sound, mesh, shulker and "shulker" or "chest", dir):open(name, blocked)
|
||||||
|
else
|
||||||
|
minetest.sound_play(sound .. "_open", {
|
||||||
|
pos = pos,
|
||||||
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -212,11 +254,14 @@ local chest_update_after_close = function(pos)
|
||||||
|
|
||||||
if node.name == "mcl_chests:trapped_chest_on_small" then
|
if node.name == "mcl_chests:trapped_chest_on_small" then
|
||||||
minetest.swap_node(pos, {name="mcl_chests:trapped_chest_small", param2 = node.param2})
|
minetest.swap_node(pos, {name="mcl_chests:trapped_chest_small", param2 = node.param2})
|
||||||
find_or_create_entity(pos, "mcl_chests:trapped_chest_small", {"mcl_chests_trapped.png"}, node.param2, false, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_small")
|
|
||||||
|
if animate_chests then
|
||||||
|
find_or_create_entity(pos, "mcl_chests:trapped_chest_small", tiles_chest_trapped_small, node.param2, false, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_small")
|
||||||
|
end
|
||||||
mesecon.receptor_off(pos, trapped_chest_mesecons_rules)
|
mesecon.receptor_off(pos, trapped_chest_mesecons_rules)
|
||||||
elseif node.name == "mcl_chests:trapped_chest_on_left" then
|
elseif node.name == "mcl_chests:trapped_chest_on_left" then
|
||||||
minetest.swap_node(pos, {name="mcl_chests:trapped_chest_left", param2 = node.param2})
|
minetest.swap_node(pos, {name="mcl_chests:trapped_chest_left", param2 = node.param2})
|
||||||
find_or_create_entity(pos, "mcl_chests:trapped_chest_left", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left")
|
find_or_create_entity(pos, "mcl_chests:trapped_chest_left", tiles_chest_trapped_double, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left")
|
||||||
mesecon.receptor_off(pos, trapped_chest_mesecons_rules)
|
mesecon.receptor_off(pos, trapped_chest_mesecons_rules)
|
||||||
|
|
||||||
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left")
|
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left")
|
||||||
|
@ -228,7 +273,7 @@ local chest_update_after_close = function(pos)
|
||||||
|
|
||||||
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right")
|
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right")
|
||||||
minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_left", param2 = node.param2})
|
minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_left", param2 = node.param2})
|
||||||
find_or_create_entity(pos_other, "mcl_chests:trapped_chest_left", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left")
|
find_or_create_entity(pos_other, "mcl_chests:trapped_chest_left", tiles_chest_trapped_double, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left")
|
||||||
mesecon.receptor_off(pos_other, trapped_chest_mesecons_rules)
|
mesecon.receptor_off(pos_other, trapped_chest_mesecons_rules)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -242,6 +287,10 @@ local player_chest_close = function(player)
|
||||||
end
|
end
|
||||||
if animate_chests then
|
if animate_chests then
|
||||||
find_or_create_entity(open_chest.pos, open_chest.node_name, open_chest.textures, open_chest.param2, open_chest.double, open_chest.sound, open_chest.mesh, open_chest.shulker and "shulker" or "chest"):close(name)
|
find_or_create_entity(open_chest.pos, open_chest.node_name, open_chest.textures, open_chest.param2, open_chest.double, open_chest.sound, open_chest.mesh, open_chest.shulker and "shulker" or "chest"):close(name)
|
||||||
|
else
|
||||||
|
minetest.sound_play(open_chest.sound .. "_close", {
|
||||||
|
pos = open_chest.pos,
|
||||||
|
})
|
||||||
end
|
end
|
||||||
chest_update_after_close(open_chest.pos)
|
chest_update_after_close(open_chest.pos)
|
||||||
|
|
||||||
|
@ -380,12 +429,21 @@ minetest.register_node(small_name, {
|
||||||
_doc_items_longdesc = longdesc,
|
_doc_items_longdesc = longdesc,
|
||||||
_doc_items_usagehelp = usagehelp,
|
_doc_items_usagehelp = usagehelp,
|
||||||
_doc_items_hidden = hidden,
|
_doc_items_hidden = hidden,
|
||||||
drawtype = "nodebox",
|
drawtype = animate_chests and "nodebox" or "mesh",
|
||||||
node_box = {
|
mesh = not animate_chests and "mcl_chests_chest.obj" or nil,
|
||||||
|
node_box = animate_chests and {
|
||||||
type = "fixed",
|
type = "fixed",
|
||||||
fixed = {-0.4375, -0.5, -0.4375, 0.4375, 0.375, 0.4375},
|
fixed = {-0.4375, -0.5, -0.4375, 0.4375, 0.375, 0.4375},
|
||||||
|
} or nil,
|
||||||
|
collision_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {-0.4375, -0.5, -0.4375, 0.4375, 0.375, 0.4375},
|
||||||
},
|
},
|
||||||
tiles = {"mcl_chests_blank.png"},
|
selection_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {-0.4375, -0.5, -0.4375, 0.4375, 0.375, 0.4375},
|
||||||
|
},
|
||||||
|
tiles = animate_chests and {"mcl_chests_blank.png"} or small_textures,
|
||||||
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true,
|
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true,
|
||||||
_chest_entity_textures = small_textures,
|
_chest_entity_textures = small_textures,
|
||||||
_chest_entity_sound = "default_chest",
|
_chest_entity_sound = "default_chest",
|
||||||
|
@ -435,7 +493,10 @@ minetest.register_node(small_name, {
|
||||||
minetest.swap_node(p, { name = "mcl_chests:"..canonical_basename.."_right", param2 = param2 })
|
minetest.swap_node(p, { name = "mcl_chests:"..canonical_basename.."_right", param2 = param2 })
|
||||||
else
|
else
|
||||||
minetest.swap_node(pos, { name = "mcl_chests:"..canonical_basename.."_small", param2 = param2 })
|
minetest.swap_node(pos, { name = "mcl_chests:"..canonical_basename.."_small", param2 = param2 })
|
||||||
create_entity(pos, small_name, small_textures, param2, false, "default_chest", "mcl_chests_chest", "chest")
|
|
||||||
|
if animate_chests then
|
||||||
|
create_entity(pos, small_name, small_textures, param2, false, "default_chest", "mcl_chests_chest", "chest")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||||
|
@ -823,8 +884,8 @@ register_chest("chest",
|
||||||
chestusage,
|
chestusage,
|
||||||
S("27 inventory slots") .. "\n" .. S("Can be combined to a large chest"),
|
S("27 inventory slots") .. "\n" .. S("Can be combined to a large chest"),
|
||||||
{
|
{
|
||||||
small = {"mcl_chests_normal.png"},
|
small = tiles_chest_normal_small,
|
||||||
double = {"mcl_chests_normal_double.png"},
|
double = tiles_chest_normal_double,
|
||||||
inv = {"default_chest_top.png", "mcl_chests_chest_bottom.png",
|
inv = {"default_chest_top.png", "mcl_chests_chest_bottom.png",
|
||||||
"mcl_chests_chest_right.png", "mcl_chests_chest_left.png",
|
"mcl_chests_chest_right.png", "mcl_chests_chest_left.png",
|
||||||
"mcl_chests_chest_back.png", "default_chest_front.png"},
|
"mcl_chests_chest_back.png", "default_chest_front.png"},
|
||||||
|
@ -839,8 +900,8 @@ register_chest("chest",
|
||||||
)
|
)
|
||||||
|
|
||||||
local traptiles = {
|
local traptiles = {
|
||||||
small = {"mcl_chests_trapped.png"},
|
small = tiles_chest_trapped_small,
|
||||||
double = {"mcl_chests_trapped_double.png"},
|
double = tiles_chest_trapped_double,
|
||||||
inv = {"mcl_chests_chest_trapped_top.png", "mcl_chests_chest_trapped_bottom.png",
|
inv = {"mcl_chests_chest_trapped_top.png", "mcl_chests_chest_trapped_bottom.png",
|
||||||
"mcl_chests_chest_trapped_right.png", "mcl_chests_chest_trapped_left.png",
|
"mcl_chests_chest_trapped_right.png", "mcl_chests_chest_trapped_left.png",
|
||||||
"mcl_chests_chest_trapped_back.png", "mcl_chests_chest_trapped_front.png"},
|
"mcl_chests_chest_trapped_back.png", "mcl_chests_chest_trapped_front.png"},
|
||||||
|
@ -865,7 +926,9 @@ register_chest("trapped_chest",
|
||||||
}},
|
}},
|
||||||
function(pos, node, clicker)
|
function(pos, node, clicker)
|
||||||
minetest.swap_node(pos, {name="mcl_chests:trapped_chest_on_small", param2 = node.param2})
|
minetest.swap_node(pos, {name="mcl_chests:trapped_chest_on_small", param2 = node.param2})
|
||||||
find_or_create_entity(pos, "mcl_chests:trapped_chest_on_small", {"mcl_chests_trapped.png"}, node.param2, false, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_small")
|
if animate_chests then
|
||||||
|
find_or_create_entity(pos, "mcl_chests:trapped_chest_on_small", tiles_chest_trapped_small, node.param2, false, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_small")
|
||||||
|
end
|
||||||
mesecon.receptor_on(pos, trapped_chest_mesecons_rules)
|
mesecon.receptor_on(pos, trapped_chest_mesecons_rules)
|
||||||
end,
|
end,
|
||||||
function(pos, node, clicker)
|
function(pos, node, clicker)
|
||||||
|
@ -873,7 +936,7 @@ register_chest("trapped_chest",
|
||||||
meta:set_int("players", 1)
|
meta:set_int("players", 1)
|
||||||
|
|
||||||
minetest.swap_node(pos, {name="mcl_chests:trapped_chest_on_left", param2 = node.param2})
|
minetest.swap_node(pos, {name="mcl_chests:trapped_chest_on_left", param2 = node.param2})
|
||||||
find_or_create_entity(pos, "mcl_chests:trapped_chest_on_left", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_left")
|
find_or_create_entity(pos, "mcl_chests:trapped_chest_on_left", tiles_chest_trapped_double, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_left")
|
||||||
mesecon.receptor_on(pos, trapped_chest_mesecons_rules)
|
mesecon.receptor_on(pos, trapped_chest_mesecons_rules)
|
||||||
|
|
||||||
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left")
|
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left")
|
||||||
|
@ -887,7 +950,7 @@ register_chest("trapped_chest",
|
||||||
mesecon.receptor_on(pos, trapped_chest_mesecons_rules)
|
mesecon.receptor_on(pos, trapped_chest_mesecons_rules)
|
||||||
|
|
||||||
minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_on_left", param2 = node.param2})
|
minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_on_left", param2 = node.param2})
|
||||||
find_or_create_entity(pos_other, "mcl_chests:trapped_chest_on_left", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_left")
|
find_or_create_entity(pos_other, "mcl_chests:trapped_chest_on_left", tiles_chest_trapped_double, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_left")
|
||||||
mesecon.receptor_on(pos_other, trapped_chest_mesecons_rules)
|
mesecon.receptor_on(pos_other, trapped_chest_mesecons_rules)
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
@ -908,13 +971,15 @@ local function close_if_trapped_chest(pos, player)
|
||||||
|
|
||||||
if node.name == "mcl_chests:trapped_chest_on_small" then
|
if node.name == "mcl_chests:trapped_chest_on_small" then
|
||||||
minetest.swap_node(pos, {name="mcl_chests:trapped_chest_small", param2 = node.param2})
|
minetest.swap_node(pos, {name="mcl_chests:trapped_chest_small", param2 = node.param2})
|
||||||
find_or_create_entity(pos, "mcl_chests:trapped_chest_small", {"mcl_chests_trapped.png"}, node.param2, false, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_small")
|
if animate_chests then
|
||||||
|
find_or_create_entity(pos, "mcl_chests:trapped_chest_small", tiles_chest_trapped_small, node.param2, false, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_small")
|
||||||
|
end
|
||||||
mesecon.receptor_off(pos, trapped_chest_mesecons_rules)
|
mesecon.receptor_off(pos, trapped_chest_mesecons_rules)
|
||||||
|
|
||||||
player_chest_close(player)
|
player_chest_close(player)
|
||||||
elseif node.name == "mcl_chests:trapped_chest_on_left" then
|
elseif node.name == "mcl_chests:trapped_chest_on_left" then
|
||||||
minetest.swap_node(pos, {name="mcl_chests:trapped_chest_left", param2 = node.param2})
|
minetest.swap_node(pos, {name="mcl_chests:trapped_chest_left", param2 = node.param2})
|
||||||
find_or_create_entity(pos, "mcl_chests:trapped_chest_left", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left")
|
find_or_create_entity(pos, "mcl_chests:trapped_chest_left", tiles_chest_trapped_double, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left")
|
||||||
mesecon.receptor_off(pos, trapped_chest_mesecons_rules)
|
mesecon.receptor_off(pos, trapped_chest_mesecons_rules)
|
||||||
|
|
||||||
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left")
|
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left")
|
||||||
|
@ -928,7 +993,7 @@ local function close_if_trapped_chest(pos, player)
|
||||||
|
|
||||||
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right")
|
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right")
|
||||||
minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_left", param2 = node.param2})
|
minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_left", param2 = node.param2})
|
||||||
find_or_create_entity(pos_other, "mcl_chests:trapped_chest_left", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left")
|
find_or_create_entity(pos_other, "mcl_chests:trapped_chest_left", tiles_chest_trapped_double, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left")
|
||||||
mesecon.receptor_off(pos_other, trapped_chest_mesecons_rules)
|
mesecon.receptor_off(pos_other, trapped_chest_mesecons_rules)
|
||||||
|
|
||||||
player_chest_close(player)
|
player_chest_close(player)
|
||||||
|
@ -976,7 +1041,7 @@ minetest.register_node("mcl_chests:ender_chest", {
|
||||||
_doc_items_usagehelp = S("Rightclick the ender chest to access your personal interdimensional inventory."),
|
_doc_items_usagehelp = S("Rightclick the ender chest to access your personal interdimensional inventory."),
|
||||||
drawtype = "mesh",
|
drawtype = "mesh",
|
||||||
mesh = "mcl_chests_chest.obj",
|
mesh = "mcl_chests_chest.obj",
|
||||||
tiles = {"mcl_chests_ender.png"},
|
tiles = tiles_chest_ender_small,
|
||||||
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
|
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
paramtype2 = "facedir",
|
paramtype2 = "facedir",
|
||||||
|
@ -1015,16 +1080,25 @@ minetest.register_node("mcl_chests:ender_chest_small", {
|
||||||
_tt_help = S("27 interdimensional inventory slots") .. "\n" .. S("Put items inside, retrieve them from any ender chest"),
|
_tt_help = S("27 interdimensional inventory slots") .. "\n" .. S("Put items inside, retrieve them from any ender chest"),
|
||||||
_doc_items_longdesc = S("Ender chests grant you access to a single personal interdimensional inventory with 27 slots. This inventory is the same no matter from which ender chest you access it from. If you put one item into one ender chest, you will find it in all other ender chests. Each player will only see their own items, but not the items of other players."),
|
_doc_items_longdesc = S("Ender chests grant you access to a single personal interdimensional inventory with 27 slots. This inventory is the same no matter from which ender chest you access it from. If you put one item into one ender chest, you will find it in all other ender chests. Each player will only see their own items, but not the items of other players."),
|
||||||
_doc_items_usagehelp = S("Rightclick the ender chest to access your personal interdimensional inventory."),
|
_doc_items_usagehelp = S("Rightclick the ender chest to access your personal interdimensional inventory."),
|
||||||
drawtype = "nodebox",
|
drawtype = animate_chests and "nodebox" or "mesh",
|
||||||
node_box = {
|
mesh = not animate_chests and "mcl_chests_chest.obj" or nil,
|
||||||
|
node_box = animate_chests and {
|
||||||
type = "fixed",
|
type = "fixed",
|
||||||
fixed = {-0.4375, -0.5, -0.4375, 0.5, 0.375, 0.4375},
|
fixed = {-0.4375, -0.5, -0.4375, 0.4375, 0.375, 0.4375},
|
||||||
|
} or nil,
|
||||||
|
collision_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {-0.4375, -0.5, -0.4375, 0.4375, 0.375, 0.4375},
|
||||||
},
|
},
|
||||||
_chest_entity_textures = {"mcl_chests_ender.png"},
|
selection_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {-0.4375, -0.5, -0.4375, 0.4375, 0.375, 0.4375},
|
||||||
|
},
|
||||||
|
tiles = animate_chests and {"mcl_chests_blank.png"} or tiles_chest_ender_small,
|
||||||
|
_chest_entity_textures = tiles_chest_ender_small,
|
||||||
_chest_entity_sound = "mcl_chests_enderchest",
|
_chest_entity_sound = "mcl_chests_enderchest",
|
||||||
_chest_entity_mesh = "mcl_chests_chest",
|
_chest_entity_mesh = "mcl_chests_chest",
|
||||||
_chest_entity_animation_type = "chest",
|
_chest_entity_animation_type = "chest",
|
||||||
tiles = {"mcl_chests_blank.png"},
|
|
||||||
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true,
|
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true,
|
||||||
--[[{"mcl_chests_ender_chest_top.png", "mcl_chests_ender_chest_bottom.png",
|
--[[{"mcl_chests_ender_chest_top.png", "mcl_chests_ender_chest_bottom.png",
|
||||||
"mcl_chests_ender_chest_right.png", "mcl_chests_ender_chest_left.png",
|
"mcl_chests_ender_chest_right.png", "mcl_chests_ender_chest_left.png",
|
||||||
|
@ -1041,10 +1115,13 @@ minetest.register_node("mcl_chests:ender_chest_small", {
|
||||||
on_construct = function(pos)
|
on_construct = function(pos)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
meta:set_string("formspec", formspec_ender_chest)
|
meta:set_string("formspec", formspec_ender_chest)
|
||||||
create_entity(pos, "mcl_chests:ender_chest_small", {"mcl_chests_ender.png"}, minetest.get_node(pos).param2, false, "mcl_chests_enderchest", "mcl_chests_chest", "chest")
|
|
||||||
|
if animate_chests then
|
||||||
|
create_entity(pos, "mcl_chests:ender_chest_small", tiles_chest_ender_small, minetest.get_node(pos).param2, false, "mcl_chests_enderchest", "mcl_chests_chest", "chest")
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
on_rightclick = function(pos, node, clicker)
|
on_rightclick = function(pos, node, clicker)
|
||||||
player_chest_open(clicker, pos, "mcl_chests:ender_chest_small", {"mcl_chests_ender.png"}, node.param2, false, "mcl_chests_enderchest", "mcl_chests_chest")
|
player_chest_open(clicker, pos, "mcl_chests:ender_chest_small", tiles_chest_ender_small, node.param2, false, "mcl_chests_enderchest", "mcl_chests_chest")
|
||||||
end,
|
end,
|
||||||
on_receive_fields = function(pos, formname, fields, sender)
|
on_receive_fields = function(pos, formname, fields, sender)
|
||||||
if fields.quit then
|
if fields.quit then
|
||||||
|
@ -1062,6 +1139,20 @@ minetest.register_on_joinplayer(function(player)
|
||||||
inv:set_size("enderchest", 9*3)
|
inv:set_size("enderchest", 9*3)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
minetest.register_allow_player_inventory_action(function(player, action, inv, info)
|
||||||
|
if inv:get_location().type == "player" and (
|
||||||
|
action == "move" and (info.from_list == "enderchest" or info.to_list == "enderchest")
|
||||||
|
or action == "put" and info.listname == "enderchest"
|
||||||
|
or action == "take" and info.listname == "enderchest"
|
||||||
|
) then
|
||||||
|
local def = player:get_wielded_item():get_definition()
|
||||||
|
|
||||||
|
if not minetest.find_node_near(player:get_pos(), def and def.range or ItemStack():get_definition().range, "mcl_chests:ender_chest_small", true) then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
output = 'mcl_chests:ender_chest',
|
output = 'mcl_chests:ender_chest',
|
||||||
recipe = {
|
recipe = {
|
||||||
|
@ -1222,8 +1313,9 @@ for color, desc in pairs(boxtypes) do
|
||||||
_doc_items_entry_name = entry_name,
|
_doc_items_entry_name = entry_name,
|
||||||
_doc_items_longdesc = longdesc,
|
_doc_items_longdesc = longdesc,
|
||||||
_doc_items_usagehelp = usagehelp,
|
_doc_items_usagehelp = usagehelp,
|
||||||
drawtype = "nodebox",
|
drawtype = animate_chests and "nodebox" or "mesh",
|
||||||
tiles = {"mcl_chests_blank.png"},
|
mesh = not animate_chests and "mcl_chests_shulker.obj" or nil,
|
||||||
|
tiles = animate_chests and {"mcl_chests_blank.png"} or {mob_texture},
|
||||||
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true,
|
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true,
|
||||||
_chest_entity_textures = {mob_texture},
|
_chest_entity_textures = {mob_texture},
|
||||||
_chest_entity_sound = "mcl_chests_shulker",
|
_chest_entity_sound = "mcl_chests_shulker",
|
||||||
|
@ -1244,7 +1336,10 @@ for color, desc in pairs(boxtypes) do
|
||||||
meta:set_string("formspec", formspec_shulker_box(nil))
|
meta:set_string("formspec", formspec_shulker_box(nil))
|
||||||
local inv = meta:get_inventory()
|
local inv = meta:get_inventory()
|
||||||
inv:set_size("main", 9*3)
|
inv:set_size("main", 9*3)
|
||||||
create_entity(pos, small_name, {mob_texture}, minetest.get_node(pos).param2, false, "mcl_chests_shulker", "mcl_chests_shulker", "shulker")
|
|
||||||
|
if animate_chests then
|
||||||
|
create_entity(pos, small_name, {mob_texture}, minetest.get_node(pos).param2, false, "mcl_chests_shulker", "mcl_chests_shulker", "shulker")
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||||
local nmeta = minetest.get_meta(pos)
|
local nmeta = minetest.get_meta(pos)
|
||||||
|
@ -1363,6 +1458,11 @@ local function select_and_spawn_entity(pos, node)
|
||||||
local node_name = node.name
|
local node_name = node.name
|
||||||
local node_def = minetest.registered_nodes[node_name]
|
local node_def = minetest.registered_nodes[node_name]
|
||||||
local double_chest = minetest.get_item_group(node_name, "double_chest") > 0
|
local double_chest = minetest.get_item_group(node_name, "double_chest") > 0
|
||||||
|
|
||||||
|
if not animate_chests and not double_chest then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
find_or_create_entity(pos, node_name, node_def._chest_entity_textures, node.param2, double_chest, node_def._chest_entity_sound, node_def._chest_entity_mesh, node_def._chest_entity_animation_type)
|
find_or_create_entity(pos, node_name, node_def._chest_entity_textures, node.param2, double_chest, node_def._chest_entity_sound, node_def._chest_entity_mesh, node_def._chest_entity_animation_type)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
After Width: | Height: | Size: 286 B |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 9.1 KiB |
After Width: | Height: | Size: 307 B |
After Width: | Height: | Size: 285 B |
After Width: | Height: | Size: 307 B |
After Width: | Height: | Size: 286 B |
|
@ -388,12 +388,11 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s
|
||||||
{ x=0, y=0, z=-1 },
|
{ x=0, y=0, z=-1 },
|
||||||
{ x=0, y=0, z=1 },
|
{ x=0, y=0, z=1 },
|
||||||
}
|
}
|
||||||
local floorpos, floor
|
|
||||||
for n=#neighbors, 1, -1 do
|
for n=#neighbors, 1, -1 do
|
||||||
local offset = neighbors[n]
|
local offset = neighbors[n]
|
||||||
local blockpos = vector.add(stempos, offset)
|
local blockpos = vector.add(stempos, offset)
|
||||||
floorpos = { x=blockpos.x, y=blockpos.y-1, z=blockpos.z }
|
local floorpos = { x=blockpos.x, y=blockpos.y-1, z=blockpos.z }
|
||||||
floor = minetest.get_node(floorpos)
|
local floor = minetest.get_node(floorpos)
|
||||||
local block = minetest.get_node(blockpos)
|
local block = minetest.get_node(blockpos)
|
||||||
local soilgroup = minetest.get_item_group(floor.name, "soil")
|
local soilgroup = minetest.get_item_group(floor.name, "soil")
|
||||||
if not ((minetest.get_item_group(floor.name, "grass_block") == 1 or floor.name=="mcl_core:dirt" or soilgroup == 2 or soilgroup == 3) and block.name == "air") then
|
if not ((minetest.get_item_group(floor.name, "grass_block") == 1 or floor.name=="mcl_core:dirt" or soilgroup == 2 or soilgroup == 3) and block.name == "air") then
|
||||||
|
@ -407,6 +406,8 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s
|
||||||
local r = math.random(1, #neighbors)
|
local r = math.random(1, #neighbors)
|
||||||
local offset = neighbors[r]
|
local offset = neighbors[r]
|
||||||
local blockpos = vector.add(stempos, offset)
|
local blockpos = vector.add(stempos, offset)
|
||||||
|
local floorpos = { x=blockpos.x, y=blockpos.y-1, z=blockpos.z }
|
||||||
|
local floor = minetest.get_node(floorpos)
|
||||||
local p2
|
local p2
|
||||||
if offset.x == 1 then
|
if offset.x == 1 then
|
||||||
minetest.set_node(stempos, {name=connected_stem_names[1]})
|
minetest.set_node(stempos, {name=connected_stem_names[1]})
|
||||||
|
|
|
@ -1,196 +0,0 @@
|
||||||
local S = minetest.get_translator("mcl_anti_dimension_hopping")
|
|
||||||
|
|
||||||
local storage = minetest.get_mod_storage()
|
|
||||||
|
|
||||||
local MAX_DISTANCE = 40
|
|
||||||
|
|
||||||
local dimension_change_is_legal = function(
|
|
||||||
player_name, -- string
|
|
||||||
dimension, -- "end"|"nether"|"overworld"|"void"
|
|
||||||
last_dimension, -- "end"|"nether"|"overworld"|"void"
|
|
||||||
last_last_dimension -- "end"|"nether"|"overworld"|"void"|nil
|
|
||||||
)
|
|
||||||
local player = minetest.get_player_by_name(player_name)
|
|
||||||
if nil == player then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
local player_position = player:get_pos()
|
|
||||||
if "end" == dimension then
|
|
||||||
assert( player_position.y > mcl_vars.mg_end_min )
|
|
||||||
assert( player_position.y < mcl_vars.mg_end_max )
|
|
||||||
-- Going to the End through a portal is allowed, but a
|
|
||||||
-- player must appear at End spawn for it to be legal.
|
|
||||||
-- The Nether as the last dimension is included here
|
|
||||||
-- because an End portal in the nether sends players
|
|
||||||
-- to End spawn, but cheaters can not teleport down
|
|
||||||
-- from the Nether, as the Nether is below the End.
|
|
||||||
if (
|
|
||||||
"overworld" == last_dimension or
|
|
||||||
"nether" == last_dimension
|
|
||||||
) then
|
|
||||||
if vector.distance(
|
|
||||||
player_position,
|
|
||||||
mcl_vars.mg_end_platform_pos
|
|
||||||
) < MAX_DISTANCE then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Going to the End via the Void is allowed only if
|
|
||||||
-- the player entered the Void from the End … nil has
|
|
||||||
-- to be handled here for players who were in the Void
|
|
||||||
-- when this mod was activated.
|
|
||||||
if "void" == last_dimension then
|
|
||||||
if (
|
|
||||||
"end" == last_last_dimension or
|
|
||||||
nil == last_last_dimension
|
|
||||||
) then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if "nether" == dimension then
|
|
||||||
assert( player_position.y > mcl_vars.mg_nether_min )
|
|
||||||
assert( player_position.y < mcl_vars.mg_nether_max )
|
|
||||||
-- Going to the Nether through a portal is allowed.
|
|
||||||
if "overworld" == last_dimension then
|
|
||||||
if nil ~= minetest.find_node_near(
|
|
||||||
player_position,
|
|
||||||
MAX_DISTANCE,
|
|
||||||
"mcl_portals:portal"
|
|
||||||
) then
|
|
||||||
-- TODO: check for portal in Overworld
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Going to the Nether via the Void is allowed only if
|
|
||||||
-- the player entered the Void from the Nether … nil
|
|
||||||
-- has to be handled here for players who were in the
|
|
||||||
-- Void when this mod was activated.
|
|
||||||
if "void" == last_dimension then
|
|
||||||
if (
|
|
||||||
"nether" == last_last_dimension or
|
|
||||||
nil == last_last_dimension
|
|
||||||
) then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if "overworld" == dimension then
|
|
||||||
assert( player_position.y > mcl_vars.mg_overworld_min )
|
|
||||||
assert( player_position.y < mcl_vars.mg_overworld_max )
|
|
||||||
-- Going to the Overworld from the Nether through a
|
|
||||||
-- portal is allowed.
|
|
||||||
if "nether" == last_dimension then
|
|
||||||
if nil ~= minetest.find_node_near(
|
|
||||||
player_position,
|
|
||||||
MAX_DISTANCE,
|
|
||||||
"mcl_portals:portal"
|
|
||||||
) then
|
|
||||||
-- TODO: check for portal in Nether
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
-- Going to the Overworld via the Void is allowed only
|
|
||||||
-- if the player entered the Void from the Overworld …
|
|
||||||
-- nil has to be handled here for players who were in
|
|
||||||
-- the Void when this mod was activated.
|
|
||||||
if "void" == last_dimension then
|
|
||||||
if (
|
|
||||||
"overworld" == last_last_dimension or
|
|
||||||
nil == last_last_dimension
|
|
||||||
) then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Going to the Overworld via the End (or any other
|
|
||||||
-- way) is allowed only if the player appears at their
|
|
||||||
-- respawn location, either because they used a portal
|
|
||||||
-- in the End or because they died.
|
|
||||||
local player_spawn_position = (
|
|
||||||
mcl_spawn.get_player_spawn_pos(player) or
|
|
||||||
mcl_spawn.get_world_spawn_pos(player)
|
|
||||||
)
|
|
||||||
if vector.distance(
|
|
||||||
player_position,
|
|
||||||
player_spawn_position
|
|
||||||
) < MAX_DISTANCE then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if "void" == dimension then
|
|
||||||
-- Going to the Void is always legal – a player who
|
|
||||||
-- enters the Void and then goes anywhere else than
|
|
||||||
-- where they came from is already handled above.
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
local kill_player_for_dimensional_trespassing = function(
|
|
||||||
player_name,
|
|
||||||
dimension,
|
|
||||||
last_dimension,
|
|
||||||
last_last_dimension
|
|
||||||
)
|
|
||||||
local player = minetest.get_player_by_name(player_name)
|
|
||||||
if nil == player then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
-- If the player holds a totem of undying, destroy it before
|
|
||||||
-- killing, so it doesn't rescue the player.
|
|
||||||
local wield = player:get_wielded_item()
|
|
||||||
if wield:get_name() == "mobs_mc:totem" then
|
|
||||||
player:set_wielded_item("")
|
|
||||||
end
|
|
||||||
local death_message = S(
|
|
||||||
"@1 was executed for dimensional trespassing.",
|
|
||||||
player_name
|
|
||||||
)
|
|
||||||
mcl_death_messages.player_damage(
|
|
||||||
player,
|
|
||||||
death_message
|
|
||||||
)
|
|
||||||
player:set_hp(0)
|
|
||||||
local log_message = string.format(
|
|
||||||
"%s was executed for dimensional trespassing: %s → %s → %s",
|
|
||||||
tostring(player_name),
|
|
||||||
tostring(last_last_dimension),
|
|
||||||
tostring(last_dimension),
|
|
||||||
tostring(dimension)
|
|
||||||
)
|
|
||||||
minetest.log(
|
|
||||||
"action",
|
|
||||||
log_message
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
mcl_worlds.register_on_dimension_change(
|
|
||||||
function(player, dimension, last_dimension)
|
|
||||||
local player_name = player:get_player_name()
|
|
||||||
local last_last_dimension = storage:get_string(
|
|
||||||
player_name .. ":dimension_previous_previous"
|
|
||||||
)
|
|
||||||
if not dimension_change_is_legal(
|
|
||||||
player_name,
|
|
||||||
dimension,
|
|
||||||
last_dimension,
|
|
||||||
last_last_dimension
|
|
||||||
) then
|
|
||||||
kill_player_for_dimensional_trespassing(
|
|
||||||
player_name,
|
|
||||||
dimension,
|
|
||||||
last_dimension,
|
|
||||||
last_last_dimension
|
|
||||||
)
|
|
||||||
end
|
|
||||||
storage:set_string(
|
|
||||||
player_name .. ":dimension_previous_previous",
|
|
||||||
last_dimension
|
|
||||||
)
|
|
||||||
storage:set_string(
|
|
||||||
player_name .. ":dimension_previous",
|
|
||||||
dimension
|
|
||||||
)
|
|
||||||
end
|
|
||||||
)
|
|
|
@ -1,2 +0,0 @@
|
||||||
name = mcl_anti_dimension_hopping
|
|
||||||
depends = mcl_init, mcl_death_messages, mcl_portals, mcl_spawn, mcl_worlds
|
|
|
@ -75,14 +75,22 @@ local test_minetest_find_nodes_in_area_can_count = function(dtime)
|
||||||
local nodes_expected = math.pow( 1 + (2 * radius), 3 )
|
local nodes_expected = math.pow( 1 + (2 * radius), 3 )
|
||||||
local nodes_counted = nnum[nodename]
|
local nodes_counted = nnum[nodename]
|
||||||
local nodes_difference = nodes_expected - nodes_counted
|
local nodes_difference = nodes_expected - nodes_counted
|
||||||
-- Yes, the following line is supposed to crash the game in
|
-- Originally, there was an assertion here that made the game
|
||||||
-- the case that Minetest forgot how to count the number of
|
-- crash at startup if Minetest forgot how to count. This was
|
||||||
-- nodes in a three dimensional volume it just filled. This
|
-- originally intended to avoid buggy engine releases, but it
|
||||||
-- function contains an excellent explanation on what not to
|
-- mostly made people upset and hindered debugging. Also, the
|
||||||
-- do further up. I strongly suggest to pester Minetest core
|
-- assertion contained no error message hinting at the reason
|
||||||
-- devs about this issue and not the author of the function,
|
-- for the crash, making it exceptionally user-unfriendly. It
|
||||||
-- should this test ever fail.
|
-- follows that a game or mod should only assert on behaviour
|
||||||
assert ( 0 == nodes_difference )
|
-- of the Lua code, not the underlying implementation, unless
|
||||||
|
-- engine bugs are bad enough to permanently corrupt a world.
|
||||||
|
if ( 0 ~= nodes_difference ) then
|
||||||
|
minetest.debug(
|
||||||
|
"minetest.find_nodes_in_area() failed to find " ..
|
||||||
|
nodes_difference .. " nodes that were placed. " ..
|
||||||
|
"Downgrading to Minetest 5.4.1 might fix this."
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.after( 0, test_minetest_find_nodes_in_area_can_count )
|
minetest.after( 0, test_minetest_find_nodes_in_area_can_count )
|
||||||
|
|
|
@ -19,8 +19,114 @@ end
|
||||||
|
|
||||||
local pitch, name, node_stand, node_stand_below, node_head, node_feet, pos
|
local pitch, name, node_stand, node_stand_below, node_head, node_feet, pos
|
||||||
|
|
||||||
minetest.register_globalstep(function(dtime)
|
local function roundN(n, d)
|
||||||
|
if type(n) ~= "number" then return n end
|
||||||
|
local m = 10^d
|
||||||
|
return math.floor(n * m + 0.5) / m
|
||||||
|
end
|
||||||
|
|
||||||
|
local function close_enough(a,b)
|
||||||
|
local rt=true
|
||||||
|
if type(a) == "table" and type(b) == "table" then
|
||||||
|
for k,v in pairs(a) do
|
||||||
|
if roundN(v,2) ~= roundN(b[k],2) then
|
||||||
|
rt=false
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
rt = roundN(a,2) == roundN(b,2)
|
||||||
|
end
|
||||||
|
return rt
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function props_changed(props,oldprops)
|
||||||
|
local changed=false
|
||||||
|
local p={}
|
||||||
|
for k,v in pairs(props) do
|
||||||
|
if not close_enough(v,oldprops[k]) then
|
||||||
|
p[k]=v
|
||||||
|
changed=true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return changed,p
|
||||||
|
end
|
||||||
|
|
||||||
|
--test if assert works
|
||||||
|
assert(true)
|
||||||
|
assert(not false)
|
||||||
|
|
||||||
|
--test data for == and ~=
|
||||||
|
local test_equal1=42
|
||||||
|
local test_equal2=42.0
|
||||||
|
local test_equal3=42.1
|
||||||
|
|
||||||
|
assert(test_equal1==test_equal1)
|
||||||
|
assert(test_equal1==test_equal2)
|
||||||
|
assert(test_equal1~=test_equal3)
|
||||||
|
|
||||||
|
--testdata for roundN
|
||||||
|
local test_round1=15
|
||||||
|
local test_round2=15.00199999999
|
||||||
|
local test_round3=15.00111111
|
||||||
|
local test_round4=15.00999999
|
||||||
|
|
||||||
|
assert(roundN(test_round1,2)==roundN(test_round1,2)) --test again if basic equality works because wth not
|
||||||
|
assert(roundN(test_round1,2)==roundN(test_round2,2))
|
||||||
|
assert(roundN(test_round1,2)==roundN(test_round3,2))
|
||||||
|
assert(roundN(test_round1,2)~=roundN(test_round4,2))
|
||||||
|
|
||||||
|
|
||||||
|
-- tests for close_enough
|
||||||
|
local test_cb = {-0.35,0,-0.35,0.35,0.8,0.35} --collisionboxes
|
||||||
|
local test_cb_close = {-0.351213,0,-0.35,0.35,0.8,0.351212}
|
||||||
|
local test_cb_diff = {-0.35,0,-1.35,0.35,0.8,0.35}
|
||||||
|
|
||||||
|
local test_eh = 1.65 --eye height
|
||||||
|
local test_eh_close = 1.65123123
|
||||||
|
local test_eh_diff = 1.35
|
||||||
|
|
||||||
|
local test_nt = { r = 225, b = 225, a = 225, g = 225 } --nametag
|
||||||
|
local test_nt_diff = { r = 225, b = 225, a = 0, g = 225 }
|
||||||
|
|
||||||
|
assert(close_enough(test_cb,test_cb_close))
|
||||||
|
assert(not close_enough(test_cb,test_cb_diff))
|
||||||
|
|
||||||
|
assert(close_enough(test_eh,test_eh_close))
|
||||||
|
assert(not close_enough(test_eh,test_eh_diff))
|
||||||
|
|
||||||
|
assert(not close_enough(test_nt,test_nt_diff)) --no floats involved here
|
||||||
|
|
||||||
|
--tests for props_changed
|
||||||
|
local test_properties_set1={collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 0.65, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}
|
||||||
|
local test_properties_set2={collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 1.35, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}
|
||||||
|
|
||||||
|
local test_p1,p=props_changed(test_properties_set1,test_properties_set1)
|
||||||
|
local test_p2,p=props_changed(test_properties_set1,test_properties_set2)
|
||||||
|
|
||||||
|
assert(not test_p1)
|
||||||
|
assert(test_p2)
|
||||||
|
|
||||||
|
-- we still don't really know if lua is lying to us! but at least everything *seems* to be ok
|
||||||
|
|
||||||
|
local function set_properties_conditional(player,props)
|
||||||
|
local changed,p=props_changed(props,player:get_properties())
|
||||||
|
if changed then
|
||||||
|
player:set_properties(p)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function set_bone_position_conditional(player,b,p,r) --bone,position,rotation
|
||||||
|
local oldp,oldr=player:get_bone_position(b)
|
||||||
|
if vector.equals(vector.round(oldp),vector.round(p)) and vector.equals(vector.round(oldr),vector.round(r)) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
player:set_bone_position(b,p,r)
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_globalstep(function(dtime)
|
||||||
time = time + dtime
|
time = time + dtime
|
||||||
|
|
||||||
-- Update jump status immediately since we need this info in real time.
|
-- Update jump status immediately since we need this info in real time.
|
||||||
|
@ -45,55 +151,55 @@ minetest.register_globalstep(function(dtime)
|
||||||
|
|
||||||
-- controls right and left arms pitch when shooting a bow or punching
|
-- controls right and left arms pitch when shooting a bow or punching
|
||||||
if string.find(player:get_wielded_item():get_name(), "mcl_bows:bow") and controls.RMB and not controls.LMB and not controls.up and not controls.down and not controls.left and not controls.right then
|
if string.find(player:get_wielded_item():get_name(), "mcl_bows:bow") and controls.RMB and not controls.LMB and not controls.up and not controls.down and not controls.left and not controls.right then
|
||||||
player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35))
|
set_bone_position_conditional(player,"Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35))
|
||||||
player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3.5,5.785,0), vector.new(pitch+90,43,pitch * .35))
|
set_bone_position_conditional(player,"Arm_Left_Pitch_Control", vector.new(3.5,5.785,0), vector.new(pitch+90,43,pitch * .35))
|
||||||
elseif controls.LMB and player:get_attach() == nil then
|
elseif controls.LMB and player:get_attach() == nil then
|
||||||
player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch,0,0))
|
set_bone_position_conditional(player,"Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch,0,0))
|
||||||
player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(0,0,0))
|
set_bone_position_conditional(player,"Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(0,0,0))
|
||||||
else
|
else
|
||||||
player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(0,0,0))
|
set_bone_position_conditional(player,"Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(0,0,0))
|
||||||
player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(0,0,0))
|
set_bone_position_conditional(player,"Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(0,0,0))
|
||||||
end
|
end
|
||||||
|
|
||||||
if controls.sneak and player:get_attach() == nil then
|
if controls.sneak and player:get_attach() == nil then
|
||||||
-- controls head pitch when sneaking
|
-- controls head pitch when sneaking
|
||||||
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+36,0,0))
|
set_bone_position_conditional(player,"Head", vector.new(0,6.3,0), vector.new(pitch+36,0,0))
|
||||||
-- sets eye height, and nametag color accordingly
|
-- sets eye height, and nametag color accordingly
|
||||||
player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.35, nametag_color = { r = 225, b = 225, a = 0, g = 225 }})
|
set_properties_conditional(player,{collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.35, nametag_color = { r = 225, b = 225, a = 0, g = 225 }})
|
||||||
-- sneaking body conrols
|
-- sneaking body conrols
|
||||||
player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0))
|
set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), vector.new(0,0,0))
|
||||||
elseif minetest.get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 and player:get_attach() == nil and mcl_sprint.is_sprinting(name) == true then
|
elseif minetest.get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 and player:get_attach() == nil and mcl_sprint.is_sprinting(name) == true then
|
||||||
-- set head pitch and yaw when swimming
|
-- set head pitch and yaw when swimming
|
||||||
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+90-degrees(dir_to_pitch(player_velocity)),yaw - player_vel_yaw * -1,0))
|
set_bone_position_conditional(player,"Head", vector.new(0,6.3,0), vector.new(pitch+90-degrees(dir_to_pitch(player_velocity)),yaw - player_vel_yaw * -1,0))
|
||||||
-- sets eye height, and nametag color accordingly
|
-- sets eye height, and nametag color accordingly
|
||||||
player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 0.65, nametag_color = { r = 225, b = 225, a = 225, g = 225 }})
|
set_properties_conditional(player,{collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 0.65, nametag_color = { r = 225, b = 225, a = 225, g = 225 }})
|
||||||
-- control body bone when swimming
|
-- control body bone when swimming
|
||||||
player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(degrees(dir_to_pitch(player_velocity)) - 90,player_vel_yaw * -1 - yaw + 180,0))
|
set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), vector.new(degrees(dir_to_pitch(player_velocity)) - 90,player_vel_yaw * -1 - yaw + 180,0))
|
||||||
|
|
||||||
elseif player:get_attach() == nil then
|
elseif player:get_attach() == nil then
|
||||||
-- sets eye height, and nametag color accordingly
|
-- sets eye height, and nametag color accordingly
|
||||||
player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.65, nametag_color = { r = 225, b = 225, a = 225, g = 225 }})
|
set_properties_conditional(player,{collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.65, nametag_color = { r = 225, b = 225, a = 225, g = 225 }})
|
||||||
|
|
||||||
if player_velocity.x > 0.35 or player_velocity.z > 0.35 or player_velocity.x < -0.35 or player_velocity.z < -0.35 then
|
if player_velocity.x > 0.35 or player_velocity.z > 0.35 or player_velocity.x < -0.35 or player_velocity.z < -0.35 then
|
||||||
if player_vel_yaw * -1 - yaw < 90 or player_vel_yaw * -1 - yaw > 270 then
|
if player_vel_yaw * -1 - yaw < 90 or player_vel_yaw * -1 - yaw > 270 then
|
||||||
-- controls head and Body_Control bones while moving backwards
|
-- controls head and Body_Control bones while moving backwards
|
||||||
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch,yaw - player_vel_yaw * -1,0))
|
set_bone_position_conditional(player,"Head", vector.new(0,6.3,0), vector.new(pitch,yaw - player_vel_yaw * -1,0))
|
||||||
player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,player_vel_yaw * -1 - yaw,0))
|
set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), vector.new(0,player_vel_yaw * -1 - yaw,0))
|
||||||
else
|
else
|
||||||
-- controls head and Body_Control bones while moving forwards
|
-- controls head and Body_Control bones while moving forwards
|
||||||
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch,yaw - player_vel_yaw * -1 + 180,0))
|
set_bone_position_conditional(player,"Head", vector.new(0,6.3,0), vector.new(pitch,yaw - player_vel_yaw * -1 + 180,0))
|
||||||
player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,player_vel_yaw * -1 - yaw + 180,0))
|
set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), vector.new(0,player_vel_yaw * -1 - yaw + 180,0))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch,0,0))
|
set_bone_position_conditional(player,"Head", vector.new(0,6.3,0), vector.new(pitch,0,0))
|
||||||
player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0))
|
set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), vector.new(0,0,0))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local attached = player:get_attach(parent)
|
local attached = player:get_attach(parent)
|
||||||
local attached_yaw = degrees(attached:get_yaw())
|
local attached_yaw = degrees(attached:get_yaw())
|
||||||
player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.65, nametag_color = { r = 225, b = 225, a = 225, g = 225 }})
|
set_properties_conditional(player,{collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.65, nametag_color = { r = 225, b = 225, a = 225, g = 225 }})
|
||||||
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch,degrees(player:get_look_horizontal()) * -1 + attached_yaw,0))
|
set_bone_position_conditional(player,"Head", vector.new(0,6.3,0), vector.new(pitch,degrees(player:get_look_horizontal()) * -1 + attached_yaw,0))
|
||||||
player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0))
|
set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), vector.new(0,0,0))
|
||||||
end
|
end
|
||||||
|
|
||||||
if mcl_playerplus_internal[name].jump_cooldown > 0 then
|
if mcl_playerplus_internal[name].jump_cooldown > 0 then
|
||||||
|
|