From ac853fa04d0d8a6489320dfe7dbd60c9371d756b Mon Sep 17 00:00:00 2001 From: autocommitter Date: Mon, 22 Apr 2024 14:57:43 +0200 Subject: State at 2022-06-19 --- auto_yards/init_code.lua | 25 ++- auto_yards/nodes/(-2004,2,-1101).lua | 23 +++ auto_yards/nodes/(416,17,5).lua | 27 +++ durt/init_code.lua | 347 ++++++++++++++++++++--------------- durt/nodes/(-1512,8,-2613).lua | 18 ++ durt/nodes/(-1515,7,-2625).lua | 18 +- 6 files changed, 303 insertions(+), 155 deletions(-) create mode 100644 auto_yards/nodes/(-2004,2,-1101).lua create mode 100644 auto_yards/nodes/(416,17,5).lua create mode 100644 durt/nodes/(-1512,8,-2613).lua diff --git a/auto_yards/init_code.lua b/auto_yards/init_code.lua index cdeacce..6e4551f 100644 --- a/auto_yards/init_code.lua +++ b/auto_yards/init_code.lua @@ -8,7 +8,10 @@ if event.init then active_indicator_pos = POS(), dir_indicator_pos = POS(), error_indicator_pos = POS(), + ext_notify_pos = POS(), + notify = table, headshunt_max = number, + }, ]]-- TY = { @@ -21,6 +24,8 @@ if event.init then active_indicator_pos = POS(-2002,3,-1099), dir_indicator_pos = POS(-2009,3,-1101), error_indicator_pos = POS(-1999,3,-1099), + ext_notify_pos = POS(-2004,2,-1101), + notify = {}, headshunt_max = 5, }, IP = { @@ -40,7 +45,11 @@ end -- Utility Functions F.indicator = function(indicator,set) if set ~= nil then - setstate(indicator,(set and "on") or "off") + if type(set) == string then + setstate(indicator,set) + else + setstate(indicator,(set and "on") or "off") + end end return (getstate(indicator) == "on") or false end @@ -156,7 +165,6 @@ F.yard_arrival = function(yard_id,this_dir) -- arrow points towards yard F.add_rc({yard_id.."_HAS_RTS"}) rts = true end - step_fc() atc_set_ars_disable(false) atc_send("S6") print("Train "..atc_id.." enters yard ".. yard_id.." from the "..tostring(this_dir).." direction and "..((rts and "will") or "won't").." return in the same direction") @@ -352,6 +360,7 @@ F.headshunt_exit = function(yard_id,this_dir) -- arrow points out of yard F.remove_rc(yard_id.."_HAS_RTS") F.add_rc({yard_id.."_RTS"}) end + step_fc() atc_set_ars_disable(false) atc_send("S6D10SM") schedule_in(";05","deactivate_check") -- wait a little to ensure train is clear from headshunt to deactivate yard @@ -368,6 +377,7 @@ F.headshunt_exit = function(yard_id,this_dir) -- arrow points out of yard if event.msg == "deactivate_check" then if not atc_id then F.indicator(yard.active_indicator_pos,false) + if yard.ext_notify_pos then interrupt_pos(yard.ext_notify_pos,{command="EXIT"}) end print(yard_id.." yard Disabled") else schedule_in(";05","deactivate_check") @@ -401,6 +411,17 @@ F.lane_EOL = function(yard_id,this_dir) -- arrow points towards headshunt else if F.indicator(yard.dir_indicator_pos) == this_dir then --train is clasifying wagons, let it pass and couple to the rest of the rake + --send a notification to the yard controller to trigger external functions + if yard.ext_notify_pos then + local fc = F.get_rc_safe():match(yard_id.."_CLASS_(%S+)") or nil + if fc then + if F.has_rc(yard_id.."_COLLECT_"..fc) then + interrupt_pos(yard.ext_notify_pos,{command="COLLECTED",msg=fc}) + else + interrupt_pos(yard.ext_notify_pos,{command="NOTIFY",msg=fc}) + end + end + end F.remove_rc_match(yard_id.."_CLASS_%S+") else --this should never come into play as it means the train has entered from the wrong end somehow atc_send("BBOL") --stop the train and open the doors (if available) to signify assistance required diff --git a/auto_yards/nodes/(-2004,2,-1101).lua b/auto_yards/nodes/(-2004,2,-1101).lua new file mode 100644 index 0000000..c39016a --- /dev/null +++ b/auto_yards/nodes/(-2004,2,-1101).lua @@ -0,0 +1,23 @@ +local yard_id = "BY" +local subs = { + ['S27'] = POS(-1512,8,-2613) +} +if event.ext_int then + print(event) + local m = event.message + if m.command == "NOTIFY" then -- store the notifications in the yards's S table entry for mass-dispatch + if m.msg == "*" then return end -- no need to notify for the LHF train's collect moves + S.yards[yard_id].notify[m.msg] = true + return + end + if m.command == "COLLECTED" then + S.yards[yard_id].notify[m.msg] = nil + return + end + if m.command == "EXIT" then + for k in pairs(S.yards[yard_id].notify) do + if subs[k] then interrupt_pos(subs[k],{command="NOTIFY",msg=k}) end + end + return + end +end \ No newline at end of file diff --git a/auto_yards/nodes/(416,17,5).lua b/auto_yards/nodes/(416,17,5).lua new file mode 100644 index 0000000..e8c1b0e --- /dev/null +++ b/auto_yards/nodes/(416,17,5).lua @@ -0,0 +1,27 @@ +local stack = function(t,channel,num_screens) + for i=0,math.ceil(#t/4) do + local calc = i*4 + local working_t = {t[calc+1],t[calc+2],t[calc+3],t[calc+4]} + local message = table.concat(working_t,"\n") + if i+1 > num_screens then return end + digiline_send(channel..i+1,message) + end +end + +if event.channel=="clock" or event.punch then + local txt = {"-- AUTOMATIC YARD STATUS --","Railway Time: "..rwt.to_string(rwt.now(),true),"LHF Trains: 719814"," ========================"} + local s + for yard_id,info in pairs(S.yards) do + table.insert(txt, yard_id.." - Active: " .. tostring(F.indicator(info.active_indicator_pos))) + table.insert(txt," Direction: " .. tostring(F.indicator(info.dir_indicator_pos))) + table.insert(txt," Error: ".. tostring(F.indicator(info.error_indicator_pos))) + if info.notify and info.notify[1] then + table.insert(txt,"Notify: "..table.concat(info.notify,", ")) + else + table.insert(txt,"Notify: N/A") + end + end + + stack(txt,"yard_status",4) + return +end \ No newline at end of file diff --git a/durt/init_code.lua b/durt/init_code.lua index 0b60d52..a837f2e 100644 --- a/durt/init_code.lua +++ b/durt/init_code.lua @@ -1,3 +1,198 @@ +--[[ + Misc Code +]]-- +S.runarounds = { + ["M27_Breaker_Factory"] = {}, + ["DJnc_4"] = {}, +} +if event.init then + local list_of_yards = { + ["WOA"] = {}, + + } + S.yards = S.yards or list_of_yards +end + +--[[ + Utility Functions +]]-- +F.indicator = function(indicator,set) + if set ~= nil then + if type(set) == string then + setstate(indicator,set) + else + setstate(indicator,(set and "on") or "off") + end + end + return (getstate(indicator) == "on") or false +end + +F.dir = F.indicator -- legacy alias, to be updated to F.indicator + +F.get_rc_safe = function() + return get_rc() or "" +end + +F.has_rc = function(query,rc_list) -- query = string, single entry + if not atc_id then return false end + if rc_list == "" or query == nil or query=="" then return false end + if not rc_list then rc_list = F.get_rc_safe() end + for word in rc_list:gmatch("[^%s]+") do + if word == query then return true end + end + -- print(F.get_rc_safe()) + return false +end + +F.has_rc_match = function(query,rc_list) -- query = pattern string, single entry + if not atc_id then return false end + if rc_list == "" or query == nil or query=="" then return false end + if not rc_list then rc_list = F.get_rc_safe() end + + local rc = {} + for v in rc_list:gmatch("("..query..")") do + table.insert(rc,v) + end + + if rc[1] == true then + return true, rc + else + return nil + end +end + +F.add_rc = function(rc_list) -- rc_list = string or table, eg: {"rc1","rc2"} OR "rc1 rc2" + if not atc_id then return false end + if type(rc_list) == "table" then + rc_list = table.concat(rc_list," ") + end + set_rc(F.get_rc_safe().." "..rc_list) + -- print(F.get_rc_safe()) + return true +end + +F.remove_rc = function(rc_list,arrow_mode) -- rc_list = string eg: "rc1 rc2 rc3" OR table eg: {"rc1","rc2","rc3"} + -- Arrow Modes: + -- true: with arrow direction + -- false: against arrow direction + -- nil: ignores arrow direction + + if not atc_id then return false end + if not rc_list then return false end + + if (arrow_mode == nil) or (atc_arrow == arrow_mode) then + -- prep rc_list to useable format + local rc_remove = {} + if type(rc_list) == "string" then + for word in rc_list:gmatch("[^%s]+") do + rc_remove[word] = true + end + elseif type(rc_list) == "table" then + for _,word in pairs(rc_list) do + rc_remove[word] = true + end + end + + -- remove codes from train's rc + local rc = F.get_rc_safe() + local reinsert = {} + for token in rc:gmatch("[^%s]+") do + if not rc_remove[token] then + table.insert(reinsert,token) + end + end + -- insert new string to train's rc + set_rc(table.concat(reinsert," ")) + end + -- print(F.get_rc_safe()) + return reinsert +end + +F.remove_rc_match = function(rc_list) -- rc_list = pattern string, single entry, eg: "rc_%d+" + if not atc_id then return false end + if not rc_list then return false end + local rm = {} + for v in F.get_rc_safe():gmatch("("..rc_list..")") do + table.insert(rm,v) + end + F.remove_rc(rm) + -- print(F.get_rc_safe()) + return rm +end + +F.yard_road_count = function(yard,section_id,monitoring_light) + if not S.yards[yard][section_id] then S.yards[yard][section_id] = {['car_count'] = 0} end + + local car_count = S.yards[yard][section_id].car_count + + if event.train then + if atc_arrow then --arrow points into section, add to length + car_count = car_count + train_length() + else -- subtract from + car_count = car_count - train_length() + end + + if car_count > 0 then -- light = on + setstate(monitoring_light,"on") + else + car_count = 0 + setstate(monitoring_light,"off") + end + + S.yards[yard][section_id].car_count = car_count + end +end + + + +--[[ + stats counter from subway/il_timetable +]]-- +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 + +--[[ + Custom Subway/Passenger Station Code +]]-- S.lines = { S23 = { termini = { @@ -195,154 +390,6 @@ S.lines = { } } -S.runarounds = { - ["TheStacks"] = {}, - ["M27_Quarry_runaround"] = {}, - ["M27_Breaker_Factory"] = {}, - ["DJnc_4"] = {}, -} - - ---------------------------------------------------------------------- ---Atlac Yard Operations -if event.init then - local list_of_yards = { - ["WOA"] = {}, - ["S27"] = {}, - - } - S.yards = S.yards or list_of_yards -end - -F.dir = function(dir_indicator,set) --returns true if on, false if off - if set ~= nil then - setstate(dir_indicator,(set and "on") or "off") - end - return (getstate(dir_indicator) == "on") or false -end - -F.get_rc_safe = function() - return get_rc() or "" -end - -F.has_rc = function(query,rc_list) - if rc_list == "" or query == nil or query=="" then return false end - if not rc_list then rc_list = F.get_rc_safe() end - for word in rc_list:gmatch("[^%s]+") do - if word == query then return true end - end - return false -end - -F.remove_rc = function(rc_list,arrow_mode) - -- rc_list MUST be a table of rc codes to remove - -- eg: {"rc1","rc2"} - -- Arrow Modes: - -- true: with arrow direction - -- false: against arrow direction - -- nil: ignores arrow direction - - if not atc_id then return false end - if (arrow_mode == nil) or (atc_arrow == arrow_mode) then - local rc = F.get_rc_safe() - rc_list = rc_list or {} - -- ensure rc-remove table can be read - local rc_remove = {} - for _,v in pairs(rc_list) do - rc_remove[v] = true - end - -- remove codes from train's rc - local reinsert = {} - for token in rc:gmatch("[^%s]+") do - if not rc_remove[token] then - table.insert(reinsert,token) - end - end - -- insert new string to train's rc - set_rc(table.concat(reinsert," ")) - end - return reinsert -end - -F.add_rc = function(rc_list) - if not atc_id then return false end - if type(rc_list) == "table" then - rc_list = table.concat(rc_list," ") - end - set_rc(F.get_rc_safe().." "..rc_list) - return true -end - -F.yard_road_count = function(yard,section_id,monitoring_light) - if not S.yards[yard][section_id] then S.yards[yard][section_id] = {['car_count'] = 0} end - - local car_count = S.yards[yard][section_id].car_count - - if event.train then - if atc_arrow then --arrow points into section, add to length - car_count = car_count + train_length() - else -- subtract from - car_count = car_count - train_length() - end - - if car_count > 0 then -- light = on - setstate(monitoring_light,"on") - else - car_count = 0 - setstate(monitoring_light,"off") - end - - S.yards[yard][section_id].car_count = car_count - end -end - - ---stats counter from subway/il_timetable -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 - ---------------------------------------------------------------------- ---defining the functions - F.arrive = function(stn_code,dir,line) S.lines[line].monitoring[dir][stn_code] = atc_id atc_send("B0 W O"..S.lines[line].stations[stn_code].doors) @@ -369,9 +416,6 @@ F.set_desto = function(dir, line) atc_set_text_outside("LINE " .. line .."\n---> " .. S.lines[line].stations[S.lines[line].termini[dir]].name) end ---------------------------------------------------------------------- ---LuaATC track functions - F.station = function(stn_code,dir,line) -- temp until all SF LuaAtc tracks are changed------------------------- @@ -388,7 +432,6 @@ F.station = function(stn_code,dir,line) end end - F.terminus = function(stn_code, newdir, line) if event.train then S.lines[line].monitoring[newdir][stn_code] = atc_id diff --git a/durt/nodes/(-1512,8,-2613).lua b/durt/nodes/(-1512,8,-2613).lua new file mode 100644 index 0000000..ecf8060 --- /dev/null +++ b/durt/nodes/(-1512,8,-2613).lua @@ -0,0 +1,18 @@ +local ind = POS(-1513,8,-2613) +local loco_track = POS(-1515,7,-2625) + +if event.ext_int then + local m = event.message + if m.command == "NOTIFY" and m.msg == "S27" then + if F.indicator(ind) then return end + interrupt_pos(loco_track,"SEND") + F.indicator(ind,"on") + return + end +end + +if event.punch then + F.indicator(ind,"on") + interrupt_pos(loco_track,"SEND") + return +end \ No newline at end of file diff --git a/durt/nodes/(-1515,7,-2625).lua b/durt/nodes/(-1515,7,-2625).lua index 7489acc..d29e92c 100644 --- a/durt/nodes/(-1515,7,-2625).lua +++ b/durt/nodes/(-1515,7,-2625).lua @@ -1 +1,17 @@ --- \ No newline at end of file +local ind = POS(-1513,8,-2613) +local function send_train() + set_rc("FREIGHT S23 TanhX_NBS23toE3 BYARD BY_COLLECT_S27 MGGRatHYARD S27 S27_UNLOAD S27_Overburden BY_RTS S27_EXIT") + atc_send("S0WRD2A1S4") + set_route(POS(-1504,8,-2622),"Through to Lead") + F.indicator(ind,"off") +end +if event.ext_int and atc_id then + send_train() +end + +if event.train then + if F.indicator(ind) then + send_train() + end + return +end \ No newline at end of file -- cgit v1.2.3