#define SAFETY_COOLDOWN 100 /obj/machinery/recycler name = "recycler" desc = "A large crushing machine used to recycle small items inefficiently. There are lights on the side." icon = 'icons/obj/recycling.dmi' icon_state = "grinder-o0" layer = ABOVE_ALL_MOB_LAYER // Overhead density = TRUE circuit = /obj/item/circuitboard/machine/recycler var/safety_mode = FALSE // Temporarily stops machine if it detects a mob, or upon deconstruction. var/icon_name = "grinder-o" var/blood = 0 var/eat_dir = WEST var/amount_produced = 50 var/crush_damage = 1000 var/eat_victim_items = TRUE var/item_recycle_sound = 'sound/items/welder.ogg' /obj/machinery/recycler/Initialize() AddComponent(/datum/component/butchering/recycler, 1, amount_produced,amount_produced/5) AddComponent(/datum/component/material_container, list(/datum/material/iron, /datum/material/glass, /datum/material/silver, /datum/material/plasma, /datum/material/gold, /datum/material/diamond, /datum/material/plastic, /datum/material/uranium, /datum/material/bananium, /datum/material/titanium, /datum/material/bluespace), INFINITY, FALSE, null, null, null, TRUE) . = ..() update_icon() req_one_access = get_all_accesses() + get_all_centcom_access() /obj/machinery/recycler/deconstruct(disassembled = TRUE) safety_mode = TRUE //to stop stock parts and circuit from being deleted. return ..() /obj/machinery/recycler/RefreshParts() var/amt_made = 0 var/mat_mod = 0 for(var/obj/item/stock_parts/matter_bin/B in component_parts) mat_mod = 2 * B.rating mat_mod *= 50000 for(var/obj/item/stock_parts/manipulator/M in component_parts) amt_made = 12.5 * M.rating //% of materials salvaged var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) materials.max_amount = mat_mod amount_produced = min(50, amt_made) + 50 var/datum/component/butchering/butchering = GetComponent(/datum/component/butchering/recycler) butchering.effectiveness = amount_produced butchering.bonus_modifier = amount_produced/5 /obj/machinery/recycler/examine(mob/user) . = ..() . += "Reclaiming [amount_produced]% of materials salvaged." . += {"The power light is [(stat & NOPOWER) ? "off" : "on"]. The safety-mode light is [safety_mode ? "on" : "off"]. The safety-sensors status light is [obj_flags & EMAGGED ? "off" : "on"]."} /obj/machinery/recycler/power_change() ..() update_icon() /obj/machinery/recycler/attackby(obj/item/I, mob/user, params) if(default_deconstruction_screwdriver(user, "grinder-oOpen", "grinder-o0", I)) return if(default_pry_open(I)) return if(default_unfasten_wrench(user, I)) return if(default_deconstruction_crowbar(I)) return return ..() /obj/machinery/recycler/emag_act(mob/user) . = ..() if(obj_flags & EMAGGED) return obj_flags |= EMAGGED if(safety_mode) safety_mode = FALSE update_icon() playsound(src, "sparks", 75, 1, -1) to_chat(user, "You use the cryptographic sequencer on [src].") return TRUE /obj/machinery/recycler/update_icon_state() var/is_powered = !(stat & (BROKEN|NOPOWER)) if(safety_mode) is_powered = FALSE icon_state = icon_name + "[is_powered]" + "[(blood ? "bld" : "")]" // add the blood tag at the end /obj/machinery/recycler/CanPass(atom/movable/AM) . = ..() if(!anchored) return var/move_dir = get_dir(loc, AM.loc) if(move_dir == eat_dir) return TRUE /obj/machinery/recycler/Crossed(atom/movable/AM) eat(AM) . = ..() /obj/machinery/recycler/proc/eat(atom/movable/AM0, sound=TRUE) if(stat & (BROKEN|NOPOWER)) return if(safety_mode) return if(!isturf(AM0.loc)) return //I don't know how you called Crossed() but stop it. var/list/to_eat = AM0.GetAllContents() var/mob/living/living_detected //technically includes silicons as well but eh var/list/nom = list() var/list/crunchy_nom = list() //Mobs have to be handled differently so they get a different list instead of checking them multiple times. for(var/i in to_eat) var/atom/movable/AM = i if(istype(AM, /obj/item)) var/obj/item/bodypart/head/as_head = AM var/obj/item/mmi/as_mmi = AM if(istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || istype(AM, /obj/item/dullahan_relay)) living_detected = living_detected || AM nom += AM else if(isliving(AM)) living_detected = living_detected || TRUE crunchy_nom += AM var/not_eaten = to_eat.len - nom.len - crunchy_nom.len if(living_detected) // First, check if we have any living beings detected. if(obj_flags & EMAGGED) for(var/CRUNCH in crunchy_nom) // Eat them and keep going because we don't care about safety. if(isliving(CRUNCH)) // MMIs and brains will get eaten like normal items crush_living(CRUNCH) else // Stop processing right now without eating anything. emergency_stop(living_detected) return for(var/nommed in nom) recycle_item(nommed) if(nom.len && sound) playsound(src, item_recycle_sound, (50 + nom.len*5), TRUE, nom.len, ignore_walls = (nom.len - 10)) // As a substitute for playing 50 sounds at once. if(not_eaten) playsound(src, 'sound/machines/buzz-sigh.ogg', (50 + not_eaten*5), FALSE, not_eaten, ignore_walls = (not_eaten - 10)) // Ditto. if(!ismob(AM0)) AM0.moveToNullspace() qdel(AM0) else // Lets not move a mob to nullspace and qdel it, yes? for(var/i in AM0.contents) var/atom/movable/content = i content.moveToNullspace() qdel(content) /obj/machinery/recycler/proc/recycle_item(obj/item/I) . = list() for(var/A in I) var/atom/movable/AM = A AM.forceMove(loc) if(AM.loc == loc) . += AM I.forceMove(loc) var/obj/item/grown/log/L = I if(istype(L)) var/seed_modifier = 0 if(L.seed) seed_modifier = round(L.seed.potency / 25) new L.plank_type(src.loc, 1 + seed_modifier) qdel(L) return else var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) var/material_amount = materials.get_item_material_amount(I) if(!material_amount) qdel(I) return materials.insert_item(I, multiplier = (amount_produced / 100)) qdel(I) materials.retrieve_all() /obj/machinery/recycler/proc/emergency_stop(mob/living/L) playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0) safety_mode = TRUE update_icon() L.forceMove(loc) addtimer(CALLBACK(src, .proc/reboot), SAFETY_COOLDOWN) /obj/machinery/recycler/proc/reboot() playsound(src, 'sound/machines/ping.ogg', 50, 0) safety_mode = FALSE update_icon() /obj/machinery/recycler/proc/crush_living(mob/living/L) . = list() L.forceMove(loc) if(issilicon(L)) playsound(src, 'sound/items/welder.ogg', 50, 1) else playsound(src, 'sound/effects/splat.ogg', 50, 1) // By default, the emagged recycler will gib all non-carbons. (human simple animal mobs don't count) if(iscarbon(L)) if(L.stat == CONSCIOUS) L.say("ARRRRRRRRRRRGH!!!", forced="recycler grinding") add_mob_blood(L) if(!blood && !issilicon(L)) blood = TRUE update_icon() // Remove and recycle the equipped items if(eat_victim_items) for(var/obj/item/I in L.get_equipped_items(TRUE)) if(L.dropItemToGround(I)) . += I // Instantly lie down, also go unconscious from the pain, before you die. L.Unconscious(100) L.adjustBruteLoss(crush_damage) /obj/machinery/recycler/deathtrap name = "dangerous old crusher" obj_flags = CAN_BE_HIT | EMAGGED crush_damage = 120 flags_1 = NODECONSTRUCT_1 /obj/item/paper/guides/recycler name = "paper - 'garbage duty instructions'" info = "_New Assignment_\n\n You have been assigned to collect garbage from trash bins, located around the station. The crewmembers will put their trash into it and you will collect the said trash.

There is a recycling machine near your closet, inside maintenance; use it to recycle the trash for a small chance to get useful minerals. Then deliver these minerals to cargo or engineering. You are our last hope for a clean station, do not screw this up!" #undef SAFETY_COOLDOWN