mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-20 19:44:09 +01:00
Reworks disarms into shoves, mostly from TG (#18186)
* Disarm rework * martial arts should work * farie review * bug fix + sound * fixes all the things * fixes diagonals * fixes anchoring, buckling and adds feedback messages. * fixes blockers ontop of tables * grammar + tabling fix * steel review
This commit is contained in:
@@ -618,3 +618,7 @@
|
||||
|
||||
/atom/movable/proc/decompile_act(obj/item/matter_decompiler/C, mob/user) // For drones to decompile mobs and objs. See drone for an example.
|
||||
return FALSE
|
||||
|
||||
/// called when a mob gets shoved into an items turf. false means the mob will be shoved backwards normally, true means the mob will not be moved by the disarm proc.
|
||||
/atom/movable/proc/shove_impact(mob/living/target, mob/living/attacker)
|
||||
return FALSE
|
||||
|
||||
@@ -230,6 +230,20 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/table/shove_impact(mob/living/target, mob/living/attacker)
|
||||
if(locate(/obj/structure/table) in get_turf(target))
|
||||
return FALSE
|
||||
if(flipped)
|
||||
return FALSE
|
||||
var/pass_flags_cache = target.pass_flags
|
||||
target.pass_flags |= PASSTABLE
|
||||
if(target.Move(loc))
|
||||
. = TRUE
|
||||
target.Weaken(4 SECONDS)
|
||||
add_attack_logs(attacker, target, "pushed onto [src]", ATKLOG_ALL)
|
||||
else
|
||||
. = FALSE
|
||||
target.pass_flags = pass_flags_cache
|
||||
|
||||
/obj/structure/table/screwdriver_act(mob/user, obj/item/I)
|
||||
if(flags & NODECONSTRUCT)
|
||||
@@ -441,6 +455,16 @@
|
||||
L.Weaken(10 SECONDS)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/table/glass/shove_impact(mob/living/target, mob/living/attacker)
|
||||
var/pass_flags_cache = target.pass_flags
|
||||
target.pass_flags |= PASSTABLE
|
||||
if(target.Move(loc)) // moving onto a table smashes it, stunning them
|
||||
. = TRUE
|
||||
add_attack_logs(attacker, target, "pushed onto [src]", ATKLOG_ALL)
|
||||
else
|
||||
. = FALSE
|
||||
target.pass_flags = pass_flags_cache
|
||||
|
||||
/obj/structure/table/glass/deconstruct(disassembled = TRUE, wrench_disassembly = 0)
|
||||
if(!(flags & NODECONSTRUCT))
|
||||
if(disassembled)
|
||||
|
||||
@@ -513,6 +513,8 @@
|
||||
SEND_SIGNAL(target, COMSIG_PARENT_ATTACKBY)
|
||||
|
||||
/datum/species/proc/disarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
|
||||
if(user == target)
|
||||
return FALSE
|
||||
if(target.check_block())
|
||||
target.visible_message("<span class='warning'>[target] blocks [user]'s disarm attempt!</span>")
|
||||
return FALSE
|
||||
@@ -523,59 +525,73 @@
|
||||
return FALSE
|
||||
if(attacker_style && attacker_style.disarm_act(user, target) == TRUE)
|
||||
return TRUE
|
||||
user.do_attack_animation(target, ATTACK_EFFECT_DISARM)
|
||||
if(target.move_resist > user.pull_force)
|
||||
return FALSE
|
||||
if(!(target.status_flags & CANPUSH))
|
||||
return FALSE
|
||||
if(target.anchored)
|
||||
return FALSE
|
||||
if(target.buckled)
|
||||
target.buckled.unbuckle_mob(target)
|
||||
|
||||
var/shove_dir = get_dir(user.loc, target.loc)
|
||||
var/turf/shove_to = get_step(target.loc, shove_dir)
|
||||
playsound(shove_to, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
|
||||
if(shove_to == user.loc)
|
||||
return FALSE
|
||||
|
||||
//Directional checks to make sure that we're not shoving through a windoor or something like that
|
||||
var/directional_blocked = FALSE
|
||||
var/target_turf = get_turf(target)
|
||||
if(shove_dir in list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)) // if we are moving diagonially, we need to check if there are dense walls either side of us
|
||||
var/turf/T = get_step(target.loc, turn(shove_dir, 45)) // check to the left for a dense turf
|
||||
if(T.density)
|
||||
directional_blocked = TRUE
|
||||
else
|
||||
T = get_step(target.loc, turn(shove_dir, -45)) // check to the right for a dense turf
|
||||
if(T.density)
|
||||
directional_blocked = TRUE
|
||||
|
||||
if(!directional_blocked)
|
||||
for(var/obj/obj_content in target_turf) // check the tile we are on for border
|
||||
if(obj_content.flags & ON_BORDER && obj_content.dir & shove_dir && obj_content.density)
|
||||
directional_blocked = TRUE
|
||||
break
|
||||
if(!directional_blocked)
|
||||
for(var/obj/obj_content in shove_to) // check tile we are moving to for borders
|
||||
if(obj_content.flags & ON_BORDER && obj_content.dir & turn(shove_dir, 180) && obj_content.density)
|
||||
directional_blocked = TRUE
|
||||
break
|
||||
|
||||
if(!directional_blocked)
|
||||
for(var/atom/movable/AM in shove_to)
|
||||
if(AM.shove_impact(target, user)) // check for special interactions EG. tabling someone
|
||||
return TRUE
|
||||
|
||||
var/moved = target.Move(shove_to, shove_dir)
|
||||
if(!moved) //they got pushed into a dense object
|
||||
add_attack_logs(user, target, "Disarmed into a dense object", ATKLOG_ALL)
|
||||
target.visible_message("<span class='warning'>[user] slams [target] into an obstacle!</span>", \
|
||||
"<span class='userdanger'>You get slammed into the obstacle by [user]!</span>", \
|
||||
"You hear a loud thud.")
|
||||
if(!HAS_TRAIT(target, TRAIT_FLOORED))
|
||||
target.KnockDown(3 SECONDS)
|
||||
addtimer(CALLBACK(target, /mob/living.proc/SetKnockDown, 0), 3 SECONDS) // so you cannot chain stun someone
|
||||
else if(!user.IsStunned())
|
||||
target.Stun(0.5 SECONDS)
|
||||
else
|
||||
add_attack_logs(user, target, "Disarmed", ATKLOG_ALL)
|
||||
user.do_attack_animation(target, ATTACK_EFFECT_DISARM)
|
||||
if(target.w_uniform)
|
||||
target.w_uniform.add_fingerprint(user)
|
||||
var/obj/item/organ/external/affecting = target.get_organ(ran_zone(user.zone_selected))
|
||||
var/randn = rand(1, 100)
|
||||
if(randn <= 25)
|
||||
target.apply_effect(4 SECONDS, WEAKEN, target.run_armor_check(affecting, MELEE))
|
||||
playsound(target.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
target.visible_message("<span class='danger'>[user] has pushed [target]!</span>")
|
||||
add_attack_logs(user, target, "Pushed over", ATKLOG_ALL)
|
||||
if(!iscarbon(user))
|
||||
target.LAssailant = null
|
||||
else
|
||||
target.LAssailant = user
|
||||
return
|
||||
|
||||
var/talked = 0 // BubbleWrap
|
||||
|
||||
if(randn <= 60)
|
||||
//BubbleWrap: Disarming breaks a pull
|
||||
if(target.pulling)
|
||||
target.visible_message("<span class='danger'>[user] has broken [target]'s grip on [target.pulling]!</span>")
|
||||
talked = 1
|
||||
target.stop_pulling()
|
||||
|
||||
//BubbleWrap: Disarming also breaks a grab - this will also stop someone being choked, won't it?
|
||||
if(istype(target.l_hand, /obj/item/grab))
|
||||
var/obj/item/grab/lgrab = target.l_hand
|
||||
if(lgrab.affecting)
|
||||
target.visible_message("<span class='danger'>[user] has broken [target]'s grip on [lgrab.affecting]!</span>")
|
||||
talked = 1
|
||||
spawn(1)
|
||||
qdel(lgrab)
|
||||
if(istype(target.r_hand, /obj/item/grab))
|
||||
var/obj/item/grab/rgrab = target.r_hand
|
||||
if(rgrab.affecting)
|
||||
target.visible_message("<span class='danger'>[user] has broken [target]'s grip on [rgrab.affecting]!</span>")
|
||||
talked = 1
|
||||
spawn(1)
|
||||
qdel(rgrab)
|
||||
//End BubbleWrap
|
||||
|
||||
if(!talked) //BubbleWrap
|
||||
if(target.drop_item())
|
||||
target.visible_message("<span class='danger'>[user] has disarmed [target]!</span>")
|
||||
playsound(target.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
return
|
||||
|
||||
|
||||
playsound(target.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
target.visible_message("<span class='danger'>[user] attempted to disarm [target]!</span>")
|
||||
if(target.IsSlowed() && target.get_active_hand())
|
||||
target.drop_item()
|
||||
add_attack_logs(user, target, "Disarmed object out of hand", ATKLOG_ALL)
|
||||
else
|
||||
target.Slowed(2.5 SECONDS, 1)
|
||||
var/obj/item/I = target.get_active_hand()
|
||||
if(I)
|
||||
to_chat(target, "<span class='warning'>Your grip on [I] loosens!</span>")
|
||||
add_attack_logs(user, target, "Disarmed, shoved back", ATKLOG_ALL)
|
||||
target.stop_pulling()
|
||||
|
||||
/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style) //Handles any species-specific attackhand events.
|
||||
if(!istype(M))
|
||||
|
||||
@@ -374,3 +374,12 @@
|
||||
|
||||
/mob/living/proc/cult_self_harm(damage)
|
||||
return FALSE
|
||||
|
||||
/mob/living/shove_impact(mob/living/target, mob/living/attacker)
|
||||
if(IS_HORIZONTAL(src))
|
||||
return FALSE
|
||||
add_attack_logs(attacker, target, "pushed into [src]", ATKLOG_ALL)
|
||||
playsound(src, 'sound/weapons/punch1.ogg', 50, 1)
|
||||
target.KnockDown(1 SECONDS) // knock them both down
|
||||
KnockDown(1 SECONDS)
|
||||
return TRUE
|
||||
|
||||
Reference in New Issue
Block a user