diff --git a/code/game/objects/items/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm
index 9558fecc808..afd0eeef956 100644
--- a/code/game/objects/items/circuitboards/computer_circuitboards.dm
+++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm
@@ -188,21 +188,33 @@
build_path = /obj/machinery/computer/cargo
var/contraband = FALSE
-/obj/item/circuitboard/computer/cargo/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/device/multitool))
- if(!emagged)
- contraband = !contraband
- to_chat(user, "Receiver spectrum set to [contraband ? "Broad" : "Standard"].")
- else
- to_chat(user, "The spectrum chip is unresponsive.")
- else if(istype(I, /obj/item/card/emag))
- if(!emagged)
- contraband = TRUE
- emagged = TRUE
- to_chat(user, "You adjust [src]'s routing and receiver spectrum, unlocking special supplies and contraband.")
+/obj/item/circuitboard/computer/cargo/multitool_act(mob/living/user)
+ if(!emagged)
+ contraband = !contraband
+ to_chat(user, "Receiver spectrum set to [contraband ? "Broad" : "Standard"].")
else
- return ..()
+ to_chat(user, "The spectrum chip is unresponsive.")
+/obj/item/circuitboard/computer/cargo/emag_act(mob/living/user)
+ if(!emagged)
+ contraband = TRUE
+ emagged = TRUE
+ to_chat(user, "You adjust [src]'s routing and receiver spectrum, unlocking special supplies and contraband.")
+
+/obj/item/circuitboard/computer/cargo/express
+ name = "Express Supply Console (Computer Board)"
+ build_path = /obj/machinery/computer/cargo/express
+
+/obj/item/circuitboard/computer/cargo/express/multitool_act(mob/living/user)
+ if (!emagged)
+ to_chat(user, "Routing protocols are already set to: \"factory defaults\".")
+ else
+ to_chat(user, "You reset the routing protocols to: \"factory defaults\".")
+ emagged = FALSE
+
+/obj/item/circuitboard/computer/cargo/express/emag_act(mob/living/user)
+ to_chat(user, "You change the routing protocols, allowing the Drop Pod to land anywhere on the station.")
+ emagged = TRUE
/obj/item/circuitboard/computer/cargo/request
name = "Supply Request Console (Computer Board)"
diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm
index a2b1ce20568..9445cd73a63 100644
--- a/code/game/objects/items/devices/multitool.dm
+++ b/code/game/objects/items/devices/multitool.dm
@@ -18,6 +18,7 @@
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
force = 5
w_class = WEIGHT_CLASS_SMALL
+ tool_behaviour = TOOL_MULTITOOL
throwforce = 0
throw_range = 7
throw_speed = 3
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index d46978f4b0c..b471e030612 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -132,7 +132,7 @@
if(opened || !can_open(user))
return
playsound(loc, open_sound, 15, 1, -3)
- opened = 1
+ opened = TRUE
if(!dense_when_open)
density = FALSE
climb_time *= 0.5 //it's faster to climb onto an open thing
@@ -185,7 +185,7 @@
take_contents()
playsound(loc, close_sound, 15, 1, -3)
climb_time = initial(climb_time)
- opened = 0
+ opened = FALSE
density = TRUE
update_icon()
return 1
@@ -206,6 +206,8 @@
bust_open()
/obj/structure/closet/attackby(obj/item/W, mob/user, params)
+ if (istype(src, /obj/structure/closet/bsdroppod))
+ return ..()//dont wanna do anything if you're a drop pod
if(user in src)
return
if(opened)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/bsdroppod.dm b/code/game/objects/structures/crates_lockers/closets/secure/bsdroppod.dm
new file mode 100644
index 00000000000..dd89e708de9
--- /dev/null
+++ b/code/game/objects/structures/crates_lockers/closets/secure/bsdroppod.dm
@@ -0,0 +1,89 @@
+//The "BDPtarget" temp visual is created by the expressconsole, which in turn makes two things: a falling droppod animation, and the droppod itself.
+
+
+//------------------------------------BLUESPACE DROP POD-------------------------------------//
+/obj/structure/closet/bsdroppod
+ name = "Bluespace Drop Pod"
+ desc = "A Nanotrasen supply drop pod."
+ icon = 'icons/obj/2x2.dmi'
+ icon_state = "BDP"
+ pixel_x = -16//2x2 sprite
+ pixel_y = -5
+ layer = TABLE_LAYER//so that the crate inside doesn't appear underneath
+ allow_objects = TRUE
+ allow_dense = TRUE
+ delivery_icon = null
+ can_weld_shut = FALSE
+ armor = list("melee" = 30, "bullet" = 50, "laser" = 50, "energy" = 100, "bomb" = 90, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80)
+ anchored = TRUE
+ anchorable = FALSE
+ var/datum/supply_order/SupplyOrder
+
+/obj/structure/closet/bsdroppod/Initialize(mapload, datum/supply_order/so)
+ . = ..()
+ SupplyOrder = so//uses Supply Order passed from expressconsole into BDPtarget
+ addtimer(CALLBACK(src, .proc/open), 30)//open 3seconds after appearing
+
+/obj/structure/closet/bsdroppod/update_icon()
+ cut_overlays()
+ if (opened)
+ add_overlay("BDP_open")
+ else
+ add_overlay("BDP_door")
+
+/obj/structure/closet/bsdroppod/toggle(mob/living/user)
+ return
+
+/obj/structure/closet/bsdroppod/open()
+ var/turf/T = get_turf(src)
+ opened = TRUE
+ SupplyOrder.generate(T)//not called during populateContents as supplyorder generation requires a turf
+ update_icon()
+ playsound(src, open_sound, 15, 1, -3)
+ addtimer(CALLBACK(src, .proc/sparks), 30)//3 seconds after opening, make some sparks and delete
+
+/obj/structure/closet/bsdroppod/proc/sparks()//sparks cant be called from addtimer
+ do_sparks(5, TRUE, src)
+ qdel(src)//no need for QDEL_IN if we already have a timer
+
+/obj/structure/closet/bsdroppod/Destroy()//make some sparks b4 deletion
+ QDEL_NULL(SupplyOrder)
+ return ..()
+
+//------------------------------------FALLING BLUESPACE DROP POD-------------------------------------//
+/obj/effect/temp_visual/BDPfall
+ icon = 'icons/obj/2x2.dmi'
+ icon_state = "BDP_falling"
+ pixel_x = -16
+ pixel_y = -5
+ pixel_z = 200
+ name = "Bluespace Drop Pod"
+ desc = "Get out of the way!"
+ layer = FLY_LAYER//that wasnt flying, that was falling with style!
+ randomdir = FALSE
+
+//------------------------------------TEMPORARY_VISUAL-------------------------------------//
+/obj/effect/BDPtarget
+ icon = 'icons/mob/actions/actions_items.dmi'
+ icon_state = "sniper_zoom"
+ layer = PROJECTILE_HIT_THRESHHOLD_LAYER
+ light_range = 2
+ var/obj/effect/temp_visual/fallingPod
+
+/obj/effect/BDPtarget/Initialize(mapload, datum/supply_order/SO)
+ . = ..()
+ addtimer(CALLBACK(src, .proc/beginLaunch, SO), 30)//wait 3 seconds
+
+/obj/effect/BDPtarget/proc/beginLaunch(datum/supply_order/SO)
+ fallingPod = new /obj/effect/temp_visual/BDPfall(drop_location())
+ animate(fallingPod, pixel_z = 0, time = 3, easing = LINEAR_EASING)//make and animate a falling pod
+ addtimer(CALLBACK(src, .proc/endLaunch, SO), 3, TIMER_CLIENT_TIME)//fall 0.3seconds
+
+/obj/effect/BDPtarget/proc/endLaunch(datum/supply_order/SO)
+ explosion(src,0,0,2, flame_range = 2) //explosion and camshake (shoutout to @cyberboss)
+ new /obj/structure/closet/bsdroppod(drop_location(), SO)//pod is created
+ qdel(src)
+
+/obj/effect/BDPtarget/Destroy()
+ QDEL_NULL(fallingPod)//delete falling pod after animation's over
+ return ..()
\ No newline at end of file
diff --git a/code/modules/cargo/expressconsole.dm b/code/modules/cargo/expressconsole.dm
new file mode 100644
index 00000000000..60be1e83494
--- /dev/null
+++ b/code/modules/cargo/expressconsole.dm
@@ -0,0 +1,125 @@
+/obj/machinery/computer/cargo/express
+ name = "express supply console"
+ desc = "This console allows the user to purchase a package for double the price,\
+ with 1/40th of the delivery time: made possible by NanoTrasen's new \"Drop Pod Railgun\".\
+ All sales are near instantaneous - please choose carefully"
+ icon_screen = "supply_express"
+ circuit = /obj/item/circuitboard/computer/cargo/express
+ blockade_warning = "Bluespace instability detected. Delivery impossible."
+ req_access = list(ACCESS_QM)
+ var/message
+ var/locked = TRUE
+
+
+/obj/machinery/computer/cargo/express/attackby(obj/item/W, mob/living/user, params)
+ ..()
+ if((istype(W, /obj/item/card/id) || istype(W, /obj/item/device/pda)) && allowed(user))
+ locked = !locked
+ to_chat(user, "You [locked ? "lock" : "unlock"] the interface.")
+
+/obj/machinery/computer/cargo/express/emag_act(mob/living/user)
+ if(emagged)
+ return
+ user.visible_message("[user] swipes a suspicious card through [src]!",
+ "You change the routing protocols, allowing the Drop Pod to land anywhere on the station.")
+ emagged = TRUE
+ // This also sets this on the circuit board
+ var/obj/item/circuitboard/computer/cargo/board = circuit
+ board.emagged = TRUE
+
+/obj/machinery/computer/cargo/express/ui_interact(mob/living/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) // Remember to use the appropriate state.
+ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "cargo_express", name, 1000, 800, master_ui, state)
+ ui.open()
+
+
+/obj/machinery/computer/cargo/express/ui_data(mob/user)
+ var/list/data = list()
+ data["locked"] = locked
+ data["siliconUser"] = user.has_unlimited_silicon_privilege
+ data["points"] = SSshuttle.points
+ data["supplies"] = list()
+ message = "For normally priced items, please use the standard Supply or Request Console. \
+ Sales are near-instantaneous - please choose carefully."
+ if(SSshuttle.supplyBlocked)
+ message = blockade_warning
+ if(emagged)
+ message = "(&!#@ERROR: ROUTING_#PROTOCOL MALF(*CT#ON. $UG%ESTE@ ACT#0N: !^/PULS3-%E)ET CIR*)ITB%ARD."
+
+ data["message"] = message
+
+ if (emagged)
+ for(var/pack in SSshuttle.supply_packs)
+ var/datum/supply_pack/P = SSshuttle.supply_packs[pack]
+ if (P.name == "Toy Crate")//Can only order toys if emagged. You gotta spend 10K points to crash a droppod somewhere on the station
+ data["supplies"][P.group] = list(
+ "name" = P.group,
+ "packs" = list()
+ )
+ data["supplies"][P.group]["packs"] += list(list(
+ "name" = P.name,
+ "cost" = P.cost * 2, //displays twice the normal cost
+ "id" = pack
+ ))
+ else
+ for(var/pack in SSshuttle.supply_packs)
+ var/datum/supply_pack/P = SSshuttle.supply_packs[pack]
+ if(!data["supplies"][P.group])
+ data["supplies"][P.group] = list(
+ "name" = P.group,
+ "packs" = list()
+ )
+ if((P.hidden) || (P.contraband) || (P.special))//no fun allowed
+ continue
+ data["supplies"][P.group]["packs"] += list(list(
+ "name" = P.name,
+ "cost" = P.cost * 2, //displays twice the normal cost
+ "id" = pack
+ ))
+
+ return data
+
+/obj/machinery/computer/cargo/express/ui_act(action, params, datum/tgui/ui)
+ switch(action)
+ if("add")//Generate Supply Order first
+ var/id = text2path(params["id"])
+ var/datum/supply_pack/pack = SSshuttle.supply_packs[id]
+ if(!istype(pack))
+ return
+ var/name = "*None Provided*"
+ var/rank = "*None Provided*"
+ var/ckey = usr.ckey
+ if(ishuman(usr))
+ var/mob/living/carbon/human/H = usr
+ name = H.get_authentification_name()
+ rank = H.get_assignment()
+ else if(issilicon(usr))
+ name = usr.real_name
+ rank = "Silicon"
+ var/reason = ""
+
+
+ var/datum/supply_order/SO = new(pack, name, rank, ckey, reason)
+ if(SO.pack.cost* 2 <= SSshuttle.points) //If you can afford it, then begin the delivery
+ SO.generateRequisition(get_turf(src))
+ SSshuttle.points -= SO.pack.cost * 2//twice the normal cost
+
+ var/list/empty_turfs = list()
+ var/area/landingzone
+
+ if (!emagged)
+ landingzone = locate(/area/quartermaster/storage) in GLOB.sortedAreas
+ else
+ landingzone = locate(pick(GLOB.the_station_areas)) in GLOB.sortedAreas
+
+ for(var/turf/open/floor/T in landingzone.contents) //get all the turfs in cargo bay
+ if(is_blocked_turf(T))//wont land on a blocked turf
+ continue
+ empty_turfs.Add(T)
+
+ if (empty_turfs.len != 0 )
+ var/LZ = empty_turfs[rand(empty_turfs.len-1)]//pick a random turf
+ new /obj/effect/BDPtarget(LZ, SO)//where the magic happens. this temp visual makes the actual droppod after a pause
+ . = TRUE
+ update_icon()
\ No newline at end of file
diff --git a/code/modules/research/designs/comp_board_designs.dm b/code/modules/research/designs/comp_board_designs.dm
index 7e743a396be..e5593ff7a61 100644
--- a/code/modules/research/designs/comp_board_designs.dm
+++ b/code/modules/research/designs/comp_board_designs.dm
@@ -194,7 +194,7 @@
id = "cargorequest"
build_path = /obj/item/circuitboard/computer/cargo/request
category = list("Computer Boards")
-
+
/datum/design/board/stockexchange
name = "Computer Design (Stock Exchange Console)"
desc = "Allows for the construction of circuit boards used to build a Stock Exchange Console."
diff --git a/code/modules/research/designs/mining_designs.dm b/code/modules/research/designs/mining_designs.dm
index 8b193577e0d..d4c716f1254 100644
--- a/code/modules/research/designs/mining_designs.dm
+++ b/code/modules/research/designs/mining_designs.dm
@@ -2,6 +2,16 @@
/////////////////////////////////////////
/////////////////Mining//////////////////
/////////////////////////////////////////
+/datum/design/cargo_express
+ name = "Computer Design (Express Supply Console)"//shes beautiful
+ desc = "Allows for the construction of circuit boards used to build an Express Supply Console."//who?
+ id = "cargoexpress"//the coder reading this
+ build_type = PROTOLATHE
+ materials = list(MAT_GLASS = 1000)
+ reagents_list = list("sacid" = 20)
+ build_path = /obj/item/circuitboard/computer/cargo/express
+ category = list("Mining Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_CARGO
/datum/design/drill
name = "Mining Drill"
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index ba43a1c24b5..ca7616db896 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -424,7 +424,7 @@
display_name = "Mining Technology"
description = "Better than Efficiency V."
prereq_ids = list("engineering")
- design_ids = list("drill", "superresonator", "triggermod", "damagemod", "cooldownmod", "rangemod", "ore_redemption", "mining_equipment_vendor")
+ design_ids = list("drill", "superresonator", "triggermod", "damagemod", "cooldownmod", "rangemod", "ore_redemption", "mining_equipment_vendor", "cargoexpress")//e a r l y g a m e)
research_cost = 2500
export_price = 10000
diff --git a/icons/obj/2x2.dmi b/icons/obj/2x2.dmi
index 3a4fa139af3..21adc379e93 100644
Binary files a/icons/obj/2x2.dmi and b/icons/obj/2x2.dmi differ
diff --git a/icons/obj/computer.dmi b/icons/obj/computer.dmi
index fb1ae63b4e5..2095bf6d250 100644
Binary files a/icons/obj/computer.dmi and b/icons/obj/computer.dmi differ
diff --git a/tgui/src/interfaces/cargo_express.ract b/tgui/src/interfaces/cargo_express.ract
new file mode 100644
index 00000000000..4df45173109
--- /dev/null
+++ b/tgui/src/interfaces/cargo_express.ract
@@ -0,0 +1,43 @@
+
+
+
+
+ {{#if data.siliconUser }}
+
+ {{data.locked ? "Engaged" : "Disengaged"}}
+
+ {{else}}
+ Swipe a QM-Level ID card to {{data.locked ? "unlock" : "lock"}} this interface.
+ {{/if}}
+
+
+{{#if !data.locked }}
+
+
+ {{Math.floor(adata.points)}}
+
+
+
+ {{data.message}}
+
+
+
+ {{#each data.supplies}}
+
+ {{#each packs}}
+
+ {{cost}} Credits (Premium Pricing)
+
+ {{/each}}
+
+ {{/each}}
+
+{{/if}}
\ No newline at end of file