Make slips eligible for shove stuns (#89313)

## About The Pull Request

Adds slips to the list of existing shove stun methods originally set in
https://github.com/tgstation/tgstation/pull/84640 (wall shoves,
telebaton, mansus grasp), and also reifies this concept as the "dazed"
status effect.

This makes it so that being knocked down from a slip from any source
(e.g. wet floor, clown stuff, lube, foam, oil, butterdog) gives the
dazed visual effect and makes you eligible for being shove stunned. The
status always lasts for 3 seconds even if e.g. slipping on lube knocks
you down for 15, but this can be customized per slip.

## Why It's Good For The Game

Further rewards environmental play and provides another feasible means
of fighting back against better equipped opponents, both in line with
the original PR. Also the visual cue fits well as an immediate signal
that you're dazed and can't get up.

## Changelog
🆑
balance: slips now make you eligible for being shove stunned
/🆑

---------

Co-authored-by: Roryl-c <5150427+Roryl-c@users.noreply.github.com>
This commit is contained in:
Runi-c
2025-02-05 21:37:22 -07:00
committed by GitHub
parent 348413a8a6
commit d7130a4598
23 changed files with 79 additions and 60 deletions

View File

@@ -43,7 +43,7 @@
#define COMSIG_LIVING_REVIVE "living_revive" #define COMSIG_LIVING_REVIVE "living_revive"
///from base of mob/living/set_buckled(): (new_buckled) ///from base of mob/living/set_buckled(): (new_buckled)
#define COMSIG_LIVING_SET_BUCKLED "living_set_buckled" #define COMSIG_LIVING_SET_BUCKLED "living_set_buckled"
///from base of mob/living/set_body_position() ///from base of mob/living/set_body_position(): (new_position, old_position)
#define COMSIG_LIVING_SET_BODY_POSITION "living_set_body_position" #define COMSIG_LIVING_SET_BODY_POSITION "living_set_body_position"
/// Sent to a mob being injected with a syringe when the do_after initiates /// Sent to a mob being injected with a syringe when the do_after initiates
#define COMSIG_LIVING_TRY_SYRINGE_INJECT "living_try_syringe_inject" #define COMSIG_LIVING_TRY_SYRINGE_INJECT "living_try_syringe_inject"

View File

@@ -616,7 +616,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_DISPLAY_JOB_IN_BINARY "display job in binary" #define TRAIT_DISPLAY_JOB_IN_BINARY "display job in binary"
/// Trait that determines vulnerability to being stunned from a shove /// Trait that determines vulnerability to being stunned from a shove
#define TRAIT_STUN_ON_NEXT_SHOVE "stun on next shove" #define TRAIT_DAZED "dazed"
/// Trait that determines whether our mob gains more strength from drinking during a fist fight /// Trait that determines whether our mob gains more strength from drinking during a fist fight
#define TRAIT_DRUNKEN_BRAWLER "drunken brawler" #define TRAIT_DRUNKEN_BRAWLER "drunken brawler"

View File

@@ -205,6 +205,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_CRITICAL_CONDITION" = TRAIT_CRITICAL_CONDITION, "TRAIT_CRITICAL_CONDITION" = TRAIT_CRITICAL_CONDITION,
"TRAIT_CULT_HALO" = TRAIT_CULT_HALO, "TRAIT_CULT_HALO" = TRAIT_CULT_HALO,
"TRAIT_CURSED" = TRAIT_CURSED, "TRAIT_CURSED" = TRAIT_CURSED,
"TRAIT_DAZED" = TRAIT_DAZED,
"TRAIT_DEAF" = TRAIT_DEAF, "TRAIT_DEAF" = TRAIT_DEAF,
"TRAIT_DEATHCOMA" = TRAIT_DEATHCOMA, "TRAIT_DEATHCOMA" = TRAIT_DEATHCOMA,
"TRAIT_DEFIB_BLACKLISTED" = TRAIT_DEFIB_BLACKLISTED, "TRAIT_DEFIB_BLACKLISTED" = TRAIT_DEFIB_BLACKLISTED,
@@ -511,7 +512,6 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_STRONG_STOMACH" = TRAIT_STRONG_STOMACH, "TRAIT_STRONG_STOMACH" = TRAIT_STRONG_STOMACH,
"TRAIT_STUBBY_BODY" = TRAIT_STUBBY_BODY, "TRAIT_STUBBY_BODY" = TRAIT_STUBBY_BODY,
"TRAIT_STUNIMMUNE" = TRAIT_STUNIMMUNE, "TRAIT_STUNIMMUNE" = TRAIT_STUNIMMUNE,
"TRAIT_STUN_ON_NEXT_SHOVE" = TRAIT_STUN_ON_NEXT_SHOVE,
"TRAIT_STURDY_FRAME" = TRAIT_STURDY_FRAME, "TRAIT_STURDY_FRAME" = TRAIT_STURDY_FRAME,
"TRAIT_SUCCUMB_OVERRIDE" = TRAIT_SUCCUMB_OVERRIDE, "TRAIT_SUCCUMB_OVERRIDE" = TRAIT_SUCCUMB_OVERRIDE,
"TRAIT_SUICIDED" = TRAIT_SUICIDED, "TRAIT_SUICIDED" = TRAIT_SUICIDED,

