From 6497a97a89c8d2c7cb25220e7451f00b709b607a Mon Sep 17 00:00:00 2001 From: Watermelon914 <37270891+Watermelon914@users.noreply.github.com> Date: Thu, 16 Sep 2021 08:11:56 +0100 Subject: [PATCH] Admins can now save custom shells (#61307) Co-authored-by: Watermelon914 <3052169-Watermelon914@users.noreply.gitlab.com> --- code/__DEFINES/dcs/signals.dm | 8 ++- .../wiremod/components/admin/save_shell.dm | 65 +++++++++++++++++++ code/modules/wiremod/core/duplicator.dm | 4 ++ tgstation.dme | 1 + 4 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 code/modules/wiremod/components/admin/save_shell.dm diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index f698321da79..47e84787f59 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -1398,9 +1398,15 @@ /// Called when the integrated circuit's shell is set. #define COMSIG_CIRCUIT_SET_SHELL "circuit_set_shell" -/// Called when the integrated circuit's is locked. +/// Called when the integrated circuit is locked. #define COMSIG_CIRCUIT_SET_LOCKED "circuit_set_locked" +/// Called right before the integrated circuit data is converted to json. Allows modification to the data right before it is returned. +#define COMSIG_CIRCUIT_PRE_SAVE_TO_JSON "circuit_pre_save_to_json" + +/// Called when the integrated circuit is loaded. +#define COMSIG_CIRCUIT_POST_LOAD "circuit_post_load" + /// Sent to an atom when a [/obj/item/usb_cable] attempts to connect to something. (/obj/item/usb_cable/usb_cable, /mob/user) #define COMSIG_ATOM_USB_CABLE_TRY_ATTACH "usb_cable_try_attach" /// Attaches the USB cable to the atom. If the USB cables moves away, it will disconnect. diff --git a/code/modules/wiremod/components/admin/save_shell.dm b/code/modules/wiremod/components/admin/save_shell.dm new file mode 100644 index 00000000000..d2b7ff6fe8a --- /dev/null +++ b/code/modules/wiremod/components/admin/save_shell.dm @@ -0,0 +1,65 @@ +/** + * # Save Shell Component + * + * A component that saves and loads a shell for the integrated circuit. + */ +/obj/item/circuit_component/save_shell + display_name = "Save Shell" + desc = "A component that saves a shell." + circuit_flags = CIRCUIT_FLAG_ADMIN + + /// Returns the output from the proccall + var/datum/port/output/on_loaded + +/obj/item/circuit_component/save_shell/populate_ports() + on_loaded = add_output_port("On Loaded", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/save_shell/add_to(obj/item/integrated_circuit/added_to) + . = ..() + RegisterSignal(added_to, COMSIG_CIRCUIT_POST_LOAD, .proc/on_post_load) + RegisterSignal(added_to, COMSIG_CIRCUIT_PRE_SAVE_TO_JSON, .proc/on_pre_save_to_json) + +/obj/item/circuit_component/save_shell/removed_from(obj/item/integrated_circuit/removed_from) + UnregisterSignal(removed_from, list(COMSIG_CIRCUIT_POST_LOAD, COMSIG_CIRCUIT_PRE_SAVE_TO_JSON)) + return ..() + +/obj/item/circuit_component/save_shell/proc/on_post_load(datum/source) + SIGNAL_HANDLER + on_loaded.set_output(COMPONENT_SIGNAL) + +/obj/item/circuit_component/save_shell/proc/on_pre_save_to_json(datum/source, list/general_data) + SIGNAL_HANDLER + // We're custom saving the shell, disable any USB cable connections and default shell components. + general_data["external_objects"] = list() + +/obj/item/circuit_component/save_shell/save_data_to_list(list/component_data) + . = ..() + var/atom/movable/shell = parent.shell + component_data["shell_type"] = shell.type + var/list/shell_variables = list() + for(var/variable in shell.vars - GLOB.duplicate_forbidden_vars) + var/variable_data = shell.vars[variable] + if(!istext(variable_data) && !isnum(variable_data)) + continue + if(initial(shell.vars[variable]) == variable_data) + continue + shell_variables[variable] = variable_data + + component_data["shell_variables"] = shell_variables + +/obj/item/circuit_component/save_shell/load_data_from_list(list/component_data) + if(parent.shell) + return + + var/shell_type = text2path(component_data["shell_type"]) + if(!shell_type) + return ..() + + var/atom/movable/shell = new shell_type(drop_location()) + var/list/shell_variables = component_data["shell_variables"] + for(var/variable in shell_variables - GLOB.duplicate_forbidden_vars) + var/variable_data = shell_variables[variable] + shell.vv_edit_var(variable, variable_data) + var/datum/component/shell/shell_component = shell.AddComponent(/datum/component/shell) + shell_component.attach_circuit(parent) + return ..() diff --git a/code/modules/wiremod/core/duplicator.dm b/code/modules/wiremod/core/duplicator.dm index b28981472e5..9d68b353c7c 100644 --- a/code/modules/wiremod/core/duplicator.dm +++ b/code/modules/wiremod/core/duplicator.dm @@ -109,6 +109,8 @@ GLOBAL_LIST_INIT(circuit_dupe_whitelisted_types, list( port.connect(output_port) + SEND_SIGNAL(src, COMSIG_CIRCUIT_POST_LOAD) + #undef LOG_ERROR /// Converts a circuit into json. @@ -181,6 +183,8 @@ GLOBAL_LIST_INIT(circuit_dupe_whitelisted_types, list( variables += list(new_data) general_data["variables"] = variables + SEND_SIGNAL(src, COMSIG_CIRCUIT_PRE_SAVE_TO_JSON, general_data) + return json_encode(general_data) /obj/item/integrated_circuit/proc/load_component(type) diff --git a/tgstation.dme b/tgstation.dme index b9d5f70a93a..31ce8048b93 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3816,6 +3816,7 @@ #include "code\modules\wiremod\components\action\speech.dm" #include "code\modules\wiremod\components\admin\getvar.dm" #include "code\modules\wiremod\components\admin\proccall.dm" +#include "code\modules\wiremod\components\admin\save_shell.dm" #include "code\modules\wiremod\components\admin\sdql.dm" #include "code\modules\wiremod\components\admin\setvar.dm" #include "code\modules\wiremod\components\admin\spawn.dm"