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
|
-- Interlocking counterpart of LZB, which has been moved into the core...
-- Registers LZB callback for signal management.
--[[
usage of lzbdata:
{
travsht = boolean indicating whether the train will be a shunt move at "trav"
travspd = speed restriction at end of traverser
travwspd = warning speed res.t
}
]]
local SHUNT_SPEED_MAX = advtrains.SHUNT_SPEED_MAX
local il = advtrains.interlocking
local function get_over_function(speed, shunt)
return function(pos, id, train, index, speed, lzbdata)
if speed == 0 and minetest.settings:get_bool("at_il_force_lzb_halt") then
atwarn(id,"overrun LZB 0 restriction (red signal) ",pos)
-- Set train 1 index backward. Hope this does not lead to bugs...
train.index = index - 0.5
train.velocity = 0
train.ctrl.lzb = 0
minetest.after(0, advtrains.invalidate_path, id)
else
train.speed_restriction = speed
train.is_shunt = shunt
end
end
end
advtrains.tnc_register_on_approach(function(pos, id, train, index, lzbdata)
--atdebug(id,"IL ApprC",pos,index,lzbdata)
--train.debug = advtrains.print_concat_table({train.is_shunt,"|",index,"|",lzbdata})
local pts = advtrains.roundfloorpts(pos)
local cn = train.path_cn[index]
local travsht = lzbdata.travsht
if travsht==nil then
travsht = train.is_shunt
end
local travspd = lzbdata.travspd
local travwspd = lzbdata.travwspd
-- check for signal
local asp, spos = il.db.get_ip_signal_asp(pts, cn)
-- do ARS if needed
local ars_enabled = not train.ars_disable
-- Note on ars_disable:
-- Theoretically, the ars_disable flag would need to behave like the speed restriction field: it should be
-- stored in lzbdata and updated once the train drives over. However, for the sake of simplicity, it is simply
-- a value in the train. In this case, this is sufficient because once a train triggers ARS for the first time,
-- resetting the path does not matter to the set route and ARS doesn't need to be called again.
if spos and ars_enabled then
--atdebug(id,"IL Spos (ARS)",spos,asp)
local sigd = il.db.get_sigd_for_signal(spos)
if sigd then
il.ars_check(sigd, train)
end
end
--atdebug("trav: ",pos, cn, asp, spos, "travsht=", lzb.travsht)
local lspd
if asp then
--atdebug(id,"IL Signal",spos,asp)
local nspd = 0
--interpreting aspect and determining speed to proceed
if travsht then
--shunt move
if asp.shunt.free then
nspd = SHUNT_SPEED_MAX
elseif asp.shunt.proceed_as_main and asp.main.free then
nspd = asp.main.speed
travsht = false
end
else
--train move
if asp.main.free then
nspd = asp.main.speed
elseif asp.shunt.free then
nspd = SHUNT_SPEED_MAX
travsht = true
end
end
-- nspd can now be: 1. !=0: new speed restriction, 2. =0: stop here or 3. nil: keep travspd
if nspd then
if nspd == -1 then
travspd = nil
else
travspd = nspd
end
end
local nwspd = asp.info.w_speed
if nwspd then
if nwspd == -1 then
travwspd = nil
else
travwspd = nwspd
end
end
--atdebug("ns,wns,ts,wts", nspd, nwspd, travspd, travwspd)
lspd = travspd
if travwspd and (not lspd or lspd>travwspd) then
lspd = travwspd
end
local udata = {signal_pos = spos}
local callback = get_over_function(lspd, travsht)
lzbdata.travsht = travsht
lzbdata.travspd = travspd
lzbdata.travwspd = travwspd
advtrains.lzb_add_checkpoint(train, index, lspd, callback, lzbdata)
end
end)
-- Set the ars_disable flag to the value passed
-- Triggers a path invalidation if set to false
function advtrains.interlocking.ars_set_disable(train, value)
if value then
train.ars_disable = true
else
train.ars_disable = nil
minetest.after(0, advtrains.path_invalidate, train)
end
end
|