/obj/structure/big_delivery name = "large parcel" desc = "A big wrapped package." icon = 'icons/obj/storage.dmi' icon_state = "deliverycloset" density = TRUE mouse_drag_pointer = MOUSE_ACTIVE_POINTER var/obj/wrapped = null var/init_welded = FALSE var/giftwrapped = FALSE var/sortTag = 1 /obj/structure/big_delivery/Destroy() var/turf/T = get_turf(src) for(var/atom/movable/AM in contents) AM.forceMove(T) return ..() /obj/structure/big_delivery/ex_act(severity) for(var/atom/movable/AM in contents) AM.ex_act() CHECK_TICK ..() /obj/structure/big_delivery/attack_hand(mob/user as mob) if(user in src) return open() /obj/structure/big_delivery/container_resist(mob/living/L) var/breakout_time = 1 MINUTES to_chat(L, SPAN_NOTICE("You attempt to break the wrapping on [src].")) if(do_after_once(L, breakout_time, needhand = FALSE, target = src, allow_moving = TRUE, allow_moving_target = TRUE)) open() /obj/structure/big_delivery/proc/open() playsound(loc, 'sound/items/poster_ripped.ogg', 50, 1) if(wrapped) wrapped.forceMove(get_turf(src)) if(istype(wrapped, /obj/structure/closet)) var/obj/structure/closet/O = wrapped O.welded = init_welded for(var/mob/living/stowaway in src) stowaway.forceMove(O) var/turf/T = get_turf(src) for(var/atom/movable/AM in src) AM.loc = T qdel(src) /obj/structure/big_delivery/item_interaction(mob/living/user, obj/item/W, list/modifiers) . = ITEM_INTERACT_COMPLETE if(istype(W, /obj/item/dest_tagger)) var/obj/item/dest_tagger/O = W if(sortTag != O.currTag) var/tag = uppertext(GLOB.TAGGERLOCATIONS[O.currTag]) to_chat(user, SPAN_NOTICE("*[tag]*")) sortTag = O.currTag playsound(loc, 'sound/machines/twobeep.ogg', 100, 1) else if(istype(W, /obj/item/shipping_package)) var/obj/item/shipping_package/sp = W if(sp.sealed) return else sortTag = sp.sortTag to_chat(user, SPAN_NOTICE("You rip the label off the shipping package and affix it to [src].")) qdel(sp) playsound(loc, 'sound/items/poster_ripped.ogg', 50, 1) else if(is_pen(W)) rename_interactive(user, W) else if(istype(W, /obj/item/stack/wrapping_paper) && !giftwrapped) var/obj/item/stack/wrapping_paper/WP = W if(WP.use(3)) user.visible_message(SPAN_NOTICE("[user] wraps the package in festive paper!")) giftwrapped = TRUE if(istype(wrapped, /obj/structure/closet/crate)) icon_state = "giftcrate" else icon_state = "giftcloset" if(WP.amount <= 0 && !WP.loc) //if we used our last wrapping paper, drop a cardboard tube new /obj/item/c_tube( get_turf(user) ) else to_chat(user, SPAN_NOTICE("You need more paper.")) else return ..() /obj/item/small_delivery name = "small parcel" desc = "A small wrapped package." icon = 'icons/obj/storage.dmi' icon_state = "deliverycrate2" var/obj/item/wrapped = null var/giftwrapped = FALSE var/sortTag = 1 /obj/item/small_delivery/ex_act(severity) for(var/atom/movable/AM in contents) AM.ex_act() CHECK_TICK ..() /obj/item/small_delivery/emp_act(severity) ..() for(var/i in contents) var/atom/A = i A.emp_act(severity) /obj/item/small_delivery/attack_self__legacy__attackchain(mob/user) if(wrapped?.loc == src) //sometimes items can disappear. For example, bombs. --rastaf0 wrapped.forceMove(get_turf(src)) if(ishuman(user)) user.put_in_hands(wrapped) playsound(src, 'sound/items/poster_ripped.ogg', 50, TRUE) qdel(src) /obj/item/small_delivery/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) if(istype(W, /obj/item/dest_tagger)) var/obj/item/dest_tagger/O = W if(sortTag != O.currTag) var/tag = uppertext(GLOB.TAGGERLOCATIONS[O.currTag]) to_chat(user, SPAN_NOTICE("*[tag]*")) sortTag = O.currTag playsound(loc, 'sound/machines/twobeep.ogg', 100, 1) else if(istype(W, /obj/item/shipping_package)) var/obj/item/shipping_package/sp = W if(sp.sealed) return else sortTag = sp.sortTag to_chat(user, SPAN_NOTICE("You rip the label off the shipping package and affix it to [src].")) qdel(sp) playsound(loc, 'sound/items/poster_ripped.ogg', 50, 1) else if(is_pen(W)) rename_interactive(user, W) else if(istype(W, /obj/item/stack/wrapping_paper) && !giftwrapped) var/obj/item/stack/wrapping_paper/WP = W if(WP.use(1)) icon_state = "giftcrate[wrapped.w_class]" giftwrapped = TRUE user.visible_message(SPAN_NOTICE("[user] wraps the package in festive paper!")) if(WP.amount <= 0 && !WP.loc) //if we used our last wrapping paper, drop a cardboard tube new /obj/item/c_tube( get_turf(user) ) else to_chat(user, SPAN_NOTICE("You need more paper.")) else return ..() /obj/item/stack/package_wrap name = "package wrapper" icon = 'icons/obj/stacks/miscellaneous.dmi' icon_state = "deliveryPaper" singular_name = "package wrapper" flags = NOBLUDGEON amount = 25 max_amount = 25 resistance_flags = FLAMMABLE var/wrap_time = 2 SECONDS var/static/list/no_wrap = list(/obj/item/small_delivery, /obj/structure/big_delivery, /obj/item/evidencebag, /obj/structure/closet/body_bag, /obj/item/envelope) /obj/item/stack/package_wrap/pre_attack(atom/atom_target, mob/living/user, params) . = ..() if(!in_range(atom_target, user)) return if(!isobj(atom_target)) return var/obj/target = atom_target if(is_type_in_list(target, no_wrap)) return if(istype(target, /obj/item/stack/package_wrap) && user.a_intent != INTENT_HARM) return if(is_type_in_list(atom_target.loc, list(/obj/item/small_delivery, /obj/structure/big_delivery))) return if(target.anchored) return if(target in user) return if(isitem(target) && !(isstorage(target) && !istype(target,/obj/item/storage/box) && !istype(target, /obj/item/shipping_package))) var/obj/item/O = target if(!use(1)) return CONTINUE_ATTACK var/obj/item/small_delivery/P = new /obj/item/small_delivery(get_turf(O.loc)) //Aaannd wrap it up! if(!isturf(O.loc)) if(user.client) user.client.screen -= O P.wrapped = O O.loc = P var/i = round(O.w_class) if(i in list(1,2,3,4,5)) P.icon_state = "deliverycrate[i]" P.w_class = i P.add_fingerprint(user) O.add_fingerprint(user) add_fingerprint(user) else if(istype(target, /obj/structure/closet/crate)) var/obj/structure/big_delivery/D = wrap_closet(target, user) if(!D) return CONTINUE_ATTACK D.icon_state = "deliverycrate" else if(istype(target, /obj/structure/closet)) var/obj/structure/closet/C = target var/obj/structure/big_delivery/D = wrap_closet(target, user) if(!D) return CONTINUE_ATTACK D.init_welded = C.welded C.welded = TRUE else if(target.GetComponent(/datum/component/two_handed)) to_chat(user, SPAN_NOTICE("[target] is too unwieldy to wrap effectively.")) return CONTINUE_ATTACK else to_chat(user, SPAN_NOTICE("The object you are trying to wrap is unsuitable for the sorting machinery.")) return CONTINUE_ATTACK user.visible_message(SPAN_NOTICE("[user] wraps [target].")) user.create_attack_log("Has used [name] on [target]") add_attack_logs(user, target, "used [name]", ATKLOG_ALL) if(amount <= 0 && QDELETED(src)) //if we used our last wrapping paper, drop a cardboard tube var/obj/item/c_tube/T = new(get_turf(user)) user.put_in_active_hand(T) return CONTINUE_ATTACK // Separate proc to avoid copy pasting the code twice /obj/item/stack/package_wrap/proc/wrap_closet(obj/structure/closet/C, mob/user) if(C.opened) return if(amount < 3) to_chat(user, SPAN_WARNING("You need more paper.")) return if(user in C) to_chat(user, SPAN_WARNING("How do you plan to wrap it from the inside?")) return // Checking these again since it's after a delay var/wrap_do_after = wrap_time if(user.mind && HAS_TRAIT(user.mind, TRAIT_PACK_RAT)) wrap_do_after *= PACK_RAT_WRAP_SPEEDUP if(!do_after_once(user, wrap_do_after, target = C) || C.opened || !use(3)) return var/obj/structure/big_delivery/P = new(get_turf(C)) for(var/mob/living/stowaway in C) stowaway.forceMove(P) P.wrapped = C C.loc = P return P /obj/item/dest_tagger name = "destination tagger" desc = "Used to set the destination of properly wrapped packages." icon = 'icons/obj/device.dmi' icon_state = "dest_tagger" worn_icon_state = "electronic" inhand_icon_state = "electronic" w_class = WEIGHT_CLASS_TINY flags = CONDUCT slot_flags = ITEM_SLOT_BELT materials = list(MAT_METAL = 250, MAT_GLASS = 150) ///Value of the tag var/currTag = 1 //The whole system for the sort_type var is determined based on the order of this list, //disposals must always be 1, since anything that's untagged will automatically go to disposals, or sort_type = list(1) --Superxpdude var/datum/ui_module/destination_tagger/destination_tagger /obj/item/dest_tagger/Initialize(mapload) . = ..() destination_tagger = new(src) /obj/item/dest_tagger/Destroy() QDEL_NULL(destination_tagger) return ..() /obj/item/dest_tagger/attack_self__legacy__attackchain(mob/user) add_fingerprint(user) ui_interact(user) /obj/item/dest_tagger/ui_state(mob/user) return GLOB.default_state /obj/item/dest_tagger/ui_interact(mob/user, datum/tgui/ui = null) destination_tagger.ui_interact(user) /obj/machinery/disposal/delivery_chute name = "delivery chute" desc = "A chute for big and small packages alike!" icon_state = "intake" required_mode_to_deconstruct = 1 deconstructs_to = PIPE_DISPOSALS_CHUTE var/can_deconstruct = FALSE /obj/machinery/disposal/delivery_chute/Initialize(mapload) . = ..() trunk = locate() in loc if(trunk) trunk.linked = src // link the pipe trunk to self /obj/machinery/disposal/delivery_chute/interact() return /obj/machinery/disposal/delivery_chute/update() return /obj/machinery/disposal/delivery_chute/CanPass(atom/movable/mover, border_dir) // If the mover is a thrownthing passing through space, remove its thrown datum, // ingest it like normal, and mark the chute as not passible. // This prevents the mover from Entering the chute's turf // while also bypassing thrownthing's /finalize, which would // cause damage to the chute. if(mover.throwing && !has_gravity(get_turf(mover))) qdel(mover.throwing) Bumped(mover) return FALSE . = ..() /obj/machinery/disposal/delivery_chute/Bumped(atom/movable/AM) //Go straight into the chute if(isprojectile(AM) || is_ai(AM) || QDELETED(AM)) return // We may already contain the object because thrown objects // call CanPass which has a chance to immediately forceMove // them into us. if(AM.loc == src) flush() return switch(dir) if(NORTH) if(AM.loc.y != loc.y + 1) return if(EAST) if(AM.loc.x != loc.x + 1) return if(SOUTH) if(AM.loc.y != loc.y - 1) return if(WEST) if(AM.loc.x != loc.x - 1) return if(isobj(AM)) var/obj/O = AM O.loc = src else if(ismob(AM)) var/mob/M = AM M.loc = src flush() /obj/machinery/disposal/delivery_chute/flush() flushing = 1 flick("intake-closing", src) var/deliveryCheck = 0 var/obj/structure/disposalholder/H = new(src) // virtual holder object which actually // travels through the pipes. for(var/obj/structure/big_delivery/O in src) deliveryCheck = 1 for(var/obj/item/small_delivery/O in src) deliveryCheck = 1 for(var/obj/item/shipping_package/O in src) deliveryCheck = 1 if(!O.sealed) //unsealed shipping packages will default to disposals O.sortTag = 1 if(deliveryCheck == 0) H.destinationTag = 1 sleep(10) if(last_sound + DISPOSAL_SOUND_COOLDOWN < world.time) playsound(src, 'sound/machines/disposalflush.ogg', 50, FALSE, FALSE) last_sound = world.time sleep(5) // wait for animation to finish H.init(src) // copy the contents of disposer to holder air_contents = new() // The holder just took our gas; replace it H.start(src) // start the holder processing movement flushing = 0 // now reset disposal state flush = 0 if(mode == 2) // if was ready, mode = 1 // switch to charging update() return /obj/machinery/disposal/delivery_chute/screwdriver_act(mob/user, obj/item/I) . = TRUE if(!I.use_tool(src, user, 0, volume = I.tool_volume)) return can_deconstruct = !can_deconstruct to_chat(user, "You [can_deconstruct ? "unfasten": "fasten"] the screws around the power connection.") /obj/machinery/disposal/delivery_chute/welder_act(mob/user, obj/item/I) . = TRUE if(!can_deconstruct) return if(length(contents) > 0) to_chat(user, "Eject the items first!") return if(!I.tool_use_check(user, 0)) return WELDER_ATTEMPT_FLOOR_SLICE_MESSAGE if(I.use_tool(src, user, 20, volume = I.tool_volume)) WELDER_FLOOR_SLICE_SUCCESS_MESSAGE var/obj/structure/disposalconstruct/C = new (loc) C.ptype = deconstructs_to C.update() C.anchored = TRUE C.density = TRUE qdel(src) /obj/item/shipping_package name = "Shipping package" desc = "A pre-labeled package for shipping an item to coworkers." icon = 'icons/obj/boxes.dmi' icon_state = "shippack" var/obj/item/wrapped = null var/sortTag = 1 var/sealed = 0 /obj/item/shipping_package/attackby__legacy__attackchain(obj/item/O, mob/user, params) if(sealed) if(is_pen(O)) var/str = tgui_input_text(user, "Intended recipient?", "Address", max_length = MAX_NAME_LEN) if(!str || !length(str)) to_chat(user, SPAN_NOTICE("Invalid text.")) return user.visible_message(SPAN_NOTICE("[user] addresses [src] to [str].")) name = "Shipping package (RE: [str])" return if(wrapped) to_chat(user, SPAN_NOTICE("[src] already contains \a [wrapped].")) return if(isitem(O) && !isstorage(O) && !istype(O, /obj/item/shipping_package)) if(!user.canUnEquip(O)) to_chat(user, SPAN_WARNING("[O] is stuck to your hand, you cannot put it in [src]!")) return if(O.w_class > 3) to_chat(user, SPAN_NOTICE("[O] is too large to fit in [src].")) else wrapped = O user.transfer_item_to(O, src) O.add_fingerprint(usr) add_fingerprint(usr) to_chat(user, SPAN_NOTICE("You put [O] in [src].")) /obj/item/shipping_package/attack_self__legacy__attackchain(mob/user) if(sealed) to_chat(user, SPAN_NOTICE("You tear open [src], dropping the contents onto the floor.")) playsound(loc, 'sound/items/poster_ripped.ogg', 50, 1) user.unequip(src) wrapped.forceMove(get_turf(user)) wrapped = null qdel(src) else if(wrapped) switch(tgui_alert(user, "Select an action:", "Shipping", list("Remove Object", "Seal Package", "Cancel"))) if("Remove Object") to_chat(user, SPAN_NOTICE("You shake out [src]'s contents onto the floor.")) wrapped.forceMove(get_turf(user)) wrapped = null if("Seal Package") to_chat(user, SPAN_NOTICE("You seal [src], preparing it for delivery.")) icon_state = "shippack_sealed" sealed = 1 update_appearance(UPDATE_DESC) else if(tgui_alert(user, "Do you want to tear up the package?", "Shipping", list("Yes", "No")) == "Yes") to_chat(user, SPAN_NOTICE("You shred [src].")) playsound(loc, 'sound/items/poster_ripped.ogg', 50, 1) user.drop_item_to_ground(src) qdel(src) /obj/item/shipping_package/update_desc() . = ..() desc = "A pre-labeled package for shipping an item to coworkers." if(sortTag) desc += " The label says \"Deliver to [GLOB.TAGGERLOCATIONS[sortTag]]\"." if(!sealed) desc += " The package is not sealed." /obj/item/shipping_package/Destroy() QDEL_NULL(wrapped) return ..()