diff --git a/baystation12.dme b/baystation12.dme index 4c45d783ba9..0d7516eff2b 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -550,6 +550,7 @@ #include "code\game\mecha\combat\marauder.dm" #include "code\game\mecha\combat\phazon.dm" #include "code\game\mecha\equipment\mecha_equipment.dm" +#include "code\game\mecha\equipment\tracking_beacon.dm" #include "code\game\mecha\equipment\tools\medical_tools.dm" #include "code\game\mecha\equipment\tools\tools.dm" #include "code\game\mecha\equipment\weapons\weapons.dm" @@ -1532,6 +1533,7 @@ #include "code\modules\modular_computers\file_system\program.dm" #include "code\modules\modular_computers\file_system\programs\_engineering.dm" #include "code\modules\modular_computers\file_system\programs\_medical.dm" +#include "code\modules\modular_computers\file_system\programs\_research.dm" #include "code\modules\modular_computers\file_system\programs\card.dm" #include "code\modules\modular_computers\file_system\programs\configurator.dm" #include "code\modules\modular_computers\file_system\programs\file_browser.dm" @@ -1582,6 +1584,7 @@ #include "code\modules\nano\modules\alarm_monitor.dm" #include "code\modules\nano\modules\atmos_control.dm" #include "code\modules\nano\modules\crew_monitor.dm" +#include "code\modules\nano\modules\exosuit_control.dm" #include "code\modules\nano\modules\human_appearance.dm" #include "code\modules\nano\modules\law_manager.dm" #include "code\modules\nano\modules\nano_module.dm" diff --git a/code/game/mecha/equipment/tracking_beacon.dm b/code/game/mecha/equipment/tracking_beacon.dm new file mode 100644 index 00000000000..92787c3873d --- /dev/null +++ b/code/game/mecha/equipment/tracking_beacon.dm @@ -0,0 +1,142 @@ + + +/obj/item/mecha_parts/mecha_tracking + name = "Exosuit tracking beacon" + desc = "Device used to transmit exosuit data." + icon = 'icons/obj/device.dmi' + icon_state = "motion2" + origin_tech = list(TECH_DATA = 2, TECH_MAGNET = 2) + var/control = 0// + +/obj/item/mecha_parts/mecha_tracking/initialize() + if (in_mecha()) + exo_beacons.Add(src)//For the sake of exosuits which spawn with a preinstalled tracking beacon + +/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info() + if(!in_mecha()) + return 0 + var/obj/mecha/M = src.loc + var/cell_charge = M.get_charge() + var/answer = {"Name: [M.name]
+ Integrity: [M.health/initial(M.health)*100]%
+ Cell charge: [isnull(cell_charge)?"Not found":"[M.cell.percent()]%"]
+ Airtank: [M.return_pressure()]kPa
+ Pilot: [M.occupant||"None"]
+ Location: [get_area(M)||"Unknown"]
+ Active equipment: [M.selected||"None"]"} + if(istype(M, /obj/mecha/working/ripley)) + var/obj/mecha/working/ripley/RM = M + answer += "Used cargo space: [RM.cargo.len/RM.cargo_capacity*100]%
" + + return answer + + +//Alternate version of this proc for nanoui +/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info_nano() + if(!in_mecha()) + return 0 + var/obj/mecha/M = src.loc + var/cell_charge = M.get_charge() + var/list/answer = list() + answer["name"] = M.name + answer["health"] = round((M.health/initial(M.health))*100, 0.1) + answer["charge"] = "[isnull(cell_charge)?"Not found":M.cell.percent()]%" + answer["air"] = "[M.return_pressure()]" + if (M.occupant) + answer["pilot"] = M.occupant.name + answer["location"] = get_area(M) + answer["active"] = M.selected || "None" + answer["ref"] = "\ref[src]" + answer["control"] = control + + if(istype(M, /obj/mecha/working/ripley)) + var/obj/mecha/working/ripley/RM = M + answer["cargo"] = "[RM.cargo.len/RM.cargo_capacity*100]" + + return answer + +/obj/item/mecha_parts/mecha_tracking/proc/install(var/obj/mecha/M, var/mob/living/user = null) + if (!istype(M)) + return + + if (M.state < 3) + user << span("warning", "You need to open the maintenance panel in order to install \the [src]") + return + + for (var/obj/item/mecha_parts/mecha_tracking/B in M.contents) + user << span("warning", "[M] already has a tracker installed. Please remove the existing one.") + return + + user.drop_from_inventory(src) + src.forceMove(M) + playsound(get_turf(user), 'sound/items/Deconstruct.ogg', 50, 1) + exo_beacons.Add(src) + user.visible_message("[user] installs [src] in [M].", "You install [src] in [M]") + +/obj/item/mecha_parts/mecha_tracking/proc/uninstall(var/mob/living/user) + var/obj/mecha/M = in_mecha() + if (!M)//This should never happen + return + + user.put_in_hands(src) + exo_beacons.Remove(src) + user.visible_message("[user] removes [src] from [M].", "You remove [src] from [M]") + + +/obj/item/mecha_parts/mecha_tracking/emp_act() + qdel(src) + return + +/obj/item/mecha_parts/mecha_tracking/ex_act() + qdel(src) + return + +/obj/item/mecha_parts/mecha_tracking/proc/in_mecha() + if(istype(src.loc, /obj/mecha)) + return src.loc + return 0 + +/obj/item/mecha_parts/mecha_tracking/proc/shock(var/mob/user) + return//No killswitch on the basic version + +/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_log() + if(!src.in_mecha()) + return 0 + var/obj/mecha/M = src.loc + return M.get_log_html() + + + + +//Subclass of tracking beacon which has the killswitch function +/obj/item/mecha_parts/mecha_tracking/control + control = 1 + name = "Exosuit Control Beacon" + desc = "Device used to transmit exosuit data. Allows an administrator to trigger a killswitch and remotely shutdown the exosuit." + +//Remote killswitch fucks everything up. +//The suit is probably not unsalvageable, but will require extensive repairs and be crippled +/obj/item/mecha_parts/mecha_tracking/control/shock(var/mob/user) + var/obj/mecha/M = in_mecha() + if(M) + M.occupant_message(span("danger", "Remote termination protocol initiated. This exosuit is now shutting down, please exit immediately. Continued operation may incur disciplinary action or death of user.")) + M.emp_act(1) + M.random_internal_damage(95)//Trigger all possible forms of internal damage + M.misconfigure_systems(95) + //Screw up all systems, including maintenance mode which will cause immediate stop + M.log_message("Remote termination protocol initiated by [user].",1) + + qdel(src) + +/obj/item/weapon/storage/box/mechabeacons + name = "Exosuit Control Beacons" + +/obj/item/weapon/storage/box/mechabeacons/New() + ..() + new /obj/item/mecha_parts/mecha_tracking/control(src) + new /obj/item/mecha_parts/mecha_tracking/control(src) + new /obj/item/mecha_parts/mecha_tracking/control(src) + new /obj/item/mecha_parts/mecha_tracking/control(src) + new /obj/item/mecha_parts/mecha_tracking/control(src) + new /obj/item/mecha_parts/mecha_tracking/control(src) + new /obj/item/mecha_parts/mecha_tracking/control(src) diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 9f737487029..921038416a5 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -97,7 +97,7 @@ M.say("*scream") ui_interact(user) -/obj/machinery/mecha_part_fabricator/ui_interact(var/mob/user, var/ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/machinery/mecha_part_fabricator/ui_interact(var/mob/user, var/ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) var/data[0] var/datum/design/current = queue.len ? queue[1] : null diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 5faacc45736..3f68e00a92b 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -343,6 +343,37 @@ if(src_object in view(2, src)) return STATUS_UPDATE //if they're close enough, allow the occupant to see the screen through the viewport or whatever. +//Menu for physically removing things from the suit while fiddling around in the maintenance panel +/obj/mecha/proc/removal_menu(var/mob/living/user) + var/list/options = list() + if(src.cell) + options += "Power Cell" + + var/obj/item/mecha_parts/mecha_tracking/beacon = locate(/obj/item/mecha_parts/mecha_tracking) in src + if (beacon) + options += "Tracking Beacon" + + if (!options.len) + user << "There are no components in [src] that can be removed" + return + + var/choice = input(user, "Choose a component to remove.", "Component removal") as null|anything in options + + if (!choice || !user) + return + + switch(choice) + if("Power Cell") + if (!cell) + return + user.put_in_hands(cell) + cell = null + user << "You unscrew and pry out the powercell." + log_message("Powercell removed.") + if ("Tracking Beacon") + if (beacon && beacon.loc == src)//safety + beacon.uninstall(user) + /obj/mecha/proc/melee_action(atom/target) return @@ -706,8 +737,10 @@ /obj/mecha/emp_act(severity) if(get_charge()) - use_power((6500)/severity) - take_damage(40 / severity,"energy") + use_power((4000)/severity) + take_damage(30 / severity,"energy") + random_internal_damage(7/severity) + misconfigure_systems(10/severity) src.log_message("EMP detected",1) check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1) return @@ -755,17 +788,21 @@ if(state==1) state = 2 user << "You undo the securing bolts." + playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1) else if(state==2) state = 1 user << "You tighten the securing bolts." + playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1) return else if(istype(W, /obj/item/weapon/crowbar)) if(state==2) state = 3 user << "You open the hatch to the power unit" + playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) else if(state==3) state=2 user << "You close the hatch to the power unit" + playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1) return else if(istype(W, /obj/item/stack/cable_coil)) if(state == 3 && hasInternalDamage(MECHA_INT_SHORT_CIRCUIT)) @@ -780,15 +817,10 @@ if(hasInternalDamage(MECHA_INT_TEMP_CONTROL)) clearInternalDamage(MECHA_INT_TEMP_CONTROL) user << "You repair the damaged temperature controller." - else if(state==3 && src.cell) - src.cell.forceMove(src.loc) - src.cell = null - state = 4 - user << "You unscrew and pry out the powercell." - src.log_message("Powercell removed.") - else if(state==4 && src.cell) - state=3 - user << "You screw the cell in place." + + else if(state==3) + removal_menu(user) + return else if(istype(W, /obj/item/device/multitool)) @@ -804,7 +836,7 @@ return else if(istype(W, /obj/item/weapon/cell)) - if(state==4) + if(state==3) if(!src.cell) user << "You install the powercell" user.drop_item() @@ -833,9 +865,8 @@ return else if(istype(W, /obj/item/mecha_parts/mecha_tracking)) - user.drop_from_inventory(W) - W.forceMove(src) - user.visible_message("[user] attaches [W] to [src].", "You attach [W] to [src]") + var/obj/item/mecha_parts/mecha_tracking/C = W + C.install(src, user) return else diff --git a/code/game/mecha/mecha_control_console.dm b/code/game/mecha/mecha_control_console.dm index c3afbb17359..e1e866209f9 100644 --- a/code/game/mecha/mecha_control_console.dm +++ b/code/game/mecha/mecha_control_console.dm @@ -1,3 +1,6 @@ +//Note: This console is deprecated. +//The exosuit control program in modular computers is its successor + /obj/machinery/computer/mecha name = "Exosuit Control" icon = 'icons/obj/computer.dmi' @@ -10,119 +13,57 @@ var/screen = 0 var/stored_data - attack_ai(var/mob/user as mob) +/obj/machinery/computer/mecha/attack_ai(var/mob/user as mob) return src.attack_hand(user) - attack_hand(var/mob/user as mob) - if(..()) - return - user.set_machine(src) - var/dat = "[src.name]" - if(screen == 0) - dat += "

