diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm
index 704da886685..936b18f35c5 100644
--- a/code/game/machinery/requests_console.dm
+++ b/code/game/machinery/requests_console.dm
@@ -8,14 +8,16 @@
//Request Console Screens
#define RCS_MAINMENU 0 // Main menu
-#define RCS_RQASSIST 1 // Request supplies
-#define RCS_RQSUPPLY 2 // Request assistance
+#define RCS_RQSUPPLY 1 // Request supplies
+#define RCS_RQASSIST 2 // Request assistance
#define RCS_SENDINFO 3 // Relay information
#define RCS_SENTPASS 4 // Message sent successfully
#define RCS_SENTFAIL 5 // Message sent unsuccessfully
#define RCS_VIEWMSGS 6 // View messages
#define RCS_MESSAUTH 7 // Authentication before sending
#define RCS_ANNOUNCE 8 // Send announcement
+#define RCS_SHIPPING 9 // Print Shipping Labels/Packages
+#define RCS_SHIP_LOG 10 // View Shipping Label Log
var/req_console_assistance = list()
var/req_console_supplies = list()
@@ -52,6 +54,10 @@ var/list/obj/machinery/requests_console/allConsoles = list()
var/priority = -1 ; //Priority of the message being sent
light_range = 0
var/datum/announcement/announcement = new
+ var/list/shipping_log = list()
+ var/ship_tag_name = ""
+ var/ship_tag_index = 0
+ var/print_cooldown = 0 //cooldown on shipping label printer, stores the in-game time of when the printer will next be ready
/obj/machinery/requests_console/power_change()
..()
@@ -128,6 +134,7 @@ var/list/obj/machinery/requests_console/allConsoles = list()
data["assist_dept"] = req_console_assistance
data["supply_dept"] = req_console_supplies
data["info_dept"] = req_console_information
+ data["ship_dept"] = TAGGERLOCATIONS
data["message"] = message
data["recipient"] = recipient
@@ -135,6 +142,8 @@ var/list/obj/machinery/requests_console/allConsoles = list()
data["msgStamped"] = msgStamped
data["msgVerified"] = msgVerified
data["announceAuth"] = announceAuth
+ data["shipDest"] = ship_tag_name
+ data["shipping_log"] = shipping_log
return data
@@ -182,7 +191,7 @@ var/list/obj/machinery/requests_console/allConsoles = list()
screen = RCS_SENTPASS
message_log += "Message sent to [recipient]
[message]"
else
- audible_message(text("[bicon(src)] *The Requests Console beeps: 'NOTICE: No server detected!'"),,4)
+ audible_message(text("[bicon(src)] *The Requests Console beeps: 'NOTICE: No server detected!'"),,4)
//Handle screen switching
if(href_list["setScreen"])
@@ -199,6 +208,26 @@ var/list/obj/machinery/requests_console/allConsoles = list()
reset_message()
screen = tempScreen
+ if(href_list["shipSelect"])
+ ship_tag_name = href_list["shipSelect"]
+ ship_tag_index = TAGGERLOCATIONS.Find(ship_tag_name)
+
+ //Handle Shipping Label Printing
+ if(href_list["printLabel"])
+ var/error_message = ""
+ if(!ship_tag_index)
+ error_message = "Please select a destination."
+ else if(!msgVerified)
+ error_message = "Please verify shipper ID."
+ else if(world.time < print_cooldown)
+ error_message = "Please allow the printer time to prepare the next shipping label."
+ if(error_message)
+ audible_message(text("[bicon(src)] *The Requests Console beeps: 'NOTICE: [error_message]'"),,4)
+ return
+ print_label(ship_tag_name, ship_tag_index)
+ shipping_log += "Shipping Label printed for [ship_tag_name]
[msgVerified]"
+ reset_message(1)
+
//Handle silencing the console
if(href_list["toggleSilent"])
silent = !silent
@@ -245,6 +274,10 @@ var/list/obj/machinery/requests_console/allConsoles = list()
reset_message()
to_chat(user, "You are not authorized to send announcements.")
updateUsrDialog()
+ if(screen == RCS_SHIPPING)
+ var/obj/item/weapon/card/id/T = O
+ msgVerified = text("Sender verified as [T.registered_name] ([T.assignment])")
+ updateUsrDialog()
if(istype(O, /obj/item/weapon/stamp))
if(inoperable(MAINT)) return
if(screen == RCS_MESSAUTH)
@@ -261,6 +294,8 @@ var/list/obj/machinery/requests_console/allConsoles = list()
msgStamped = ""
announceAuth = 0
announcement.announcer = ""
+ ship_tag_name = ""
+ ship_tag_index = 0
if(mainmenu)
screen = RCS_MAINMENU
@@ -286,3 +321,9 @@ var/list/obj/machinery/requests_console/allConsoles = list()
else // Normal
src.message_log += "From: [linkedSender]
[message]"
set_light(2)
+
+/obj/machinery/requests_console/proc/print_label(tag_name, tag_index)
+ var/obj/item/shippingPackage/sp = new /obj/item/shippingPackage(get_turf(src))
+ sp.sortTag = tag_index
+ sp.update_desc()
+ print_cooldown = world.time + 600 //1 minute cooldown before you can print another label, but you can still configure the next one during this time
diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm
index a2ed354657b..622fe780031 100644
--- a/code/modules/recycling/disposal.dm
+++ b/code/modules/recycling/disposal.dm
@@ -138,7 +138,8 @@
msg_admin_attack("[key_name_admin(user)] placed [key_name_admin(GM)] in a disposals unit. (JMP)")
return
- if(!I) return
+ if(!I)
+ return
if(!user.drop_item())
return
@@ -530,14 +531,18 @@
has_fat_guy = 1 // set flag on holder
if(istype(AM, /obj/structure/bigDelivery) && !hasmob)
var/obj/structure/bigDelivery/T = AM
- src.destinationTag = T.sortTag
+ destinationTag = T.sortTag
if(istype(AM, /obj/item/smallDelivery) && !hasmob)
var/obj/item/smallDelivery/T = AM
- src.destinationTag = T.sortTag
+ destinationTag = T.sortTag
//Drones can mail themselves through maint.
if(istype(AM, /mob/living/silicon/robot/drone))
var/mob/living/silicon/robot/drone/drone = AM
- src.destinationTag = drone.mail_destination
+ destinationTag = drone.mail_destination
+ if(istype(AM, /obj/item/shippingPackage) && !hasmob)
+ var/obj/item/shippingPackage/sp = AM
+ if(sp.sealed) //only sealed packages get delivered to their intended destination
+ destinationTag = sp.sortTag
// start the movement process
@@ -987,7 +992,7 @@
/obj/structure/disposalpipe/sortjunction
icon_state = "pipe-j1s"
- var/sortType = 0 //Look at the list called TAGGERLOCATIONS in setup.dm
+ var/sortType = 0 //Look at the list called TAGGERLOCATIONS in /code/_globalvars/lists/flavor_misc.dm
var/posdir = 0
var/negdir = 0
var/sortdir = 0
diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm
index dec76eaa5f0..a0e9d59a803 100755
--- a/code/modules/recycling/sortingmachinery.dm
+++ b/code/modules/recycling/sortingmachinery.dm
@@ -35,6 +35,16 @@
sortTag = O.currTag
playsound(loc, 'sound/machines/twobeep.ogg', 100, 1)
+ else if(istype(W, /obj/item/shippingPackage))
+ var/obj/item/shippingPackage/sp = W
+ if(sp.sealed)
+ return
+ else
+ sortTag = sp.sortTag
+ to_chat(user, "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(istype(W, /obj/item/weapon/pen))
var/str = copytext(sanitize(input(user,"Label text?","Set label","")),1,MAX_NAME_LEN)
if(!str || !length(str))
@@ -89,6 +99,16 @@
sortTag = O.currTag
playsound(loc, 'sound/machines/twobeep.ogg', 100, 1)
+ else if(istype(W, /obj/item/shippingPackage))
+ var/obj/item/shippingPackage/sp = W
+ if(sp.sealed)
+ return
+ else
+ sortTag = sp.sortTag
+ to_chat(user, "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(istype(W, /obj/item/weapon/pen))
var/str = copytext(sanitize(input(user,"Label text?","Set label","")),1,MAX_NAME_LEN)
if(!str || !length(str))
@@ -134,7 +154,7 @@
- if(istype(target, /obj/item) && !(istype(target, /obj/item/weapon/storage) && !istype(target,/obj/item/weapon/storage/box)))
+ if(istype(target, /obj/item) && !(istype(target, /obj/item/weapon/storage) && !istype(target,/obj/item/weapon/storage/box) && !istype(target, /obj/item/shippingPackage)))
var/obj/item/O = target
if(use(1))
var/obj/item/smallDelivery/P = new /obj/item/smallDelivery(get_turf(O.loc)) //Aaannd wrap it up!
@@ -235,101 +255,181 @@
var/c_mode = 0
- New()
- ..()
- spawn(5)
- trunk = locate() in src.loc
- if(trunk)
- trunk.linked = src // link the pipe trunk to self
+/obj/machinery/disposal/deliveryChute/New()
+ ..()
+ spawn(5)
+ trunk = locate() in src.loc
+ if(trunk)
+ trunk.linked = src // link the pipe trunk to self
- interact()
- return
+/obj/machinery/disposal/deliveryChute/interact()
+ return
- update()
- return
+/obj/machinery/disposal/deliveryChute/update()
+ return
- Bumped(var/atom/movable/AM) //Go straight into the chute
- if(istype(AM, /obj/item/projectile)) return
- switch(dir)
- if(NORTH)
- if(AM.loc.y != src.loc.y+1) return
- if(EAST)
- if(AM.loc.x != src.loc.x+1) return
- if(SOUTH)
- if(AM.loc.y != src.loc.y-1) return
- if(WEST)
- if(AM.loc.x != src.loc.x-1) return
+/obj/machinery/disposal/deliveryChute/Bumped(atom/movable/AM) //Go straight into the chute
+ if(istype(AM, /obj/item/projectile)) return
+ switch(dir)
+ if(NORTH)
+ if(AM.loc.y != src.loc.y+1) return
+ if(EAST)
+ if(AM.loc.x != src.loc.x+1) return
+ if(SOUTH)
+ if(AM.loc.y != src.loc.y-1) return
+ if(WEST)
+ if(AM.loc.x != src.loc.x-1) return
- if(istype(AM, /obj))
- var/obj/O = AM
- O.loc = src
- else if(istype(AM, /mob))
- var/mob/M = AM
- M.loc = src
- src.flush()
+ if(istype(AM, /obj))
+ var/obj/O = AM
+ O.loc = src
+ else if(istype(AM, /mob))
+ var/mob/M = AM
+ M.loc = src
+ src.flush()
- flush()
- flushing = 1
- flick("intake-closing", src)
- var/deliveryCheck = 0
- var/obj/structure/disposalholder/H = new() // virtual holder object which actually
+/obj/machinery/disposal/deliveryChute/flush()
+ flushing = 1
+ flick("intake-closing", src)
+ var/deliveryCheck = 0
+ var/obj/structure/disposalholder/H = new() // virtual holder object which actually
// travels through the pipes.
- for(var/obj/structure/bigDelivery/O in src)
- deliveryCheck = 1
- if(O.sortTag == 0)
- O.sortTag = 1
- for(var/obj/item/smallDelivery/O in src)
- deliveryCheck = 1
- if(O.sortTag == 0)
- O.sortTag = 1
- if(deliveryCheck == 0)
- H.destinationTag = 1
+ for(var/obj/structure/bigDelivery/O in src)
+ deliveryCheck = 1
+ if(O.sortTag == 0)
+ O.sortTag = 1
+ for(var/obj/item/smallDelivery/O in src)
+ deliveryCheck = 1
+ if(O.sortTag == 0)
+ O.sortTag = 1
+ for(var/obj/item/shippingPackage/O in src)
+ deliveryCheck = 1
+ if(!O.sealed || O.sortTag == 0) //unsealed or untagged shipping packages will default to disposals
+ O.sortTag = 1
+ if(deliveryCheck == 0)
+ H.destinationTag = 1
- sleep(10)
- playsound(src, 'sound/machines/disposalflush.ogg', 50, 0, 0)
- sleep(5) // wait for animation to finish
+ sleep(10)
+ playsound(src, 'sound/machines/disposalflush.ogg', 50, 0, 0)
+ 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()
+ 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/deliveryChute/attackby(obj/item/I, mob/user, params)
+ if(!I || !user)
return
- attackby(var/obj/item/I, var/mob/user, params)
- if(!I || !user)
+ if(istype(I, /obj/item/weapon/screwdriver))
+ if(c_mode==0)
+ c_mode=1
+ playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
+ to_chat(user, "You remove the screws around the power connection.")
+ return
+ else if(c_mode==1)
+ c_mode=0
+ playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
+ to_chat(user, "You attach the screws around the power connection.")
+ return
+ else if(istype(I,/obj/item/weapon/weldingtool) && c_mode==1)
+ var/obj/item/weapon/weldingtool/W = I
+ if(W.remove_fuel(0,user))
+ playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1)
+ to_chat(user, "You start slicing the floorweld off the delivery chute.")
+ if(do_after(user,20, target = src))
+ if(!src || !W.isOn()) return
+ to_chat(user, "You sliced the floorweld off the delivery chute.")
+ var/obj/structure/disposalconstruct/C = new (src.loc)
+ C.ptype = 8 // 8 = Delivery chute
+ C.update()
+ C.anchored = 1
+ C.density = 1
+ qdel(src)
+ return
+ else
+ to_chat(user, "You need more welding fuel to complete this task.")
return
- if(istype(I, /obj/item/weapon/screwdriver))
- if(c_mode==0)
- c_mode=1
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
- to_chat(user, "You remove the screws around the power connection.")
- return
- else if(c_mode==1)
- c_mode=0
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
- to_chat(user, "You attach the screws around the power connection.")
- return
- else if(istype(I,/obj/item/weapon/weldingtool) && c_mode==1)
- var/obj/item/weapon/weldingtool/W = I
- if(W.remove_fuel(0,user))
- playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1)
- to_chat(user, "You start slicing the floorweld off the delivery chute.")
- if(do_after(user,20, target = src))
- if(!src || !W.isOn()) return
- to_chat(user, "You sliced the floorweld off the delivery chute.")
- var/obj/structure/disposalconstruct/C = new (src.loc)
- C.ptype = 8 // 8 = Delivery chute
- C.update()
- C.anchored = 1
- C.density = 1
- qdel(src)
- return
- else
- to_chat(user, "You need more welding fuel to complete this task.")
+
+/obj/item/shippingPackage
+ name = "Shipping package"
+ desc = "A pre-labeled package for shipping an item to coworkers."
+ icon = 'icons/obj/storage.dmi'
+ icon_state = "shippack"
+ var/obj/item/wrapped = null
+ var/sortTag = 0
+ var/sealed = 0
+
+/obj/item/shippingPackage/attackby(obj/item/O, mob/user, params)
+ if(sealed)
+ if(istype(O, /obj/item/weapon/pen))
+ var/str = copytext(sanitize(input(user,"Intended recipient?","Address","")),1,MAX_NAME_LEN)
+ if(!str || !length(str))
+ to_chat(user, "Invalid text.")
return
+ user.visible_message("[user] addresses [src] to [str].")
+ name = "Shipping package (RE: [str])"
+ return
+ if(wrapped)
+ to_chat(user, "[src] already contains \a [wrapped].")
+ return
+ if(istype(O, /obj/item) && !istype(O, /obj/item/weapon/storage) && !istype(O, /obj/item/shippingPackage))
+ if(!user.canUnEquip(O))
+ to_chat(user, "[O] is stuck to your hand, you cannot put it in [src]!")
+ return
+ if(O.w_class > 3)
+ to_chat(user, "[O] is too large to fit in [src].")
+ else
+ wrapped = O
+ user.unEquip(O)
+ O.forceMove(src)
+ O.add_fingerprint(usr)
+ add_fingerprint(usr)
+ to_chat(user, "You put [O] in [src].")
+
+/obj/item/shippingPackage/attack_self(mob/user)
+ if(sealed)
+ to_chat(user, "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(alert("Select an action:",, "Remove Object", "Seal Package", "Cancel"))
+ if("Remove Object")
+ to_chat(user, "You shake out [src]'s contents onto the floor.")
+ wrapped.forceMove(get_turf(user))
+ wrapped = null
+ if("Seal Package")
+ to_chat(user, "You seal [src], preparing it for delivery.")
+ icon_state = "shippack_sealed"
+ sealed = 1
+ update_desc()
+ else
+ if(alert("Do you want to tear up the package?",, "Yes", "No") == "Yes")
+ to_chat(user, "You shred [src].")
+ playsound(loc, 'sound/items/poster_ripped.ogg', 50, 1)
+ user.unEquip(src)
+ qdel(src)
+
+/obj/item/shippingPackage/proc/update_desc()
+ desc = "A pre-labeled package for shipping an item to coworkers."
+ if(sortTag)
+ desc += " The label says \"Deliver to [TAGGERLOCATIONS[sortTag]]\"."
+ if(!sealed)
+ desc += " The package is not sealed."
+
+/obj/item/shippingPackage/Destroy()
+ if(wrapped)
+ qdel(wrapped)
+ wrapped = null
+ return ..()
\ No newline at end of file
diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi
index bd09b38dcd4..76286c26373 100644
Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ
diff --git a/nano/templates/request_console.tmpl b/nano/templates/request_console.tmpl
index 73a00c74471..aaa8726f50a 100644
--- a/nano/templates/request_console.tmpl
+++ b/nano/templates/request_console.tmpl
@@ -3,8 +3,8 @@ Title: Request Console
Used In File(s): \code\game\machinery\requests_console.dm
#define RCS_MAINMENU 0 // Main men
-#define RCS_RQASSIST 1 // Request supplies
-#define RCS_RQSUPPLY 2 // Request assistance
+#define RCS_RQSUPPLY 1 // Request supplies
+#define RCS_RQASSIST 2 // Request assistance
#define RCS_SENDINFO 3 // Relay information
#define RCS_SENTPASS 4 // Message sent successfully
#define RCS_SENTFAIL 5 // Message sent unsuccessfully
@@ -102,6 +102,33 @@ Used In File(s): \code\game\machinery\requests_console.dm
{{:helper.link('Announce', 'signal', { 'sendAnnouncement' : 1 }, (data.announceAuth && data.message) ? null : 'disabled' )}}
{{:helper.link('Back', 'arrow-left', { 'setScreen' : 0 })}}
+{{else data.screen == 9}}
+
{{:value}} - |
+ {{:helper.link('Select', null, { 'shipSelect' : value })}} |
+
There are no available shipping destinations. |