diff --git a/code/datums/elements/connect_loc.dm b/code/datums/elements/connect_loc.dm new file mode 100644 index 0000000000..fee9072f75 --- /dev/null +++ b/code/datums/elements/connect_loc.dm @@ -0,0 +1,43 @@ +/// This element hooks a signal onto the loc the current object is on. +/// When the object moves, it will unhook the signal and rehook it to the new object. +/datum/element/connect_loc + element_flags = ELEMENT_BESPOKE + id_arg_index = 2 + + /// An assoc list of signal -> procpath to register to the loc this object is on. + var/list/connections + +/datum/element/connect_loc/Attach(atom/movable/listener, list/connections) + . = ..() + if (!istype(listener)) + return ELEMENT_INCOMPATIBLE + + src.connections = connections + + RegisterSignal(listener, COMSIG_MOVABLE_MOVED, .proc/on_moved, override = TRUE) + update_signals(listener) + +/datum/element/connect_loc/Detach(atom/movable/listener) + . = ..() + unregister_signals(listener, listener.loc) + UnregisterSignal(listener, COMSIG_MOVABLE_MOVED) + +/datum/element/connect_loc/proc/update_signals(atom/movable/listener) + var/atom/listener_loc = listener.loc + if(isnull(listener_loc)) + return + + for (var/signal in connections) + //override=TRUE because more than one connect_loc element instance tracked object can be on the same loc + listener.RegisterSignal(listener_loc, signal, connections[signal], override=TRUE) + +/datum/element/connect_loc/proc/unregister_signals(datum/listener, atom/old_loc) + if(isnull(old_loc)) + return + + listener.UnregisterSignal(old_loc, connections) + +/datum/element/connect_loc/proc/on_moved(atom/movable/listener, atom/old_loc) + SIGNAL_HANDLER + unregister_signals(listener, old_loc) + update_signals(listener) diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm index a21b026080..1a469b9408 100644 --- a/code/modules/recycling/conveyor2.dm +++ b/code/modules/recycling/conveyor2.dm @@ -308,6 +308,7 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) S.update_icon() CHECK_TICK +/* /obj/machinery/conveyor_switch/attackby(obj/item/I, mob/user, params) if(I.tool_behaviour == TOOL_CROWBAR) var/obj/item/conveyor_switch_construct/C = new/obj/item/conveyor_switch_construct(src.loc) @@ -315,6 +316,34 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) transfer_fingerprints_to(C) to_chat(user, "You detach the conveyor switch.") qdel(src) +*/ + +/obj/machinery/conveyor_switch/crowbar_act(mob/user, obj/item/tool) + tool.play_tool_sound(src, 50) + var/obj/item/conveyor_switch_construct/switch_construct = new/obj/item/conveyor_switch_construct(src.loc) + switch_construct.id = id + transfer_fingerprints_to(switch_construct) + to_chat(user, span_notice("You detach [src].")) + qdel(src) + return TRUE + +/obj/machinery/conveyor_switch/screwdriver_act(mob/user, obj/item/tool) + tool.play_tool_sound(src, 50) + oneway = !oneway + to_chat(user, span_notice("You set [src] to [oneway ? "one way" : "default"] configuration.")) + return TRUE + +/obj/machinery/conveyor_switch/wrench_act(mob/user, obj/item/tool) + tool.play_tool_sound(src, 50) + invert_icon = !invert_icon + update_appearance() + to_chat(user, span_notice("You set [src] to [invert_icon ? "inverted": "normal"] position.")) + return TRUE + +/obj/machinery/conveyor_switch/examine(mob/user) + . = ..() + . += span_notice("[src] is set to [oneway ? "one way" : "default"] configuration. It can be changed with a screwdriver.") + . += span_notice("[src] is set to [invert_icon ? "inverted": "normal"] position. It can be rotated with a wrench.") /obj/machinery/conveyor_switch/oneway icon_state = "conveyor_switch_oneway" diff --git a/code/modules/recycling/conveyor_sorter.dm b/code/modules/recycling/conveyor_sorter.dm new file mode 100644 index 0000000000..12451fc0d6 --- /dev/null +++ b/code/modules/recycling/conveyor_sorter.dm @@ -0,0 +1,145 @@ +// credits to jjpark-kb, see Skyrat-SS13/Skyrat-tg#8790 and related files +// - hatterhat + +/obj/item/conveyor_sorter + name = "conveyor sorter lister" + desc = "A tool that is used to create conveyor sorting marks, and give sorting lists to them." + icon = 'icons/obj/recycling.dmi' + icon_state = "lister" + ///the list of conveyor sorters spawned by + var/list/spawned_sorters = list() + ///the list of things that are currently within the sorting list + var/list/current_sort = list() + +/obj/item/conveyor_sorter/Destroy() + for(var/deleting_sorters in spawned_sorters) + qdel(deleting_sorters) + return ..() + +/obj/item/conveyor_sorter/examine(mob/user) + . = ..() + . += span_notice("Use it to place down a conveyor sorter, up to three.") + . += span_notice("Use Alt-Click to reset the sorting list.") + . += span_notice("Attack things to attempt to add to the sorting list.") + +/obj/item/conveyor_sorter/attack_self(mob/user, modifiers) + if(length(spawned_sorters) >= 3) + to_chat(user, span_warning("You may only have three spawned conveyor sorters!")) + return + var/obj/effect/decal/cleanable/conveyor_sorter/new_cs = new /obj/effect/decal/cleanable/conveyor_sorter(get_turf(src)) + new_cs.parent_item = src + spawned_sorters += new_cs + +/obj/item/conveyor_sorter/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + if(target == src) + return ..() + if(!proximity_flag) + return ..() + if(!ismovable(target)) + return ..() + if(istype(target, /obj/effect/decal/cleanable/conveyor_sorter)) + return + if(is_type_in_list(target, current_sort)) + to_chat(user, span_warning("[target] is already in [src]'s sorting list!")) + return + if(length(current_sort) >= 5) + to_chat(user, span_warning("[src] already has five things within the sorting list!")) + return + current_sort += target.type + to_chat(user, span_notice("[target] has been added to [src]'s sorting list.")) + +/obj/item/conveyor_sorter/AltClick(mob/user) + visible_message("[src] pings, resetting its sorting list!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + current_sort = list() + +/obj/effect/decal/cleanable/conveyor_sorter + name = "conveyor sorter" + desc = "A mark that sorts items out based on what they are." + icon = 'icons/obj/recycling.dmi' + icon_state = "sorter" + layer = OBJ_LAYER + plane = GAME_PLANE + ///the list of items that will be sorted to the sorted direction + var/list/sorting_list = list() + //the direction that the items in the sorting list will be moved to + dir = NORTH + ///the parent conveyor sorter lister item, used for deletion + var/obj/item/conveyor_sorter/parent_item + /// To prevent spam + COOLDOWN_DECLARE(use_cooldown) + + light_range = 3 + light_color = COLOR_RED_LIGHT + +/obj/effect/decal/cleanable/conveyor_sorter/Initialize(mapload, list/datum/disease/diseases) + . = ..() + var/static/list/loc_connections = list( + COMSIG_ATOM_ENTERED = .proc/on_entered, + ) + AddElement(/datum/element/connect_loc, loc_connections) + +/obj/effect/decal/cleanable/conveyor_sorter/Destroy() + if(parent_item) + parent_item.spawned_sorters -= src + parent_item = null + return ..() + +/obj/effect/decal/cleanable/conveyor_sorter/examine(mob/user) + . = ..() + . += span_notice("Attack with conveyor sorter lister to set the sorting list.") + . += span_notice("Slap with empty hands to change the sorting direction.") + . += span_notice("Alt-Click to reset the sorting list.") + . += span_notice("Ctrl-Click to remove.") + +/obj/effect/decal/cleanable/conveyor_sorter/attack_hand(mob/living/user, list/modifiers) + var/user_choice = tgui_input_list(user, "Choose which direction to sort to!", "Direction choice", list("North", "East", "South", "West")) + if(!user_choice) + return ..() + switch(user_choice) + if("North") + setDir(NORTH) + if("East") + setDir(EAST) + if("South") + setDir(SOUTH) + if("West") + setDir(WEST) + visible_message("[src] pings, updating its sorting direction!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + +/obj/effect/decal/cleanable/conveyor_sorter/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/conveyor_sorter)) + var/obj/item/conveyor_sorter/cs_item = W + sorting_list = cs_item.current_sort + visible_message("[src] pings, updating its sorting list!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + return + else + return ..() + +/obj/effect/decal/cleanable/conveyor_sorter/AltClick(mob/user) + visible_message("[src] pings, resetting its sorting list!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + sorting_list = list() + +/obj/effect/decal/cleanable/conveyor_sorter/CtrlClick(mob/user) + visible_message("[src] pings, before disappearing!") + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + qdel(src) + +/obj/effect/decal/cleanable/conveyor_sorter/proc/on_entered(datum/source, atom/movable/AM) + . = ..() + if(is_type_in_list(AM, sorting_list) && !AM.anchored && COOLDOWN_FINISHED(src, use_cooldown)) + COOLDOWN_START(src, use_cooldown, 1 SECONDS) + AM.Move(get_step(src, dir)) + +/datum/design/conveyor_sorter + name = "Conveyor Sorter" + desc = "A wonderful item that can set markers and forcefully move stuff to a direction." + id = "conveyor_sorter" + build_type = PROTOLATHE + build_path = /obj/item/conveyor_sorter + materials = list(/datum/material/iron = 500, /datum/material/plastic = 500) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_CARGO diff --git a/code/modules/research/techweb/nodes/engineering_nodes.dm b/code/modules/research/techweb/nodes/engineering_nodes.dm index 2b5d6f3cc1..b108476f9b 100644 --- a/code/modules/research/techweb/nodes/engineering_nodes.dm +++ b/code/modules/research/techweb/nodes/engineering_nodes.dm @@ -7,8 +7,8 @@ prereq_ids = list("base") design_ids = list("solarcontrol", "recharger", "powermonitor", "rped", "pacman", "adv_capacitor", "adv_scanning", "emitter", "high_cell", "adv_matter_bin", "atmosalerts", "atmos_control", "recycler", "autolathe", "autolathe_secure", "high_micro_laser", "nano_mani", "mesons", "thermomachine", "rad_collector", "tesla_coil", "grounding_rod", - "apc_control", "power control", "airlock_board", "firelock_board", "airalarm_electronics", "firealarm_electronics", "cell_charger", "stack_console", "stack_machine", "rcd_ammo","oxygen_tank", - "plasma_tank", "emergency_oxygen", "emergency_oxygen_engi", "plasmaman_tank_belt", "colormate") + "apc_control", "power control", "airlock_board", "firelock_board", "airalarm_electronics", "firealarm_electronics", "cell_charger", "stack_console", "stack_machine", "rcd_ammo", "oxygen_tank", + "plasma_tank", "emergency_oxygen", "emergency_oxygen_engi", "plasmaman_tank_belt", "colormate", "conveyor_sorter") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 6000) /datum/techweb_node/adv_engi diff --git a/icons/obj/recycling.dmi b/icons/obj/recycling.dmi index 9604d6b97e..621b9e4241 100644 Binary files a/icons/obj/recycling.dmi and b/icons/obj/recycling.dmi differ diff --git a/tgstation.dme b/tgstation.dme index c010fc66fe..6825b9432b 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -684,6 +684,7 @@ #include "code\datums\elements\bed_tucking.dm" #include "code\datums\elements\bsa_blocker.dm" #include "code\datums\elements\cleaning.dm" +#include "code\datums\elements\connect_loc.dm" #include "code\datums\elements\decal.dm" #include "code\datums\elements\dusts_on_catatonia.dm" #include "code\datums\elements\dusts_on_leaving_area.dm" @@ -3328,6 +3329,7 @@ #include "code\modules\reagents\reagent_containers\spray.dm" #include "code\modules\reagents\reagent_containers\syringes.dm" #include "code\modules\recycling\conveyor2.dm" +#include "code\modules\recycling\conveyor_sorter.dm" #include "code\modules\recycling\sortingmachinery.dm" #include "code\modules\recycling\disposal\bin.dm" #include "code\modules\recycling\disposal\construction.dm"