Tracking beacons data

" - for(var/obj/item/mecha_parts/mecha_tracking/TR in world) - var/answer = TR.get_mecha_info() - if(answer) - dat += {"
[answer]
- Send message
- Show exosuit log | (EMP pulse)
"} - - if(screen==1) - dat += "

Log contents

" - dat += "Return
" - dat += "[stored_data]" - - dat += "(Refresh)
" - dat += "" - - user << browse(dat, "window=computer;size=400x500") - onclose(user, "computer") +/obj/machinery/computer/mecha/attack_hand(var/mob/user as mob) + if(..()) return + user.set_machine(src) + var/dat = "[src.name]" + if(screen == 0) + dat += "

Tracking beacons data

" + for(var/obj/item/mecha_parts/mecha_tracking/TR in world) + var/answer = TR.get_mecha_info() + if(answer) + dat += {"
[answer]
+ Send message
+ Show exosuit log | (EMP pulse)
"} - Topic(href, href_list) - if(..()) - return - var/datum/topic_input/filter = new /datum/topic_input(href,href_list) - if(href_list["send_message"]) - var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("send_message") - var/message = sanitize(input(usr,"Input message","Transmit message") as text) - var/obj/mecha/M = MT.in_mecha() - if(message && M) - M.occupant_message(message) - return - if(href_list["shock"]) - var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("shock") - MT.shock() - if(href_list["get_log"]) - var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("get_log") - stored_data = MT.get_mecha_log() - screen = 1 - if(href_list["return"]) - screen = 0 - src.updateUsrDialog() + if(screen==1) + dat += "

Log contents

" + dat += "Return
" + dat += "[stored_data]" + + dat += "(Refresh)
" + dat += "" + + user << browse(dat, "window=computer;size=400x500") + onclose(user, "computer") + return + +/obj/machinery/computer/mecha/Topic(href, href_list) + if(..()) return - - - -/obj/item/mecha_parts/mecha_tracking - name = "Exosuit tracking beacon" - desc = "Device used to transmit exosuit data." - icon = 'icons/obj/device.dmi' - icon_state = "motion2" - origin_tech = list(TECH_DATA = 2, TECH_MAGNET = 2) - - proc/get_mecha_info() - if(!in_mecha()) - return 0 - var/obj/mecha/M = src.loc - var/cell_charge = M.get_charge() - var/answer = {"Name: [M.name]
- Integrity: [M.health/initial(M.health)*100]%
- Cell charge: [isnull(cell_charge)?"Not found":"[M.cell.percent()]%"]
- Airtank: [M.return_pressure()]kPa
- Pilot: [M.occupant||"None"]
- Location: [get_area(M)||"Unknown"]
- Active equipment: [M.selected||"None"]"} - if(istype(M, /obj/mecha/working/ripley)) - var/obj/mecha/working/ripley/RM = M - answer += "Used cargo space: [RM.cargo.len/RM.cargo_capacity*100]%
" - - return answer - - emp_act() - qdel(src) + var/datum/topic_input/filter = new /datum/topic_input(href,href_list) + if(href_list["send_message"]) + var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("send_message") + var/message = sanitize(input(usr,"Input message","Transmit message") as text) + var/obj/mecha/M = MT.in_mecha() + if(message && M) + M.occupant_message(message) return - - ex_act() - qdel(src) - return - - proc/in_mecha() - if(istype(src.loc, /obj/mecha)) - return src.loc - return 0 - - proc/shock() - var/obj/mecha/M = in_mecha() - if(M) - M.emp_act(2) - qdel(src) - - proc/get_mecha_log() - if(!src.in_mecha()) - return 0 - var/obj/mecha/M = src.loc - return M.get_log_html() + if(href_list["shock"]) + var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("shock") + MT.shock() + if(href_list["get_log"]) + var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("get_log") + stored_data = MT.get_mecha_log() + screen = 1 + if(href_list["return"]) + screen = 0 + src.updateUsrDialog() + return + -/obj/item/weapon/storage/box/mechabeacons - name = "Exosuit Tracking Beacons" - New() - ..() - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) diff --git a/code/global.dm b/code/global.dm index b916ed959a3..eeec488d973 100644 --- a/code/global.dm +++ b/code/global.dm @@ -164,3 +164,7 @@ var/list/station_departments = list("Command", "Medical", "Engineering", "Scienc var/global/const/TICKS_IN_DAY = 864000 var/global/const/TICKS_IN_HOUR = 36000 var/global/const/TICKS_IN_SECOND = 10 + + +//List of exosuit tracking beacons, to save performance +var/global/list/exo_beacons = list() \ No newline at end of file diff --git a/code/modules/modular_computers/computers/machinery/console_presets.dm b/code/modules/modular_computers/computers/machinery/console_presets.dm index 9dafd2405c9..615e5a58099 100644 --- a/code/modules/modular_computers/computers/machinery/console_presets.dm +++ b/code/modules/modular_computers/computers/machinery/console_presets.dm @@ -44,7 +44,7 @@ // ===== RESEARCH CONSOLE ===== /obj/machinery/modular_computer/console/preset/research - console_department = "Medbay" + console_department = "Research" desc = "A stationary computer. This one comes preloaded with research programs." /obj/machinery/modular_computer/console/preset/research/install_programs() diff --git a/code/modules/modular_computers/file_system/programs/_research.dm b/code/modules/modular_computers/file_system/programs/_research.dm new file mode 100644 index 00000000000..bd2e031aa00 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/_research.dm @@ -0,0 +1,9 @@ +/datum/computer_file/program/exosuit_monitor + filename = "exosuitmonitor" + filedesc = "Exosuit monitoring and control" + nanomodule_path = /datum/nano_module/exosuit_control + program_icon_state = "mecha" + extended_desc = "This program allows remote monitoring and administration of exosuits with tracking beacons installed." + required_access = access_robotics + requires_ntnet = 1 + size = 8 \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/ntdownloader.dm b/code/modules/modular_computers/file_system/programs/ntdownloader.dm index 1703f55ca78..76a9cd01ede 100644 --- a/code/modules/modular_computers/file_system/programs/ntdownloader.dm +++ b/code/modules/modular_computers/file_system/programs/ntdownloader.dm @@ -16,8 +16,9 @@ var/download_completion = 0 //GQ of downloaded data. var/download_netspeed = 0 var/downloaderror = "" + var/downstream_variance = 0.1 -/datum/computer_file/program/ntnetdownload/proc/begin_file_download(var/filename) +/datum/computer_file/program/ntnetdownload/proc/begin_file_download(var/filename, var/user = null) if(downloaded_file) return 0 @@ -46,6 +47,9 @@ hacked_download = 0 downloaded_file = PRG.clone() + if (user) + spawn() + ui_interact(user) /datum/computer_file/program/ntnetdownload/proc/abort_file_download() if(!downloaded_file) @@ -71,6 +75,7 @@ return if(download_completion >= downloaded_file.size) complete_file_download() + return // Download speed according to connectivity state. NTNet server is assumed to be on unlimited speed so we're limited by our local connectivity download_netspeed = 0 // Speed defines are found in misc.dm @@ -81,14 +86,20 @@ download_netspeed = NTNETSPEED_HIGHSIGNAL if(3) download_netspeed = NTNETSPEED_ETHERNET - download_completion += download_netspeed + + var/delta = ((rand()-0.5)*2)*downstream_variance*download_netspeed + //Download speed varies +/- 10% each proc. Adds a more realistic feel + + download_netspeed += delta + download_netspeed = round(download_netspeed, 0.002)//3 decimal places + download_completion = min(download_completion + download_netspeed, downloaded_file.size) /datum/computer_file/program/ntnetdownload/Topic(href, href_list) if(..()) return 1 if(href_list["PRG_downloadfile"]) if(!downloaded_file) - begin_file_download(href_list["PRG_downloadfile"]) + begin_file_download(href_list["PRG_downloadfile"], usr) return 1 if(href_list["PRG_reseterror"]) if(downloaderror) @@ -125,8 +136,8 @@ data["downloadname"] = prog.downloaded_file.filename data["downloaddesc"] = prog.downloaded_file.filedesc data["downloadsize"] = prog.downloaded_file.size - data["downloadspeed"] = prog.download_netspeed - data["downloadcompletion"] = round(prog.download_completion, 0.1) + data["downloadspeed"] = (prog.download_netspeed * 0.5)//It updates every two seconds + data["downloadcompletion"] = round(prog.download_completion, 0.01) else // No download running, pick file. data["disk_size"] = my_computer.hard_drive.max_capacity data["disk_used"] = my_computer.hard_drive.used_capacity diff --git a/code/modules/nano/modules/exosuit_control.dm b/code/modules/nano/modules/exosuit_control.dm new file mode 100644 index 00000000000..96ed3f38bc7 --- /dev/null +++ b/code/modules/nano/modules/exosuit_control.dm @@ -0,0 +1,62 @@ +/datum/nano_module/exosuit_control + name = "Exosuit Monitoring and Control" + var/stored_data + var/screen = 0 + +// If PC is not null header template is loaded. Use PC.get_header_data() to get relevant nanoui data from it. All data entries begin with "PC_...." +// In future it may be expanded to other modular computer devices. +/datum/nano_module/exosuit_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + var/list/data = list() + if(program) + data = program.get_header_data() + + data["screen"] = screen + switch (screen) + if (0) + var/list/beacons = list() + for(var/obj/item/mecha_parts/mecha_tracking/TR in exo_beacons) + beacons.len++ + beacons[beacons.len] = TR.get_mecha_info_nano() + + data["beacons"] = beacons + if (1) + data["log"] = stored_data + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "exosuit_control.tmpl", "Exosuit Control and Monitoring", 800, 500, state = state) + if(program) // This is necessary to ensure the status bar remains updated along with rest of the UI. + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + + +/datum/nano_module/exosuit_control/Topic(href, href_list) + if(..()) + return + var/datum/topic_input/filter = new /datum/topic_input(href,href_list) + if(href_list["send_message"]) + var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("send_message") + var/message = sanitize(input(usr,"Input message","Transmit message") as text) + var/obj/mecha/M = MT.in_mecha() + if(message && M) + M.occupant_message(message) + return + if(href_list["shock"]) + var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("shock") + + var/response = alert(usr,"Are you certain you wish to terminate this exosuit? Executing this procedure will render it inoperable, and should only be used in extreme circumstances. Improper use will result in your being held liable for damage to Nanotrasen property","Confirm shutdown","Destroy","Cancel") + if (response == "Destroy") + MT.shock(usr) + if(href_list["get_log"]) + var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("get_log") + stored_data = MT.get_mecha_log() + screen = 1 + if(href_list["return"]) + screen = 0 + + if (usr) + spawn() + program.ui_interact(usr) + return \ No newline at end of file diff --git a/code/modules/research/mechfab_designs.dm b/code/modules/research/mechfab_designs.dm index 1327cd68029..16ceb35bfc9 100644 --- a/code/modules/research/mechfab_designs.dm +++ b/code/modules/research/mechfab_designs.dm @@ -387,12 +387,20 @@ /datum/design/item/mecha_tracking name = "Exosuit tracking beacon" + id = "exotrack" build_type = MECHFAB time = 5 materials = list(DEFAULT_WALL_MATERIAL = 500) build_path = /obj/item/mecha_parts/mecha_tracking category = "Misc" +/datum/design/item/mecha_tracking/control + name = "Exosuit control beacon" + id = "exocontrol" + time = 30 + materials = list(DEFAULT_WALL_MATERIAL = 3000) + build_path = /obj/item/mecha_parts/mecha_tracking/control + /datum/design/item/mecha build_type = MECHFAB category = "Exosuit Equipment" diff --git a/html/changelogs/Nanako-Exotrack.yml b/html/changelogs/Nanako-Exotrack.yml new file mode 100644 index 00000000000..85cb4b1335f --- /dev/null +++ b/html/changelogs/Nanako-Exotrack.yml @@ -0,0 +1,39 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Nanako + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - tweak: "Reworked exosuit tracking beacons into two types, one with and one without a killswitch." + - rscadd: "Tracking beacons can now be removed. Opening the panel is necessary to install or remove them." + - tweak: "EMP effects against exosuits are less directly damaging but cause more side effects and malfunctions." + - soundadd: "Added some audio to a couple of maintenance operations on exosuits." diff --git a/maps/exodus-1.dmm b/maps/exodus-1.dmm index 672e118c777..208e9bd6a66 100644 --- a/maps/exodus-1.dmm +++ b/maps/exodus-1.dmm @@ -3368,7 +3368,7 @@ "bmN" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/blast/shutters{dir = 2; id = "Skynet_launch"; name = "Mech Bay"},/turf/simulated/floor/tiled,/area/hallway/primary/starboard) "bmO" = (/obj/machinery/computer/rdconsole/robotics,/obj/machinery/alarm{pixel_y = 25},/turf/simulated/floor/tiled/white,/area/assembly/robotics) "bmP" = (/obj/machinery/r_n_d/circuit_imprinter,/obj/item/weapon/reagent_containers/glass/beaker/sulphuric,/turf/simulated/floor/tiled/white,/area/assembly/robotics) -"bmQ" = (/obj/item/weapon/book/manual/robotics_cyborgs{pixel_x = 2; pixel_y = 5},/obj/item/weapon/storage/belt/utility,/obj/machinery/requests_console{department = "Robotics"; departmentType = 2; name = "Robotics RC"; pixel_y = 30},/obj/machinery/light{dir = 1},/obj/item/weapon/storage/belt/utility,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/structure/table/standard{name = "plastic table frame"},/turf/simulated/floor/tiled/white,/area/assembly/robotics) +"bmQ" = (/obj/machinery/requests_console{department = "Robotics"; departmentType = 2; name = "Robotics RC"; pixel_y = 30},/obj/machinery/light{dir = 1},/obj/machinery/modular_computer/console/preset/research,/turf/simulated/floor/tiled/white,/area/assembly/robotics) "bmR" = (/turf/simulated/wall/r_wall,/area/maintenance/substation/command) "bmS" = (/obj/machinery/autolathe,/turf/simulated/floor/tiled/white,/area/rnd/lab) "bmT" = (/obj/structure/table/standard,/obj/item/weapon/storage/belt/utility,/obj/item/clothing/gloves/latex,/obj/item/weapon/computer_hardware/hard_drive/portable,/turf/simulated/floor/tiled/white,/area/rnd/lab) @@ -3549,7 +3549,7 @@ "bqm" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled/white,/area/assembly/robotics) "bqn" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "hazard door east"},/obj/machinery/door/airlock/glass_research{name = "Robotics Lab"; req_access = list(29)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled/white,/area/assembly/robotics) "bqo" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled/white,/area/assembly/robotics) -"bqp" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/toolbox/electrical{pixel_x = 1; pixel_y = 6},/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/obj/item/weapon/storage/toolbox/mechanical,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/turf/simulated/floor/tiled/white,/area/assembly/robotics) +"bqp" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/toolbox/electrical{pixel_x = 1; pixel_y = 6},/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/obj/item/weapon/storage/toolbox/mechanical,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/item/weapon/storage/belt/utility,/obj/item/weapon/storage/belt/utility,/turf/simulated/floor/tiled/white,/area/assembly/robotics) "bqq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/tiled/white,/area/assembly/robotics) "bqr" = (/obj/structure/closet/emcloset,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/obj/effect/floor_decal/industrial/warning{dir = 9},/turf/simulated/floor/tiled/white,/area/rnd/research) "bqs" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/machinery/camera/network/research{c_tag = "Research Division Access"},/obj/effect/floor_decal/industrial/warning{dir = 5},/turf/simulated/floor/tiled/white,/area/rnd/research) @@ -3746,7 +3746,7 @@ "bub" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/carpet,/area/crew_quarters/captain) "buc" = (/obj/machinery/light_switch{pixel_y = 28},/turf/simulated/floor/carpet,/area/crew_quarters/captain) "bud" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor/tiled,/area/assembly/robotics) -"bue" = (/obj/structure/table/standard,/obj/machinery/cell_charger,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29},/turf/simulated/floor/tiled/white,/area/assembly/robotics) +"bue" = (/obj/structure/table/standard,/obj/machinery/cell_charger,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29},/obj/item/weapon/reagent_containers/glass/beaker/large,/turf/simulated/floor/tiled/white,/area/assembly/robotics) "buf" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/visible/supply,/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/turf/simulated/floor/plating,/area/crew_quarters/captain) "bug" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/white,/area/assembly/robotics) "buh" = (/obj/structure/closet/firecloset,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 10},/turf/simulated/floor/tiled/white,/area/rnd/research) @@ -3906,7 +3906,7 @@ "bxf" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled,/area/assembly/chargebay) "bxg" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/floor_decal/industrial/warning{dir = 8},/turf/simulated/floor/tiled,/area/assembly/chargebay) "bxh" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/hallway/primary/central_three) -"bxi" = (/obj/structure/table/standard,/obj/item/device/mmi,/obj/item/device/mmi,/obj/item/device/mmi,/turf/simulated/floor/tiled,/area/assembly/robotics) +"bxi" = (/obj/structure/table/standard,/obj/item/device/mmi,/obj/item/device/mmi,/obj/item/device/mmi,/obj/item/weapon/book/manual/robotics_cyborgs{pixel_x = 2; pixel_y = 5},/turf/simulated/floor/tiled,/area/assembly/robotics) "bxj" = (/obj/item/weapon/folder/white,/obj/structure/table/standard,/obj/item/weapon/disk/tech_disk{pixel_x = 0; pixel_y = 0},/obj/item/weapon/disk/tech_disk{pixel_x = 0; pixel_y = 0},/obj/item/weapon/disk/design_disk,/obj/item/weapon/disk/design_disk,/obj/item/weapon/reagent_containers/dropper{pixel_y = -4},/turf/simulated/floor/tiled/white,/area/rnd/lab) "bxk" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/structure/extinguisher_cabinet{pixel_x = -5; pixel_y = 28},/obj/effect/floor_decal/industrial/hatch/yellow,/turf/simulated/floor/tiled,/area/rnd/research) "bxl" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/effect/floor_decal/industrial/hatch/yellow,/turf/simulated/floor/tiled,/area/rnd/research) @@ -4478,9 +4478,9 @@ "bIf" = (/obj/machinery/portable_atmospherics/powered/scrubber/huge,/obj/structure/sign/nosmoking_2{pixel_x = 28},/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/rnd/storage) "bIg" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/effect/floor_decal/corner/white/full{tag = "icon-corner_white_full (EAST)"; icon_state = "corner_white_full"; dir = 4},/turf/simulated/floor/tiled,/area/rnd/research) "bIh" = (/obj/structure/table/rack,/obj/item/weapon/rig/hazmat/equipped,/obj/effect/floor_decal/corner/white/diagonal{tag = "icon-corner_white_diagonal (EAST)"; icon_state = "corner_white_diagonal"; dir = 4},/turf/simulated/floor/tiled,/area/crew_quarters/heads/hor) -"bIi" = (/obj/machinery/computer/mecha,/obj/structure/window/reinforced{dir = 4},/obj/effect/floor_decal/corner/white/diagonal{tag = "icon-corner_white_diagonal (EAST)"; icon_state = "corner_white_diagonal"; dir = 4},/turf/simulated/floor/tiled,/area/crew_quarters/heads/hor) +"bIi" = (/obj/structure/window/reinforced{dir = 4},/obj/effect/floor_decal/corner/white/diagonal{tag = "icon-corner_white_diagonal (EAST)"; icon_state = "corner_white_diagonal"; dir = 4},/obj/machinery/papershredder,/turf/simulated/floor/tiled,/area/crew_quarters/heads/hor) "bIj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/floor_decal/corner/white/diagonal{tag = "icon-corner_white_diagonal (EAST)"; icon_state = "corner_white_diagonal"; dir = 4},/turf/simulated/floor/tiled,/area/crew_quarters/heads/hor) -"bIk" = (/obj/effect/floor_decal/corner/white/diagonal{tag = "icon-corner_white_diagonal (EAST)"; icon_state = "corner_white_diagonal"; dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/papershredder,/turf/simulated/floor/tiled,/area/crew_quarters/heads/hor) +"bIk" = (/obj/effect/floor_decal/corner/white/diagonal{tag = "icon-corner_white_diagonal (EAST)"; icon_state = "corner_white_diagonal"; dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/tiled,/area/crew_quarters/heads/hor) "bIl" = (/obj/machinery/computer/area_atmos,/obj/effect/floor_decal/corner/white/diagonal{tag = "icon-corner_white_diagonal (EAST)"; icon_state = "corner_white_diagonal"; dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/tiled,/area/crew_quarters/heads/hor) "bIm" = (/obj/structure/table/standard,/obj/item/device/taperecorder{pixel_x = -3},/obj/item/device/paicard{pixel_x = 4},/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29},/obj/item/weapon/circuitboard/teleporter,/obj/item/weapon/circuitboard/aicore{pixel_x = -2; pixel_y = 4},/obj/item/device/gps,/obj/effect/floor_decal/corner/white/diagonal{tag = "icon-corner_white_diagonal (EAST)"; icon_state = "corner_white_diagonal"; dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/tiled,/area/crew_quarters/heads/hor) "bIn" = (/obj/structure/bed/chair/office/dark{dir = 8},/obj/effect/landmark/start{name = "Shaft Miner"},/turf/simulated/floor/tiled,/area/quartermaster/miningdock) diff --git a/nano/templates/exosuit_control.tmpl b/nano/templates/exosuit_control.tmpl new file mode 100644 index 00000000000..0d8d60b166a --- /dev/null +++ b/nano/templates/exosuit_control.tmpl @@ -0,0 +1,24 @@ +{{if data.screen == 0}} + {{for data.beacons}} +
+ Name: {{:value.name}}
+ Integrity: {{:value.health}}%
+ Cell charge: {{:value.charge}}
+ Airtank: {{:value.air}}kPa
+ Pilot: {{:value.pilot || "None"}}
+ Location: {{:value.location}}
+ Active equipment: {{:value.active}}
+ {{:helper.link("Send Message", null, {'send_message' : value.ref}, (value.pilot) ? null : 'disabled')}} + {{:helper.link("Get Log", null, {'get_log' : value.ref})}} + {{if value.control == 1}} + {{:helper.link("Terminate", null, {'shock' : value.ref})}} + {{/if}} + {{empty}} +
+ No active beacons detected + {{/for}} +{{else}} +

