Advertisement
samuelask

Hiddengate Lab/bunker

Mar 29th, 2025 (edited)
495
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 17.95 KB | None | 0 0
  1. -- Script for Bunker Control
  2. local component = require("component")
  3. local thread = require("thread")
  4. local event = require("event")
  5. local term = require("term")
  6. local serialization = require("serialization")
  7. local reds = component.redstone
  8. local sides = require("sides")
  9. local colors = require("colors")
  10. local modem = component.modem
  11. local gpu = component.gpu
  12. local debug_card = component.debug
  13. local lastMessageId = nil
  14. relay_address = "c4c7c470-2df1-49a0-9199-af7af3cdc989"
  15. user = ""
  16. Local_Name = "Epsilon Site"
  17. Short_Name = "[Epsilon]"
  18. running = true
  19. decon = false
  20. -- Configuration
  21. beacon = true
  22. modem.open(123)
  23. local screenWidth, _ = gpu.getResolution()
  24.  
  25. local default_messages = {
  26.   {
  27.     from = "Omega Site",
  28.     shrt = "[Omega]",
  29.     user = "Unknown entity",
  30.     to = Local_Name,
  31.     header = "ComE",
  32.     message = "Join us, we lvie in hramony, the msnoetrs are gone, we cannot aecscc your wold,\nyou will cmoe to ouesr, cmoe cmoe, Alvin missse you all",
  33.     timestamp = 7
  34.   },
  35.   {
  36.     from = "Alpha Site",
  37.     shrt = "[ALERT]",
  38.     user = "Rosewood, Head of Security",
  39.     to = Local_Name,
  40.     header = "LOCKDOWN INITIATED",
  41.     message = "THIS IS NOT A DRILL, THIS IS NOT A DRILL, THIS IS NOT A DRILL\nALL SITES, COMMENCE Decontamination Procedure, COMMENCE LOCKDOWN.\nREAD REST OF MESSAGE WHEN COMPLETE!\n\nOmega site is unavailable, no one is answering. Lab 2 is the same.\nAlpha site received a wormhole from Omega site but no one got through!.\nWe cannot reach them since High Command is also unavailable.\nI have ordered an ALERT on all channels as proper procedure.\nPLEASE RESPOND IF YOU ARE READING THIS!.\nWe also have a power problem at Alpha site, today we were supposed to receive a new ZPM.\nAt limited usage we should be good for another month, but after that we need to evacuate.\nSince High Command is not available we cannot use our stargate, the Iris code is encrypted.\nRESPOND IMMEDIATELY if receiving this message!.",
  42.     timestamp = 6
  43.   },
  44.   {
  45.     from = "Laboratory 1",
  46.     shrt = "[Lab 1]",
  47.     user = "Jack, Shipment officer",
  48.     to = Local_Name,
  49.     header = "Missing Shipment",
  50.     message = "Im reaching you since i cant get a hold of Lab 2 myself, my security clearence isnt that high.\nWe were supposed to receive a shipment today but it never came. It was supposed to be delivered through the gate.\nIt does not say what it even is, so you can imagine my frustration.\nLet me know if you find it, i will report this incident to my higher ups, you should report it to High Command.",
  51.     timestamp = 5
  52.   },
  53.   {
  54.     from = "Laboratory 2",
  55.     shrt = "[Lab 2]",
  56.     user = "Doctor Greywall",
  57.     to = Local_Name,
  58.     header = "Lab results",
  59.     message = "We have dubbed it Alvin, from alvin and the chipmunks!\nAlvin has exceeded our expectations, he (or it rather) is a perfect creature. Able to adapt and reform his body at will.\nWe have feeded it live chipmunks and it immediately assumed its form as one! Before devouring them.\nIt has now grown, its the size of a human. Although i doubt it has the intelligence of one.\nIt also has this weird effect on life around it, it kinda dies, and reanimates into something different.\nWe had to increase the security zone around its holding area, my plants were dying because of it.\nWe will need to move it in the near future, to a more secure facility.\nI hear Lab 1 is getting a 20 billion dollar funding this year, lucky them.\nLet High Command know i will be terminating the rest of the eggs also, they have begun to smell.\nOh and that Lab 1 can take care of Alvin.",
  60.     timestamp = 4
  61.   },
  62.   {
  63.     from = "Omega Site",
  64.     shrt = "[Omega]",
  65.     user = "Bryan Haddoc",
  66.     to = Local_Name,
  67.     header = "Iris installed",
  68.     message = "As per requested the Iris is now operational, although we are abit sceptical that the code is classified.\nWhat if the settlers have family to visit?\nAlso it will become harder to receive supply, High command needs to approve everytime so they can shutdown the Iris!\nPlease forward these issues to High Command, its important for us.\nWe have also been seeing things here, things in the dark. I'm not the only one.\nDavid saw a GIANT spider yesterday, looked like it could eat a cat!.",
  69.     timestamp = 3
  70.   },
  71.   {
  72.     from = "High Command",
  73.     shrt = "[High cmd]",
  74.     user = "Secretary General Coldwell",
  75.     to = Local_Name,
  76.     header = "Increased activity READ ME",
  77.     message = "High Command has finished its assessment around the Omega site, new security measures are to be taken.\nThe local fauna has been increasing its hostility towards the site, where as before it was only curious of us, it is now our belief it has grown more hostile.\nNo doubt due to the experiments from Doctor Greywall in Lab 2.\nAn Iris to the gate at Omega site is to be installed at once! New intel suggests that there is currently a large scale operation\nunderway intended to sabotage the site, possibly even a takeover. Secure the gate, then take care of the wildlife surrounding the Omega site.\nWe dont want any surprises. Make sure that the Iris gate code is ONLY known by High Command.\n\nThe settlements beyond Omega is also now at greater risk.\nUntil we have a greater understanding of the local fauna, NO personnel is allowed to leave the Omega site.\nThe settlers can protect themselves, they are all armed after all.",
  78.     timestamp = 2
  79.   },
  80.   {
  81.     from = "Laboratory 2",
  82.     shrt = "[Lab 2]",
  83.     user = "Doctor Greywall",
  84.     to = Local_Name,
  85.     header = "Eggsacks",
  86.     message = "The eggsacks found on the planet Nibiru have produced results.\nWe have managed to create a hybrid of a vein floater along with local fauna found on the Omega site.\nSo far it has adapted to everything we have thrown at it,\nLava, shotguns, electrocutions, it seems to handle it all.\nThe staff is beginning to wonder what we should do if it breaks out.\nNot to worry, the lab is set to blow with a 100 Megaton warhead if it does, but I won't tell them that.\nAlso it has begun laying eggs on its own, expect more results sooner now rather than later.",
  87.     timestamp = 1
  88.   },
  89. }
  90.  
  91. function drawMessageBox(message_data)
  92.   local screenWidth, _ = gpu.getResolution()
  93.  
  94.   -- Prepare message lines
  95.   local lines = {
  96.     "New message received from " .. message_data.from,
  97.     "Subject: " .. message_data.shrt .. " " .. message_data.header,
  98.     "Message: " .. message_data.message,
  99.     "User: " .. message_data.user
  100.   }
  101.  
  102.   -- Determine max line length
  103.   local maxLength = 0
  104.   for _, line in ipairs(lines) do
  105.     if #line > maxLength then
  106.       maxLength = #line
  107.     end
  108.   end
  109.  
  110.   -- Box styling
  111.   local padding = 2
  112.   local boxWidth = maxLength + padding * 2
  113.   local boxHeight = #lines + 2 -- top + bottom border
  114.  
  115.   local startX = screenWidth - boxWidth + 1
  116.   local startY = 1
  117.  
  118.   -- Draw top border
  119.   gpu.set(startX, startY, "┌" .. string.rep("─", boxWidth - 2) .. "┐")
  120.  
  121.   -- Draw box sides and empty space
  122.   for i = 1, boxHeight - 2 do
  123.     gpu.set(startX, startY + i, "│" .. string.rep(" ", boxWidth - 2) .. "│")
  124.   end
  125.  
  126.   -- Draw bottom border
  127.   gpu.set(startX, startY + boxHeight - 1, "└" .. string.rep("─", boxWidth - 2) .. "┘")
  128.  
  129.   -- Write text inside the box
  130.   for i, line in ipairs(lines) do
  131.     gpu.set(startX + padding, startY + i, line)
  132.   end
  133. end
  134. -- UI Drawing Function
  135. local function draw_ui()
  136.     term.clear()
  137.     print("Bunker Control")
  138.     print("[SPACE] Toggle Emergency Beacon [" .. (beacon and "ON" or "OFF") .. "]")
  139.     print("[D] " .. (decon and "Run Decontamination Procedure [RUNNING]" or "Run Decontamination Procedure"))
  140.     print("[U] Update orders from high command")
  141.     print("[M] Messages")
  142.     print("[Q] Dial Omega Site")
  143.     print("[C] Charge Gate")
  144. end
  145.  
  146. -- UI Drawing Function messages
  147. local function draw_ui_messages()
  148.     term.clear()
  149.     print("Messages")
  150.     print("[R] Read messages")
  151.     print("[S] Send message")
  152.     print("[E] Exit")
  153. end
  154.  
  155. -- Function to send commands
  156. local function send_command(address, value, header)
  157.  
  158.   local data = {
  159.     from = Local_Name,
  160.     shrt = Short_Name,
  161.     user = user,
  162.     to = address,
  163.     header = header,
  164.     message = value,
  165.     timestamp = os.time()
  166.   }
  167.     local serialized_data = serialization.serialize(data)
  168.     modem.send(relay_address, 123, serialized_data)
  169. end
  170.  
  171. local function read_message()
  172.   local path = "/messages.dat"
  173.   local file = io.open(path, "r")
  174.   if not file then
  175.     print("No messages found.")
  176.     os.sleep(2)
  177.     return
  178.   end
  179.  
  180.   local content = file:read("*a")
  181.   file:close()
  182.  
  183.   local messages = serialization.unserialize(content)
  184.  
  185.   if not messages or #messages == 0 then
  186.     print("Inbox empty.")
  187.     os.sleep(2)
  188.     return
  189.   end
  190.  
  191.   -- Sort by timestamp descending (newest first)
  192.   table.sort(messages, function(a, b)
  193.     return tonumber(a.timestamp) > tonumber(b.timestamp)
  194.   end)
  195.  
  196.   while true do
  197.     term.clear()
  198.     print("Inbox")
  199.     print("︱NEWEST︱")
  200.  
  201.     for i, msg in ipairs(messages) do
  202.       print(string.format("[%d] ︱ %s %s ︱", i, msg.shrt or "", msg.header or ""))
  203.     end
  204.  
  205.     print("︱OLDEST︱")
  206.     print("")
  207.     print("[E] Exit")
  208.     local answer = io.read()
  209.  
  210.     if answer == "e" or answer == "E" then
  211.       break
  212.     else
  213.       local index = tonumber(answer)
  214.       if index and messages[index] then
  215.         local msg = messages[index]
  216.         term.clear()
  217.         print(string.format("︱ %s %s ︱", msg.shrt or "", msg.header or ""))
  218.         print("")
  219.         print(msg.message or "")
  220.         print("")
  221.         print(msg.user or "Unknown sender")
  222.         print("")
  223.         print("[E] Exit")
  224.         local _ = io.read()
  225.       end
  226.     end
  227.   end
  228. end
  229.  
  230. -- Function to send messages
  231. local function send_message()
  232.     ::continue1::
  233.     term.clear()
  234.     print("Pick receiver")
  235.     print("[1] High Command")
  236.     print("[2] Laboratory 1")
  237.     print("[3] Laboratory 2")
  238.     print("[4] Omega Site")
  239.     print("[E] Exit")
  240.     local answer = io.read()
  241.     if answer == "1" then
  242.         send_to = "High Command"
  243.         term.clear()
  244.         print("High Command Confirmed, please type the subject of your message and press enter")
  245.         print("")
  246.         local header = io.read()
  247.         term.clear()
  248.         print("Subject: " .. header)
  249.         print("")
  250.         print("Please type your message")
  251.         print("")
  252.         local message = io.read()
  253.         term.clear()
  254.         print("From: " .. Local_Name)
  255.         print("Subject: " .. header)
  256.         print("Message: " .. message)
  257.         print("")
  258.         print("Do you want to send this message to ".. send_to .."?")
  259.         io.write("Y/n: ")
  260.         local answer = io.read()
  261.         if answer == "Y" or answer == "y" then
  262.             send_command(send_to, message, header)
  263.         end
  264.         term.clear()
  265.         goto continue1
  266.     elseif answer == "2" then
  267.         send_to = "Laboratory 1"
  268.         term.clear()
  269.         print("Laboratory 1 Confirmed, please type the subject of your message and press enter")
  270.         print("")
  271.         local header = io.read()
  272.         term.clear()
  273.         print("Subject: " .. header)
  274.         print("")
  275.         print("Please type your message")
  276.         print("")
  277.         local message = io.read()
  278.         term.clear()
  279.         print("From: " .. Local_Name)
  280.         print("Subject: " .. header)
  281.         print("Message: " .. message)
  282.         print("")
  283.         print("Do you want to send this message to ".. send_to .."?")
  284.         io.write("Y/n: ")
  285.         local answer = io.read()
  286.         if answer == "Y" or answer == "y" then
  287.             send_command(send_to, message, header)
  288.         end
  289.         term.clear()
  290.         goto continue1
  291.     elseif answer == "3" then
  292.         send_to = "Laboratory 2"
  293.         term.clear()
  294.         print("Laboratory 2 Confirmed, please type the subject of your message and press enter")
  295.         print("")
  296.         local header = io.read()
  297.         term.clear()
  298.         print("Subject: " .. header)
  299.         print("")
  300.         print("Please type your message")
  301.         print("")
  302.         local message = io.read()
  303.         term.clear()
  304.         print("From: " .. Local_Name)
  305.         print("Subject: " .. header)
  306.         print("Message: " .. message)
  307.         print("")
  308.         print("Do you want to send this message to ".. send_to .."?")
  309.         io.write("Y/n: ")
  310.         local answer = io.read()
  311.         if answer == "Y" or answer == "y" then
  312.             send_command(send_to, message, header)
  313.         end
  314.         term.clear()
  315.         goto continue1
  316.     elseif answer == "4" then
  317.         send_to = "Omega Site"
  318.         term.clear()
  319.         print("Omega Site Confirmed, please type the subject of your message and press enter.")
  320.         print("")
  321.         local header = io.read()
  322.         term.clear()
  323.         print("Subject: " .. header)
  324.         print("")
  325.         print("Please type your message")
  326.         print("")
  327.         local message = io.read()
  328.         term.clear()
  329.         print("From: " .. Local_Name)
  330.         print("Subject: " .. header)
  331.         print("Message: " .. message)
  332.         print("")
  333.         print("Do you want to send this message to ".. send_to .."?")
  334.         io.write("Y/n: ")
  335.         local answer = io.read()
  336.         if answer == "Y" or answer == "y" then
  337.             send_command(send_to, message, header)
  338.         end
  339.         term.clear()
  340.         goto continue1
  341.     elseif answer == "e" or answer == "E" then
  342.    
  343.     else
  344.         goto continue1
  345.     end
  346. end
  347. local function init_message_file()
  348.   local path = "/messages.dat"
  349.   local f = io.open(path, "r")
  350.   if not f then
  351.     -- Save default messages to file
  352.     local file = io.open(path, "w")
  353.     if file then
  354.       file:write(serialization.serialize(default_messages))
  355.       file:close()
  356.     end
  357.   else
  358.     f:close()
  359.   end
  360. end
  361. local function save_message(message_data)
  362.   local filepath = "/messages.dat"
  363.   local messages = {}
  364.  
  365.   -- Load existing messages if file exists
  366.   local file = io.open(filepath, "r")
  367.   if file then
  368.     local content = file:read("*a")
  369.     file:close()
  370.     if content and #content > 0 then
  371.       messages = serialization.unserialize(content) or {}
  372.     end
  373.   end
  374.  
  375.   -- Add new message
  376.   table.insert(messages, message_data)
  377.  
  378.   -- Sort by timestamp
  379.   table.sort(messages, function(a, b)
  380.     return a.timestamp < b.timestamp
  381.   end)
  382.  
  383.   -- Save updated messages back to file
  384.   file = io.open(filepath, "w")
  385.   if file then
  386.     file:write(serialization.serialize(messages))
  387.     file:close()
  388.   end
  389. end
  390. local function handle_modem_message(_, _, from, port, _, message, data)
  391.     if port == 123 then
  392.         if message == "error" then
  393.             print("")
  394.             print("[ERROR] " .. data)
  395.         elseif message == "sent_message" then
  396.             print("")
  397.             print("Sent message to " .. data)
  398.         elseif message == "new_message" then
  399.             local message_data = serialization.unserialize(data)
  400.             if message_data.timestamp ~= lastMessageId then
  401.                 lastMessageId = message_data.timestamp
  402.                 drawMessageBox(message_data)
  403.                 save_message(message_data)
  404.             end
  405.         end
  406.     end
  407. end
  408. if reds.getBundledOutput(sides.bottom, colors.black) > 0 then
  409.     reds.setBundledOutput(sides.bottom, colors.black, 0)
  410. end
  411. function drawChargingProgress()
  412.   local screenWidth, screenHeight = gpu.getResolution()
  413.   local label = "Charging Gate..."
  414.   local labelX = math.floor((screenWidth - #label) / 2) + 1
  415.   local labelY = math.floor(screenHeight / 2)
  416.  
  417.   -- Progress bar settings
  418.   local barWidth = 30
  419.   local barX = math.floor((screenWidth - barWidth) / 2) + 1
  420.   local barY = labelY + 2
  421.   local totalTime = 34 -- seconds
  422.   local updateRate = 0.1 -- how often to update in seconds
  423.   local steps = math.floor(totalTime / updateRate)
  424.  
  425.   -- Clear label and bar area
  426.   for i = 0, 3 do
  427.     gpu.set(1, labelY + i, string.rep(" ", screenWidth))
  428.   end
  429.  
  430.   -- Draw label
  431.   gpu.set(labelX, labelY, label)
  432.  
  433.   -- Progress bar loop
  434.   for i = 0, steps do
  435.     local filled = math.floor((i / steps) * barWidth)
  436.     local empty = barWidth - filled
  437.     gpu.set(barX, barY, "[" .. string.rep("█", filled) .. string.rep(" ", empty) .. "]")
  438.     os.sleep(updateRate)
  439.   end
  440. end
  441. local function chargegate()
  442.     reds.setBundledOutput(sides.bottom, colors.purple, 255)
  443.     os.sleep(1)
  444.     reds.setBundledOutput(sides.bottom, colors.purple, 0)
  445.     reds.setBundledOutput(sides.bottom, colors.pink, 255)
  446.     drawChargingProgress()
  447.     os.sleep(3)
  448.     reds.setBundledOutput(sides.bottom, colors.pink, 0)
  449. end
  450. -- Keyboard Input Listener
  451. local function key_listener(_, _, char, code, playerName)
  452.     local key = string.char(char)
  453.     user = playerName
  454.     event.ignore("key_down", key_listener)
  455.     if key == "u" then
  456.             term.clear()
  457.             print("Connecting to central network...")
  458.             os.sleep(3)
  459.             print("[ERROR] No connection")
  460.             os.sleep(0.5)
  461.             print("[ERROR] Diagnosing...")
  462.             os.sleep(3)
  463.             print("[✔] Receiver [ONLINE]")
  464.             print("[✔] Transmitter [ONLINE]")
  465.             print("[ERROR] High Command blocked or not responding")
  466.             print("[⚠] Can not receive orders!")
  467.             print("")
  468.             print("Please follow standard Emergency Procedures")
  469.             os.sleep(8)
  470.             draw_ui()
  471.     elseif key == "d" then
  472.             if decon then
  473.                 print("Cannot stop Decontamination Procedure")
  474.             elseif not decon then
  475.                 decon = not decon
  476.                 draw_ui()
  477.                 debug_card.runCommand("/effect @e[x=15019,y=40,z=12603,dx=57,dy=13,dz=57] minecraft:poison 10 3")
  478.                 os.sleep(10)
  479.                 decon = not decon
  480.                 draw_ui()
  481.                 print("Decontamination Procedure Complete!")
  482.             end
  483.     elseif key == "q" then
  484.             reds.setBundledOutput(sides.bottom, colors.black, 255)
  485.             draw_ui()
  486.             print("")
  487.             print("Dialing Omega Site!")
  488.             os.sleep(2)
  489.             reds.setBundledOutput(sides.bottom, colors.black, 0)
  490.     elseif code == 57 then
  491.         if beacon then
  492.             print("Confirm Beacon Shutdown")
  493.             io.write("Y/n: ")
  494.             local answer = io.read()
  495.             if answer == "y" or answer == "Y" then
  496.                 beacon = not beacon
  497.                 print("Confirmed")
  498.                 os.sleep(3)
  499.                 draw_ui()
  500.             else
  501.                 print("Aborted!")
  502.                 os.sleep(3)
  503.                 draw_ui()
  504.             end
  505.         elseif not beacon then
  506.             beacon = not beacon
  507.             draw_ui()
  508.             print("Emergency Beacon Online!")
  509.         end
  510.     elseif key == "m" then
  511.         ::continue::
  512.         draw_ui_messages()
  513.         local answer = io.read()
  514.         if answer == "r" or answer == "R" then
  515.             read_message()
  516.             goto continue
  517.         elseif answer == "s" or answer == "S" then
  518.             send_message()
  519.             goto continue
  520.         elseif answer == "e" or answer == "E" then
  521.             draw_ui()
  522.         else
  523.             goto continue
  524.         end
  525.     elseif key == "c" then
  526.         chargegate()
  527.         draw_ui()
  528.     end
  529.     event.listen("key_down", key_listener)
  530. end
  531. draw_ui()
  532. init_message_file()
  533. messages = event.listen("modem_message", handle_modem_message)
  534. event.listen("key_down", key_listener)
  535.  
  536. while running do
  537.     os.sleep(0.5)
  538. end
  539.  
  540. os.sleep(1)
  541. os.exit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement