diff --git a/code/game/machinery/computer/supply.dm b/code/game/machinery/computer/supply.dm index 63b85c47730..cf7e1d5197b 100644 --- a/code/game/machinery/computer/supply.dm +++ b/code/game/machinery/computer/supply.dm @@ -398,7 +398,6 @@ if("send_to_station") shuttle.launch(src) to_chat(usr, "The supply shuttle has been called and will arrive in approximately [round(supply_controller.movetime/600,1)] minutes.") - post_signal("supply") if("cancel_shuttle") shuttle.cancel_launch(src) diff --git a/code/game/objects/items/devices/communicator/cartridge.dm b/code/game/objects/items/devices/communicator/cartridge.dm index 732f52cb57a..57c83e66dc3 100644 --- a/code/game/objects/items/devices/communicator/cartridge.dm +++ b/code/game/objects/items/devices/communicator/cartridge.dm @@ -84,19 +84,14 @@ if(G.loc != src) // No longer within the cartridge return - world << "Valid gps_target" - switch(href_list["gps_action"]) if("Power") - world << "Setting tracking to [href_list["value"]]" G.tracking = text2num(href_list["value"]) if("Long_Range") - world << "Setting local_mode to [href_list["value"]]" G.local_mode = text2num(href_list["value"]) if("Hide_Signal") - world << "Setting hide_signal to [href_list["value"]]" G.hide_signal = text2num(href_list["value"]) if("Tag") @@ -106,11 +101,242 @@ var/newTag = input(user, "Please enter desired tag.", G.tag) as text|null - world << "Setting Tag to [newTag]" - if(newTag) G.tag = newTag + if(href_list["active_category"]) + internal_data["supply_category"] = href_list["active_category"] + + // Supply topic + // Copied from /obj/machinery/computer/supplycomp/Topic() + // code\game\machinery\computer\supply.dm, line 188 + // Unfortunately, in order to support complete functionality, the whole thing is necessary + 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"]) + internal_data["supply_pack_expanded"] ^= 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(world.time < internal_data["supply_reqtime"]) + visible_message("[src] flashes, \"[internal_data["supply_reqtime"] - world.time] seconds remaining until another requisition form may be printed.\"") + return + + var/timeout = world.time + 600 + var/reason = sanitize(input(user, "Reason:","Why do you require this item?","") as null|text) + if(world.time > timeout) + to_chat(user, "Error. Request timed out.") + return + if(!reason) + return + + supply_controller.create_order(S, user, reason) + internal_data["supply_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) + if(!new_val) + return + + switch(href_list["edit"]) + if("Supply Pack") + O.name = new_val + + if("Cost") + var/num = text2num(new_val) + if(num) + O.cost = num + + if("Index") + var/num = text2num(new_val) + if(num) + O.index = num + + if("Reason") + O.comment = new_val + + if("Ordered by") + O.ordered_by = new_val + + if("Ordered at") + O.ordered_at = new_val + + if("Approved by") + O.approved_by = new_val + + if("Approved at") + O.approved_at = new_val + + if(href_list["approve"]) + supply_controller.approve_order(O, user) + + if(href_list["deny"]) + supply_controller.deny_order(O, user) + + if(href_list["delete"]) + supply_controller.delete_order(O, user) + + if(href_list["clear_all_requests"]) + var/mob/user = locate(href_list["user"]) + if(!istype(user)) // Invalid ref + return + + supply_controller.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) + if(!new_val) + return + + switch(href_list["edit"]) + if("Name") + E.name = new_val + + if("Value") + var/num = text2num(new_val) + if(num) + E.value = num + + else if(href_list["delete"]) + supply_controller.delete_export(E, user) + + else if(href_list["add_item"]) + supply_controller.add_export_item(E, user) + + if(supply_controller && supply_controller.shuttle) + switch(href_list["send_shuttle"]) + if("send_away") + if(supply_controller.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 + supply_controller.shuttle.launch(src) + to_chat(usr, "Initiating launch sequence.") + + if("send_to_station") + supply_controller.shuttle.launch(src) + to_chat(usr, "The supply shuttle has been called and will arrive in approximately [round(supply_controller.movetime/600,1)] minutes.") + + if("cancel_shuttle") + supply_controller.shuttle.cancel_launch(src) + + if("force_shuttle") + supply_controller.shuttle.force_launch(src) + + switch(href_list["stat_display"]) + if("message") + post_status("message", internal_data["stat_display_line1"], internal_data["stat_display_line2"]) + internal_data["stat_display_special"] = "message" + if("alert") + post_status("alert", href_list["alert"]) + internal_data["stat_display_special"] = href_list["alert"] + if("setmsg") + internal_data["stat_display_line[href_list["line"]]"] = reject_bad_text(sanitize(input("Line 1", "Enter Message Text", internal_data["stat_display_line[href_list["line"]]"]) as text|null, 40), 40) + else + post_status(href_list["stat_display"]) + internal_data["stat_display_special"] = href_list["stat_display"] + + +// Updates status displays with a new message +// Copied from /obj/itme/weapon/cartridge/proc/post_status(), +// code\game\objects\items\devices\PDA\cart.dm, line 251 +/obj/item/weapon/commcard/proc/post_status(var/command, var/data1, var/data2) + var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435) + if(!frequency) + return + + var/datum/signal/status_signal = new + status_signal.source = src + status_signal.transmission_method = 1 + status_signal.data["command"] = command + + switch(command) + if("message") + status_signal.data["msg1"] = data1 + status_signal.data["msg2"] = data2 + if(loc) + var/obj/item/PDA = loc + var/mob/user = PDA.fingerprintslast + log_admin("STATUS: [user] set status screen with [src]. Message: [data1] [data2]") + message_admins("STATUS: [user] set status screen with [src]. Message: [data1] [data2]") + + if("alert") + status_signal.data["picture_state"] = data1 + + frequency.post_signal(src, status_signal) + +// Receives updates by external devices to the status displays +/obj/item/weapon/commcard/receive_signal(var/datum/signal/signal, var/receive_method, var/receive_param) + // Putting it inside a frequency switch in case future uses also need to use the radio controller, and they use similar commands, different freq's + switch(signal.frequency) + if(1435) + internal_data["stat_display_special"] = signal.data["command"] + switch(signal.data["command"]) + if("message") + internal_data["stat_display_line1"] = signal.data["msg1"] + internal_data["stat_display_line2"] = signal.data["msg2"] + if("alert") + internal_data["stat_display_special"] = signal.data["picture_state"] + // Engineering Cartridge: // Devices @@ -215,9 +441,6 @@ list("name" = "Security Records", "template" = "sec_records.tmpl") ) -/obj/item/weapon/commcard/int_aff/New() - ..() - /obj/item/weapon/commcard/int_aff/get_data() return list( list("field" = "emp_records", "value" = get_emp_records()), @@ -234,12 +457,9 @@ icon_state = "cart-s" ui_templates = list( list("name" = "Security Records", "template" = "sec_records.tmpl"), - list("name" = "Security Bot Controller", "template" = "sec_bot_access.tmpl") + list("name" = "Security Bot Control", "template" = "sec_bot_access.tmpl") ) -/obj/item/weapon/commcard/security/New() - ..() - /obj/item/weapon/commcard/security/get_data() return list( list("field" = "sec_records", "value" = get_sec_records()), @@ -278,7 +498,6 @@ /obj/item/weapon/commcard/signal/New() ..() internal_devices |= new /obj/item/device/assembly/signaler(src) - // I'm probably gonna regret this too /obj/item/weapon/commcard/signal/get_data() return list( @@ -307,16 +526,47 @@ // Supply Cartridge: // Templates -// -- Supply Records -// -- Supply Bot Access +// *- Supply Records +// ?- Supply Bot Access /obj/item/weapon/commcard/supply name = "\improper Space Parts & Space Vendors cartridge" desc = "Perfect for the Quartermaster on the go!" icon_state = "cart-q" + ui_templates = list( + list("name" = "Supply Records", "template" = "supply_records.tmpl"), + list("name" = "Supply Bot Control", "template" = "supply_bot_access.tmpl") + ) + +/obj/item/weapon/commcard/supply/New() + ..() + internal_data["supply_category"] = null + internal_data["supply_controls"] = FALSE // Cannot control the supply shuttle, cannot accept orders + internal_data["supply_pack_expanded"] = list() + internal_data["supply_reqtime"] = -1 /obj/item/weapon/commcard/supply/get_data() - // Add supply records to ui template - // Add supply bot access to ui template + // Supply records data + var/list/shuttle_status = get_supply_shuttle_status() + var/list/orders = get_supply_orders() + var/list/receipts = get_supply_receipts() + var/list/misc_supply_data = get_misc_supply_data() // Packaging this stuff externally so it's less hardcoded into the specific cartridge + var/list/pack_list = list() // List of supply packs within the currently selected category + + if(internal_data["supply_category"]) + pack_list = get_supply_pack_list() + + return list( + list("field" = "shuttle_auth", "value" = misc_supply_data["shuttle_auth"]), + list("field" = "order_auth", "value" = misc_supply_data["order_auth"]), + list("field" = "supply_points", "value" = misc_supply_data["supply_points"]), + list("field" = "categories", "value" = misc_supply_data["supply_categories"]), + list("field" = "contraband", "value" = misc_supply_data["contraband"]), + list("field" = "active_category", "value" = internal_data["supply_category"]), + list("field" = "shuttle", "value" = shuttle_status), + list("field" = "orders", "value" = orders), + list("field" = "receipts", "value" = receipts), + list("field" = "supply_packs", "value" = pack_list) + ) // Command Cartridge: @@ -326,20 +576,46 @@ /obj/item/weapon/commcard/head name = "\improper Easy-Record DELUXE" icon_state = "cart-h" + ui_templates = list( + list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"), + list("name" = "Employment Records", "template" = "emp_records.tmpl") + ) + +/obj/item/weapon/commcard/head/New() + ..() + internal_data["stat_display_line1"] = null + internal_data["stat_display_line2"] = null + internal_data["stat_display_special"] = null + +/obj/item/weapon/commcard/head/initialize() + // Have to register the commcard with the Radio controller to receive updates to the status displays + radio_controller.add_object(src, 1435) + ..() + +/obj/item/weapon/commcard/head/Destroy() + // Have to unregister the commcard for proper bookkeeping + radio_controller.remove_object(src, 1435) + ..() /obj/item/weapon/commcard/head/get_data() - // Add status display to ui template - // Add employment records to ui template + var/list/status_message = list( + "line1" = internal_data["stat_display_line1"], + "line2" = internal_data["stat_display_line2"], + "active" = internal_data["stat_display_special"] + ) + return list( + list("field" = "emp_records", "value" = get_emp_records()), + list("field" = "stat_display", "value" = status_message) + ) // Head of Personnel Cartridge: // Templates // -- Status Display Access // *- Employment Records // *- Security Records -// -- Supply Records -// -- Supply Bot Access -// X- Recipe Lists - See service cartridge +// *- Supply Records +// ?- Supply Bot Access // *- Janitorial Locator Magicbox /obj/item/weapon/commcard/head/hop name = "\improper HumanResources9001 cartridge" @@ -460,7 +736,7 @@ // *- Medical Records // *- Security Records // *- Power Monitoring -// -- Supply Records +// *- Supply Records // -- Supply Bot Access // *- Security Bot Access // *- Janitorial Locator Magicbox @@ -499,6 +775,7 @@ // IMPORTANT: NOT MAPPED IN DUE TO BALANCE CONCERNS RE: FINDING THE VICTIMS OF ANTAGS. // See suit sensors, specifically ease of turning them off, and variable level of settings which may or may not give location +// A GPS in your phone that is either broadcasting position or totally off, and can be hidden in pockets, coats, bags, boxes, etc, is much harder to disable /obj/item/weapon/commcard/explorer name = "\improper Explorator cartridge" icon_state = "cart-tox" diff --git a/code/game/objects/items/devices/communicator/helper.dm b/code/game/objects/items/devices/communicator/helper.dm index cdc1ffbf78d..14581b7ff95 100644 --- a/code/game/objects/items/devices/communicator/helper.dm +++ b/code/game/objects/items/devices/communicator/helper.dm @@ -386,4 +386,140 @@ intgps, extgps, stagps - ) \ No newline at end of file + ) + +// Collects the current status of the supply shuttle +// Copied from /obj/machinery/computer/supplycomp/ui_interact(), +// code\game\machinery\computer\supply.dm, starting at line 55 +/obj/item/weapon/commcard/proc/get_supply_shuttle_status() + var/shuttle_status[0] + var/datum/shuttle/ferry/supply/shuttle = supply_controller.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() + + else + shuttle_status["time"] = 0 + if(shuttle.at_station()) + if(shuttle.docking_controller) + switch(shuttle.docking_controller.get_docking_status()) + if("docked") + shuttle_status["location"] = "Docked" + shuttle_status["mode"] = SUP_SHUTTLE_DOCKED + if("undocked") + shuttle_status["location"] = "Undocked" + shuttle_status["mode"] = SUP_SHUTTLE_UNDOCKED + if("docking") + shuttle_status["location"] = "Docking" + shuttle_status["mode"] = SUP_SHUTTLE_DOCKING + shuttle_status["force"] = shuttle.can_force() + if("undocking") + shuttle_status["location"] = "Undocking" + shuttle_status["mode"] = SUP_SHUTTLE_UNDOCKING + shuttle_status["force"] = shuttle.can_force() + + else + shuttle_status["location"] = "Station" + shuttle_status["mode"] = SUP_SHUTTLE_DOCKED + + else + shuttle_status["location"] = "Away" + shuttle_status["mode"] = SUP_SHUTTLE_AWAY + + if(shuttle.can_launch()) + shuttle_status["launch"] = 1 + else if(shuttle.can_cancel()) + shuttle_status["launch"] = 2 + else + shuttle_status["launch"] = 0 + + switch(shuttle.moving_status) + if(SHUTTLE_IDLE) + shuttle_status["engine"] = "Idle" + if(SHUTTLE_WARMUP) + shuttle_status["engine"] = "Warming up" + if(SHUTTLE_INTRANSIT) + shuttle_status["engine"] = "Engaged" + + else + shuttle["mode"] = SUP_SHUTTLE_ERROR + + return shuttle_status + +// Compiles the list of supply orders +// Copied from /obj/machinery/computer/supplycomp/ui_interact(), +// code\game\machinery\computer\supply.dm, starting at line 130 +/obj/item/weapon/commcard/proc/get_supply_orders() + var/orders[0] + for(var/datum/supply_order/S in supply_controller.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) + ) + ) + + return orders + +// Compiles the list of supply export receipts +// Copied from /obj/machinery/computer/supplycomp/ui_interact(), +// code\game\machinery\computer\supply.dm, starting at line 147 +/obj/item/weapon/commcard/proc/get_supply_receipts() + var/receipts[0] + for(var/datum/exported_crate/E in supply_controller.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) + ) + ) + return receipts + + +// Compiles the list of supply packs for the category currently stored in internal_data["supply_category"] +// Copied from /obj/machinery/computer/supplycomp/ui_interact(), +// code\game\machinery\computer\supply.dm, starting at line 147 +/obj/item/weapon/commcard/proc/get_supply_pack_list() + var/supply_packs[0] + for(var/pack_name in supply_controller.supply_pack) + var/datum/supply_pack/P = supply_controller.supply_pack[pack_name] + if(P.group == internal_data["supply_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 internal_data["supply_pack_expanded"]) + pack["expand"] = 1 + + supply_packs[++supply_packs.len] = pack + + return supply_packs + + +// Compiles miscellaneous data and permissions used by the supply template +/obj/item/weapon/commcard/proc/get_misc_supply_data() + return list( + "shuttle_auth" = (internal_data["supply_controls"] & SUP_SEND_SHUTTLE), + "order_auth" = (internal_data["supply_controls"] & SUP_ACCEPT_ORDERS), + "supply_points" = supply_controller.points, + "supply_categories" = all_supply_groups + ) diff --git a/nano/templates/stat_display_access.tmpl b/nano/templates/stat_display_access.tmpl new file mode 100644 index 00000000000..f00f44d3fcc --- /dev/null +++ b/nano/templates/stat_display_access.tmpl @@ -0,0 +1,34 @@ +

Station Status Display Interlink

+ +
+
+ Code: +
+
+ {{:helper.link('Clear Message', 'trash', {'cartridge_topic' : "1", 'stat_display' : "blank"}, (data.stat_display.active == "blank") ? 'active' : null, null)}} + {{:helper.link('Shuttle ETA', 'gear', {'cartridge_topic' : "1", 'stat_display' : "shuttle"}, (data.stat_display.active == "shuttle") ? 'active' : null, null)}} + {{:helper.link('Set Message', 'gear', {'cartridge_topic' : "1", 'stat_display' : "message"}, (data.stat_display.active == "message") ? 'active' : null, null)}} +
+
+ {{:helper.link('Clear Alert', 'alert', {'cartridge_topic' : "1", 'choice' : "Status", 'stat_display' : "alert", 'alert' : "default"}, (data.stat_display.active == "default") ? 'active' : null, null)}} + {{:helper.link('Red Alert', 'alert', {'cartridge_topic' : "1", 'choice' : "Status", 'stat_display' : "alert", 'alert' : "redalert"}, (data.stat_display.active == "redalert") ? 'active' : null, null)}} + {{:helper.link('Lockdown', 'caution', {'cartridge_topic' : "1", 'choice' : "Status", 'stat_display' : "alert", 'alert' : "lockdown"}, (data.stat_display.active == "lockdown") ? 'active' : null, null)}} + {{:helper.link('Biohazard', 'radiation', {'cartridge_topic' : "1", 'choice' : "Status", 'stat_display' : "alert", 'alert' : "biohazard"}, (data.stat_display.active == "biohazard") ? 'active' : null, null)}} +
+
+
+
+ Message line 1 +
+
+ {{:helper.link(data.stat_display.line1 + ' (set)', 'pencil', {'cartridge_topic' : "1", 'stat_display' : "setmsg", 'line' : "1"}, null, null)}} +
+
+
+
+ Message line 2 +
+
+ {{:helper.link(data.stat_display.line2 + ' (set)', 'pencil', {'cartridge_topic' : "1", 'stat_display' : "setmsg", 'line' : "2"}, null, null)}} +
+