From 94f7960ef2d09ac26953d362e10b5eb5bf728b10 Mon Sep 17 00:00:00 2001
From: AndroBetel <44546836+AndroBetel@users.noreply.github.com>
Date: Tue, 20 Feb 2024 10:45:05 +0300
Subject: [PATCH 1/2] 1
---
.../__DEFINES/dcs/signals/atom/signals_gun.dm | 3 +
code/_onclick/hud/fullscreen.dm | 6 +
code/datums/components/iff_fire_prevention.dm | 105 ++++++++++++
code/modules/projectiles/gun.dm | 96 ++++++-----
code/modules/projectiles/guns/smartgun.dm | 154 +++++-------------
colonialmarines.dme | 1 +
6 files changed, 215 insertions(+), 150 deletions(-)
create mode 100644 code/datums/components/iff_fire_prevention.dm
diff --git a/code/__DEFINES/dcs/signals/atom/signals_gun.dm b/code/__DEFINES/dcs/signals/atom/signals_gun.dm
index 51b8c25fce..e09b96503b 100644
--- a/code/__DEFINES/dcs/signals/atom/signals_gun.dm
+++ b/code/__DEFINES/dcs/signals/atom/signals_gun.dm
@@ -29,3 +29,6 @@
#define COMSIG_GUN_BEFORE_FIRE "gun_before_fire"
#define COMPONENT_CANCEL_GUN_BEFORE_FIRE (1<<0) //continue full-auto/burst attempts
#define COMPONENT_HARD_CANCEL_GUN_BEFORE_FIRE (1<<1) //hard stop firing
+
+/// Called when IFF is toggled on or off
+#define COMSIG_GUN_IFF_TOGGLED "gun_iff_toggled"
diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm
index 0bd2206091..b0e2d2b57e 100644
--- a/code/_onclick/hud/fullscreen.dm
+++ b/code/_onclick/hud/fullscreen.dm
@@ -61,6 +61,12 @@
else
client.remove_from_screen(screen)
+/mob/proc/get_maximum_view_range()
+ if(!client)
+ return world.view
+
+ var/offset = max(abs(client.pixel_x), abs(client.pixel_y))
+ return client.view + offset / 32
/atom/movable/screen/fullscreen
icon = 'icons/mob/hud/screen1_full.dmi'
diff --git a/code/datums/components/iff_fire_prevention.dm b/code/datums/components/iff_fire_prevention.dm
new file mode 100644
index 0000000000..d45b85887b
--- /dev/null
+++ b/code/datums/components/iff_fire_prevention.dm
@@ -0,0 +1,105 @@
+#define IFF_HALT_COOLDOWN 0.5 SECONDS
+
+/// A component that prevents gun (although you can attach it to anything else that shoot projectiles) from shooting when mob from the same faction stands in the way.
+/// You can also pass number of ticks, to make gun have an additional delay if firing prevention comes into play, but it is not neccesary.
+/datum/component/iff_fire_prevention
+ var/iff_additional_fire_delay
+ COOLDOWN_DECLARE(iff_halt_cooldown)
+
+/datum/component/iff_fire_prevention/Initialize(additional_fire_delay = 0)
+ . = ..()
+ iff_additional_fire_delay = additional_fire_delay
+
+
+/datum/component/iff_fire_prevention/RegisterWithParent()
+ . = ..()
+ RegisterSignal(parent, COMSIG_GUN_BEFORE_FIRE, PROC_REF(check_firing_lane))
+ RegisterSignal(parent, COMSIG_GUN_IFF_TOGGLED, PROC_REF(handle_iff_toggle))
+
+/datum/component/iff_fire_prevention/UnregisterFromParent()
+ . = ..()
+ UnregisterSignal(parent, list(
+ COMSIG_GUN_BEFORE_FIRE,
+ COMSIG_GUN_IFF_TOGGLED
+ ))
+
+/datum/component/iff_fire_prevention/proc/check_firing_lane(obj/firing_weapon, obj/projectile/projectile_to_fire, atom/target, mob/living/user)
+ SIGNAL_HANDLER
+
+ var/angle = get_angle(user, target)
+
+ var/range_to_check = user.get_maximum_view_range()
+
+ var/extended_target_turf = get_angle_target_turf(user, angle, range_to_check)
+
+ var/turf/starting_turf = get_turf(user)
+
+ if(!starting_turf || !extended_target_turf)
+ return COMPONENT_CANCEL_GUN_BEFORE_FIRE
+
+ var/list/checked_turfs = getline2(starting_turf, extended_target_turf)
+
+ //Don't shoot yourself, thanks
+ if(target == user)
+ if(COOLDOWN_FINISHED(src, iff_halt_cooldown) && user.client)
+ playsound_client(user.client, 'sound/weapons/smartgun_fail.ogg', src, 25)
+ to_chat(user, SPAN_WARNING("[firing_weapon] halts firing as an IFF marked target crosses your field of fire!"))
+ COOLDOWN_START(src, iff_halt_cooldown, IFF_HALT_COOLDOWN)
+ if(iff_additional_fire_delay)
+ var/obj/item/weapon/gun/gun = firing_weapon
+ if(istype(gun))
+ LAZYSET(user.fire_delay_next_fire, gun, world.time + iff_additional_fire_delay)
+ return COMPONENT_CANCEL_GUN_BEFORE_FIRE
+
+ //At some angles (scatter or otherwise) the original target is not in checked_turfs so we put it in there in order based on distance from user
+ //If we are literally clicking on someone with IFF then we don't want to fire, feels funny as a user otherwise
+ if(projectile_to_fire.original)
+ var/turf/original_target_turf = get_turf(projectile_to_fire.original)
+
+ if(original_target_turf && !(original_target_turf in checked_turfs))
+ var/user_to_target_dist = get_dist(starting_turf, original_target_turf)
+ var/list/temp_checked_turfs = checked_turfs.Copy()
+ checked_turfs = list()
+
+ for(var/turf/checked_turf as anything in temp_checked_turfs)
+ if(!(original_target_turf in checked_turfs) && user_to_target_dist < get_dist(starting_turf, checked_turf))
+ checked_turfs += original_target_turf
+
+ checked_turfs += checked_turf
+
+ for(var/turf/checked_turf as anything in checked_turfs)
+
+ //Wall, should block the bullet so we're good to stop checking.
+ if(istype(checked_turf, /turf/closed))
+ return
+
+ for(var/mob/living/checked_living in checked_turf)
+ if(checked_living == user) // sometimes it still happens
+ continue
+ if(checked_living.body_position == LYING_DOWN && projectile_to_fire.original != checked_living)
+ continue
+
+ if(checked_living.get_target_lock(user.faction_group))
+ if(HAS_TRAIT(checked_living, TRAIT_CLOAKED))
+ continue
+ if(COOLDOWN_FINISHED(src, iff_halt_cooldown) && user.client)
+ playsound_client(user.client, 'sound/weapons/smartgun_fail.ogg', src, 25)
+ to_chat(user, SPAN_WARNING("[firing_weapon] halts firing as an IFF marked target crosses your field of fire!"))
+ COOLDOWN_START(src, iff_halt_cooldown, IFF_HALT_COOLDOWN)
+ if(iff_additional_fire_delay)
+ var/obj/item/weapon/gun/gun = firing_weapon
+ if(istype(gun))
+ LAZYSET(user.fire_delay_next_fire, gun, world.time + iff_additional_fire_delay)
+ return COMPONENT_CANCEL_GUN_BEFORE_FIRE
+
+ return //if we have a target we *can* hit and find it before any IFF targets we want to fire
+
+/// Disable fire prevention when IFF is toggled off and other way around
+/datum/component/iff_fire_prevention/proc/handle_iff_toggle(obj/gun, iff_enabled)
+ SIGNAL_HANDLER
+ if(iff_enabled)
+ RegisterSignal(parent, COMSIG_GUN_BEFORE_FIRE, PROC_REF(check_firing_lane))
+ else
+ UnregisterSignal(parent, COMSIG_GUN_BEFORE_FIRE)
+
+#undef IFF_HALT_COOLDOWN
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index c7a64f710a..a3e4900326 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -234,7 +234,6 @@
/// The multiplier for how much slower this should fire in automatic mode. 1 is normal, 1.2 is 20% slower, 2 is 100% slower, etc. Protected due to it never needing to be edited.
VAR_PROTECTED/autofire_slow_mult = 1
-
/**
* An assoc list where the keys are fire delay group string defines
* and the keys are when the guns of the group can be fired again
@@ -1142,8 +1141,9 @@ and you're good to go.
flags_gun_features &= ~GUN_BURST_FIRING
return NONE
- apply_bullet_effects(projectile_to_fire, user, reflex, dual_wield) //User can be passed as null.
- SEND_SIGNAL(projectile_to_fire, COMSIG_BULLET_USER_EFFECTS, user)
+ var/original_scatter = projectile_to_fire.scatter
+ var/original_accuracy = projectile_to_fire.accuracy
+ apply_bullet_scatter(projectile_to_fire, user, reflex, dual_wield) //User can be passed as null.
curloc = get_turf(user)
if(QDELETED(original_target)) //If the target's destroyed, shoot at where it was last.
@@ -1192,14 +1192,25 @@ and you're good to go.
return NONE
var/before_fire_cancel = SEND_SIGNAL(src, COMSIG_GUN_BEFORE_FIRE, projectile_to_fire, target, user)
-
if(before_fire_cancel)
+
+ //yeah we revert these since we are not going to shoot anyway
+ projectile_to_fire.scatter = original_scatter
+ projectile_to_fire.accuracy = original_accuracy
+
if(before_fire_cancel & COMPONENT_CANCEL_GUN_BEFORE_FIRE)
return TRUE
if(before_fire_cancel & COMPONENT_HARD_CANCEL_GUN_BEFORE_FIRE)
return NONE
+ apply_bullet_effects(projectile_to_fire, user, reflex, dual_wield) //User can be passed as null.
+ SEND_SIGNAL(projectile_to_fire, COMSIG_BULLET_USER_EFFECTS, user)
+
+ projectile_to_fire.firer = user
+ if(isliving(user))
+ projectile_to_fire.def_zone = user.zone_selected
+
play_firing_sounds(projectile_to_fire, user)
if(targloc != curloc)
@@ -1244,7 +1255,7 @@ and you're good to go.
return TRUE //Nothing else to do here, time to cancel out.
return TRUE
-#define EXECUTION_CHECK (attacked_mob.stat == UNCONSCIOUS || attacked_mob.is_mob_restrained()) && ((user.a_intent == INTENT_GRAB) || (user.a_intent == INTENT_DISARM)) && !(length(user.faction_group & attacked_mob.faction_group)) && ishuman(attacked_mob)
+#define EXECUTION_CHECK (attacked_mob.stat == UNCONSCIOUS || attacked_mob.is_mob_restrained()) && ((user.a_intent == INTENT_GRAB)||(user.a_intent == INTENT_DISARM))
/obj/item/weapon/gun/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
if(!proximity_flag)
@@ -1400,6 +1411,15 @@ and you're good to go.
click_empty(user)
break
+ //Checking if we even can PB the mob, only for the first projectile because why check the rest
+ if(bullets_fired == 1)
+ var/before_fire_cancel = SEND_SIGNAL(src, COMSIG_GUN_BEFORE_FIRE, projectile_to_fire, attacked_mob, user)
+ if(before_fire_cancel)
+ if(before_fire_cancel & COMPONENT_CANCEL_GUN_BEFORE_FIRE)
+ return TRUE
+ if(before_fire_cancel & COMPONENT_HARD_CANCEL_GUN_BEFORE_FIRE)
+ return NONE
+
if(SEND_SIGNAL(projectile_to_fire.ammo, COMSIG_AMMO_POINT_BLANK, attacked_mob, projectile_to_fire, user, src) & COMPONENT_CANCEL_AMMO_POINT_BLANK)
flags_gun_features &= ~GUN_BURST_FIRING
return TRUE
@@ -1411,7 +1431,7 @@ and you're good to go.
var/damage_buff = BASE_BULLET_DAMAGE_MULT
//if target is lying or unconscious - add damage bonus
- if(!(attacked_mob.mobility_flags & MOBILITY_STAND) || attacked_mob.stat == UNCONSCIOUS)
+ if(attacked_mob.body_position == LYING_DOWN || attacked_mob.stat == UNCONSCIOUS)
damage_buff += BULLET_DAMAGE_MULT_TIER_4
projectile_to_fire.damage *= damage_buff //Multiply the damage for point blank.
if(bullets_fired == 1) //First shot gives the PB message.
@@ -1421,6 +1441,10 @@ and you're good to go.
user.track_shot(initial(name))
apply_bullet_effects(projectile_to_fire, user, bullets_fired, dual_wield) //We add any damage effects that we need.
+ projectile_to_fire.firer = user
+ if(isliving(user))
+ projectile_to_fire.def_zone = user.zone_selected
+
play_firing_sounds(projectile_to_fire, user)
SEND_SIGNAL(projectile_to_fire, COMSIG_BULLET_USER_EFFECTS, user)
@@ -1623,6 +1647,32 @@ not all weapons use normal magazines etc. load_into_chamber() itself is designed
//This proc applies some bonus effects to the shot/makes the message when a bullet is actually fired.
/obj/item/weapon/gun/proc/apply_bullet_effects(obj/projectile/projectile_to_fire, mob/user, reflex = 0, dual_wield = 0)
+ if(wield_delay > 0 && (world.time < wield_time || world.time < pull_time))
+ var/old_time = max(wield_time, pull_time) - wield_delay
+ var/new_time = world.time
+ var/pct_settled = 1 - (new_time-old_time + 1)/wield_delay
+ if(delay_style & WEAPON_DELAY_ACCURACY)
+ var/accuracy_debuff = 1 + (SETTLE_ACCURACY_MULTIPLIER - 1) * pct_settled
+ projectile_to_fire.accuracy /=accuracy_debuff
+ if(delay_style & WEAPON_DELAY_SCATTER)
+ var/scatter_debuff = 1 + (SETTLE_SCATTER_MULTIPLIER - 1) * pct_settled
+ projectile_to_fire.scatter *= scatter_debuff
+
+ projectile_to_fire.damage = round(projectile_to_fire.damage * damage_mult) // Apply gun damage multiplier to projectile damage
+
+ // Apply effective range and falloffs/buildups
+ projectile_to_fire.damage_falloff = damage_falloff_mult * projectile_to_fire.ammo.damage_falloff
+ projectile_to_fire.damage_buildup = damage_buildup_mult * projectile_to_fire.ammo.damage_buildup
+
+ projectile_to_fire.effective_range_min = effective_range_min + projectile_to_fire.ammo.effective_range_min //Add on ammo-level value, if specified.
+ projectile_to_fire.effective_range_max = effective_range_max + projectile_to_fire.ammo.effective_range_max //Add on ammo-level value, if specified.
+
+ projectile_to_fire.shot_from = src
+
+ return 1
+
+//This proc calculates scatter and accuracy
+/obj/item/weapon/gun/proc/apply_bullet_scatter(obj/projectile/projectile_to_fire, mob/user, reflex = 0, dual_wield = 0)
var/gun_accuracy_mult = accuracy_mult_unwielded
var/gun_scatter = scatter_unwielded
@@ -1651,35 +1701,7 @@ not all weapons use normal magazines etc. load_into_chamber() itself is designed
projectile_to_fire.accuracy = round(projectile_to_fire.accuracy * gun_accuracy_mult) // Apply gun accuracy multiplier to projectile accuracy
projectile_to_fire.scatter += gun_scatter
- if(wield_delay > 0 && (world.time < wield_time || world.time < pull_time))
- var/old_time = max(wield_time, pull_time) - wield_delay
- var/new_time = world.time
- var/pct_settled = 1 - (new_time-old_time + 1)/wield_delay
- if(delay_style & WEAPON_DELAY_ACCURACY)
- var/accuracy_debuff = 1 + (SETTLE_ACCURACY_MULTIPLIER - 1) * pct_settled
- projectile_to_fire.accuracy /=accuracy_debuff
- if(delay_style & WEAPON_DELAY_SCATTER)
- var/scatter_debuff = 1 + (SETTLE_SCATTER_MULTIPLIER - 1) * pct_settled
- projectile_to_fire.scatter *= scatter_debuff
-
- projectile_to_fire.damage = round(projectile_to_fire.damage * damage_mult) // Apply gun damage multiplier to projectile damage
-
- // Apply effective range and falloffs/buildups
- projectile_to_fire.damage_falloff = damage_falloff_mult * projectile_to_fire.ammo.damage_falloff
- projectile_to_fire.damage_buildup = damage_buildup_mult * projectile_to_fire.ammo.damage_buildup
-
- projectile_to_fire.effective_range_min = effective_range_min + projectile_to_fire.ammo.effective_range_min //Add on ammo-level value, if specified.
- projectile_to_fire.effective_range_max = effective_range_max + projectile_to_fire.ammo.effective_range_max //Add on ammo-level value, if specified.
-
- projectile_to_fire.shot_from = src
-
- if(user)
- projectile_to_fire.firer = user
- if(isliving(user))
- projectile_to_fire.def_zone = user.zone_selected
-
- return 1
-
+/// When the gun is about to shoot this is called to play the specific gun's firing sound. Requires the firing projectile and the gun's user as the first and second argument
/obj/item/weapon/gun/proc/play_firing_sounds(obj/projectile/projectile_to_fire, mob/user)
if(!user) //The gun only messages when fired by a user.
return
@@ -1694,8 +1716,6 @@ not all weapons use normal magazines etc. load_into_chamber() itself is designed
//Guns with low ammo have their firing sound
var/firing_sndfreq = (current_mag && (current_mag.current_rounds / current_mag.max_rounds) > GUN_LOW_AMMO_PERCENTAGE) ? FALSE : SOUND_FREQ_HIGH
- firing_sndfreq = in_chamber.ammo.firing_freq_offset ? in_chamber.ammo.firing_freq_offset : firing_sndfreq
-
//firing from an attachment
if(active_attachable && active_attachable.flags_attach_features & ATTACH_PROJECTILE)
if(active_attachable.fire_sound) //If we're firing from an attachment, use that noise instead.
@@ -1703,7 +1723,7 @@ not all weapons use normal magazines etc. load_into_chamber() itself is designed
else
if(!(flags_gun_features & GUN_SILENCED))
if (firing_sndfreq && fire_rattle)
- playsound(user, fire_rattle, firesound_volume, FALSE) //if the gun has a unique 'mag rattle' SFX play that instead of pitch shifting.
+ playsound(user, fire_rattle, firesound_volume, FALSE)//if the gun has a unique 'mag rattle' SFX play that instead of pitch shifting.
else
playsound(user, actual_sound, firesound_volume, firing_sndfreq)
else
diff --git a/code/modules/projectiles/guns/smartgun.dm b/code/modules/projectiles/guns/smartgun.dm
index d42c1f4aa8..7a65705d48 100644
--- a/code/modules/projectiles/guns/smartgun.dm
+++ b/code/modules/projectiles/guns/smartgun.dm
@@ -29,7 +29,7 @@
actions_types = list(
/datum/action/item_action/smartgun/toggle_accuracy_improvement,
/datum/action/item_action/smartgun/toggle_ammo_type,
- ///datum/action/item_action/smartgun/toggle_auto_fire, - Thanks Bales
+ ///datum/action/item_action/smartgun/toggle_auto_fire,
/datum/action/item_action/smartgun/toggle_lethal_mode,
///datum/action/item_action/smartgun/toggle_motion_detector,
/datum/action/item_action/smartgun/toggle_recoil_compensation,
@@ -51,9 +51,6 @@
var/recycletime = 120
var/cover_open = FALSE
- /// Cooldown used for the delay on sound and to_chat() when IFF encounters a friendly target while trying to fire
- COOLDOWN_DECLARE(iff_halt_cooldown)
-
unacidable = 1
indestructible = 1
@@ -109,7 +106,7 @@
LAZYADD(traits_to_give, list(
BULLET_TRAIT_ENTRY_ID("iff", /datum/element/bullet_trait_iff)
))
- RegisterSignal(src, COMSIG_GUN_BEFORE_FIRE, PROC_REF(check_firing_lane))
+ AddComponent(/datum/component/iff_fire_prevention)
/obj/item/weapon/gun/smartgun/get_examine_text(mob/user)
. = ..()
@@ -190,30 +187,29 @@
/datum/action/item_action/smartgun/update_button_icon()
return
+/*
+/datum/action/item_action/smartgun/toggle_motion_detector/New(Target, obj/item/holder)
+ . = ..()
+ name = "Toggle Motion Detector"
+ action_icon_state = "motion_detector"
+ button.name = name
+ button.overlays.Cut()
+ button.overlays += image('icons/mob/hud/actions.dmi', button, action_icon_state)
-///datum/action/item_action/smartgun/toggle_motion_detector/New(Target, obj/item/holder)
-// . = ..()
-// name = "Toggle Motion Detector"
-// action_icon_state = "motion_detector"
-// button.name = name
-// button.overlays.Cut()
-// button.overlays += image('icons/mob/hud/actions.dmi', button, action_icon_state)
-
-///datum/action/item_action/smartgun/toggle_motion_detector/action_activate()
-// . = ..()
-// var/obj/item/weapon/gun/smartgun/G = holder_item
-// G.toggle_motion_detector(usr)
-
-///datum/action/item_action/smartgun/toggle_motion_detector/proc/update_icon()
-// if(!holder_item)
-// return
-// var/obj/item/weapon/gun/smartgun/G = holder_item
-// if(G.motion_detector)
-// button.icon_state = "template_on"
-// else
-// button.icon_state = "template"
+/datum/action/item_action/smartgun/toggle_motion_detector/action_activate()
+ . = ..()
+ var/obj/item/weapon/gun/smartgun/G = holder_item
+ G.toggle_motion_detector(usr)
+
+/datum/action/item_action/smartgun/toggle_motion_detector/proc/update_icon()
+ if(!holder_item)
+ return
+ var/obj/item/weapon/gun/smartgun/G = holder_item
+ if(G.motion_detector)
+ button.icon_state = "template_on"
+ else
+ button.icon_state = "template"
-/*
/datum/action/item_action/smartgun/toggle_auto_fire/New(Target, obj/item/holder)
. = ..()
name = "Toggle Auto Fire"
@@ -235,9 +231,7 @@
button.icon_state = "template_on"
else
button.icon_state = "template"
-
*/
-
/datum/action/item_action/smartgun/toggle_accuracy_improvement/New(Target, obj/item/holder)
. = ..()
name = "Toggle Accuracy Improvement"
@@ -332,66 +326,6 @@
to_chat(H, SPAN_WARNING("You can't fire \the [src] with the feed cover open! (alt-click to close)"))
return FALSE
-#define SMARTGUN_IFF_RANGE_CHECK 7
-#define SMARTGUN_IFF_HALT_COOLDOWN (0.5 SECONDS)
-
-/obj/item/weapon/gun/smartgun/proc/check_firing_lane(obj/item/weapon/gun/smartgun/firing_weapon, obj/projectile/projectile_to_fire, atom/target, mob/living/user)
- SIGNAL_HANDLER
-
- var/angle = get_angle(user, target)
-
- var/range_to_check = SMARTGUN_IFF_RANGE_CHECK
-
- var/extended_target_turf = get_angle_target_turf(user, angle, range_to_check)
-
- var/turf/user_turf = get_turf(user)
-
- if(!user_turf || !extended_target_turf)
- return COMPONENT_CANCEL_GUN_BEFORE_FIRE
-
- var/list/checked_turfs = getline2(user_turf, extended_target_turf)
-
- checked_turfs -= user_turf
-
- //At some angles (scatter or otherwise) the original target is not in checked_turfs so we put it in there in order based on distance from user
- //If we are literally clicking on someone with IFF then we don't want to fire, feels funny as a user otherwise
- if(projectile_to_fire.original)
- var/turf/original_target_turf = get_turf(projectile_to_fire.original)
-
- if(original_target_turf && !(original_target_turf in checked_turfs))
- var/user_to_target_dist = get_dist(user_turf, original_target_turf)
- var/list/temp_checked_turfs = checked_turfs.Copy()
- checked_turfs = list()
-
- for(var/turf/checked_turf as anything in temp_checked_turfs)
- if(!(original_target_turf in checked_turfs) && user_to_target_dist < get_dist(user_turf, checked_turf))
- checked_turfs += original_target_turf
-
- checked_turfs += checked_turf
-
- for(var/turf/checked_turf as anything in checked_turfs)
-
- //Wall, should block the bullet so we're good to stop checking.
- if(istype(checked_turf, /turf/closed))
- return
-
- for(var/mob/living/checked_living in checked_turf)
- if(checked_living.body_position == LYING_DOWN && projectile_to_fire.original != checked_living)
- continue
-
- if(checked_living.get_target_lock(user.faction_group))
- if(COOLDOWN_FINISHED(src, iff_halt_cooldown))
- playsound_client(user.client, 'sound/weapons/smartgun_fail.ogg', src, 25)
- to_chat(user, SPAN_WARNING("[src] halts firing as an IFF marked target crosses your field of fire!"))
- COOLDOWN_START(src, iff_halt_cooldown, SMARTGUN_IFF_HALT_COOLDOWN)
-
- return COMPONENT_CANCEL_GUN_BEFORE_FIRE
-
- return //if we have a target we *can* hit and find it before any IFF targets we want to fire
-
-#undef SMARTGUN_IFF_RANGE_CHECK
-#undef SMARTGUN_IFF_HALT_COOLDOWN
-
/obj/item/weapon/gun/smartgun/unique_action(mob/user)
if(isobserver(usr) || isxeno(usr))
return
@@ -420,14 +354,13 @@
secondary_toggled = FALSE
if(iff_enabled)
add_bullet_trait(BULLET_TRAIT_ENTRY_ID("iff", /datum/element/bullet_trait_iff))
- RegisterSignal(src, COMSIG_GUN_BEFORE_FIRE, PROC_REF(check_firing_lane))
drain += 10
MD.iff_signal = initial(MD.iff_signal)
if(!iff_enabled)
remove_bullet_trait("iff")
- UnregisterSignal(src, COMSIG_GUN_BEFORE_FIRE)
drain -= 10
MD.iff_signal = null
+ SEND_SIGNAL(src, COMSIG_GUN_IFF_TOGGLED, iff_enabled)
/obj/item/weapon/gun/smartgun/Fire(atom/target, mob/living/user, params, reflex = 0, dual_wield)
if(!requires_battery)
@@ -479,7 +412,6 @@
drain -= 50
recalculate_attachment_bonuses()
-/*
/obj/item/weapon/gun/smartgun/proc/toggle_auto_fire(mob/user)
if(!(flags_item & WIELDED))
to_chat(user, "[icon2html(src, usr)] You need to wield \the [src] to enable autofire.")
@@ -518,7 +450,6 @@
long_range_cooldown = initial(long_range_cooldown)
MD.scan()
-
/obj/item/weapon/gun/smartgun/proc/auto_prefire(warned) //To allow the autofire delay to properly check targets after waiting.
if(ishuman(loc) && (flags_item & WIELDED))
var/human_user = loc
@@ -600,6 +531,7 @@
/obj/item/weapon/gun/smartgun/proc/process_shot(mob/living/user, warned)
set waitfor = 0
+
if(!target)
return //Acquire our victim.
@@ -615,27 +547,25 @@
Fire(target,user)
target = null
+/*
+/obj/item/weapon/gun/smartgun/proc/toggle_motion_detector(mob/user)
+ to_chat(user, "[icon2html(src, usr)] You [motion_detector? "disable" : "enable"] \the [src]'s motion detector.")
+ playsound(loc,'sound/machines/click.ogg', 25, 1)
+ motion_detector = !motion_detector
+ var/datum/action/item_action/smartgun/toggle_motion_detector/TMD = locate(/datum/action/item_action/smartgun/toggle_motion_detector) in actions
+ TMD.update_icon()
+ motion_detector()
+/obj/item/weapon/gun/smartgun/proc/motion_detector()
+ if(motion_detector)
+ drain += 15
+ if(!auto_fire)
+ START_PROCESSING(SSobj, src)
+ if(!motion_detector)
+ drain -= 15
+ if(!auto_fire)
+ STOP_PROCESSING(SSobj, src)
*/
-
-///obj/item/weapon/gun/smartgun/proc/toggle_motion_detector(mob/user)
-// to_chat(user, "[icon2html(src, usr)] You [motion_detector? "disable" : "enable"] \the [src]'s motion detector.")
-// playsound(loc,'sound/machines/click.ogg', 25, 1)
-// motion_detector = !motion_detector
-// var/datum/action/item_action/smartgun/toggle_motion_detector/TMD = locate(/datum/action/item_action/smartgun/toggle_motion_detector) in actions
-// TMD.update_icon()
-// motion_detector()
-
-///obj/item/weapon/gun/smartgun/proc/motion_detector()
-// if(motion_detector)
-// drain += 15
-// if(!auto_fire)
-// START_PROCESSING(SSobj, src)
-// if(!motion_detector)
-// drain -= 15
-// if(!auto_fire)
-// STOP_PROCESSING(SSobj, src)
-
//CO SMARTGUN
/obj/item/weapon/gun/smartgun/co
name = "\improper M56C 'Cavalier' smartgun"
diff --git a/colonialmarines.dme b/colonialmarines.dme
index 276767ade3..013649c4dc 100644
--- a/colonialmarines.dme
+++ b/colonialmarines.dme
@@ -389,6 +389,7 @@
#include "code\datums\components\footstep.dm"
#include "code\datums\components\healing_reduction.dm"
#include "code\datums\components\id_lock.dm"
+#include "code\datums\components\iff_fire_prevention.dm"
#include "code\datums\components\label.dm"
#include "code\datums\components\orbiter.dm"
#include "code\datums\components\overlay_lighting.dm"
From c88ad114cbabe99dd9153f53b4630fb522860fbe Mon Sep 17 00:00:00 2001
From: AndroBetel <44546836+AndroBetel@users.noreply.github.com>
Date: Tue, 20 Feb 2024 10:59:19 +0300
Subject: [PATCH 2/2] 2
---
code/modules/cm_marines/smartgun_mount.dm | 12 ++++++++++++
code/modules/projectiles/guns/smartgun.dm | 4 ++--
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/code/modules/cm_marines/smartgun_mount.dm b/code/modules/cm_marines/smartgun_mount.dm
index 501cbfdd6e..32983f455c 100644
--- a/code/modules/cm_marines/smartgun_mount.dm
+++ b/code/modules/cm_marines/smartgun_mount.dm
@@ -512,6 +512,8 @@
burst_scatter_mult = SCATTER_AMOUNT_TIER_7
update_icon()
AddComponent(/datum/component/automatedfire/autofire, fire_delay, burst_fire_delay, burst_amount, gun_firemode, autofire_slow_mult, CALLBACK(src, PROC_REF(set_burst_firing)), CALLBACK(src, PROC_REF(reset_fire)), CALLBACK(src, PROC_REF(try_fire)), CALLBACK(src, PROC_REF(display_ammo)))
+ AddComponent(/datum/component/iff_fire_prevention)
+
/obj/structure/machinery/m56d_hmg/Destroy(force) //Make sure we pick up our trash.
operator?.unset_interaction()
@@ -723,6 +725,16 @@
final_angle += rand(-total_scatter_angle, total_scatter_angle)
target = get_angle_target_turf(T, final_angle, 30)
+ var/before_fire_cancel = SEND_SIGNAL(src, COMSIG_GUN_BEFORE_FIRE, in_chamber, target, operator)
+
+ if(before_fire_cancel)
+ if(before_fire_cancel & COMPONENT_CANCEL_GUN_BEFORE_FIRE)
+ return AUTOFIRE_CONTINUE
+
+ if(before_fire_cancel & COMPONENT_HARD_CANCEL_GUN_BEFORE_FIRE)
+ return
+
+
in_chamber.weapon_cause_data = create_cause_data(initial(name), operator)
in_chamber.setDir(dir)
in_chamber.def_zone = pick("chest","chest","chest","head")
diff --git a/code/modules/projectiles/guns/smartgun.dm b/code/modules/projectiles/guns/smartgun.dm
index 7a65705d48..7b444de0db 100644
--- a/code/modules/projectiles/guns/smartgun.dm
+++ b/code/modules/projectiles/guns/smartgun.dm
@@ -411,7 +411,7 @@
else
drain -= 50
recalculate_attachment_bonuses()
-
+/*
/obj/item/weapon/gun/smartgun/proc/toggle_auto_fire(mob/user)
if(!(flags_item & WIELDED))
to_chat(user, "[icon2html(src, usr)] You need to wield \the [src] to enable autofire.")
@@ -547,7 +547,7 @@
Fire(target,user)
target = null
-/*
+
/obj/item/weapon/gun/smartgun/proc/toggle_motion_detector(mob/user)
to_chat(user, "[icon2html(src, usr)] You [motion_detector? "disable" : "enable"] \the [src]'s motion detector.")
playsound(loc,'sound/machines/click.ogg', 25, 1)