diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index 0902bd3871..4673d0ef26 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -339,3 +339,9 @@ var/list/mob/living/forced_ambiance_list = new
/area/proc/shuttle_departed()
return TRUE
+
+/area/AllowDrop()
+ CRASH("Bad op: area/AllowDrop() called")
+
+/area/drop_location()
+ CRASH("Bad op: area/drop_location() called")
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index dba0ec67ab..c994aff121 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -502,3 +502,12 @@
if(A && A.has_gravity())
return TRUE
return FALSE
+
+/atom/proc/drop_location()
+ var/atom/L = loc
+ if(!L)
+ return null
+ return L.AllowDrop() ? L : get_turf(L)
+
+/atom/proc/AllowDrop()
+ return FALSE
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 3ae19b1e4f..0cd09b8a57 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -296,7 +296,3 @@
/atom/movable/proc/adjust_scale(new_scale)
icon_scale = new_scale
update_transform()
-
-// Stub for now, override with better things.
-/atom/movable/proc/drop_location()
- return loc
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm
index 799169bad5..e85982ea80 100644
--- a/code/game/objects/items/weapons/storage/storage.dm
+++ b/code/game/objects/items/weapons/storage/storage.dm
@@ -723,4 +723,7 @@
..()
if(open && contents.len)
var/display_item = contents[1]
- to_chat(user, "\The [src] contains \the [display_item]!")
\ No newline at end of file
+ to_chat(user, "\The [src] contains \the [display_item]!")
+
+/obj/item/weapon/storage/AllowDrop()
+ return TRUE
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index a9fc515e3b..c0303d8753 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -416,3 +416,6 @@
/obj/structure/closet/onDropInto(var/atom/movable/AM)
return
+
+/obj/structure/closet/AllowDrop()
+ return TRUE
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 2f1fdda438..798ad0e81c 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -280,3 +280,6 @@ var/const/enterloopsanity = 100
if(isliving(AM))
var/mob/living/M = AM
M.turf_collision(src, speed)
+
+/turf/AllowDrop()
+ return TRUE
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index 439aed4ec7..612f34bc83 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -209,7 +209,7 @@ var/list/slot_equipment_priority = list( \
if(target)
I.forceMove(target)
else
- I.dropInto(loc)
+ I.dropInto(drop_location())
I.dropped(src)
return 1