mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-13 17:14:47 +01:00
Adds Animation and Filter Components for Admin Circuits (#61766)
Adds a selection of components for animating atoms and manipulating filters. Makes animating atoms and filters using circuits more intuitive. Also Watermelon planned to make these but was too busy with other circuit QOL stuff and asked me if I would be willing to do it.
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
#define COMP_ANIMATE_ATOM "Object"
|
||||
#define COMP_ANIMATE_FILTER "Filter"
|
||||
|
||||
/obj/item/circuit_component/begin_animation
|
||||
display_name = "Begin Animation"
|
||||
desc = "Begins an animation on the target. Create animation steps by chaining \"Animation Step\" components off of the \"Perform Animation\" port."
|
||||
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL|CIRCUIT_FLAG_INSTANT|CIRCUIT_FLAG_ADMIN
|
||||
|
||||
var/datum/port/input/target
|
||||
|
||||
var/datum/port/input/animation_loops
|
||||
|
||||
var/datum/port/output/animate_event
|
||||
|
||||
/obj/item/circuit_component/begin_animation/populate_ports()
|
||||
target = add_input_port("Target", PORT_TYPE_ATOM)
|
||||
animation_loops = add_input_port("Loops", PORT_TYPE_NUMBER)
|
||||
animate_event = add_output_port("Perform Animation", PORT_TYPE_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/begin_animation/input_received(datum/port/input/port, list/return_values)
|
||||
if(!target.value)
|
||||
return
|
||||
|
||||
SScircuit_component.queue_instant_run()
|
||||
animate_event.set_output(COMPONENT_SIGNAL)
|
||||
var/list/result = SScircuit_component.execute_instant_run()
|
||||
|
||||
if(!result)
|
||||
return
|
||||
|
||||
var/atom/target_atom = target.value
|
||||
var/last_step_used_filter = FALSE
|
||||
if(result["animation_steps"])
|
||||
animate(target_atom, pixel_x = pixel_x, time = 0, loop = animation_loops.value, flags = ANIMATION_PARALLEL) //Just to start the animation
|
||||
for(var/list/step in result["animation_steps"])
|
||||
if(step["filter"])
|
||||
var/filter = target_atom.get_filter(step["filter"])
|
||||
if(filter)
|
||||
last_step_used_filter = TRUE
|
||||
animate(filter, step["vars"], time = step["time"], easing = step["easing"], flags = step["flags"])
|
||||
var/list/filter_params = target_atom.filter_data[step["filter"]]
|
||||
for(var/param in step["vars"])
|
||||
if(filter_params.Find(param))
|
||||
filter_params[param] = step["vars"][param]
|
||||
else
|
||||
if(last_step_used_filter)
|
||||
last_step_used_filter = FALSE
|
||||
animate(target_atom, step["vars"], time = step["time"], easing = step["easing"], flags = step["flags"])
|
||||
else
|
||||
animate(time = step["time"], step["vars"], easing = step["easing"], flags = step["flags"])
|
||||
|
||||
/obj/item/circuit_component/animation_step
|
||||
display_name = "Animation Step"
|
||||
desc = "Perform a single animation step. The input of this component should be connected, directly or indirectly, to the \"Perform Animation\" port of a \"Begin Animation\" component."
|
||||
|
||||
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL|CIRCUIT_FLAG_ADMIN
|
||||
|
||||
var/datum/port/input/option/atom_or_filter
|
||||
|
||||
var/datum/port/input/animation_variables
|
||||
|
||||
var/datum/port/input/animation_filter
|
||||
|
||||
var/datum/port/input/animation_time
|
||||
var/datum/port/input/animation_easing
|
||||
var/datum/port/input/animation_flags
|
||||
|
||||
/obj/item/circuit_component/animation_step/populate_options()
|
||||
var/static/list/component_options = list(
|
||||
COMP_ANIMATE_ATOM,
|
||||
COMP_ANIMATE_FILTER,
|
||||
)
|
||||
|
||||
atom_or_filter = add_option_port("Target", component_options)
|
||||
|
||||
/obj/item/circuit_component/animation_step/populate_ports()
|
||||
animation_variables = add_input_port("Variables", PORT_TYPE_ASSOC_LIST, order = 1.66)
|
||||
animation_time = add_input_port("Time", PORT_TYPE_NUMBER, order = 1.66)
|
||||
animation_easing = add_input_port("Easing", PORT_TYPE_NUMBER, order = 1.66)
|
||||
animation_flags = add_input_port("Flags", PORT_TYPE_NUMBER, order = 1.66)
|
||||
|
||||
/obj/item/circuit_component/animation_step/pre_input_received(datum/port/input/port)
|
||||
if(port == atom_or_filter)
|
||||
if((atom_or_filter.value == COMP_ANIMATE_ATOM) && animation_filter)
|
||||
remove_input_port(animation_filter)
|
||||
animation_filter = null
|
||||
else if((atom_or_filter.value == COMP_ANIMATE_FILTER) && !animation_filter)
|
||||
animation_filter = add_input_port("Filter Name", PORT_TYPE_STRING, order = 1.33)
|
||||
|
||||
/obj/item/circuit_component/animation_step/input_received(datum/port/input/port, list/return_values)
|
||||
if(!return_values)
|
||||
return
|
||||
|
||||
if(!return_values["animation_steps"])
|
||||
return_values["animation_steps"] = list()
|
||||
|
||||
var/list/variables = animation_variables.value
|
||||
|
||||
var/list/step = list(
|
||||
"vars" = variables.Copy(),
|
||||
"time" = animation_time.value,
|
||||
"easing" = animation_easing.value,
|
||||
"flags" = animation_flags.value
|
||||
)
|
||||
|
||||
if(atom_or_filter.value == COMP_ANIMATE_FILTER)
|
||||
step["filter"] = animation_filter.value
|
||||
|
||||
return_values["animation_steps"] += list(step)
|
||||
|
||||
#undef COMP_ANIMATE_ATOM
|
||||
#undef COMP_ANIMATE_FILTER
|
||||
@@ -0,0 +1,313 @@
|
||||
GLOBAL_LIST_INIT(wiremod_filter_info, list(
|
||||
"alpha" = list(
|
||||
"x" = PORT_TYPE_NUMBER,
|
||||
"y" = PORT_TYPE_NUMBER,
|
||||
"icon" = PORT_TYPE_STRING,
|
||||
"render_source" = PORT_TYPE_STRING,
|
||||
"flags" = PORT_TYPE_NUMBER,
|
||||
),
|
||||
"angular_blur" = list(
|
||||
"x" = PORT_TYPE_NUMBER,
|
||||
"y" = PORT_TYPE_NUMBER,
|
||||
"size" = PORT_TYPE_NUMBER,
|
||||
),
|
||||
"color" = list(
|
||||
"color" = PORT_TYPE_LIST,
|
||||
"space" = PORT_TYPE_NUMBER,
|
||||
),
|
||||
"displace" = list(
|
||||
"x" = PORT_TYPE_NUMBER,
|
||||
"y" = PORT_TYPE_NUMBER,
|
||||
"size" = PORT_TYPE_NUMBER,
|
||||
"icon" = PORT_TYPE_STRING,
|
||||
"render_source" = PORT_TYPE_NUMBER,
|
||||
),
|
||||
"drop_shadow" = list(
|
||||
"x" = PORT_TYPE_NUMBER,
|
||||
"y" = PORT_TYPE_NUMBER,
|
||||
"size" = PORT_TYPE_NUMBER,
|
||||
"offset" = PORT_TYPE_NUMBER,
|
||||
"color" = PORT_TYPE_STRING,
|
||||
),
|
||||
"blur" = list(
|
||||
"size" = PORT_TYPE_NUMBER,
|
||||
),
|
||||
"layer" = list(
|
||||
"x" = PORT_TYPE_NUMBER,
|
||||
"y" = PORT_TYPE_NUMBER,
|
||||
"icon" = PORT_TYPE_STRING,
|
||||
"render_source" = PORT_TYPE_STRING,
|
||||
"flags" = PORT_TYPE_NUMBER,
|
||||
"color" = PORT_TYPE_STRING,
|
||||
"transform" = PORT_TYPE_LIST,
|
||||
"blend_mode" = PORT_TYPE_NUMBER,
|
||||
),
|
||||
"motion_blur" = list(
|
||||
"x" = PORT_TYPE_NUMBER,
|
||||
"y" = PORT_TYPE_NUMBER,
|
||||
),
|
||||
"outline" = list(
|
||||
"size" = PORT_TYPE_NUMBER,
|
||||
"color" = PORT_TYPE_STRING,
|
||||
"flags" = PORT_TYPE_NUMBER,
|
||||
),
|
||||
"radial_blur" = list(
|
||||
"x" = PORT_TYPE_NUMBER,
|
||||
"y" = PORT_TYPE_NUMBER,
|
||||
"size" = PORT_TYPE_NUMBER,
|
||||
),
|
||||
"rays" = list(
|
||||
"x" = PORT_TYPE_NUMBER,
|
||||
"y" = PORT_TYPE_NUMBER,
|
||||
"size" = PORT_TYPE_NUMBER,
|
||||
"color" = PORT_TYPE_STRING,
|
||||
"offset" = PORT_TYPE_NUMBER,
|
||||
"density" = PORT_TYPE_NUMBER,
|
||||
"threshold" = PORT_TYPE_NUMBER,
|
||||
"factor" = PORT_TYPE_NUMBER,
|
||||
"flags" = PORT_TYPE_NUMBER,
|
||||
),
|
||||
"ripple" = list(
|
||||
"x" = PORT_TYPE_NUMBER,
|
||||
"y" = PORT_TYPE_NUMBER,
|
||||
"size" = PORT_TYPE_NUMBER,
|
||||
"repeat" = PORT_TYPE_NUMBER,
|
||||
"radius" = PORT_TYPE_NUMBER,
|
||||
"falloff" = PORT_TYPE_NUMBER,
|
||||
"flags" = PORT_TYPE_NUMBER,
|
||||
),
|
||||
"wave" = list(
|
||||
"x" = PORT_TYPE_NUMBER,
|
||||
"y" = PORT_TYPE_NUMBER,
|
||||
"size" = PORT_TYPE_NUMBER,
|
||||
"offset" = PORT_TYPE_NUMBER,
|
||||
"flags" = PORT_TYPE_NUMBER,
|
||||
),
|
||||
))
|
||||
|
||||
GLOBAL_LIST_INIT(wiremod_flag_info, list(
|
||||
"Animation Easing" = list(
|
||||
"Easing Type" = list(
|
||||
"LINEAR_EASING" = LINEAR_EASING,
|
||||
"SINE_EASING" = SINE_EASING,
|
||||
"CIRCULAR_EASING" = CIRCULAR_EASING,
|
||||
"QUAD_EASING" = QUAD_EASING,
|
||||
"CUBIC_EASING" = CUBIC_EASING,
|
||||
"BOUNCE_EASING" = BOUNCE_EASING,
|
||||
"ELASTIC_EASING" = ELASTIC_EASING,
|
||||
"BACK_EASING" = BACK_EASING,
|
||||
"JUMP_EASING" = JUMP_EASING,
|
||||
),
|
||||
"EASE_IN" = EASE_IN,
|
||||
"EASE_OUT" = EASE_OUT,
|
||||
),
|
||||
"Animation Flags" = list(
|
||||
"ANIMATION_END_NOW" = ANIMATION_END_NOW,
|
||||
"ANIMATION_LINEAR_TRANSFORM" = ANIMATION_LINEAR_TRANSFORM,
|
||||
"ANIMATION_PARALLEL" = ANIMATION_PARALLEL,
|
||||
"ANIMATION_RELATIVE" = ANIMATION_RELATIVE,
|
||||
),
|
||||
"Alpha Filter Flags" = list(
|
||||
"MASK_INVERSE" = MASK_INVERSE,
|
||||
"MASK_SWAP" = MASK_SWAP,
|
||||
),
|
||||
"Color Space" = list("_" = list(
|
||||
"COLORSPACE_RGB" = COLORSPACE_RGB,
|
||||
"COLORSPACE_HSV" = COLORSPACE_HSV,
|
||||
"COLORSPACE_HSL" = COLORSPACE_HSL,
|
||||
"COLORSPACE_HCY" = COLORSPACE_HCY,
|
||||
)),
|
||||
"Layering Flags" = list("_" = list(
|
||||
"FILTER_OVERLAY" = FILTER_OVERLAY,
|
||||
"FILTER_UNDERLAY" = FILTER_UNDERLAY,
|
||||
)),
|
||||
"Layering Blend Mode" = list("_" = list(
|
||||
"BLEND_OVERLAY" = BLEND_OVERLAY,
|
||||
"BLEND_ADD" = BLEND_ADD,
|
||||
"BLEND_SUBTRACT" = BLEND_SUBTRACT,
|
||||
"BLEND_MULTIPLY" = BLEND_MULTIPLY,
|
||||
"BLEND_INSET_OVERLAY" = BLEND_INSET_OVERLAY,
|
||||
)),
|
||||
"Outline Flags" = list(
|
||||
"OUTLINE_SHARP" = OUTLINE_SHARP,
|
||||
"OUTLINE_SQUARE" = OUTLINE_SQUARE,
|
||||
),
|
||||
"Ray Flags" = list(
|
||||
"FILTER_OVERLAY" = FILTER_OVERLAY,
|
||||
"FILTER_UNDERLAY" = FILTER_UNDERLAY,
|
||||
),
|
||||
"Ripple Flags" = list(
|
||||
"WAVE_BOUNDED" = WAVE_BOUNDED,
|
||||
),
|
||||
"Wave Flags" = list(
|
||||
"WAVE_BOUNDED" = WAVE_BOUNDED,
|
||||
"WAVE_SIDEWAYS" = WAVE_SIDEWAYS,
|
||||
),
|
||||
))
|
||||
|
||||
/obj/item/circuit_component/filter_helper
|
||||
display_name = "Filter Parameter Helper"
|
||||
desc = "Constructs a list of filter parameters from the inputs."
|
||||
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL|CIRCUIT_FLAG_ADMIN
|
||||
|
||||
var/datum/port/input/option/filter_type_port
|
||||
var/current_filter_type
|
||||
|
||||
var/list/filter_params = list()
|
||||
|
||||
var/datum/port/output/output_params
|
||||
|
||||
/obj/item/circuit_component/filter_helper/populate_options()
|
||||
filter_type_port = add_option_port("Filter Type", assoc_to_keys(GLOB.wiremod_filter_info))
|
||||
|
||||
/obj/item/circuit_component/filter_helper/populate_ports()
|
||||
current_filter_type = filter_type_port.value
|
||||
output_params = add_output_port("Parameters", PORT_TYPE_ASSOC_LIST)
|
||||
handle_filter_type_changed()
|
||||
|
||||
/obj/item/circuit_component/filter_helper/pre_input_received(datum/port/input/port)
|
||||
if((port == filter_type_port) && filter_type_port.value != current_filter_type)
|
||||
current_filter_type = filter_type_port.value
|
||||
handle_filter_type_changed()
|
||||
|
||||
/obj/item/circuit_component/filter_helper/proc/handle_filter_type_changed()
|
||||
for(var/param_name in filter_params)
|
||||
remove_input_port(filter_params[param_name])
|
||||
filter_params.Cut()
|
||||
for(var/param_name in GLOB.wiremod_filter_info[current_filter_type])
|
||||
filter_params[param_name] = add_input_port(param_name,
|
||||
GLOB.wiremod_filter_info[current_filter_type][param_name],
|
||||
default = GLOB.master_filter_info?[current_filter_type]["defaults"][param_name])
|
||||
|
||||
/obj/item/circuit_component/filter_helper/input_received(datum/port/input/port, list/return_values)
|
||||
var/list/new_params = list()
|
||||
for(var/param_name in filter_params)
|
||||
var/datum/port/input/param_port = filter_params[param_name]
|
||||
if(!isnull(param_port.value))
|
||||
new_params[param_name] = param_port.value
|
||||
|
||||
output_params.set_value(new_params)
|
||||
|
||||
/obj/item/circuit_component/filter_adder
|
||||
display_name = "Add Filter"
|
||||
desc = "Adds a filter to the target atom."
|
||||
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL|CIRCUIT_FLAG_ADMIN
|
||||
|
||||
var/datum/port/input/target_port
|
||||
var/datum/port/input/filter_name
|
||||
var/datum/port/input/filter_priority
|
||||
var/datum/port/input/option/filter_type_port
|
||||
var/current_filter_type
|
||||
|
||||
var/list/filter_params = list()
|
||||
|
||||
/obj/item/circuit_component/filter_adder/populate_options()
|
||||
filter_type_port = add_option_port("Filter Type", assoc_to_keys(GLOB.wiremod_filter_info))
|
||||
|
||||
/obj/item/circuit_component/filter_adder/populate_ports()
|
||||
current_filter_type = filter_type_port.value
|
||||
target_port = add_input_port("Target", PORT_TYPE_ATOM)
|
||||
filter_name = add_input_port("Filter Name", PORT_TYPE_STRING)
|
||||
filter_priority = add_input_port("Priority", PORT_TYPE_NUMBER)
|
||||
handle_filter_type_changed()
|
||||
|
||||
/obj/item/circuit_component/filter_adder/pre_input_received(datum/port/input/port)
|
||||
if((port == filter_type_port) && filter_type_port.value != current_filter_type)
|
||||
current_filter_type = filter_type_port.value
|
||||
handle_filter_type_changed()
|
||||
|
||||
/obj/item/circuit_component/filter_adder/proc/handle_filter_type_changed()
|
||||
for(var/param_name in filter_params)
|
||||
remove_input_port(filter_params[param_name])
|
||||
filter_params.Cut()
|
||||
for(var/param_name in GLOB.wiremod_filter_info[current_filter_type])
|
||||
filter_params[param_name] = add_input_port(param_name,
|
||||
GLOB.wiremod_filter_info[current_filter_type][param_name],
|
||||
order = 1.5,
|
||||
default = GLOB.master_filter_info?[current_filter_type]["defaults"][param_name])
|
||||
|
||||
/obj/item/circuit_component/filter_adder/input_received(datum/port/input/port, list/return_values)
|
||||
var/atom/target_atom = target_port.value
|
||||
if(!target_atom)
|
||||
return
|
||||
|
||||
var/list/new_params = list()
|
||||
new_params["type"] = current_filter_type
|
||||
for(var/param_name in filter_params)
|
||||
var/datum/port/input/param_port = filter_params[param_name]
|
||||
new_params[param_name] = param_port.value
|
||||
|
||||
target_atom.add_filter(filter_name.value, filter_priority.value, new_params)
|
||||
|
||||
/obj/item/circuit_component/filter_remover
|
||||
display_name = "Filter Remover"
|
||||
desc = "Removes the specified filter from the target."
|
||||
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL|CIRCUIT_FLAG_ADMIN
|
||||
|
||||
var/datum/port/input/target_port
|
||||
var/datum/port/input/filter_name
|
||||
|
||||
/obj/item/circuit_component/filter_remover/populate_ports()
|
||||
target_port = add_input_port("Target", PORT_TYPE_ATOM)
|
||||
filter_name = add_input_port("Filter Name", PORT_TYPE_STRING)
|
||||
|
||||
/obj/item/circuit_component/filter_remover/input_received(datum/port/input/port)
|
||||
var/atom/target_atom = target_port.value
|
||||
if(!target_atom)
|
||||
return
|
||||
|
||||
target_atom.remove_filter(filter_name.value)
|
||||
|
||||
/obj/item/circuit_component/bitflag_helper
|
||||
display_name = "Animation & Filter Bitflag Helper"
|
||||
desc = "Allows you to construct bitflags for BYOND animation and filter parameters without having to manually search for the corresponding values."
|
||||
|
||||
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL|CIRCUIT_FLAG_ADMIN
|
||||
|
||||
var/datum/port/input/option/bitflag_port
|
||||
var/current_bitflag
|
||||
|
||||
var/list/flag_ports = list()
|
||||
|
||||
var/datum/port/output/output_bitflag
|
||||
|
||||
/obj/item/circuit_component/bitflag_helper/populate_options()
|
||||
bitflag_port = add_option_port("Bitflag Type", assoc_to_keys(GLOB.wiremod_flag_info))
|
||||
|
||||
/obj/item/circuit_component/bitflag_helper/populate_ports()
|
||||
current_bitflag = bitflag_port.value
|
||||
handle_bitflag_type_changed()
|
||||
output_bitflag = add_output_port("Output", PORT_TYPE_NUMBER)
|
||||
|
||||
/obj/item/circuit_component/bitflag_helper/pre_input_received(datum/port/input/port)
|
||||
if(port == bitflag_port && bitflag_port.value != current_bitflag)
|
||||
current_bitflag = bitflag_port.value
|
||||
handle_bitflag_type_changed()
|
||||
|
||||
/obj/item/circuit_component/bitflag_helper/proc/handle_bitflag_type_changed()
|
||||
for(var/flag_name in flag_ports)
|
||||
remove_input_port(flag_ports[flag_name])
|
||||
flag_ports.Cut()
|
||||
|
||||
var/list/flags = GLOB.wiremod_flag_info[current_bitflag]
|
||||
for(var/flag in flags)
|
||||
if(islist(flags[flag]))
|
||||
flag_ports[flag] = add_option_port(flag == "_" ? current_bitflag : flag, flags[flag])
|
||||
else
|
||||
flag_ports[flag] = add_input_port(flag, PORT_TYPE_NUMBER)
|
||||
|
||||
/obj/item/circuit_component/bitflag_helper/input_received(datum/port/input/port)
|
||||
var/new_output = 0
|
||||
var/list/flags = GLOB.wiremod_flag_info[current_bitflag]
|
||||
for(var/flag in flags)
|
||||
if(!flag_ports[flag])
|
||||
continue
|
||||
else
|
||||
var/datum/port/input/flag_port = flag_ports[flag]
|
||||
if(islist(flags[flag]))
|
||||
var/list/flag_options = flags[flag]
|
||||
new_output += flag_options[flag_port.value]
|
||||
else if(flag_port.value)
|
||||
new_output += flags[flag]
|
||||
|
||||
output_bitflag.set_output(new_output)
|
||||
Reference in New Issue
Block a user