diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm index 160849218d1..b919f94a1c1 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm @@ -139,6 +139,9 @@ #define COMSIG_LIVING_EARLY_UNARMED_ATTACK "human_pre_attack_hand" /// from mob/living/*/UnarmedAttack(): (mob/living/source, atom/target, proximity, modifiers) #define COMSIG_LIVING_UNARMED_ATTACK "living_unarmed_attack" +///From base of mob/living/MobBump(): (mob/bumped, mob/living/bumper) +#define COMSIG_LIVING_PRE_MOB_BUMP "movable_pre_bump" + #define COMPONENT_LIVING_BLOCK_PRE_MOB_BUMP (1<<0) ///From base of mob/living/MobBump() (mob/living) #define COMSIG_LIVING_MOB_BUMP "living_mob_bump" ///From base of mob/living/Bump() (turf/closed) diff --git a/code/datums/components/gunpoint.dm b/code/datums/components/gunpoint.dm index c248b4f18c0..bf44f1c4b3c 100644 --- a/code/datums/components/gunpoint.dm +++ b/code/datums/components/gunpoint.dm @@ -36,7 +36,16 @@ target = targ weapon = wep - RegisterSignals(targ, list(COMSIG_MOB_ATTACK_HAND, COMSIG_MOB_ITEM_ATTACK, COMSIG_MOVABLE_MOVED, COMSIG_MOB_FIRED_GUN), PROC_REF(trigger_reaction)) + RegisterSignals(targ, list( + COMSIG_MOB_ATTACK_HAND, + COMSIG_MOB_ITEM_ATTACK, + COMSIG_MOVABLE_MOVED, + COMSIG_MOB_FIRED_GUN, + COMSIG_MOVABLE_SET_GRAB_STATE, + COMSIG_LIVING_START_PULL), PROC_REF(trigger_reaction)) + RegisterSignal(targ, COMSIG_ATOM_EXAMINE, PROC_REF(examine_target)) + RegisterSignal(targ, COMSIG_LIVING_PRE_MOB_BUMP, PROC_REF(block_bumps_target)) + RegisterSignals(targ, list(COMSIG_HUMAN_DISARM_HIT, COMSIG_LIVING_GET_PULLED), PROC_REF(cancel)) RegisterSignals(weapon, list(COMSIG_ITEM_DROPPED, COMSIG_ITEM_EQUIPPED), PROC_REF(cancel)) var/distance = min(get_dist(shooter, target), 1) // treat 0 distance as adjacent @@ -77,6 +86,9 @@ RegisterSignal(parent, COMSIG_MOB_ATTACK_HAND, PROC_REF(check_shove)) RegisterSignal(parent, COMSIG_MOB_UPDATE_SIGHT, PROC_REF(check_deescalate)) RegisterSignals(parent, list(COMSIG_LIVING_START_PULL, COMSIG_MOVABLE_BUMP), PROC_REF(check_bump)) + RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(examine)) + RegisterSignal(parent, COMSIG_LIVING_PRE_MOB_BUMP, PROC_REF(block_bumps_parent)) + RegisterSignal(parent, COMSIG_HUMAN_DISARM_HIT, PROC_REF(cancel)) /datum/component/gunpoint/UnregisterFromParent() UnregisterSignal(parent, COMSIG_MOVABLE_MOVED) @@ -84,6 +96,9 @@ UnregisterSignal(parent, COMSIG_MOB_UPDATE_SIGHT) UnregisterSignal(parent, COMSIG_MOB_ATTACK_HAND) UnregisterSignal(parent, list(COMSIG_LIVING_START_PULL, COMSIG_MOVABLE_BUMP)) + UnregisterSignal(parent, COMSIG_ATOM_EXAMINE) + UnregisterSignal(parent, COMSIG_LIVING_PRE_MOB_BUMP) + UnregisterSignal(parent, COMSIG_HUMAN_DISARM_HIT) ///If the shooter bumps the target, cancel the holdup to avoid cheesing and forcing the charged shot /datum/component/gunpoint/proc/check_bump(atom/B, atom/A) @@ -195,6 +210,30 @@ ) INVOKE_ASYNC(src, PROC_REF(trigger_reaction)) +///Shows if the parent is holding someone at gunpoint +/datum/component/gunpoint/proc/examine(datum/source, mob/user, list/examine_list) + SIGNAL_HANDLER + if(user in viewers(target)) + examine_list += span_boldwarning("[parent] [parent.p_are()] holding [target] at gunpoint with [weapon]!") + +///Shows if the examine target is being held at gunpoint +/datum/component/gunpoint/proc/examine_target(datum/source, mob/user, list/examine_list) + SIGNAL_HANDLER + if(user in viewers(parent)) + examine_list += span_boldwarning("[target] [target.p_are()] being held at gunpoint by [parent]!") + +///Prevents bumping the shooter to break gunpoint since shove does that +/datum/component/gunpoint/proc/block_bumps_parent(mob/bumped, mob/living/bumper) + SIGNAL_HANDLER + to_chat(bumper, span_warning("[bumped] [bumped.p_are()] holding [target] at gunpoint, you cannot push past.")) + return COMPONENT_LIVING_BLOCK_PRE_MOB_BUMP + +///Prevents bumping the target by an ally to cheese and force the charged shot +/datum/component/gunpoint/proc/block_bumps_target(mob/bumped, mob/living/bumper) + SIGNAL_HANDLER + to_chat(bumper, span_warning("[bumped] [bumped.p_are()] being held at gunpoint, it's not wise to push [bumped.p_them()]!")) + return COMPONENT_LIVING_BLOCK_PRE_MOB_BUMP + #undef GUNPOINT_DELAY_STAGE_2 #undef GUNPOINT_DELAY_STAGE_3 #undef GUNPOINT_BASE_WOUND_BONUS diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm index 598b78ca9df..48b14f36cd0 100644 --- a/code/datums/status_effects/neutral.dm +++ b/code/datums/status_effects/neutral.dm @@ -149,9 +149,16 @@ /atom/movable/screen/alert/status_effect/holdup name = "Holding Up" - desc = "You're currently pointing a gun at someone." + desc = "You're currently pointing a gun at someone. Click to cancel." icon_state = "aimed" +/atom/movable/screen/alert/status_effect/holdup/Click(location, control, params) + . = ..() + if(!.) + return + var/datum/component/gunpoint/gunpoint = owner.GetComponent(/datum/component/gunpoint) + gunpoint?.cancel() + // this status effect is used to negotiate the high-fiving capabilities of all concerned parties /datum/status_effect/offering id = "offering" diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 8b8efbc23cd..d329dc819d7 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -94,6 +94,9 @@ if(move_intent == MOVE_INTENT_WALK) return TRUE + if(SEND_SIGNAL(M, COMSIG_LIVING_PRE_MOB_BUMP, src) & COMPONENT_LIVING_BLOCK_PRE_MOB_BUMP) + return TRUE + SEND_SIGNAL(src, COMSIG_LIVING_MOB_BUMP, M) //Even if we don't push/swap places, we "touched" them, so spread fire spreadFire(M)