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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
|
-- 'subway' environment --
--F.stn_union=function(line1, prev1, prev2, this, next, doors, dps, osig, ret_sw, ret_st, nohalt, waittime)
F.stationnames={
Ewb="Edenwood Beach",
Ban="Bananame",
ctr="Coulomb Street Triangle",
Cht="Churchill Street",
Bbe="Birch Bay East",
Bap="Turtle Rock",
Icm="Ice Mountain",
Eft="BHS10",
Apl="Apple Plains",
Pal="Palm Bay",
Slh="Smacker's Land of Hope and Glory",
Lks="Leekston",
Ta1="Testing Area 1",
Ta2="Testing Area 2",
Ahr="AHRAZHUL's Station",
Ahz="Large Beach",
Wim="Windy Mountains",
Dam="Szymon's Dam",
Wva="Windy Mountains Valley 1",
Wvb="Windy Mountains Valley 2",
Wvc="Windy Mountains Valley 3",
App="Apple Grove",
Dem="Desert Mountain",
Dev="Desert View (OCP)",
Lvc="Levenshtein Canyon",
Gho="Green Hope",
Snb="Snake Bend",
Adb="Adorno Boulevard",
Duf="Duff Road",
Wat="Something in the water",
Ram="Ramanujan Street",
Per="Perelman Street",
Trp="Trump Park",
Sfs="South Forest Station",
Lok="Jude Milhon Street",
Bam="Bamboo Hills",
Sfa="unnamed",
Gcl="Green Cliffs",
Dri="Dry Island",
Ged="Green Edge",
Ghb="Green Hill Beach",
Acm="Acacia Mountains",
Ghm="Greenhat Mountain",
Pna="Pence Avenue",
Dbl="Dubulti",
Sws="Schwarzschildt Street",
Mnk="Minkowsky Street",
Rgs="Robert Gardon Street",
Ehl="Ehlodex",
Lus="Lusin Street",
Lin="Lesnoi Industrial Area",
Boz="Booze Grove",
Mrh="Mirzakhani Street",
Plt="Planetarium",
Mcf="McFly Street",
Tha="Theodor Adorno Street",
Oni="Onionland",
Ora="Orange Lake",
Uaa="Eiffel Street",
Leo="Leonhard Street",
Bby="Birch Bay",
Stb="Stone Beach",
Jis="Jungle Island",
Ice="Eternal Ice",
Bnt="Pierre Berton Street",
Osa="Origin Sands",
OBa="Cartesian Square",
OOr="School",
OSc="ARA",
ONb="Intel ME Stairs",
OIs="SCSI Connector Mess",
OSm="Origin Sands (Plaza de la Republica)",
ioa="Cow Bridge",
iob="Babbage Road",
Wcs="Watson-Crick Street",
Rru="Rockefeller Runway",
Ewd="Edenwood",
Chu="Marcuse Street Station",
Erd="Erdos Street",
Uni="Museum",
Mar="Felfa's Market (Bracket Road)",
Wac="Watson-Crick",
OLv="Market",
Irk="Ice Rink",
Sbr="Suburb",
Unv="University",
Arc="Archangel",
Dar="Darwin Road",
Hmi="Half-Mile Island",
Zoo="Zoo",
Bea="Beach",
Yos="Yoshi Island",
Krs="Kernighan&Ritchie Street",
Rkb="Robert Koch Boulevard",
Rsi="Riverside",
Swr="Swimming Rabbit Street",
Wbb="Banana Forest",
Ori="Origin",
Snl="Snowland",
Sys="Ship Rock",
Rfo="Redwood forest",
Moj="Mom Junction",
Wfr="Wolf Rock",
Spa="Shanielle Park",
Thh="Treehouse Hotel",
Stn="Main station",
WB1="Riverside",
WB2="Banana Forest",
WB3="Eiffel Street",
WB4="Buckminster Fuller Street",
WB5="White Beaches",
Shn="Shanielle City",
Jus="Tom Lehrer Street",
Fre="Frege Street",
Min="MinerLand",
Vlc="Volcano Cliffs",
Mio="Minio",
Wpy="Water Pyramid",
Cat="Cathedral",
Dca="Desert Canyon",
Spn="Spawn",
Brn="Ministry of Transport (bernhardd)",
Kav="Knuth Avenue",
Lvf="Library",
Fms="John Horton Conway Street",
Mnt="Mountain",
Mnv="Mountain Valley",
Mnn="Mountain View",
Max="Maxwell Street",
Snp="Snowy Peak",
Scl="ScottishLion's City",
Lza="Laza's City",
Bld="BlackDog",
Hts="Hotel Shanielle",
Fmn="Euler Street",
Gpl="Market",
Jun="Jungle",
Jng="Franklin Road",
Uic="Coulomb Street",
Grs="Gram-Schmidt Street",
Lih="Lighthouse",
Rea="Reactor",
Hhs="Henderson-Hasselbalch Street",
Ack="Ackermann Avenue",
Lis="Lone Island",
Pyr="Pytagoras Road",
Nha="North Harbour",
STn="Technic Station",
SPo="Post Office",
SSw="Spawn, westbound",
SSe="Spawn, eastbound",
SPa="Papyrus Farm",
STo="Tourist Info",
SMi="Public Mine",
MR1="Euler Street",
MSt="Main Station (Spawn)",
MOr="Marcuse Street Station (Origin)",
}
--[[
Signal names:
F.stn(<previous>, <this>, <next>
<door side>, <Depart speed (maximum if omitted)>
Halt here and continue when signal is green.
no halt:
F.stn_nohalt=function(prev, this, next, dps, osig)
F.stn_return(<previous>, <this>, <next>,
<door side>, <Switch to set>, <State to set switch to (st/cr)>,
<Depart speed (maximum if omitted)>
Halt here. Set the switch to desired state and return when signal is green. Does not free previous section!
F.stn_return_free=function(<Signal at previous station>, <Switch>, <State>)
To be called after train left the switch of a stn_return station. Sets the switch back to incoming trains and sets signal to green.
]]
--Warning: Expects line to be a string!
local linet={
["1"] = {W="Palm Bay", E="Windy Mountains"},
["2"] = {N="Szymon's Dam", S="Onionland"},
["3"] = {S="Bananame", N="Large Beach"},
["4"] = {E="Schwarzschildt Street", W="Ice Mountain"},
["5"] = {W="Lighthouse", E="Leekston"},
["7"] = {N="Birch Bay East", S="Planetarium"},
}
F.lineterm = function(line, terminal)
if linet[line] and linet[line][terminal] then return linet[line][terminal] end
return terminal
end
F.lineset = function(line, terminal)
if event.train then
atc_set_text_outside("Line "..line.." - "..F.lineterm(line, terminal))
S.line[atc_id] = line
set_line(tonumber(line))
end
end
F.rant=function()
return math.random(5,8)
end
F.stnname=function(cap)
return F.stationnames[string.sub(cap, 1, 3)] or "?"
end
F.stn=function(prev, this, next, doors, dps, osig)
F.stn_union(nil, prev, nil, this, next, doors, dps, osig)
end
F.stn_return=function(prev, this, next, doors, switch, state, dps, osig, waittime)
F.stn_union(nil, prev, nil, this, next, doors, dps, osig, switch, state, false, waittime)
end
F.stn_return_nohalt=function(prev, this, next, switch, state, dps)
F.stn_union(nil, prev, nil, this, next, "C", dps, osig, switch, state, true)
end
F.stn_return_free=function(prev, switch, state)
if event.train then
setstate(prev, "green")
setstate(switch, state)
end
end
F.stn_nohalt=function(prev, this, next, dps, osig)
F.stn_union(nil, prev, nil, this, next, "C", dps, osig, nil, nil, true)
end
F.union_wait=function(sect)
S.union_waiting[sect] = not depart
end
F.stn_union=function(line1, prev1, prev2, this, next, doors, dps, osig, ret_sw, ret_st, nohalt, waittime)
if not atc_id then
atc_send("B0")
error("Train has disappeared!")
end
if not atc_arrow then
atc_send("B0")
error("Train passed in wrong direction!")
end
depart=false
if event.train then
setstate(prev1, "red")
if prev2 then setstate(prev2, "red") end
atc_send("B0O"..doors)
if atc_speed and atc_speed > 10 then
local dt = os.date()
atc_set_text_outside("BrakeFail speed="..atc_speed.." when="..dt.year.."-"..dt.month.."-"..dt.day.." "..dt.hour..":"..dt.min..":"..dt.sec)
error("Train "..atc_id.." has passed rail at speed of "..atc_speed)
end
if not nohalt then
interrupt(waittime or (ret_sw and 20 or 7), "ready")
atc_set_text_inside(F.stnname(this))
end
end
if (event.int and event.message=="ready") or (event.train and nohalt) then
if getstate(this)=="green" and (not osig or getstate(osig)=="green") then
if ret_sw then
atc_send("OCD1B0WRS"..(dps or "M"))
setstate(ret_sw, ret_st)
else
atc_send("OCD1S"..(dps or "M"))
setstate(prev1, "green")
if line1 then --this call did not come from F.stn, do union stuff
setstate(prev2, "green")
if S.line[atc_id]==line1 then
if S.union_waiting[prev2] then setstate(prev1, "red") end
else
if S.union_waiting[prev1] then setstate(prev2, "red") end
end
end
end
setstate(this, "red")
atc_set_text_inside("Next stop: "..F.stnname(next))
depart=true
nodepartc=nil
else
interrupt(F.rant(), "ready")
nodepartc=nodepartc and nodepartc+1 or 0
if nodepartc>=10 then
atc_set_text_inside(F.stnname(this).."\nLine out of order!")
else
if (not osig or getstate(osig)=="green") then
atc_set_text_inside(F.stnname(this).."\nWaiting for preceding train...")
else
atc_set_text_inside(F.stnname(this).."\nWaiting for oncoming train...")
end
end
end
end
end
F.pre=function(signal)
if getstate(signal) == "red" then
atc_send("B4")
end
end
F.uiclog = function ()
return
end
--L197
F.stat=function(line, init)
--statistics
-- init
if init then
reftrain = atc_id
a_tbt = 30
a_tbtmax = 30
a_rtt = 500
a_not = 0
c_not = 0
c_tbtmax = 0
time_lt = os.time()
time_rt=os.time()
end
if not a_tbtmax then a_tbtmax = 30 end
if not c_tbtmax then c_tbtmax = 0 end
--real code
if event.train then
local time = os.time()
c_not = c_not + 1
a_tbt = (a_tbt + (time - time_lt)) / 2
c_tbtmax = math.max(c_tbtmax, (time - time_lt))
if atc_id == reftrain then
a_rtt = (a_rtt*0.2 + (time - time_rt)*0.8)
a_not = c_not
c_not = 0
a_tbtmax = (a_tbtmax + c_tbtmax) / 2
c_tbtmax = 0
end
digiline_send("stats", "Stat: "..line..
" NoT:"..a_not.."("..c_not..")"..
" TbT:"..math.floor(a_tbt).."("..(time-time_lt)..")"..
" Tmx:"..math.floor(a_tbtmax).."("..c_tbtmax..")"..
" R:"..math.floor(a_rtt).."("..(time - time_rt)..")"
)
time_lt = time
if atc_id == reftrain then
time_rt = time
end
end
end
local function aspect_is_free(asp)
if type(asp.main) == "table" then
return asp.main.free
else
return asp.main ~= 0
end
end
-- 21.1.19, the rise of tss
F.stn_ilk=function(prev, this, next, doors, dps)
depart = false
if event.train then
atc_send("B0 W O"..doors)
atc_set_text_inside(F.stnname(this))
interrupt(7, "ready")
elseif event.int then
local asp = get_aspect(this)
if not asp then
atc_set_text_inside(F.stnname(this).."\nNo aspect for "..this)
else
if aspect_is_free(asp) then
atc_set_text_inside("Next stop:\n"..F.stnname(next))
atc_send("OC D1 S"..(dps or "M"))
depart = true
return
else
atc_set_text_inside(F.stnname(this).."\nSection ahead is blocked...")
end
end
interrupt(7, "ready")
end
end
F.stn_ilkentry=function(prev, this, next, doors, dps)
F.stn_ilk(prev, this, next, doors, dps)
if depart then setstate(prev, "green") end
end
|