View difference between Paste ID: z3cyAkCr and ZgmytdU4
SHOW: | | - or go back to the newest paste.
1-
function scheduleFromFile(path)
1+
local LONG_PING = 5
2-
    local file = fs.open(path, "r")
2+
local MEDIUM_PING = 1
3-
	local body = file.readAll()
3+
local SHORT_PING = 0.
4-
	file.close()
4+
5-
    return textutils.unserialize(body)
5+
local RANDOM_MIN = 60
6
local RANDOM_MAX = 120
7
8-
function scheduleFromStation()
8+
local AUDIO_PATH = "audio/transit/"
9-
	return peripheral.find("Create_Station").getSchedule()
9+
10
local VOLUME = 2.0
11
local inst1 = "pling"
12-
local args = {...}
12+
local inst2 = "iron_xylophone"
13-
local filePath = args[1]
13+
local inst3 = "bass"
14-
local schedule
14+
15-
if filePath == nil then
15+
local JINGLES = {
16-
    schedule = scheduleFromStation()
16+
	arrival = {
17-
else
17+
		{duration=0.5, notes={{inst1, VOLUME, 20}, {inst2, VOLUME, 20}, {inst3, VOLUME, 4}}},
18-
    schedule = scheduleFromFile(filePath)
18+
		{duration=0.5, notes={{inst1, VOLUME, 16}, {inst2, VOLUME, 16}, {inst3, VOLUME, 8}}},
19
		{duration=0.5, notes={{inst1, VOLUME, 18}, {inst2, VOLUME, 18}, {inst3, VOLUME, 6}}},
20
		{duration=0.5, notes={{inst1, VOLUME, 11}, {inst2, VOLUME, 11}, {inst3, VOLUME, 11}}}
21-
local color = schedule.color
21+
	},
22-
if color == nil then
22+
    random = {
23-
    color = 2048
23+
    	{duration=0.4, notes={{inst1, VOLUME, 4}, {inst2, VOLUME, 4}, {inst3, VOLUME, 16}}},
24
        {duration=0.4, notes={{inst1, VOLUME, 8}, {inst2, VOLUME, 8}, {inst3, VOLUME, 11}}},
25-
term.setTextColor(colors.white)
25+
        {duration=0.4, notes={{inst1, VOLUME, 11}, {inst2, VOLUME, 11}, {inst3, VOLUME, 8}}}
26-
term.setBackgroundColor(colors.black)
26+
    }
27-
term.clear()
27+
}
28
29-
local i = 1
29+
function splitWord(target, word)
30-
for _, entry in ipairs(schedule.entries) do
30+
    local i, j = string.find(target, word)
31-
    if entry.instruction.id == "create:destination" then
31+
    if i == nil then return target end
32-
		local name = entry.instruction.data.text:gsub("%s%d+$", "")
32+
    return string.sub(target, 1, i - 1), string.sub(target, j + 1, -1)
33-
		term.setCursorPos(4, i)
33+
34-
        term.write(name)
34+
function getName(name)
35-
		i = i + 1
35+
    return string.gfind(string.gsub(name, "%s%d", ""), "[%a%s%p]+")()
36-
	end
36+
37
function getFilename(name)
38-
term.setBackgroundColor(color)
38+
    return string.gsub(getName(name), "%s", "_")
39-
for j=1,i-1 do
39+
40-
    term.setCursorPos(2, j)
40+
function getNumber(name)
41-
    term.write(" ")
41+
    return tonumber(string.gfind(name, "%d+$")())
42-
--    if j == 1 or j == i-1 then
42+
43-
--        term.write("O")
43+
44-
--    else
44+
local decoder = require("cc.audio.dfpwm").make_decoder()
45-
--        term.write("|")
45+
local speaker = peripheral.find("speaker")
46-
--    end
46+
local stations = {}
47
for _, name in pairs(peripheral.getNames()) do
48-
term.setBackgroundColor(colors.black)
48+
	pType = peripheral.getType(name)
49-
term.setCursorPos(1, i)
49+
    if pType == "Create_Station" then
50
        local station = peripheral.wrap(name)
51
        station.fullName = station.getStationName()
52
        station.name=getName(station.fullName)
53
        station.platform=getNumber(station.fullName)
54
        station.present=station.isTrainPresent()
55
        table.insert(stations, station)
56
    end
57
end
58
59
shell.run("clear")
60
61
local pingTimer = os.startTimer(SHORT_PING)
62
local randomTimer = os.startTimer(math.random(RANDOM_MIN, RANDOM_MAX))
63
local soundTasks = {}
64
function addSoundTasks(newTasks)
65
    for i=1, #newTasks do
66
        if newTasks[i].filename ~= nil then
67
            for chunk in io.lines(AUDIO_PATH..newTasks[i].filename, 16*1024) do
