aboutsummaryrefslogtreecommitdiff
path: root/advtrains_interlocking/signal_aspect_accessors.lua
blob: a1cbd4ebd6693198ecb9f77696dd94d272e45f3d (plain)
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
local A = advtrains.interlocking.aspects
local D = advtrains.distant
local I = advtrains.interlocking
local N = advtrains.ndb
local pts = advtrains.roundfloorpts

local get_aspect

local supposed_aspects = {}

function I.load_supposed_aspects(tbl)
	if tbl then
		supposed_aspects = tbl
	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))

	local mainpos = D.get_main(pos)
	local nxtasp
	if asp.main ~= 0 and mainpos then
		nxtasp = get_aspect(mainpos)
		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 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.type2main_to_type1(suppasp.group, 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
		--[[
		local dbgmsg = string.format("[%s]set_aspect(%s,%s,%s)", os.clock(), minetest.pos_to_string(pos), minetest.serialize(asp), tostring(skipdst))
		dbgmsg = debug.traceback(dbgmsg, 2)
		minetest.chat_send_all(dbgmsg)
		--]]
	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