From 811ccaa273673309b7b3b23eebb4d63427f95255 Mon Sep 17 00:00:00 2001 From: FalseIncarnate Date: Sun, 15 Jan 2017 05:13:17 -0500 Subject: [PATCH] NTPS: Requests Console Based Shipping Ever been stuck in your office and thought "Wow, I really could go for a burger, but the kitchen doesn't deliver." or "I'm too lazy and/or scared to go to science to ask for a new circuitboard in person."? Introducing NTPS: NanoTrasen Priority Shipping! All requests consoles have been upgraded with a brand new printer, capable of producing pre-tagged, single-use, single-object shipping packages for crew use! Chefs can send burgers to distant diners, or science can package up that brand new circuitboard you've been harassing them for and send it straight to you! But what if you have a larger parcel you want to ship, but don't have access to cargo's coveted destination tagger? Have no fear, simply slap the empty shipping package onto the parcel to give tag it just like cargo! But wait, there's more! Use a pen on any sealed shipping package and you can include the name of your intended recipient on the package! Now, when a coworker steals their mail, at least they will know it! This PR adds the ability for all requests console to print off Shipping Packages that come pre-tagged for a destination of your choosing. Each package can hold a single item of normal or smaller size (no storage containers, so you can't stick a bag or box in them). Once filled, simply activate the package in hand to either dump out the item (in case you put the wrong thing in) or seal the box for shipping. A sealed box can then be further addressed with a pen, and dropped into any disposal bin to start the delivery process (assuming it's connected to the standard loop). Unsealed boxes will be delivered to disposals by way of the cargo mail room, so make sure you seal it or hope that cargo is kind enough to seal and resend it for you! If you have a wrapped parcel (wrapped with packaging paper), you can also affix an empty shipping container to the parcel to tag it yourself with the destination of the shipping package, just in case cargo accidentally sent that virus crate to the wrong person! --- code/game/machinery/requests_console.dm | 47 +++- code/modules/recycling/disposal.dm | 15 +- code/modules/recycling/sortingmachinery.dm | 256 ++++++++++++++------- nano/templates/request_console.tmpl | 34 ++- 4 files changed, 256 insertions(+), 96 deletions(-) diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index 704da886685..5645ac54c3c 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.desc += " The label says \"Deliver to [tag_name]\"." + 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 6691df19a1d..1867f0a8a0f 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 7f7b3bfbb45..4e808c362df 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,165 @@ 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 = "idOld" + var/obj/item/wrapped = null + var/sortTag = 0 + var/sealed = 0 + var/original_name = "Shipping package" + +/obj/item/shippingPackage/attackby(obj/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 = "[original_name] (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)) + var/obj/item/I = O + if(I.w_class > 3) + to_chat(user, "[I] is too large to fit in [src].") + else + wrapped = I + user.unEquip(I) + I.forceMove(src) + I.add_fingerprint(usr) + add_fingerprint(usr) + to_chat(user, "You put [I] 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.") + sealed = 1 + 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) diff --git a/nano/templates/request_console.tmpl b/nano/templates/request_console.tmpl index 1005f583ec8..eb4f71c6236 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}} +

Print a Shipping Label.

+
+
Destination: {{:data.shipDest}}
+
Validated by: {{:data.msgVerified}}
+
{{:helper.link('Print Label', null, { 'printLabel' : 1 })}}
+
+ + {{for data.ship_dept}} + + + + + {{empty}} + + {{/for}} +
{{:value}} -
{{:helper.link('Select', null, { 'shipSelect' : value })}}
There are no available shipping destinations.

+
{{:helper.link('Back', 'arrow-left', { 'setScreen' : 0 })}}
+{{else data.screen == 10}} +
+ {{for data.shipping_log}} +
{{:value}}
+ {{empty}} +
No shipping labels have been printed.
+ {{/for}} +
+
{{:helper.link('Back', 'arrow-left', { 'setScreen' : 0 })}}
{{else}} {{if data.newmessagepriority == 1}}
There are new messages
@@ -114,6 +141,9 @@ Used In File(s): \code\game\machinery\requests_console.dm
{{:helper.link('Request Supplies', 'gear', { 'setScreen' : 2 })}}
{{:helper.link('Relay Anonymous Information', 'gear', { 'setScreen' : 3})}}

+
{{:helper.link('Print Shipping Label', 'gear', { 'setScreen' : 9})}}
+
{{:helper.link('View Shipping Logs', 'gear', { 'setScreen' : 10})}}
+
{{if data.announcementConsole}}
{{:helper.link('Send Station-wide Announcement', 'signal', { 'setScreen' : 8})}}