mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-18 11:36:24 +01:00
Fixes bugs with admin circuits, expands upon some admin circuit components and fixes duplicator runtiming when a port doesn't exist. (#61948)
Co-authored-by: Watermelon914 <3052169-Watermelon914@users.noreply.gitlab.com>
This commit is contained in:
@@ -64,6 +64,9 @@
|
||||
return
|
||||
|
||||
var/atom/target_atom = target.value
|
||||
if(!isatom(target_atom))
|
||||
return
|
||||
|
||||
var/target_for_animation = target_atom
|
||||
if(atom_or_filter.value == COMP_ANIMATE_FILTER)
|
||||
target_for_animation = target_atom.get_filter(filter_target.value)
|
||||
@@ -71,6 +74,10 @@
|
||||
if(!target_for_animation)
|
||||
return
|
||||
|
||||
if(!isatom(target_atom))
|
||||
return
|
||||
target_atom.datum_flags |= DF_VAR_EDITED
|
||||
|
||||
var/extra_flags = NONE
|
||||
if(parallel.value)
|
||||
extra_flags |= ANIMATION_PARALLEL
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
desc = "A component that gets a variable on an object."
|
||||
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL|CIRCUIT_FLAG_ADMIN
|
||||
|
||||
/// Whether to grab a global variable or a variable from this entity.
|
||||
var/datum/port/input/option/getvar_options
|
||||
|
||||
/// Entity to get variable of
|
||||
var/datum/port/input/entity
|
||||
|
||||
@@ -21,21 +24,30 @@
|
||||
var/datum/port/output/output_value
|
||||
|
||||
/obj/item/circuit_component/get_variable/populate_options()
|
||||
getvar_options = add_option_port("Variable Options", list("Object", "Global"))
|
||||
expected_output_type = add_option_port("Expected Output Type", GLOB.wiremod_fundamental_types)
|
||||
|
||||
/obj/item/circuit_component/get_variable/populate_ports()
|
||||
entity = add_input_port("Target", PORT_TYPE_DATUM)
|
||||
variable_name = add_input_port("Variable Name", PORT_TYPE_STRING)
|
||||
|
||||
output_value = add_output_port("Output Value", PORT_TYPE_ANY)
|
||||
variable_name = add_input_port("Variable Name", PORT_TYPE_STRING, order = 2)
|
||||
output_value = add_output_port("Output Value", PORT_TYPE_ANY, order = 2)
|
||||
|
||||
/obj/item/circuit_component/get_variable/pre_input_received(datum/port/input/port)
|
||||
if(port == getvar_options)
|
||||
remove_input_port(entity)
|
||||
entity = null
|
||||
if(getvar_options.value == "Object")
|
||||
entity = add_input_port("Target", PORT_TYPE_DATUM)
|
||||
|
||||
if(port == expected_output_type)
|
||||
if(output_value.datatype != expected_output_type.value)
|
||||
output_value.set_datatype(expected_output_type.value)
|
||||
|
||||
/obj/item/circuit_component/get_variable/input_received(datum/port/input/port)
|
||||
var/atom/object = entity.value
|
||||
var/atom/object = entity?.value
|
||||
if(getvar_options.value == "Global")
|
||||
object = GLOB
|
||||
|
||||
var/var_name = variable_name.value
|
||||
if(!var_name || !object)
|
||||
output_value.set_output(null)
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
/// Returns the output from the proccall
|
||||
var/datum/port/output/on_loaded
|
||||
|
||||
var/atom/movable/loaded_shell
|
||||
|
||||
/obj/item/circuit_component/save_shell/populate_ports()
|
||||
on_loaded = add_output_port("On Loaded", PORT_TYPE_SIGNAL)
|
||||
|
||||
@@ -25,6 +27,7 @@
|
||||
|
||||
/obj/item/circuit_component/save_shell/proc/on_post_load(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
loaded_shell.AddComponent(/datum/component/shell, starting_circuit = parent)
|
||||
on_loaded.set_output(COMPONENT_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/save_shell/proc/on_pre_save_to_json(datum/source, list/general_data)
|
||||
@@ -41,8 +44,6 @@
|
||||
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
|
||||
@@ -52,14 +53,16 @@
|
||||
return
|
||||
|
||||
var/shell_type = text2path(component_data["shell_type"])
|
||||
if(!shell_type)
|
||||
if(!shell_type || !ispath(shell_type, /atom))
|
||||
return ..()
|
||||
|
||||
var/atom/movable/shell = new shell_type(drop_location())
|
||||
loaded_shell = new shell_type(drop_location())
|
||||
if(!loaded_shell)
|
||||
return
|
||||
loaded_shell.datum_flags |= DF_VAR_EDITED
|
||||
|
||||
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)
|
||||
loaded_shell.vv_edit_var(variable, variable_data)
|
||||
return ..()
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
/obj/item/circuit_component/signal_handler
|
||||
display_name = "Signal Handler"
|
||||
desc = "A component that listens for signals on an object. Registering a new object will automatically unregister the old."
|
||||
desc = "A component that listens for signals on an object."
|
||||
circuit_flags = CIRCUIT_FLAG_ADMIN|CIRCUIT_FLAG_INSTANT
|
||||
|
||||
/// Whether it is a global or object signal
|
||||
@@ -17,14 +17,19 @@
|
||||
/// The list of signal IDs that can be selected as an option.
|
||||
var/datum/port/input/option/signal_id
|
||||
|
||||
/// Whether this executes instantly or not. If set to 0, this will not execute instantly.
|
||||
var/datum/port/input/instant
|
||||
|
||||
var/list/signal_map
|
||||
|
||||
/// Entity to register the signal on
|
||||
var/datum/port/input/target
|
||||
/// Registers the signal
|
||||
var/datum/port/input/register
|
||||
/// Unregisters the signal from the current registered entity.
|
||||
/// Unregisters the signal on the target.
|
||||
var/datum/port/input/unregister
|
||||
/// Unregisters the signal from everyone.
|
||||
var/datum/port/input/unregister_all
|
||||
|
||||
/// The custom signal ports from the current signal type. Used for saving and loading.
|
||||
var/list/signal_ports
|
||||
@@ -38,8 +43,8 @@
|
||||
/// The event has been triggered
|
||||
var/datum/port/output/event_triggered
|
||||
|
||||
/// The current entity that has the signal registered on it
|
||||
var/datum/weakref/current_registered_entity
|
||||
/// The current entities that have the signal registered on it
|
||||
var/list/datum/weakref/registered_entities = list()
|
||||
/// The current registered signal
|
||||
var/registered_signal
|
||||
|
||||
@@ -57,8 +62,10 @@
|
||||
signal_map = GLOB.integrated_circuit_signal_ids
|
||||
|
||||
/obj/item/circuit_component/signal_handler/populate_ports()
|
||||
instant = add_input_port("Instant", PORT_TYPE_NUMBER, order = 0.5, trigger = null, default = 1)
|
||||
register = add_input_port("Register", PORT_TYPE_SIGNAL, order = 2, trigger = .proc/register_signals)
|
||||
unregister = add_input_port("Unregister Current", PORT_TYPE_SIGNAL, order = 2, trigger = .proc/unregister_signals)
|
||||
unregister = add_input_port("Unregister", PORT_TYPE_SIGNAL, order = 2, trigger = .proc/unregister_signals)
|
||||
unregister_all = add_input_port("Unregister All", PORT_TYPE_SIGNAL, order = 2, trigger = .proc/unregister_signals_all)
|
||||
|
||||
add_source_entity()
|
||||
event_triggered = add_output_port("Triggered", PORT_TYPE_INSTANT_SIGNAL, order = 2)
|
||||
@@ -86,19 +93,13 @@
|
||||
|
||||
|
||||
/obj/item/circuit_component/signal_handler/pre_input_received(datum/port/input/port)
|
||||
if(signal_id == port)
|
||||
if(signal_id.value != registered_signal)
|
||||
custom_signal = FALSE
|
||||
if(current_registered_entity)
|
||||
unregister_signals(port)
|
||||
|
||||
var/last_registered_signal = registered_signal
|
||||
unregister_signals_all(port)
|
||||
registered_signal = signal_id.value
|
||||
|
||||
if(registered_signal != last_registered_signal)
|
||||
var/list/data = signal_map[registered_signal]
|
||||
if(data)
|
||||
load_new_ports(data)
|
||||
unregister_signals(port)
|
||||
var/list/data = signal_map[registered_signal]
|
||||
if(data)
|
||||
load_new_ports(data)
|
||||
|
||||
if(signal_handler_options == port)
|
||||
set_signal_options(port)
|
||||
@@ -112,6 +113,8 @@
|
||||
signal_map = GLOB.integrated_circuit_global_signal_ids
|
||||
remove_output_port(entity)
|
||||
remove_input_port(target)
|
||||
target = null
|
||||
entity = null
|
||||
if(COMP_SIGNAL_HANDLER_OBJECT)
|
||||
signal_id.possible_options = GLOB.integrated_circuit_signal_ids
|
||||
signal_map = GLOB.integrated_circuit_signal_ids
|
||||
@@ -119,20 +122,18 @@
|
||||
|
||||
if(!custom_signal)
|
||||
signal_id.set_value(null, TRUE)
|
||||
unregister_signals()
|
||||
unregister_signals_all(port)
|
||||
|
||||
/obj/item/circuit_component/signal_handler/proc/register_signals(datum/port/input/port)
|
||||
CIRCUIT_TRIGGER
|
||||
if(current_registered_entity)
|
||||
unregister_signals(port)
|
||||
|
||||
var/datum/target_datum = target.value
|
||||
var/datum/target_datum = target?.value
|
||||
if(signal_handler_options.value == COMP_SIGNAL_HANDLER_GLOBAL)
|
||||
target_datum = SSdcs
|
||||
|
||||
if(target_datum)
|
||||
RegisterSignal(target_datum, registered_signal, .proc/handle_signal_received)
|
||||
current_registered_entity = WEAKREF(target_datum)
|
||||
// We override because an admin may try registering a signal on the same object/datum again, so this prevents any runtimes from occuring
|
||||
RegisterSignal(target_datum, registered_signal, .proc/handle_signal_received, override = TRUE)
|
||||
registered_entities |= WEAKREF(target_datum)
|
||||
|
||||
/obj/item/circuit_component/signal_handler/proc/load_new_ports(list/ports_to_load)
|
||||
for(var/datum/port/input/input_port as anything in input_signal_ports)
|
||||
@@ -145,26 +146,51 @@
|
||||
signal_ports = ports_to_load
|
||||
for(var/list/data in signal_ports)
|
||||
if(data["is_response"])
|
||||
var/datum/port/input/bitflag_input = add_input_port(data["name"], PORT_TYPE_RESPONSE_SIGNAL, order = 1, trigger = .proc/handle_bitflag_received)
|
||||
var/datum/port/input/bitflag_input = add_input_port(data["name"], PORT_TYPE_SIGNAL, order = 3, trigger = .proc/handle_bitflag_received)
|
||||
input_signal_ports[bitflag_input] = data["bitflag"]
|
||||
else
|
||||
output_signal_ports += add_output_port(data["name"], data["type"], order = 1)
|
||||
|
||||
|
||||
/obj/item/circuit_component/signal_handler/proc/unregister_signals_all(datum/port/input/port)
|
||||
CIRCUIT_TRIGGER
|
||||
for(var/datum/weakref/weakref_of_object as anything in registered_entities)
|
||||
var/datum/datum_to_unregister = weakref_of_object.resolve()
|
||||
if(!datum_to_unregister)
|
||||
continue
|
||||
UnregisterSignal(datum_to_unregister, registered_signal)
|
||||
registered_entities.Cut()
|
||||
|
||||
/obj/item/circuit_component/signal_handler/proc/unregister_signals(datum/port/input/port)
|
||||
CIRCUIT_TRIGGER
|
||||
|
||||
var/datum/registered_datum = current_registered_entity?.resolve()
|
||||
var/datum/registered_datum = target?.value
|
||||
if(signal_handler_options.value == COMP_SIGNAL_HANDLER_GLOBAL)
|
||||
registered_datum = SSdcs
|
||||
|
||||
if(!registered_datum)
|
||||
return
|
||||
|
||||
UnregisterSignal(registered_datum, registered_signal)
|
||||
current_registered_entity = null
|
||||
registered_entities -= WEAKREF(registered_datum)
|
||||
|
||||
/obj/item/circuit_component/signal_handler/proc/run_ports_on_args(list/arguments)
|
||||
var/first_arg = popleft(arguments)
|
||||
if(entity)
|
||||
entity.set_output(first_arg)
|
||||
|
||||
for(var/datum/port/output/port as anything in output_signal_ports)
|
||||
port.set_output(popleft(arguments))
|
||||
event_triggered.set_output(COMPONENT_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/signal_handler/proc/handle_signal_received(...)
|
||||
SIGNAL_HANDLER
|
||||
var/list/arguments = args.Copy()
|
||||
|
||||
if(!instant.value)
|
||||
run_ports_on_args(arguments)
|
||||
return
|
||||
|
||||
// usr is not supposed to be defined whilst these execute, which it can be for some signal IDs.
|
||||
// Especially if you try to proccall something - it'll fail because of this reason.
|
||||
// No other way to solve this problem without refactoring proccall code, but it's admin tooling so it's whatever.
|
||||
@@ -172,13 +198,7 @@
|
||||
usr = null
|
||||
|
||||
SScircuit_component.queue_instant_run()
|
||||
var/first_arg = popleft(arguments)
|
||||
if(entity)
|
||||
entity.set_output(first_arg)
|
||||
|
||||
for(var/datum/port/output/port as anything in output_signal_ports)
|
||||
port.set_output(popleft(arguments))
|
||||
event_triggered.set_output(COMPONENT_SIGNAL)
|
||||
run_ports_on_args(arguments)
|
||||
var/list/output = SScircuit_component.execute_instant_run()
|
||||
|
||||
usr = temp_usr
|
||||
|
||||
Reference in New Issue
Block a user