Larvix

arenaControl-2

Nov 14th, 2024 (edited)
439
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.86 KB | None | 0 0
  1. --==VARIABLES==--
  2.  
  3. --Phrase to start trial
  4. startPhrase = "i accept the trial"
  5.  
  6. --modem
  7. modem = peripheral.find("modem")
  8. --monitor + window
  9. mon = peripheral.find("monitor")
  10. mon.clear()
  11. mon.setTextScale(1)
  12. mon.setBackgroundColor(colors.black)
  13. mon.setTextColor(colors.white)
  14. monX,monY = mon.getSize()
  15. win = window.create(mon,2,2,monX-2,monY-2,true)
  16.  
  17. --sensors
  18. sensors = {
  19. "manipulator_15",
  20. "manipulator_16",
  21. "manipulator_17",
  22. "manipulator_18"
  23. }
  24. --essence tank
  25. tank = peripheral.wrap("industrialforegoing:black_hole_tank_tile_9")
  26. --mob-tool / tape chest
  27. chestName = "projecte:alchemical_chest_1094"
  28. chest = peripheral.wrap(chestName)
  29. --tape drive
  30. tape = "tape_drive_17"
  31.  
  32. --block name for spawners
  33. blockName = "industrialforegoing:mob_duplicator_tile_"
  34. --spawner IDs, split into rings
  35. spawners = {
  36. -- Ring 1
  37.     {
  38.         "8",
  39.         "11",
  40.         "5",
  41.         "29",
  42.         "9",
  43.         "32",
  44.         "10",
  45.         "31"
  46.     },
  47. -- Ring 2
  48.     {
  49.         "14",
  50.         "17",
  51.         "7",
  52.         "30",
  53.         "15",
  54.         "18",
  55.         "16",
  56.         "20"
  57.     },
  58. -- Ring 3
  59.     {
  60.         "21",
  61.         "25",
  62.         "23",
  63.         "26",
  64.         "22",
  65.         "28",
  66.         "24",
  67.         "27"
  68.     }
  69. }
  70. --add block name to spawner IDs
  71. for ring,group in pairs(spawners) do
  72.     for spawner,id in pairs(group) do
  73.         spawners[ring][spawner] = blockName..id
  74.     end
  75. end
  76.  
  77. waves = {
  78.     [1] = {["Husk"] = 4},
  79.     [2] = {["quark:dweller"] = 4},
  80.     [3] = {["quark:ashen"] = 1,["Stray"] = 1},
  81.     [4] = {["WitherSkeleton"] = 2},
  82.     [5] = {["quark:ashen"] = 1,["Stray"] = 1},
  83.     [6] = {["WitherSkeleton"] = 2},
  84.     [7] = {["VindicationIllager"] = 2},
  85.     [8] = {["EvocationIllager"] = 1,["Witch"] = 1},
  86.     [9] = {["VindicationIllager"] = 2},
  87.     [10] = {["EvocationIllager"] = 1,["Witch"] = 1}
  88. }
  89.  
  90. function initVars()
  91. --mobs
  92. mobs = {
  93. ["Zombie"] = 0,
  94. ["ZombieVillager"] = 0,
  95. ["quark:dweller"] = 0,
  96. ["Husk"] = 0,
  97. ["PigZombie"] = 0,
  98. ["Skeleton"] = 0,
  99. ["Stray"] = 0,
  100. ["quark:ashen"] = 0,
  101. ["WitherSkeleton"] = 0,
  102. ["quark:foxhound"] = 0,
  103. ["Blaze"] = 0,
  104. ["Ghast"] = 0,
  105. ["Witch"] = 0,
  106. ["VindicationIllager"] = 0,
  107. ["EvocationIllager"] = 0,
  108. }
  109. --flags
  110. queue = {}
  111. alive = {}
  112. wave = 0
  113. player = nil
  114. time = 0
  115. scores = {{},{},{},{},{}}
  116. running = false
  117. end
  118. initVars()
  119.  
  120. --==FUNCTIONS==--
  121.  
  122. ----------------------------------------------------
  123. --functions for managing timers
  124.  
  125. function getTime()
  126.     h = os.date("%H")
  127.     m = os.date("%M")
  128.     s = os.date("%S")
  129.     return ((h*60*60)+(m*60)+s)
  130. end
  131.  
  132. function timeString(timeInt)
  133.     return string.format("%sm%ss", math.floor(timeInt/60),timeInt%60)
  134. end
  135.  
  136. ----------------------------------------------------
  137. --functions for given terminal/monitor/window object
  138.  
  139. --write text for given terminal/monitor/window object
  140. --takes string, x (or alignment) and y, and colours
  141. function advWrite(obj,str,x,y,fg,bg)
  142.     if fg then
  143.         ofg = obj.getTextColor()
  144.         obj.setTextColor(fg)
  145.     end
  146.     if bg then
  147.         obg = obj.getBackgroundColor()
  148.         obj.setBackgroundColor(bg)
  149.     end
  150.     maxX = obj.getSize()
  151.     if x == "c" then x = (1+maxX-#str)/2
  152.     elseif x == "r" then x = (1+maxX-#str) end
  153.  
  154.     obj.setCursorPos(x,y)
  155.     obj.write(str)
  156.  
  157.     if fg then obj.setTextColor(ofg) end
  158.     if bg then obj.setBackgroundColour(obg) end
  159. end
  160.  
  161. --colour for given terminal/monitor/window object
  162. --sets text and background simultaneously
  163. function setColour(obj,fg,bg)
  164.     if fg then obj.setTextColor(fg) end
  165.     if bg then obj.setBackgroundColor(bg) end
  166. end
  167.  
  168. function clearLine(obj,y)
  169.     obj.setCursorPos(1,y)
  170.     obj.clearLine()
  171. end
  172.  
  173. function monitorBorder()
  174. --draw monitor border
  175.     setColour(mon,colors.black,colors.gray)
  176.     for a = 1,monX do
  177.         if (a == 1) or (a == monX) then
  178.             advWrite(mon,string.char(7),a,1,colors.green,colors.black)
  179.             advWrite(mon,string.char(7),a,monY,colors.green,colors.black)
  180.         else
  181.             advWrite(mon,"-",a,1)
  182.             advWrite(mon,"-",a,monY)
  183.         end
  184.     end
  185.     for b = 2,monY-1 do
  186.         advWrite(mon,"|",1,b)
  187.         advWrite(mon,"|",monX,b)
  188.     end
  189.     setColour(mon,colors.white,colors.black)
  190. end
  191.  
  192. function displayScoreboard()
  193.     if fs.exists("scores") then
  194.         file = fs.open("scores","r")
  195.         scores = textutils.unserialise(file.readAll())
  196.         file.close()
  197.     else
  198.         file = fs.open("scores","w")
  199.         file.write(textutils.serialise(scores))
  200.     end
  201.    
  202.     win.clear()
  203.     advWrite(win,"Leaderboard:","c",2,colors.green,colors.gray)
  204.     for i = 1,5 do
  205.         if #scores[i] == 2 then
  206.             p = scores[i][1]
  207.             t = timeString(scores[i][2])
  208.         else
  209.             p = "#"
  210.             t = "#m#s"
  211.         end
  212.         clearLine(win,(2+(2*i)))
  213.         advWrite(win,string.format("%s. %s - %s",i,p,t),"c",(2+(2*i)),colors.orange)
  214.     end
  215. end
  216.  
  217. ----------------------------------------------------
  218. --main arena management functions
  219.  
  220. function initWave()
  221.     wave = wave + 1
  222.     modem.transmit(wave,100,"")
  223.     clearLine(win, 2)
  224.     advWrite(win,string.format("Wave %s",wave),"c",2,colors.green,colors.gray)
  225.     for w,exists in pairs(waves) do
  226.         if w == wave then
  227.             for m,c in pairs(exists) do
  228.                 mobs[m] = mobs[m] + c
  229.             end
  230.             if wave == 10 then running = false end
  231.         end
  232.     end
  233.     for mob,count in pairs(mobs) do
  234.         if count > 0 then
  235.             for _ = 1,count do
  236.                 table.insert(queue,mob)
  237.                 if not alive[mob] then
  238.                     alive[mob] = {}
  239.                 end
  240.             end
  241.         end
  242.     end
  243. end
  244.  
  245. function checkSpawned(mobQueued)
  246.         for _,sensorID in pairs(sensors) do
  247.             sensor = peripheral.wrap(sensorID)
  248.             for _,found in pairs(sensor.sense()) do
  249.                 if found.name == mobQueued then
  250.                     if #alive[mobQueued] > 0 then
  251.                     for _,mobID in pairs(alive[mobQueued]) do
  252.                         if found.id == mobID then
  253.                             mobExists = true
  254.                         end
  255.                     end
  256.                     end
  257.                     if not mobExists then
  258.                         table.insert(alive[mobQueued],found.id)
  259.                         return true
  260.                     end
  261.                 end
  262.                 if mobExists then mobExists = false end
  263.             end
  264.         end
  265.     return false
  266. end
  267.  
  268. function checkAlive(totalCount)
  269.     isAlive = false
  270.         for m,ids in pairs(alive) do
  271.             for n,id in pairs(ids) do
  272.                 for i,sensor in pairs(sensors) do
  273.                     if peripheral.wrap(sensor).getMetaByID(id) then
  274.                         isAlive = true
  275.                     end
  276.                 end
  277.                 if not isAlive then
  278.                     table.remove(alive[m],n)
  279.                 else
  280.                     isAlive = false
  281.                 end
  282.             end
  283.             if (#alive[m] + #queue) == 0 then
  284.                 alive[m] = nil
  285.             end
  286.             numAlive = 0
  287.             for _,ids in pairs(alive) do numAlive = numAlive + #ids end
  288.             waveProg = math.floor(((numAlive+#queue)/totalCount)*100)
  289.             if waveProg ~= lastCheck then
  290.                 modem.transmit(wave,waveProg,"")
  291.                 lastCheck = waveProg
  292.             end
  293.             if (numAlive + #queue) == 0 then waveOver = true end
  294.      end
  295.     return waveOver
  296. end
  297.  
  298. function checkPlayers(runOnce)
  299.     while (player and runOnce) or (player and running) do
  300.         playerAlive = false
  301.         for i,sensor in pairs(sensors) do
  302.             playerData = peripheral.wrap(sensor).getMetaByName(player)
  303.             if player and playerData then
  304.                 playerAlive = true
  305.                 if running then
  306.                     clearLine(win,1)
  307.                     hearts = (math.ceil(playerData.health))/2
  308.                     for i = 1,math.floor(hearts) do
  309.                         advWrite(win,string.char(3),i,1,colors.red)
  310.                     end
  311.                     if hearts ~= math.floor(hearts) then
  312.                         advWrite(win,string.char(7),math.ceil(hearts),1,colors.red)
  313.                     end
  314.                     if math.ceil(hearts) < 10 then
  315.                     for i = math.ceil(hearts)+1,10 do
  316.                         advWrite(win,string.char(7),i,1,colors.gray)
  317.                     end
  318.                     end
  319.                     advWrite(win,timeString(getTime()-sTime),"r",1,colors.orange)
  320.                 end
  321.             end
  322.         end
  323.         if not playerAlive then player = nil end
  324.         if runOnce then runOnce = false end
  325.     end
  326. end
  327.  
  328. function spawn(r,s,m)
  329.     tank.pushFluid(spawners[r][s],8000,"essence")
  330.     spawner = peripheral.wrap(spawners[r][s])
  331.     item = 0
  332.     for slot,_ in pairs(chest.list()) do
  333.         if string.match(chest.getItem(slot).getMetadata().displayName,m) then
  334.             item = slot
  335.             break
  336.         end
  337.     end
  338.     if not (item == 0) then
  339.         spawner.pullItems(chestName,item)
  340.         spawned = false
  341.         while not checkSpawned(m) do
  342.             sleep()
  343.         end
  344.         spawner.pushItems(chestName,7)
  345.     end
  346. end
  347.  
  348. function displayWave()
  349.         currentY = 3
  350.         for mob,count in pairs(mobs) do
  351.             if count > 0 then
  352.                 if alive[mob] then live = #alive[mob] else live = 0 end
  353.                 for _,m in pairs(queue) do
  354.                     if m == mob then live = live + 1 end
  355.                 end
  356.                 currentY = currentY + 1
  357.                 clearLine(win, currentY)
  358.                 if string.find(mob,":") then
  359.                     mobStr = string.sub(mob,string.find(mob,":")+1,#mob)
  360.                     mobStr = string.upper(string.sub(mobStr,1,1))..string.sub(mobStr,2,#mobStr)
  361.                 else mobStr = mob end
  362.                 advWrite(win,string.format("%s: %s/%s",mobStr,live,count),"c",currentY,colors.orange)
  363.             end
  364.         end
  365. end
  366.  
  367. function trial()
  368.     running = true
  369.     while running and player do
  370.     --initialise next wave
  371.     initWave()
  372.     --reset ring/spawner flag
  373.     cRing = 1
  374.     cSpwner = 0
  375.     --list all mobs in wave on monitor
  376.     currentY = 3
  377.     totalCount = 0
  378.     for mob,count in pairs(mobs) do
  379.         if count > 0 then
  380.             currentY = currentY + 1
  381.             clearLine(win, currentY)
  382.             if string.find(mob,":") then
  383.                 mobStr = string.sub(mob,string.find(mob,":")+1,#mob)
  384.                 mobStr = string.upper(string.sub(mobStr,1,1))..string.sub(mobStr,2,#mobStr)
  385.             else mobStr = mob end
  386.             advWrite(win,string.format("%s: %s/%s",mobStr,count,count),"c",currentY,colors.orange)
  387.         end
  388.         totalCount = totalCount + count
  389.     end
  390.     --for each mob queued
  391.     while ((#queue > 0) and player) do
  392.     mobQueued = queue[#queue]
  393.     --if ring full
  394.         if cSpwner == #spawners[cRing] then
  395.     --increment ring
  396.             cRing = cRing + 1
  397.     --reset spawner to start
  398.             cSpwner = 1
  399.         else
  400.     --otherwise increment spawner
  401.             cSpwner = cSpwner + 1
  402.         end
  403.     --spawn next mob in queue
  404.         spawn(cRing,cSpwner,mobQueued)
  405.     --check mobs still alive
  406.         checkAlive(totalCount)
  407.     --remove mob from queue
  408.         table.remove(queue,#queue)
  409.     --update monitor display
  410.         displayWave()
  411.     end
  412.     --check alive mobs until none
  413.     while ((not waveOver) and player) do
  414.         waveOver = checkAlive(totalCount)
  415.         displayWave()
  416.     end
  417.     waveOver=false
  418.     waveProg = ""
  419.     if player then
  420.         _,currentY = mon.getCursorPos()
  421.         advWrite(win,"Wave Cleared!","c",currentY+2)
  422.     --if trial still in progress
  423.         if running then
  424.     --pause 5 seconds before next wave
  425.             sleep(5)
  426.         end
  427.     end
  428.     win.clear()
  429.     end
  430. end
  431.  
  432. ----------------------------------------------------
  433.  
  434. --==RUNTIME==--
  435.  
  436. monitorBorder()
  437. displayScoreboard()
  438.  
  439. while true do
  440. --wait for chat message event
  441.     evt = {os.pullEvent("chat_message")}
  442.     player = string.sub(evt[2],3)
  443.     checkPlayers(true)
  444.     if ((string.match(string.lower(evt[3]),startPhrase)) and player) then
  445.     playerName = player
  446. --look through chest
  447.         for slot,item in pairs(chest.list()) do
  448. --find tape
  449.             if ((item.name == "computronics:tape") and (chest.getItemMeta(slot).media.label == "d&d Battle music (48000)")) then
  450. --give tape to drive
  451.                 chest.pushItems(tape,slot)
  452.             end
  453.         end
  454. --wait 5 seconds
  455.     sleep(5)
  456. --start trial if player still present
  457.     checkPlayers(true)
  458.     if player then
  459.         win.clear()
  460.         sTime = getTime()
  461.         parallel.waitForAll(trial,checkPlayers)
  462.     end
  463.     modem.transmit(1,1,"end")
  464.     chest.pullItems(tape,1)
  465.     if player then
  466.         time = getTime() - sTime
  467.         win.clear()
  468.         advWrite(win,"Trial Completed!","c",2)
  469.         advWrite(win,string.format("Time: %s",timeString(time)),"c",3)
  470.         sleep(5)
  471.         scoreExists = false
  472.         for i,v in pairs(scores) do
  473.             if #v == 2 then
  474.                 if v[1] == player and time < v[2] then
  475.                     table.remove(scores,i)
  476.                 elseif v[1] == player then
  477.                     scoreExists = true
  478.                 end
  479.             end
  480.         end
  481.         if not scoreExists then
  482.             for i,v in pairs(scores) do
  483.                 if #v == 2 then
  484.                     if v[2] > time then
  485.                         table.insert(scores,i,{player,time})
  486.                         break
  487.                     end
  488.                 else
  489.                     scores[i] = {player,time}
  490.                     break
  491.                 end
  492.             end
  493.             if #scores > 5 then
  494.                 table.remove(scores,6)
  495.             end
  496.         end
  497.     fs.delete("scores")
  498.     file = fs.open("scores","w")
  499.     file.write(textutils.serialise(scores))
  500.     file.close()
  501.     elseif wave > 0 then
  502.         advWrite(win,string.format("Trial failed by %s!", playerName),"c",2)
  503.         advWrite(win,string.format("Wave Reached: %s", wave),"c",3)
  504.     end
  505.     playerName = nil
  506.     end
  507.     initVars()
  508.     sleep(5)
  509.     win.clear()
  510.     displayScoreboard()
  511. end
Advertisement
Add Comment
Please, Sign In to add comment