diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 7c1f02d049d..0a0a3d78f80 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -16,6 +16,8 @@
var/no_spin_thrown = 0
var/moved_recently = 0
var/mob/pulledby = null
+ var/atom/movable/pulling
+ var/canmove = 1
var/inertia_dir = 0
var/atom/inertia_last_loc
@@ -58,6 +60,62 @@
pulledby = null
return ..()
+/atom/movable/proc/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE)
+ if(QDELETED(AM))
+ return FALSE
+ if(!(AM.can_be_pulled(src, state, force)))
+ return FALSE
+
+ // If we're pulling something then drop what we're currently pulling and pull this instead.
+ if(pulling)
+ if(state == 0)
+ stop_pulling()
+ return FALSE
+ // Are we trying to pull something we are already pulling? Then enter grab cycle and end.
+ if(AM == pulling)
+ if(istype(AM,/mob/living))
+ var/mob/living/AMob = AM
+ AMob.grabbedby(src)
+ return TRUE
+ stop_pulling()
+ if(AM.pulledby)
+ add_attack_logs(AM, AM.pulledby, "pulled from", src)
+ AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once.
+ pulling = AM
+ AM.pulledby = src
+ if(ismob(AM))
+ var/mob/M = AM
+ add_attack_logs(src, M, "grabbed", addition="passive grab")
+ if(!supress_message)
+ visible_message("[src] has grabbed [M] passively!")
+ return TRUE
+
+/atom/movable/proc/stop_pulling()
+ if(pulling)
+ pulling.pulledby = null
+ var/mob/living/ex_pulled = pulling
+ pulling = null
+ if(isliving(ex_pulled))
+ var/mob/living/L = ex_pulled
+ L.update_canmove()// mob gets up if it was lyng down in a chokehold
+
+/atom/movable/proc/check_pulling()
+ if(pulling)
+ var/atom/movable/pullee = pulling
+ if(pullee && get_dist(src, pullee) > 1)
+ stop_pulling()
+ return
+ if(!isturf(loc))
+ stop_pulling()
+ return
+ if(pullee && !isturf(pullee.loc) && pullee.loc != loc) //to be removed once all code that changes an object's loc uses forceMove().
+ log_game("DEBUG:[src]'s pull on [pullee] wasn't broken despite [pullee] being in [pullee.loc]. Pull stopped manually.")
+ stop_pulling()
+ return
+ if(pulling.anchored)
+ stop_pulling()
+ return
+
/atom/movable/proc/can_be_pulled(user, grab_state, force)
if(src == user || !isturf(loc))
return FALSE
@@ -232,7 +290,7 @@
step(src, AM.dir)
..()
-/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, /datum/callback/callback, force = INFINITY)
+/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = INFINITY)
if(!target || (flags & NODROP) || speed <= 0)
return 0
@@ -341,15 +399,15 @@
/atom/movable/proc/force_pushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
return FALSE
- /atom/movable/proc/force_push(atom/movable/AM, force = move_force, direction, silent = FALSE)
+/atom/movable/proc/force_push(atom/movable/AM, force = move_force, direction, silent = FALSE)
. = AM.force_pushed(src, force, direction)
if(!silent && .)
visible_message("[src] forcefully pushes against [AM]!", "You forcefully push against [AM]!")
- /atom/movable/proc/move_crush(atom/movable/AM, force = move_force, direction, silent = FALSE)
+/atom/movable/proc/move_crush(atom/movable/AM, force = move_force, direction, silent = FALSE)
. = AM.move_crushed(src, force, direction)
if(!silent && .)
visible_message("[src] crushes past [AM]!", "You crush [AM]!")
- /atom/movable/proc/move_crushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
+/atom/movable/proc/move_crushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
return FALSE
/atom/movable/CanPass(atom/movable/mover, turf/target, height=1.5)
diff --git a/code/game/gamemodes/miniantags/slaughter/bloodcrawl.dm b/code/game/gamemodes/miniantags/slaughter/bloodcrawl.dm
index 51f3d277598..d769c2f6807 100644
--- a/code/game/gamemodes/miniantags/slaughter/bloodcrawl.dm
+++ b/code/game/gamemodes/miniantags/slaughter/bloodcrawl.dm
@@ -154,7 +154,6 @@
name = "odd blood"
icon = 'icons/effects/effects.dmi'
icon_state = "nothing"
- var/canmove = 1
density = 0
anchored = 1
invisibility = 60
diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm
index 7741d1ce056..eba0a5b860c 100644
--- a/code/game/machinery/magnet.dm
+++ b/code/game/machinery/magnet.dm
@@ -22,7 +22,7 @@
var/code = 0 // frequency code, they should be different unless you have a group of magnets working together or something
var/turf/center // the center of magnetic attraction
var/on = 0
- var/pulling = 0
+ var/magpulling = 0
// x, y modifiers to the center turf; (0, 0) is centered on the magnet, whereas (1, -1) is one tile right, one tile down
var/center_x = 0
@@ -154,10 +154,10 @@
/obj/machinery/magnetic_module/proc/magnetic_process() // proc that actually does the pulling
- if(pulling) return
+ if(magpulling) return
while(on)
- pulling = 1
+ magpulling = 1
center = locate(x+center_x, y+center_y, z)
if(center)
for(var/obj/M in orange(magnetic_field, center))
@@ -171,7 +171,7 @@
use_power(electricity_level * 5)
sleep(13 - electricity_level)
- pulling = 0
+ magpulling = 0
/obj/machinery/magnetic_controller
name = "Magnetic Control Console"
diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm
index 2f260559191..825e5ad2cc1 100644
--- a/code/game/objects/obj_defense.dm
+++ b/code/game/objects/obj_defense.dm
@@ -89,10 +89,10 @@
/obj/force_pushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
return TRUE
- /obj/move_crushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
+/obj/move_crushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
collision_damage(pusher, force, direction)
return TRUE
- /obj/proc/collision_damage(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
+/obj/proc/collision_damage(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
var/amt = max(0, ((force - (move_resist * MOVE_FORCE_CRUSH_RATIO)) / (move_resist * MOVE_FORCE_CRUSH_RATIO)) * 10)
take_damage(amt, BRUTE)
diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm
index a64750ad93d..e6c9da4e1aa 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva.dm
@@ -38,6 +38,12 @@
amount_grown = min(amount_grown + 1, max_grown)
..(amount)
+<<<<<<< HEAD
+=======
+/mob/living/carbon/alien/larva/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE)
+ return
+
+>>>>>>> Lots of edits, needs review
/mob/living/carbon/alien/larva/ex_act(severity)
..()
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 88ac1320f04..ca791c9e400 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -574,7 +574,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
if(thrown_thing)
visible_message("[src] has thrown [thrown_thing].")
newtonian_move(get_dir(target, src))
- thrown_thing.safe_throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed, src, null, null, null, move_force)
+ thrown_thing.throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed, src, null, null, null, move_force)
/mob/living/carbon/can_use_hands()
if(handcuffed)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index dfc3a949cac..a2a1b17530d 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -134,8 +134,7 @@
return TRUE
if(!client && (mob_size < MOB_SIZE_SMALL))
return
- if(!AM.anchored)
-now_pushing = TRUE
+ now_pushing = TRUE
var/t = get_dir(src, AM)
var/push_anchored = FALSE
if((AM.move_resist * MOVE_FORCE_CRUSH_RATIO) <= force)
@@ -862,6 +861,51 @@ now_pushing = TRUE
return 0
return 1
+/mob/living/start_pulling(atom/movable/AM, state, force = pull_force, supress_message = FALSE)
+ if(src == AM) // Trying to pull yourself is a shortcut to stop pulling
+ stop_pulling()
+ return
+ if(!AM || !isturf(AM.loc)) //if there's no object or the object being pulled is inside something: abort!
+ return
+ if(incapacitated())
+ return
+ if(!(AM.anchored))
+ AM.add_fingerprint(src)
+
+ // If we're pulling something then drop what we're currently pulling and pull this instead.
+ if(pulling)
+ // Are we trying to pull something we are already pulling? Then just stop here, no need to continue.
+ if(AM == pulling)
+ return
+ stop_pulling()
+ if(AM.pulledby)
+ visible_message("[src] has pulled [AM] from [AM.pulledby]'s grip.")
+ AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once.
+
+ pulling = AM
+ AM.pulledby = src
+ if(pullin)
+ pullin.update_icon(src)
+ if(ismob(AM))
+ var/mob/M = AM
+ if(!iscarbon(src))
+ M.LAssailant = null
+ else
+ M.LAssailant = usr
+
+/mob/living/verb/stop_pulling1()
+ set name = "Stop Pulling"
+ set category = "IC"
+ if(pulling)
+ pulling.pulledby = null
+ pulling = null
+ if(pullin)
+ pullin.update_icon(src)
+
+/mob/living/proc/check_pull()
+ if(pulling && !(pulling in orange(1)))
+ stop_pulling()
+
/mob/living/proc/get_taste_sensitivity()
return 1
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index bfe9ac7484a..3de413ef8a1 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -35,7 +35,6 @@
var/obj/machinery/machine = null
var/other_mobs = null
var/memory = ""
- var/atom/movable/pulling = null
var/next_move = null
var/notransform = null //Carbon
var/other = 0.0
@@ -48,7 +47,6 @@
var/bhunger = 0 //Carbon
var/lying = 0
var/lying_prev = 0
- var/canmove = 1
var/lastpuke = 0
var/unacidable = 0
var/can_strip = 1
diff --git a/paradise.dme b/paradise.dme
index 518fa02c2fe..11a6d3ad9e3 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -326,6 +326,7 @@
#include "code\datums\helper_datums\topic_input.dm"
#include "code\datums\looping_sounds\looping_sound.dm"
#include "code\datums\looping_sounds\machinery_sounds.dm"
+#include "code\datums\looping_sounds\thermal_drill.dm"
#include "code\datums\looping_sounds\weather.dm"
#include "code\datums\outfits\outfit.dm"
#include "code\datums\outfits\outfit_admin.dm"
@@ -1598,7 +1599,6 @@
#include "code\modules\mob\mob_helpers.dm"
#include "code\modules\mob\mob_movement.dm"
#include "code\modules\mob\mob_transformation_simple.dm"
-#include "code\modules\mob\pulling.dm"
#include "code\modules\mob\say.dm"
#include "code\modules\mob\status_procs.dm"
#include "code\modules\mob\transform_procs.dm"