View File

@@ -75,6 +75,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list(
"TRAIT_CORPSELOCKED" = TRAIT_CORPSELOCKED, "TRAIT_CORPSELOCKED" = TRAIT_CORPSELOCKED,
"TRAIT_CRITICAL_CONDITION" = TRAIT_CRITICAL_CONDITION, "TRAIT_CRITICAL_CONDITION" = TRAIT_CRITICAL_CONDITION,
"TRAIT_CULT_HALO" = TRAIT_CULT_HALO, "TRAIT_CULT_HALO" = TRAIT_CULT_HALO,
"TRAIT_DAZED" = TRAIT_DAZED,
"TRAIT_DEAF" = TRAIT_DEAF, "TRAIT_DEAF" = TRAIT_DEAF,
"TRAIT_DEATHCOMA" = TRAIT_DEATHCOMA, "TRAIT_DEATHCOMA" = TRAIT_DEATHCOMA,
"TRAIT_DEFIB_BLACKLISTED" = TRAIT_DEFIB_BLACKLISTED, "TRAIT_DEFIB_BLACKLISTED" = TRAIT_DEFIB_BLACKLISTED,

View File

@@ -23,6 +23,8 @@
var/knockdown_time = 0 var/knockdown_time = 0
/// How long the slip paralyzes (prevents the crossing mob doing anything) for. /// How long the slip paralyzes (prevents the crossing mob doing anything) for.
var/paralyze_time = 0 var/paralyze_time = 0
/// How long the slip dazes (makes the crossing mob vulnerable to shove stuns) for.
var/daze_time = 3 SECONDS
/// Flags for how slippery the parent is. See [__DEFINES/mobs.dm] /// Flags for how slippery the parent is. See [__DEFINES/mobs.dm]
var/lube_flags var/lube_flags
/// Optional callback allowing you to define custom conditions for slipping /// Optional callback allowing you to define custom conditions for slipping
@@ -53,6 +55,7 @@
* * lube_flags - Controls the slip behaviour, they are listed starting [here][SLIDE] * * lube_flags - Controls the slip behaviour, they are listed starting [here][SLIDE]
* * datum/callback/on_slip_callback - Callback to define further custom controls on when slipping is applied * * datum/callback/on_slip_callback - Callback to define further custom controls on when slipping is applied
* * paralyze - length of time to paralyze the crossing mob for (Deciseconds) * * paralyze - length of time to paralyze the crossing mob for (Deciseconds)
* * daze - length of time to daze the crossing mob for (Deciseconds), default 3 seconds
* * force_drop - should the crossing mob drop items in its hands or not * * force_drop - should the crossing mob drop items in its hands or not
* * slot_whitelist - flags controlling where on a mob this item can be equipped to make the parent mob slippery full list [here][ITEM_SLOT_OCLOTHING] * * slot_whitelist - flags controlling where on a mob this item can be equipped to make the parent mob slippery full list [here][ITEM_SLOT_OCLOTHING]
* * datum/callback/on_slip_callback - Callback to add custom behaviours as the crossing mob is slipped * * datum/callback/on_slip_callback - Callback to add custom behaviours as the crossing mob is slipped
@@ -62,12 +65,14 @@
lube_flags = NONE, lube_flags = NONE,
datum/callback/on_slip_callback, datum/callback/on_slip_callback,
paralyze, paralyze,
daze = 3 SECONDS,
force_drop = FALSE, force_drop = FALSE,
slot_whitelist, slot_whitelist,
datum/callback/can_slip_callback, datum/callback/can_slip_callback,
) )
src.knockdown_time = max(knockdown, 0) src.knockdown_time = max(knockdown, 0)
src.paralyze_time = max(paralyze, 0) src.paralyze_time = max(paralyze, 0)
src.daze_time = max(daze, 0)
src.force_drop_items = force_drop src.force_drop_items = force_drop
src.lube_flags = lube_flags src.lube_flags = lube_flags
src.can_slip_callback = can_slip_callback src.can_slip_callback = can_slip_callback
@@ -126,6 +131,7 @@
lube_flags = NONE, lube_flags = NONE,
datum/callback/on_slip_callback, datum/callback/on_slip_callback,
paralyze, paralyze,
daze,
force_drop = FALSE, force_drop = FALSE,
slot_whitelist, slot_whitelist,
datum/callback/can_slip_callback, datum/callback/can_slip_callback,
@@ -136,11 +142,13 @@
on_slip_callback = component.on_slip_callback on_slip_callback = component.on_slip_callback
can_slip_callback = component.on_slip_callback can_slip_callback = component.on_slip_callback
paralyze = component.paralyze_time paralyze = component.paralyze_time
daze = component.daze_time
force_drop = component.force_drop_items force_drop = component.force_drop_items
slot_whitelist = component.slot_whitelist slot_whitelist = component.slot_whitelist
src.knockdown_time = max(knockdown, 0) src.knockdown_time = max(knockdown, 0)
src.paralyze_time = max(paralyze, 0) src.paralyze_time = max(paralyze, 0)
src.daze_time = max(daze, 0)
src.force_drop_items = force_drop src.force_drop_items = force_drop
src.lube_flags = lube_flags src.lube_flags = lube_flags
src.on_slip_callback = on_slip_callback src.on_slip_callback = on_slip_callback
@@ -167,7 +175,7 @@
return return
if(can_slip_callback && !can_slip_callback.Invoke(holder, victim)) if(can_slip_callback && !can_slip_callback.Invoke(holder, victim))
return return
if(victim.slip(knockdown_time, parent, lube_flags, paralyze_time, force_drop_items)) if(victim.slip(knockdown_time, parent, lube_flags, paralyze_time, daze_time, force_drop_items))
on_slip_callback?.Invoke(victim) on_slip_callback?.Invoke(victim)
/** /**

View File

@@ -51,62 +51,74 @@
animate(pixel_x = normal_pos, time = 0.2 SECONDS) animate(pixel_x = normal_pos, time = 0.2 SECONDS)
/// Status effect specifically for instances where someone is vulnerable to being stunned when shoved. /// Status effect specifically for instances where someone is vulnerable to being stunned when shoved.
/datum/status_effect/next_shove_stuns /datum/status_effect/dazed
id = "next shove stuns" id = "dazed"
duration = 3 SECONDS
status_type = STATUS_EFFECT_UNIQUE status_type = STATUS_EFFECT_UNIQUE
tick_interval = 0.5 SECONDS tick_interval = 0.5 SECONDS
alert_type = null alert_type = null
remove_on_fullheal = TRUE remove_on_fullheal = TRUE
/// Our visual cue for the vulnerable state this status effect puts us in. /// Our visual cue for the vulnerable state this status effect puts us in.
var/mutable_appearance/vulnverability_overlay var/mutable_appearance/dazed_overlay
/datum/status_effect/next_shove_stuns/on_apply() /datum/status_effect/dazed/on_creation(mob/living/new_owner, duration = 3 SECONDS)
src.duration = duration
return ..()
/datum/status_effect/dazed/on_apply()
//Let's just clear this if they're dead or we can't stun them on a shove //Let's just clear this if they're dead or we can't stun them on a shove
if(owner.stat == DEAD || HAS_TRAIT(owner, TRAIT_NO_SIDE_KICK) || HAS_TRAIT(owner, TRAIT_IMMOBILIZED)) if(owner.stat == DEAD || HAS_TRAIT(owner, TRAIT_NO_SIDE_KICK) || HAS_TRAIT(owner, TRAIT_IMMOBILIZED))
return FALSE return FALSE
RegisterSignal(owner, COMSIG_LIVING_DEATH, PROC_REF(clear_stun_vulnverability_on_death)) RegisterSignal(owner, COMSIG_LIVING_DEATH, PROC_REF(clear_daze_on_death))
RegisterSignal(owner, COMSIG_LIVING_SET_BODY_POSITION, PROC_REF(clear_daze_on_stand))
RegisterSignals(owner, list( RegisterSignals(owner, list(
COMSIG_LIVING_STATUS_PARALYZE, COMSIG_LIVING_STATUS_PARALYZE,
COMSIG_LIVING_STATUS_STUN, COMSIG_LIVING_STATUS_STUN,
COMSIG_LIVING_STATUS_IMMOBILIZE), PROC_REF(clear_stun_vulnverability) COMSIG_LIVING_STATUS_IMMOBILIZE), PROC_REF(clear_daze)
) )
ADD_TRAIT(owner, TRAIT_STUN_ON_NEXT_SHOVE, TRAIT_STATUS_EFFECT(id)) ADD_TRAIT(owner, TRAIT_DAZED, TRAIT_STATUS_EFFECT(id))
vulnverability_overlay = mutable_appearance(icon = 'icons/effects/effects.dmi', icon_state = "dazed") dazed_overlay = mutable_appearance(icon = 'icons/effects/effects.dmi', icon_state = "dazed")
owner.add_overlay(vulnverability_overlay) owner.add_overlay(dazed_overlay)
return TRUE return TRUE
/datum/status_effect/next_shove_stuns/on_remove() /datum/status_effect/dazed/on_remove()
UnregisterSignal(owner, list( UnregisterSignal(owner, list(
COMSIG_LIVING_DEATH,
COMSIG_LIVING_SET_BODY_POSITION,
COMSIG_LIVING_STATUS_PARALYZE, COMSIG_LIVING_STATUS_PARALYZE,
COMSIG_LIVING_STATUS_STUN, COMSIG_LIVING_STATUS_STUN,
COMSIG_LIVING_STATUS_IMMOBILIZE, COMSIG_LIVING_STATUS_IMMOBILIZE,
COMSIG_LIVING_DEATH,
)) ))
REMOVE_TRAIT(owner, TRAIT_STUN_ON_NEXT_SHOVE, TRAIT_STATUS_EFFECT(id)) REMOVE_TRAIT(owner, TRAIT_DAZED, TRAIT_STATUS_EFFECT(id))
if(vulnverability_overlay) if(dazed_overlay)
clear_stun_vulnverability_overlay() clear_dazed_overlay()
/// If our owner is either stunned, paralzyed or immobilized, we remove the status effect. /// If our owner is either stunned, paralzyed or immobilized, we remove the status effect.
/// This is both an anti-chainstun measure and a sanity check. /// This is both an anti-chainstun measure and a sanity check.
/datum/status_effect/next_shove_stuns/proc/clear_stun_vulnverability(mob/living/source, amount = 0, ignore_canstun = FALSE) /datum/status_effect/dazed/proc/clear_daze(mob/living/source, amount = 0, ignore_canstun = FALSE)
SIGNAL_HANDLER SIGNAL_HANDLER
if(amount > 0) if(amount > 0)
// Making absolutely sure we're removing this overlay // Making absolutely sure we're removing this overlay
clear_stun_vulnverability_overlay() clear_dazed_overlay()
qdel(src) qdel(src)
/datum/status_effect/next_shove_stuns/proc/clear_stun_vulnverability_on_death(mob/living/source) /datum/status_effect/dazed/proc/clear_daze_on_stand(mob/living/source, new_position)
SIGNAL_HANDLER SIGNAL_HANDLER
clear_stun_vulnverability_overlay() if(new_position == STANDING_UP)
clear_dazed_overlay()
qdel(src)
/datum/status_effect/dazed/proc/clear_daze_on_death(mob/living/source)
SIGNAL_HANDLER
clear_dazed_overlay()
qdel(src) qdel(src)
/// Clears our overlay where needed. /// Clears our overlay where needed.
/datum/status_effect/next_shove_stuns/proc/clear_stun_vulnverability_overlay() /datum/status_effect/dazed/proc/clear_dazed_overlay()
owner.cut_overlay(vulnverability_overlay) owner.cut_overlay(dazed_overlay)
vulnverability_overlay = null dazed_overlay = null
/// Status effect to prevent stuns from a shove /// Status effect to prevent stuns from a shove
/// Only applied by shoving someone to paralyze them /// Only applied by shoving someone to paralyze them

View File

@@ -150,7 +150,7 @@
step(harmed_atom, REVERSE_DIR(harmed_atom.dir)) step(harmed_atom, REVERSE_DIR(harmed_atom.dir))
///Handle the atom being slipped over ///Handle the atom being slipped over
/atom/proc/handle_slip(mob/living/carbon/slipped_carbon, knockdown_amount, obj/slipping_object, lube, paralyze, force_drop) /atom/proc/handle_slip(mob/living/carbon/slipped_carbon, knockdown_amount, obj/slipping_object, lube, paralyze, daze, force_drop)
return return
///Used for making a sound when a mob involuntarily falls into the ground. ///Used for making a sound when a mob involuntarily falls into the ground.

View File

@@ -382,7 +382,7 @@
RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_transform)) RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_transform))
/obj/item/melee/baton/telescopic/additional_effects_non_cyborg(mob/living/target, mob/living/user) /obj/item/melee/baton/telescopic/additional_effects_non_cyborg(mob/living/target, mob/living/user)
target.apply_status_effect(/datum/status_effect/next_shove_stuns) target.apply_status_effect(/datum/status_effect/dazed)
/obj/item/melee/baton/telescopic/suicide_act(mob/living/user) /obj/item/melee/baton/telescopic/suicide_act(mob/living/user)
var/mob/living/carbon/human/human_user = user var/mob/living/carbon/human/human_user = user

View File

@@ -348,8 +348,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0)
custom_materials = list(/datum/material/iron =SHEET_MATERIAL_AMOUNT) custom_materials = list(/datum/material/iron =SHEET_MATERIAL_AMOUNT)
item_flags = SKIP_FANTASY_ON_SPAWN item_flags = SKIP_FANTASY_ON_SPAWN
// Whether or not the chair causes the target to become shove stun vulnerable if smashed against someone from behind. // Duration of daze inflicted when the chair is smashed against someone from behind.
var/inflicts_stun_vulnerability = TRUE var/daze_amount = 3 SECONDS
// What structure type does this chair become when placed? // What structure type does this chair become when placed?
var/obj/structure/chair/origin_type = /obj/structure/chair var/obj/structure/chair/origin_type = /obj/structure/chair
@@ -432,11 +432,9 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0)
user.visible_message(span_danger("[user] smashes [src] to pieces against [give_this_fucker_the_chair]")) user.visible_message(span_danger("[user] smashes [src] to pieces against [give_this_fucker_the_chair]"))
if(!HAS_TRAIT(give_this_fucker_the_chair, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED)) if(!HAS_TRAIT(give_this_fucker_the_chair, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED))
if(vulnerable_hit || give_this_fucker_the_chair.get_timed_status_effect_duration(/datum/status_effect/staggered)) if(vulnerable_hit || give_this_fucker_the_chair.get_timed_status_effect_duration(/datum/status_effect/staggered))
give_this_fucker_the_chair.Knockdown(2 SECONDS) give_this_fucker_the_chair.Knockdown(2 SECONDS, daze_amount = daze_amount)
if(give_this_fucker_the_chair.health < give_this_fucker_the_chair.maxHealth*0.5) if(give_this_fucker_the_chair.health < give_this_fucker_the_chair.maxHealth*0.5)
give_this_fucker_the_chair.adjust_confusion(10 SECONDS) give_this_fucker_the_chair.adjust_confusion(10 SECONDS)
if(inflicts_stun_vulnerability)
give_this_fucker_the_chair.apply_status_effect(/datum/status_effect/next_shove_stuns)
smash(user) smash(user)
@@ -470,7 +468,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0)
hitsound = 'sound/items/weapons/genhit1.ogg' hitsound = 'sound/items/weapons/genhit1.ogg'
origin_type = /obj/structure/chair/stool/bamboo origin_type = /obj/structure/chair/stool/bamboo
max_integrity = 40 //Submissive and breakable unlike the chad iron stool max_integrity = 40 //Submissive and breakable unlike the chad iron stool
inflicts_stun_vulnerability = FALSE //Not hard enough to cause them to become vulnerable to a shove daze_amount = 0 //Not hard enough to cause them to become dazed
/obj/item/chair/stool/narsie_act() /obj/item/chair/stool/narsie_act()
return //sturdy enough to ignore a god return //sturdy enough to ignore a god
@@ -484,7 +482,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0)
hitsound = 'sound/items/weapons/genhit1.ogg' hitsound = 'sound/items/weapons/genhit1.ogg'
origin_type = /obj/structure/chair/wood origin_type = /obj/structure/chair/wood
custom_materials = null custom_materials = null
inflicts_stun_vulnerability = FALSE daze_amount = 0
/obj/item/chair/wood/narsie_act() /obj/item/chair/wood/narsie_act()
return return
@@ -606,7 +604,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0)
throw_range = 5 //Lighter Weight --> Flies Farther. throw_range = 5 //Lighter Weight --> Flies Farther.
custom_materials = list(/datum/material/plastic =SHEET_MATERIAL_AMOUNT) custom_materials = list(/datum/material/plastic =SHEET_MATERIAL_AMOUNT)
max_integrity = 70 max_integrity = 70
inflicts_stun_vulnerability = FALSE daze_amount = 0
origin_type = /obj/structure/chair/plastic origin_type = /obj/structure/chair/plastic
/obj/structure/chair/musical /obj/structure/chair/musical

View File

@@ -345,8 +345,7 @@
SIGNAL_HANDLER SIGNAL_HANDLER
if((shove_flags & SHOVE_KNOCKDOWN_BLOCKED) || !(shove_flags & SHOVE_BLOCKED)) if((shove_flags & SHOVE_KNOCKDOWN_BLOCKED) || !(shove_flags & SHOVE_BLOCKED))
return return
target.Knockdown(SHOVE_KNOCKDOWN_TABLE) target.Knockdown(SHOVE_KNOCKDOWN_TABLE, daze_amount = 3 SECONDS)
target.apply_status_effect(/datum/status_effect/next_shove_stuns)
target.visible_message(span_danger("[shover.name] shoves [target.name] onto \the [src]!"), target.visible_message(span_danger("[shover.name] shoves [target.name] onto \the [src]!"),
span_userdanger("You're shoved onto \the [src] by [shover.name]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, shover) span_userdanger("You're shoved onto \the [src] by [shover.name]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, shover)
to_chat(shover, span_danger("You shove [target.name] onto \the [src]!")) to_chat(shover, span_danger("You shove [target.name] onto \the [src]!"))

View File

@@ -340,7 +340,7 @@
wash(CLEAN_WASH, TRUE) wash(CLEAN_WASH, TRUE)
return TRUE return TRUE
/turf/open/handle_slip(mob/living/slipper, knockdown_amount, obj/slippable, lube, paralyze_amount, force_drop) /turf/open/handle_slip(mob/living/slipper, knockdown_amount, obj/slippable, lube, paralyze_amount, daze_amount, force_drop)
if(slipper.movement_type & MOVETYPES_NOT_TOUCHING_GROUND) if(slipper.movement_type & MOVETYPES_NOT_TOUCHING_GROUND)
return FALSE return FALSE
if(!has_gravity(src)) if(!has_gravity(src))
@@ -393,8 +393,8 @@
slipper.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH, 10 SECONDS) slipper.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH, 10 SECONDS)
slipper.stop_pulling() slipper.stop_pulling()
else else
slipper.Knockdown(knockdown_amount)
slipper.Paralyze(paralyze_amount) slipper.Paralyze(paralyze_amount)
slipper.Knockdown(knockdown_amount, daze_amount = daze_amount)
if(!isnull(buckled_obj) && !ismob(buckled_obj)) if(!isnull(buckled_obj) && !ismob(buckled_obj))
buckled_obj.unbuckle_mob(slipper) buckled_obj.unbuckle_mob(slipper)

View File

@@ -64,9 +64,8 @@
return TRUE return TRUE
carbon_hit.adjust_timed_status_effect(4 SECONDS, /datum/status_effect/speech/slurring/heretic) carbon_hit.adjust_timed_status_effect(4 SECONDS, /datum/status_effect/speech/slurring/heretic)
carbon_hit.AdjustKnockdown(5 SECONDS) carbon_hit.AdjustKnockdown(5 SECONDS, daze_amount = 3 SECONDS)
carbon_hit.adjustStaminaLoss(80) carbon_hit.adjustStaminaLoss(80)
carbon_hit.apply_status_effect(/datum/status_effect/next_shove_stuns)
return TRUE return TRUE

View File

@@ -356,7 +356,7 @@
/obj/effect/meteor/banana/ram_turf(turf/bumped) /obj/effect/meteor/banana/ram_turf(turf/bumped)
for(var/mob/living/slipped in get_turf(bumped)) for(var/mob/living/slipped in get_turf(bumped))
slipped.slip(100, slipped.loc,- GALOSHES_DONT_HELP|SLIDE, 0, FALSE) slipped.slip(100, slipped.loc,- GALOSHES_DONT_HELP|SLIDE)
slipped.visible_message(span_warning("[src] honks [slipped] to the floor!"), span_userdanger("[src] harmlessly passes through you, knocking you over.")) slipped.visible_message(span_warning("[src] honks [slipped] to the floor!"), span_userdanger("[src] harmlessly passes through you, knocking you over."))
get_hit() get_hit()

View File

@@ -712,7 +712,7 @@
/mob/living/carbon/get_shove_flags(mob/living/shover, obj/item/weapon) /mob/living/carbon/get_shove_flags(mob/living/shover, obj/item/weapon)
. = ..() . = ..()
. |= SHOVE_CAN_STAGGER . |= SHOVE_CAN_STAGGER
if(IsKnockdown() && !IsParalyzed() && HAS_TRAIT(src, TRAIT_STUN_ON_NEXT_SHOVE)) if(IsKnockdown() && !IsParalyzed() && HAS_TRAIT(src, TRAIT_DAZED))
. |= SHOVE_CAN_KICK_SIDE . |= SHOVE_CAN_KICK_SIDE
if(HAS_TRAIT(src, TRAIT_NO_SIDE_KICK)) // added as an extra check, just in case if(HAS_TRAIT(src, TRAIT_NO_SIDE_KICK)) // added as an extra check, just in case
. &= ~SHOVE_CAN_KICK_SIDE . &= ~SHOVE_CAN_KICK_SIDE

View File

@@ -1,10 +1,10 @@
/mob/living/carbon/slip(knockdown_amount, obj/slipped_on, lube_flags, paralyze, force_drop = FALSE) /mob/living/carbon/slip(knockdown_amount, obj/slipped_on, lube_flags, paralyze, daze, force_drop = FALSE)
if(movement_type & MOVETYPES_NOT_TOUCHING_GROUND) if(movement_type & MOVETYPES_NOT_TOUCHING_GROUND)
return FALSE return FALSE
if(!(lube_flags & SLIDE_ICE)) if(!(lube_flags & SLIDE_ICE))
log_combat(src, (slipped_on || get_turf(src)), "slipped on the", null, ((lube_flags & SLIDE) ? "(SLIDING)" : null)) log_combat(src, (slipped_on || get_turf(src)), "slipped on the", null, ((lube_flags & SLIDE) ? "(SLIDING)" : null))
..() ..()
return loc.handle_slip(src, knockdown_amount, slipped_on, lube_flags, paralyze, force_drop) return loc.handle_slip(src, knockdown_amount, slipped_on, lube_flags, paralyze, daze, force_drop)
/mob/living/carbon/Move(NewLoc, direct) /mob/living/carbon/Move(NewLoc, direct)
. = ..() . = ..()

View File

@@ -140,11 +140,9 @@
if(src == target || LAZYFIND(target.buckled_mobs, src) || !iscarbon(target)) if(src == target || LAZYFIND(target.buckled_mobs, src) || !iscarbon(target))
return return
if(!(shove_flags & SHOVE_KNOCKDOWN_BLOCKED)) if(!(shove_flags & SHOVE_KNOCKDOWN_BLOCKED))
target.Knockdown(SHOVE_KNOCKDOWN_HUMAN) target.Knockdown(SHOVE_KNOCKDOWN_HUMAN, daze_amount = 3 SECONDS)
target.apply_status_effect(/datum/status_effect/next_shove_stuns)
if(!HAS_TRAIT(src, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED)) if(!HAS_TRAIT(src, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED))
Knockdown(SHOVE_KNOCKDOWN_COLLATERAL) Knockdown(SHOVE_KNOCKDOWN_COLLATERAL, daze_amount = 3 SECONDS)
apply_status_effect(/datum/status_effect/next_shove_stuns)
target.visible_message(span_danger("[shover] shoves [target.name] into [name]!"), target.visible_message(span_danger("[shover] shoves [target.name] into [name]!"),
span_userdanger("You're shoved into [name] by [shover]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, src) span_userdanger("You're shoved into [name] by [shover]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, src)
to_chat(src, span_danger("You shove [target.name] into [name]!")) to_chat(src, span_danger("You shove [target.name] into [name]!"))

View File

@@ -9,7 +9,7 @@
return return
return considering return considering
/mob/living/carbon/human/slip(knockdown_amount, obj/slipped_on, lube_flags, paralyze, force_drop = FALSE) /mob/living/carbon/human/slip(knockdown_amount, obj/slipped_on, lube_flags, paralyze, daze, force_drop = FALSE)
if(HAS_TRAIT(src, TRAIT_NO_SLIP_ALL)) if(HAS_TRAIT(src, TRAIT_NO_SLIP_ALL))
return FALSE return FALSE

View File

@@ -3,7 +3,7 @@
amount = dna.species.spec_stun(src, amount) amount = dna.species.spec_stun(src, amount)
return ..() return ..()
/mob/living/carbon/human/Knockdown(amount, ignore_canstun = FALSE) /mob/living/carbon/human/Knockdown(amount, daze_amount = 0, ignore_canstun = FALSE)
amount = dna.species.spec_stun(src, amount) * physiology.knockdown_mod amount = dna.species.spec_stun(src, amount) * physiology.knockdown_mod
return ..() return ..()

View File

@@ -748,8 +748,7 @@
if(!(shove_flags & SHOVE_DIRECTIONAL_BLOCKED) && (SEND_SIGNAL(target_shove_turf, COMSIG_LIVING_DISARM_COLLIDE, src, target, shove_flags, weapon) & COMSIG_LIVING_SHOVE_HANDLED)) if(!(shove_flags & SHOVE_DIRECTIONAL_BLOCKED) && (SEND_SIGNAL(target_shove_turf, COMSIG_LIVING_DISARM_COLLIDE, src, target, shove_flags, weapon) & COMSIG_LIVING_SHOVE_HANDLED))
return return
if((shove_flags & SHOVE_BLOCKED) && !(shove_flags & (SHOVE_KNOCKDOWN_BLOCKED|SHOVE_CAN_KICK_SIDE))) if((shove_flags & SHOVE_BLOCKED) && !(shove_flags & (SHOVE_KNOCKDOWN_BLOCKED|SHOVE_CAN_KICK_SIDE)))
target.Knockdown(SHOVE_KNOCKDOWN_SOLID) target.Knockdown(SHOVE_KNOCKDOWN_SOLID, daze_amount = 3 SECONDS)
target.apply_status_effect(/datum/status_effect/next_shove_stuns)
target.visible_message(span_danger("[name] shoves [target.name], knocking [target.p_them()] down!"), target.visible_message(span_danger("[name] shoves [target.name], knocking [target.p_them()] down!"),
span_userdanger("You're knocked down from a shove by [name]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, src) span_userdanger("You're knocked down from a shove by [name]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, src)
to_chat(src, span_danger("You shove [target.name], knocking [target.p_them()] down!")) to_chat(src, span_danger("You shove [target.name], knocking [target.p_them()] down!"))

View File

@@ -89,7 +89,7 @@
return K.duration - world.time return K.duration - world.time
return 0 return 0
/mob/living/proc/Knockdown(amount, ignore_canstun = FALSE) //Can't go below remaining duration /mob/living/proc/Knockdown(amount, daze_amount = 0, ignore_canstun = FALSE) //Can't go below remaining duration
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_KNOCKDOWN, amount, ignore_canstun) & COMPONENT_NO_STUN) if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_KNOCKDOWN, amount, ignore_canstun) & COMPONENT_NO_STUN)
return return
if(check_stun_immunity(CANKNOCKDOWN, ignore_canstun)) if(check_stun_immunity(CANKNOCKDOWN, ignore_canstun))
@@ -99,6 +99,8 @@
K.duration = max(world.time + amount, K.duration) K.duration = max(world.time + amount, K.duration)
else if(amount > 0) else if(amount > 0)
K = apply_status_effect(/datum/status_effect/incapacitating/knockdown, amount) K = apply_status_effect(/datum/status_effect/incapacitating/knockdown, amount)
if(daze_amount > 0)
apply_status_effect(/datum/status_effect/dazed, daze_amount)
return K return K
/mob/living/proc/SetKnockdown(amount, ignore_canstun = FALSE) //Sets remaining duration /mob/living/proc/SetKnockdown(amount, ignore_canstun = FALSE) //Sets remaining duration
@@ -117,7 +119,7 @@
K = apply_status_effect(/datum/status_effect/incapacitating/knockdown, amount) K = apply_status_effect(/datum/status_effect/incapacitating/knockdown, amount)
return K return K
/mob/living/proc/AdjustKnockdown(amount, ignore_canstun = FALSE) //Adds to remaining duration /mob/living/proc/AdjustKnockdown(amount, daze_amount = 0, ignore_canstun = FALSE) //Adds to remaining duration
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_KNOCKDOWN, amount, ignore_canstun) & COMPONENT_NO_STUN) if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_KNOCKDOWN, amount, ignore_canstun) & COMPONENT_NO_STUN)
return return
if(check_stun_immunity(CANKNOCKDOWN, ignore_canstun)) if(check_stun_immunity(CANKNOCKDOWN, ignore_canstun))
@@ -127,6 +129,8 @@
K.duration += amount K.duration += amount
else if(amount > 0) else if(amount > 0)
K = apply_status_effect(/datum/status_effect/incapacitating/knockdown, amount) K = apply_status_effect(/datum/status_effect/incapacitating/knockdown, amount)
if(daze_amount > 0)
apply_status_effect(/datum/status_effect/dazed, daze_amount)
return K return K
/* IMMOBILIZED */ /* IMMOBILIZED */

