diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 00009c8eeca..ade06f58b35 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -61,7 +61,7 @@
/atom/movable/proc/get_cell()
return
-/atom/movable/proc/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE)
+/atom/movable/proc/start_pulling(atom/movable/AM, state, force = pull_force, show_message = FALSE)
if(QDELETED(AM))
return FALSE
if(!(AM.can_be_pulled(src, state, force)))
@@ -87,7 +87,7 @@
if(ismob(AM))
var/mob/M = AM
add_attack_logs(src, M, "passively grabbed", ATKLOG_ALMOSTALL)
- if(!supress_message)
+ if(show_message)
visible_message("[src] has grabbed [M] passively!")
return TRUE
@@ -120,12 +120,18 @@
if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1) //separated from our puller and not in the middle of a diagonal move.
pulledby.stop_pulling()
-/atom/movable/proc/can_be_pulled(user, grab_state, force)
+/atom/movable/proc/can_be_pulled(user, grab_state, force, show_message = FALSE)
if(src == user || !isturf(loc))
return FALSE
- if(anchored || throwing)
+ if(anchored || move_resist == INFINITY)
+ if(show_message)
+ to_chat(user, "[src] appears to be anchored to the ground!")
+ return FALSE
+ if(throwing)
return FALSE
if(force < (move_resist * MOVE_FORCE_PULL_RATIO))
+ if(show_message)
+ to_chat(user, "[src] is too heavy to pull!")
return FALSE
return TRUE
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index baaf0cab16b..edcc6620531 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -2,6 +2,8 @@ GLOBAL_DATUM_INIT(fire_overlay, /image, image("icon" = 'icons/goonstation/effect
/obj/item
name = "item"
icon = 'icons/obj/items.dmi'
+
+ move_resist = null // Set in the Initialise depending on the item size. Unless it's overriden by a specific item
var/discrete = 0 // used in item_attack.dm to make an item not show an attack message to viewers
var/image/blood_overlay = null //this saves our blood splatter overlay, which will be processed not to go over the edges of the sprite
var/blood_overlay_color = null
@@ -113,6 +115,23 @@ GLOBAL_DATUM_INIT(fire_overlay, /image, image("icon" = 'icons/goonstation/effect
hitsound = 'sound/items/welder.ogg'
if(damtype == "brute")
hitsound = "swing_hit"
+ if(!move_resist)
+ determine_move_resist()
+
+/obj/item/proc/determine_move_resist()
+ switch(w_class)
+ if(WEIGHT_CLASS_TINY)
+ move_resist = MOVE_FORCE_EXTREMELY_WEAK
+ if(WEIGHT_CLASS_SMALL)
+ move_resist = MOVE_FORCE_VERY_WEAK
+ if(WEIGHT_CLASS_NORMAL)
+ move_resist = MOVE_FORCE_WEAK
+ if(WEIGHT_CLASS_BULKY)
+ move_resist = MOVE_FORCE_NORMAL
+ if(WEIGHT_CLASS_HUGE)
+ move_resist = MOVE_FORCE_NORMAL
+ if(WEIGHT_CLASS_GIGANTIC)
+ move_resist = MOVE_FORCE_NORMAL
/obj/item/Destroy()
flags &= ~DROPDEL //prevent reqdels
diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm
index aeee677b905..f281b8abec3 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva.dm
@@ -81,7 +81,7 @@
/mob/living/carbon/alien/larva/show_inv(mob/user as mob)
return
-/mob/living/carbon/alien/larva/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE)
+/mob/living/carbon/alien/larva/start_pulling(atom/movable/AM, state, force = pull_force, show_message = FALSE)
return FALSE
/* Commented out because it's duplicated in life.dm
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 93a3b6f14cd..c05aae7e664 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -3,8 +3,29 @@
var/datum/atom_hud/data/human/medical/advanced/medhud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
medhud.add_to_hud(src)
faction += "\ref[src]"
+ determine_move_and_pull_forces()
GLOB.mob_living_list += src
+// Used to determine the forces dependend on the mob size
+// Will only change the force if the force was not set in the mob type itself
+/mob/living/proc/determine_move_and_pull_forces()
+ var/value
+ switch(mob_size)
+ if(MOB_SIZE_TINY)
+ value = MOVE_FORCE_EXTREMELY_WEAK
+ if(MOB_SIZE_SMALL)
+ value = MOVE_FORCE_WEAK
+ if(MOB_SIZE_HUMAN)
+ value = MOVE_FORCE_NORMAL
+ if(MOB_SIZE_LARGE)
+ value = MOVE_FORCE_NORMAL // For now
+ if(!move_force)
+ move_force = value
+ if(!pull_force)
+ pull_force = value
+ if(!move_resist)
+ move_resist = value
+
/mob/living/prepare_huds()
..()
prepare_data_huds()
@@ -203,7 +224,7 @@
set category = "Object"
if(istype(AM) && Adjacent(AM))
- start_pulling(AM)
+ start_pulling(AM, show_message = TRUE)
else
stop_pulling()
@@ -921,10 +942,10 @@
return 0
return 1
-/mob/living/start_pulling(atom/movable/AM, state, force = pull_force, supress_message = FALSE)
+/mob/living/start_pulling(atom/movable/AM, state, force = pull_force, show_message = FALSE)
if(!AM || !src)
return FALSE
- if(!(AM.can_be_pulled(src, state, force)))
+ if(!(AM.can_be_pulled(src, state, force, show_message)))
return FALSE
if(incapacitated())
return
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 1f0f1cfa0f4..4da8aa97e06 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -219,7 +219,7 @@
fire_stacks += L.fire_stacks
IgniteMob()
-/mob/living/can_be_pulled(user, grab_state, force)
+/mob/living/can_be_pulled(user, grab_state, force, show_message = FALSE)
return ..() && !(buckled && buckled.buckle_prevents_pull)
/mob/living/water_act(volume, temperature, source, method = REAGENT_TOUCH)
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index e230f7a2b99..c3575f4a7b5 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -2,6 +2,11 @@
see_invisible = SEE_INVISIBLE_LIVING
pressure_resistance = 10
+ // Will be determined based on mob size if left null. Done in living/proc/determine_move_and_pull_forces()
+ move_resist = null
+ move_force = null
+ pull_force = null
+
//Health and life related vars
var/maxHealth = 100 //Maximum health that should be possible.
var/health = 100 //A mob's health
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 2a5a7b0aa08..db95f18c210 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -517,7 +517,7 @@
/mob/living/silicon/pai/Bumped()
return
-/mob/living/silicon/pai/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE)
+/mob/living/silicon/pai/start_pulling(atom/movable/AM, state, force = pull_force, show_message = FALSE)
return FALSE
/mob/living/silicon/pai/update_canmove(delay_action_updates = 0)
diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm
index 33ae1c923ec..5cc6e50fd06 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone.dm
@@ -19,6 +19,7 @@
ventcrawler = 2
magpulse = 1
mob_size = MOB_SIZE_SMALL
+ pull_force = MOVE_FORCE_VERY_WEAK // Can only drag small items
modules_break = FALSE
@@ -335,21 +336,22 @@
/mob/living/silicon/robot/drone/Bumped(atom/movable/AM)
return
-/mob/living/silicon/robot/drone/start_pulling(var/atom/movable/AM)
+/mob/living/silicon/robot/drone/start_pulling(atom/movable/AM, state, force = pull_force, show_message = FALSE)
if(is_type_in_list(AM, pullable_drone_items))
- ..()
+ ..(AM, force = INFINITY) // Drone power! Makes them able to drag pipes and such
else if(istype(AM,/obj/item))
var/obj/item/O = AM
if(O.w_class > WEIGHT_CLASS_SMALL)
- to_chat(src, "You are too small to pull that.")
+ if(show_message)
+ to_chat(src, "You are too small to pull that.")
return
else
..()
else
- to_chat(src, "You are too small to pull that.")
- return
+ if(show_message)
+ to_chat(src, "You are too small to pull that.")
/mob/living/silicon/robot/drone/add_robot_verbs()
src.verbs |= silicon_subsystems
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index 2881141f4dd..be3f985db2e 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -85,8 +85,11 @@
get_scooped(M)
..()
-/mob/living/simple_animal/mouse/start_pulling(var/atom/movable/AM)//Prevents mouse from pulling things
- to_chat(src, "You are too small to pull anything.")
+/mob/living/simple_animal/mouse/start_pulling(atom/movable/AM, state, force = pull_force, show_message = FALSE)//Prevents mouse from pulling things
+ if(istype(AM, /obj/item/reagent_containers/food/snacks/cheesewedge))
+ return ..() // Get dem
+ if(show_message)
+ to_chat(src, "You are too small to pull anything except cheese.")
return
/mob/living/simple_animal/mouse/Crossed(AM as mob|obj, oldloc)
diff --git a/code/modules/mob/living/simple_animal/posessed_object.dm b/code/modules/mob/living/simple_animal/posessed_object.dm
index c3cb61d5970..729790d098c 100644
--- a/code/modules/mob/living/simple_animal/posessed_object.dm
+++ b/code/modules/mob/living/simple_animal/posessed_object.dm
@@ -32,8 +32,9 @@
animate_ghostly_presence(src, -1, 20, 1) // Restart the floating animation after the attack animation, as it will be cancelled.
-/mob/living/simple_animal/possessed_object/start_pulling(var/atom/movable/AM) // Silly motherfuckers think they can pull things.
- to_chat(src, "You are unable to pull [AM]!")
+/mob/living/simple_animal/possessed_object/start_pulling(atom/movable/AM, state, force = pull_force, show_message = FALSE) // Silly motherfuckers think they can pull things.
+ if(show_message)
+ to_chat(src, "You are unable to pull [AM]!")
/mob/living/simple_animal/possessed_object/ghost() // Ghosting will return the object to normal, and will not disqualify the ghoster from various mid-round antag positions.
diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm
index 15f483bef76..1b67b53119a 100644
--- a/code/modules/mob/living/simple_animal/slime/slime.dm
+++ b/code/modules/mob/living/simple_animal/slime/slime.dm
@@ -265,7 +265,7 @@
/mob/living/simple_animal/slime/unEquip(obj/item/I, force)
return
-/mob/living/simple_animal/slime/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE)
+/mob/living/simple_animal/slime/start_pulling(atom/movable/AM, state, force = pull_force, show_message = FALSE)
return
/mob/living/simple_animal/slime/attack_ui(slot)