68
                soundTasks[#soundTasks+1] = {buffer=chunk}
69
            end
70
        else
71
        	soundTasks[#soundTasks+1] = newTasks[i]
72
        end
73
    end
74
end
75
local soundTaskIndex = 1
76
local soundTaskTimer = nil
77
local soundPlaying = false
78
while true do
79
    local event, id = os.pullEvent()
80
    local startSound = false
81
    if event == "timer" and id == pingTimer then
82
        local newTime = LONG_PING
83
        for i, station in pairs(stations) do
84
            if station.isTrainPresent() then
85
                if not station.present then
86
                    stations[i].present = true
87
                    newTime = math.min(newTime, MEDIUM_PING)
88
                    local name = station.getTrainName()
89
                    write(name)
90
                    
91
					if not soundPlaying then
92
                    	addSoundTasks(JINGLES.arrival)
93
                    end
94
                    
95
                    local lineFilename = "lines/"..getFilename(name)..".dfpwm"
96
                    if fs.exists(AUDIO_PATH..lineFilename) then
97
                        addSoundTasks({{filename=lineFilename}})
98
                    else
99
                        addSoundTasks({{filename="Train.dfpwm"}})
100
                    end
101
                    if station.hasSchedule() then
102
                        local schedule = station.getSchedule()
103
                        local entries = schedule.entries
104
                        local progress = schedule.progress -- BUG: This value is often incorrect.
105
                        if progress == nil then progress = 1 end
106
                        for i=1, #entries do
107
                            if entries[i].instruction.id == "create:destination" and entries[i].instruction.data.text == station.fullName then
108
                                progress = i
109
                                break
110
                            end
111
                        end
112
                        local stations = {}
113
                        local label = nil
114
                        local index = math.mod(progress, #entries) + 1
115
                        while index ~= progress do
116
                            --write(index..": ")
117
                            local entry = entries[index]
118
                            if entry.instruction.id == "create:destination" then
119
                                stations[#stations + 1] = entry.instruction.data.text
120
                                --print(stations[#stations])
121
                            elseif entry.instruction.id == "create:rename" then
122
                                label = entry.instruction.data.text
123
                                --print("-> "..label)
124
                            end
125
                            index = math.mod(index, #entries) + 1
126
                        end
127
						
128
                        if label ~= nil then
129
                            write(" to "..label)
130
                        	local name, andName = splitWord(label, " and ")
131
                       		local isVia = false
132
                        	if andName == nil then
133
                        	    isVia = true
134
                       		    name, andName = splitWord(label, " via ")
135
                        	end
136
                            addSoundTasks({
137
                                {filename="To.dfpwm"},
138
                                {duration=0.4},
139
                                {filename="stations/"..getFilename(name)..".dfpwm"}
140
                            })
141
                            if andName ~= nil then
142
                                addSoundTasks({{duration=0.2}})
143
                                if isVia then addSoundTasks({{filename="Via.dfpwm"}})
144
                                else addSoundTasks({{filename="And.dfpwm"}}) end
145
                                addSoundTasks({{duration=0.2}, {filename="stations/"..getFilename(andName)..".dfpwm"}})
146
                            end
147
                        end
148
                    end
149
                    addSoundTasks({{filename="ArrivesNowOnTrack.dfpwm"}})
150
                    addSoundTasks({
151
                        {duration=0.2},
152
                        {filename="numbers/"..station.platform..".dfpwm"},
153
						{duration=1.0}
154
                    })
155
                    startSound = true
156
                    randomTimer = os.startTimer(math.random(RANDOM_MIN, RANDOM_MAX))
157
                    
158
                    print(" arrived on platform "..station.platform)
159
                end
160
            else
161
                stations[i].present = false
162
                if station.isTrainEnroute() then
163
                    newTime = math.min(newTime, MEDIUM_PING)
164
                elseif station.isTrainImminent() then
165
                    newTime = math.min(newTime, SHORT_PING)
166
                    randomTimer = nil
167
                end
168
            end
169
        end
170
        pingTimer = os.startTimer(newTime)
171
    end
172
    if event == "timer" and id == randomTimer then
173
        local filenames = fs.list(AUDIO_PATH.."random")
174
        local randomFile = filenames[math.random(#filenames)]
175
        print("Playing announcment \""..randomFile.."\"...")
176
        addSoundTasks(JINGLES.random)
177
       	addSoundTasks({{filename="random/"..randomFile}})
178
        startSound = true
179
        randomTimer = os.startTimer(math.random(RANDOM_MIN, RANDOM_MAX))
180
    end
181
    if (event == "timer" and id == soundTaskTimer) or (event == "speaker_audio_empty") or (startSound and not soundPlaying) then
182
        soundPlaying = true
183
        local soundTask = soundTasks[soundTaskIndex]
184
        if soundTask == nil then
185
            soundPlaying = false
186
            soundTasks = {}
187
            soundTaskIndex = 1
188
        else
189
            if soundTask.notes ~= nil then
190
           		for _, note in pairs(soundTask.notes) do
191
                	speaker.playNote(unpack(note))
192
            	end
193
            elseif soundTask.buffer ~= nil then
194
                speaker.playAudio(decoder(soundTask.buffer), VOLUME)
195
            end
196
            if soundTask.duration ~= nil then
197
                soundTaskTimer = os.startTimer(soundTask.duration)
198
            end
199
            soundTaskIndex = soundTaskIndex + 1
200
        end
201
    end
202
end