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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
local A = advtrains.interlocking.aspects
local D = advtrains.distant
local I = advtrains.interlocking
local N = advtrains.ndb
local pts = advtrains.roundfloorpts
local signal_aspect_metatable = {
__tostring = function(asp)
local st = {}
if asp.type2group and asp.type2name then
table.insert(st, string.format("%q in group %q", asp.type2name, asp.type2group))
end
if asp.main then
table.insert(st, string.format("current %d", asp.main))
end
if asp.main ~= 0 then
if asp.dst then
table.insert(st, string.format("next %d", asp.dst))
end
if asp.proceed_as_main then
table.insert(st, "proceed as main")
end
end
return string.format("[%s]", table.concat(st, ", "))
end,
}
local get_aspect
local supposed_aspects = {}
function I.load_supposed_aspects(tbl)
if tbl then
supposed_aspects = tbl
for _, v in pairs(tbl) do
setmetatable(v, signal_aspect_metatable)
end
end
end
function I.save_supposed_aspects()
return supposed_aspects
end
local function get_supposed_aspect(pos)
return supposed_aspects[pts(pos)]
end
local function set_supposed_aspect(pos, asp)
supposed_aspects[pts(pos)] = asp
end
local function get_ndef(pos)
local node = N.get_node(pos)
return minetest.registered_nodes[node.name] or {}
end
local function get_supported_aspects(pos)
local ndef = get_ndef(pos)
if ndef.advtrains and ndef.advtrains.supported_aspects then
return ndef.advtrains.supported_aspects
end
return nil
end
local function adjust_aspect(pos, asp)
asp = table.copy(I.signal_convert_aspect_if_necessary(asp))
setmetatable(asp, signal_aspect_metatable)
local mainpos = D.get_main(pos)
local nxtasp
if mainpos then
nxtasp = get_aspect(mainpos)
end
if asp.main ~= 0 and mainpos then
asp.dst = nxtasp.main
else
asp.dst = nil
end
local suppasp = get_supported_aspects(pos)
if not suppasp then
return asp, asp
end
local stype = suppasp.type
if stype == 2 then
local group = suppasp.group
local name
if suppasp.dst_shift and nxtasp then
asp.main = nil
name = A.type1_to_type2main(nxtasp, group, suppasp.dst_shift)
elseif asp.main ~= 0 and nxtasp and nxtasp.type2group == group and nxtasp.type2name then
name = A.get_type2_dst(group, nxtasp.type2name)
else
name = A.type1_to_type2main(asp, group)
end
asp.type2group = group
asp.type2name = name
return asp, name
end
asp.type2name = nil
asp.type2group = nil
return asp, asp
end
local function get_real_aspect(pos)
local ndef = get_ndef(pos)
if ndef.advtrains and ndef.advtrains.get_aspect then
local asp = ndef.advtrains.get_aspect(pos, node) or I.DANGER
local suppasp = get_supported_aspects(pos)
if suppasp.type == 2 then
asp = A.type2_to_type1(suppasp, asp)
end
return adjust_aspect(pos, asp)
end
return nil
end
get_aspect = function(pos)
local asp = get_supposed_aspect(pos)
if not asp then
asp = get_real_aspect(pos)
set_supposed_aspect(pos, asp)
end
return asp
end
local function set_aspect(pos, asp, skipdst)
local node = N.get_node(pos)
local ndef = minetest.registered_nodes[node.name]
if ndef and ndef.advtrains and ndef.advtrains.set_aspect then
local oldasp = I.signal_get_aspect(pos) or DANGER
local newasp, aspval = adjust_aspect(pos, asp)
set_supposed_aspect(pos, newasp)
ndef.advtrains.set_aspect(pos, node, aspval)
I.signal_on_aspect_changed(pos)
local aspect_changed = A.not_equalp(oldasp, newasp)
if (not skipdst) and aspect_changed then
D.update_main(pos)
end
end
end
local function clear_aspect(pos)
set_supposed_aspect(pos, nil)
end
local function readjust_aspect(pos)
set_aspect(pos, get_aspect(pos))
end
I.signal_get_supported_aspects = get_supported_aspects
I.signal_get_real_aspect = get_real_aspect
I.signal_get_aspect = get_aspect
I.signal_set_aspect = set_aspect
I.signal_clear_aspect = clear_aspect
I.signal_readjust_aspect = readjust_aspect
|