diff --git a/code/__DEFINES/dcs/signals/signals_mod.dm b/code/__DEFINES/dcs/signals/signals_mod.dm index 26a8f2b80c0..4050481fb99 100644 --- a/code/__DEFINES/dcs/signals/signals_mod.dm +++ b/code/__DEFINES/dcs/signals/signals_mod.dm @@ -1,5 +1,5 @@ //MODsuit signals -/// Called when a module is selected to be the active one from on_select() +/// Called when a module is selected to be the active one from on_select(obj/item/mod/module/module) #define COMSIG_MOD_MODULE_SELECTED "mod_module_selected" /// Called when a MOD activation is called from toggle_activate(mob/user) #define COMSIG_MOD_ACTIVATE "mod_activate" diff --git a/code/modules/mod/modules/modules_science.dm b/code/modules/mod/modules/modules_science.dm index c472a0cd37d..5ef7ac34857 100644 --- a/code/modules/mod/modules/modules_science.dm +++ b/code/modules/mod/modules/modules_science.dm @@ -55,111 +55,6 @@ return to_chat(mod.wearer, span_notice("Explosion detected! Epicenter: [devastation_range], Outer: [heavy_impact_range], Shock: [light_impact_range]")) -//Circuit Adapter - -/obj/item/mod/module/circuit - name = "MOD circuit adapter module" - desc = "A popular aftermarket module, seen in wide varieties with wide applications by those across the galaxy. \ - This is able to fit any sort of integrated circuit, hooking it into controls in the suit and displaying information \ - to the HUD. Useful for universal translation, or perhaps as a calculator." - module_type = MODULE_USABLE - complexity = 3 - idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.5 - incompatible_modules = list(/obj/item/mod/module/circuit) - cooldown_time = 0.5 SECONDS - var/obj/item/integrated_circuit/circuit - -/obj/item/mod/module/circuit/Initialize(mapload) - . = ..() - circuit = new() - AddComponent(/datum/component/shell, \ - list(new /obj/item/circuit_component/mod()), \ - capacity = SHELL_CAPACITY_LARGE, \ - shell_flags = SHELL_FLAG_CIRCUIT_UNREMOVABLE, \ - starting_circuit = circuit, \ - ) - -/obj/item/mod/module/circuit/on_install() - circuit.set_cell(mod.get_cell()) - -/obj/item/mod/module/circuit/on_uninstall() - circuit.set_cell(mod.get_cell()) - -/obj/item/mod/module/circuit/on_suit_activation() - circuit.set_on(TRUE) - -/obj/item/mod/module/circuit/on_suit_deactivation() - circuit.set_on(FALSE) - -/obj/item/mod/module/circuit/on_use() - . = ..() - if(!.) - return - circuit.interact(mod.wearer) - -/obj/item/circuit_component/mod - display_name = "MOD" - desc = "Used to send and receive signals from a MODsuit." - - var/obj/item/mod/module/attached_module - - var/datum/port/input/module_to_select - var/datum/port/input/toggle_suit - var/datum/port/input/select_module - - var/datum/port/output/wearer - var/datum/port/output/selected_module - -/obj/item/circuit_component/mod/populate_ports() - // Input Signals - module_to_select = add_input_port("Module to Select", PORT_TYPE_STRING) - toggle_suit = add_input_port("Toggle Suit", PORT_TYPE_SIGNAL) - select_module = add_input_port("Select Module", PORT_TYPE_SIGNAL) - // States - wearer = add_output_port("Wearer", PORT_TYPE_ATOM) - selected_module = add_output_port("Selected Module", PORT_TYPE_ATOM) - -/obj/item/circuit_component/mod/register_shell(atom/movable/shell) - if(istype(shell, /obj/item/mod/module)) - attached_module = shell - RegisterSignal(attached_module, COMSIG_MOVABLE_MOVED, .proc/on_move) - -/obj/item/circuit_component/mod/unregister_shell(atom/movable/shell) - UnregisterSignal(attached_module, COMSIG_MOVABLE_MOVED) - attached_module = null - -/obj/item/circuit_component/mod/input_received(datum/port/input/port) - var/obj/item/mod/module/module - for(var/obj/item/mod/module/potential_module as anything in attached_module.mod.modules) - if(potential_module.name == module_to_select.value) - module = potential_module - if(COMPONENT_TRIGGERED_BY(toggle_suit, port)) - INVOKE_ASYNC(attached_module.mod, /obj/item/mod/control.proc/toggle_activate, attached_module.mod.wearer) - if(module && COMPONENT_TRIGGERED_BY(select_module, port)) - INVOKE_ASYNC(module, /obj/item/mod/module.proc/on_select) - -/obj/item/circuit_component/mod/proc/on_move(atom/movable/source, atom/old_loc, dir, forced) - SIGNAL_HANDLER - if(istype(source.loc, /obj/item/mod/control)) - RegisterSignal(source.loc, COMSIG_MOD_MODULE_SELECTED, .proc/on_module_select) - RegisterSignal(source.loc, COMSIG_ITEM_EQUIPPED, .proc/equip_check) - equip_check() - else if(istype(old_loc, /obj/item/mod/control)) - UnregisterSignal(old_loc, list(COMSIG_MOD_MODULE_SELECTED, COMSIG_ITEM_EQUIPPED)) - selected_module.set_output(null) - wearer.set_output(null) - -/obj/item/circuit_component/mod/proc/on_module_select() - SIGNAL_HANDLER - selected_module.set_output(attached_module.mod.selected_module) - -/obj/item/circuit_component/mod/proc/equip_check() - SIGNAL_HANDLER - - if(!attached_module.mod?.wearer) - return - wearer.set_output(attached_module.mod.wearer) - ///Anti-Gravity - Makes the user weightless. /obj/item/mod/module/anomaly_locked/antigrav name = "MOD anti-gravity module" diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index 67cb72007c2..7988d2ce5b5 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -1328,13 +1328,6 @@ materials = list(/datum/material/diamond = 500, /datum/material/glass = 1000) build_path = /obj/item/mod/module/dna_lock -/datum/design/module/mod_circuit - name = "MOD Module: Circuit Adapter" - id = "mod_circuit" - materials = list(/datum/material/glass = 2000) - build_path = /obj/item/mod/module/circuit - department_type = MODULE_SCIENCE - /datum/design/module/mod_plasma_stabilizer name = "MOD Module: Plasma Stabilizer" id = "mod_plasma" diff --git a/code/modules/research/designs/wiremod_designs.dm b/code/modules/research/designs/wiremod_designs.dm index 673767bef72..4dc93953e8a 100644 --- a/code/modules/research/designs/wiremod_designs.dm +++ b/code/modules/research/designs/wiremod_designs.dm @@ -309,7 +309,7 @@ /datum/design/component/bci/bci_action name = "BCI Action Component" id = "comp_bci_action" - build_path = /obj/item/circuit_component/bci_action + build_path = /obj/item/circuit_component/equipment_action/bci /datum/design/component/bci/object_overlay name = "Object Overlay Component" @@ -341,6 +341,11 @@ id = "comp_filter_list" build_path = /obj/item/circuit_component/filter_list +/datum/design/component/mod_action + name = "MOD Action Component" + id = "comp_mod_action" + build_path = /obj/item/circuit_component/equipment_action/mod + /datum/design/component/id_getter name = "ID Getter Component" id = "comp_id_getter" @@ -505,3 +510,12 @@ build_path = /obj/item/assembly/wiremod build_type = PROTOLATHE | COMPONENT_PRINTER category = list("Circuitry", "Shells") + +/datum/design/mod_module_shell + name = "MOD Module Shell" + desc = "A module shell that allows a circuit to be inserted into, and interface with, a MODsuit." + id = "module_shell" + materials = list(/datum/material/glass = 2000) + build_path = /obj/item/mod/module/circuit + build_type = MECHFAB | COMPONENT_PRINTER + category = list("MOD Modules", "Shells") diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 82359fafee6..463bf1d122e 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -715,11 +715,12 @@ design_ids = list( "assembly_shell", "bot_shell", + "comp_mod_action", "controller_shell", "dispenser_shell", "door_shell", "gun_shell", - "mod_circuit", + "module_shell", "money_bot_shell", "scanner_gate_shell", "scanner_shell", diff --git a/code/modules/wiremod/components/abstract/equpiment_action.dm b/code/modules/wiremod/components/abstract/equpiment_action.dm new file mode 100644 index 00000000000..17f931ae5e3 --- /dev/null +++ b/code/modules/wiremod/components/abstract/equpiment_action.dm @@ -0,0 +1,65 @@ +/obj/item/circuit_component/equipment_action + display_name = "Abstract Equipment Action" + desc = "You shouldn't be seeing this." + + /// The icon of the button + var/datum/port/input/option/icon_options + + /// The name to use for the button + var/datum/port/input/button_name + + /// Called when the user presses the button + var/datum/port/output/signal + +/obj/item/circuit_component/equipment_action/Initialize(mapload, default_icon) + . = ..() + + if (!isnull(default_icon)) + icon_options.set_input(default_icon) + + button_name = add_input_port("Name", PORT_TYPE_STRING) + + signal = add_output_port("Signal", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/equipment_action/populate_options() + var/static/action_options = list( + "Blank", + + "One", + "Two", + "Three", + "Four", + "Five", + + "Blood", + "Bomb", + "Brain", + "Brain Damage", + "Cross", + "Electricity", + "Exclamation", + "Heart", + "Id", + "Info", + "Injection", + "Magnetism", + "Minus", + "Network", + "Plus", + "Power", + "Question", + "Radioactive", + "Reaction", + "Repair", + "Say", + "Scan", + "Shield", + "Skull", + "Sleep", + "Wireless", + ) + + icon_options = add_option_port("Icon", action_options) + +/obj/item/circuit_component/equipment_action/proc/update_action() + return diff --git a/code/modules/wiremod/shell/brain_computer_interface.dm b/code/modules/wiremod/shell/brain_computer_interface.dm index 91c745db74f..e0244f5b017 100644 --- a/code/modules/wiremod/shell/brain_computer_interface.dm +++ b/code/modules/wiremod/shell/brain_computer_interface.dm @@ -11,7 +11,7 @@ . = ..() var/obj/item/integrated_circuit/circuit = new(src) - circuit.add_component(new /obj/item/circuit_component/bci_action(null, "One")) + circuit.add_component(new /obj/item/circuit_component/equipment_action/bci(null, "One")) AddComponent(/datum/component/shell, list( new /obj/item/circuit_component/bci_core, @@ -34,96 +34,39 @@ else return ..() -/obj/item/circuit_component/bci_action +/obj/item/circuit_component/equipment_action/bci display_name = "BCI Action" desc = "Represents an action the user can take when implanted with the brain-computer interface." required_shells = list(/obj/item/organ/cyberimp/bci) - /// The icon of the button - var/datum/port/input/option/icon_options - - /// The name to use for the button - var/datum/port/input/button_name - - /// Called when the user presses the button - var/datum/port/output/signal - /// A reference to the action button itself var/datum/action/innate/bci_action/bci_action -/obj/item/circuit_component/bci_action/Initialize(mapload, default_icon) - . = ..() - - if (!isnull(default_icon)) - icon_options.set_input(default_icon) - - button_name = add_input_port("Name", PORT_TYPE_STRING) - - signal = add_output_port("Signal", PORT_TYPE_SIGNAL) - -/obj/item/circuit_component/bci_action/Destroy() +/obj/item/circuit_component/equipment_action/bci/Destroy() QDEL_NULL(bci_action) return ..() -/obj/item/circuit_component/bci_action/populate_options() - var/static/action_options = list( - "Blank", - - "One", - "Two", - "Three", - "Four", - "Five", - - "Blood", - "Bomb", - "Brain", - "Brain Damage", - "Cross", - "Electricity", - "Exclamation", - "Heart", - "Id", - "Info", - "Injection", - "Magnetism", - "Minus", - "Network", - "Plus", - "Power", - "Question", - "Radioactive", - "Reaction", - "Repair", - "Say", - "Scan", - "Shield", - "Skull", - "Sleep", - "Wireless", - ) - - icon_options = add_option_port("Icon", action_options) - -/obj/item/circuit_component/bci_action/register_shell(atom/movable/shell) +/obj/item/circuit_component/equipment_action/bci/register_shell(atom/movable/shell) + . = ..() var/obj/item/organ/cyberimp/bci/bci = shell + if(istype(bci)) + bci_action = new(src) + update_action() - bci_action = new(src) - update_action() + bci.actions += list(bci_action) - bci.actions += list(bci_action) - -/obj/item/circuit_component/bci_action/unregister_shell(atom/movable/shell) +/obj/item/circuit_component/equipment_action/bci/unregister_shell(atom/movable/shell) var/obj/item/organ/cyberimp/bci/bci = shell + if(istype(bci)) + bci.actions -= bci_action + QDEL_NULL(bci_action) + return ..() - bci.actions -= bci_action - QDEL_NULL(bci_action) - -/obj/item/circuit_component/bci_action/input_received(datum/port/input/port) +/obj/item/circuit_component/equipment_action/bci/input_received(datum/port/input/port) if (!isnull(bci_action)) update_action() -/obj/item/circuit_component/bci_action/proc/update_action() +/obj/item/circuit_component/equipment_action/bci/update_action() bci_action.name = button_name.value bci_action.button_icon_state = "bci_[replacetextEx(lowertext(icon_options.value), " ", "_")]" @@ -133,9 +76,9 @@ check_flags = AB_CHECK_CONSCIOUS button_icon_state = "bci_power" - var/obj/item/circuit_component/bci_action/circuit_component + var/obj/item/circuit_component/equipment_action/bci/circuit_component -/datum/action/innate/bci_action/New(obj/item/circuit_component/bci_action/circuit_component) +/datum/action/innate/bci_action/New(obj/item/circuit_component/equipment_action/bci/circuit_component) ..() src.circuit_component = circuit_component diff --git a/code/modules/wiremod/shell/module.dm b/code/modules/wiremod/shell/module.dm new file mode 100644 index 00000000000..b3a8275d607 --- /dev/null +++ b/code/modules/wiremod/shell/module.dm @@ -0,0 +1,156 @@ +/obj/item/mod/module/circuit + name = "MOD circuit adapter module" + desc = "A module shell that allows a circuit to be inserted into, and interface with, a MODsuit." + module_type = MODULE_USABLE + complexity = 3 + idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.5 + incompatible_modules = list(/obj/item/mod/module/circuit) + cooldown_time = 0.5 SECONDS + + /// A reference to the shell component, used to access the shell and its attached circuit + var/datum/component/shell/shell + +/obj/item/mod/module/circuit/Initialize(mapload) + . = ..() + shell = AddComponent(/datum/component/shell, \ + list(new /obj/item/circuit_component/mod_adapter_core()), \ + capacity = SHELL_CAPACITY_LARGE, \ + ) + +/obj/item/mod/module/circuit/proc/override_power_usage(datum/source, amount) + SIGNAL_HANDLER + if(drain_power(amount)) + . = COMPONENT_OVERRIDE_POWER_USAGE + +/obj/item/mod/module/circuit/on_install() + RegisterSignal(shell?.attached_circuit, COMSIG_CIRCUIT_PRE_POWER_USAGE, .proc/override_power_usage) + +/obj/item/mod/module/circuit/on_uninstall() + UnregisterSignal(shell?.attached_circuit, COMSIG_CIRCUIT_PRE_POWER_USAGE) + +/obj/item/mod/module/circuit/on_use() + . = ..() + if(!.) + return + if(!shell.attached_circuit) + return + var/list/action_components = shell.attached_circuit.get_all_contents_type(/obj/item/circuit_component/equipment_action/mod) + if(!action_components.len) + shell.attached_circuit.interact(mod.wearer) + return + var/list/repeat_name_counts = list("Access Circuit" = 1) + var/list/display_names = list() + var/list/radial_options = list() + for(var/obj/item/circuit_component/equipment_action/mod/action_component in action_components) + var/action_name = action_component.button_name.value + if(!repeat_name_counts[action_name]) + repeat_name_counts[action_name] = 0 + repeat_name_counts[action_name]++ + if(repeat_name_counts[action_name] > 1) + action_name += " ([repeat_name_counts[action_name]])" + display_names[action_name] = REF(action_component) + var/option_icon_state = "bci_[replacetextEx(lowertext(action_component.icon_options.value), " ", "_")]" + radial_options += list("[action_name]" = image('icons/mob/actions/actions_items.dmi', option_icon_state)) + radial_options += list("Access Circuit" = image(shell.attached_circuit)) + var/selected_option = show_radial_menu(mod.wearer, src, radial_options, custom_check = FALSE, require_near = TRUE) + if(!selected_option) + return + if(!mod || !mod.wearer || !mod.active || mod.activating) + return + if(selected_option == "Access Circuit") + shell.attached_circuit?.interact(mod.wearer) + else + var/component_reference = display_names[selected_option] + var/obj/item/circuit_component/equipment_action/mod/selected_component = locate(component_reference) in shell.attached_circuit.contents + if(!istype(selected_component)) + return + selected_component.signal.set_output(COMPONENT_SIGNAL) + + +/obj/item/circuit_component/mod_adapter_core + display_name = "MOD circuit adapter core" + desc = "Provides a reference to the MODsuit's occupant and allows the circuit to toggle the MODsuit." + + /// The MODsuit module this circuit is associated with + var/obj/item/mod/module/attached_module + + /// The name of the module to select + var/datum/port/input/module_to_select + + /// The signal to toggle the suit + var/datum/port/input/toggle_suit + + /// The signal to select a module + var/datum/port/input/select_module + + /// A reference to the wearer of the MODsuit + var/datum/port/output/wearer + + /// The name of the last selected module + var/datum/port/output/selected_module + + /// The signal that is triggered when a module is selected + var/datum/port/output/on_module_selected + +/obj/item/circuit_component/mod_adapter_core/populate_ports() + // Input Signals + module_to_select = add_input_port("Module to Select", PORT_TYPE_STRING) + toggle_suit = add_input_port("Toggle Suit", PORT_TYPE_SIGNAL) + select_module = add_input_port("Select Module", PORT_TYPE_SIGNAL) + // States + wearer = add_output_port("Wearer", PORT_TYPE_ATOM) + selected_module = add_output_port("Selected Module", PORT_TYPE_STRING) + // Output Signals + on_module_selected = add_output_port("On Module Selected", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/mod_adapter_core/register_shell(atom/movable/shell) + . = ..() + if(istype(shell, /obj/item/mod/module)) + attached_module = shell + RegisterSignal(attached_module, COMSIG_MOVABLE_MOVED, .proc/on_move) + +/obj/item/circuit_component/mod_adapter_core/unregister_shell(atom/movable/shell) + UnregisterSignal(attached_module, COMSIG_MOVABLE_MOVED) + attached_module = null + return ..() + +/obj/item/circuit_component/mod_adapter_core/input_received(datum/port/input/port) + if(!attached_module?.mod) + return + var/obj/item/mod/module/module + for(var/obj/item/mod/module/potential_module as anything in attached_module.mod.modules) + if(potential_module.name == module_to_select.value) + module = potential_module + if(COMPONENT_TRIGGERED_BY(toggle_suit, port)) + INVOKE_ASYNC(attached_module.mod, /obj/item/mod/control.proc/toggle_activate, attached_module.mod.wearer) + if(attached_module.mod.active && module && COMPONENT_TRIGGERED_BY(select_module, port)) + INVOKE_ASYNC(module, /obj/item/mod/module.proc/on_select) + +/obj/item/circuit_component/mod_adapter_core/proc/on_move(atom/movable/source, atom/old_loc, dir, forced) + SIGNAL_HANDLER + if(istype(source.loc, /obj/item/mod/control)) + RegisterSignal(source.loc, COMSIG_MOD_MODULE_SELECTED, .proc/on_module_select) + RegisterSignal(source.loc, COMSIG_ITEM_EQUIPPED, .proc/equip_check) + equip_check() + else if(istype(old_loc, /obj/item/mod/control)) + UnregisterSignal(old_loc, list(COMSIG_MOD_MODULE_SELECTED, COMSIG_ITEM_EQUIPPED)) + selected_module.set_output(null) + wearer.set_output(null) + +/obj/item/circuit_component/mod_adapter_core/proc/on_module_select(datum/source, obj/item/mod/module/module) + SIGNAL_HANDLER + selected_module.set_output(module.name) + on_module_selected.set_output(COMPONENT_SIGNAL) + + +/obj/item/circuit_component/mod_adapter_core/proc/equip_check() + SIGNAL_HANDLER + + if(!attached_module.mod?.wearer) + return + wearer.set_output(attached_module.mod.wearer) + +/obj/item/circuit_component/equipment_action/mod + display_name = "MOD action" + desc = "Represents an action the user can take when wearing the MODsuit." + required_shells = list(/obj/item/mod/module/circuit) diff --git a/tgstation.dme b/tgstation.dme index de3ec01751d..290929ec2ec 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4081,6 +4081,7 @@ #include "code\modules\vending\youtool.dm" #include "code\modules\wiremod\components\abstract\binary_decimal.dm" #include "code\modules\wiremod\components\abstract\compare.dm" +#include "code\modules\wiremod\components\abstract\equpiment_action.dm" #include "code\modules\wiremod\components\abstract\module.dm" #include "code\modules\wiremod\components\abstract\variable.dm" #include "code\modules\wiremod\components\action\light.dm" @@ -4189,6 +4190,7 @@ #include "code\modules\wiremod\shell\dispenser.dm" #include "code\modules\wiremod\shell\drone.dm" #include "code\modules\wiremod\shell\gun.dm" +#include "code\modules\wiremod\shell\module.dm" #include "code\modules\wiremod\shell\moneybot.dm" #include "code\modules\wiremod\shell\scanner.dm" #include "code\modules\wiremod\shell\scanner_gate.dm"