diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm
index 76a4f332fda..82a5d49c094 100644
--- a/code/controllers/subsystem/throwing.dm
+++ b/code/controllers/subsystem/throwing.dm
@@ -56,6 +56,7 @@ SUBSYSTEM_DEF(throwing)
var/dx
var/dy
var/force = MOVE_FORCE_DEFAULT
+ var/gentle = FALSE
var/pure_diagonal
var/diagonal_error
var/datum/callback/callback
@@ -147,7 +148,7 @@ SUBSYSTEM_DEF(throwing)
if (callback)
callback.Invoke()
-
+
if(!thrownthing.zfalling) // I don't think you can zfall while thrown but hey, just in case.
var/turf/T = get_turf(thrownthing)
if(T && thrownthing.has_gravity(T))
diff --git a/code/datums/components/riding.dm b/code/datums/components/riding.dm
index 7ec58c5318d..529492e3ed7 100644
--- a/code/datums/components/riding.dm
+++ b/code/datums/components/riding.dm
@@ -20,7 +20,7 @@
var/ride_check_ridden_incapacitated = FALSE
var/del_on_unbuckle_all = FALSE
-
+
/// If the "vehicle" is a mob, respect MOBILITY_MOVE on said mob.
var/respect_mob_mobility = TRUE
@@ -70,16 +70,21 @@
AM.unbuckle_mob(M)
return TRUE
-/datum/component/riding/proc/force_dismount(mob/living/M)
+/datum/component/riding/proc/force_dismount(mob/living/M, gentle = FALSE)
var/atom/movable/AM = parent
AM.unbuckle_mob(M)
if(isanimal(AM) || iscyborg(AM))
var/turf/target = get_edge_target_turf(AM, AM.dir)
var/turf/targetm = get_step(get_turf(AM), AM.dir)
M.Move(targetm)
- M.visible_message("[M] is thrown clear of [AM]!", \
- "You're thrown clear of [AM]!")
- M.throw_at(target, 14, 5, AM)
+ if(gentle)
+ M.visible_message("[M] is thrown clear of [AM]!", \
+ "You're thrown clear of [AM]!")
+ M.throw_at(target, 8, 3, AM, gentle = TRUE)
+ else
+ M.visible_message("[M] is thrown violently from [AM]!", \
+ "You're thrown violently from [AM]!")
+ M.throw_at(target, 14, 5, AM, gentle = FALSE)
M.Knockdown(3 SECONDS)
/datum/component/riding/proc/handle_vehicle_offsets()
@@ -371,4 +376,4 @@
if(rider in AM.buckled_mobs)
AM.unbuckle_mob(rider)
. = ..()
-
+
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index deb849a33c2..8622abd8563 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -533,12 +533,12 @@
step(src, AM.dir)
..()
-/atom/movable/proc/safe_throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = MOVE_FORCE_STRONG)
+/atom/movable/proc/safe_throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = MOVE_FORCE_STRONG, gentle = FALSE)
if((force < (move_resist * MOVE_FORCE_THROW_RATIO)) || (move_resist == INFINITY))
return
- return throw_at(target, range, speed, thrower, spin, diagonals_first, callback, force)
+ return throw_at(target, range, speed, thrower, spin, diagonals_first, callback, force, gentle)
-/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = MOVE_FORCE_STRONG) //If this returns FALSE then callback will not be called.
+/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = MOVE_FORCE_STRONG, gentle = FALSE) //If this returns FALSE then callback will not be called.
. = FALSE
if (!target || speed <= 0)
return
@@ -585,6 +585,7 @@
TT.thrower = thrower
TT.diagonals_first = diagonals_first
TT.force = force
+ TT.gentle = gentle
TT.callback = callback
if(!QDELETED(thrower))
TT.target_zone = thrower.zone_selected
diff --git a/code/game/gamemodes/clown_ops/clown_weapons.dm b/code/game/gamemodes/clown_ops/clown_weapons.dm
index d9140a5323e..95e632f63f5 100644
--- a/code/game/gamemodes/clown_ops/clown_weapons.dm
+++ b/code/game/gamemodes/clown_ops/clown_weapons.dm
@@ -138,7 +138,7 @@
var/datum/component/slippery/slipper = GetComponent(/datum/component/slippery)
slipper.signal_enabled = active
-/obj/item/shield/energy/bananium/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force)
+/obj/item/shield/energy/bananium/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, gentle = FALSE)
if(active)
if(iscarbon(thrower))
var/mob/living/carbon/C = thrower
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 9fe652ddbe3..1a8415c549c 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -576,10 +576,10 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
playsound(src, drop_sound, YEET_SOUND_VOLUME, ignore_walls = FALSE)
return hit_atom.hitby(src, 0, itempush, throwingdatum=throwingdatum)
-/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force)
+/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, gentle = FALSE)
thrownby = thrower
callback = CALLBACK(src, .proc/after_throw, callback) //replace their callback with our own
- . = ..(target, range, speed, thrower, spin, diagonals_first, callback, force)
+ . = ..(target, range, speed, thrower, spin, diagonals_first, callback, force, gentle)
/obj/item/proc/after_throw(datum/callback/callback)
@@ -846,7 +846,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
dropped(M, FALSE)
return ..()
-/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=TRUE, diagonals_first = FALSE, datum/callback/callback)
+/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=TRUE, diagonals_first = FALSE, datum/callback/callback, gentle = FALSE)
if(HAS_TRAIT(src, TRAIT_NODROP))
return
return ..()
diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm
index 99434d2bce6..310d3b65264 100644
--- a/code/game/objects/items/handcuffs.dm
+++ b/code/game/objects/items/handcuffs.dm
@@ -319,7 +319,7 @@
gender = NEUTER
var/knockdown = 0
-/obj/item/restraints/legcuffs/bola/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback)
+/obj/item/restraints/legcuffs/bola/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, gentle = FALSE)
if(!..())
return
playsound(src.loc,'sound/weapons/bolathrow.ogg', 75, TRUE)
diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm
index 96085e30adc..00ca681430b 100644
--- a/code/game/objects/items/stunbaton.dm
+++ b/code/game/objects/items/stunbaton.dm
@@ -278,7 +278,7 @@
convertable = FALSE
custom_materials = list(/datum/material/iron = 10000, /datum/material/glass = 4000, /datum/material/silver = 10000, /datum/material/gold = 2000)
-/obj/item/melee/baton/boomerang/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force)
+/obj/item/melee/baton/boomerang/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, gentle = FALSE)
if(turned_on)
if(ishuman(thrower))
var/mob/living/carbon/human/H = thrower
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index 37cee6addf7..1d265123bb2 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -83,7 +83,7 @@
SEND_SIGNAL(src, COMSIG_OBJ_SETANCHORED, anchorvalue)
anchored = anchorvalue
-/obj/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force)
+/obj/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, gentle = FALSE)
..()
if(obj_flags & FROZEN)
visible_message("[src] shatters into a million pieces!")
diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm
index 59e4d7e2ede..811fccf0e05 100644
--- a/code/modules/assembly/infrared.dm
+++ b/code/modules/assembly/infrared.dm
@@ -140,7 +140,7 @@
. = ..()
setDir(t)
-/obj/item/assembly/infra/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force)
+/obj/item/assembly/infra/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, gentle = FALSE)
. = ..()
olddir = dir
diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm
index 3fc498b9f16..9de0eda024a 100644
--- a/code/modules/awaymissions/gateway.dm
+++ b/code/modules/awaymissions/gateway.dm
@@ -73,7 +73,7 @@ GLOBAL_DATUM(the_gateway, /obj/machinery/gateway/centerstation)
/obj/machinery/gateway/proc/toggleon(mob/user)
return FALSE
-/obj/machinery/gateway/safe_throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = MOVE_FORCE_STRONG)
+/obj/machinery/gateway/safe_throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = MOVE_FORCE_STRONG, gentle = FALSE)
return
/obj/machinery/gateway/centerstation/Initialize()
diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm
index c0d8c192382..9d9c6cecf6a 100644
--- a/code/modules/mob/emote.dm
+++ b/code/modules/mob/emote.dm
@@ -75,7 +75,11 @@
var/mob/living/L = user
var/datum/component/riding/riding_datum = L.GetComponent(/datum/component/riding)
if(riding_datum)
- for(var/mob/M in L.buckled_mobs)
- riding_datum.force_dismount(M)
+ if(L.a_intent == INTENT_HELP)
+ for(var/mob/M in L.buckled_mobs)
+ riding_datum.force_dismount(M, TRUE)
+ else
+ for(var/mob/M in L.buckled_mobs)
+ riding_datum.force_dismount(M)
else
L.unbuckle_all_mobs()
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index a9d8709a39a..b734f24cabd 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -68,11 +68,7 @@
. = ..()
var/hurt = TRUE
if(istype(throwingdatum, /datum/thrownthing))
- var/datum/thrownthing/D = throwingdatum
- if(iscyborg(D.thrower))
- var/mob/living/silicon/robot/R = D.thrower
- if(!R.emagged)
- hurt = FALSE
+ hurt = !throwingdatum.gentle
if(hit_atom.density && isturf(hit_atom))
if(hurt)
Paralyze(20)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index dc9eebf5699..99e1ac04cbc 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -1013,7 +1013,7 @@
return TRUE
return FALSE
-/mob/living/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force)
+/mob/living/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, gentle = FALSE)
stop_pulling()
. = ..()
diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm
index 4a2165b6952..c9b1eea82bf 100644
--- a/code/modules/power/gravitygenerator.dm
+++ b/code/modules/power/gravitygenerator.dm
@@ -28,7 +28,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
var/sprite_number = 0
-/obj/machinery/gravity_generator/safe_throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = MOVE_FORCE_STRONG)
+/obj/machinery/gravity_generator/safe_throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = MOVE_FORCE_STRONG, gentle = FALSE)
return FALSE
/obj/machinery/gravity_generator/ex_act(severity, target)