diff --git a/code/__HELPERS/vector.dm b/code/__HELPERS/vector.dm
index b697408a41..dff3cefead 100644
--- a/code/__HELPERS/vector.dm
+++ b/code/__HELPERS/vector.dm
@@ -1,44 +1,44 @@
// Basic geometry things.
-/vector/
+/datum/vector/
var/x = 0
var/y = 0
-/vector/New(var/x, var/y)
+/datum/vector/New(var/x, var/y)
src.x = x
src.y = y
-/vector/proc/duplicate()
- return new /vector(x, y)
+/datum/vector/proc/duplicate()
+ return new /datum/vector(x, y)
-/vector/proc/euclidian_norm()
+/datum/vector/proc/euclidian_norm()
return sqrt(x*x + y*y)
-/vector/proc/squared_norm()
+/datum/vector/proc/squared_norm()
return x*x + y*y
-/vector/proc/normalize()
+/datum/vector/proc/normalize()
var/norm = euclidian_norm()
x = x/norm
y = y/norm
return src
-/vector/proc/chebyshev_norm()
+/datum/vector/proc/chebyshev_norm()
return max(abs(x), abs(y))
-/vector/proc/chebyshev_normalize()
+/datum/vector/proc/chebyshev_normalize()
var/norm = chebyshev_norm()
x = x/norm
y = y/norm
return src
-/vector/proc/is_integer()
+/datum/vector/proc/is_integer()
return ISINTEGER(x) && ISINTEGER(y)
-/atom/movable/proc/vector_translate(var/vector/V, var/delay)
+/atom/movable/proc/datum/vector_translate(var/datum/vector/V, var/delay)
var/turf/T = get_turf(src)
var/turf/destination = locate(T.x + V.x, T.y + V.y, z)
- var/vector/V_norm = V.duplicate()
+ var/datum/vector/V_norm = V.duplicate()
V_norm.chebyshev_normalize()
if (!V_norm.is_integer())
return
@@ -49,9 +49,9 @@
T = get_turf(src)
sleep(delay + world.tick_lag) // Shortest possible time to sleep
-/atom/proc/get_translated_turf(var/vector/V)
+/atom/proc/get_translated_turf(var/datum/vector/V)
var/turf/T = get_turf(src)
return locate(T.x + V.x, T.y + V.y, z)
/proc/atoms2vector(var/atom/A, var/atom/B)
- return new /vector((B.x - A.x), (B.y - A.y)) // Vector from A -> B
\ No newline at end of file
+ return new /datum/vector((B.x - A.x), (B.y - A.y)) // Vector from A -> B
\ No newline at end of file
diff --git a/code/datums/action.dm b/code/datums/action.dm
index 8659a9e7c4..66a2e4b0ec 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -756,3 +756,11 @@
target.layer = old_layer
target.plane = old_plane
current_button.appearance_cache = target.appearance
+
+/proc/get_action_of_type(mob/M, var/action_type)
+ if(!M.actions || !ispath(action_type, /datum/action))
+ return
+ for(var/datum/action/A in M.actions)
+ if(istype(A, action_type))
+ return A
+ return
\ No newline at end of file
diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm
index fd0fd8a718..9ac81b821e 100644
--- a/code/modules/food_and_drinks/drinks/drinks.dm
+++ b/code/modules/food_and_drinks/drinks/drinks.dm
@@ -139,58 +139,57 @@
/obj/item/reagent_containers/food/drinks/MouseDrop(atom/over, atom/src_location, atom/over_location, src_control, over_control, params)
var/mob/user = usr
+ . = ..()
if (!istype(src_location))
return
- if (!user || user.incapacitated())
+ if (!user || user.incapacitated() || !user.Adjacent(src))
return
// Attempted drink sliding
- if (locate(/obj/structure/table) in src_location)
- //Are we an expert slider?
- for(var/datum/action/innate/drink_fling/D in user.actions)
- if(D.active)
- if (!user.Adjacent(src))
- return
- var/distance = MANHATTAN_DISTANCE(over_location, src)
- if (distance >= 8 || distance == 0) // More than a full screen to go, or trying to slide to the same tile
- return ..()
+ if (!locate(/obj/structure/table) in src_location)
+ return
+ //Are we an expert slider?
+ var/datum/action/innate/D = get_action_of_type(user, /datum/action/innate/drink_fling)
+ if(D.active)
+ var/distance = MANHATTAN_DISTANCE(over_location, src)
+ if (distance >= 8 || distance == 0) // More than a full screen to go, or trying to slide to the same tile
+ return
- // Geometrically checking if we're on a straight line.
- var/vector/V = atoms2vector(src, over_location)
- var/vector/V_norm = V.duplicate()
- V_norm.normalize()
- if (!V_norm.is_integer())
- return ..() // Only a cardinal vector (north, south, east, west) can pass this test
+ // Geometrically checking if we're on a straight line.
+ var/datum/vector/V = atoms2vector(src, over_location)
+ var/datum/vector/V_norm = V.duplicate()
+ V_norm.normalize()
+ if (!V_norm.is_integer())
+ return // Only a cardinal vector (north, south, east, west) can pass this test
- // Checks if there's tables on the path.
- var/turf/dest = get_translated_turf(V)
- var/turf/temp_turf = src_location
+ // Checks if there's tables on the path.
+ var/turf/dest = get_translated_turf(V)
+ var/turf/temp_turf = src_location
- do
- temp_turf = temp_turf.get_translated_turf(V_norm)
- if (!locate(/obj/structure/table) in temp_turf)
- var/vector/V2 = atoms2vector(src, temp_turf)
- vector_translate(V2, 0.1 SECONDS)
- user.visible_message("\The [user] slides \the [src] down the table... and straight into the ground!", "You slide \the [src] down the table, and straight into the ground!")
- smash(over_location, user, FALSE)
- return
- while (temp_turf != dest)
-
- vector_translate(V, 0.1 SECONDS)
- user.visible_message("\The [user] expertly slides \the [src] down the table.", "You slide \the [src] down the table. What a pro.")
+ do
+ temp_turf = temp_turf.get_translated_turf(V_norm)
+ if (!locate(/obj/structure/table) in temp_turf)
+ var/datum/vector/V2 = atoms2vector(src, temp_turf)
+ vector_translate(V2, 0.1 SECONDS)
+ user.visible_message("\The [user] slides \the [src] down the table... and straight into the ground!", "You slide \the [src] down the table, and straight into the ground!")
+ smash(over_location, user, FALSE)
return
- else
- if (!(locate(/obj/structure/table) in over_location))
- return ..()
- if (!user.Adjacent(src) || !src_location.Adjacent(over_location)) // Regular users can only do short slides.
- return ..()
- if (prob(10))
- user.visible_message("\The [user] tries to slide \the [src] down the table, but fails miserably.", "You fail to slide \the [src] down the table!")
- smash(over_location, user, FALSE)
- return
- user.visible_message("\The [user] slides \the [src] down the table.", "You slide \the [src] down the table!")
- forceMove(over_location)
- return
- return ..()
+ while (temp_turf != dest)
+
+ vector_translate(V, 0.1 SECONDS)
+ user.visible_message("\The [user] expertly slides \the [src] down the table.", "You slide \the [src] down the table. What a pro.")
+ return
+ else
+ if (!(locate(/obj/structure/table) in over_location))
+ return
+ if (!user.Adjacent(src) || !src_location.Adjacent(over_location)) // Regular users can only do short slides.
+ return
+ if (prob(10))
+ user.visible_message("\The [user] tries to slide \the [src] down the table, but fails miserably.", "You fail to slide \the [src] down the table!")
+ smash(over_location, user, FALSE)
+ return
+ user.visible_message("\The [user] slides \the [src] down the table.", "You slide \the [src] down the table!")
+ forceMove(over_location)
+ return
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index b254c6298e..236f2c4a56 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -107,9 +107,9 @@
var/turf/T = get_turf(src)
if(!T || !target.CanPass(src, T) || !thrownby || !thrownby.actions)
return
- for(var/datum/action/innate/drink_fling/D in thrownby.actions)
- if(D.active)
- return TRUE
+ var/datum/action/innate/D = get_action_of_type(thrownby, /datum/action/innate/drink_fling)
+ if(D.active)
+ return TRUE
/obj/item/reagent_containers/proc/ForceResetRotation()
transform = initial(transform)