View File

@@ -376,12 +376,13 @@
* slipped_on - optional, what'd we slip on? if not set, we assume they just fell over * slipped_on - optional, what'd we slip on? if not set, we assume they just fell over
* lube - bitflag of "lube flags", see [mobs.dm] for more information * lube - bitflag of "lube flags", see [mobs.dm] for more information
* paralyze - time (in deciseconds) the slip leaves them paralyzed / unable to move * paralyze - time (in deciseconds) the slip leaves them paralyzed / unable to move
* daze - time (in deciseconds) the slip leaves them vulnerable to shove stuns
* force_drop = the slip forces them to drop held items * force_drop = the slip forces them to drop held items
*/ */
/mob/proc/slip(knockdown_amount, obj/slipped_on, lube_flags, paralyze, force_drop = FALSE) /mob/proc/slip(knockdown_amount, obj/slipped_on, lube_flags, paralyze, daze, force_drop = FALSE)
add_mob_memory(/datum/memory/was_slipped, antagonist = slipped_on) add_mob_memory(/datum/memory/was_slipped, antagonist = slipped_on)
SEND_SIGNAL(src, COMSIG_MOB_SLIPPED, knockdown_amount, slipped_on, lube_flags, paralyze, force_drop) SEND_SIGNAL(src, COMSIG_MOB_SLIPPED, knockdown_amount, slipped_on, lube_flags, paralyze, daze, force_drop)
//bodypart selection verbs - Cyberboss //bodypart selection verbs - Cyberboss
//8: repeated presses toggles through head - eyes - mouth //8: repeated presses toggles through head - eyes - mouth

View File

@@ -23,7 +23,7 @@
if(M.can_block_magic()) if(M.can_block_magic())
return BULLET_ACT_BLOCK return BULLET_ACT_BLOCK
else else
M.slip(100, M.loc, GALOSHES_DONT_HELP|SLIDE, 0, FALSE) M.slip(100, M.loc, GALOSHES_DONT_HELP|SLIDE)
// Mime // Mime

View File

@@ -951,7 +951,7 @@
for(var/mob/living/nearby_mob in range(location, 3)) for(var/mob/living/nearby_mob in range(location, 3))
do_sparks(3,FALSE,nearby_mob) do_sparks(3,FALSE,nearby_mob)
do_teleport(nearby_mob, get_turf(holder.my_atom), 3, no_effects=TRUE) do_teleport(nearby_mob, get_turf(holder.my_atom), 3, no_effects=TRUE)
nearby_mob.Knockdown(20, TRUE) nearby_mob.Knockdown(20, ignore_canstun = TRUE)
nearby_mob.add_atom_colour("#cebfff", WASHABLE_COLOUR_PRIORITY) nearby_mob.add_atom_colour("#cebfff", WASHABLE_COLOUR_PRIORITY)
do_sparks(3,FALSE,nearby_mob) do_sparks(3,FALSE,nearby_mob)
clear_products(holder, step_volume_added) clear_products(holder, step_volume_added)