Log Contents



+ {{:helper.link("Return", null, {'return' : 0})}}
+ {{:data.log}} +{{/if}} \ No newline at end of file diff --git a/nano/templates/ntnet_downloader.tmpl b/nano/templates/ntnet_downloader.tmpl index 6e4fc8ad93b..96002312439 100644 --- a/nano/templates/ntnet_downloader.tmpl +++ b/nano/templates/ntnet_downloader.tmpl @@ -16,18 +16,18 @@ {{else data.downloadname}}

Download Running

Please wait... -
- File name: -
-
- {{:data.downloadname}} -
File description:
{{:data.downloaddesc}}
+
+ File name: +
+
+ {{:data.downloadname}} +
File size:
@@ -55,20 +55,22 @@ {{:helper.displayBar(data.disk_used, 0, data.disk_size, 'good')}} {{:data.disk_used}}GQ / {{:data.disk_size}}GQ +
{{for data.downloadable_programs}} +
+
+ Program name: +
+
+ {{:value.filedesc}} +
File name:
{{:value.filename}} ({{:value.size}} GQ)
-
- Program name: -
-
- {{:value.filedesc}} -
Description:
@@ -79,8 +81,8 @@ File controls:
- {{:helper.link("DOWNLOAD", null, {'PRG_downloadfile' : value.filename})}} -
+ {{:helper.link("Download", null, {'PRG_downloadfile' : value.filename})}} + {{/for}} {{if data.hackedavailable}} @@ -88,18 +90,18 @@ Please note that NanoTrasen does not recommend download of software from non-official servers. {{for data.hacked_programs}}
-
- File name: -
-
- {{:value.filename}} ({{:value.size}} GQ) -
Program name:
{{:value.filedesc}}
+
+ File name: +
+
+ {{:value.filename}} ({{:value.size}} GQ) +
Description:
@@ -110,11 +112,11 @@ File controls:
- {{:helper.link("DOWNLOAD", null, {'PRG_downloadfile' : value.filename})}} + {{:helper.link("Download", null, {'PRG_downloadfile' : value.filename})}}
{{/for}} {{/if}} {{/if}} -


NTOS v2.0.4b Copyright NanoTrasen 2557 - 2559 \ No newline at end of file +


NTOS v2.0.5 Copyright NanoTrasen 2557 - 2559 \ No newline at end of file