From 036a7450d376f02fee973ddbd520db795c554465 Mon Sep 17 00:00:00 2001 From: Will <7099514+Willburd@users.noreply.github.com> Date: Thu, 16 Jul 2026 22:39:56 -0400 Subject: [PATCH] unify ranged_disarm procs (#19613) * unify ranged_disarm procs * clarity * shoot at that --- code/game/objects/items.dm | 51 +++++++++++++++++++ .../objects/items/weapons/material/misc.dm | 42 +-------------- code/modules/projectiles/projectile/hook.dm | 41 +-------------- 3 files changed, 55 insertions(+), 79 deletions(-) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index cfa8b21e3ba..ed9a102b28e 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -1216,3 +1216,54 @@ Note: This proc can be overwritten to allow for different types of auto-alignmen name = cleanname if(cleandesc) desc = cleandesc + +/obj/item/proc/ranged_disarm(mob/living/carbon/human/target, mob/living/user, zone_override = null) + if(!ishuman(target)) + return + + var/target_zone + var/list/holding + if(istype(src,/obj/item/projectile)) + // Projectiles use their aim, and always disarm + var/obj/item/projectile/bullet = src + target_zone = bullet.def_zone + holding = list(target.get_active_hand() = 100, target.get_inactive_hand() = 100) + else + // Melee attacks use user's targeting zone, and have a decent chance to disarm main hand + target_zone = user.zone_sel.selecting + holding = list(target.get_active_hand() = 40, target.get_inactive_hand() = 20) + if(zone_override) // Argument override + target_zone = zone_override + + if(target_zone in list(BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND)) // Guns are complex devices, both of a mechanical and electronic nature. A weird gravity ball or other type of object trying to pull or grab it is likely not safe. + for(var/obj/item/gun/W in holding) + if(W && prob(holding[W])) + var/list/turfs = list() + for(var/turf/T in view()) + turfs += T + if(turfs.len) + var/turf/shoot_at_turf = pick(turfs) + visible_message(span_danger("[target]'s [W] goes off due to \the [src]!")) + return W.afterattack(shoot_at_turf,target) + + if(!(target.species.flags & NO_SLIP) && prob(10) && (target_zone in list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT))) + var/armor_check = target.run_armor_check(target_zone, "melee") + target.apply_effect(3, WEAKEN, armor_check) + playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + if(armor_check < 60) + visible_message(span_danger("\The [src] has tripped [target]!")) + else + visible_message(span_warning("\The [src] attempted to trip [target]!")) + return + + if(target.break_all_grabs(user)) + playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + return + + if(target_zone in list(BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND)) + for(var/obj/item/I in holding) + if(I && prob(holding[I])) + target.drop_from_inventory(I) + visible_message(span_danger("\The [src] has disarmed [target]!")) + playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + return diff --git a/code/game/objects/items/weapons/material/misc.dm b/code/game/objects/items/weapons/material/misc.dm index f463a5ee037..36a2e7e2f4f 100644 --- a/code/game/objects/items/weapons/material/misc.dm +++ b/code/game/objects/items/weapons/material/misc.dm @@ -142,10 +142,10 @@ if(I_HURT) if(prob(10) && ishuman(target) && (user.zone_sel in list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT, BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND))) to_chat(target, span_warning("\The [src] rips at your hands!")) - ranged_disarm(target) + ranged_disarm(target, user) if(I_DISARM) if(prob(min(90, force * 3)) && ishuman(target) && (user.zone_sel in list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT, BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND))) - ranged_disarm(target) + ranged_disarm(target, user) else target.visible_message(span_danger("\The [src] sends \the [target] stumbling away.")) target.Move(get_step(target,get_dir(user,target))) @@ -158,44 +158,6 @@ ..() -/obj/item/material/whip/proc/ranged_disarm(mob/living/carbon/human/H, mob/living/user) - if(istype(H)) - var/list/holding = list(H.get_active_hand() = 40, H.get_inactive_hand() = 20) - - if(user.zone_sel in list(BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND)) - for(var/obj/item/gun/W in holding) - if(W && prob(holding[W])) - var/list/turfs = list() - for(var/turf/T in view()) - turfs += T - if(turfs.len) - var/turf/target = pick(turfs) - visible_message(span_danger("[H]'s [W] goes off due to \the [src]!")) - return W.afterattack(target,H) - - if(!(H.species.flags & NO_SLIP) && prob(10) && (user.zone_sel in list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT))) - var/armor_check = H.run_armor_check(user.zone_sel, "melee") - H.apply_effect(3, WEAKEN, armor_check) - playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - if(armor_check < 60) - visible_message(span_danger("\The [src] has tripped [H]!")) - else - visible_message(span_warning("\The [src] attempted to trip [H]!")) - return - - else - if(H.break_all_grabs(user)) - playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - return - - if(user.zone_sel in list(BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND)) - for(var/obj/item/I in holding) - if(I && prob(holding[I])) - H.drop_from_inventory(I) - visible_message(span_danger("\The [src] has disarmed [H]!")) - playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - return - /obj/item/material/whip/attack_self(mob/user) . = ..(user) if(.) diff --git a/code/modules/projectiles/projectile/hook.dm b/code/modules/projectiles/projectile/hook.dm index 2d074745004..7ef18686f7e 100644 --- a/code/modules/projectiles/projectile/hook.dm +++ b/code/modules/projectiles/projectile/hook.dm @@ -79,43 +79,6 @@ /obj/item/projectile/energy/hook/on_impact(atom/A) perform_intent_unique(get_turf(A)) -/obj/item/projectile/energy/hook/proc/ranged_disarm(mob/living/carbon/human/H) - if(istype(H)) - var/list/holding = list(H.get_active_hand() = 60, H.get_inactive_hand() = 40) - - for(var/obj/item/gun/W in holding) // Guns are complex devices, both of a mechanical and electronic nature. A weird gravity ball or other type of object trying to pull or grab it is likely not safe. - if(W && prob(holding[W])) - var/list/turfs = list() - for(var/turf/T in view()) - turfs += T - if(turfs.len) - var/turf/target = pick(turfs) - visible_message(span_danger("[H]'s [W] goes off due to \the [src]!")) - return W.afterattack(target,H) - - if(!(H.species.flags & NO_SLIP) && prob(50)) - var/armor_check = H.run_armor_check(def_zone, "melee") - H.apply_effect(3, WEAKEN, armor_check) - playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - if(armor_check < 60) - visible_message(span_danger("\The [src] has pushed [H]!")) - else - visible_message(span_warning("\The [src] attempted to push [H]!")) - return - - else - if(H.break_all_grabs(firer)) - playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - return - - for(var/obj/item/I in holding) - if(I) - H.drop_from_inventory(I) - visible_message(span_danger("\The [src] has disarmed [H]!")) - playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - return - - /obj/item/projectile/energy/hook/proc/perform_intent_unique(atom/target) playsound(src, impact_sound, 40, 1) var/success = FALSE @@ -169,12 +132,12 @@ if(I_HURT) if(prob(10) && ishuman(L)) to_chat(L, span_warning("\The [src] rips at your hands!")) - ranged_disarm(L) + ranged_disarm(L, null) success = TRUE done_mob_unique = TRUE if(I_DISARM) if(prob(disarm_chance) && ishuman(L)) - ranged_disarm(L) + ranged_disarm(L, null) else L.visible_message(span_danger("\The [src] sends \the [L] stumbling backwards.")) L.throw_at(get_turf(get_step(L,get_dir(firer,L))), 1, 1, src)