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
|
--advtrains by orwell96, see readme.txt and license.txt
--crafting.lua
--registers crafting recipes
--tracks: see advtrains_train_track
--signals
minetest.register_craft({
output = 'advtrains:retrosignal_off 2',
recipe = {
{'dye:red', 'default:steel_ingot', 'default:steel_ingot'},
{'', '', 'default:steel_ingot'},
{'', '', 'default:steel_ingot'},
},
})
minetest.register_craft({
output = 'advtrains:signal_off 2',
recipe = {
{'', 'dye:red', 'default:steel_ingot'},
{'', 'dye:dark_green', 'default:steel_ingot'},
{'', '', 'default:steel_ingot'},
},
})
--Wallmounted Signal
minetest.register_craft({
output = 'advtrains:signal_wall_l_off 2',
recipe = {
{'default:steel_ingot', 'default:steel_ingot', 'dye:red'},
{'', 'default:steel_ingot', ''},
{'default:steel_ingot', 'default:steel_ingot', 'dye:dark_green'},
},
})
minetest.register_craft({
output = 'advtrains:signal_wall_r_off 2',
recipe = {
{'dye:red', 'default:steel_ingot', 'default:steel_ingot'},
{'', 'default:steel_ingot', ''},
{'dye:dark_green', 'default:steel_ingot', 'default:steel_ingot'},
},
})
minetest.register_craft({
output = 'advtrains:signal_wall_t_off 2',
recipe = {
{'default:steel_ingot', '', 'default:steel_ingot'},
{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
{'dye:dark_green', '', 'dye:red'},
},
})
--Wallmounted Signals can be converted into every orientation by shapeless crafting
minetest.register_craft({
output = 'advtrains:signal_wall_l_off',
type = "shapeless",
recipe = {'advtrains:signal_wall_r_off'},
})
minetest.register_craft({
output = 'advtrains:signal_wall_t_off',
type = "shapeless",
recipe = {'advtrains:signal_wall_l_off'},
})
minetest.register_craft({
output = 'advtrains:signal_wall_r_off',
type = "shapeless",
recipe = {'advtrains:signal_wall_t_off'},
})
--trackworker
minetest.register_craft({
output = 'advtrains:trackworker',
recipe = {
{'default:diamond'},
{'screwdriver:screwdriver'},
{'default:steel_ingot'},
},
})
--boiler
minetest.register_craft({
output = 'advtrains:boiler',
recipe = {
{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
{'doors:trapdoor_steel', '', 'default:steel_ingot'},
{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
},
})
--drivers'cab
minetest.register_craft({
output = 'advtrains:driver_cab',
recipe = {
{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
{'', '', 'default:glass'},
{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
},
})
--drivers'cab
minetest.register_craft({
output = 'advtrains:wheel',
recipe = {
{'', 'default:steel_ingot', ''},
{'default:steel_ingot', 'group:stick', 'default:steel_ingot'},
{'', 'default:steel_ingot', ''},
},
})
--chimney
minetest.register_craft({
output = 'advtrains:chimney',
recipe = {
{'', 'default:steel_ingot', ''},ute.entry, sigd) then
-- Train entered not from the route. Locate origin and cancel route!
atwarn("Train",tid,"hit route",ts.route.rsn,"!")
advtrains.interlocking.route.cancel_route_from(ts.route.origin)
atwarn("Route was cancelled.")
else
-- train entered route regularily.
end
ts.route = nil
end
if tcbs and tcbs.signal then
-- Reset route and signal
-- Note that the hit-route case is already handled by cancel_route_from
-- this code only handles signal at entering tcb and also triggers for non-route ts
tcbs.route_committed = nil
tcbs.route_aspect = nil
tcbs.route_remote = nil
tcbs.route_origin = nil
tcbs.route_rsn = nil
if not tcbs.route_auto then
tcbs.routeset = nil
end
advtrains.interlocking.signal.update_route_aspect(tcbs)
advtrains.interlocking.route.update_route(sigd, tcbs)
end
end
local function freesection(tid, train, ts_id, ts, clear_all)
-- train
if not train.il_sections then train.il_sections = {} end
itkremove(train.il_sections, "ts_id", ts_id, not clear_all)
-- ts
if not ts.trains then ts.trains = {} end
itremove(ts.trains, tid, not clear_all)
-- route locks
if ts.route_post then
advtrains.interlocking.route.free_route_locks(ts_id, ts.route_post.locks)
if ts.route_post.next then
--this does nothing when the train went the right way, because
-- "route" info is already cleared.
advtrains.interlocking.route.cancel_route_from(ts.route_post.next)
end
ts.route_post = nil
end
-- This must be delayed, because this code is executed in-between a train step
-- TODO use luaautomation timers?
minetest.after(0, advtrains.interlocking.route.update_waiting, "ts", ts_id)
end
-- This is regular operation
-- The train is on a track and drives back and forth
-- This sets the section for both directions, to be failsafe
advtrains.tnc_register_on_enter(function(pos, id, train, index)
local tcb = ildb.get_tcb(pos)
if tcb and train.path_cp[index] and train.path_cn[index] then
-- forward conn
local connid = train.path_cn[index]
local ts = tcb[connid] and tcb[connid].ts_id and ildb.get_ts(tcb[connid].ts_id)
if ts then
setsection(id, train, tcb[connid].ts_id, ts, {p=pos, s=connid})
end
-- backward conn (safety only)
connid = train.path_cp[index]
ts = tcb[connid] and tcb[connid].ts_id and ildb.get_ts(tcb[connid].ts_id)
if ts then
setsection(id, train, tcb[connid].ts_id, ts, {p=pos, s=connid}, true)
end
end
end)
-- this time, of course, only clear the backside (cp connid)
advtrains.tnc_register_on_leave(function(pos, id, train, index)
local tcb = ildb.get_tcb(pos)
if tcb and train.path_cp[index] then
-- backward conn
local connid = train.path_cp[index]
local ts = tcb[connid] and tcb[connid].ts_id and ildb.get_ts(tcb[connid].ts_id)
if ts then
freesection(id, train, tcb[connid].ts_id, ts)
end
end
end)
-- those callbacks are needed to account for created and removed trains (also regarding coupling)
advtrains.te_register_on_create(function(id, train)
-- let's see what track sections we find here
local index = atround(train.index)
local pos = advtrains.round_vector_floor_y(advtrains.path_get(train, index))
local ts_id = ildb.check_and_repair_ts_at_pos(pos, 1) -- passing connid 1 - that always exists
if ts_id then
local ts = ildb.get_ts(ts_id)
if ts then
setsection(id, train, ts_id, ts, nil, true)
else
atwarn("While placing train, TS didnt exist ",ts_id)
end
-- Make train a shunt move
train.is_shunt = true
elseif ts_id==nil then
atlog("Train",id,": Unable to determine whether to block a track section!")
else
--atdebug("Train",id,": Outside of interlocked area!")
end
end)
advtrains.te_register_on_remove(function(id, train)
if train.il_sections then
for idx, item in ipairs(train.il_sections) do
local ts = item.ts_id and ildb.get_ts(item.ts_id)
if ts and ts.trains then
itremove(ts.trains, id)
end
end
train.il_sections = nil
end
end)
|