Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --Version 1.1.2
- 2.--Code by O'Reezy
- 3.
- 4.local helpString = [[Arguments: (in any order)
- 5.-t terminal mode (incompatible with monitor mode)
- 6.-d debug mode
- 7.-nd non-daemon mode
- 8.-m<side or name> specifies which monitor to use (no space) (incompatible with terminal mode)
- 9.-s<.5-5> sets scale of radio (no space) (not available for terminal)
- 10.-v<1-15> sets initial volume (no space)
- 11.
- 12.Example: radio -mmonitor_1 -s2
- 13.]]
- 14.
- 15.local radio, chest, display, displayName, radioDir, chestDir
- 16.local mX, mY
- 17.local disks = {}
- 18.local diskLoc = {}
- 19.local volumeSide
- 20.local tArgs = {...}
- 21.
- 22.--Wraps necessary peripherals to variables
- 23.local function findPeripherals()
- 24. local peripherals = peripheral.getNames()
- 25. for k,v in pairs(peripherals) do
- 26. if string.match(peripheral.getType(v), "radio") then
- 27. radio = peripheral.wrap(v)
- 28. elseif string.match(peripheral.getType(v), "chest") then
- 29. chest = peripheral.wrap(v)
- 30. elseif string.match(peripheral.getType(v), "monitor") then
- 31. display = peripheral.wrap(v)
- 32. displayName = v
- 33. end
- 34. end
- 35. --Errors if all necessary peripherals are not found
- 36. if not radio then
- 37. error("Radio peripheral not found", 0)
- 38. elseif not chest then
- 39. error("Chest peripheral not found", 0)
- 40. end
- 41.end
- 42.
- 43.--Table of possible arguments
- 44.local options = {
- 45. daemon = true;
- 46. terminal = false;
- 47. scale = false;
- 48. debug = false;
- 49. monitor = false;
- 50. volume = 4;
- 51.}
- 52.
- 53.local function saveOptions()
- 54. local config = fs.open(".radioConfig", "w")
- 55. config.write(textutils.serialize(options))
- 56. config.close()
- 57.end
- 58.
- 59.local function loadOptions()
- 60. if fs.exists(".radioConfig") then
- 61. local config = fs.open(".radioConfig", "r")
- 62. options = textutils.unserialize(config.readAll())
- 63. config.close()
- 64. end
- 65.end
- 66.
- 67.--Determines which arguments are used
- 68.local function getArgs()
- 69. local sides = {}
- 70. for k,v in pairs({rs.getSides}) do
- 71. sides[v] = true
- 72. end
- 73. for i= 1, #tArgs do
- 74. if tArgs[i] == "-nd" then
- 75. options.daemon = false
- 76. elseif tArgs[i] == "-t" then
- 77. options.terminal = true
- 78. options.daemon = false
- 79. elseif tArgs[i] == "-d" then
- 80. options.debug = true
- 81. options.daemon = false
- 82. elseif string.match(tArgs[i], "-s") then
- 83. options.scale = tonumber(string.match(tArgs[i], ".*", 3))
- 84. if options.scale < .5 or options.scale > 5 then
- 85. error("Scale must be (0.5-5.0)")
- 86. end
- 87. elseif string.match(tArgs[i], "-v") then
- 88. options.volume = tonumber(string.match(tArgs[i], "%d"))
- 89. if options.volume > 15 then
- 90. options.volume = 15
- 91. elseif options.volume < 1 then
- 92. options.volume = 1
- 93. end
- 94. elseif string.match(tArgs[i], "-m") then
- 95. local monFind = string.match(tArgs[i], ".*", 3)
- 96. if sides[monFind] or peripheral.getType(monFind) == "monitor" then
- 97. displayName = monFind
- 98. display = peripheral.wrap(monFind)
- 99. options.monitor = true
- 100. end
- 101. elseif tArgs[i] == "help" then
- 102. error(helpString, 0)
- 103. end
- 104. end
- 105. if #tArgs > 0 then
- 106. saveOptions()
- 107. end
- 108.end
- 109.
- 110.--Finds which directions the chest/radio are from each other
- 111.local function findDirection()
- 112. local dirs = {"north", "east", "up", "south", "west", "down"}
- 113. for i = 1,#dirs do
- 114. local t = {radio.pullItemIntoSlot(dirs[i], 1, 1, 1)}
- 115. if t[1] == 1 then
- 116. if i <= 3 then
- 117. radio.pushItemIntoSlot(dirs[i], 1, 1, 1)
- 118. return dirs[i], dirs[i+3]
- 119. elseif i >= 4 then
- 120. radio.pushItemIntoSlot(dirs[i], 1, 1, 1)
- 121. return dirs[i], dirs[i-3]
- 122. end
- 123. end
- 124. end
- 125. --Errors if the radio and chest are not next to each other
- 126. error("Radio and Chest must be touching", 0)
- 127.end
- 128.
- 129.--Creates a table and reverse table of disks available
- 130.local function indexDisks()
- 131. local t = chest.getAllStacks()
- 132. --Creates indexed tables of disks in chests
- 133. for k,v in pairs(t) do
- 134. disks[#disks+1] = t[k].name
- 135. end
- 136.
- 137. for k,v in pairs(disks) do
- 138. diskLoc[v] = k
- 139. end
- 140.end
- 141.
- 142.--Checks if correct disks are used
- 143.local function diskTypeCheck()
- 144. local t = chest.getStackInSlot(1)
- 145. if string.match(t.rawName, "tuned_crystal") then
- 146. return true
- 147. end
- 148. return false
- 149.end
- 150.
- 151.--Empties the radio if there is a disk already in it (necessary or findDirection will error)
- 152.local function initialEmpty()
- 153. local dirs = {"north", "east", "up", "south", "west", "down"}
- 154. if radio.getStackInSlot(1) then
- 155. if #chest.getAllStacks() < chest.getInventorySize() then
- 156. for k,v in ipairs(dirs) do
- 157. radio.pushItemIntoSlot(v, 1, 1, #chest.getAllStacks() + 1)
- 158. end
- 159. else
- 160. error("No room in chest for crystal.")
- 161. end
- 162. end
- 163.end
- 164.
- 165.local function debugPrint(string)
- 166. if options.debug then
- 167. print(string)
- 168. end
- 169.end
- 170.
- 171.--Prints the volume
- 172.local function printVolume(target)
- 173. target.setCursorPos(mX-5,1)
- 174. target.write("^")
- 175. target.setCursorPos(mX-6, math.ceil(mY/2))
- 176. if options.volume < 10 then
- 177. target.write(" ")
- 178. end
- 179. target.write(tostring(options.volume))
- 180. target.setCursorPos(mX-5,mY)
- 181. target.write("v")
- 182.end
- 183.
- 184.--Draws all options found
- 185.local select = 1
- 186.local function drawOptions(target)
- 187. local length = #disks
- 188. if mY < length then
- 189. length = mY
- 190. end
- 191. target.clear()
- 192. target.setCursorPos(1,1)
- 193. local x = 1
- 194. for i = select, length-1+select do
- 195. target.setCursorPos(1, x)
- 196. if disks[i] ~= current then
- 197. target.write(disks[i])
- 198. else
- 199. target.setTextColor(colors.green)
- 200. target.write(disks[i])
- 201. target.setTextColor(colors.lightBlue)
- 202. end
- 203. x = x+1
- 204. end
- 205. if mY < #disks then
- 206. target.setCursorPos(mX-1,1)
- 207. target.write("^")
- 208. target.setCursorPos(mX-1,mY)
- 209. target.write("v")
- 210. end
- 211. target.setCursorPos(mX-2, math.ceil(mY/2))
- 212. if radio.getStackInSlot(1) then
- 213. target.setTextColor(colors.green)
- 214. target.write(" ON")
- 215. target.setTextColor(colors.lightBlue)
- 216. else
- 217. target.setTextColor(colors.red)
- 218. target.write("OFF")
- 219. target.setTextColor(colors.lightBlue)
- 220. end
- 221. if volumeSide then
- 222. printVolume(display)
- 223. end
- 224.end
- 225.
- 226.--Finds if the radio is on the side of the computer and returns the correct side
- 227.local function findRadioSide()
- 228. local sides = {"left", "right", "bottom", "top", "front", "back"}
- 229. for k,v in ipairs(sides) do
- 230. if peripheral.getType(v) then
- 231. if string.match(peripheral.getType(v), "radio") then
- 232. return v
- 233. end
- 234. end
- 235. end
- 236. return false
- 237.end
- 238.
- 239.--Runs set up functions and prints info about the set up
- 240.local function setUp()
- 241. findPeripherals()
- 242. debugPrint("All necessary peripherals found.")
- 243. loadOptions()
- 244. getArgs()
- 245. if options.debug then
- 246. term.clear()
- 247. term.setCursorPos(1,1)
- 248. term.setTextColor(colors.green)
- 249. end
- 250. --If terminal mode is active or no monitor is found
- 251. if options.terminal or not display then
- 252. display = term
- 253. debugPrint("Terminal mode activated. Daemon mode and monitors inactive.")
- 254. else
- 255. options.monitor = true
- 256. end
- 257. --Last check if monitors/terminals are correct
- 258. if options.terminal and options.monitor then
- 259. error("Cannot run terminal and monitor modes simultaneously", 0)
- 260. end
- 261. initialEmpty()
- 262. if not diskTypeCheck() then
- 263. error("Must use openblocks tuned_crystal", 0)
- 264. end
- 265. radioDir, chestDir = findDirection()
- 266. debugPrint("Radio and Chest connection found.")
- 267. indexDisks()
- 268. debugPrint("Disks indexed. Found "..#disks.." disks.")
- 269. volumeSide = findRadioSide()
- 270. if volumeSide then
- 271. debugPrint("Volume control enabled")
- 272. else
- 273. term.setTextColor(colors.red)
- 274. debugPrint("Volume control disabled. Place radio next to computer to enable.")
- 275. term.setTextColor(colors.green)
- 276. end
- 277. mX, mY = display.getSize()
- 278. if not options.terminal then
- 279. if type(options.scale) == "number" then
- 280. debugPrint("Custom scale found.")
- 281. display.setTextScale(options.scale)
- 282. mX, mY = display.getSize()
- 283. elseif mX <= 18 then
- 284. debugPrint("Small monitor found, scale reduced. Enter custom scale to change.\nUsage: radio (scale)")
- 285. display.setTextScale(.5)
- 286. mX, mY = display.getSize()
- 287. end
- 288. end
- 289. if options.debug and options.terminal then
- 290. print("Radio starting in 5 seconds")
- 291. sleep(5)
- 292. end
- 293. display.clear()
- 294. display.setTextColor(colors.lightBlue)
- 295. drawOptions(display)
- 296. if volumeSide then
- 297. rs.setAnalogOutput(volumeSide, options.volume)
- 298. end
- 299.end
- 300.
- 301.--Runs the radio
- 302.local function radioMonitor()
- 303. while true do
- 304. local input = {os.pullEvent()}
- 305. if (options.monitor and input[1] == "monitor_touch" and input[2] == displayName) or (options.terminal and input[1] == "mouse_click") then
- 306. --Checks disk selection
- 307. if input[3] < mX-7 then
- 308. if input[4] <= #disks then
- 309. if current then
- 310. radio.pushItemIntoSlot(radioDir, 1, 1, diskLoc[current])
- 311. end
- 312. radio.pullItem(radioDir, input[4]-1+select)
- 313. current = disks[input[4]-1+select]
- 314. if volumeSide then
- 315. rs.setAnalogOutput(volumeSide, options.volume)
- 316. end
- 317. drawOptions(display)
- 318. end
- 319. --Checks volume selection
- 320. elseif input[3] < mX-2 then
- 321. if volumeSide then
- 322. if input[4] <= 2 then
- 323. if options.volume < 15 then
- 324. options.volume = options.volume + 1
- 325. rs.setAnalogOutput(volumeSide, options.volume)
- 326. printVolume(display)
- 327. end
- 328. elseif input[4] >= mY - 1 then
- 329. if options.volume > 1 then
- 330. options.volume = options.volume - 1
- 331. rs.setAnalogOutput(volumeSide, options.volume)
- 332. printVolume(display)
- 333. end
- 334. end
- 335. end
- 336. --Checks OFF selection
- 337. elseif input[4] <= math.ceil(mY/2)+1 and input[4] >= math.floor(mY/2) then
- 338. radio.pushItemIntoSlot(radioDir, 1, 1, diskLoc[current])
- 339. rs.setOutput("right", false)
- 340. current = nil
- 341. drawOptions(display)
- 342. --Checks for scrolling selection
- 343. elseif #disks > mY then
- 344. if input[4] >= mY-1 then
- 345. if select < mY-1 then
- 346. select = select+1
- 347. drawOptions(display)
- 348. end
- 349. elseif input[4] <= 2 then
- 350. if select > 1 then
- 351. select = select-1
- 352. drawOptions(display)
- 353. end
- 354. end
- 355. end
- 356. end
- 357. end
- 358.end
- 359.
- 360.--Runs the radio in the background
- 361.local function runDaemon()
- 362. term.clear()
- 363. term.setCursorPos(1, 1)
- 364. shell.run("shell")
- 365.end
- 366.
- 367.--Main Code
- 368.setUp()
- 369.if options.daemon then
- 370. parallel.waitForAny(runDaemon, radioMonitor)
- 371.else
- 372. radioMonitor()
- 373.end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement