diff --git a/code/_global_vars/lists/misc.dm b/code/_global_vars/lists/misc.dm index adec2bf824..e02c99290c 100644 --- a/code/_global_vars/lists/misc.dm +++ b/code/_global_vars/lists/misc.dm @@ -2,4 +2,7 @@ GLOBAL_LIST_INIT(speech_toppings, list("|" = "i", "+" = "b", "_" = "u")) GLOBAL_LIST_EMPTY(meteor_list) /// List of wire colors for each object type of that round. One for airlocks, one for vendors, etc. -GLOBAL_LIST_EMPTY(wire_color_directory) // This is an associative list with the `holder_type` as the key, and a list of colors as the value. \ No newline at end of file +GLOBAL_LIST_EMPTY(wire_color_directory) // This is an associative list with the `holder_type` as the key, and a list of colors as the value. + +// Reference list for disposal sort junctions. Filled up by sorting junction's New() +GLOBAL_LIST_EMPTY(tagger_locations) \ No newline at end of file diff --git a/code/_helpers/text.dm b/code/_helpers/text.dm index 1b028e117b..669cc60b5b 100644 --- a/code/_helpers/text.dm +++ b/code/_helpers/text.dm @@ -453,4 +453,22 @@ proc/TextPreview(var/string,var/len=40) . += .(rest) -#define gender2text(gender) capitalize(gender) \ No newline at end of file +#define gender2text(gender) capitalize(gender) + +/// Used to get a properly sanitized input, of max_length +/// no_trim is self explanatory but it prevents the input from being trimed if you intend to parse newlines or whitespace. +/proc/stripped_input(mob/user, message = "", title = "", default = "", max_length=MAX_MESSAGE_LEN, no_trim=FALSE) + var/name = input(user, message, title, default) as text|null + + if(no_trim) + return copytext(html_encode(name), 1, max_length) + else + return trim(html_encode(name), max_length) //trim is "outside" because html_encode can expand single symbols into multiple symbols (such as turning < into <) + +// Used to get a properly sanitized multiline input, of max_length +/proc/stripped_multiline_input(mob/user, message = "", title = "", default = "", max_length=MAX_MESSAGE_LEN, no_trim=FALSE) + var/name = input(user, message, title, default) as message|null + if(no_trim) + return copytext(html_encode(name), 1, max_length) + else + return trim(html_encode(name), max_length) diff --git a/code/game/machinery/computer/supply.dm b/code/game/machinery/computer/supply.dm index a310b33f78..6a6fd60703 100644 --- a/code/game/machinery/computer/supply.dm +++ b/code/game/machinery/computer/supply.dm @@ -36,7 +36,7 @@ if(!allowed(user)) return user.set_machine(src) - ui_interact(user) + tgui_interact(user) return /obj/machinery/computer/supplycomp/emag_act(var/remaining_charges, var/mob/user) @@ -44,24 +44,27 @@ to_chat(user, "Special supplies unlocked.") authorization |= SUP_CONTRABAND req_access = list() + can_order_contraband = TRUE return 1 +// TGUI +/obj/machinery/computer/supplycomp/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "SupplyConsole", name) + ui.open() - -/obj/machinery/computer/supplycomp/ui_interact(mob/user, ui_key = "supply_records", var/datum/nanoui/ui = null, var/force_open = 1, var/key_state = null) - var/data[0] - var/shuttle_status[0] // Supply shuttle status - var/pack_list[0] // List of supply packs within the active_category - var/orders[0] - var/receipts[0] +/obj/machinery/computer/supplycomp/tgui_data(mob/user) + var/list/data = ..() + var/list/shuttle_status = list() var/datum/shuttle/autodock/ferry/supply/shuttle = SSsupply.shuttle if(shuttle) if(shuttle.has_arrive_time()) shuttle_status["location"] = "In transit" shuttle_status["mode"] = SUP_SHUTTLE_TRANSIT - shuttle_status["time"] = shuttle.eta_minutes() + shuttle_status["time"] = shuttle.eta_seconds() else shuttle_status["time"] = 0 @@ -107,149 +110,192 @@ shuttle_status["engine"] = "Engaged" else - shuttle["mode"] = SUP_SHUTTLE_ERROR - - for(var/pack_name in SSsupply.supply_pack) - var/datum/supply_pack/P = SSsupply.supply_pack[pack_name] - if(P.group == active_category) - var/list/pack = list( - "name" = P.name, - "cost" = P.cost, - "contraband" = P.contraband, - "manifest" = uniquelist(P.manifest), - "random" = P.num_contained, - "expand" = 0, - "ref" = "\ref[P]" - ) - - if(P in expanded_packs) - pack["expand"] = 1 - - pack_list[++pack_list.len] = pack + shuttle_status["mode"] = SUP_SHUTTLE_ERROR // Compile user-side orders // Status determines which menus the entry will display in // Organized in field-entry list for iterative display // List is nested so both the list of orders, and the list of elements in each order, can be iterated over + var/list/orders = list() for(var/datum/supply_order/S in SSsupply.order_history) - orders[++orders.len] = list( - "ref" = "\ref[S]", - "status" = S.status, - "entries" = list( - list("field" = "Supply Pack", "entry" = S.name), - list("field" = "Cost", "entry" = S.cost), - list("field" = "Index", "entry" = S.index), - list("field" = "Reason", "entry" = S.comment), - list("field" = "Ordered by", "entry" = S.ordered_by), - list("field" = "Ordered at", "entry" = S.ordered_at), - list("field" = "Approved by", "entry" = S.approved_by), - list("field" = "Approved at", "entry" = S.approved_at) - ) - ) + orders.Add(list(list( + "ref" = "\ref[S]", + "status" = S.status, + "cost" = S.cost, + "entries" = list( + list("field" = "Supply Pack", "entry" = S.name), + list("field" = "Cost", "entry" = S.cost), + list("field" = "Index", "entry" = S.index), + list("field" = "Reason", "entry" = S.comment), + list("field" = "Ordered by", "entry" = S.ordered_by), + list("field" = "Ordered at", "entry" = S.ordered_at), + list("field" = "Approved by", "entry" = S.approved_by), + list("field" = "Approved at", "entry" = S.approved_at) + ) + ))) // Compile exported crates + var/list/receipts = list() for(var/datum/exported_crate/E in SSsupply.exported_crates) - receipts[++receipts.len] = list( - "ref" = "\ref[E]", - "contents" = E.contents, - "error" = E.contents["error"], - "title" = list( - list("field" = "Name", "entry" = E.name), - list("field" = "Value", "entry" = E.value) - ) + receipts.Add(list(list( + "ref" = "\ref[E]", + "contents" = E.contents, + "error" = E.contents["error"], + "title" = list( + list("field" = "Name", "entry" = E.name), + list("field" = "Value", "entry" = E.value) ) + ))) - data["user"] = "\ref[user]" - data["currentTab"] = menu_tab // Communicator compatibility, controls which menu is in use data["shuttle_auth"] = (authorization & SUP_SEND_SHUTTLE) // Whether this ui is permitted to control the supply shuttle data["order_auth"] = (authorization & SUP_ACCEPT_ORDERS) // Whether this ui is permitted to accept/deny requested orders data["shuttle"] = shuttle_status data["supply_points"] = SSsupply.points - data["categories"] = all_supply_groups - data["active_category"] = active_category - data["supply_packs"] = pack_list data["orders"] = orders data["receipts"] = receipts data["contraband"] = can_order_contraband || (authorization & SUP_CONTRABAND) + data["modal"] = tgui_modal_data(src) + return data - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "supply_records.tmpl", "Supply Console", 475, 700, state = key_state) - // when the ui is first opened this is the data it will use - ui.set_initial_data(data) - // open the new ui window - ui.open() - // auto update every 20 Master Controller tick - ui.set_auto_update(20) // Longer term to reduce the rate of data collection and processing +/obj/machinery/computer/supplycomp/tgui_static_data(mob/user) + var/list/data = ..() + + var/list/pack_list = list() + for(var/pack_name in SSsupply.supply_pack) + var/datum/supply_pack/P = SSsupply.supply_pack[pack_name] + var/list/pack = list( + "name" = P.name, + "cost" = P.cost, + "group" = P.group, + "contraband" = P.contraband, + "manifest" = uniquelist(P.manifest), + "random" = P.num_contained, + "ref" = "\ref[P]" + ) + pack_list.Add(list(pack)) + data["supply_packs"] = pack_list + data["categories"] = all_supply_groups + return data - - -/obj/machinery/computer/supplycomp/Topic(href, href_list) - if(!SSsupply) - to_world_log("## ERROR: The SSsupply datum is missing.") - return - var/datum/shuttle/autodock/ferry/supply/shuttle = SSsupply.shuttle - if (!shuttle) - to_world_log("## ERROR: The supply shuttle datum is missing.") - return +/obj/machinery/computer/supplycomp/tgui_act(action, params) if(..()) - return 1 + return TRUE + if(!SSsupply) + log_runtime(EXCEPTION("## ERROR: The SSsupply datum is missing.")) + return TRUE + var/datum/shuttle/autodock/ferry/supply/shuttle = SSsupply.shuttle + if(!shuttle) + log_runtime(EXCEPTION("## ERROR: The supply shuttle datum is missing.")) + return TRUE - if(isturf(loc) && ( in_range(src, usr) || istype(usr, /mob/living/silicon) ) ) - usr.set_machine(src) + if(tgui_modal_act(src, action, params)) + return TRUE - // NEW TOPIC + switch(action) + if("view_crate") + var/datum/supply_pack/P = locate(params["crate"]) + if(!istype(P)) + return FALSE + var/list/payload = list( + "name" = P.name, + "cost" = P.cost, + "manifest" = uniquelist(P.manifest), + "ref" = "\ref[P]", + "random" = P.num_contained, + ) + tgui_modal_message(src, action, "", null, payload) + . = TRUE + if("request_crate_multi") + var/datum/supply_pack/S = locate(params["ref"]) - // Switch menu - if(href_list["switch_tab"]) - menu_tab = href_list["switch_tab"] + // Invalid ref + if(!istype(S)) + return FALSE - if(href_list["active_category"]) - active_category = href_list["active_category"] - - if(href_list["pack_ref"]) - var/datum/supply_pack/S = locate(href_list["pack_ref"]) - - // Invalid ref - if(!istype(S)) - return - - // Expand the supply pack's contents - if(href_list["expand"]) - expanded_packs ^= S - - // Make a request for the pack - if(href_list["request"]) - var/mob/user = locate(href_list["user"]) - if(!istype(user)) // Invalid ref - return + if(S.contraband && !(authorization & SUP_CONTRABAND || can_order_contraband)) + return FALSE if(world.time < reqtime) visible_message("[src]'s monitor flashes, \"[reqtime - world.time] seconds remaining until another requisition form may be printed.\"") - return + return FALSE + + var/amount = clamp(input(usr, "How many crates? (0 to 20)") as num|null, 0, 20) + if(!amount) + return FALSE var/timeout = world.time + 600 - var/reason = sanitize(input(user, "Reason:","Why do you require this item?","") as null|text) + var/reason = sanitize(input(usr, "Reason:","Why do you require this item?","") as null|text) if(world.time > timeout) - to_chat(user, "Error. Request timed out.") - return + to_chat(usr, "Error. Request timed out.") + return FALSE if(!reason) - return + return FALSE - SSsupply.create_order(S, user, reason) + for(var/i in 1 to amount) + SSsupply.create_order(S, usr, reason) var/idname = "*None Provided*" var/idrank = "*None Provided*" - if(ishuman(user)) - var/mob/living/carbon/human/H = user + if(ishuman(usr)) + var/mob/living/carbon/human/H = usr idname = H.get_authentification_name() idrank = H.get_assignment() - else if(issilicon(user)) - idname = user.real_name + else if(issilicon(usr)) + idname = usr.real_name + idrank = "Stationbound synthetic" + + var/obj/item/weapon/paper/reqform = new /obj/item/weapon/paper(loc) + reqform.name = "Requisition Form - [S.name]" + reqform.info += "

[station_name()] Supply Requisition Form


" + reqform.info += "INDEX: #[SSsupply.ordernum]
" + reqform.info += "REQUESTED BY: [idname]
" + reqform.info += "RANK: [idrank]
" + reqform.info += "REASON: [reason]
" + reqform.info += "SUPPLY CRATE TYPE: [S.name]
" + reqform.info += "ACCESS RESTRICTION: [get_access_desc(S.access)]
" + reqform.info += "AMOUNT: [amount]
" + reqform.info += "CONTENTS:
" + reqform.info += S.get_html_manifest() + reqform.info += "
" + reqform.info += "STAMP BELOW TO APPROVE THIS REQUISITION:
" + + reqform.update_icon() //Fix for appearing blank when printed. + reqtime = (world.time + 5) % 1e5 + . = TRUE + + if("request_crate") + var/datum/supply_pack/S = locate(params["ref"]) + + // Invalid ref + if(!istype(S)) + return FALSE + + if(S.contraband && !(authorization & SUP_CONTRABAND || can_order_contraband)) + return FALSE + + if(world.time < reqtime) + visible_message("[src]'s monitor flashes, \"[reqtime - world.time] seconds remaining until another requisition form may be printed.\"") + return FALSE + + var/timeout = world.time + 600 + var/reason = sanitize(input(usr, "Reason:","Why do you require this item?","") as null|text) + if(world.time > timeout) + to_chat(usr, "Error. Request timed out.") + return FALSE + if(!reason) + return FALSE + + SSsupply.create_order(S, usr, reason) + + var/idname = "*None Provided*" + var/idrank = "*None Provided*" + if(ishuman(usr)) + var/mob/living/carbon/human/H = usr + idname = H.get_authentification_name() + idrank = H.get_assignment() + else if(issilicon(usr)) + idname = usr.real_name idrank = "Stationbound synthetic" var/obj/item/weapon/paper/reqform = new /obj/item/weapon/paper(loc) @@ -268,24 +314,19 @@ reqform.update_icon() //Fix for appearing blank when printed. reqtime = (world.time + 5) % 1e5 - - if(href_list["order_ref"]) - var/datum/supply_order/O = locate(href_list["order_ref"]) - - // Invalid ref - if(!istype(O)) - return - - var/mob/user = locate(href_list["user"]) - if(!istype(user)) // Invalid ref - return - - if(href_list["edit"]) - var/new_val = sanitize(input(user, href_list["edit"], "Enter the new value for this field:", href_list["default"]) as null|text) + . = TRUE + // Approving Orders + if("edit_order_value") + var/datum/supply_order/O = locate(params["ref"]) + if(!istype(O)) + return FALSE + if(!(authorization & SUP_ACCEPT_ORDERS)) + return FALSE + var/new_val = sanitize(input(usr, params["edit"], "Enter the new value for this field:", params["default"]) as null|text) if(!new_val) - return + return FALSE - switch(href_list["edit"]) + switch(params["edit"]) if("Supply Pack") O.name = new_val @@ -313,68 +354,95 @@ if("Approved at") O.approved_at = new_val + . = TRUE + if("approve_order") + var/datum/supply_order/O = locate(params["ref"]) + if(!istype(O)) + return FALSE + if(!(authorization & SUP_ACCEPT_ORDERS)) + return FALSE + SSsupply.approve_order(O, usr) + . = TRUE + if("deny_order") + var/datum/supply_order/O = locate(params["ref"]) + if(!istype(O)) + return FALSE + if(!(authorization & SUP_ACCEPT_ORDERS)) + return FALSE + SSsupply.deny_order(O, usr) + . = TRUE + if("delete_order") + var/datum/supply_order/O = locate(params["ref"]) + if(!istype(O)) + return FALSE + if(!(authorization & SUP_ACCEPT_ORDERS)) + return FALSE + SSsupply.delete_order(O, usr) + . = TRUE + if("clear_all_requests") + if(!(authorization & SUP_ACCEPT_ORDERS)) + return FALSE + SSsupply.deny_all_pending(usr) + . = TRUE + // Exports + if("export_edit_field") + var/datum/exported_crate/E = locate(params["ref"]) + // Invalid ref + if(!istype(E)) + return FALSE + if(!(authorization & SUP_ACCEPT_ORDERS)) + return FALSE + var/list/L = E.contents[params["index"]] + var/field = alert(usr, "Select which field to edit", , "Name", "Quantity", "Value") - if(href_list["approve"]) - SSsupply.approve_order(O, user) - - if(href_list["deny"]) - SSsupply.deny_order(O, user) - - if(href_list["delete"]) - SSsupply.delete_order(O, user) - - if(href_list["clear_all_requests"]) - var/mob/user = locate(href_list["user"]) - if(!istype(user)) // Invalid ref - return - - SSsupply.deny_all_pending(user) - - if(href_list["export_ref"]) - var/datum/exported_crate/E = locate(href_list["export_ref"]) - - // Invalid ref - if(!istype(E)) - return - - var/mob/user = locate(href_list["user"]) - if(!istype(user)) // Invalid ref - return - - if(href_list["index"]) - var/list/L = E.contents[href_list["index"]] - - if(href_list["edit"]) - var/field = alert(user, "Select which field to edit", , "Name", "Quantity", "Value") - - var/new_val = sanitize(input(user, href_list["edit"], "Enter the new value for this field:", href_list["default"]) as null|text) - if(!new_val) - return - - switch(field) - if("Name") - L["object"] = new_val - - if("Quantity") - var/num = text2num(new_val) - if(num) - L["quantity"] = num - - if("Value") - var/num = text2num(new_val) - if(num) - L["value"] = num - - if(href_list["delete"]) - E.contents.Cut(href_list["index"], href_list["index"] + 1) - - // Else clause means they're editing/deleting the whole export report, rather than a specific item in it - else if(href_list["edit"]) - var/new_val = sanitize(input(user, href_list["edit"], "Enter the new value for this field:", href_list["default"]) as null|text) + var/new_val = sanitize(input(usr, field, "Enter the new value for this field:", L[lowertext(field)]) as null|text) if(!new_val) return - switch(href_list["edit"]) + switch(field) + if("Name") + L["object"] = new_val + + if("Quantity") + var/num = text2num(new_val) + if(num) + L["quantity"] = num + + if("Value") + var/num = text2num(new_val) + if(num) + L["value"] = num + . = TRUE + if("export_delete_field") + var/datum/exported_crate/E = locate(params["ref"]) + // Invalid ref + if(!istype(E)) + return FALSE + if(!(authorization & SUP_ACCEPT_ORDERS)) + return FALSE + E.contents.Cut(params["index"], params["index"] + 1) + . = TRUE + if("export_add_field") + var/datum/exported_crate/E = locate(params["ref"]) + // Invalid ref + if(!istype(E)) + return FALSE + if(!(authorization & SUP_ACCEPT_ORDERS)) + return FALSE + SSsupply.add_export_item(E, usr) + . = TRUE + if("export_edit") + var/datum/exported_crate/E = locate(params["ref"]) + // Invalid ref + if(!istype(E)) + return FALSE + if(!(authorization & SUP_ACCEPT_ORDERS)) + return FALSE + var/new_val = sanitize(input(usr, params["edit"], "Enter the new value for this field:", params["default"]) as null|text) + if(!new_val) + return + + switch(params["edit"]) if("Name") E.name = new_val @@ -382,39 +450,39 @@ var/num = text2num(new_val) if(num) E.value = num + . = TRUE + if("export_delete") + var/datum/exported_crate/E = locate(params["ref"]) + // Invalid ref + if(!istype(E)) + return FALSE + if(!(authorization & SUP_ACCEPT_ORDERS)) + return FALSE + SSsupply.delete_export(E, usr) + . = TRUE + if("send_shuttle") + switch(params["mode"]) + if("send_away") + if (shuttle.forbidden_atoms_check()) + to_chat(usr, "For safety reasons the automated supply shuttle cannot transport live organisms, classified nuclear weaponry or homing beacons.") + else + shuttle.launch(src) + to_chat(usr, "Initiating launch sequence.") - else if(href_list["delete"]) - SSsupply.delete_export(E, user) + if("send_to_station") + shuttle.launch(src) + to_chat(usr, "The supply shuttle has been called and will arrive in approximately [round(SSsupply.movetime/600,1)] minutes.") - else if(href_list["add_item"]) - SSsupply.add_export_item(E, user) + if("cancel_shuttle") + shuttle.cancel_launch(src) - - - switch(href_list["send_shuttle"]) - if("send_away") - if (shuttle.forbidden_atoms_check()) - to_chat(usr, "For safety reasons the automated supply shuttle cannot transport live organisms, classified nuclear weaponry or homing beacons.") - else - shuttle.launch(src) - to_chat(usr, "Initiating launch sequence.") - - if("send_to_station") - shuttle.launch(src) - to_chat(usr, "The supply shuttle has been called and will arrive in approximately [round(SSsupply.movetime/600,1)] minutes.") - - if("cancel_shuttle") - shuttle.cancel_launch(src) - - if("force_shuttle") - shuttle.force_launch(src) + if("force_shuttle") + shuttle.force_launch(src) + . = TRUE add_fingerprint(usr) - updateUsrDialog() - return /obj/machinery/computer/supplycomp/proc/post_signal(var/command) - var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435) if(!frequency) return diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index d3eec4057a..e87de196d9 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -38,7 +38,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() // 0 = no new message // 1 = normal priority // 2 = high priority - var/screen = RCS_MAINMENU + var/screen = RCS_VIEWMSGS var/silent = 0 // set to 1 for it not to beep all the time // var/hackState = 0 // 0 = not hacked @@ -105,10 +105,16 @@ var/list/obj/machinery/requests_console/allConsoles = list() if(..(user)) return ui_interact(user) + tgui_interact(user) -/obj/machinery/requests_console/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] +/obj/machinery/requests_console/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "RequestConsole", "[department] Request Console") + ui.open() +/obj/machinery/requests_console/tgui_data(mob/user) + var/list/data = ..() data["department"] = department data["screen"] = screen data["message_log"] = message_log @@ -122,93 +128,103 @@ var/list/obj/machinery/requests_console/allConsoles = list() data["message"] = message data["recipient"] = recipient - data["priortiy"] = priority + data["priority"] = priority data["msgStamped"] = msgStamped data["msgVerified"] = msgVerified data["announceAuth"] = announceAuth + return data - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "request_console.tmpl", "[department] Request Console", 520, 410) - ui.set_initial_data(data) - ui.open() - -/obj/machinery/requests_console/Topic(href, href_list) - if(..()) return - usr.set_machine(src) +/obj/machinery/requests_console/tgui_act(action, list/params) + if(..()) + return TRUE + add_fingerprint(usr) + + switch(action) + if("write") + if(reject_bad_text(params["write"])) + recipient = params["write"] //write contains the string of the receiving department's name - if(reject_bad_text(href_list["write"])) - recipient = href_list["write"] //write contains the string of the receiving department's name + var/new_message = sanitize(input("Write your message:", "Awaiting Input", "")) + if(new_message) + message = new_message + screen = RCS_MESSAUTH + switch(params["priority"]) + if(1) + priority = 1 + if(2) + priority = 2 + else + priority = 0 + else + reset_message(1) + . = TRUE - var/new_message = sanitize(input("Write your message:", "Awaiting Input", "")) - if(new_message) - message = new_message - screen = RCS_MESSAUTH - switch(href_list["priority"]) - if("1") priority = 1 - if("2") priority = 2 - else priority = 0 - else + if("writeAnnouncement") + var/new_message = sanitize(input("Write your message:", "Awaiting Input", "")) + if(new_message) + message = new_message + else + reset_message(1) + . = TRUE + + if("sendAnnouncement") + if(!announcementConsole) + return FALSE + announcement.Announce(message, msg_sanitized = 1) reset_message(1) + . = TRUE - if(href_list["writeAnnouncement"]) - var/new_message = sanitize(input("Write your message:", "Awaiting Input", "")) - if(new_message) - message = new_message - else - reset_message(1) + if("department") + if(!message) + return FALSE + var/log_msg = message + var/pass = 0 + screen = RCS_SENTFAIL + for(var/obj/machinery/message_server/MS in machines) + if(!MS.active) + continue + MS.send_rc_message(ckey(params["department"]), department, log_msg, msgStamped, msgVerified, priority) + pass = 1 + if(pass) + screen = RCS_SENTPASS + message_log += list(list("Message sent to [recipient]", "[message]")) + else + audible_message(text("[bicon(src)] *The Requests Console beeps: 'NOTICE: No server detected!'"),,4) + . = TRUE - if(href_list["sendAnnouncement"]) - if(!announcementConsole) return - announcement.Announce(message, msg_sanitized = 1) - reset_message(1) + //Handle printing + if("print") + var/msg = message_log[text2num(params["print"])]; + if(msg) + msg = "[msg[1]]:
[msg[2]]" + msg = replacetext(msg, "
", "\n") + msg = strip_html_properly(msg) + var/obj/item/weapon/paper/R = new(src.loc) + R.name = "[department] Message" + R.info = "

[department] Requests Console

[msg]
" + . = TRUE - if(href_list["department"] && message) - var/log_msg = message - var/pass = 0 - screen = RCS_SENTFAIL - for (var/obj/machinery/message_server/MS in machines) - if(!MS.active) continue - MS.send_rc_message(ckey(href_list["department"]),department,log_msg,msgStamped,msgVerified,priority) - pass = 1 - if(pass) - screen = RCS_SENTPASS - message_log += "Message sent to [recipient]
[message]" - else - audible_message(text("[bicon(src)] *The Requests Console beeps: 'NOTICE: No server detected!'"),,4) + //Handle screen switching + if("setScreen") + var/tempScreen = text2num(params["setScreen"]) + if(tempScreen == RCS_ANNOUNCE && !announcementConsole) + return + if(tempScreen == RCS_VIEWMSGS) + for (var/obj/machinery/requests_console/Console in allConsoles) + if(Console.department == department) + Console.newmessagepriority = 0 + Console.icon_state = "req_comp0" + Console.set_light(1) + if(tempScreen == RCS_MAINMENU) + reset_message() + screen = tempScreen + . = TRUE - //Handle printing - if (href_list["print"]) - var/msg = message_log[text2num(href_list["print"])]; - if(msg) - msg = replacetext(msg, "
", "\n") - msg = strip_html_properly(msg) - var/obj/item/weapon/paper/R = new(src.loc) - R.name = "[department] Message" - R.info = "

[department] Requests Console

[msg]
" - - //Handle screen switching - if(href_list["setScreen"]) - var/tempScreen = text2num(href_list["setScreen"]) - if(tempScreen == RCS_ANNOUNCE && !announcementConsole) - return - if(tempScreen == RCS_VIEWMSGS) - for (var/obj/machinery/requests_console/Console in allConsoles) - if(Console.department == department) - Console.newmessagepriority = 0 - Console.icon_state = "req_comp0" - Console.set_light(1) - if(tempScreen == RCS_MAINMENU) - reset_message() - screen = tempScreen - - //Handle silencing the console - if(href_list["toggleSilent"]) - silent = !silent - - updateUsrDialog() - return + //Handle silencing the console + if("toggleSilent") + silent = !silent + . = TRUE //err... hacking code, which has no reason for existing... but anyway... it was once supposed to unlock priority 3 messaging on that console (EXTREME priority...), but the code for that was removed. /obj/machinery/requests_console/attackby(var/obj/item/weapon/O as obj, var/mob/user as mob) @@ -238,7 +254,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() if(screen == RCS_MESSAUTH) var/obj/item/weapon/card/id/T = O msgVerified = text("Verified by [T.registered_name] ([T.assignment])") - updateUsrDialog() + SStgui.update_uis(src) if(screen == RCS_ANNOUNCE) var/obj/item/weapon/card/id/ID = O if(access_RC_announce in ID.GetAccess()) @@ -247,13 +263,13 @@ var/list/obj/machinery/requests_console/allConsoles = list() else reset_message() to_chat(user, "You are not authorized to send announcements.") - updateUsrDialog() + SStgui.update_uis(src) if(istype(O, /obj/item/weapon/stamp)) if(inoperable(MAINT)) return if(screen == RCS_MESSAUTH) var/obj/item/weapon/stamp/T = O msgStamped = text("Stamped with the [T.name]") - updateUsrDialog() + SStgui.update_uis(src) return /obj/machinery/requests_console/proc/reset_message(var/mainmenu = 0) diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm index 095f565bd4..e14a4c0edf 100644 --- a/code/game/objects/items/devices/gps.dm +++ b/code/game/objects/items/devices/gps.dm @@ -11,6 +11,7 @@ var/list/GPS_list = list() matter = list(DEFAULT_WALL_MATERIAL = 500) var/gps_tag = "GEN0" var/emped = FALSE + var/updating = TRUE // Lets users lock the UI so they don't have to deal with constantly shifting signals var/tracking = FALSE // Will not show other signals or emit its own signal if false. var/long_range = FALSE // If true, can see farther, depending on get_map_levels(). var/local_mode = FALSE // If true, only GPS signals of the same Z level are shown. @@ -66,7 +67,11 @@ var/list/GPS_list = list() add_overlay("working") /obj/item/device/gps/attack_self(mob/user) - display(user) + tgui_interact(user) + +/obj/item/device/gps/examine(mob/user) + . = ..() + . += display() // Compiles all the data not available directly from the GPS // Like the positions and directions to all other GPS units @@ -117,12 +122,12 @@ var/list/GPS_list = list() return dat -/obj/item/device/gps/proc/display(mob/user) +/obj/item/device/gps/proc/display() if(!tracking) - to_chat(user, "The device is off. Alt-click it to turn it on.") + . = "The device is off. Alt-click it to turn it on." return if(emped) - to_chat(user, "It's busted!") + . = "It's busted!" return var/list/dat = list() @@ -143,8 +148,7 @@ var/list/GPS_list = list() else dat += "No other signals detected." - var/result = dat.Join("
") - to_chat(user, result) + . = dat /obj/item/device/gps/Topic(var/href, var/list/href_list) if(..()) @@ -168,6 +172,85 @@ var/list/GPS_list = list() hide_signal = !hide_signal to_chat(usr, "You set the device to [hide_signal ? "not " : ""]broadcast a signal while scanning for other signals.") +/obj/item/device/gps/tgui_interact(mob/user, datum/tgui/ui) + if(emped) + to_chat(user, "[src] fizzles weakly.") + return + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Gps", name) + ui.open() + ui.set_autoupdate(updating) + +/obj/item/device/gps/tgui_data(mob/user) + var/list/data = list() + data["power"] = tracking + data["tag"] = gps_tag + data["updating"] = updating + data["globalmode"] = !local_mode + if(!tracking || emped) //Do not bother scanning if the GPS is off or EMPed + return data + + var/turf/curr = get_turf(src) + data["currentArea"] = "[get_area_name(curr, TRUE)]" + data["currentCoords"] = list(curr.x, curr.y, curr.z) + data["currentCoordsText"] = "[curr.x], [curr.y], [using_map.get_zlevel_name(curr.z)]" + + data["zLevelDetection"] = using_map.get_map_levels(curr.z, long_range) + + var/list/signals = list() + data["signals"] = list() + + for(var/obj/item/device/gps/G in GPS_list - src) + if(!G.tracking || G.emped || G.hide_signal) + continue + + var/turf/T = get_turf(G) + if(!T) + continue + if(local_mode && curr.z != T.z) + continue + if(!(T.z in data["zLevelDetection"])) + continue + + var/list/signal = list() + signal["entrytag"] = G.gps_tag //Name or 'tag' of the GPS + signal["coords"] = list(T.x, T.y, T.z) + signal["coordsText"] = "[T.x], [T.y], [using_map.get_zlevel_name(T.z)]" + if(T.z == curr.z) //Distance/Direction calculations for same z-level only + signal["dist"] = max(get_dist(curr, T), 0) //Distance between the src and remote GPS turfs + signal["degrees"] = round(Get_Angle(curr, T)) //0-360 degree directional bearing, for more precision. + signals += list(signal) //Add this signal to the list of signals + data["signals"] = signals + return data + +/obj/item/device/gps/tgui_act(action, params) + if(..()) + return TRUE + + switch(action) + if("rename") + var/a = stripped_input(usr, "Please enter desired tag.", name, gps_tag, 20) + + if(!a) + return + + gps_tag = a + name = "global positioning system ([gps_tag])" + . = TRUE + + if("power") + toggletracking(usr) + . = TRUE + + if("updating") + updating = !updating + . = TRUE + + if("globalmode") + local_mode = !local_mode + . = TRUE + /obj/item/device/gps/on // Defaults to off to avoid polluting the signal list with a bunch of GPSes without owners. If you need to spawn active ones, use these. tracking = TRUE @@ -291,10 +374,10 @@ var/list/GPS_list = list() /obj/item/device/gps/syndie/display(mob/user) if(!tracking) - to_chat(user, "The device is off. Alt-click it to turn it on.") + . = "The device is off. Alt-click it to turn it on." return if(emped) - to_chat(user, "It's busted!") + . = "It's busted!" return var/list/dat = list() @@ -312,5 +395,4 @@ var/list/GPS_list = list() else dat += "No other signals detected." - var/result = dat.Join("
") - to_chat(user, result) + . = dat diff --git a/code/global.dm b/code/global.dm index 9e6b6c555b..48628c5e02 100644 --- a/code/global.dm +++ b/code/global.dm @@ -130,9 +130,6 @@ var/custom_event_msg = null var/DBConnection/dbcon = new() // Feedback database (New database) var/DBConnection/dbcon_old = new() // /tg/station database (Old database) -- see the files in the SQL folder for information on what goes where. -// Reference list for disposal sort junctions. Filled up by sorting junction's New() -/var/list/tagger_locations = list() - // Added for Xenoarchaeology, might be useful for other stuff. var/global/list/alphabet_uppercase = list("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z") diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm index 03b23b15a6..93c711b6be 100644 --- a/code/modules/mining/machine_processing.dm +++ b/code/modules/mining/machine_processing.dm @@ -33,7 +33,10 @@ /obj/machinery/mineral/processing_unit_console/attack_hand(mob/user) if(..()) return - interact(user) + if(!allowed(user)) + to_chat(user, "Access denied.") + return + tgui_interact(user) /obj/machinery/mineral/processing_unit_console/attackby(var/obj/item/I, var/mob/user) if(istype(I, /obj/item/weapon/card/id)) @@ -42,97 +45,89 @@ if(!inserted_id && user.unEquip(I)) I.forceMove(src) inserted_id = I - interact(user) + SStgui.update_uis(src) return ..() -/obj/machinery/mineral/processing_unit_console/interact(mob/user) - if(..()) - return +/obj/machinery/mineral/processing_unit_console/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "MiningOreProcessingConsole", name) + ui.open() - if(!allowed(user)) - to_chat(user, "Access denied.") - return +/obj/machinery/mineral/processing_unit_console/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + data["unclaimedPoints"] = machine.points - user.set_machine(src) - - var/dat = "

Ore processor console

" - - dat += "Current unclaimed points: [machine.points]
" - if(istype(inserted_id)) - dat += "You have [inserted_id.mining_points] mining points collected. Eject ID.
" - dat += "Claim points.
" + if(inserted_id) + data["has_id"] = TRUE + data["id"] = list( + "name" = inserted_id.registered_name, + "points" = inserted_id.mining_points, + ) else - dat += "No ID inserted. Insert ID.
" - - dat += "
" + data["has_id"] = FALSE + data["ores"] = list() for(var/ore in machine.ores_processing) - - if(!machine.ores_stored[ore] && !show_all_ores) continue + if(!machine.ores_stored[ore] && !show_all_ores) + continue var/ore/O = ore_data[ore] - if(!O) continue - dat += "" + if(!O) + continue + data["ores"].Add(list(list( + "ore" = ore, + "name" = O.display_name, + "amount" = machine.ores_stored[ore], + "processing" = machine.ores_processing[ore] ? machine.ores_processing[ore] : 0, + ))) - dat += "
[capitalize(O.display_name)][machine.ores_stored[ore]]" - if(machine.ores_processing[ore]) - switch(machine.ores_processing[ore]) - if(PROCESS_NONE) - dat += "not processing" - if(PROCESS_SMELT) - dat += "smelting" - if(PROCESS_COMPRESS) - dat += "compressing" - if(PROCESS_ALLOY) - dat += "alloying" - else - dat += "not processing" - dat += ".\[change\]

" - dat += "Currently displaying [show_all_ores ? "all ore types" : "only available ore types"]. \[[show_all_ores ? "show less" : "show more"]\]
" - dat += "The ore processor is currently [(machine.active ? "processing" : "disabled")]." - user << browse(dat, "window=processor_console;size=400x500") - onclose(user, "processor_console") - return + data["showAllOres"] = show_all_ores + data["power"] = machine.active -/obj/machinery/mineral/processing_unit_console/Topic(href, href_list) + return data + +/obj/machinery/mineral/processing_unit_console/tgui_act(action, list/params) if(..()) - return 1 - usr.set_machine(src) - src.add_fingerprint(usr) + return TRUE - if(href_list["toggle_smelting"]) - - var/choice = input("What setting do you wish to use for processing [href_list["toggle_smelting"]]?") as null|anything in list("Smelting","Compressing","Alloying","Nothing") - if(!choice) return - - switch(choice) - if("Nothing") choice = PROCESS_NONE - if("Smelting") choice = PROCESS_SMELT - if("Compressing") choice = PROCESS_COMPRESS - if("Alloying") choice = PROCESS_ALLOY - - machine.ores_processing[href_list["toggle_smelting"]] = choice - - if(href_list["toggle_power"]) - - machine.active = !machine.active - - if(href_list["toggle_ores"]) - - show_all_ores = !show_all_ores - - if(href_list["choice"]) - if(istype(inserted_id)) - if(href_list["choice"] == "eject") - usr.put_in_hands(inserted_id) - inserted_id = null - if(href_list["choice"] == "claim") + add_fingerprint(usr) + switch(action) + if("toggleSmelting") + var/ore = params["ore"] + var/new_setting = params["set"] + if(new_setting == null) + new_setting = input("What setting do you wish to use for processing [ore]]?") as null|anything in list("Smelting","Compressing","Alloying","Nothing") + if(!new_setting) + return + switch(new_setting) + if("Nothing") new_setting = PROCESS_NONE + if("Smelting") new_setting = PROCESS_SMELT + if("Compressing") new_setting = PROCESS_COMPRESS + if("Alloying") new_setting = PROCESS_ALLOY + machine.ores_processing[ore] = new_setting + . = TRUE + if("power") + machine.active = !machine.active + . = TRUE + if("showAllOres") + show_all_ores = !show_all_ores + . = TRUE + if("logoff") + if(!inserted_id) + return + usr.put_in_hands(inserted_id) + inserted_id = null + . = TRUE + if("claim") + if(istype(inserted_id)) if(access_mining_station in inserted_id.access) inserted_id.mining_points += machine.points machine.points = 0 else to_chat(usr, "Required access not found.") - else if(href_list["choice"] == "insert") + . = TRUE + if("insert") var/obj/item/weapon/card/id/I = usr.get_active_hand() if(istype(I)) usr.drop_item() @@ -140,9 +135,9 @@ inserted_id = I else to_chat(usr, "No valid ID.") - - src.updateUsrDialog() - return + . = TRUE + else + return FALSE /**********************Mineral processing unit**************************/ diff --git a/code/modules/mining/machine_stacking.dm b/code/modules/mining/machine_stacking.dm index ec6b7623df..c1d6c4ee4c 100644 --- a/code/modules/mining/machine_stacking.dm +++ b/code/modules/mining/machine_stacking.dm @@ -25,46 +25,47 @@ /obj/machinery/mineral/stacking_unit_console/attack_hand(mob/user) add_fingerprint(user) - interact(user) + tgui_interact(user) -/obj/machinery/mineral/stacking_unit_console/interact(mob/user) - user.set_machine(src) +/obj/machinery/mineral/stacking_unit_console/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "MiningStackingConsole", name) + ui.open() - var/dat - - dat += text("

Stacking unit console


") +/obj/machinery/mineral/stacking_unit_console/tgui_data(mob/user) + var/list/data = ..() + data["stacktypes"] = list() for(var/stacktype in machine.stack_storage) if(machine.stack_storage[stacktype] > 0) - dat += "" - dat += "
[capitalize(stacktype)]:[machine.stack_storage[stacktype]]\[release\]

" - dat += text("
Stacking: [machine.stack_amt] \[change\]

") + data["stacktypes"].Add(list(list( + "type" = stacktype, + "amt" = machine.stack_storage[stacktype], + ))) + data["stackingAmt"] = machine.stack_amt + return data - user << browse("[dat]", "window=console_stacking_machine") - onclose(user, "console_stacking_machine") - - -/obj/machinery/mineral/stacking_unit_console/Topic(href, href_list) +/obj/machinery/mineral/stacking_unit_console/tgui_act(action, list/params) if(..()) - return 1 + return TRUE - if(href_list["change_stack"]) - var/choice = input("What would you like to set the stack amount to?") as null|anything in list(1,5,10,20,50) - if(!choice) return - machine.stack_amt = choice + switch(action) + if("change_stack") + machine.stack_amt = clamp(text2num(params["amt"]), 1, 50) + . = TRUE - if(href_list["release_stack"]) - if(machine.stack_storage[href_list["release_stack"]] > 0) - var/stacktype = machine.stack_paths[href_list["release_stack"]] - var/obj/item/stack/material/S = new stacktype (get_turf(machine.output)) - S.amount = machine.stack_storage[href_list["release_stack"]] - machine.stack_storage[href_list["release_stack"]] = 0 - S.update_icon() + if("release_stack") + var/stack = params["stack"] + if(machine.stack_storage[stack] > 0) + var/stacktype = machine.stack_paths[stack] + var/obj/item/stack/material/S = new stacktype(get_turf(machine.output)) + S.amount = machine.stack_storage[stack] + machine.stack_storage[stack] = 0 + S.update_icon() + . = TRUE - src.add_fingerprint(usr) - src.updateUsrDialog() - - return + add_fingerprint(usr) /**********************Mineral stacking unit**************************/ diff --git a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm index 822dccaf57..397b2ef1ce 100644 --- a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm +++ b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm @@ -1,3 +1,9 @@ +// Use this define to register something as a purchasable! +// * n — The proper name of the purchasable +// * o — The object type path of the purchasable to spawn +// * p — The price of the purchasable in mining points +#define EQUIPMENT(n, o, p) n = new /datum/data/mining_equipment(n, o, p) + /**********************Mining Equipment Locker**************************/ /obj/machinery/mineral/equipment_vendor @@ -11,81 +17,8 @@ var/icon_vend = "adh-tool-vend" circuit = /obj/item/weapon/circuitboard/mining_equipment_vendor var/obj/item/weapon/card/id/inserted_id - //VOREStation Edit Start - Heavily modified list - var/list/prize_list = list( - new /datum/data/mining_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 10), - new /datum/data/mining_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 100), - new /datum/data/mining_equipment("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 300), - new /datum/data/mining_equipment("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 125), - new /datum/data/mining_equipment("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 125), - new /datum/data/mining_equipment("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 150), - new /datum/data/mining_equipment("Soap", /obj/item/weapon/soap/nanotrasen, 200), - new /datum/data/mining_equipment("Laser Pointer", /obj/item/device/laser_pointer, 900), - new /datum/data/mining_equipment("Geiger Counter", /obj/item/device/geiger, 750), - new /datum/data/mining_equipment("Plush Toy", /obj/random/plushie, 300), - new /datum/data/mining_equipment("GPS Device", /obj/item/device/gps/mining, 100), - // TODO new /datum/data/mining_equipment("Advanced Scanner", /obj/item/device/t_scanner/adv_mining_scanner, 800), - new /datum/data/mining_equipment("Fulton Beacon", /obj/item/fulton_core, 500), - new /datum/data/mining_equipment("Shelter Capsule", /obj/item/device/survivalcapsule, 500), - // TODO new /datum/data/mining_equipment("Explorer's Webbing", /obj/item/storage/belt/mining, 500), - new /datum/data/mining_equipment("Umbrella", /obj/item/weapon/melee/umbrella/random, 200), - new /datum/data/mining_equipment("Point Transfer Card", /obj/item/weapon/card/mining_point_card, 500), - new /datum/data/mining_equipment("Trauma Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/trauma, 250), - new /datum/data/mining_equipment("Burn Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/burn, 250), - new /datum/data/mining_equipment("Oxy Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/oxy, 250), - new /datum/data/mining_equipment("Detox Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/detox, 250), - new /datum/data/mining_equipment("Mini-Translocator", /obj/item/device/perfect_tele/one_beacon, 1200), - // new /datum/data/mining_equipment("Kinetic Crusher", /obj/item/twohanded/required/kinetic_crusher, 750), - new /datum/data/mining_equipment("Kinetic Accelerator", /obj/item/weapon/gun/energy/kinetic_accelerator, 900), - new /datum/data/mining_equipment("Resonator", /obj/item/resonator, 900), - new /datum/data/mining_equipment("Fulton Pack", /obj/item/extraction_pack, 1200), - new /datum/data/mining_equipment("Silver Pickaxe", /obj/item/weapon/pickaxe/silver, 1200), - // new /datum/data/mining_equipment("Mining Conscription Kit", /obj/item/storage/backpack/duffelbag/mining_conscript, 1000), - new /datum/data/mining_equipment("Thalers - 100", /obj/item/weapon/spacecash/c100, 1000), - new /datum/data/mining_equipment("Hardsuit - Control Module", /obj/item/weapon/rig/industrial/vendor, 2000), - new /datum/data/mining_equipment("Hardsuit - Plasma Cutter", /obj/item/rig_module/device/plasmacutter, 800), - new /datum/data/mining_equipment("Hardsuit - Drill", /obj/item/rig_module/device/drill, 5000), - new /datum/data/mining_equipment("Hardsuit - Ore Scanner", /obj/item/rig_module/device/orescanner, 1000), - new /datum/data/mining_equipment("Hardsuit - Material Scanner", /obj/item/rig_module/vision/material, 500), - new /datum/data/mining_equipment("Hardsuit - Maneuvering Jets", /obj/item/rig_module/maneuvering_jets, 1250), - new /datum/data/mining_equipment("Hardsuit - Intelligence Storage", /obj/item/rig_module/ai_container, 2500), - new /datum/data/mining_equipment("Hardsuit - Smoke Bomb Deployer", /obj/item/rig_module/grenade_launcher/smoke, 2000), - new /datum/data/mining_equipment("Industrial Equipment - Phoron Bore", /obj/item/weapon/gun/magnetic/matfed, 3000), - new /datum/data/mining_equipment("Industrial Equipment - Sheet-Snatcher",/obj/item/weapon/storage/bag/sheetsnatcher, 500), - new /datum/data/mining_equipment("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 500), - new /datum/data/mining_equipment("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 1000), - // new /datum/data/mining_equipment("Diamond Pickaxe", /obj/item/weapon/pickaxe/diamond, 2000), - new /datum/data/mining_equipment("Super Resonator", /obj/item/resonator/upgraded, 2500), - new /datum/data/mining_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 2500), - new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 3100), - new /datum/data/mining_equipment("Bar Shelter Capsule", /obj/item/device/survivalcapsule/luxurybar, 10000), - new /datum/data/mining_equipment("KA White Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer, 125), - new /datum/data/mining_equipment("KA Adjustable Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer/adjustable, 175), - new /datum/data/mining_equipment("KA Super Chassis", /obj/item/borg/upgrade/modkit/chassis_mod, 250), - new /datum/data/mining_equipment("KA Hyper Chassis", /obj/item/borg/upgrade/modkit/chassis_mod/orange, 300), - new /datum/data/mining_equipment("KA Range Increase", /obj/item/borg/upgrade/modkit/range, 1000), - new /datum/data/mining_equipment("KA Damage Increase", /obj/item/borg/upgrade/modkit/damage, 1000), - new /datum/data/mining_equipment("KA Efficiency Increase", /obj/item/borg/upgrade/modkit/efficiency, 1200), - new /datum/data/mining_equipment("KA AoE Damage", /obj/item/borg/upgrade/modkit/aoe/mobs, 2000), - new /datum/data/mining_equipment("KA Holster", /obj/item/clothing/accessory/holster/waist/kinetic_accelerator, 350), - new /datum/data/mining_equipment("Fine Excavation Kit - Chisels",/obj/item/weapon/storage/excavation, 500), - new /datum/data/mining_equipment("Fine Excavation Kit - Measuring Tape",/obj/item/device/measuring_tape, 125), - new /datum/data/mining_equipment("Fine Excavation Kit - Hand Pick",/obj/item/weapon/pickaxe/hand, 375), - new /datum/data/mining_equipment("Explosive Excavation Kit - Plastic Charge",/obj/item/weapon/plastique/seismic/locked, 1500), - new /datum/data/mining_equipment("Injector (L) - Glucose",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose, 500), - new /datum/data/mining_equipment("Injector (L) - Panacea",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity, 500), - new /datum/data/mining_equipment("Injector (L) - Trauma",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute, 500), - new /datum/data/mining_equipment("Nanopaste Tube", /obj/item/stack/nanopaste, 1000), - new /datum/data/mining_equipment("Defense Equipment - Smoke Bomb",/obj/item/weapon/grenade/smokebomb, 100), - new /datum/data/mining_equipment("Defense Equipment - Razor Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked, 1000), - new /datum/data/mining_equipment("Defense Equipment - Sentry Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/ward, 1500), - new /datum/data/mining_equipment("Defense Equipment - Plasteel Machete", /obj/item/weapon/material/knife/machete, 500), - new /datum/data/mining_equipment("Fishing Net", /obj/item/weapon/material/fishing_net, 500), - new /datum/data/mining_equipment("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 1000), - new /datum/data/mining_equipment("Durasteel Fishing Rod", /obj/item/weapon/material/fishing_rod/modern/strong, 7500), - new /datum/data/mining_equipment("Survival Equipment - Insulated Poncho", /obj/random/thermalponcho, 750) - ) - //VOREStation Edit End + var/list/prize_list // Initialized just below! (if you're wondering why - check CONTRIBUTING.md, look for: "hidden" init proc) + var/dirty_items = FALSE // Used to refresh the static/redundant data in case the machine gets VV'd /datum/data/mining_equipment var/equipment_name = "generic" @@ -97,9 +30,96 @@ src.equipment_path = path src.cost = cost -/obj/machinery/power/quantumpad/Initialize() +/obj/machinery/mineral/equipment_vendor/Initialize(mapload) . = ..() - default_apply_parts() + //VOREStation Edit Start - Heavily modified list + prize_list = list() + prize_list["Gear"] = list( + // TODO EQUIPMENT("Advanced Scanner", /obj/item/device/t_scanner/adv_mining_scanner, 800), + // TODO EQUIPMENT("Explorer's Webbing", /obj/item/storage/belt/mining, 500), + EQUIPMENT("Defense Equipment - Plasteel Machete", /obj/item/weapon/material/knife/machete, 500), + EQUIPMENT("Defense Equipment - Razor Drone Deployer", /obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked, 1000), + EQUIPMENT("Defense Equipment - Sentry Drone Deployer", /obj/item/weapon/grenade/spawnergrenade/ward, 1500), + EQUIPMENT("Defense Equipment - Smoke Bomb", /obj/item/weapon/grenade/smokebomb, 100), + EQUIPMENT("Durasteel Fishing Rod", /obj/item/weapon/material/fishing_rod/modern/strong, 7500), + EQUIPMENT("Fishing Net", /obj/item/weapon/material/fishing_net, 500), + EQUIPMENT("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 1000), + EQUIPMENT("Fulton Beacon", /obj/item/fulton_core, 500), + EQUIPMENT("Geiger Counter", /obj/item/device/geiger, 750), + EQUIPMENT("GPS Device", /obj/item/device/gps/mining, 100), + // EQUIPMENT("Mining Conscription Kit", /obj/item/storage/backpack/duffelbag/mining_conscript, 1000), + EQUIPMENT("Jump Boots", /obj/item/clothing/shoes/bhop, 2500), + EQUIPMENT("Mini-Translocator", /obj/item/device/perfect_tele/one_beacon, 1200), + EQUIPMENT("Survival Equipment - Insulated Poncho", /obj/random/thermalponcho, 750), + + ) + prize_list["Consumables"] = list( + EQUIPMENT("1 Marker Beacon", /obj/item/stack/marker_beacon, 10), + EQUIPMENT("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 100), + EQUIPMENT("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 300), + EQUIPMENT("Fulton Pack", /obj/item/extraction_pack, 1200), + EQUIPMENT("Injector (L) - Glucose", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose, 500), + EQUIPMENT("Injector (L) - Panacea", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity, 500), + EQUIPMENT("Injector (L) - Trauma", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute, 500), + EQUIPMENT("Nanopaste Tube", /obj/item/stack/nanopaste, 1000), + EQUIPMENT("Point Transfer Card", /obj/item/weapon/card/mining_point_card, 500), + EQUIPMENT("Shelter Capsule", /obj/item/device/survivalcapsule, 500), + EQUIPMENT("Burn Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/burn, 250), + EQUIPMENT("Detox Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/detox, 250), + EQUIPMENT("Oxy Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/oxy, 250), + EQUIPMENT("Trauma Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/trauma, 250), + ) + prize_list["Kinetic Accelerator"] = list( + EQUIPMENT("Kinetic Accelerator", /obj/item/weapon/gun/energy/kinetic_accelerator, 900), + EQUIPMENT("KA Adjustable Tracer Rounds",/obj/item/borg/upgrade/modkit/tracer/adjustable, 175), + EQUIPMENT("KA AoE Damage", /obj/item/borg/upgrade/modkit/aoe/mobs, 2000), + EQUIPMENT("KA Damage Increase", /obj/item/borg/upgrade/modkit/damage, 1000), + EQUIPMENT("KA Efficiency Increase", /obj/item/borg/upgrade/modkit/efficiency, 1200), + EQUIPMENT("KA Holster", /obj/item/clothing/accessory/holster/waist/kinetic_accelerator, 350), + EQUIPMENT("KA Hyper Chassis", /obj/item/borg/upgrade/modkit/chassis_mod/orange, 300), + EQUIPMENT("KA Range Increase", /obj/item/borg/upgrade/modkit/range, 1000), + EQUIPMENT("KA Super Chassis", /obj/item/borg/upgrade/modkit/chassis_mod, 250), + EQUIPMENT("KA White Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer, 125), + ) + prize_list["Digging Tools"] = list( + // EQUIPMENT("Diamond Pickaxe", /obj/item/weapon/pickaxe/diamond, 2000), + // EQUIPMENT("Kinetic Crusher", /obj/item/twohanded/required/kinetic_crusher, 750), + EQUIPMENT("Resonator", /obj/item/resonator, 900), + EQUIPMENT("Silver Pickaxe", /obj/item/weapon/pickaxe/silver, 1200), + EQUIPMENT("Super Resonator", /obj/item/resonator/upgraded, 2500), + EQUIPMENT("Fine Excavation Kit - Chisels", /obj/item/weapon/storage/excavation, 500), + EQUIPMENT("Fine Excavation Kit - Measuring Tape", /obj/item/device/measuring_tape, 125), + EQUIPMENT("Fine Excavation Kit - Hand Pick", /obj/item/weapon/pickaxe/hand, 375), + EQUIPMENT("Explosive Excavation Kit - Plastic Charge",/obj/item/weapon/plastique/seismic/locked, 1500), + ) + prize_list["Hardsuit"] = list( + EQUIPMENT("Hardsuit - Control Module", /obj/item/weapon/rig/industrial/vendor, 2000), + EQUIPMENT("Hardsuit - Drill", /obj/item/rig_module/device/drill, 5000), + EQUIPMENT("Hardsuit - Intelligence Storage",/obj/item/rig_module/ai_container, 2500), + EQUIPMENT("Hardsuit - Maneuvering Jets", /obj/item/rig_module/maneuvering_jets, 1250), + EQUIPMENT("Hardsuit - Material Scanner", /obj/item/rig_module/vision/material, 500), + EQUIPMENT("Hardsuit - Ore Scanner", /obj/item/rig_module/device/orescanner, 1000), + EQUIPMENT("Hardsuit - Plasma Cutter", /obj/item/rig_module/device/plasmacutter, 800), + EQUIPMENT("Hardsuit - Smoke Bomb Deployer", /obj/item/rig_module/grenade_launcher/smoke,2000), + ) + prize_list["Miscellaneous"] = list( + EQUIPMENT("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 125), + EQUIPMENT("Bar Shelter Capsule", /obj/item/device/survivalcapsule/luxurybar, 10000), + EQUIPMENT("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 150), + EQUIPMENT("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 1000), + EQUIPMENT("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 500), + EQUIPMENT("Industrial Equipment - Phoron Bore", /obj/item/weapon/gun/magnetic/matfed, 3000), + EQUIPMENT("Industrial Equipment - Sheet-Snatcher",/obj/item/weapon/storage/bag/sheetsnatcher, 500), + EQUIPMENT("Laser Pointer", /obj/item/device/laser_pointer, 900), + EQUIPMENT("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 3100), + EQUIPMENT("Plush Toy", /obj/random/plushie, 300), + EQUIPMENT("Soap", /obj/item/weapon/soap/nanotrasen, 200), + EQUIPMENT("Thalers - 100", /obj/item/weapon/spacecash/c100, 1000), + EQUIPMENT("Umbrella", /obj/item/weapon/melee/umbrella/random, 200), + EQUIPMENT("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 125), + ) + prize_list["Extra"] = list() // Used in child vendors + //VOREStation Edit End /obj/machinery/mineral/equipment_vendor/power_change() var/old_stat = stat @@ -126,73 +146,104 @@ /obj/machinery/mineral/equipment_vendor/attack_hand(mob/user) if(..()) return - interact(user) + tgui_interact(user) /obj/machinery/mineral/equipment_vendor/attack_ghost(mob/user) - interact(user) + tgui_interact(user) -/obj/machinery/mineral/equipment_vendor/interact(mob/user) - user.set_machine(src) +/obj/machinery/mineral/equipment_vendor/tgui_data(mob/user) + var/list/data = ..() - var/dat - dat +="
" - if(istype(inserted_id)) - dat += "You have [inserted_id.mining_points] mining points collected. Eject ID.
" + // ID + if(inserted_id) + data["has_id"] = TRUE + data["id"] = list() + data["id"]["name"] = inserted_id.registered_name + data["id"]["points"] = get_points(inserted_id) else - dat += "No ID inserted. Insert ID.
" - dat += "
" - dat += "
Equipment point cost list:
" - for(var/datum/data/mining_equipment/prize in prize_list) - dat += "" - dat += "
[prize.equipment_name][prize.cost]Purchase
" - var/datum/browser/popup = new(user, "miningvendor", "Mining Equipment Vendor", 400, 600) - popup.set_content(dat) - popup.open() + data["has_id"] = FALSE -/obj/machinery/mineral/equipment_vendor/Topic(href, href_list) + return data + +/obj/machinery/mineral/equipment_vendor/proc/get_points(obj/item/weapon/card/id/target) + if(!istype(target)) + return 0 + return target.mining_points + +/obj/machinery/mineral/equipment_vendor/proc/remove_points(obj/item/weapon/card/id/target, amt) + target.mining_points -= amt + +/obj/machinery/mineral/equipment_vendor/tgui_static_data(mob/user) + var/list/static_data[0] + + // Available items - in static data because we don't wanna compute this list every time! It hardly changes. + static_data["items"] = list() + for(var/cat in prize_list) + var/list/cat_items = list() + for(var/prize_name in prize_list[cat]) + var/datum/data/mining_equipment/prize = prize_list[cat][prize_name] + cat_items[prize_name] = list("name" = prize_name, "price" = prize.cost) + static_data["items"][cat] = cat_items + + return static_data + +/obj/machinery/mineral/equipment_vendor/vv_edit_var(var_name, var_value) + // Gotta update the static data in case an admin VV's the items for some reason..! + if(var_name == "prize_list") + dirty_items = TRUE + return ..() + +/obj/machinery/mineral/equipment_vendor/tgui_interact(mob/user, datum/tgui/ui = null) + // Update static data if need be + if(dirty_items) + update_tgui_static_data(user, ui) + dirty_items = FALSE + + // Open the window + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "MiningVendor", name) + ui.open() + ui.set_autoupdate(FALSE) + + +/obj/machinery/mineral/equipment_vendor/tgui_act(action, params) if(..()) - return 1 + return - if(href_list["choice"]) - if(istype(inserted_id)) - if(href_list["choice"] == "eject") - to_chat(usr, "You eject the ID from [src]'s card slot.") - usr.put_in_hands(inserted_id) - inserted_id = null - else if(href_list["choice"] == "insert") - var/obj/item/weapon/card/id/I = usr.get_active_hand() - if(istype(I) && !inserted_id && usr.unEquip(I)) - I.forceMove(src) - inserted_id = I - interact(usr) - to_chat(usr, "You insert the ID into [src]'s card slot.") - else - to_chat(usr, "No valid ID.") - flick(icon_deny, src) - - if(href_list["purchase"]) - if(istype(inserted_id)) - var/datum/data/mining_equipment/prize = locate(href_list["purchase"]) - if (!prize || !(prize in prize_list)) - to_chat(usr, "Error: Invalid choice!") - flick(icon_deny, src) + . = TRUE + switch(action) + if("logoff") + if(!inserted_id) return - if(prize.cost > inserted_id.mining_points) - to_chat(usr, "Error: Insufficent points for [prize.equipment_name]!") - flick(icon_deny, src) - else - inserted_id.mining_points -= prize.cost - to_chat(usr, "[src] clanks to life briefly before vending [prize.equipment_name]!") - new prize.equipment_path(drop_location()) - flick(icon_vend, src) + usr.put_in_hands(inserted_id) + inserted_id = null + if("purchase") + if(!inserted_id) + flick(icon_deny, src) //VOREStation Add + return + var/category = params["cat"] // meow + var/name = params["name"] + if(!(category in prize_list) || !(name in prize_list[category])) // Not trying something that's not in the list, are you? + flick(icon_deny, src) //VOREStation Add + return + var/datum/data/mining_equipment/prize = prize_list[category][name] + if(prize.cost > get_points(inserted_id)) // shouldn't be able to access this since the button is greyed out, but.. + to_chat(usr, "You have insufficient points.") + flick(icon_deny, src) //VOREStation Add + return + + remove_points(inserted_id, prize.cost) + new prize.equipment_path(loc) + flick(icon_vend, src) //VOREStation Add else - to_chat(usr, "Error: Please insert a valid ID!") - flick(icon_deny, src) - updateUsrDialog() + flick(icon_deny, src) //VOREStation Add + return FALSE + add_fingerprint() + /obj/machinery/mineral/equipment_vendor/attackby(obj/item/I, mob/user, params) if(default_deconstruction_screwdriver(user, I)) - updateUsrDialog() return if(default_part_replacement(user, I)) return @@ -201,7 +252,7 @@ if(istype(I, /obj/item/mining_voucher)) if(!powered()) return - RedeemVoucher(I, user) + redeem_voucher(I, user) return if(istype(I,/obj/item/weapon/card/id)) if(!powered()) @@ -209,16 +260,23 @@ else if(!inserted_id && user.unEquip(I)) I.forceMove(src) inserted_id = I - interact(user) + tgui_interact(user) return - ..() + return ..() /obj/machinery/mineral/equipment_vendor/dismantle() if(inserted_id) inserted_id.forceMove(loc) //Prevents deconstructing the ORM from deleting whatever ID was inside it. . = ..() -/obj/machinery/mineral/equipment_vendor/proc/RedeemVoucher(obj/item/mining_voucher/voucher, mob/redeemer) +/** + * Called when someone slaps the machine with a mining voucher + * + * Arguments: + * * voucher - The voucher card item + * * redeemer - The person holding it + */ +/obj/machinery/mineral/equipment_vendor/proc/redeem_voucher(obj/item/mining_voucher/voucher, mob/redeemer) var/selection = input(redeemer, "Pick your equipment", "Mining Voucher Redemption") as null|anything in list("Kinetic Accelerator", "Resonator", "Mining Drone", "Advanced Scanner", "Crusher") if(!selection || !Adjacent(redeemer) || voucher.loc != redeemer) return diff --git a/code/modules/mining/ore_redemption_machine/survey_vendor.dm b/code/modules/mining/ore_redemption_machine/survey_vendor.dm index 65b7ccc76d..d69cfe3f27 100644 --- a/code/modules/mining/ore_redemption_machine/survey_vendor.dm +++ b/code/modules/mining/ore_redemption_machine/survey_vendor.dm @@ -8,109 +8,68 @@ circuit = /obj/item/weapon/circuitboard/exploration_equipment_vendor icon_deny = "exploration-deny" //VOREStation Edit icon_vend = "exploration-vend" //VOREStation Add + +/obj/machinery/mineral/equipment_vendor/survey/Initialize(mapload) + . = ..() //VOREStation Edit Start - Heavily modified list - prize_list = list( - new /datum/data/mining_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 1), - new /datum/data/mining_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 10), - new /datum/data/mining_equipment("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 30), - new /datum/data/mining_equipment("GPS Device", /obj/item/device/gps/explorer, 10), - new /datum/data/mining_equipment("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 10), - new /datum/data/mining_equipment("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 10), - new /datum/data/mining_equipment("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 15), - new /datum/data/mining_equipment("Soap", /obj/item/weapon/soap/nanotrasen, 20), - new /datum/data/mining_equipment("Laser Pointer", /obj/item/device/laser_pointer, 90), - new /datum/data/mining_equipment("Geiger Counter", /obj/item/device/geiger, 75), - new /datum/data/mining_equipment("Plush Toy", /obj/random/plushie, 30), - new /datum/data/mining_equipment("Extraction Equipment - Fulton Beacon",/obj/item/fulton_core, 300), - new /datum/data/mining_equipment("Extraction Equipment - Fulton Pack",/obj/item/extraction_pack, 125), - new /datum/data/mining_equipment("Umbrella", /obj/item/weapon/melee/umbrella/random, 20), - new /datum/data/mining_equipment("Shelter Capsule", /obj/item/device/survivalcapsule, 50), - new /datum/data/mining_equipment("Point Transfer Card", /obj/item/weapon/card/mining_point_card/survey, 50), - new /datum/data/mining_equipment("Trauma Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/trauma, 25), - new /datum/data/mining_equipment("Burn Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/burn, 25), - new /datum/data/mining_equipment("Oxy Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/oxy, 25), - new /datum/data/mining_equipment("Detox Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/detox, 25), - new /datum/data/mining_equipment("Injector (L) - Glucose", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose,50), - new /datum/data/mining_equipment("Injector (L) - Panacea", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity,50), - new /datum/data/mining_equipment("Injector (L) - Trauma", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute,50), - new /datum/data/mining_equipment("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 50), - new /datum/data/mining_equipment("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 100), - new /datum/data/mining_equipment("Nanopaste Tube", /obj/item/stack/nanopaste, 100), - new /datum/data/mining_equipment("Mini-Translocator", /obj/item/device/perfect_tele/one_beacon, 120), - new /datum/data/mining_equipment("UAV - Recon Skimmer", /obj/item/device/uav, 400), - new /datum/data/mining_equipment("Thalers - 100", /obj/item/weapon/spacecash/c100, 100), - new /datum/data/mining_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 250), - new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 310), - new /datum/data/mining_equipment("Bar Shelter Capsule", /obj/item/device/survivalcapsule/luxurybar, 1000), - new /datum/data/mining_equipment("Industrial Equipment - Phoron Bore",/obj/item/weapon/gun/magnetic/matfed, 300), - new /datum/data/mining_equipment("Survey Tools - Shovel", /obj/item/weapon/shovel, 40), - new /datum/data/mining_equipment("Survey Tools - Mechanical Trap", /obj/item/weapon/beartrap, 50), - new /datum/data/mining_equipment("Defense Equipment - Smoke Bomb",/obj/item/weapon/grenade/smokebomb, 10), - new /datum/data/mining_equipment("Defense Equipment - Razor Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked, 100), - new /datum/data/mining_equipment("Defense Equipment - Sentry Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/ward, 150), - new /datum/data/mining_equipment("Defense Equipment - Steel Machete", /obj/item/weapon/material/knife/machete, 75), - new /datum/data/mining_equipment("Fishing Net", /obj/item/weapon/material/fishing_net, 50), - new /datum/data/mining_equipment("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 100), - new /datum/data/mining_equipment("Durasteel Fishing Rod", /obj/item/weapon/material/fishing_rod/modern/strong, 750), - new /datum/data/mining_equipment("Survival Equipment - Insulated Poncho", /obj/random/thermalponcho, 75) - ) - //VOREStation Edit End + prize_list = list() + prize_list["Gear"] = list( + EQUIPMENT("Defense Equipment - Plasteel Machete", /obj/item/weapon/material/knife/machete, 500), + EQUIPMENT("Defense Equipment - Razor Drone Deployer", /obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked, 1000), + EQUIPMENT("Defense Equipment - Sentry Drone Deployer", /obj/item/weapon/grenade/spawnergrenade/ward, 1500), + EQUIPMENT("Defense Equipment - Smoke Bomb", /obj/item/weapon/grenade/smokebomb, 100), + EQUIPMENT("Durasteel Fishing Rod", /obj/item/weapon/material/fishing_rod/modern/strong, 7500), + EQUIPMENT("Fishing Net", /obj/item/weapon/material/fishing_net, 500), + EQUIPMENT("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 1000), + EQUIPMENT("Fulton Beacon", /obj/item/fulton_core, 500), + EQUIPMENT("Geiger Counter", /obj/item/device/geiger, 750), + EQUIPMENT("GPS Device", /obj/item/device/gps/mining, 100), + EQUIPMENT("Jump Boots", /obj/item/clothing/shoes/bhop, 2500), + EQUIPMENT("Mini-Translocator", /obj/item/device/perfect_tele/one_beacon, 1200), + EQUIPMENT("Survival Equipment - Insulated Poncho", /obj/random/thermalponcho, 750), + ) + prize_list["Consumables"] = list( + EQUIPMENT("1 Marker Beacon", /obj/item/stack/marker_beacon, 10), + EQUIPMENT("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 100), + EQUIPMENT("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 300), + EQUIPMENT("Fulton Pack", /obj/item/extraction_pack, 1200), + EQUIPMENT("Injector (L) - Glucose", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose, 500), + EQUIPMENT("Injector (L) - Panacea", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity, 500), + EQUIPMENT("Injector (L) - Trauma", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute, 500), + EQUIPMENT("Nanopaste Tube", /obj/item/stack/nanopaste, 1000), + EQUIPMENT("Point Transfer Card", /obj/item/weapon/card/mining_point_card/survey, 500), + EQUIPMENT("Shelter Capsule", /obj/item/device/survivalcapsule, 500), + EQUIPMENT("Burn Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/burn, 250), + EQUIPMENT("Detox Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/detox, 250), + EQUIPMENT("Oxy Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/oxy, 250), + EQUIPMENT("Trauma Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/trauma, 250), + ) + prize_list["Digging Tools"] = list( + EQUIPMENT("Survey Tools - Shovel", /obj/item/weapon/shovel, 40), + EQUIPMENT("Survey Tools - Mechanical Trap", /obj/item/weapon/beartrap, 50), + ) + prize_list["Miscellaneous"] = list( + EQUIPMENT("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 125), + EQUIPMENT("Bar Shelter Capsule", /obj/item/device/survivalcapsule/luxurybar, 10000), + EQUIPMENT("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 150), + EQUIPMENT("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 1000), + EQUIPMENT("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 500), + EQUIPMENT("Industrial Equipment - Phoron Bore", /obj/item/weapon/gun/magnetic/matfed, 3000), + EQUIPMENT("Laser Pointer", /obj/item/device/laser_pointer, 900), + EQUIPMENT("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 3100), + EQUIPMENT("Plush Toy", /obj/random/plushie, 300), + EQUIPMENT("Soap", /obj/item/weapon/soap/nanotrasen, 200), + EQUIPMENT("Thalers - 100", /obj/item/weapon/spacecash/c100, 1000), + EQUIPMENT("Umbrella", /obj/item/weapon/melee/umbrella/random, 200), + EQUIPMENT("UAV - Recon Skimmer", /obj/item/device/uav, 400), + EQUIPMENT("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 125), + ) + //VOREStation Edit End -/obj/machinery/mineral/equipment_vendor/survey/interact(mob/user) - user.set_machine(src) +/obj/machinery/mineral/equipment_vendor/survey/get_points(obj/item/weapon/card/id/target) + if(!istype(target)) + return 0 + return target.survey_points - var/dat - dat +="
" - if(istype(inserted_id)) - dat += "You have [inserted_id.survey_points] survey points collected. Eject ID.
" - else - dat += "No ID inserted. Insert ID.
" - dat += "
" - dat += "
Equipment point cost list:
" - for(var/datum/data/mining_equipment/prize in prize_list) - dat += "" - dat += "
[prize.equipment_name][prize.cost]Purchase
" - var/datum/browser/popup = new(user, "miningvendor", "Survey Equipment Vendor", 400, 600) - popup.set_content(dat) - popup.open() - -/obj/machinery/mineral/equipment_vendor/survey/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["choice"]) - if(istype(inserted_id)) - if(href_list["choice"] == "eject") - to_chat(usr, "You eject the ID from [src]'s card slot.") - usr.put_in_hands(inserted_id) - inserted_id = null - else if(href_list["choice"] == "insert") - var/obj/item/weapon/card/id/I = usr.get_active_hand() - if(istype(I) && !inserted_id && usr.unEquip(I)) - I.forceMove(src) - inserted_id = I - interact(usr) - to_chat(usr, "You insert the ID into [src]'s card slot.") - else - to_chat(usr, "No valid ID.") - flick(icon_deny, src) - - if(href_list["purchase"]) - if(istype(inserted_id)) - var/datum/data/mining_equipment/prize = locate(href_list["purchase"]) - if (!prize || !(prize in prize_list)) - to_chat(usr, "Error: Invalid choice!") - flick(icon_deny, src) - return - if(prize.cost > inserted_id.survey_points) - to_chat(usr, "Error: Insufficent points for [prize.equipment_name]!") - flick(icon_deny, src) - else - inserted_id.survey_points -= prize.cost - to_chat(usr, "[src] clanks to life briefly before vending [prize.equipment_name]!") - flick(icon_vend, src) //VOREStation Add - new prize.equipment_path(drop_location()) - else - to_chat(usr, "Error: Please insert a valid ID!") - flick(icon_deny, src) - updateUsrDialog() +/obj/machinery/mineral/equipment_vendor/survey/remove_points(obj/item/weapon/card/id/target, amt) + target.survey_points -= amt diff --git a/code/modules/mob/living/bot/mulebot.dm b/code/modules/mob/living/bot/mulebot.dm index 67fc8fd051..fa0b76009f 100644 --- a/code/modules/mob/living/bot/mulebot.dm +++ b/code/modules/mob/living/bot/mulebot.dm @@ -61,72 +61,57 @@ load(C) /mob/living/bot/mulebot/attack_hand(var/mob/user) - interact(user) + tgui_interact(user) -/mob/living/bot/mulebot/proc/interact(var/mob/user) - var/dat - dat += "Multiple Utility Load Effector Mk. III

" - dat += "ID: [suffix]
" - dat += "Power: [on ? "On" : "Off"]
" +/mob/living/bot/mulebot/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "MuleBot", "Mulebot [suffix ? "([suffix])" : ""]") + ui.open() - if(!open) - dat += "
Current Load: [load ? load.name : "none"]
" +/mob/living/bot/mulebot/tgui_data(mob/user) + var/list/data = list( + "suffix" = suffix, + "power" = on, + "issilicon" = issilicon(user), + "load" = load, + "locked" = locked, + "auto_return" = auto_return, + "crates_only" = crates_only, + "hatch" = open, + "safety" = safety, + ) + return data - if(locked) - dat += "
Controls are locked" - else - dat += "
Controls are unlocked

" - - if(!locked || issilicon(user)) - dat += "Toggle power
" - dat += "Stop
" - dat += "Proceed
" - dat += "Return to home
" - dat += "Set destination
" - dat += "Set home
" - dat += "Toggle auto return home ([auto_return ? "On" : "Off"])
" - dat += "Toggle non-standard cargo ([crates_only ? "Off" : "On"])
" - - if(load) - dat += "Unload now
" - dat += "
The maintenance hatch is closed.
" - - else - if(!issilicon(user)) - dat += "The maintenance hatch is open.

" - - dat += "Toggle safety ([safety ? "On" : "Off - DANGER"])
" - else - dat += "The bot is in maintenance mode and cannot be controlled.
" - - user << browse("Mulebot [suffix ? "([suffix])" : ""][dat]", "window=mulebot;size=350x500") - onclose(user, "mulebot") - return - -/mob/living/bot/mulebot/Topic(href, href_list) +/mob/living/bot/mulebot/tgui_act(action, params) if(..()) - return - usr.set_machine(src) + return TRUE + add_fingerprint(usr) - switch(href_list["op"]) + switch(action) if("power") if(on) turn_off() else turn_on() visible_message("[usr] switches [on ? "on" : "off"] [src].") + . = TRUE if("stop") obeyCommand("Stop") + . = TRUE if("go") obeyCommand("GoTD") + . = TRUE if("home") obeyCommand("Home") + . = TRUE if("destination") obeyCommand("SetD") + . = TRUE if("sethome") var/new_dest @@ -138,20 +123,23 @@ if(new_dest) home = get_turf(beaconlist[new_dest]) homeName = new_dest + . = TRUE if("unload") unload() + . = TRUE if("autoret") auto_return = !auto_return + . = TRUE if("cargotypes") crates_only = !crates_only + . = TRUE if("safety") safety = !safety - - interact(usr) + . = TRUE /mob/living/bot/mulebot/attackby(var/obj/item/O, var/mob/user) ..() diff --git a/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm b/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm index 6d28b6ce61..a799e2a1c9 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm @@ -4,7 +4,7 @@ set desc = "Tag yourself for delivery through the disposals system." set category = "Robot Commands" - var/new_tag = input("Select the desired destination.", "Set Mail Tag", null) as null|anything in tagger_locations + var/new_tag = input("Select the desired destination.", "Set Mail Tag", null) as null|anything in GLOB.tagger_locations if(!new_tag) mail_destination = "" diff --git a/code/modules/mob/living/silicon/robot/drone/drone_console.dm b/code/modules/mob/living/silicon/robot/drone/drone_console.dm index 94b8bb2e2c..77486ecfff 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_console.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_console.dm @@ -53,7 +53,7 @@ data["fabricator"] = dronefab data["fabPower"] = dronefab?.produce_drones - data["areas"] = tagger_locations + data["areas"] = GLOB.tagger_locations data["selected_area"] = "[drone_call_area]" return data @@ -65,7 +65,7 @@ switch(action) if("set_dcall_area") var/t_area = params["area"] - if(!t_area || !(t_area in tagger_locations)) + if(!t_area || !(t_area in GLOB.tagger_locations)) return drone_call_area = t_area diff --git a/code/modules/overmap/ships/computers/shuttle.dm b/code/modules/overmap/ships/computers/shuttle.dm index 42904d2a42..f51587d594 100644 --- a/code/modules/overmap/ships/computers/shuttle.dm +++ b/code/modules/overmap/ships/computers/shuttle.dm @@ -2,9 +2,9 @@ /obj/machinery/computer/shuttle_control/explore name = "general shuttle control console" circuit = /obj/item/weapon/circuitboard/shuttle_console/explore - ui_template = "shuttle_control_console_exploration.tmpl" + tgui_subtemplate = "ShuttleControlConsoleExploration" -/obj/machinery/computer/shuttle_control/explore/get_ui_data(var/datum/shuttle/autodock/overmap/shuttle) +/obj/machinery/computer/shuttle_control/explore/shuttlerich_tgui_data(var/datum/shuttle/autodock/overmap/shuttle) . = ..() if(istype(shuttle)) var/total_gas = 0 @@ -25,22 +25,28 @@ "fuel_span" = fuel_span ) -/obj/machinery/computer/shuttle_control/explore/handle_topic_href(var/datum/shuttle/autodock/overmap/shuttle, var/list/href_list) +/obj/machinery/computer/shuttle_control/explore/tgui_act(action, list/params) + if(..()) + return TRUE + + var/datum/shuttle/autodock/overmap/shuttle = SSshuttles.shuttles[shuttle_tag] + if(!istype(shuttle)) + to_chat(usr, "Unable to establish link with the shuttle.") + return TRUE + if(ismob(usr)) var/mob/user = usr shuttle.operator_skill = user.get_skill_value(/datum/skill/pilot) - if((. = ..()) != null) - return - - if(href_list["pick"]) - var/list/possible_d = shuttle.get_possible_destinations() - var/D - if(possible_d.len) - D = input("Choose shuttle destination", "Shuttle Destination") as null|anything in possible_d - else - to_chat(usr,"No valid landing sites in range.") - possible_d = shuttle.get_possible_destinations() - if(CanInteract(usr, global.default_state) && (D in possible_d)) - shuttle.set_destination(possible_d[D]) - return TOPIC_REFRESH + switch(action) + if("pick") + var/list/possible_d = shuttle.get_possible_destinations() + var/D + if(possible_d.len) + D = input("Choose shuttle destination", "Shuttle Destination") as null|anything in possible_d + else + to_chat(usr,"No valid landing sites in range.") + possible_d = shuttle.get_possible_destinations() + if(CanInteract(usr, global.default_state) && (D in possible_d)) + shuttle.set_destination(possible_d[D]) + return TRUE diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 5618257494..3975ee2c22 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -444,8 +444,12 @@ // if paper is not in usr, then it must be near them, or in a clipboard or folder, which must be in or near usr - if(src.loc != usr && !src.Adjacent(usr) && !((istype(src.loc, /obj/item/weapon/clipboard) || istype(src.loc, /obj/item/weapon/folder)) && (src.loc.loc == usr || src.loc.Adjacent(usr)) ) ) + if(istype(loc, /obj/item/weapon/clipboard) || istype(loc, /obj/structure/noticeboard) || istype(loc, /obj/item/weapon/folder)) + if(loc.loc != usr && !in_range(loc, usr)) + return + else if(loc != usr && !Adjacent(usr)) return + /* t = checkhtml(t) diff --git a/code/modules/persistence/noticeboard.dm b/code/modules/persistence/noticeboard.dm index ad8cfef590..046972ee36 100644 --- a/code/modules/persistence/noticeboard.dm +++ b/code/modules/persistence/noticeboard.dm @@ -20,36 +20,6 @@ if(LAZYLEN(notices) >= max_notices) break - // Automatically place noticeboards that aren't mapped to specific positions. - if(pixel_x == 0 && pixel_y == 0) - - var/turf/here = get_turf(src) - var/placing = 0 - for(var/checkdir in GLOB.cardinal) - var/turf/T = get_step(here, checkdir) - if(T.density) - placing = checkdir - break - for(var/thing in T) - var/atom/A = thing - if(A.simulated && !A.CanPass(src, T)) - placing = checkdir - break - - switch(placing) - if(NORTH) - pixel_x = 0 - pixel_y = 32 - if(SOUTH) - pixel_x = 0 - pixel_y = -32 - if(EAST) - pixel_x = 32 - pixel_y = 0 - if(WEST) - pixel_x = -32 - pixel_y = 0 - update_icon() /obj/structure/noticeboard/proc/add_paper(var/atom/movable/paper, var/skip_icon_update) @@ -77,16 +47,16 @@ QDEL_NULL_LIST(notices) . = ..() -/obj/structure/noticeboard/ex_act(var/severity) +/obj/structure/noticeboard/ex_act(severity) dismantle() /obj/structure/noticeboard/update_icon() icon_state = "[base_icon_state][LAZYLEN(notices)]" -/obj/structure/noticeboard/attackby(var/obj/item/weapon/thing, var/mob/user) - if(thing.is_screwdriver()) - var/choice = input("Which direction do you wish to place the noticeboard?", "Noticeboard Offset") as null|anything in list("North", "South", "East", "West") - if(choice && Adjacent(user) && thing.loc == user && !user.incapacitated()) +/obj/structure/noticeboard/attackby(obj/item/I, mob/user) + if(I.is_screwdriver()) + var/choice = input("Which direction do you wish to place the noticeboard?", "Noticeboard Offset") as null|anything in list("North", "South", "East", "West", "No Offset") + if(choice && Adjacent(user) && I.loc == user && !user.incapacitated()) playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1) switch(choice) if("North") @@ -101,27 +71,29 @@ if("West") pixel_x = -32 pixel_y = 0 + if("No Offset") + return return - else if(thing.is_wrench()) - visible_message(SPAN_WARNING("\The [user] begins dismantling \the [src].")) + else if(I.is_wrench()) + visible_message("[user] begins dismantling [src].") playsound(loc, 'sound/items/Ratchet.ogg', 50, 1) if(do_after(user, 50, src)) - visible_message(SPAN_DANGER("\The [user] has dismantled \the [src]!")) + visible_message("[user] has dismantled [src]!") dismantle() return - else if(istype(thing, /obj/item/weapon/paper) || istype(thing, /obj/item/weapon/photo)) + else if(istype(I, /obj/item/weapon/paper) || istype(I, /obj/item/weapon/photo)) if(jobban_isbanned(user, "Graffiti")) - to_chat(user, SPAN_WARNING("You are banned from leaving persistent information across rounds.")) + to_chat(user, "You are banned from leaving persistent information across rounds.") else - if(LAZYLEN(notices) < max_notices && user.unEquip(thing, src)) + if(LAZYLEN(notices) < max_notices && user.unEquip(I, src)) add_fingerprint(user) - add_paper(thing) - to_chat(user, SPAN_NOTICE("You pin \the [thing] to \the [src].")) - SSpersistence.track_value(thing, /datum/persistent/paper) + add_paper(I) + to_chat(user, "You pin [I] to [src].") + SSpersistence.track_value(I, /datum/persistent/paper) else - to_chat(user, SPAN_WARNING("You hesitate, certain \the [thing] will not be seen among the many others already attached to \the [src].")) + to_chat(user, "You hesitate, certain [I] will not be seen among the many others already attached to \the [src].") return - ..() + return ..() /obj/structure/noticeboard/attack_ai(var/mob/user) examine(user) @@ -129,56 +101,71 @@ /obj/structure/noticeboard/attack_hand(var/mob/user) examine(user) -/obj/structure/noticeboard/examine(var/mob/user) - . = ..() - if(.) - var/list/dat = list("") - for(var/thing in notices) - LAZYADD(dat, "") - var/datum/browser/popup = new(user, "noticeboard-\ref[src]", "Noticeboard") - popup.set_content(jointext(dat, null)) - popup.open() +/obj/structure/noticeboard/examine(mob/user) + tgui_interact(user) + return list() -/obj/structure/noticeboard/Topic(var/mob/user, var/list/href_list) - if(href_list["read"]) - var/obj/item/weapon/paper/P = locate(href_list["read"]) - if(P && P.loc == src) - P.show_content(user) - . = TOPIC_HANDLED +/obj/structure/noticeboard/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "NoticeBoard", name) + ui.open() - if(href_list["look"]) - var/obj/item/weapon/photo/P = locate(href_list["look"]) - if(P && P.loc == src) - P.show(user) - . = TOPIC_HANDLED +/obj/structure/noticeboard/tgui_data(mob/user) + var/list/data = ..() + + data["notices"] = list() + for(var/obj/item/I in notices) + data["notices"].Add(list(list( + "ispaper" = istype(I, /obj/item/weapon/paper), + "isphoto" = istype(I, /obj/item/weapon/photo), + "name" = I.name, + "ref" = "\ref[I]", + ))) - if(href_list["remove"]) - remove_paper(locate(href_list["remove"])) - add_fingerprint(user) - . = TOPIC_REFRESH + return data - if(href_list["write"]) - if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open - return - var/obj/item/P = locate(href_list["write"]) - if((P && P.loc == src)) //ifthe paper's on the board - var/mob/living/M = usr - if(istype(M)) - var/obj/item/weapon/pen/E = M.get_type_in_hands(/obj/item/weapon/pen) - if(E) - add_fingerprint(M) - P.attackby(E, usr) - else - to_chat(M, "You'll need something to write with!") - . = TOPIC_REFRESH +/obj/structure/noticeboard/tgui_act(action, params) + if(..()) + return TRUE - if(. == TOPIC_REFRESH) - interact(user) + switch(action) + if("read") + var/obj/item/weapon/paper/P = locate(params["ref"]) + if(P && P.loc == src) + P.show_content(usr) + . = TRUE + + if("look") + var/obj/item/weapon/photo/P = locate(params["ref"]) + if(P && P.loc == src) + P.show(usr) + . = TRUE + + if("remove") + if(!in_range(src, usr)) + return FALSE + var/obj/item/I = locate(params["ref"]) + remove_paper(I) + if(istype(I)) + usr.put_in_hands(I) + add_fingerprint(usr) + . = TRUE + + if("write") + if(!in_range(src, usr)) + return FALSE + var/obj/item/P = locate(params["ref"]) + if((P && P.loc == src)) //if the paper's on the board + var/mob/living/M = usr + if(istype(M)) + var/obj/item/weapon/pen/E = M.get_type_in_hands(/obj/item/weapon/pen) + if(E) + add_fingerprint(M) + P.attackby(E, usr) + else + to_chat(M, "You'll need something to write with!") + . = TRUE /obj/structure/noticeboard/anomaly notices = 5 @@ -190,32 +177,32 @@ P.info = "
We keep test dummies in pens here for a reason, so standard procedure should be to activate newfound alien artifacts and place the two in close proximity. Promising items I might even approve monkey testing on." P.stamped = list(/obj/item/weapon/stamp/rd) P.overlays = list("paper_stamped_rd") - src.contents += P + contents += P P = new() P.name = "Memo RE: materials gathering" P.info = "Corasang,
the hands-on approach to gathering our samples may very well be slow at times, but it's safer than allowing the blundering miners to roll willy-nilly over our dig sites in their mechs, destroying everything in the process. And don't forget the escavation tools on your way out there!
- R.W" P.stamped = list(/obj/item/weapon/stamp/rd) P.overlays = list("paper_stamped_rd") - src.contents += P + contents += P P = new() P.name = "Memo RE: ethical quandaries" P.info = "Darion-

I don't care what his rank is, our business is that of science and knowledge - questions of moral application do not come into this. Sure, so there are those who would employ the energy-wave particles my modified device has managed to abscond for their own personal gain, but I can hardly see the practical benefits of some of these artifacts our benefactors left behind. Ward--" P.stamped = list(/obj/item/weapon/stamp/rd) P.overlays = list("paper_stamped_rd") - src.contents += P + contents += P P = new() P.name = "READ ME! Before you people destroy any more samples" P.info = "how many times do i have to tell you people, these xeno-arch samples are del-i-cate, and should be handled so! careful application of a focussed, concentrated heat or some corrosive liquids should clear away the extraneous carbon matter, while application of an energy beam will most decidedly destroy it entirely - like someone did to the chemical dispenser! W, the one who signs your paychecks" P.stamped = list(/obj/item/weapon/stamp/rd) P.overlays = list("paper_stamped_rd") - src.contents += P + contents += P P = new() P.name = "Reminder regarding the anomalous material suits" P.info = "Do you people think the anomaly suits are cheap to come by? I'm about a hair trigger away from instituting a log book for the damn things. Only wear them if you're going out for a dig, and for god's sake don't go tramping around in them unless you're field testing something, R" P.stamped = list(/obj/item/weapon/stamp/rd) P.overlays = list("paper_stamped_rd") - src.contents += P \ No newline at end of file + contents += P \ No newline at end of file diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 3437c8b582..1d46e16ce5 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -1210,7 +1210,7 @@ New() . = ..() dpdir = dir | turn(dir, 180) - if(sort_tag) tagger_locations |= sort_tag + if(sort_tag) GLOB.tagger_locations |= sort_tag updatename() updatedesc() update() @@ -1276,7 +1276,7 @@ New() . = ..() - if(sortType) tagger_locations |= sortType + if(sortType) GLOB.tagger_locations |= sortType updatedir() updatename() diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index 315b492e6b..a97c2894c2 100755 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -14,100 +14,100 @@ var/label_x var/tag_x - attack_hand(mob/user as mob) - unwrap() +/obj/structure/bigDelivery/attack_hand(mob/user as mob) + unwrap() - proc/unwrap() - playsound(src, 'sound/items/package_unwrap.ogg', 50, 1) - // Destroy will drop our wrapped object on the turf, so let it. - qdel(src) +/obj/structure/bigDelivery/proc/unwrap() + playsound(src, 'sound/items/package_unwrap.ogg', 50, 1) + // Destroy will drop our wrapped object on the turf, so let it. + qdel(src) - attackby(obj/item/W as obj, mob/user as mob) - if(istype(W, /obj/item/device/destTagger)) - var/obj/item/device/destTagger/O = W - if(O.currTag) - if(src.sortTag != O.currTag) - to_chat(user, "You have labeled the destination as [O.currTag].") - if(!src.sortTag) - src.sortTag = O.currTag - update_icon() - else - src.sortTag = O.currTag - playsound(src, 'sound/machines/twobeep.ogg', 50, 1) +/obj/structure/bigDelivery/attackby(obj/item/W as obj, mob/user as mob) + if(istype(W, /obj/item/device/destTagger)) + var/obj/item/device/destTagger/O = W + if(O.currTag) + if(src.sortTag != O.currTag) + to_chat(user, "You have labeled the destination as [O.currTag].") + if(!src.sortTag) + src.sortTag = O.currTag + update_icon() else - to_chat(user, "The package is already labeled for [O.currTag].") + src.sortTag = O.currTag + playsound(src, 'sound/machines/twobeep.ogg', 50, 1) else - to_chat(user, "You need to set a destination first!") + to_chat(user, "The package is already labeled for [O.currTag].") + else + to_chat(user, "You need to set a destination first!") - else if(istype(W, /obj/item/weapon/pen)) - switch(alert("What would you like to alter?",,"Title","Description", "Cancel")) - if("Title") - var/str = sanitizeSafe(input(usr,"Label text?","Set label",""), MAX_NAME_LEN) - if(!str || !length(str)) - to_chat(user, " Invalid text.") - return - user.visible_message("\The [user] titles \the [src] with \a [W], marking down: \"[str]\"",\ - "You title \the [src]: \"[str]\"",\ - "You hear someone scribbling a note.") - playsound(src, pick('sound/bureaucracy/pen1.ogg','sound/bureaucracy/pen2.ogg'), 20) - name = "[name] ([str])" - if(!examtext && !nameset) - nameset = 1 - update_icon() - else - nameset = 1 - if("Description") - var/str = sanitize(input(usr,"Label text?","Set label","")) - if(!str || !length(str)) - to_chat(user, "Invalid text.") - return - if(!examtext && !nameset) - examtext = str - update_icon() - else - examtext = str - user.visible_message("\The [user] labels \the [src] with \a [W], scribbling down: \"[examtext]\"",\ - "You label \the [src]: \"[examtext]\"",\ - "You hear someone scribbling a note.") - playsound(src, pick('sound/bureaucracy/pen1.ogg','sound/bureaucracy/pen2.ogg'), 20) - return + else if(istype(W, /obj/item/weapon/pen)) + switch(alert("What would you like to alter?",,"Title","Description", "Cancel")) + if("Title") + var/str = sanitizeSafe(input(usr,"Label text?","Set label",""), MAX_NAME_LEN) + if(!str || !length(str)) + to_chat(user, " Invalid text.") + return + user.visible_message("\The [user] titles \the [src] with \a [W], marking down: \"[str]\"",\ + "You title \the [src]: \"[str]\"",\ + "You hear someone scribbling a note.") + playsound(src, pick('sound/bureaucracy/pen1.ogg','sound/bureaucracy/pen2.ogg'), 20) + name = "[name] ([str])" + if(!examtext && !nameset) + nameset = 1 + update_icon() + else + nameset = 1 + if("Description") + var/str = sanitize(input(usr,"Label text?","Set label","")) + if(!str || !length(str)) + to_chat(user, "Invalid text.") + return + if(!examtext && !nameset) + examtext = str + update_icon() + else + examtext = str + user.visible_message("\The [user] labels \the [src] with \a [W], scribbling down: \"[examtext]\"",\ + "You label \the [src]: \"[examtext]\"",\ + "You hear someone scribbling a note.") + playsound(src, pick('sound/bureaucracy/pen1.ogg','sound/bureaucracy/pen2.ogg'), 20) + return - update_icon() - overlays = new() - if(nameset || examtext) - var/image/I = new/image('icons/obj/storage.dmi',"delivery_label") - if(icon_state == "deliverycloset") - I.pixel_x = 2 - if(label_y == null) - label_y = rand(-6, 11) - I.pixel_y = label_y - else if(icon_state == "deliverycrate") - if(label_x == null) - label_x = rand(-8, 6) - I.pixel_x = label_x - I.pixel_y = -3 - overlays += I - if(src.sortTag) - var/image/I = new/image('icons/obj/storage.dmi',"delivery_tag") - if(icon_state == "deliverycloset") - if(tag_x == null) - tag_x = rand(-2, 3) - I.pixel_x = tag_x - I.pixel_y = 9 - else if(icon_state == "deliverycrate") - if(tag_x == null) - tag_x = rand(-8, 6) - I.pixel_x = tag_x - I.pixel_y = -3 - overlays += I +/obj/structure/bigDelivery/update_icon() + overlays = new() + if(nameset || examtext) + var/image/I = new/image('icons/obj/storage.dmi',"delivery_label") + if(icon_state == "deliverycloset") + I.pixel_x = 2 + if(label_y == null) + label_y = rand(-6, 11) + I.pixel_y = label_y + else if(icon_state == "deliverycrate") + if(label_x == null) + label_x = rand(-8, 6) + I.pixel_x = label_x + I.pixel_y = -3 + overlays += I + if(src.sortTag) + var/image/I = new/image('icons/obj/storage.dmi',"delivery_tag") + if(icon_state == "deliverycloset") + if(tag_x == null) + tag_x = rand(-2, 3) + I.pixel_x = tag_x + I.pixel_y = 9 + else if(icon_state == "deliverycrate") + if(tag_x == null) + tag_x = rand(-8, 6) + I.pixel_x = tag_x + I.pixel_y = -3 + overlays += I - examine(mob/user) - . = ..() - if(get_dist(user, src) <= 4) - if(sortTag) - . += "It is labeled \"[sortTag]\"" - if(examtext) - . += "It has a note attached which reads, \"[examtext]\"" +/obj/structure/bigDelivery/examine(mob/user) + . = ..() + if(get_dist(user, src) <= 4) + if(sortTag) + . += "It is labeled \"[sortTag]\"" + if(examtext) + . += "It has a note attached which reads, \"[examtext]\"" /obj/item/smallDelivery desc = "A small wrapped package." @@ -121,100 +121,100 @@ var/nameset = 0 var/tag_x - attack_self(mob/user as mob) - if (src.wrapped) //sometimes items can disappear. For example, bombs. --rastaf0 - wrapped.loc = user.loc - if(ishuman(user)) - user.put_in_hands(wrapped) - else - wrapped.loc = get_turf(src) +/obj/item/smallDelivery/attack_self(mob/user as mob) + if (src.wrapped) //sometimes items can disappear. For example, bombs. --rastaf0 + wrapped.loc = user.loc + if(ishuman(user)) + user.put_in_hands(wrapped) + else + wrapped.loc = get_turf(src) - qdel(src) - return + qdel(src) + return - attackby(obj/item/W as obj, mob/user as mob) - if(istype(W, /obj/item/device/destTagger)) - var/obj/item/device/destTagger/O = W - if(O.currTag) - if(src.sortTag != O.currTag) - to_chat(user, "You have labeled the destination as [O.currTag].") - if(!src.sortTag) - src.sortTag = O.currTag - update_icon() - else - src.sortTag = O.currTag - playsound(src, 'sound/machines/twobeep.ogg', 50, 1) +/obj/item/smallDelivery/attackby(obj/item/W as obj, mob/user as mob) + if(istype(W, /obj/item/device/destTagger)) + var/obj/item/device/destTagger/O = W + if(O.currTag) + if(src.sortTag != O.currTag) + to_chat(user, "You have labeled the destination as [O.currTag].") + if(!src.sortTag) + src.sortTag = O.currTag + update_icon() else - to_chat(user, "The package is already labeled for [O.currTag].") + src.sortTag = O.currTag + playsound(src, 'sound/machines/twobeep.ogg', 50, 1) else - to_chat(user, "You need to set a destination first!") + to_chat(user, "The package is already labeled for [O.currTag].") + else + to_chat(user, "You need to set a destination first!") - else if(istype(W, /obj/item/weapon/pen)) - switch(alert("What would you like to alter?",,"Title","Description", "Cancel")) - if("Title") - var/str = sanitizeSafe(input(usr,"Label text?","Set label",""), MAX_NAME_LEN) - if(!str || !length(str)) - to_chat(user, " Invalid text.") - return - user.visible_message("\The [user] titles \the [src] with \a [W], marking down: \"[str]\"",\ - "You title \the [src]: \"[str]\"",\ - "You hear someone scribbling a note.") - playsound(src, pick('sound/bureaucracy/pen1.ogg','sound/bureaucracy/pen2.ogg'), 20) - name = "[name] ([str])" - if(!examtext && !nameset) - nameset = 1 - update_icon() - else - nameset = 1 + else if(istype(W, /obj/item/weapon/pen)) + switch(alert("What would you like to alter?",,"Title","Description", "Cancel")) + if("Title") + var/str = sanitizeSafe(input(usr,"Label text?","Set label",""), MAX_NAME_LEN) + if(!str || !length(str)) + to_chat(user, " Invalid text.") + return + user.visible_message("\The [user] titles \the [src] with \a [W], marking down: \"[str]\"",\ + "You title \the [src]: \"[str]\"",\ + "You hear someone scribbling a note.") + playsound(src, pick('sound/bureaucracy/pen1.ogg','sound/bureaucracy/pen2.ogg'), 20) + name = "[name] ([str])" + if(!examtext && !nameset) + nameset = 1 + update_icon() + else + nameset = 1 - if("Description") - var/str = sanitize(input(usr,"Label text?","Set label","")) - if(!str || !length(str)) - to_chat(user, "Invalid text.") - return - if(!examtext && !nameset) - examtext = str - update_icon() - else - examtext = str - user.visible_message("\The [user] labels \the [src] with \a [W], scribbling down: \"[examtext]\"",\ - "You label \the [src]: \"[examtext]\"",\ - "You hear someone scribbling a note.") - playsound(src, pick('sound/bureaucracy/pen1.ogg','sound/bureaucracy/pen2.ogg'), 20) - return + if("Description") + var/str = sanitize(input(usr,"Label text?","Set label","")) + if(!str || !length(str)) + to_chat(user, "Invalid text.") + return + if(!examtext && !nameset) + examtext = str + update_icon() + else + examtext = str + user.visible_message("\The [user] labels \the [src] with \a [W], scribbling down: \"[examtext]\"",\ + "You label \the [src]: \"[examtext]\"",\ + "You hear someone scribbling a note.") + playsound(src, pick('sound/bureaucracy/pen1.ogg','sound/bureaucracy/pen2.ogg'), 20) + return - update_icon() - overlays = new() - if((nameset || examtext) && icon_state != "deliverycrate1") - var/image/I = new/image('icons/obj/storage.dmi',"delivery_label") - if(icon_state == "deliverycrate5") - I.pixel_y = -1 - overlays += I - if(src.sortTag) - var/image/I = new/image('icons/obj/storage.dmi',"delivery_tag") - switch(icon_state) - if("deliverycrate1") - I.pixel_y = -5 - if("deliverycrate2") - I.pixel_y = -2 - if("deliverycrate3") - I.pixel_y = 0 - if("deliverycrate4") - if(tag_x == null) - tag_x = rand(0,5) - I.pixel_x = tag_x - I.pixel_y = 3 - if("deliverycrate5") - I.pixel_y = -3 - overlays += I +/obj/item/smallDelivery/update_icon() + overlays = new() + if((nameset || examtext) && icon_state != "deliverycrate1") + var/image/I = new/image('icons/obj/storage.dmi',"delivery_label") + if(icon_state == "deliverycrate5") + I.pixel_y = -1 + overlays += I + if(src.sortTag) + var/image/I = new/image('icons/obj/storage.dmi',"delivery_tag") + switch(icon_state) + if("deliverycrate1") + I.pixel_y = -5 + if("deliverycrate2") + I.pixel_y = -2 + if("deliverycrate3") + I.pixel_y = 0 + if("deliverycrate4") + if(tag_x == null) + tag_x = rand(0,5) + I.pixel_x = tag_x + I.pixel_y = 3 + if("deliverycrate5") + I.pixel_y = -3 + overlays += I - examine(mob/user) - . = ..() - if(get_dist(user, src) <= 4) - if(sortTag) - . += "It is labeled \"[sortTag]\"" - if(examtext) - . += "It has a note attached which reads, \"[examtext]\"" +/obj/item/smallDelivery/examine(mob/user) + . = ..() + if(get_dist(user, src) <= 4) + if(sortTag) + . += "It is labeled \"[sortTag]\"" + if(examtext) + . += "It has a note attached which reads, \"[examtext]\"" /obj/item/weapon/packageWrap name = "package wrapper" @@ -226,95 +226,95 @@ drop_sound = 'sound/items/drop/wrapper.ogg' - afterattack(var/obj/target as obj, mob/user as mob, proximity) - if(!proximity) return - if(!istype(target)) //this really shouldn't be necessary (but it is). -Pete - return - if(istype(target, /obj/item/smallDelivery) || istype(target,/obj/structure/bigDelivery) \ - || istype(target, /obj/item/weapon/gift) || istype(target, /obj/item/weapon/evidencebag)) - return - if(target.anchored) - return - if(target in user) - return - if(user in target) //no wrapping closets that you are inside - it's not physically possible - return - - user.attack_log += text("\[[time_stamp()]\] Has used [src.name] on \ref[target]") - - - if (istype(target, /obj/item) && !(istype(target, /obj/item/weapon/storage) && !istype(target,/obj/item/weapon/storage/box))) - var/obj/item/O = target - if (src.amount > 1) - var/obj/item/smallDelivery/P = new /obj/item/smallDelivery(get_turf(O.loc)) //Aaannd wrap it up! - if(!istype(O.loc, /turf)) - if(user.client) - user.client.screen -= O - P.wrapped = O - O.forceMove(P) - P.w_class = O.w_class - var/i = round(O.w_class) - if(i in list(1,2,3,4,5)) - P.icon_state = "deliverycrate[i]" - switch(i) - if(1) P.name = "tiny parcel" - if(3) P.name = "normal-sized parcel" - if(4) P.name = "large parcel" - if(5) P.name = "huge parcel" - if(i < 1) - P.icon_state = "deliverycrate1" - P.name = "tiny parcel" - if(i > 5) - P.icon_state = "deliverycrate5" - P.name = "huge parcel" - P.add_fingerprint(usr) - O.add_fingerprint(usr) - src.add_fingerprint(usr) - src.amount -= 1 - user.visible_message("\The [user] wraps \a [target] with \a [src].",\ - "You wrap \the [target], leaving [amount] units of paper on \the [src].",\ - "You hear someone taping paper around a small object.") - playsound(src, 'sound/items/package_wrap.ogg', 50, 1) - else if (istype(target, /obj/structure/closet/crate)) - var/obj/structure/closet/crate/O = target - if (src.amount > 3 && !O.opened) - var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc)) - P.icon_state = "deliverycrate" - P.wrapped = O - O.loc = P - src.amount -= 3 - user.visible_message("\The [user] wraps \a [target] with \a [src].",\ - "You wrap \the [target], leaving [amount] units of paper on \the [src].",\ - "You hear someone taping paper around a large object.") - playsound(src, 'sound/items/package_wrap.ogg', 50, 1) - else if(src.amount < 3) - to_chat(user, "You need more paper.") - else if (istype (target, /obj/structure/closet)) - var/obj/structure/closet/O = target - if (src.amount > 3 && !O.opened) - var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc)) - P.wrapped = O - O.sealed = 1 - O.loc = P - src.amount -= 3 - user.visible_message("\The [user] wraps \a [target] with \a [src].",\ - "You wrap \the [target], leaving [amount] units of paper on \the [src].",\ - "You hear someone taping paper around a large object.") - playsound(src, 'sound/items/package_wrap.ogg', 50, 1) - else if(src.amount < 3) - to_chat(user, "You need more paper.") - else - to_chat(user, "The object you are trying to wrap is unsuitable for the sorting machinery!") - if (src.amount <= 0) - new /obj/item/weapon/c_tube( src.loc ) - qdel(src) - return +/obj/item/weapon/packageWrap/afterattack(var/obj/target as obj, mob/user as mob, proximity) + if(!proximity) return + if(!istype(target)) //this really shouldn't be necessary (but it is). -Pete + return + if(istype(target, /obj/item/smallDelivery) || istype(target,/obj/structure/bigDelivery) \ + || istype(target, /obj/item/weapon/gift) || istype(target, /obj/item/weapon/evidencebag)) + return + if(target.anchored) + return + if(target in user) + return + if(user in target) //no wrapping closets that you are inside - it's not physically possible return - examine(mob/user) - . = ..() - if(get_dist(user, src) <= 0) - . += "There are [amount] units of package wrap left!" + user.attack_log += text("\[[time_stamp()]\] Has used [src.name] on \ref[target]") + + + if (istype(target, /obj/item) && !(istype(target, /obj/item/weapon/storage) && !istype(target,/obj/item/weapon/storage/box))) + var/obj/item/O = target + if (src.amount > 1) + var/obj/item/smallDelivery/P = new /obj/item/smallDelivery(get_turf(O.loc)) //Aaannd wrap it up! + if(!istype(O.loc, /turf)) + if(user.client) + user.client.screen -= O + P.wrapped = O + O.forceMove(P) + P.w_class = O.w_class + var/i = round(O.w_class) + if(i in list(1,2,3,4,5)) + P.icon_state = "deliverycrate[i]" + switch(i) + if(1) P.name = "tiny parcel" + if(3) P.name = "normal-sized parcel" + if(4) P.name = "large parcel" + if(5) P.name = "huge parcel" + if(i < 1) + P.icon_state = "deliverycrate1" + P.name = "tiny parcel" + if(i > 5) + P.icon_state = "deliverycrate5" + P.name = "huge parcel" + P.add_fingerprint(usr) + O.add_fingerprint(usr) + src.add_fingerprint(usr) + src.amount -= 1 + user.visible_message("\The [user] wraps \a [target] with \a [src].",\ + "You wrap \the [target], leaving [amount] units of paper on \the [src].",\ + "You hear someone taping paper around a small object.") + playsound(src, 'sound/items/package_wrap.ogg', 50, 1) + else if (istype(target, /obj/structure/closet/crate)) + var/obj/structure/closet/crate/O = target + if (src.amount > 3 && !O.opened) + var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc)) + P.icon_state = "deliverycrate" + P.wrapped = O + O.loc = P + src.amount -= 3 + user.visible_message("\The [user] wraps \a [target] with \a [src].",\ + "You wrap \the [target], leaving [amount] units of paper on \the [src].",\ + "You hear someone taping paper around a large object.") + playsound(src, 'sound/items/package_wrap.ogg', 50, 1) + else if(src.amount < 3) + to_chat(user, "You need more paper.") + else if (istype (target, /obj/structure/closet)) + var/obj/structure/closet/O = target + if (src.amount > 3 && !O.opened) + var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc)) + P.wrapped = O + O.sealed = 1 + O.loc = P + src.amount -= 3 + user.visible_message("\The [user] wraps \a [target] with \a [src].",\ + "You wrap \the [target], leaving [amount] units of paper on \the [src].",\ + "You hear someone taping paper around a large object.") + playsound(src, 'sound/items/package_wrap.ogg', 50, 1) + else if(src.amount < 3) + to_chat(user, "You need more paper.") + else + to_chat(user, "The object you are trying to wrap is unsuitable for the sorting machinery!") + if (src.amount <= 0) + new /obj/item/weapon/c_tube( src.loc ) + qdel(src) + return + return + +/obj/item/weapon/packageWrap/examine(mob/user) + . = ..() + if(get_dist(user, src) <= 0) + . += "There are [amount] units of package wrap left!" /obj/structure/bigDelivery/Destroy() if(wrapped) //sometimes items can disappear. For example, bombs. --rastaf0 @@ -338,30 +338,34 @@ item_state = "electronic" slot_flags = SLOT_BELT - proc/openwindow(mob/user as mob) - var/dat = "

TagMaster 2.3

" +/obj/item/device/destTagger/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "DestinationTagger", name) + ui.open() - dat += "
[thing]") - if(istype(thing, /obj/item/weapon/paper)) - LAZYADD(dat, "ReadWrite") - else if(istype(thing, /obj/item/weapon/photo)) - LAZYADD(dat, "Look") - LAZYADD(dat, "Remove
" - for(var/i = 1, i <= tagger_locations.len, i++) - dat += "" +/obj/item/device/destTagger/tgui_data(mob/user, datum/tgui/ui) + var/list/data = ..() - if (i%4==0) - dat += "" + data["currTag"] = currTag + data["taggerLocs"] = GLOB.tagger_locations - dat += "
[tagger_locations[i]]

Current Selection: [currTag ? currTag : "None"]
" + return data - user << browse(dat, "window=destTagScreen;size=450x350") - onclose(user, "destTagScreen") +/obj/item/device/destTagger/attack_self(mob/user as mob) + tgui_interact(user) - attack_self(mob/user as mob) - openwindow(user) - return - - Topic(href, href_list) - src.add_fingerprint(usr) - if(href_list["nextTag"] && href_list["nextTag"] in tagger_locations) - src.currTag = href_list["nextTag"] - openwindow(usr) +/obj/item/device/destTagger/tgui_act(action, params) + if(..()) + return TRUE + add_fingerprint(usr) + switch(action) + if("set_tag") + var/new_tag = params["tag"] + if(!(new_tag in GLOB.tagger_locations)) + return FALSE + currTag = new_tag + . = TRUE /obj/machinery/disposal/deliveryChute name = "Delivery chute" @@ -371,94 +375,94 @@ var/c_mode = 0 - New() - ..() - spawn(5) - trunk = locate() in src.loc - if(trunk) - trunk.linked = src // link the pipe trunk to self +/obj/machinery/disposal/deliveryChute/New() + ..() + spawn(5) + trunk = locate() in src.loc + if(trunk) + trunk.linked = src // link the pipe trunk to self - interact() - return +/obj/machinery/disposal/deliveryChute/interact() + return +/obj/machinery/disposal/deliveryChute/update() + return + +/obj/machinery/disposal/deliveryChute/Bumped(var/atom/movable/AM) //Go straight into the chute + if(istype(AM, /obj/item/projectile) || istype(AM, /obj/effect) || istype(AM, /obj/mecha)) return + switch(dir) + if(NORTH) + if(AM.loc.y != src.loc.y+1) return + if(EAST) + if(AM.loc.x != src.loc.x+1) return + if(SOUTH) + if(AM.loc.y != src.loc.y-1) return + if(WEST) + if(AM.loc.x != src.loc.x-1) return + + if(istype(AM, /obj)) + var/obj/O = AM + O.loc = src + else if(istype(AM, /mob)) + var/mob/M = AM + M.loc = src + src.flush() + +/obj/machinery/disposal/deliveryChute/flush() + flushing = 1 + flick("intake-closing", src) + var/obj/structure/disposalholder/H = new() // virtual holder object which actually + // travels through the pipes. + air_contents = new() // new empty gas resv. + + sleep(10) + playsound(src, 'sound/machines/disposalflush.ogg', 50, 0, 0) + sleep(5) // wait for animation to finish + + H.init(src) // copy the contents of disposer to holder + + H.start(src) // start the holder processing movement + flushing = 0 + // now reset disposal state + flush = 0 + if(mode == 2) // if was ready, + mode = 1 // switch to charging update() + return + +/obj/machinery/disposal/deliveryChute/attackby(var/obj/item/I, var/mob/user) + if(!I || !user) return - Bumped(var/atom/movable/AM) //Go straight into the chute - if(istype(AM, /obj/item/projectile) || istype(AM, /obj/effect) || istype(AM, /obj/mecha)) return - switch(dir) - if(NORTH) - if(AM.loc.y != src.loc.y+1) return - if(EAST) - if(AM.loc.x != src.loc.x+1) return - if(SOUTH) - if(AM.loc.y != src.loc.y-1) return - if(WEST) - if(AM.loc.x != src.loc.x-1) return - - if(istype(AM, /obj)) - var/obj/O = AM - O.loc = src - else if(istype(AM, /mob)) - var/mob/M = AM - M.loc = src - src.flush() - - flush() - flushing = 1 - flick("intake-closing", src) - var/obj/structure/disposalholder/H = new() // virtual holder object which actually - // travels through the pipes. - air_contents = new() // new empty gas resv. - - sleep(10) - playsound(src, 'sound/machines/disposalflush.ogg', 50, 0, 0) - sleep(5) // wait for animation to finish - - H.init(src) // copy the contents of disposer to holder - - H.start(src) // start the holder processing movement - flushing = 0 - // now reset disposal state - flush = 0 - if(mode == 2) // if was ready, - mode = 1 // switch to charging - update() - return - - attackby(var/obj/item/I, var/mob/user) - if(!I || !user) + if(I.is_screwdriver()) + if(c_mode==0) + c_mode=1 + playsound(src, I.usesound, 50, 1) + to_chat(user, "You remove the screws around the power connection.") + return + else if(c_mode==1) + c_mode=0 + playsound(src, I.usesound, 50, 1) + to_chat(user, "You attach the screws around the power connection.") + return + else if(istype(I, /obj/item/weapon/weldingtool) && c_mode==1) + var/obj/item/weapon/weldingtool/W = I + if(W.remove_fuel(0,user)) + playsound(src, W.usesound, 50, 1) + to_chat(user, "You start slicing the floorweld off the delivery chute.") + if(do_after(user,20 * W.toolspeed)) + if(!src || !W.isOn()) return + to_chat(user, "You sliced the floorweld off the delivery chute.") + var/obj/structure/disposalconstruct/C = new (src.loc) + C.ptype = 8 // 8 = Delivery chute + C.update() + C.anchored = 1 + C.density = 1 + qdel(src) + return + else + to_chat(user, "You need more welding fuel to complete this task.") return - - if(I.is_screwdriver()) - if(c_mode==0) - c_mode=1 - playsound(src, I.usesound, 50, 1) - to_chat(user, "You remove the screws around the power connection.") - return - else if(c_mode==1) - c_mode=0 - playsound(src, I.usesound, 50, 1) - to_chat(user, "You attach the screws around the power connection.") - return - else if(istype(I, /obj/item/weapon/weldingtool) && c_mode==1) - var/obj/item/weapon/weldingtool/W = I - if(W.remove_fuel(0,user)) - playsound(src, W.usesound, 50, 1) - to_chat(user, "You start slicing the floorweld off the delivery chute.") - if(do_after(user,20 * W.toolspeed)) - if(!src || !W.isOn()) return - to_chat(user, "You sliced the floorweld off the delivery chute.") - var/obj/structure/disposalconstruct/C = new (src.loc) - C.ptype = 8 // 8 = Delivery chute - C.update() - C.anchored = 1 - C.density = 1 - qdel(src) - return - else - to_chat(user, "You need more welding fuel to complete this task.") - return /obj/machinery/disposal/deliveryChute/Destroy() if(trunk) diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm index bbcda60927..81f888155d 100644 --- a/code/modules/research/message_server.dm +++ b/code/modules/research/message_server.dm @@ -113,15 +113,15 @@ var/global/list/obj/machinery/message_server/message_servers = list() /obj/machinery/message_server/proc/send_rc_message(var/recipient = "",var/sender = "",var/message = "",var/stamp = "", var/id_auth = "", var/priority = 1) rc_msgs += new/datum/data_rc_msg(recipient,sender,message,stamp,id_auth) - var/authmsg = "[message]
" + var/authmsg = "[message]\n" if (id_auth) - authmsg += "[id_auth]
" + authmsg += "([id_auth])\n" if (stamp) - authmsg += "[stamp]
" + authmsg += "([stamp])\n" for (var/obj/machinery/requests_console/Console in allConsoles) if (ckey(Console.department) == ckey(recipient)) if(Console.inoperable()) - Console.message_log += "Message lost due to console failure.
Please contact [station_name()] system adminsitrator or AI for technical assistance.
" + Console.message_log += list(list("Message lost due to console failure.","Please contact [station_name()] system adminsitrator or AI for technical assistance.")) continue if(Console.newmessagepriority < priority) Console.newmessagepriority = priority @@ -131,12 +131,12 @@ var/global/list/obj/machinery/message_server/message_servers = list() if(!Console.silent) playsound(Console, 'sound/machines/twobeep.ogg', 50, 1) Console.audible_message(text("[bicon(Console)] *The Requests Console beeps: 'PRIORITY Alert in [sender]'"),,5) - Console.message_log += "High Priority message from [sender]
[authmsg]" + Console.message_log += list(list("High Priority message from [sender]", "[authmsg]")) else if(!Console.silent) playsound(Console, 'sound/machines/twobeep.ogg', 50, 1) Console.audible_message(text("[bicon(Console)] *The Requests Console beeps: 'Message from [sender]'"),,4) - Console.message_log += "Message from [sender]
[authmsg]" + Console.message_log += list(list("Message from [sender]", "[authmsg]")) Console.set_light(2) diff --git a/code/modules/rogueminer_vr/zone_console.dm b/code/modules/rogueminer_vr/zone_console.dm index be367629ca..56544479a3 100644 --- a/code/modules/rogueminer_vr/zone_console.dm +++ b/code/modules/rogueminer_vr/zone_console.dm @@ -36,17 +36,19 @@ add_fingerprint(user) if(stat & (BROKEN|NOPOWER)) return - user.set_machine(src) - ui_interact(user) - -/obj/machinery/computer/roguezones/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - user.set_machine(src) + tgui_interact(user) +/obj/machinery/computer/roguezones/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "RogueZones", name) + ui.open() +/obj/machinery/computer/roguezones/tgui_data(mob/user) var/chargePercent = min(100, ((((world.time - rm_controller.last_scan) / 10) / 60) / rm_controller.scan_wait) * 100) var/curZoneOccupied = rm_controller.current_zone ? rm_controller.current_zone.is_occupied() : 0 - var/list/data = list() + var/list/data = ..() data["timeout_percent"] = chargePercent data["diffstep"] = rm_controller.diffstep data["difficulty"] = rm_controller.diffstep_strs[rm_controller.diffstep] @@ -80,32 +82,24 @@ // Permit emergency recall of the shuttle if its stranded in a zone with just dead people. data["can_recall_shuttle"] = (shuttle_control && (shuttle_control.z in using_map.belter_belt_z) && !curZoneOccupied) + return data - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "zone_console.tmpl", src.name, 600, 400) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(5) - -/obj/machinery/computer/roguezones/Topic(href, href_list) +/obj/machinery/computer/roguezones/tgui_act(action, list/params) if(..()) - return 1 - usr.set_machine(src) - if (href_list["action"]) - switch(href_list["action"]) - if ("scan_for_new") - scan_for_new_zone() - if ("point_at_old") - point_at_old_zone() - if ("recall_shuttle") - failsafe_shuttle_recall() + return TRUE + switch(action) + if("scan_for_new") + scan_for_new_zone() + . = TRUE + if("recall_shuttle") + failsafe_shuttle_recall() + . = TRUE - src.add_fingerprint(usr) - SSnanoui.update_uis(src) + add_fingerprint(usr) /obj/machinery/computer/roguezones/proc/scan_for_new_zone() - if(scanning) return + if(scanning) + return //Set some kinda scanning var to pause UI input on console rm_controller.last_scan = world.time @@ -137,9 +131,6 @@ return -/obj/machinery/computer/roguezones/proc/point_at_old_zone() - - return /obj/machinery/computer/roguezones/proc/failsafe_shuttle_recall() if(!shuttle_control) diff --git a/code/modules/shuttles/shuttle_console.dm b/code/modules/shuttles/shuttle_console.dm index 3e3655ca5a..93688365c0 100644 --- a/code/modules/shuttles/shuttle_console.dm +++ b/code/modules/shuttles/shuttle_console.dm @@ -8,8 +8,8 @@ var/shuttle_tag // Used to coordinate data in shuttle controller. var/hacked = 0 // Has been emagged, no access restrictions. - var/ui_template = "shuttle_control_console.tmpl" - + var/skip_act = FALSE + var/tgui_subtemplate = "ShuttleControlConsoleDefault" /obj/machinery/computer/shuttle_control/attack_hand(user as mob) if(..(user)) @@ -19,9 +19,9 @@ to_chat(user, "Access Denied.") return 1 - ui_interact(user) + tgui_interact(user) -/obj/machinery/computer/shuttle_control/proc/get_ui_data(var/datum/shuttle/autodock/shuttle) +/obj/machinery/computer/shuttle_control/proc/shuttlerich_tgui_data(var/datum/shuttle/autodock/shuttle) var/shuttle_state switch(shuttle.moving_status) if(SHUTTLE_IDLE) shuttle_state = "idle" @@ -29,7 +29,7 @@ if(SHUTTLE_INTRANSIT) shuttle_state = "in_transit" var/shuttle_status - switch (shuttle.process_state) + switch(shuttle.process_state) if(IDLE_STATE) var/cannot_depart = shuttle.current_location.cannot_depart(shuttle) if (shuttle.in_use) @@ -55,7 +55,8 @@ "can_launch" = shuttle.can_launch(), "can_cancel" = shuttle.can_cancel(), "can_force" = shuttle.can_force(), - "docking_codes" = shuttle.docking_codes + "docking_codes" = shuttle.docking_codes, + "subtemplate" = tgui_subtemplate, ) // This is a subset of the actual checks; contains those that give messages to the user. @@ -74,59 +75,54 @@ return FALSE return TRUE -/obj/machinery/computer/shuttle_control/Topic(href, href_list) - if((. = ..())) +/obj/machinery/computer/shuttle_control/tgui_act(action, list/params) + if(..()) + return TRUE + if(skip_act) return - usr.set_machine(src) - src.add_fingerprint(usr) + add_fingerprint(usr) var/datum/shuttle/autodock/shuttle = SSshuttles.shuttles[shuttle_tag] - if(!shuttle) - to_chat(usr, "Unable to establish link with the shuttle.") - return handle_topic_href(shuttle, href_list, usr) - -/obj/machinery/computer/shuttle_control/proc/handle_topic_href(var/datum/shuttle/autodock/shuttle, var/list/href_list, var/user) if(!istype(shuttle)) - return TOPIC_NOACTION + to_chat(usr, "Unable to establish link with the shuttle.") + return TRUE - if(href_list["move"]) - if(can_move(shuttle, user)) - shuttle.launch(src) - return TOPIC_REFRESH - return TOPIC_HANDLED + switch(action) + if("move") + if(can_move(shuttle, usr)) + shuttle.launch(src) + return TRUE - if(href_list["force"]) - if(can_move(shuttle, user)) - shuttle.force_launch(src) - return TOPIC_REFRESH - return TOPIC_HANDLED + if("force") + if(can_move(shuttle, usr)) + shuttle.force_launch(src) + return TRUE - if(href_list["cancel"]) - shuttle.cancel_launch(src) - return TOPIC_REFRESH + if("cancel") + shuttle.cancel_launch(src) + return TRUE - if(href_list["set_codes"]) - var/newcode = input("Input new docking codes", "Docking codes", shuttle.docking_codes) as text|null - if (newcode && CanInteract(usr, global.default_state)) - shuttle.set_docking_codes(uppertext(newcode)) - return TOPIC_REFRESH + if("set_codes") + var/newcode = input("Input new docking codes", "Docking codes", shuttle.docking_codes) as text|null + if(newcode && !..()) + shuttle.set_docking_codes(uppertext(newcode)) + return TRUE + +/obj/machinery/computer/shuttle_control/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ShuttleControl", "[shuttle_tag] Shuttle Control") // 470, 360 + ui.open() // We delegate populating data to another proc to make it easier for overriding types to add their data. -/obj/machinery/computer/shuttle_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/machinery/computer/shuttle_control/tgui_data(mob/user) var/datum/shuttle/autodock/shuttle = SSshuttles.shuttles[shuttle_tag] - if (!istype(shuttle)) + if(!istype(shuttle)) to_chat(user, "Unable to establish link with the shuttle.") return - var/list/data = get_ui_data(shuttle) - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, ui_template, "[shuttle_tag] Shuttle Control", 470, 360) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return shuttlerich_tgui_data(shuttle) // Call to set the linked shuttle tag; override to add behaviour to shuttle tag changes /obj/machinery/computer/shuttle_control/proc/set_shuttle_tag(var/new_shuttle_tag) diff --git a/code/modules/shuttles/shuttle_console_multi.dm b/code/modules/shuttles/shuttle_console_multi.dm index 9a724a9ab7..9226caebfb 100644 --- a/code/modules/shuttles/shuttle_console_multi.dm +++ b/code/modules/shuttles/shuttle_console_multi.dm @@ -1,8 +1,8 @@ /obj/machinery/computer/shuttle_control/multi circuit = /obj/item/weapon/circuitboard/shuttle_console/multi - ui_template = "shuttle_control_console_multi.tmpl" + tgui_subtemplate = "ShuttleControlConsoleMulti" -/obj/machinery/computer/shuttle_control/multi/get_ui_data(var/datum/shuttle/autodock/multi/shuttle) +/obj/machinery/computer/shuttle_control/multi/shuttlerich_tgui_data(var/datum/shuttle/autodock/multi/shuttle) . = ..() if(istype(shuttle)) . += list( @@ -14,22 +14,28 @@ // "engines_charging" = ((shuttle.last_move + (shuttle.cooldown SECONDS)) > world.time), // Replaced by longer warmup_time ) -/obj/machinery/computer/shuttle_control/multi/handle_topic_href(var/datum/shuttle/autodock/multi/shuttle, var/list/href_list) - if((. = ..()) != null) - return +/obj/machinery/computer/shuttle_control/multi/tgui_act(action, list/params) + if(..()) + return TRUE - if(href_list["pick"]) - var/dest_key = input("Choose shuttle destination", "Shuttle Destination") as null|anything in shuttle.get_destinations() - if(dest_key && CanInteract(usr, global.default_state)) - shuttle.set_destination(dest_key, usr) - return TOPIC_REFRESH + var/datum/shuttle/autodock/multi/shuttle = SSshuttles.shuttles[shuttle_tag] + if(!istype(shuttle)) + to_chat(usr, "Unable to establish link with the shuttle.") + return TRUE - if(href_list["toggle_cloaked"]) - if(!shuttle.can_cloak) - return TOPIC_HANDLED - shuttle.cloaked = !shuttle.cloaked - if(shuttle.legit) - to_chat(usr, "Ship ATC inhibitor systems have been [(shuttle.cloaked ? "activated. The station will not" : "deactivated. The station will")] be notified of our arrival.") - else - to_chat(usr, "Ship stealth systems have been [(shuttle.cloaked ? "activated. The station will not" : "deactivated. The station will")] be warned of our arrival.") - return TOPIC_REFRESH + switch(action) + if("pick") + var/dest_key = input("Choose shuttle destination", "Shuttle Destination") as null|anything in shuttle.get_destinations() + if(dest_key && CanInteract(usr, global.default_state)) + shuttle.set_destination(dest_key, usr) + return TRUE + + if("toggle_cloaked") + if(!shuttle.can_cloak) + return TRUE + shuttle.cloaked = !shuttle.cloaked + if(shuttle.legit) + to_chat(usr, "Ship ATC inhibitor systems have been [(shuttle.cloaked ? "activated. The station will not" : "deactivated. The station will")] be notified of our arrival.") + else + to_chat(usr, "Ship stealth systems have been [(shuttle.cloaked ? "activated. The station will not" : "deactivated. The station will")] be warned of our arrival.") + return TRUE diff --git a/code/modules/shuttles/shuttles_web.dm b/code/modules/shuttles/shuttles_web.dm index 00d9344b00..acc7dc3461 100644 --- a/code/modules/shuttles/shuttles_web.dm +++ b/code/modules/shuttles/shuttles_web.dm @@ -167,6 +167,8 @@ icon_screen = "flight_center" var/list/my_doors //Should be list("id_tag" = "Pretty Door Name", ...) var/list/my_sensors //Should be list("id_tag" = "Pretty Sensor Name", ...) + tgui_subtemplate = "ShuttleControlConsoleWeb" + skip_act = TRUE // Note - Searching own area for doors/sensors is fine for legacy web shuttles as they are single-area. // However if this code is copied to future multi-area shuttles, should search in all shuttle areas @@ -205,80 +207,9 @@ return ..() - -// Fairly copypasta-y. -/obj/machinery/computer/shuttle_control/web/attack_hand(mob/user) - if(..(user)) - return - src.add_fingerprint(user) - - ui_interact(user) - - /* - // If nanoUI falls over and you want a non-nanoUI UI, feel free to uncomment this section. - var/datum/shuttle/autodock/web_shuttle/WS = shuttle_controller.shuttles[shuttle_tag] - if(!istype(WS)) - message_admins("ERROR: Shuttle computer ([src]) ([shuttle_tag]) could not find their shuttle in the shuttles list.") - return - - var/list/dat = list() - dat += "
[shuttle_tag] Ship Control
" - - if(WS.moving_status != SHUTTLE_IDLE) - dat += "Location: Moving
" - else - var/area/areacheck = get_area(src) - dat += "Location: [areacheck.name]
" - - if((WS.last_move + WS.cooldown) > world.time) - dat += "Engines charging.
" - else - dat += "Engines ready.
" - - if(WS.can_cloak) - dat += "
Toggle cloaking field
" - - for(var/datum/shuttle_route/route in WS.current_destination.routes) - dat += "[route.display_route(WS.current_destination)]
" - - - //Docking - dat += "

" - if(WS.skip_docking_checks()) - dat += "Docking Status: Not in use." - else - var/override_en = WS.docking_controller.override_enabled - var/docking_status = WS.docking_controller.get_docking_status() - - dat += "Docking Status: " - switch(docking_status) - if("undocked") - dat += "Undocked" - if("docking") - dat += "Docking" - if("undocking") - dat += "Undocking" - if("docked") - dat += "Docked" - - if(override_en) - dat += " (Override Enabled)" - - dat += ". \[Refresh\]

" - - switch(docking_status) - if("undocked") - dat += "Dock" - if("docked") - dat += "Undock" - dat += "
" - - user << browse(dat.Join(), "window=[shuttle_tag]shuttlecontrol;size=300x300") - */ - - -/obj/machinery/computer/shuttle_control/web/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] +/obj/machinery/computer/shuttle_control/web/tgui_data(mob/user) + var/list/data = list() + var/list/routes[0] var/datum/shuttle/autodock/web_shuttle/shuttle = SSshuttles.shuttles[shuttle_tag] if(!istype(shuttle)) @@ -286,7 +217,7 @@ return var/list/R = shuttle.web_master.get_available_routes() - for (var/i = 1 to length(R)) + for(var/i = 1 to length(R)) var/datum/shuttle_route/route = R[i] var/travel_time = null var/travel_modifier = shuttle.flight_time_modifier @@ -313,7 +244,6 @@ if(SHUTTLE_INTRANSIT) shuttle_state = "in_transit" - // For the progress bar. var/elapsed_time = world.time - shuttle.depart_time var/total_time = shuttle.arrive_time - shuttle.depart_time @@ -322,7 +252,6 @@ if(total_time) // Need to check or we might divide by zero. percent_finished = (elapsed_time / total_time) * 100 - var/list/doors = list() if(my_doors) for(var/doorname in my_doors) @@ -356,111 +285,90 @@ "autopilot" = shuttle.autopilot ? 1 : 0, "can_rename" = shuttle.can_rename ? 1 : 0, "doors" = doors, - "sensors" = sensors + "sensors" = sensors, + "subtemplate" = tgui_subtemplate, ) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + return data - if(!ui) - ui = new(user, src, ui_key, "flight.tmpl", "[shuttle.visible_name] Flight Computer", 500, 500) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - - -/obj/machinery/computer/shuttle_control/web/Topic(href, href_list) - if((. = ..())) - return - - usr.set_machine(src) - src.add_fingerprint(usr) +/obj/machinery/computer/shuttle_control/web/tgui_act(action, list/params) + if(..()) + return TRUE var/datum/shuttle/autodock/web_shuttle/WS = SSshuttles.shuttles[shuttle_tag] if(!istype(WS)) message_admins("ERROR: Shuttle computer ([src]) ([shuttle_tag]) could not find their shuttle in the shuttles list.") return - if(href_list["refresh"]) - ui_interact(usr) - - if (WS.moving_status != SHUTTLE_IDLE) + if(WS.moving_status != SHUTTLE_IDLE) to_chat(usr, "[WS.visible_name] is busy moving.") return - if(href_list["rename_command"]) - WS.rename_shuttle(usr) + switch(action) + if("rename_command") + WS.rename_shuttle(usr) - if(href_list["dock_command"]) - if(WS.autopilot) - to_chat(usr, "The autopilot must be disabled before you can control the vessel manually.") - return - WS.dock() + if("dock_command") + if(WS.autopilot) + to_chat(usr, "The autopilot must be disabled before you can control the vessel manually.") + return + WS.dock() - if(href_list["undock_command"]) - if(WS.autopilot) - to_chat(usr, "The autopilot must be disabled before you can control the vessel manually.") - return - WS.undock() + if("undock_command") + if(WS.autopilot) + to_chat(usr, "The autopilot must be disabled before you can control the vessel manually.") + return + WS.undock() - if(href_list["cloak_command"]) - if(!WS.can_cloak) - return - WS.cloaked = TRUE - to_chat(usr, "Ship stealth systems have been activated. The station will not be warned of our arrival.") + if("toggle_cloaking") + if(!WS.can_cloak) + return + WS.cloaked = !WS.cloaked + if(WS.cloaked) + to_chat(usr, "Ship stealth systems have been activated. The station will not be warned of our arrival.") + else + to_chat(usr, "Ship stealth systems have been deactivated. The station will be warned of our arrival.") - if(href_list["uncloak_command"]) - if(!WS.can_cloak) - return - WS.cloaked = FALSE - to_chat(usr, "Ship stealth systems have been deactivated. The station will be warned of our arrival.") + if("toggle_autopilot") + WS.adjust_autopilot(!WS.autopilot) - if(href_list["autopilot_on_command"]) - WS.adjust_autopilot(TRUE) + if("traverse") + if(WS.autopilot) + to_chat(usr, "The autopilot must be disabled before you can control the vessel manually.") + return - if(href_list["autopilot_off_command"]) - WS.adjust_autopilot(FALSE) + if((WS.last_move + WS.cooldown) > world.time) + to_chat(usr, "The ship's drive is inoperable while the engines are charging.") + return - if(href_list["traverse"]) - if(WS.autopilot) - to_chat(usr, "The autopilot must be disabled before you can control the vessel manually.") - return + var/index = text2num(params["traverse"]) + var/datum/shuttle_route/new_route = WS.web_master.current_destination.routes[index] + if(!istype(new_route)) + message_admins("ERROR: Shuttle computer was asked to traverse a nonexistant route.") + return - if((WS.last_move + WS.cooldown) > world.time) - to_chat(usr, "The ship's drive is inoperable while the engines are charging.") - return + if(!check_docking(WS)) + return TRUE - var/index = text2num(href_list["traverse"]) - var/datum/shuttle_route/new_route = WS.web_master.current_destination.routes[index] - if(!istype(new_route)) - message_admins("ERROR: Shuttle computer was asked to traverse a nonexistant route.") - return + var/datum/shuttle_destination/target_destination = new_route.get_other_side(WS.web_master.current_destination) + if(!istype(target_destination)) + message_admins("ERROR: Shuttle computer was asked to travel to a nonexistant destination.") + return - if(!check_docking(WS)) - // updateUsrDialog() - ui_interact(usr) - return + WS.next_location = target_destination.my_landmark + if(!can_move(WS, usr)) + return - var/datum/shuttle_destination/target_destination = new_route.get_other_side(WS.web_master.current_destination) - if(!istype(target_destination)) - message_admins("ERROR: Shuttle computer was asked to travel to a nonexistant destination.") - return + WS.web_master.future_destination = target_destination + to_chat(usr, "[WS.visible_name] flight computer received command.") + WS.web_master.reset_autopath() // Deviating from the path will almost certainly confuse the autopilot, so lets just reset its memory. - WS.next_location = target_destination.my_landmark - if(!can_move(WS, usr)) - return - - WS.web_master.future_destination = target_destination - to_chat(usr, "[WS.visible_name] flight computer received command.") - WS.web_master.reset_autopath() // Deviating from the path will almost certainly confuse the autopilot, so lets just reset its memory. - - var/travel_time = new_route.travel_time * WS.flight_time_modifier - // TODO - Leshana - Change this to use proccess stuff of autodock! - if(new_route.interim && new_route.travel_time) - WS.long_jump(target_destination.my_landmark, new_route.interim, travel_time / 10) - else - WS.short_jump(target_destination.my_landmark) - - ui_interact(usr) + var/travel_time = new_route.travel_time * WS.flight_time_modifier + // TODO - Leshana - Change this to use proccess stuff of autodock! + if(new_route.interim && new_route.travel_time) + WS.long_jump(target_destination.my_landmark, new_route.interim, travel_time / 10) + else + WS.short_jump(target_destination.my_landmark) //check if we're undocked, give option to force launch /obj/machinery/computer/shuttle_control/web/proc/check_docking(datum/shuttle/autodock/MS) diff --git a/code/modules/tgui/external.dm b/code/modules/tgui/external.dm index 19f039869e..bb39c721d0 100644 --- a/code/modules/tgui/external.dm +++ b/code/modules/tgui/external.dm @@ -141,6 +141,26 @@ */ /datum/proc/tgui_close(mob/user) +/** + * verb + * + * Used by a client to fix broken TGUI windows caused by opening a UI window before assets load. + * Probably not very performant and forcibly destroys a bunch of windows, so it has some warnings attached. + * Conveniently, also allows devs to force a dev server reattach without relogging, since it yeets windows. + */ +/client/verb/tgui_fix_white() + set desc = "Only use this if you have a broken TGUI window occupying your screen!" + set name = "Fix TGUI" + set category = "OOC" + + if(alert(src, "Only use this verb if you have a white TGUI window stuck on your screen.", "Fix TGUI", "Continue", "Nevermind") != "Continue") + return + + SStgui.close_user_uis(mob) + if(alert(src, "Did that fix the problem?", "Fix TGUI", "Yes", "No") == "No") + SStgui.force_close_all_windows(mob) + alert(src, "UIs should be fixed now. If not, please cry to your nearest coder.", "Fix TGUI") + /** * verb * diff --git a/nano/templates/flight.tmpl b/nano/templates/flight.tmpl deleted file mode 100644 index 60d4cd605a..0000000000 --- a/nano/templates/flight.tmpl +++ /dev/null @@ -1,241 +0,0 @@ -{{if data.autopilot == 1}} -
-

AI PILOT (CLASS D) ACTIVE

- This vessel will start and stop automatically.
- Ensure that all non-cycling capable hatches and doors are closed, as the automated system may not be able to control them.
- Docking and flight controls are locked. To unlock, disable the automated flight system.

-
-{{/if}} - -{{if data.can_rename == 1}} -
-
-
- {{:helper.link('Rename', 'pencil', {"rename_command" : 1})}} -
-
-
-{{/if}} - -

Shuttle Status

-{{if data.is_moving == 0}} -
-
- Current Location: -
-
- {{:data.shuttle_location}} -
-
-{{/if}} - -
-
-
- Engines: -
-
- {{if data.shuttle_state == "idle"}} - IDLE - {{else data.shuttle_state == "warmup"}} - SPINNING UP - {{else data.shuttle_state == "in_transit"}} - ENGAGED - {{else}} - ERROR - {{/if}} -
-
-
- -{{if data.is_moving == 0}} - - {{if data.skip_docking == 0}} -
-
-
- Docking Status: -
-
- {{if data.docking_status == "docked"}} - DOCKED - {{else data.docking_status == "docking"}} - {{if !data.docking_override}} - DOCKING - {{else}} - DOCKING-MANUAL - {{/if}} - {{else data.docking_status == "undocking"}} - {{if !data.docking_override}} - UNDOCKING - {{else}} - UNDOCKING-MANUAL - {{/if}} - {{else data.docking_status == "undocked"}} - UNDOCKED - {{else}} - ERROR - {{/if}} - - - {{:helper.link('Dock', 'arrowthickstop-1-e', {'dock_command' : 1}, (data.docking_status != "undocked")? 'selected' : null)}} - {{:helper.link('Undock', 'arrowthickstop-1-e', {'undock_command' : 1}, (data.docking_status != "docked")? 'selected' : null)}} -
- -
- -
- - {{/if}} - - {{if data.can_cloak == 1}} -
-
- Shuttle Stealth System: -
- - {{:helper.link('Cloak', 'radio-off', {'cloak_command' : 1}, (data.cloaked == 1)? 'selected' : null)}} - {{:helper.link('Uncloak', 'radio-on', {'uncloak_command' : 1}, (data.cloaked == 0)? 'selected' : null)}} -
- - {{/if}} - - {{if data.can_autopilot == 1}} -
-
- Automated Flight Control: -
- - {{:helper.link('On', 'circle-check', {'autopilot_on_command' : 1}, (data.autopilot == 1)? 'selected' : null)}} - {{:helper.link('Off', 'circle-close ', {'autopilot_off_command' : 1}, (data.autopilot == 0)? 'selected' : null)}} -
- - {{/if}} - -{{/if}} - -{{if data.is_moving == 0}} -

Available Destinations

-
-

- {{for data.routes}} -
-
- {{:value.name}} -
-
-
- {{:helper.link(value.travel_time, 'clock', {"traverse" : value.index})}} -
-
-
- {{/for}} - -{{/if}} - -{{if data.is_in_transit == 1}} -

Destination ETA

-
-
- Distance from target: -
-
- {{:helper.displayBar(data.travel_progress, 0, 100, "good")}} -
- {{:data.time_left}}s -
-
-
-{{/if}} - -{{if data.doors}} -

Hatch Status

-
-
- {{props data.doors}} -
-
{{:key}}
-
- {{if value.open}} - OPN - {{else}} - CLS - {{/if}} - - - {{if value.bolted}} - BLT - {{else}} - UBLT - {{/if}} -
-
- {{/props}} -
-{{/if}} - -{{if data.sensors}} -

Air Readout

-
- {{props data.sensors}} -
-
- {{:key}} -
-
- {{if value.reading == 1}} -
- Pressure: -
-
- {{:helper.string('{1} kPa', value.pressure < 80 || value.pressure > 120 ? 'bad' : value.pressure < 95 || value.pressure > 110 ? 'average' : 'good' , value.pressure)}} -
-
- Temperature: -
-
- {{:helper.string('{1} °C', value.temp < 5 || value.temp > 35 ? 'bad' : value.temp < 15 || value.temp > 25 ? 'average' : 'good' , value.temp)}} -
-
-
- Oxygen: -
-
- {{:helper.string('{1}%', value.oxygen < 17 ? 'bad' : value.oxygen < 19 ? 'average' : 'good' , value.oxygen)}} -
-
- Nitrogen: -
-
- {{:helper.string('{1}%', value.nitrogen > 82 ? 'bad' : value.nitrogen > 80 ? 'average' : 'good' , value.nitrogen)}} -
-
- Carbon Dioxide: -
-
- {{:helper.string('{1}%', value.carbon_dioxide > 5 ? 'bad' : 'good' , value.carbon_dioxide)}} -
-
- Phoron: -
-
- {{:helper.string('{1}%', value.phoron > 0 ? 'bad' : 'good' , value.phoron)}} - -
- {{if value.other > 0}} -
- Unknown: -
-
- {{:value.other}}% -
- {{/if}} - {{else}} -
- Unable to get air reading -
- {{/if}} -
-
- {{/props}} -{{/if}} - diff --git a/nano/templates/request_console.tmpl b/nano/templates/request_console.tmpl deleted file mode 100644 index 5750bbe2b0..0000000000 --- a/nano/templates/request_console.tmpl +++ /dev/null @@ -1,123 +0,0 @@ - - -{{if data.screen == 1}} -

Request assistance from another department.

- - {{for data.assist_dept}} - {{if value != data.department}} - - - - - - {{/if}} - {{empty}} - - {{/for}} -
{{:value}} -
{{:helper.link('Message', null, { 'write' : value , 'priority' : 1 })}}
{{:helper.link('High Priority', null, { 'write' : value , 'priority' : 2 })}}
There are no available departments to request assistance from.

-
{{:helper.link('Back', 'arrowreturnthick-1-w', { 'setScreen' : 0 })}}
-{{else data.screen == 2}} -

Request supplies from another department.

- - {{for data.supply_dept}} - {{if value != data.department}} - - - - - - {{/if}} - {{empty}} - - {{/for}} -
{{:value}} -
{{:helper.link('Message', null, { 'write' : value , 'priority' : 1 })}}
{{:helper.link('High Priority', null, { 'write' : value , 'priority' : 2 })}}
There are no available departments to request supplies from.

-
{{:helper.link('Back', 'arrowreturnthick-1-w', { 'setScreen' : 0 })}}
-{{else data.screen == 3}} -

Relay info to another department.

- - {{for data.info_dept}} - {{if value != data.department}} - - - - - - {{/if}} - {{empty}} - - {{/for}} -
{{:value}} -
{{:helper.link('Message', null, { 'write' : value , 'priority' : 1 })}}
{{:helper.link('High Priority', null, { 'write' : value , 'priority' : 2 })}}
There are no available departments to relay information to.

-
{{:helper.link('Back', 'arrowreturnthick-1-w', { 'setScreen' : 0 })}}
-{{else data.screen == 4}} -
Message sent successfully.
-
{{:helper.link('Continue', 'arrowthick-1-e', { 'setScreen' : 0 })}}
-{{else data.screen == 5}} -
An Error occured. Message not sent.
-
{{:helper.link('Continue', 'arrowthick-1-e', { 'setScreen' : 0 })}}
-{{else data.screen == 6}} -
- {{for data.message_log}} -
{{:value}}
-
{{:helper.link('Print', null, { 'print' : index + 1 })}}
- {{empty}} -
No messages have been received.
- {{/for}} -
-
{{:helper.link('Back', 'arrowreturnthick-1-w', { 'setScreen' : 0 })}}
-{{else data.screen == 7}} -

Message Authentication


-
-
Message for {{:data.recipient}}: {{:data.message}}
-
Validated by: {{:data.msgVerified}}
-
Stamped by: {{:data.msgStamped}}
-
-
- {{:helper.link('Send Message', 'arrowthick-1-e', { 'department' : data.recipient })}} - {{:helper.link('Back', 'arrowreturnthick-1-w', { 'setScreen' : 0 })}} -
-{{else data.screen == 8}} -

Station wide announcement

-
Message: {{:data.message}} {{:helper.link('Write Message', 'pencil', { 'writeAnnouncement' : 1 })}}
-
- {{if data.announceAuth}} -
ID verified. Authentication accepted.
- {{else}} -
Swipe your ID card to authenticate yourself.
- {{/if}} -
-
- {{:helper.link('Announce', 'signal-diag', { 'sendAnnouncement' : 1 }, (data.announceAuth && data.message) ? null : 'disabled' )}} - {{:helper.link('Back', 'arrowreturnthick-1-w', { 'setScreen' : 0 })}} -
-{{else}} - {{if data.newmessagepriority == 1}} -
There are new messages
- {{else data.newmessagepriority == 2}} -
NEW PRIORITY MESSAGES
- {{/if}} -
{{:helper.link('View Messages', data.newmessagepriority ? 'mail-closed' : 'mail-open', { 'setScreen' : 6 })}}
-
-
{{:helper.link('Request Assistance', 'gear', { 'setScreen' : 1 })}}
-
{{:helper.link('Request Supplies', 'gear', { 'setScreen' : 2 })}}
-
{{:helper.link('Relay Anonymous Information', 'gear', { 'setScreen' : 3})}}
-
- {{if data.announcementConsole}} -
{{:helper.link('Send Station-wide Announcement', 'signal-diag', { 'setScreen' : 8})}}
-
- {{/if}} -
{{:helper.link(data.silent ? 'Speaker OFF' : 'Speaker ON', data.silent ? 'volume-off' : 'volume-on', { 'toggleSilent' : 1})}}
-{{/if}} \ No newline at end of file diff --git a/nano/templates/shuttle_control_console.tmpl b/nano/templates/shuttle_control_console.tmpl deleted file mode 100644 index 05cae4ef09..0000000000 --- a/nano/templates/shuttle_control_console.tmpl +++ /dev/null @@ -1,72 +0,0 @@ -

Shuttle Status

-
-
- {{:data.shuttle_status}} -
-
-
-
-
- Bluespace Drive: -
-
- {{if data.shuttle_state == "idle"}} - IDLE - {{else data.shuttle_state == "warmup"}} - SPINNING UP - {{else data.shuttle_state == "in_transit"}} - ENGAGED - {{else}} - ERROR - {{/if}} -
-
-
-{{if data.has_docking}} -
-
-
- Docking Status: -
-
- {{if data.docking_status == "docked"}} - DOCKED - {{else data.docking_status == "docking"}} - {{if !data.docking_override}} - DOCKING - {{else}} - DOCKING-MANUAL - {{/if}} - {{else data.docking_status == "undocking"}} - {{if !data.docking_override}} - UNDOCKING - {{else}} - UNDOCKING-MANUAL - {{/if}} - {{else data.docking_status == "undocked"}} - UNDOCKED - {{else}} - ERROR - {{/if}} - -
-
- Docking Codes: -
-
- {{:helper.link(data.docking_codes ? data.docking_codes : 'Not set', null, {'set_codes' : '1'}, null , null)}} -
-
-
-{{/if}} - -

Shuttle Control

-
-
-
- {{:helper.link('Launch Shuttle', 'arrowthickstop-1-e', {'move' : '1'}, data.can_launch? null : 'disabled' , null)}} - {{:helper.link('Cancel Launch', 'cancel', {'cancel' : '1'}, data.can_cancel ? null : 'disabled' , null)}} - {{:helper.link('Force Launch', 'alert', {'force' : '1'}, data.can_force? null : 'disabled' , data.can_force ? 'redButton' : null)}} -
-
-
\ No newline at end of file diff --git a/nano/templates/shuttle_control_console_exploration.tmpl b/nano/templates/shuttle_control_console_exploration.tmpl deleted file mode 100644 index e368f484db..0000000000 --- a/nano/templates/shuttle_control_console_exploration.tmpl +++ /dev/null @@ -1,95 +0,0 @@ -

Shuttle Status

-
-
- {{:data.shuttle_status}} -
-
-
-
-
- Engines: -
-
- {{if data.shuttle_state == "idle"}} - IDLE - {{else data.shuttle_state == "warmup"}} - SPINNING UP - {{else data.shuttle_state == "in_transit"}} - ENGAGED - {{else}} - ERROR - {{/if}} -
-
-
-{{if data.has_docking}} -
-
-
- Docking Status: -
-
- {{if data.docking_status == "docked"}} - DOCKED - {{else data.docking_status == "docking"}} - {{if !data.docking_override}} - DOCKING - {{else}} - DOCKING-MANUAL - {{/if}} - {{else data.docking_status == "undocking"}} - {{if !data.docking_override}} - UNDOCKING - {{else}} - UNDOCKING-MANUAL - {{/if}} - {{else data.docking_status == "undocked"}} - UNDOCKED - {{else}} - ERROR - {{/if}} -
-
- Docking Codes: -
-
- {{:helper.link(data.docking_codes ? data.docking_codes : 'Not set', null, {'set_codes' : '1'}, null , null)}} -
-
-
-{{/if}} -
-
- Current Destination: -
- {{:data.destination_name}} -
- {{:helper.link('Choose Destination', 'arrowreturn-1-s', {'pick' : '1'}, data.can_pick ? null : 'disabled' , null)}} -
-
-{{if data.fuel_usage}} -
-
- Est. Delta-V Budget: -
-
- {{:data.remaining_fuel}} m/s -
-
- Avg. Delta-V Per Maneuver: -
-
- {{:data.fuel_usage}} m/s -
-
-{{/if}} -

Shuttle Control

-
-
-
- {{:helper.link('Launch Shuttle', 'arrowthickstop-1-e', {'move' : '1'}, data.can_launch ? null : 'disabled' , null)}} - {{:helper.link('Cancel Launch', 'cancel', {'cancel' : '1'}, data.can_cancel ? null : 'disabled' , null)}} - {{:helper.link('Force Launch', 'alert', {'force' : '1'}, data.can_force ? null : 'disabled' , data.can_force ? 'redButton' : null)}} -
-
-
\ No newline at end of file diff --git a/nano/templates/shuttle_control_console_multi.tmpl b/nano/templates/shuttle_control_console_multi.tmpl deleted file mode 100644 index df25132bc7..0000000000 --- a/nano/templates/shuttle_control_console_multi.tmpl +++ /dev/null @@ -1,84 +0,0 @@ -

Shuttle Status

-
-
- {{:data.shuttle_status}} -
- {{if data.can_cloak}} -
- {{:data.legit ? "ATC Inhibitor" : "Cloaking Field"}} is {{:data.cloaked ? "enabled" : "disabled"}}. {{:helper.link('Toggle', 'arrowreturn-1-s', {'toggle_cloaked' : '1'}) }} -
- {{/if}} -
-
-
-
- Bluespace Drive: -
-
- {{if data.shuttle_state == "idle"}} - IDLE - {{else data.shuttle_state == "warmup"}} - SPINNING UP - {{else data.shuttle_state == "in_transit"}} - ENGAGED - {{else}} - ERROR - {{/if}} -
-
-
-{{if data.has_docking}} -
-
-
- Docking Status: -
-
- {{if data.docking_status == "docked"}} - DOCKED - {{else data.docking_status == "docking"}} - {{if !data.docking_override}} - DOCKING - {{else}} - DOCKING-MANUAL - {{/if}} - {{else data.docking_status == "undocking"}} - {{if !data.docking_override}} - UNDOCKING - {{else}} - UNDOCKING-MANUAL - {{/if}} - {{else data.docking_status == "undocked"}} - UNDOCKED - {{else}} - ERROR - {{/if}} -
-
- Docking Codes: -
-
- {{:helper.link(data.docking_codes ? data.docking_codes : 'Not set', null, {'set_codes' : '1'}, null , null)}} -
-
-
-{{/if}} -
-
- Current Destination: -
- {{:data.destination_name}} -
- {{:helper.link('Choose Destination', 'arrowreturn-1-s', {'pick' : '1'}, data.can_pick ? null : 'disabled' , null)}} -
-
-

Shuttle Control

-
-
-
- {{:helper.link('Launch Shuttle', 'arrowthickstop-1-e', {'move' : '1'}, data.can_launch ? null : 'disabled' , null)}} - {{:helper.link('Cancel Launch', 'cancel', {'cancel' : '1'}, data.can_cancel ? null : 'disabled' , null)}} - {{:helper.link('Force Launch', 'alert', {'force' : '1'}, data.can_force ? null : 'disabled' , data.can_force ? 'redButton' : null)}} -
-
-
diff --git a/nano/templates/zone_console.tmpl b/nano/templates/zone_console.tmpl deleted file mode 100644 index cb7389f978..0000000000 --- a/nano/templates/zone_console.tmpl +++ /dev/null @@ -1,83 +0,0 @@ -
-
-
- Scn. Ramestat Core: -
-
- {{:helper.displayBar(data.timeout_percent, 0, 100, (data.timeout_percent < 75) ? 'bad' : (data.timeout_percent < 100) ? 'average' : 'good')}} -
-
-
-
-
- Mineral Content: -
-
- {{:data.difficulty}} -
-
- -
-
- Shuttle Location: -
-
- {{:data.shuttle_location}} -
- {{if data.can_recall_shuttle > 0}} -
- {{:helper.link('Recall Shuttle', 'alert-red', {'action' : 'recall_shuttle'}, null)}} -
- {{/if}} -
-{{if data.occupied > 0}} -
-
- WARNING: -
-
- Area Occupied by {{:data.occupied}} personnel! -
-
-{{/if}} - - -

Scanner Operation

-
-
- Scanner Activation: -
-
- {{:helper.link('Scan For Asteroids', 'power', {'action' : 'scan_for_new'}, data.scan_ready ? null : 'disabled')}} -
-
-{{if data.scanning > 0}} -
-
- Scanning: -
-
- In Progress... -
-
-{{/if}} -{{if data.updated > 0 && data.scanning == 0}} -
-
- Info: -
-
- Updated shuttle destination! -
-
-{{/if}} -{{if data.debug > 0}} -
-
- DEBUG: -
-
- TP:{{:data.timeout_percent}},DS:{{:data.diffstep}},D:{{:data.difficulty}},O:{{:data.occupied}},DBG:{{:data.debug}},SL:{{:data.shuttle_location}},SAS:{{:data.shuttle_at_station}},SR:{{:data.scan_ready}} -
-
-{{/if}} \ No newline at end of file diff --git a/tgui/packages/tgui/format.js b/tgui/packages/tgui/format.js index db21025bdf..2d5333d4f8 100644 --- a/tgui/packages/tgui/format.js +++ b/tgui/packages/tgui/format.js @@ -103,4 +103,14 @@ export const formatCommaNumber = value => { let parts = value.toString().split("."); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); return parts.join("."); -}; \ No newline at end of file +}; + +// Function from https://stackoverflow.com/a/34841026. CC BY-SA 4.0. +export const formatTime = seconds => { + let hours = Math.floor(seconds / 3600); + let minutes = Math.floor(seconds / 60) % 60; + return [hours, minutes, seconds % 60] + .map(v => v < 10 ? "0" + v : v) + .filter((v, i) => v !== "00" || i > 0) + .join(":"); +}; diff --git a/tgui/packages/tgui/interfaces/DestinationTagger.js b/tgui/packages/tgui/interfaces/DestinationTagger.js new file mode 100644 index 0000000000..5a70ede6d6 --- /dev/null +++ b/tgui/packages/tgui/interfaces/DestinationTagger.js @@ -0,0 +1,34 @@ +import { round } from 'common/math'; +import { Fragment } from 'inferno'; +import { useBackend } from "../backend"; +import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section, Table } from "../components"; +import { Window } from "../layouts"; + +export const DestinationTagger = (props, context) => { + const { act, data } = useBackend(context); + + const { + currTag, + taggerLocs, + } = data; + + return ( + + +
+ + {taggerLocs.sort().map(tag => ( + +
+
+
+ ); +}; \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/Gps.js b/tgui/packages/tgui/interfaces/Gps.js new file mode 100644 index 0000000000..f2549a31a5 --- /dev/null +++ b/tgui/packages/tgui/interfaces/Gps.js @@ -0,0 +1,133 @@ +import { map, sortBy } from 'common/collections'; +import { flow } from 'common/fp'; +import { clamp } from 'common/math'; +import { vecLength, vecSubtract } from 'common/vector'; +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Box, Button, Icon, LabeledList, Section, Table } from '../components'; +import { Window } from '../layouts'; + +import { createLogger } from '../logging'; +const logger = createLogger('lol what'); + +const coordsToVec = coords => map(parseFloat)(coords.split(', ')); + +export const Gps = (props, context) => { + const { act, data } = useBackend(context); + const { + currentArea, + currentCoords, + currentCoordsText, + globalmode, + power, + tag, + updating, + } = data; + const signals = flow([ + map((signal, index) => { + // Calculate distance to the target. BYOND distance is capped to 127, + // that's why we roll our own calculations here. + const dist = signal.dist && ( + Math.round(vecLength(vecSubtract( + currentCoords, + signal.coords))) + ); + return { ...signal, dist, index }; + }), + sortBy( + // Signals with distance metric go first + signal => signal.dist === undefined, + // Sort alphabetically + signal => signal.entrytag), + ])(data.signals || []); + return ( + + +
act('power')} /> + )}> + + +
+ {!!power && ( + +
+ + {currentArea} ({currentCoordsText}) + +
+
+ + + + + + + {signals.map(signal => ( + + + {signal.entrytag} + + + {signal.degrees !== undefined && ( + + )} + {signal.dist !== undefined && ( + signal.dist + 'm' + )} + + + {signal.coordsText} + + + ))} +
+
+
+ )} +
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/MiningOreProcessingConsole.js b/tgui/packages/tgui/interfaces/MiningOreProcessingConsole.js new file mode 100644 index 0000000000..f1a22fbe8b --- /dev/null +++ b/tgui/packages/tgui/interfaces/MiningOreProcessingConsole.js @@ -0,0 +1,145 @@ +import { toTitleCase } from 'common/string'; +import { Fragment } from 'inferno'; +import { useBackend, useLocalState } from "../backend"; +import { Box, Button, Collapsible, Dropdown, Flex, Input, NoticeBox, Section, LabeledList, AnimatedNumber } from '../components'; +import { Window } from "../layouts"; +import { refocusLayout } from '../layouts'; +import { sortBy } from 'common/collections'; +import { MiningUser } from './common/Mining'; + +export const MiningOreProcessingConsole = (props, context) => { + const { act, data } = useBackend(context); + + const { + unclaimedPoints, + ores, + showAllOres, + power, + } = data; + + return ( + + + + + in order to claim points. + + )} /> +
act("power")}> + {power ? "Smelting" : "Not Smelting"} + + }> + + act("claim")}> + Claim + + }> + + + +
+ +
+
+ ); +}; + +// ORDER IS IMPORTANT HERE. +const processingOptions = [ + "Not Processing", + "Smelting", + "Compressing", + "Alloying", +]; + +// Higher in the list == closer to top +// This is just kind of an arbitrary list to sort by because the machine has no predictable ore order in it's list +// and alphabetizing them doesn't really make sense +const oreOrder = [ + "verdantium", + "mhydrogen", + "diamond", + "platinum", + "uranium", + "gold", + "silver", + "rutile", + "phoron", + "marble", + "lead", + "sand", + "carbon", + "hematite", +]; + +const oreSorter = (a, b) => { + if (oreOrder.indexOf(a.ore) === -1) { + return a.ore - b.ore; + } + if (oreOrder.indexOf(b.ore) === -1) { + return a.ore - b.ore; + } + return oreOrder.indexOf(b.ore) - oreOrder.indexOf(a.ore); +}; + +const MOPCOres = (props, context) => { + const { act, data } = useBackend(context); + const { + ores, + showAllOres, + power, + } = data; + return ( +
act("showAllOres")}> + {showAllOres ? "All Ores" : "Ores in Machine"} + + }> + + {ores.length && ores.sort(oreSorter).map(ore => ( + act("toggleSmelting", { + ore: ore.ore, + set: processingOptions.indexOf(val), + })} /> + }> + + + + + )) || ( + + No ores in machine. + + )} + +
+ ); +}; \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/MiningStackingConsole.js b/tgui/packages/tgui/interfaces/MiningStackingConsole.js new file mode 100644 index 0000000000..0aac5ca35c --- /dev/null +++ b/tgui/packages/tgui/interfaces/MiningStackingConsole.js @@ -0,0 +1,51 @@ +import { toTitleCase } from 'common/string'; +import { Fragment } from 'inferno'; +import { useBackend, useLocalState } from "../backend"; +import { Box, Button, Collapsible, Dropdown, Flex, Input, NoticeBox, Section, LabeledList, AnimatedNumber, NumberInput } from '../components'; +import { Window } from "../layouts"; +import { sortBy } from 'common/collections'; + +export const MiningStackingConsole = (props, context) => { + const { act, data } = useBackend(context); + + const { + stacktypes, + stackingAmt, + } = data; + + return ( + + +
+ + + act("change_stack", { amt: val })} /> + + + {stacktypes.length && stacktypes.sort().map(stack => ( + act("release_stack", { stack: stack.type })}> + Eject + + }> + + + )) || ( + + No stacks in machine. + + )} + +
+
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/MiningVendor.js b/tgui/packages/tgui/interfaces/MiningVendor.js new file mode 100644 index 0000000000..2b653faaae --- /dev/null +++ b/tgui/packages/tgui/interfaces/MiningVendor.js @@ -0,0 +1,179 @@ +import { createSearch } from 'common/string'; +import { Fragment } from 'inferno'; +import { useBackend, useLocalState } from "../backend"; +import { Box, Button, Collapsible, Dropdown, Flex, Input, NoticeBox, Section } from '../components'; +import { Window } from "../layouts"; +import { refocusLayout } from '../layouts'; +import { MiningUser } from './common/Mining'; + +const sortTypes = { + 'Alphabetical': (a, b) => a - b, + 'By availability': (a, b) => -(a.affordable - b.affordable), + 'By price': (a, b) => a.price - b.price, +}; + +export const MiningVendor = (props, context) => { + return ( + + + + + + + + ); +}; + + +const MiningVendorItems = (props, context) => { + const { act, data } = useBackend(context); + const { + has_id, + id, + items, + } = data; + // Search thingies + const [ + searchText, + _setSearchText, + ] = useLocalState(context, 'search', ''); + const [ + sortOrder, + _setSortOrder, + ] = useLocalState(context, 'sort', 'Alphabetical'); + const [ + descending, + _setDescending, + ] = useLocalState(context, 'descending', false); + const searcher = createSearch(searchText, item => { + return item[0]; + }); + + let has_contents = false; + let contents = Object.entries(items).map((kv, _i) => { + let items_in_cat = Object.entries(kv[1]) + .filter(searcher) + .map(kv2 => { + kv2[1].affordable = has_id && id.points >= kv2[1].price; + return kv2[1]; + }) + .sort(sortTypes[sortOrder]); + if (items_in_cat.length === 0) { + return; + } + if (descending) { + items_in_cat = items_in_cat.reverse(); + } + + has_contents = true; + return ( + + ); + }); + return ( + +
refocusLayout()}> + {has_contents + ? contents : ( + + No items matching your criteria was found! + + )} +
+
+ ); +}; + +const MiningVendorSearch = (props, context) => { + const [ + _searchText, + setSearchText, + ] = useLocalState(context, 'search', ''); + const [ + _sortOrder, + setSortOrder, + ] = useLocalState(context, 'sort', ''); + const [ + descending, + setDescending, + ] = useLocalState(context, 'descending', false); + return ( + + + + setSearchText(value)} + /> + + + setSortOrder(v)} /> + + + + + ); +}; + +const RequestConsoleSupplies = (props, context) => { + const { act, data } = useBackend(context); + const { + department, + supply_dept, + } = data; + return ( +
+ +
+ ); +}; + +const RequestConsoleAssistance = (props, context) => { + const { act, data } = useBackend(context); + const { + department, + assist_dept, + } = data; + return ( +
+ +
+ ); +}; + +const RequestConsoleRelay = (props, context) => { + const { act, data } = useBackend(context); + const { + department, + info_dept, + } = data; + return ( +
+ +
+ ); +}; + +const RequestConsoleSendMenu = (props, context) => { + const { act } = useBackend(context); + const { + dept_list, + department, + } = props; + return ( + + {dept_list.sort().map(dept => dept !== department && ( + + + + + } /> + ) || null)} + + ); +}; + +const RequestConsoleSendPass = (props, context) => { + const { act, data } = useBackend(context); + return ( +
+ + Message Sent Successfully + + + + +
+ ); +}; + +const RequestConsoleSendFail = (props, context) => { + const { act, data } = useBackend(context); + return ( +
+ + An error occured. Message Not Sent. + + + + +
+ ); +}; + +const RequestConsoleViewMessages = (props, context) => { + const { act, data } = useBackend(context); + const { + message_log, + } = data; + return ( +
+ {(message_log.length && message_log.map((msg, i) => ( + act("print", { print: i + 1 })}> + Print + + }> + {decodeHtmlEntities(msg[1])} + + ))) || ( + + No messages. + + )} +
+ ); +}; + +const RequestConsoleMessageAuth = (props, context) => { + const { act, data } = useBackend(context); + const { + message, + recipient, + priority, + msgStamped, + msgVerified, + } = data; + return ( +
+ + + {message} + + + {priority === 2 ? "High Priority" : (priority === 1 ? "Normal Priority" : "Unknown")} + + + {decodeHtmlEntities(msgVerified) || "No Validation"} + + + {decodeHtmlEntities(msgStamped) || "No Stamp"} + + + + +
+ ); +}; + +const RequestConsoleAnnounce = (props, context) => { + const { act, data } = useBackend(context); + const { + department, + screen, + message_log, + newmessagepriority, + silent, + announcementConsole, + assist_dept, + supply_dept, + info_dept, + message, + recipient, + priority, + msgStamped, + msgVerified, + announceAuth, + } = data; + return ( +
+ {announceAuth && ( + + + ID Verified. Authentication Accepted. + +
act("writeAnnouncement")}> + Edit + + }> + {message || "No Message"} +
+
+ ) || ( + + Swipe your ID card to authenticate yourself. + + )} + + +
+ ); +}; + +let screenToTemplate = {}; +screenToTemplate[RCS_MAINMENU] = RequestConsoleSettings; +screenToTemplate[RCS_RQASSIST] = RequestConsoleAssistance; +screenToTemplate[RCS_RQSUPPLY] = RequestConsoleSupplies; +screenToTemplate[RCS_SENDINFO] = RequestConsoleRelay; +screenToTemplate[RCS_SENTPASS] = RequestConsoleSendPass; +screenToTemplate[RCS_SENTFAIL] = RequestConsoleSendFail; +screenToTemplate[RCS_VIEWMSGS] = RequestConsoleViewMessages; +screenToTemplate[RCS_MESSAUTH] = RequestConsoleMessageAuth; +screenToTemplate[RCS_ANNOUNCE] = RequestConsoleAnnounce; + +export const RequestConsole = (props, context) => { + const { act, data } = useBackend(context); + const { + screen, + newmessagepriority, + announcementConsole, + } = data; + + let BodyElement = screenToTemplate[screen]; + + return ( + + + + act("setScreen", { setScreen: RCS_VIEWMSGS })} + icon="envelope-open-text"> + Messages + + act("setScreen", { setScreen: RCS_RQASSIST })} + icon="share-square"> + Assistance + + act("setScreen", { setScreen: RCS_RQSUPPLY })} + icon="share-square"> + Supplies + + act("setScreen", { setScreen: RCS_SENDINFO })} + icon="share-square-o"> + Report + + {announcementConsole && ( + act("setScreen", { setScreen: RCS_ANNOUNCE })} + icon="volume-up"> + Announce + + ) || null} + act("setScreen", { setScreen: RCS_MAINMENU })} + icon="cog" /> + + {newmessagepriority && ( +
1 ? "NEW PRIORITY MESSAGES" : "There are new messages!"} + color={newmessagepriority > 1 ? "bad" : "average"} bold={newmessagepriority > 1} /> + ) || null} + + + + ); +}; \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/RogueZones.js b/tgui/packages/tgui/interfaces/RogueZones.js new file mode 100644 index 0000000000..3e01200cd6 --- /dev/null +++ b/tgui/packages/tgui/interfaces/RogueZones.js @@ -0,0 +1,98 @@ +import { useBackend } from "../backend"; +import { Box, Button, LabeledList, ProgressBar, Section } from "../components"; +import { Window } from "../layouts"; + +export const RogueZones = (props, context) => { + const { act, data } = useBackend(context); + const { + timeout_percent, + diffstep, + difficulty, + occupied, + scanning, + updated, + debug, + shuttle_location, + shuttle_at_station, + scan_ready, + can_recall_shuttle, + } = data; + return ( + + +
+ + + {difficulty} + + act("recall_shuttle")}> + Recall Shuttle + + ) || null + }> + {shuttle_location} + + {occupied && ( + + WARNING: Area occupied by {occupied} personnel! + + ) || ( + + No personnel detected. + + )} + +
+
act("scan_for_new")}> + Scan For Asteroids + + }> + + + + + {scanning && ( + + In progress. + + ) || null} + {(updated && !scanning) && ( + + Updated shuttle destination! + + ) || null} + {debug && ( + + Timeout Percent: {timeout_percent} + Diffstep: {diffstep} + Difficulty: {difficulty} + Occupied: {occupied} + Debug: {debug} + Shuttle Location: {shuttle_location} + Shuttle at station: {shuttle_at_station} + Scan Ready: {scan_ready} + + ) || null} + +
+
+
+ ); +}; \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/ShuttleControl.js b/tgui/packages/tgui/interfaces/ShuttleControl.js new file mode 100644 index 0000000000..5c798f9a50 --- /dev/null +++ b/tgui/packages/tgui/interfaces/ShuttleControl.js @@ -0,0 +1,478 @@ +import { toTitleCase } from 'common/string'; +import { Fragment } from 'inferno'; +import { useBackend } from "../backend"; +import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section, AnimatedNumber } from "../components"; +import { Window } from "../layouts"; + +/* Helpers */ +const getDockingStatus = (docking_status, docking_override) => { + let main = "ERROR"; + let color = "bad"; + let showsOverride = false; + if (docking_status === "docked") { + main = "DOCKED"; + color = "good"; + } else if (docking_status === "docking") { + main = "DOCKING"; + color = "average"; + showsOverride = true; + } else if (docking_status === "undocking") { + main = "UNDOCKING"; + color = "average"; + showsOverride = true; + } else if (docking_status === "undocked") { + main = "UNDOCKED"; + color = "#676767"; + } + + if (showsOverride && docking_override) { + main = main + "-MANUAL"; + } + + return ( + + {main} + + ); +}; + +/* Templates */ +const ShuttleControlSharedShuttleStatus = (props, context) => { + const { act, data } = useBackend(context); + const { + engineName = "Bluespace Drive", + } = props; + const { + shuttle_status, + shuttle_state, + has_docking, + docking_status, + docking_override, + docking_codes, + } = data; + return ( +
+ {shuttle_status} + + + {shuttle_state === "idle" && ( + + IDLE + + ) || shuttle_state === "warmup" && ( + + SPINNING UP + + ) || shuttle_state === "in_transit" && ( + + ENGAGED + + ) || ( + + ERROR + + )} + + {has_docking && ( + + + {getDockingStatus(docking_status, docking_override)} + + + + + + ) || null} + +
+ ); +}; + +const ShuttleControlSharedShuttleControls = (props, context) => { + const { act, data } = useBackend(context); + + const { + can_launch, + can_cancel, + can_force, + } = data; + + return ( +
+ + + + + + + + + + + +
+ ); +}; + +const ShuttleControlConsoleDefault = (props, context) => { + const { act, data } = useBackend(context); + return ( + + + + + ); +}; + +const ShuttleControlConsoleMulti = (props, context) => { + const { act, data } = useBackend(context); + const { + can_cloak, + can_pick, + legit, + cloaked, + destination_name, + } = data; + return ( + + +
+ + {can_cloak && ( + + + + ) || null} + + + + +
+ +
+ ); +}; + +const ShuttleControlConsoleExploration = (props, context) => { + const { act, data } = useBackend(context); + const { + can_pick, + destination_name, + fuel_usage, + fuel_span, + remaining_fuel, + } = data; + return ( + + +
+ + + + + {fuel_usage && ( + + + {remaining_fuel} m/s + + + {fuel_usage} m/s + + + ) || null} + +
+ +
+ ); +}; + +/* Ugh. Just ugh. */ +const ShuttleControlConsoleWeb = (props, context) => { + const { act, data } = useBackend(context); + + const { + autopilot, + can_rename, + shuttle_state, + is_moving, + skip_docking, + docking_status, + docking_override, + shuttle_location, + can_cloak, + cloaked, + can_autopilot, + routes, + is_in_transit, + travel_progress, + time_left, + doors, + sensors, + } = data; + + return ( + + {autopilot && ( +
+ + This vessel will start and stop automatically. + Ensure that all non-cycling capable hatches and doors are closed, + as the automated system may not be able to control them. + Docking and flight controls are locked. To unlock, disable the automated flight system. + +
+ ) || null} +
act("rename_command")}> + Rename + + ) || null + }> + + + {shuttle_state === "idle" && ( + + IDLE + + ) || shuttle_state === "warmup" && ( + + SPINNING UP + + ) || shuttle_state === "in_transit" && ( + + ENGAGED + + ) || ( + + ERROR + + )} + + {!is_moving && ( + + + {toTitleCase(shuttle_location)} + + {!skip_docking && ( + + + + + }> + {getDockingStatus(docking_status, docking_override)} + + ) || null} + {can_cloak && ( + + + + ) || null} + {can_autopilot && ( + + + + ) || null} + + ) || null} + + {!is_moving && ( +
+ + {routes.length && routes.map(route => ( + + + + )) || ( + + No routes found. + + )} + +
+ ) || null} +
+ {is_in_transit && ( +
+ + + + {time_left}s + + + +
+ ) || null} + {Object.keys(doors).length && ( +
+ + {Object.keys(doors).map(key => { + let door = doors[key]; + return ( + + {door.open && ( + + Open + + ) || ( + + Closed + + )} +  -  + {door.bolted && ( + + Bolted + + ) || ( + + Unbolted + + )} + + ); + })} + +
+ ) || null} + {Object.keys(sensors).length && ( +
+ + {Object.keys(sensors).map(key => { + let sensor = sensors[key]; + if (sensor.reading !== -1) { + return ( + + Unable to get sensor air reading. + + ); + } + return ( + + + + {sensor.pressure}kPa + + + {sensor.temp}°C + + + {sensor.oxygen}% + + + {sensor.nitrogen}% + + + {sensor.carbon_dioxide}% + + + {sensor.phoron}% + + {sensor.other && ( + + {sensor.other}% + + ) || null} + + + ); + })} + +
+ ) || null} +
+ ); +}; + +// This may look tempting to convert to require() or some kind of dynamic call +// Don't do it. XSS abound. +const SubtemplateList = { + "ShuttleControlConsoleDefault": , + "ShuttleControlConsoleMulti": , + "ShuttleControlConsoleExploration": , + "ShuttleControlConsoleWeb": , +}; + +export const ShuttleControl = (props, context) => { + const { act, data } = useBackend(context); + const { + subtemplate, + } = data; + return ( + + + {SubtemplateList[subtemplate]} + + + ); +}; \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/SupplyConsole.js b/tgui/packages/tgui/interfaces/SupplyConsole.js new file mode 100644 index 0000000000..69ee550849 --- /dev/null +++ b/tgui/packages/tgui/interfaces/SupplyConsole.js @@ -0,0 +1,439 @@ +import { filter, sortBy } from 'common/collections'; +import { round } from "common/math"; +import { Fragment } from "inferno"; +import { formatTime } from "../format"; +import { useBackend, useLocalState } from "../backend"; +import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section, Tabs, Collapsible, AnimatedNumber } from "../components"; +import { ComplexModal, modalRegisterBodyOverride } from '../interfaces/common/ComplexModal'; +import { Window } from "../layouts"; +import { flow } from 'common/fp'; + +const viewCrateContents = (modal, context) => { + const { act, data } = useBackend(context); + const { + supply_points, + } = data; + const { + name, + cost, + manifest, + ref, + random, + } = modal.args; + return ( +
supply_points} + onClick={() => act("request_crate", { ref: ref })} /> + }> +
+ {manifest.map(m => ( + + {m} + + ))} +
+
+ ); +}; + +export const SupplyConsole = (props, context) => { + const { act, data } = useBackend(context); + modalRegisterBodyOverride("view_crate", viewCrateContents); + return ( + + + +
+ + +
+
+
+ ); +}; + +const SupplyConsoleShuttleStatus = (props, context) => { + const { act, data } = useBackend(context); + + const { + supply_points, + shuttle, + shuttle_auth, + } = data; + + let shuttle_buttons = null; + let showShuttleForce = false; + + if (shuttle_auth) { + if (shuttle.launch === 1 && shuttle.mode === 0) { + shuttle_buttons = ( +
+ + ); +}; + +const SupplyConsoleMenu = (props, context) => { + const { act, data } = useBackend(context); + + const { + order_auth, + } = data; + + const [tabIndex, setTabIndex] = useLocalState(context, "tabIndex", 0); + + return ( +
+ + setTabIndex(0)}> + Request + + setTabIndex(1)}> + Accepted + + setTabIndex(2)}> + Requests + + setTabIndex(3)}> + Order history + + setTabIndex(4)}> + Export history + + + {tabIndex === 0 ? : null} + {tabIndex === 1 ? : null} + {tabIndex === 2 ? : null} + {tabIndex === 3 ? : null} + {tabIndex === 4 ? : null} +
+ ); +}; + +const SupplyConsoleMenuOrder = (props, context) => { + const { act, data } = useBackend(context); + + const { + categories, + supply_packs, + contraband, + supply_points, + } = data; + + const [activeCategory, setActiveCategory] = useLocalState(context, "activeCategory", null); + + const viewingPacks = flow([ + filter(val => val.group === activeCategory), + filter(val => !val.contraband || contraband), + sortBy(val => val.name), + sortBy(val => (val.cost > supply_points)), + ])(supply_packs); + + // const viewingPacks = sortBy(val => val.name)(supply_packs).filter(val => val.group === activeCategory); + + return ( +
+ + +
+ {categories.map(category => ( +
+
+ +
+ {viewingPacks.map(pack => ( + + + +
+
+
+
+ ); +}; + +const SupplyConsoleMenuOrderList = (props, context) => { + const { act, data } = useBackend(context); + const { + mode, + } = props; + const { + orders, + order_auth, + supply_points, + } = data; + + const displayedOrders = orders.filter(val => (val.status === mode || mode === "All")); + + if (!displayedOrders.length) { + return ( +
+ No orders found. +
+ ); + } + + return ( +
+ {(mode === "Requested" && order_auth) ? ( +
+ ))} + + ); +}; + +const SupplyConsoleMenuHistoryExport = (props, context) => { + const { act, data } = useBackend(context); + const { + receipts, + order_auth, + } = data; + + if (!receipts.length) { + return ( +
+ No receipts found. +
+ ); + } + + return ( +
+ {receipts.map((r, ri) => ( +
+ + {r.title.map(title => ( + act("export_edit", { ref: r.ref, edit: title.field, default: title.entry })} /> + ) : null}> + {title.entry} + + ))} + {r.error ? ( + + {r.error} + + ) : r.contents.map((item, i) => ( + +
+ ))} +
+ ); +}; \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/common/Mining.js b/tgui/packages/tgui/interfaces/common/Mining.js new file mode 100644 index 0000000000..4a4f12fd37 --- /dev/null +++ b/tgui/packages/tgui/interfaces/common/Mining.js @@ -0,0 +1,44 @@ +import { Fragment } from 'inferno'; +import { useBackend } from "../../backend"; +import { Box, Button, Input, NoticeBox } from '../../components'; + +export const MiningUser = (props, context) => { + const { act, data } = useBackend(context); + const { + insertIdText, + } = props; + const { + has_id, + id, + } = data; + return ( + + {has_id ? ( + + + Logged in as {id.name}.
+ You have {id.points.toLocaleString('en-US')} points. +
+