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 += "
| [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\] |
| [capitalize(stacktype)]: | [machine.stack_storage[stacktype]] | \[release\] |
| [prize.equipment_name] | [prize.cost] | Purchase |
| [prize.equipment_name] | [prize.cost] | Purchase |