diff --git a/code/__defines/construction.dm b/code/__defines/construction.dm index 4f12c0a01ec..e90259d09bd 100644 --- a/code/__defines/construction.dm +++ b/code/__defines/construction.dm @@ -83,6 +83,7 @@ #define DISPOSAL_SORT_NORMAL 0 #define DISPOSAL_SORT_WILDCARD 1 #define DISPOSAL_SORT_UNTAGGED 2 +#define DISPOSAL_SORT_BODIES 3 // Macro for easy use of boilerplate code for searching for a valid node connection. #define STANDARD_ATMOS_CHOOSE_NODE(node_num, direction) \ diff --git a/code/game/machinery/pipe/pipe_recipes.dm b/code/game/machinery/pipe/pipe_recipes.dm index 594eb0a00a8..0d4ed2719d0 100644 --- a/code/game/machinery/pipe/pipe_recipes.dm +++ b/code/game/machinery/pipe/pipe_recipes.dm @@ -57,6 +57,7 @@ GLOBAL_LIST_INIT(disposal_pipe_recipes, list( new /datum/pipe_recipe/disposal("Sort Junction", DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, DISPOSAL_SORT_NORMAL), new /datum/pipe_recipe/disposal("Sort Junction (Wildcard)", DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, DISPOSAL_SORT_WILDCARD), new /datum/pipe_recipe/disposal("Sort Junction (Untagged)", DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, DISPOSAL_SORT_UNTAGGED), + new /datum/pipe_recipe/disposal("Sort Junction (Body Recovery)", DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, DISPOSAL_SORT_BODIES), new /datum/pipe_recipe/disposal("Tagger", DISPOSAL_PIPE_TAGGER, "pipe-tagger", PIPE_STRAIGHT), new /datum/pipe_recipe/disposal("Tagger (Partial)", DISPOSAL_PIPE_TAGGER_PARTIAL, "pipe-tagger-partial", PIPE_STRAIGHT), new /datum/pipe_recipe/disposal("Trunk", DISPOSAL_PIPE_TRUNK, "conpipe-t"), diff --git a/code/modules/recycling/disposal-construction.dm b/code/modules/recycling/disposal-construction.dm index 179db1ca1f2..fd8e22ab392 100644 --- a/code/modules/recycling/disposal-construction.dm +++ b/code/modules/recycling/disposal-construction.dm @@ -169,6 +169,8 @@ return /obj/structure/disposalpipe/sortjunction/wildcard if(DISPOSAL_SORT_UNTAGGED) return /obj/structure/disposalpipe/sortjunction/untagged + if(DISPOSAL_SORT_BODIES) + return /obj/structure/disposalpipe/sortjunction/bodies if(DISPOSAL_PIPE_SORTER_FLIPPED) switch(subtype) if(DISPOSAL_SORT_NORMAL) @@ -177,6 +179,8 @@ return /obj/structure/disposalpipe/sortjunction/wildcard/flipped if(DISPOSAL_SORT_UNTAGGED) return /obj/structure/disposalpipe/sortjunction/untagged/flipped + if(DISPOSAL_SORT_BODIES) + return /obj/structure/disposalpipe/sortjunction/bodies/flipped if(DISPOSAL_PIPE_UPWARD) return /obj/structure/disposalpipe/up if(DISPOSAL_PIPE_DOWNWARD) @@ -211,6 +215,8 @@ nicetype = "wildcard sorting pipe" if(DISPOSAL_SORT_UNTAGGED) nicetype = "untagged sorting pipe" + if(DISPOSAL_SORT_BODIES) + nicetype = "body recovery sorting pipe" ispipe = 1 if(DISPOSAL_PIPE_TAGGER) nicetype = "tagging pipe" diff --git a/code/modules/recycling/disposal_bin_subtypes.dm b/code/modules/recycling/disposal_bin_subtypes.dm new file mode 100644 index 00000000000..0df64a3b637 --- /dev/null +++ b/code/modules/recycling/disposal_bin_subtypes.dm @@ -0,0 +1,55 @@ +// Cleaner subtype +/obj/machinery/disposal/cleaner + name = "resleeving equipment deposit" + desc = "Automatically cleans and transports items to the local resleeving facilities." + icon_state = "blue" + +/obj/machinery/disposal/cleaner/flush() + if(flushing) + return + clean_items() + . = ..() + +/obj/machinery/disposal/wall/cleaner + name = "resleeving equipment deposit" + desc = "Automatically cleans and transports items to the local resleeving facilities." + icon_state = "bluewall" + +/obj/machinery/disposal/wall/cleaner/flush() + if(flushing) + return + clean_items() + . = ..() + +// Incin/space +/obj/machinery/disposal/burn_pit + name = "disposal(hazardous)" + desc = "A pneumatic waste disposal unit. This unit is either connected directly to the station's waste processor or dumped into space." + icon_state = "red" + +/obj/machinery/disposal/wall/burn_pit + name = "disposal(hazardous)" + desc = "A pneumatic waste disposal unit. This unit is either connected directly to the station's waste processor or dumped into space." + icon_state = "redwall" + +// Amnesty box +/obj/machinery/disposal/turn_in + name = "amnesty bin" + desc = "A pneumatic waste disposal unit. A place to legally turn in contraban to security." + icon_state = "green" + +/obj/machinery/disposal/wall/turn_in + name = "amnesty bin" + desc = "A pneumatic waste disposal unit. A place to legally turn in contraban to security." + icon_state = "greenwall" + +// Gets mail +/obj/machinery/disposal/mail_reciever + name = "disposal mail destination" + desc = "A pneumatic waste disposal unit. This unit is marked for receiving mail." + icon_state = "white" + +/obj/machinery/disposal/wall/mail_reciever + name = "disposal mail destination" + desc = "A pneumatic waste disposal unit. This unit is marked for receiving mail." + icon_state = "whitewall" diff --git a/code/modules/recycling/disposal_junctions.dm b/code/modules/recycling/disposal_junctions.dm index ac3037b984b..6c735897329 100644 --- a/code/modules/recycling/disposal_junctions.dm +++ b/code/modules/recycling/disposal_junctions.dm @@ -195,3 +195,54 @@ /obj/structure/disposalpipe/sortjunction/untagged/flipped icon_state = "pipe-j2s" + +//junction that filters bodies and IDs +#define CORPSE_SORT_TAG "corpse" + +/obj/structure/disposalpipe/sortjunction/bodies + name = "body recovery junction" + desc = "An underfloor disposal pipe which filters out detectable bodies, living or soon to be dead. Also diverts anything containing an ID." + subtype = DISPOSAL_SORT_BODIES + +/obj/structure/disposalpipe/sortjunction/bodies/transfer(obj/structure/disposalholder/H) + if(H.destinationTag == "") + // If the package isn't mail and we're a body sorter, check if it has a body/ID, and divert it if so. + H.destinationTag = check_for_corpse_or_id(H) + . = ..() + +/obj/structure/disposalpipe/sortjunction/bodies/divert_check(var/checkTag) + return checkTag == CORPSE_SORT_TAG + +/obj/structure/disposalpipe/sortjunction/bodies/flipped + icon_state = "pipe-j2s" + +/obj/structure/disposalpipe/sortjunction/bodies/proc/check_for_corpse_or_id(var/obj/structure/disposalholder/H) + for(var/mob/living/L in H) + if(iscarbon(L)) // only living carbons count not silicons, drones can control their own mailing destination... + return CORPSE_SORT_TAG + + // Check for microholders, you can't skip the system this way either! + for(var/obj/item/holder/hl in H) + if(isliving(hl.held_mob)) + return CORPSE_SORT_TAG + + // find an ID in items + for(var/obj/item/card/id in H) + if(!istype(id,/obj/item/card/id/guest)) + return CORPSE_SORT_TAG + for(var/obj/item/pda/P in H) + if(!istype(P.id,/obj/item/card/id/guest)) + return CORPSE_SORT_TAG + + // Check in bags, only one level deep. Need to check for pda again too + for(var/obj/item/storage in H) + for(var/obj/item/pda/P in storage.contents) + if(!istype(P.id,/obj/item/card/id/guest)) + return CORPSE_SORT_TAG + for(var/obj/item/card/id in storage.contents) + if(!istype(id,/obj/item/card/id/guest)) + return CORPSE_SORT_TAG + + return H.destinationTag + +#undef CORPSE_SORT_TAG diff --git a/code/modules/recycling/disposal_machines.dm b/code/modules/recycling/disposal_machines.dm index d89d80f3f72..1b21c25da78 100644 --- a/code/modules/recycling/disposal_machines.dm +++ b/code/modules/recycling/disposal_machines.dm @@ -18,6 +18,7 @@ desc = "A pneumatic waste disposal unit." icon = 'icons/obj/pipes/disposal.dmi' icon_state = "disposal" + var/controls_iconstate = "disposal" anchored = TRUE density = TRUE var/datum/gas_mixture/air_contents // internal reservoir @@ -56,7 +57,10 @@ add_fingerprint(user) if(mode <= DISPOSALMODE_OFF) // It's off - if(I.has_tool_quality(TOOL_SCREWDRIVER)) + if(I.has_tool_quality(TOOL_MULTITOOL)) + alter_bin_type(user) + return + else if(I.has_tool_quality(TOOL_SCREWDRIVER)) if(contents.len > 0) to_chat(user, "Eject the items first!") return @@ -148,6 +152,93 @@ user.visible_message("[user] places \the [I] into the [src].", "You place \the [I] into the [src].","Ca-Clunk") update() +// Transform into next machine type +/obj/machinery/disposal/proc/alter_bin_type(mob/user) + if(contents.len > 0) + to_chat(user, "Eject the items first!") + return + // Get what we want to turn into + var/nametag + var/new_dir = SOUTH + var/new_disposal_path + var/result = tgui_input_list(user, + "What do you want to reconfigure the disposal bin to?", + "Multitool-Disposal interface", + list( + "Standard", + "Wall", + "Resleeving Deposit", + "Wall Resleeving Deposit", + "Hazard Bin", + "Wall Hazard Bin", + "Turn-In Bin", + "Wall Turn-In Bin", + "Mail Destination", + "Wall Mail Destination" + )) + if(!result) + return + switch(result) + // Yellow + if("Standard") + new_disposal_path = /obj/machinery/disposal + if("Wall") + new_disposal_path = /obj/machinery/disposal/wall + new_dir = reverse_direction(user.dir) + // Blue + if("Resleeving Deposit") + new_disposal_path = /obj/machinery/disposal/cleaner + new_dir = reverse_direction(user.dir) + if("Wall Resleeving Deposit") + new_disposal_path = /obj/machinery/disposal/wall/cleaner + new_dir = reverse_direction(user.dir) + // Red + if("Hazard Bin") + new_disposal_path = /obj/machinery/disposal/burn_pit + if("Wall Hazard Bin") + new_disposal_path = /obj/machinery/disposal/wall/burn_pit + new_dir = reverse_direction(user.dir) + // Green + if("Turn-In Bin") + new_disposal_path = /obj/machinery/disposal/turn_in + if("Wall Turn-In Bin") + new_disposal_path = /obj/machinery/disposal/wall/turn_in + new_dir = reverse_direction(user.dir) + // White + if("Mail Destination") + new_disposal_path = /obj/machinery/disposal/mail_reciever + nametag = tgui_input_text(user,"Name this mail destination. This name has no effect on the disposal sorting junction, and is only for crew convenience.", "Mail Destination") + if("Wall Mail Destination") + new_disposal_path = /obj/machinery/disposal/wall/mail_reciever + new_dir = reverse_direction(user.dir) + nametag = tgui_input_text(user,"Name this mail destination. This name has no effect on the disposal sorting junction, and is only for crew convenience.", "Mail Destination") + + if(!new_disposal_path || (new_disposal_path == type && dir == new_dir)) + return + if(!Adjacent(user) || contents.len > 0) + return + if(mode > DISPOSALMODE_OFF) + return + // Make new bin + var/obj/machinery/disposal/new_bin = new new_disposal_path(loc) + if(nametag) // mailer only + new_bin.name = "[initial(new_bin.name)]([nametag])" + new_bin.stat = stat + new_bin.dir = new_dir + new_bin.mode = mode + new_bin.update() // sets up wall outlets + new_bin.update_icon() + new_bin.visible_message("\The [src] reconfigures into \a [new_bin]!") + // Effects + playsound(new_bin, 'sound/items/jaws_cut.ogg', 50, 1) + playsound(new_bin, 'sound/machines/machine_die_short.ogg', 50, 1) + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, new_bin) + spark_system.attach(new_bin) + spark_system.start() + // Cleanup + qdel(src) + // mouse drop another mob or self // /obj/machinery/disposal/MouseDrop_T(mob/target, mob/user) @@ -316,7 +407,7 @@ // flush handle if(flush) - add_overlay("[initial(icon_state)]-handle") + add_overlay("[controls_iconstate]-handle") // only handle is shown if no power if(stat & NOPOWER || mode == DISPOSALMODE_EJECTONLY) @@ -324,13 +415,13 @@ // check for items in disposal - occupied light if(contents.len > 0) - add_overlay("[initial(icon_state)]-full") + add_overlay("[controls_iconstate]-full") // charging and ready light if(mode == DISPOSALMODE_CHARGING) - add_overlay("[initial(icon_state)]-charge") + add_overlay("[controls_iconstate]-charge") else if(mode == DISPOSALMODE_CHARGED) - add_overlay("[initial(icon_state)]-ready") + add_overlay("[controls_iconstate]-ready") // timed process // charge the gas reservoir and perform flush if ready @@ -433,40 +524,7 @@ source.forceMove(src) visible_message("\The [source] lands in \the [src].") -/obj/machinery/disposal/wall - name = "inset disposal unit" - icon_state = "wall" - - density = FALSE - -/obj/machinery/disposal/wall/update() - ..() - - switch(dir) - if(1) - pixel_x = 0 - pixel_y = -32 - if(2) - pixel_x = 0 - pixel_y = 32 - if(4) - pixel_x = -32 - pixel_y = 0 - if(8) - pixel_x = 32 - pixel_y = 0 - - -// Cleaner subtype -/obj/machinery/disposal/wall/cleaner - name = "resleeving equipment deposit" - desc = "Automatically cleans and transports items to the local resleeving facilities." - icon_state = "bluewall" - -/obj/machinery/disposal/wall/cleaner/flush() - if(flushing) - return - +/obj/machinery/disposal/proc/clean_items() // Clean items before sending them for(var/obj/item/flushed_item in src) if(istype(flushed_item, /obj/item/storage)) @@ -478,7 +536,29 @@ if(istype(flushed_item, /obj/item)) flushed_item.wash(CLEAN_WASH) +// Wall mounted base type +/obj/machinery/disposal/wall + name = "inset disposal unit" + icon_state = "wall" + controls_iconstate = "wall" + + density = FALSE + +/obj/machinery/disposal/wall/update() . = ..() + switch(dir) + if(NORTH) + pixel_x = 0 + pixel_y = -32 + if(SOUTH) + pixel_x = 0 + pixel_y = 32 + if(EAST) + pixel_x = -32 + pixel_y = 0 + if(WEST) + pixel_x = 32 + pixel_y = 0 #undef DISPOSALMODE_EJECTONLY #undef DISPOSALMODE_OFF diff --git a/icons/obj/pipes/disposal.dmi b/icons/obj/pipes/disposal.dmi index f242efe8fe3..360ef5c6341 100644 Binary files a/icons/obj/pipes/disposal.dmi and b/icons/obj/pipes/disposal.dmi differ diff --git a/vorestation.dme b/vorestation.dme index f7dd05540b7..e72b589c841 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -4292,6 +4292,7 @@ #include "code\modules\recycling\destination_tagger.dm" #include "code\modules\recycling\disposal-construction.dm" #include "code\modules\recycling\disposal.dm" +#include "code\modules\recycling\disposal_bin_subtypes.dm" #include "code\modules\recycling\disposal_holder.dm" #include "code\modules\recycling\disposal_junctions.dm" #include "code\modules\recycling\disposal_machines.dm"