Advertisement
Guest User

compucraft radio

a guest
Nov 27th, 2014
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.21 KB | None | 0 0
  1.  
  2. --Version 1.1.2
  3.  
  4.  
  5. 2.--Code by O'Reezy
  6.  
  7.  
  8. 3.
  9.  
  10.  
  11. 4.local helpString = [[Arguments: (in any order)
  12.  
  13.  
  14. 5.-t terminal mode (incompatible with monitor mode)
  15.  
  16.  
  17. 6.-d debug mode
  18.  
  19.  
  20. 7.-nd non-daemon mode
  21.  
  22.  
  23. 8.-m<side or name> specifies which monitor to use (no space) (incompatible with terminal mode)
  24.  
  25.  
  26. 9.-s<.5-5> sets scale of radio (no space) (not available for terminal)
  27.  
  28.  
  29. 10.-v<1-15> sets initial volume (no space)
  30.  
  31.  
  32. 11.
  33.  
  34.  
  35. 12.Example: radio -mmonitor_1 -s2
  36.  
  37.  
  38. 13.]]
  39.  
  40.  
  41. 14.
  42.  
  43.  
  44. 15.local radio, chest, display, displayName, radioDir, chestDir
  45.  
  46.  
  47. 16.local mX, mY
  48.  
  49.  
  50. 17.local disks = {}
  51.  
  52.  
  53. 18.local diskLoc = {}
  54.  
  55.  
  56. 19.local volumeSide
  57.  
  58.  
  59. 20.local tArgs = {...}
  60.  
  61.  
  62. 21.
  63.  
  64.  
  65. 22.--Wraps necessary peripherals to variables
  66.  
  67.  
  68. 23.local function findPeripherals()
  69.  
  70.  
  71. 24. local peripherals = peripheral.getNames()
  72.  
  73.  
  74. 25. for k,v in pairs(peripherals) do
  75.  
  76.  
  77. 26. if string.match(peripheral.getType(v), "radio") then
  78.  
  79.  
  80. 27. radio = peripheral.wrap(v)
  81.  
  82.  
  83. 28. elseif string.match(peripheral.getType(v), "chest") then
  84.  
  85.  
  86. 29. chest = peripheral.wrap(v)
  87.  
  88.  
  89. 30. elseif string.match(peripheral.getType(v), "monitor") then
  90.  
  91.  
  92. 31. display = peripheral.wrap(v)
  93.  
  94.  
  95. 32. displayName = v
  96.  
  97.  
  98. 33. end
  99.  
  100.  
  101. 34. end
  102.  
  103.  
  104. 35. --Errors if all necessary peripherals are not found
  105.  
  106.  
  107. 36. if not radio then
  108.  
  109.  
  110. 37. error("Radio peripheral not found", 0)
  111.  
  112.  
  113. 38. elseif not chest then
  114.  
  115.  
  116. 39. error("Chest peripheral not found", 0)
  117.  
  118.  
  119. 40. end
  120.  
  121.  
  122. 41.end
  123.  
  124.  
  125. 42.
  126.  
  127.  
  128. 43.--Table of possible arguments
  129.  
  130.  
  131. 44.local options = {
  132.  
  133.  
  134. 45. daemon = true;
  135.  
  136.  
  137. 46. terminal = false;
  138.  
  139.  
  140. 47. scale = false;
  141.  
  142.  
  143. 48. debug = false;
  144.  
  145.  
  146. 49. monitor = false;
  147.  
  148.  
  149. 50. volume = 4;
  150.  
  151.  
  152. 51.}
  153.  
  154.  
  155. 52.
  156.  
  157.  
  158. 53.local function saveOptions()
  159.  
  160.  
  161. 54. local config = fs.open(".radioConfig", "w")
  162.  
  163.  
  164. 55. config.write(textutils.serialize(options))
  165.  
  166.  
  167. 56. config.close()
  168.  
  169.  
  170. 57.end
  171.  
  172.  
  173. 58.
  174.  
  175.  
  176. 59.local function loadOptions()
  177.  
  178.  
  179. 60. if fs.exists(".radioConfig") then
  180.  
  181.  
  182. 61. local config = fs.open(".radioConfig", "r")
  183.  
  184.  
  185. 62. options = textutils.unserialize(config.readAll())
  186.  
  187.  
  188. 63. config.close()
  189.  
  190.  
  191. 64. end
  192.  
  193.  
  194. 65.end
  195.  
  196.  
  197. 66.
  198.  
  199.  
  200. 67.--Determines which arguments are used
  201.  
  202.  
  203. 68.local function getArgs()
  204.  
  205.  
  206. 69. local sides = {}
  207.  
  208.  
  209. 70. for k,v in pairs({rs.getSides}) do
  210.  
  211.  
  212. 71. sides[v] = true
  213.  
  214.  
  215. 72. end
  216.  
  217.  
  218. 73. for i= 1, #tArgs do
  219.  
  220.  
  221. 74. if tArgs[i] == "-nd" then
  222.  
  223.  
  224. 75. options.daemon = false
  225.  
  226.  
  227. 76. elseif tArgs[i] == "-t" then
  228.  
  229.  
  230. 77. options.terminal = true
  231.  
  232.  
  233. 78. options.daemon = false
  234.  
  235.  
  236. 79. elseif tArgs[i] == "-d" then
  237.  
  238.  
  239. 80. options.debug = true
  240.  
  241.  
  242. 81. options.daemon = false
  243.  
  244.  
  245. 82. elseif string.match(tArgs[i], "-s") then
  246.  
  247.  
  248. 83. options.scale = tonumber(string.match(tArgs[i], ".*", 3))
  249.  
  250.  
  251. 84. if options.scale < .5 or options.scale > 5 then
  252.  
  253.  
  254. 85. error("Scale must be (0.5-5.0)")
  255.  
  256.  
  257. 86. end
  258.  
  259.  
  260. 87. elseif string.match(tArgs[i], "-v") then
  261.  
  262.  
  263. 88. options.volume = tonumber(string.match(tArgs[i], "%d"))
  264.  
  265.  
  266. 89. if options.volume > 15 then
  267.  
  268.  
  269. 90. options.volume = 15
  270.  
  271.  
  272. 91. elseif options.volume < 1 then
  273.  
  274.  
  275. 92. options.volume = 1
  276.  
  277.  
  278. 93. end
  279.  
  280.  
  281. 94. elseif string.match(tArgs[i], "-m") then
  282.  
  283.  
  284. 95. local monFind = string.match(tArgs[i], ".*", 3)
  285.  
  286.  
  287. 96. if sides[monFind] or peripheral.getType(monFind) == "monitor" then
  288.  
  289.  
  290. 97. displayName = monFind
  291.  
  292.  
  293. 98. display = peripheral.wrap(monFind)
  294.  
  295.  
  296. 99. options.monitor = true
  297.  
  298.  
  299. 100. end
  300.  
  301.  
  302. 101. elseif tArgs[i] == "help" then
  303.  
  304.  
  305. 102. error(helpString, 0)
  306.  
  307.  
  308. 103. end
  309.  
  310.  
  311. 104. end
  312.  
  313.  
  314. 105. if #tArgs > 0 then
  315.  
  316.  
  317. 106. saveOptions()
  318.  
  319.  
  320. 107. end
  321.  
  322.  
  323. 108.end
  324.  
  325.  
  326. 109.
  327.  
  328.  
  329. 110.--Finds which directions the chest/radio are from each other
  330.  
  331.  
  332. 111.local function findDirection()
  333.  
  334.  
  335. 112. local dirs = {"north", "east", "up", "south", "west", "down"}
  336.  
  337.  
  338. 113. for i = 1,#dirs do
  339.  
  340.  
  341. 114. local t = {radio.pullItemIntoSlot(dirs[i], 1, 1, 1)}
  342.  
  343.  
  344. 115. if t[1] == 1 then
  345.  
  346.  
  347. 116. if i <= 3 then
  348.  
  349.  
  350. 117. radio.pushItemIntoSlot(dirs[i], 1, 1, 1)
  351.  
  352.  
  353. 118. return dirs[i], dirs[i+3]
  354.  
  355.  
  356. 119. elseif i >= 4 then
  357.  
  358.  
  359. 120. radio.pushItemIntoSlot(dirs[i], 1, 1, 1)
  360.  
  361.  
  362. 121. return dirs[i], dirs[i-3]
  363.  
  364.  
  365. 122. end
  366.  
  367.  
  368. 123. end
  369.  
  370.  
  371. 124. end
  372.  
  373.  
  374. 125. --Errors if the radio and chest are not next to each other
  375.  
  376.  
  377. 126. error("Radio and Chest must be touching", 0)
  378.  
  379.  
  380. 127.end
  381.  
  382.  
  383. 128.
  384.  
  385.  
  386. 129.--Creates a table and reverse table of disks available
  387.  
  388.  
  389. 130.local function indexDisks()
  390.  
  391.  
  392. 131. local t = chest.getAllStacks()
  393.  
  394.  
  395. 132. --Creates indexed tables of disks in chests
  396.  
  397.  
  398. 133. for k,v in pairs(t) do
  399.  
  400.  
  401. 134. disks[#disks+1] = t[k].name
  402.  
  403.  
  404. 135. end
  405.  
  406.  
  407. 136.
  408.  
  409.  
  410. 137. for k,v in pairs(disks) do
  411.  
  412.  
  413. 138. diskLoc[v] = k
  414.  
  415.  
  416. 139. end
  417.  
  418.  
  419. 140.end
  420.  
  421.  
  422. 141.
  423.  
  424.  
  425. 142.--Checks if correct disks are used
  426.  
  427.  
  428. 143.local function diskTypeCheck()
  429.  
  430.  
  431. 144. local t = chest.getStackInSlot(1)
  432.  
  433.  
  434. 145. if string.match(t.rawName, "tuned_crystal") then
  435.  
  436.  
  437. 146. return true
  438.  
  439.  
  440. 147. end
  441.  
  442.  
  443. 148. return false
  444.  
  445.  
  446. 149.end
  447.  
  448.  
  449. 150.
  450.  
  451.  
  452. 151.--Empties the radio if there is a disk already in it (necessary or findDirection will error)
  453.  
  454.  
  455. 152.local function initialEmpty()
  456.  
  457.  
  458. 153. local dirs = {"north", "east", "up", "south", "west", "down"}
  459.  
  460.  
  461. 154. if radio.getStackInSlot(1) then
  462.  
  463.  
  464. 155. if #chest.getAllStacks() < chest.getInventorySize() then
  465.  
  466.  
  467. 156. for k,v in ipairs(dirs) do
  468.  
  469.  
  470. 157. radio.pushItemIntoSlot(v, 1, 1, #chest.getAllStacks() + 1)
  471.  
  472.  
  473. 158. end
  474.  
  475.  
  476. 159. else
  477.  
  478.  
  479. 160. error("No room in chest for crystal.")
  480.  
  481.  
  482. 161. end
  483.  
  484.  
  485. 162. end
  486.  
  487.  
  488. 163.end
  489.  
  490.  
  491. 164.
  492.  
  493.  
  494. 165.local function debugPrint(string)
  495.  
  496.  
  497. 166. if options.debug then
  498.  
  499.  
  500. 167. print(string)
  501.  
  502.  
  503. 168. end
  504.  
  505.  
  506. 169.end
  507.  
  508.  
  509. 170.
  510.  
  511.  
  512. 171.--Prints the volume
  513.  
  514.  
  515. 172.local function printVolume(target)
  516.  
  517.  
  518. 173. target.setCursorPos(mX-5,1)
  519.  
  520.  
  521. 174. target.write("^")
  522.  
  523.  
  524. 175. target.setCursorPos(mX-6, math.ceil(mY/2))
  525.  
  526.  
  527. 176. if options.volume < 10 then
  528.  
  529.  
  530. 177. target.write(" ")
  531.  
  532.  
  533. 178. end
  534.  
  535.  
  536. 179. target.write(tostring(options.volume))
  537.  
  538.  
  539. 180. target.setCursorPos(mX-5,mY)
  540.  
  541.  
  542. 181. target.write("v")
  543.  
  544.  
  545. 182.end
  546.  
  547.  
  548. 183.
  549.  
  550.  
  551. 184.--Draws all options found
  552.  
  553.  
  554. 185.local select = 1
  555.  
  556.  
  557. 186.local function drawOptions(target)
  558.  
  559.  
  560. 187. local length = #disks
  561.  
  562.  
  563. 188. if mY < length then
  564.  
  565.  
  566. 189. length = mY
  567.  
  568.  
  569. 190. end
  570.  
  571.  
  572. 191. target.clear()
  573.  
  574.  
  575. 192. target.setCursorPos(1,1)
  576.  
  577.  
  578. 193. local x = 1
  579.  
  580.  
  581. 194. for i = select, length-1+select do
  582.  
  583.  
  584. 195. target.setCursorPos(1, x)
  585.  
  586.  
  587. 196. if disks[i] ~= current then
  588.  
  589.  
  590. 197. target.write(disks[i])
  591.  
  592.  
  593. 198. else
  594.  
  595.  
  596. 199. target.setTextColor(colors.green)
  597.  
  598.  
  599. 200. target.write(disks[i])
  600.  
  601.  
  602. 201. target.setTextColor(colors.lightBlue)
  603.  
  604.  
  605. 202. end
  606.  
  607.  
  608. 203. x = x+1
  609.  
  610.  
  611. 204. end
  612.  
  613.  
  614. 205. if mY < #disks then
  615.  
  616.  
  617. 206. target.setCursorPos(mX-1,1)
  618.  
  619.  
  620. 207. target.write("^")
  621.  
  622.  
  623. 208. target.setCursorPos(mX-1,mY)
  624.  
  625.  
  626. 209. target.write("v")
  627.  
  628.  
  629. 210. end
  630.  
  631.  
  632. 211. target.setCursorPos(mX-2, math.ceil(mY/2))
  633.  
  634.  
  635. 212. if radio.getStackInSlot(1) then
  636.  
  637.  
  638. 213. target.setTextColor(colors.green)
  639.  
  640.  
  641. 214. target.write(" ON")
  642.  
  643.  
  644. 215. target.setTextColor(colors.lightBlue)
  645.  
  646.  
  647. 216. else
  648.  
  649.  
  650. 217. target.setTextColor(colors.red)
  651.  
  652.  
  653. 218. target.write("OFF")
  654.  
  655.  
  656. 219. target.setTextColor(colors.lightBlue)
  657.  
  658.  
  659. 220. end
  660.  
  661.  
  662. 221. if volumeSide then
  663.  
  664.  
  665. 222. printVolume(display)
  666.  
  667.  
  668. 223. end
  669.  
  670.  
  671. 224.end
  672.  
  673.  
  674. 225.
  675.  
  676.  
  677. 226.--Finds if the radio is on the side of the computer and returns the correct side
  678.  
  679.  
  680. 227.local function findRadioSide()
  681.  
  682.  
  683. 228. local sides = {"left", "right", "bottom", "top", "front", "back"}
  684.  
  685.  
  686. 229. for k,v in ipairs(sides) do
  687.  
  688.  
  689. 230. if peripheral.getType(v) then
  690.  
  691.  
  692. 231. if string.match(peripheral.getType(v), "radio") then
  693.  
  694.  
  695. 232. return v
  696.  
  697.  
  698. 233. end
  699.  
  700.  
  701. 234. end
  702.  
  703.  
  704. 235. end
  705.  
  706.  
  707. 236. return false
  708.  
  709.  
  710. 237.end
  711.  
  712.  
  713. 238.
  714.  
  715.  
  716. 239.--Runs set up functions and prints info about the set up
  717.  
  718.  
  719. 240.local function setUp()
  720.  
  721.  
  722. 241. findPeripherals()
  723.  
  724.  
  725. 242. debugPrint("All necessary peripherals found.")
  726.  
  727.  
  728. 243. loadOptions()
  729.  
  730.  
  731. 244. getArgs()
  732.  
  733.  
  734. 245. if options.debug then
  735.  
  736.  
  737. 246. term.clear()
  738.  
  739.  
  740. 247. term.setCursorPos(1,1)
  741.  
  742.  
  743. 248. term.setTextColor(colors.green)
  744.  
  745.  
  746. 249. end
  747.  
  748.  
  749. 250. --If terminal mode is active or no monitor is found
  750.  
  751.  
  752. 251. if options.terminal or not display then
  753.  
  754.  
  755. 252. display = term
  756.  
  757.  
  758. 253. debugPrint("Terminal mode activated. Daemon mode and monitors inactive.")
  759.  
  760.  
  761. 254. else
  762.  
  763.  
  764. 255. options.monitor = true
  765.  
  766.  
  767. 256. end
  768.  
  769.  
  770. 257. --Last check if monitors/terminals are correct
  771.  
  772.  
  773. 258. if options.terminal and options.monitor then
  774.  
  775.  
  776. 259. error("Cannot run terminal and monitor modes simultaneously", 0)
  777.  
  778.  
  779. 260. end
  780.  
  781.  
  782. 261. initialEmpty()
  783.  
  784.  
  785. 262. if not diskTypeCheck() then
  786.  
  787.  
  788. 263. error("Must use openblocks tuned_crystal", 0)
  789.  
  790.  
  791. 264. end
  792.  
  793.  
  794. 265. radioDir, chestDir = findDirection()
  795.  
  796.  
  797. 266. debugPrint("Radio and Chest connection found.")
  798.  
  799.  
  800. 267. indexDisks()
  801.  
  802.  
  803. 268. debugPrint("Disks indexed. Found "..#disks.." disks.")
  804.  
  805.  
  806. 269. volumeSide = findRadioSide()
  807.  
  808.  
  809. 270. if volumeSide then
  810.  
  811.  
  812. 271. debugPrint("Volume control enabled")
  813.  
  814.  
  815. 272. else
  816.  
  817.  
  818. 273. term.setTextColor(colors.red)
  819.  
  820.  
  821. 274. debugPrint("Volume control disabled. Place radio next to computer to enable.")
  822.  
  823.  
  824. 275. term.setTextColor(colors.green)
  825.  
  826.  
  827. 276. end
  828.  
  829.  
  830. 277. mX, mY = display.getSize()
  831.  
  832.  
  833. 278. if not options.terminal then
  834.  
  835.  
  836. 279. if type(options.scale) == "number" then
  837.  
  838.  
  839. 280. debugPrint("Custom scale found.")
  840.  
  841.  
  842. 281. display.setTextScale(options.scale)
  843.  
  844.  
  845. 282. mX, mY = display.getSize()
  846.  
  847.  
  848. 283. elseif mX <= 18 then
  849.  
  850.  
  851. 284. debugPrint("Small monitor found, scale reduced. Enter custom scale to change.\nUsage: radio (scale)")
  852.  
  853.  
  854. 285. display.setTextScale(.5)
  855.  
  856.  
  857. 286. mX, mY = display.getSize()
  858.  
  859.  
  860. 287. end
  861.  
  862.  
  863. 288. end
  864.  
  865.  
  866. 289. if options.debug and options.terminal then
  867.  
  868.  
  869. 290. print("Radio starting in 5 seconds")
  870.  
  871.  
  872. 291. sleep(5)
  873.  
  874.  
  875. 292. end
  876.  
  877.  
  878. 293. display.clear()
  879.  
  880.  
  881. 294. display.setTextColor(colors.lightBlue)
  882.  
  883.  
  884. 295. drawOptions(display)
  885.  
  886.  
  887. 296. if volumeSide then
  888.  
  889.  
  890. 297. rs.setAnalogOutput(volumeSide, options.volume)
  891.  
  892.  
  893. 298. end
  894.  
  895.  
  896. 299.end
  897.  
  898.  
  899. 300.
  900.  
  901.  
  902. 301.--Runs the radio
  903.  
  904.  
  905. 302.local function radioMonitor()
  906.  
  907.  
  908. 303. while true do
  909.  
  910.  
  911. 304. local input = {os.pullEvent()}
  912.  
  913.  
  914. 305. if (options.monitor and input[1] == "monitor_touch" and input[2] == displayName) or (options.terminal and input[1] == "mouse_click") then
  915.  
  916.  
  917. 306. --Checks disk selection
  918.  
  919.  
  920. 307. if input[3] < mX-7 then
  921.  
  922.  
  923. 308. if input[4] <= #disks then
  924.  
  925.  
  926. 309. if current then
  927.  
  928.  
  929. 310. radio.pushItemIntoSlot(radioDir, 1, 1, diskLoc[current])
  930.  
  931.  
  932. 311. end
  933.  
  934.  
  935. 312. radio.pullItem(radioDir, input[4]-1+select)
  936.  
  937.  
  938. 313. current = disks[input[4]-1+select]
  939.  
  940.  
  941. 314. if volumeSide then
  942.  
  943.  
  944. 315. rs.setAnalogOutput(volumeSide, options.volume)
  945.  
  946.  
  947. 316. end
  948.  
  949.  
  950. 317. drawOptions(display)
  951.  
  952.  
  953. 318. end
  954.  
  955.  
  956. 319. --Checks volume selection
  957.  
  958.  
  959. 320. elseif input[3] < mX-2 then
  960.  
  961.  
  962. 321. if volumeSide then
  963.  
  964.  
  965. 322. if input[4] <= 2 then
  966.  
  967.  
  968. 323. if options.volume < 15 then
  969.  
  970.  
  971. 324. options.volume = options.volume + 1
  972.  
  973.  
  974. 325. rs.setAnalogOutput(volumeSide, options.volume)
  975.  
  976.  
  977. 326. printVolume(display)
  978.  
  979.  
  980. 327. end
  981.  
  982.  
  983. 328. elseif input[4] >= mY - 1 then
  984.  
  985.  
  986. 329. if options.volume > 1 then
  987.  
  988.  
  989. 330. options.volume = options.volume - 1
  990.  
  991.  
  992. 331. rs.setAnalogOutput(volumeSide, options.volume)
  993.  
  994.  
  995. 332. printVolume(display)
  996.  
  997.  
  998. 333. end
  999.  
  1000.  
  1001. 334. end
  1002.  
  1003.  
  1004. 335. end
  1005.  
  1006.  
  1007. 336. --Checks OFF selection
  1008.  
  1009.  
  1010. 337. elseif input[4] <= math.ceil(mY/2)+1 and input[4] >= math.floor(mY/2) then
  1011.  
  1012.  
  1013. 338. radio.pushItemIntoSlot(radioDir, 1, 1, diskLoc[current])
  1014.  
  1015.  
  1016. 339. rs.setOutput("right", false)
  1017.  
  1018.  
  1019. 340. current = nil
  1020.  
  1021.  
  1022. 341. drawOptions(display)
  1023.  
  1024.  
  1025. 342. --Checks for scrolling selection
  1026.  
  1027.  
  1028. 343. elseif #disks > mY then
  1029.  
  1030.  
  1031. 344. if input[4] >= mY-1 then
  1032.  
  1033.  
  1034. 345. if select < mY-1 then
  1035.  
  1036.  
  1037. 346. select = select+1
  1038.  
  1039.  
  1040. 347. drawOptions(display)
  1041.  
  1042.  
  1043. 348. end
  1044.  
  1045.  
  1046. 349. elseif input[4] <= 2 then
  1047.  
  1048.  
  1049. 350. if select > 1 then
  1050.  
  1051.  
  1052. 351. select = select-1
  1053.  
  1054.  
  1055. 352. drawOptions(display)
  1056.  
  1057.  
  1058. 353. end
  1059.  
  1060.  
  1061. 354. end
  1062.  
  1063.  
  1064. 355. end
  1065.  
  1066.  
  1067. 356. end
  1068.  
  1069.  
  1070. 357. end
  1071.  
  1072.  
  1073. 358.end
  1074.  
  1075.  
  1076. 359.
  1077.  
  1078.  
  1079. 360.--Runs the radio in the background
  1080.  
  1081.  
  1082. 361.local function runDaemon()
  1083.  
  1084.  
  1085. 362. term.clear()
  1086.  
  1087.  
  1088. 363. term.setCursorPos(1, 1)
  1089.  
  1090.  
  1091. 364. shell.run("shell")
  1092.  
  1093.  
  1094. 365.end
  1095.  
  1096.  
  1097. 366.
  1098.  
  1099.  
  1100. 367.--Main Code
  1101.  
  1102.  
  1103. 368.setUp()
  1104.  
  1105.  
  1106. 369.if options.daemon then
  1107.  
  1108.  
  1109. 370. parallel.waitForAny(runDaemon, radioMonitor)
  1110.  
  1111.  
  1112. 371.else
  1113.  
  1114.  
  1115. 372. radioMonitor()
  1116.  
  1117.  
  1118. 373.end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement