1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
ch_core.open_submod("nodedir", {lib = true})
ch_core.registered_nodedir_groups = {}
local node_to_info = {}
function ch_core.register_nodedir_group(def)
local to_add = {}
local new_group = {}
for i = 0, 23 do
local nodename = def[i]
if type(nodename) == "string" then
if node_to_info[nodename] ~= nil then
error(nodename.." is already registered in a different nodedir group!")
elseif to_add[nodename] == nil then
to_add[nodename] = {facedir = i, group = new_group}
end
new_group[i] = nodename
elseif nodename ~= nil then
error("Invalid nodename type: "..type(nodename))
elseif i == 0 then
error("Nodedir name [0] is required!")
end
end
assert(type(new_group[0]) == "string")
for k, v in pairs(to_add) do
node_to_info[k] = v
end
table.insert(ch_core.registered_nodedir_groups, new_group)
return true
end
local facedir_table = {}
for i = 0, 23 do
facedir_table[i] = true
end
local function assert_is_facedir(facedir)
if type(facedir) == "number" and facedir_table[facedir] then
return facedir
else
error("Invalid facedir value: "..dump2({type = type(facedir), value = facedir}))
end
end
--[[
Pokud je zadaný blok registrován, vrátí jeho otočení typu facedir, jinak vrací nil.
]]
function ch_core.get_nodedir(nodename)
local info = node_to_info[assert(nodename)]
if info ~= nil then
return info.facedir
else
return nil
end
end
--[[
Pokud je zadaný blok registrován a podporuje cílové otočení, vrátí název odpovídajícího cílového bloku.
Jinak vrací nil.
]]
function ch_core.get_nodedir_nodename(current_nodename, new_facedir)
local info = node_to_info[assert(current_nodename)]
if info ~= nil then
return info ~= nil and info.group[assert_is_facedir(new_facedir)]
else
return nil
end
end
--[[
Pokud je zadaný blok registrován, nastaví v množině 'set' klíče odpovídající
zadanému bloku a jeho ostatním otočením na true.
'set' může být nil, v takovém případě jen vrátí návratovou hodnotu, zda je blok registrován.
Vrací true, pokud je zadaný blok registrován, jinak false.
]]
function ch_core.fill_nodedir_equals_set(set, nodename)
local info = node_to_info[assert(nodename)]
if info == nil then return false end
if set ~= nil then
local group, n = info.group
for i = 0, 23 do
n = group[i]
if n ~= nil then
set[n] = true
end
end
end
return true
end
-- override screwdriver handler:
local old_screwdriver_handler = assert(screwdriver.handler)
function screwdriver.handler(itemstack, user, pointed_thing, mode, uses)
if pointed_thing.type ~= "node" then return end
local node = minetest.get_node(pointed_thing.under)
local nodedir_facedir = ch_core.get_nodedir(node.name)
if nodedir_facedir == nil then
-- call a normal handler
return old_screwdriver_handler(itemstack, user, pointed_thing, mode, uses)
end
local pos = pointed_thing.under
local player_name = (user and user:get_player_name()) or ""
if minetest.is_protected(pos, player_name) then
minetest.record_protection_violation(pos, player_name)
return
end
local new_facedir
if mode == screwdriver.ROTATE_FACE then
new_facedir = bit.band(nodedir_facedir, 0x1C) + bit.band(nodedir_facedir + 1, 0x03)
elseif mode == screwdriver.ROTATE_AXIS then
new_facedir = (nodedir_facedir + 4) % 24
else
return -- unknown mode
end
local new_node_name = ch_core.get_nodedir_nodename(node.name, new_facedir)
if new_node_name == nil then
return -- orientation not supported by the node
end
if new_node_name ~= node.name then
local old_node = table.copy(node)
node.name = new_node_name
minetest.swap_node(pos, node)
minetest.check_for_falling(pos)
local old_node_def = core.registered_nodes[old_node.name]
if old_node_def ~= nil and old_node_def.after_nodedir_rotate ~= nil then
old_node_def.after_nodedir_rotate(pos, old_node, node, itemstack, user)
end
end
if not minetest.is_creative_enabled(player_name) then
itemstack:add_wear_by_uses(uses or 200)
end
return itemstack
end
ch_core.close_submod("nodedir")
|