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
|
ch_core.open_submod("interiors", {})
local normal = 0
local passable = 1
local evadable = 2
minetest.register_on_mods_loaded(function()
local passable_drawtypes = {
airlike = true,
firelike = true,
flowingliquid = true,
liquid = true,
plantlike = true,
plantlike_rooted = true,
signlike = true,
torchlike = true,
}
for _, ndef in pairs(minetest.registered_nodes) do
if passable_drawtypes[ndef.drawtype or "normal"] then -- or ndef.sunlight_propagates == true
ndef._ch_interior = passable
else
local groups = ndef.groups
if groups == nil then
ndef._ch_interior = normal
elseif groups.leaves then
ndef._ch_interior = passable
elseif groups.tree then
ndef._ch_interior = evadable
else
ndef._ch_interior = normal
end
end
end
end)
local get_node = minetest.get_node
local registered_nodes = minetest.registered_nodes
local function has_passable_neighbour(pos)
local ndef
pos.x = pos.x - 1 -- -x
ndef = registered_nodes[get_node(pos).name]
if ndef ~= nil and ndef._ch_interior == passable then
return true
end
pos.z = pos.z - 1 -- -x -z
ndef = registered_nodes[get_node(pos).name]
if ndef ~= nil and ndef._ch_interior == passable then
return true
end
pos.x = pos.x + 1 -- -z
ndef = registered_nodes[get_node(pos).name]
if ndef ~= nil and ndef._ch_interior == passable then
return true
end
pos.x = pos.x + 1 -- +x -z
ndef = registered_nodes[get_node(pos).name]
if ndef ~= nil and ndef._ch_interior == passable then
return true
end
pos.z = pos.z + 1 -- +x
ndef = registered_nodes[get_node(pos).name]
if ndef ~= nil and ndef._ch_interior == passable then
return true
end
pos.z = pos.z + 1 -- +x +z
ndef = registered_nodes[get_node(pos).name]
if ndef ~= nil and ndef._ch_interior == passable then
return true
end
pos.x = pos.x - 1 -- +z
ndef = registered_nodes[get_node(pos).name]
if ndef ~= nil and ndef._ch_interior == passable then
return true
end
pos.x = pos.x - 1 -- -x +z
ndef = registered_nodes[get_node(pos).name]
if ndef ~= nil and ndef._ch_interior == passable then
return true
end
return false
end
--[[
Prozkoumá, zda se zadaná pozice jeví být v interiéru.
Při použití na hráčskou postavu (player:get_pos()) je potřeba k souřadnici y přičíst 0.5.
]]
function ch_core.is_in_interior(pos)
local nlight = minetest.get_natural_light(pos, 0.5) or 0
if nlight <= 0 then
return true
elseif nlight >= minetest.LIGHT_MAX then
return false
else
local ndef, ntype
local ray = minetest.raycast(pos, vector.offset(pos, 0, 20, 0), false, false)
for pointed_thing in ray do
if pointed_thing.type == "node" then
ndef = registered_nodes[get_node(pointed_thing.under)]
if ndef == nil then
return true -- under unknown node => interior
end
ntype = ndef._ch_interior
if ntype ~= passable then
if ntype == evadable then
local pos2 = vector.offset(pointed_thing.under, 0, 1, 0)
ndef = registered_nodes[get_node(pos2).name]
if ndef == nil or ndef._ch_interior == evadable then
return true -- under two evadable nodes => interior
end
pos2.y = pointed_thing.under.y
if not has_passable_neighbour(pointed_thing.under) then
return true -- under evadable node with no passable neighbour => interior
end
else
return true -- under full node => interior
end
end
end
end
return false
end
end
ch_core.close_submod("interiors")
|