--[[ Cross 3 Standard Schedule Program ]] require("libevent") require("util") require("checkarg") require("queue") local sides = require("sides") -- Config your update functions here (Do not change variable name) local redin1 = proxy("redstone", "") local redin2 = proxy("redstone", "") local redin3 = proxy("redstone", "") local redout1 = proxy("redstone", "") -- Redirect Table local redirect_tb = { ["ab_st"]={redin1,sides.north}, ["ab_sr"]={redin1,sides.east}, ["ab_lout"]={redin1,sides.south}, ["ab_left"]={redin1,sides.west}, ["ba_st"]={redin2,sides.north}, ["ba_sr"]={redin2,sides.east}, ["ba_lout"]={redin2,sides.south}, ["ba_left"]={redin2,sides.west}, ["c_st"]={redin3,sides.north}, ["c_sr"]={redin3,sides.east}, ["c_lout"]={redin3,sides.south}, ["c_left"]={redin3,sides.west}, ["ab_ks"]={redout1,sides.north}, ["ab_m"]={redout1,sides.east}, ["ba_ks"]={redout1,sides.south}, ["ba_m"]={redout1,sides.west}, ["c_ks"]={redout2,sides.north}, ["c_m"]={redout2,sides.east}, ["last_unused"]={redin1,sides.north} } local function getNameFromRaw(Device, Side) for k, t in pairs(redirect_tb) do if (t[1].address == Device and t[2] == Side) then return k end end return nil end local function getRawFromName(Name) return redirect_tb[Name][1], redirect_tb[Name][2] end local function enabledevice(Name) local d, s = getRawFromName(Name) if (d ~= nil and s ~= nil) then d.setOutput(s, 15) end end local function disabledevice(Name) local d, s = getRawFromName(Name) if (d ~= nil and s ~= nil) then d.setOutput(s, 0) end end local function readdevice(Name) local d, s = getRawFromName(Name) if (d ~= nil and s ~= nil) then return d.getInput(s) else -- Critical error error("failed to read device input") end end local function trigger(Name) enabledevice(Name) os.sleep(0.25) disabledevice(Name) end local evl = Queue.new() local function restone_delegator(Name, callback_func) evl:push( AddEventListener( "redstone_changed", function(ev, dev, sd, from, to) if (getNameFromRaw(dev, sd) == Name) then callback_func(from, to) end end ) ) end local bus=Queue.new(); local function redstone_event(DeviceName,OnEvent,OffEvent) if(OnEvent~=nil and OffEvent~=nil) then redstone_delegator(DeviceName, function(from,to) if(fromto) then bus:push(OffEvent) end end) end end local function doInit() evl:push( AddEventListener( "interrupted", function() bus:push("stop") end ) ) redstone_event("ab_st","a_new_train","a_train_left") redstone_event("ba_st","b_new_train","b_train_left") redstone_event("c_st","c_new_train","c_train_left") redstone_event("ab_left","b_detect_start","b_detect_end") redstone_event("ba_left","a_detect_start","a_detect_end") redstone_event("c_left","c_detect_start","c_detect_end") end -- Status -- Out busy flag local a_busy,b_busy,c_busy=false,false,false local crosslocked=false local function doCheck() for k, vt in pairs(redirect_tb) do if (vt[1] == nil) then error("Check Failed. Please review your redstone configure") end end print("Check Pass.") end local function doClearOutput() local smt={"ab_ks","ab_m","ba_ks","ba_m","c_ks","c_m"} for k, v in pairs(smt) do disabledevice(v) end end local function CCSMain() doCheck() doClearOutput() doInit() print("CCS Started. Press Ctrl+C to stop.") local running=true while(running) do os.sleep(0.25) local ev="no_evnet" if(bus:top()~=nil) then ev=bus:pop(); end if (ev ~= "no_event") then print(ev) end if (ev == "no_event") then -- No event, no action. elseif (ev == "stop") then running = false elseif (ev=="delay") then os.sleep(0.25) elseif (ev=="a_new_train") then -- New Train From A local done=false if(readdevice("ab_sr")>0) then -- Turn to C if( (not c_busy) and (not crosslocked) and readdevice("c_lout")>0) then c_busy=true crosslocked=true enabledevice("ab_m") trigger("ab_ks") done=true end else -- Go directly to B if( (not b_busy) and (not crosslocked) and readdevice("ab_lout")>0) then b_busy=true crosslocked=true disabledevice("ab_m") trigger("ab_ks") done=true end end if(not done) then bus:push(ev) end elseif (ev=="b_new_train") then -- New Train From B local done=false if(readdevice("ba_sr")>0) then -- Turn to C if( (not c_busy) and readdevice("c_lout")>0) then c_busy=true enabledevice("ba_m") trigger("ba_ks") done=true end else -- Go directly to A if( (not a_busy) and (not crosslocked) and readdevice("ba_lout")>0) then a_busy=true crosslocked=true disabledevice("ba_m") trigger("ba_ks") done=true end end if(not done) then bus:push(ev) end elseif (ev=="c_new_train") then -- New Train From C local done=false if(readdevice("ba_sr")>0) then -- Turn to A if( (not a_busy) and readdevice("ba_lout")>0) then a_busy=true enabledevice("c_m") trigger("c_ks") done=true end else -- Go directly to B if( (not b_busy) and (not crosslocked) and readdevice("ab_lout")>0) then b_busy=true crosslocked=true disabledevice("c_m") trigger("c_ks") done=true end end if(not done) then bus:push(ev) end elseif(ev=="a_detect_end") then a_busy=false crosslocked=true elseif(ev=="b_detect_end") then b_busy=false crosslocked=true elseif(ev=="c_detect_end") then c_busy=false crosslocked=true end end end