Cleanup and expand suppressors (#17173)

* Cleanup and expand suppressors

Suicide uses suppressed sounds too

Fix CL

Added the suppressor to the antagonist uplink

Fix CL escape characters

Fix random list

Resolve issues from code review

Split the suppressor into its own file

* Bayonets and ammo displays now add their weight to their attached weapon

* Balloon alerts for weapon mods

* Fix lint
This commit is contained in:
Cody Brittain
2023-09-04 08:22:14 +00:00
committed by GitHub
parent 723a40c866
commit 9a6edb999f
22 changed files with 273 additions and 121 deletions
+1 -1
View File
@@ -20,7 +20,7 @@
fire_sound = 'sound/weapons/kinetic_accel.ogg'
fire_sound_text = "blast"
recoil = 0
silenced = 0
suppressed = FALSE
muzzle_flash = 3
accuracy = 0 //accuracy is measured in tiles. +1 accuracy means that everything is effectively one tile closer for the purpose of miss chance, -1 means the opposite. launchers are not supported, at the moment.
scoped_accuracy = null
+1 -1
View File
@@ -242,7 +242,7 @@ var/list/worths = list(
/obj/item/tracker_electronics = 150,
/obj/item/am_containment = 5000,
/obj/item/syringe_cartridge = 20,
/obj/item/silencer = 60,
/obj/item/suppressor = 60,
/obj/item/fossil = 100,
/obj/item/vampiric = 666,
/obj/item/anobattery = 1800,
+2 -1
View File
@@ -1,7 +1,8 @@
/obj/item/ammo_display
name = "holographic ammo display"
desc = "A device that can be attached to most firearms, providing a holographic display of the remaining ammunition to the user."
desc_info = "Holographic ammo displays can be attached to firearms to give an ammo readout on the HUD. Click on a weapon adjacent to you or in your hand to attach it. Use a screwdriver on the weapon to remove it."
icon = 'icons/obj/weapons.dmi'
icon_state = "ammo_display"
origin_tech = list(TECH_BLUESPACE = 3, TECH_MATERIAL = 4, TECH_DATA = 4)
w_class = ITEMSIZE_SMALL
w_class = ITEMSIZE_TINY
+77 -33
View File
@@ -62,15 +62,51 @@
attack_verb = list("struck", "hit", "bashed")
zoomdevicename = "scope"
/*
* Suppression vars
*/
///Does the gun have a suppressor attached, or should it be suppressed? This will modify firing messages to obscure their source, and change the firing sound to use suppressed_sound
var/suppressed = FALSE
///The suppressor item currently attached to the gun
var/obj/item/suppressor/suppressor
///Whether the weapon can have a suppressor attached
var/can_suppress = FALSE
///Whether the weapon can have a suppressor unattached
var/can_unsuppress = TRUE
/*
* Sound vars
*/
///Sound of the gun firing
var/fire_sound = 'sound/weapons/gunshot/gunshot1.ogg'
///Whether to vary the frequency of the firing sound
var/vary_fire_sound = TRUE
///The volume of the firing sound
var/fire_sound_volume = 50
///Sound of the gun firing when empty (dryfiring)
var/empty_sound = /singleton/sound_category/out_of_ammo
///Determines what a player should hear in audible_message when the gun is fired. e.g gunshot, blast
var/fire_sound_text = "gunshot"
///The firing sound to play when suppressed = TRUE
var/suppressed_sound = 'sound/weapons/gunshot/gunshot_suppressed.ogg'
///The volume of the suppressed sound
var/suppressed_volume = 60
///The sound of the safety being turned on
var/safetyon_sound = 'sound/weapons/blade_open.ogg'
///The sound of the safety being turned off
var/safetyoff_sound = 'sound/weapons/blade_close.ogg'
drop_sound = 'sound/items/drop/gun.ogg'
pickup_sound = 'sound/items/pickup/gun.ogg'
var/burst = 1
var/can_autofire = FALSE
var/fire_delay = 6 //delay after shooting before the gun can be used again
var/burst_delay = 1 //delay between shots, if firing in bursts
var/move_delay = 0
var/fire_sound = 'sound/weapons/gunshot/gunshot1.ogg'
var/fire_sound_text = "gunshot"
var/recoil = 0 //screen shake
var/silenced = 0
var/muzzle_flash = 3
var/accuracy = 0 //accuracy is measured in tiles. +1 accuracy means that everything is effectively one tile closer for the purpose of miss chance, -1 means the opposite. launchers are not supported, at the moment.
var/offhand_accuracy = 0 // the higher this number, the more accurate this weapon is when fired from the off-hand
@@ -83,8 +119,6 @@
var/displays_maptext = FALSE
var/can_ammo_display = TRUE
var/obj/item/ammo_display
var/empty_sound = /singleton/sound_category/out_of_ammo
var/casing_drop_sound = /singleton/sound_category/casing_drop_sound
maptext_x = 22
maptext_y = 2
@@ -124,13 +158,6 @@
var/iff_capable = FALSE // if true, applies the user's ID iff_faction to the projectile
// sounds n shit
var/safetyon_sound = 'sound/weapons/blade_open.ogg'
var/safetyoff_sound = 'sound/weapons/blade_close.ogg'
drop_sound = 'sound/items/drop/gun.ogg'
pickup_sound = 'sound/items/pickup/gun.ogg'
/obj/item/gun/Initialize(mapload)
. = ..()
for(var/i in 1 to firemodes.len)
@@ -404,17 +431,12 @@
P.dispersion = disp
P.shot_from = src.name
P.silenced = silenced
P.suppressed = suppressed
P.launch_projectile(target)
handle_post_fire() // should be safe to not include arguments here, as there are failsafes in effect (?)
if(silenced)
playsound(src, fire_sound, 10, 1)
else
playsound(src, fire_sound, 75, 1, 3, 0.5, 1)
if (muzzle_flash)
set_light(muzzle_flash)
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, set_light), 0), 2, TIMER_UNIQUE | TIMER_OVERRIDE)
@@ -450,11 +472,8 @@
//called after successfully firing
/obj/item/gun/proc/handle_post_fire(mob/user, atom/target, var/pointblank = FALSE, var/reflex = FALSE, var/playemote = TRUE)
if(silenced)
playsound(user, fire_sound, 10, 1)
else
playsound(user, fire_sound, 75, 1, 3, 0.5, 1)
play_fire_sound()
if(!suppressed)
if(playemote)
if(reflex)
user.visible_message(
@@ -484,6 +503,12 @@
S.deactivate()
update_icon()
/obj/item/gun/proc/play_fire_sound()
if(suppressed)
playsound(loc, suppressed_sound, suppressed_volume, vary_fire_sound)
else
playsound(loc, fire_sound, fire_sound_volume, vary_fire_sound, falloff = 0.5, is_global = TRUE)
/obj/item/gun/proc/process_point_blank(obj/projectile, mob/user, atom/target)
var/obj/item/projectile/P = projectile
if(!istype(P))
@@ -578,10 +603,7 @@
handle_click_empty(user)
mouthshoot = FALSE
return
if(silenced)
playsound(user, fire_sound, 10, 1)
else
playsound(user, fire_sound, 75, 1, 3, 0.5, 1)
play_fire_sound()
in_chamber.on_hit(M)
@@ -634,6 +656,14 @@
accuracy = initial(accuracy)
recoil = initial(recoil)
///Handles removing the suppressor from the gun
/obj/item/gun/proc/clear_suppressor()
if(!can_unsuppress)
return
suppressed = FALSE
suppressor = null
update_icon()
/obj/item/gun/examine(mob/user)
..()
if(get_dist(src, user) > 1)
@@ -872,6 +902,8 @@
QDEL_NULL(pin)
if(bayonet)
QDEL_NULL(bayonet)
if(istype(suppressor))
QDEL_NULL(suppressor)
return ..()
@@ -901,15 +933,21 @@
/obj/item/gun/attackby(var/obj/item/I, var/mob/user)
if(istype(I, /obj/item/material/knife/bayonet))
if(!can_bayonet)
balloon_alert(user, "\the [I.name] doesn't fit")
return ..()
if(user.l_hand != bayonet && user.r_hand != bayonet)
balloon_alert(user, "not in hand")
return
if(bayonet)
to_chat(user, SPAN_WARNING("There is a bayonet attached to \the [src] already!"))
balloon_alert(user, "\the [src] already has a bayonet")
return TRUE
user.drop_from_inventory(I,src)
bayonet = I
to_chat(user, SPAN_NOTICE("You attach \the [I] to the front of \the [src]."))
balloon_alert(user, "[I.name] attached")
w_class += I.w_class
update_icon()
return TRUE
@@ -918,24 +956,29 @@
if(istype(I, /obj/item/ammo_display))
if(!can_ammo_display)
to_chat(user, SPAN_WARNING("\The [I] cannot attach to \the [src]."))
balloon_alert(user, "\the [I.name] doesn't fit")
return TRUE
if(user.l_hand != ammo_display && user.r_hand != ammo_display)
balloon_alert(user, "not in hand")
return
if(ammo_display)
to_chat(user, SPAN_WARNING("\The [src] already has a holographic ammo display."))
balloon_alert(user, "\the [src] already has an ammo display")
return TRUE
if(displays_maptext)
to_chat(user, SPAN_WARNING("\The [src] is already displaying its ammo count."))
balloon_alert(user, "\the [src] is already displaying its ammo count")
return TRUE
user.drop_from_inventory(I, src)
ammo_display = I
displays_maptext = TRUE
to_chat(user, SPAN_NOTICE("You attach \the [I] to \the [src]."))
balloon_alert(user, "[I.name] attached")
w_class += I.w_class
return TRUE
if(I.iscrowbar() && bayonet)
to_chat(user, SPAN_NOTICE("You detach \the [bayonet] from \the [src]."))
bayonet.forceMove(get_turf(src))
user.put_in_hands(bayonet)
w_class -= bayonet.w_class
bayonet = null
update_icon()
return TRUE
@@ -944,6 +987,7 @@
to_chat(user, SPAN_NOTICE("You wrench the ammo display loose from \the [src]."))
ammo_display.forceMove(get_turf(src))
user.put_in_hands(ammo_display)
w_class -= ammo_display.w_class
ammo_display = null
displays_maptext = FALSE
maptext = ""
@@ -144,7 +144,7 @@
for(var/obj/item/laser_components/modifier/modifier in gun_mods)
switch(modifier.mod_type)
if(MOD_SILENCE)
silenced = 1
suppressed = TRUE
if(MOD_NUCLEAR_CHARGE)
self_recharge = 1
criticality *= 2
+2 -1
View File
@@ -47,7 +47,8 @@
origin_tech = list(TECH_COMBAT = 2, TECH_MAGNET = 2, TECH_ILLEGAL = 5)
matter = list(DEFAULT_WALL_MATERIAL = 2000)
slot_flags = SLOT_BELT
silenced = 1
suppressed = TRUE
can_unsuppress = FALSE
fire_sound = 'sound/weapons/Genhit.ogg'
projectile_type = /obj/item/projectile/energy/bolt
max_shots = 5
+59 -2
View File
@@ -27,6 +27,11 @@
var/unjam_cooldown = 0 //Gives the unjammer some time after spamming unjam to not eject their mag
var/jam_chance = 0 //Chance it jams on fire
///Pixel offset for the suppressor overlay on the x axis.
var/suppressor_x_offset
///Pixel offset for the suppressor overlay on the y axis.
var/suppressor_y_offset
//TODO generalize ammo icon states for guns
//var/magazine_states = 0
//var/list/icon_keys = list() //keys
@@ -49,6 +54,16 @@
QDEL_NULL_LIST(loaded)
. = ..()
/obj/item/gun/projectile/update_icon()
..()
if(suppressed)
var/mutable_appearance/MA = mutable_appearance('icons/obj/guns/suppressor.dmi', "suppressor")
if(suppressor_x_offset)
MA.pixel_x = suppressor_x_offset
if(suppressor_y_offset)
MA.pixel_y = suppressor_y_offset
underlays += MA
/obj/item/gun/projectile/consume_next_projectile()
if(jam_num)
return FALSE
@@ -212,9 +227,26 @@
update_maptext()
update_icon()
/obj/item/gun/projectile/attackby(obj/item/A, mob/user)
/obj/item/gun/projectile/attackby(obj/item/I, mob/user)
. = ..()
load_ammo(A, user)
if(.)
return
load_ammo(I, user)
if(istype(I, /obj/item/suppressor))
var/obj/item/suppressor/S = I
if(!can_suppress)
balloon_alert(user, "\the [S.name] doesn't fit")
return
if(user.l_hand != suppressor && user.r_hand != suppressor)
balloon_alert(user, "not in hand")
return
if(suppressed)
balloon_alert(user, "already has a suppressor")
return
user.drop_from_inventory(suppressor, src)
balloon_alert(user, "[S.name] attached")
install_suppressor(S)
return
/obj/item/gun/projectile/toggle_firing_mode(mob/user)
if(jam_num)
@@ -261,6 +293,8 @@
to_chat(user, "<span class='warning'>It looks jammed.</span>")
if(ammo_magazine)
to_chat(user, "It has \a [ammo_magazine] loaded.")
if(suppressed)
to_chat(user, "It has a suppressor attached.")
to_chat(user, "Has [get_ammo()] round\s remaining.")
return
@@ -296,3 +330,26 @@
else
. += "No magazine inserted.<br>"
. += ..(FALSE)
///Installs a new suppressor, assumes that the suppressor is already in the contents of src
/obj/item/gun/projectile/proc/install_suppressor(obj/item/suppressor/S)
suppressed = TRUE
w_class += S.w_class //Add our weight class to the item's weight class
suppressor = S
update_icon()
/obj/item/gun/projectile/clear_suppressor()
if(!can_unsuppress)
return
if(istype(suppressor))
w_class -= suppressor.w_class
return ..()
/obj/item/gun/projectile/AltClick(mob/user)
if(use_check_and_message(user))
return
if(suppressed && can_unsuppress)
balloon_alert(user, "[suppressor.name] removed")
user.put_in_hands(suppressor)
clear_suppressor()
return ..()
@@ -16,6 +16,8 @@
burst_delay = 2
sel_mode = 1
fire_delay = ROF_SMG
can_suppress = TRUE
suppressor_x_offset = 8
firemodes = list(
list(mode_name="semiauto", can_autofire=0, burst=1, fire_delay=ROF_SMG),
@@ -40,6 +42,9 @@
caliber = ".45"
origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 2, TECH_ILLEGAL = 8)
ammo_type = /obj/item/ammo_casing/c45
suppressed = FALSE
can_suppress = TRUE
suppressor_x_offset = 10
/obj/item/gun/projectile/automatic/mini_uzi/update_icon()
..()
@@ -65,6 +70,9 @@
allowed_magazines = list(/obj/item/ammo_magazine/a10mm)
auto_eject = 1
auto_eject_sound = 'sound/weapons/smg_empty_alarm.ogg'
suppressed = FALSE
can_suppress = TRUE
suppressor_x_offset = 11
/obj/item/gun/projectile/automatic/c20r/update_icon()
..()
@@ -80,6 +88,7 @@
icon = 'icons/obj/guns/sol_smg.dmi'
icon_state = "vityaz"
item_state = "vityaz"
suppressor_x_offset = 10
/obj/item/gun/projectile/automatic/c20r/sol/update_icon()
..()
@@ -100,6 +109,9 @@
load_method = MAGAZINE
magazine_type = /obj/item/ammo_magazine/mc9mmt/rubber
allowed_magazines = list(/obj/item/ammo_magazine/mc9mmt)
can_suppress = TRUE
suppressor_x_offset = 10
suppressor_y_offset = -1
/obj/item/gun/projectile/automatic/wt550/lethal
magazine_type = /obj/item/ammo_magazine/mc9mmt
@@ -133,6 +145,7 @@
fire_delay = ROF_RIFLE
is_wieldable = TRUE
can_suppress = FALSE
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=ROF_RIFLE),
@@ -529,6 +542,10 @@
allowed_magazines = list(/obj/item/ammo_magazine/submachinemag, /obj/item/ammo_magazine/submachinedrum)
fire_sound = 'sound/weapons/gunshot/gunshot_tommygun.ogg'
can_suppress = TRUE
suppressor_x_offset = 10
suppressor_y_offset = -1
/obj/item/gun/projectile/automatic/tommygun/update_icon()
..()
icon_state = (ammo_magazine)? "tommygun" : "tommygun-empty"
@@ -566,6 +583,8 @@
auto_eject = 1
auto_eject_sound = 'sound/weapons/smg_empty_alarm.ogg'
can_suppress = FALSE
firemodes = list(
list(mode_name="single coil", burst = 1),
list(mode_name="dual coil", burst = 2, move_delay = 1, accuracy = list(-2,-3), dispersion = list(20))
@@ -589,6 +608,8 @@
auto_eject = 1
auto_eject_sound = 'sound/weapons/smg_empty_alarm.ogg'
can_suppress = FALSE
is_wieldable = TRUE
firemodes = list(
@@ -52,7 +52,8 @@
fire_sound_text = "a metallic click"
accuracy = 1
recoil = 0
silenced = 1
suppressed = TRUE
can_unsuppress = FALSE
load_method = MAGAZINE
magazine_type = /obj/item/ammo_magazine/chemdart
auto_eject = 0
@@ -198,9 +198,9 @@
icon_state = "c05r-e"
/obj/item/gun/projectile/silenced
name = "silenced pistol"
name = "suppressed pistol"
desc = "A small, quiet, easily concealable gun."
desc_extended = "Created as a disposable and concealable weapon, the Mrrazhakulii suppressed pistol is a firearm with a silencer integrated as part of its barrel. \
desc_extended = "Created as a disposable and concealable weapon, the Mrrazhakulii suppressed pistol is a firearm with a suppressor integrated as part of its barrel. \
Carried by guerrilla forces and spies, those guns are used in assassination and subterfuge operations. Due to using cheap and available materials, such as \
recycled iron and tires, countless of those pistols were distributed among cells and ALA soldiers."
icon = 'icons/obj/guns/silenced_pistol.dmi'
@@ -211,7 +211,8 @@
accuracy = 1
offhand_accuracy = 1
caliber = ".45"
silenced = 1
suppressed = TRUE
can_unsuppress = FALSE
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2, TECH_ILLEGAL = 8)
load_method = MAGAZINE
magazine_type = /obj/item/ammo_magazine/c45m
@@ -295,14 +296,15 @@
accuracy = 1
offhand_accuracy = 2
caliber = "9mm"
silenced = 0
suppressed = FALSE
can_suppress = TRUE
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2, TECH_ILLEGAL = 2)
fire_sound = 'sound/weapons/gunshot/gunshot_pistol.ogg'
load_method = MAGAZINE
magazine_type = /obj/item/ammo_magazine/mc9mm
allowed_magazines = list(/obj/item/ammo_magazine/mc9mm)
var/can_silence = TRUE
fire_delay = ROF_PISTOL
suppressor_x_offset = 5
/obj/item/gun/projectile/pistol/flash
name = "9mm signal pistol"
@@ -316,7 +318,7 @@
icon = 'icons/obj/guns/detgun.dmi'
icon_state = "detgun"
item_state = "detgun"
can_silence = FALSE
can_suppress = FALSE
/obj/item/gun/projectile/pistol/detective/update_icon()
..()
@@ -338,56 +340,12 @@
name = input
to_chat(usr, "You name the gun [input]. Say hello to your new friend.")
/obj/item/gun/projectile/pistol/attack_hand(mob/user as mob)
if(user.get_inactive_hand() == src)
if(silenced && can_silence)
if(user.l_hand != src && user.r_hand != src)
..()
return
to_chat(user, "<span class='notice'>You unscrew [silenced] from [src].</span>")
user.put_in_hands(silenced)
silenced = 0
w_class = ITEMSIZE_SMALL
update_icon()
return
..()
/obj/item/gun/projectile/pistol/attackby(obj/item/I as obj, mob/user as mob)
if(istype(I, /obj/item/silencer) && can_silence)
if(user.l_hand != src && user.r_hand != src) //if we're not in his hands
to_chat(user, "<span class='notice'>You'll need [src] in your hands to do that.</span>")
return
user.drop_from_inventory(I,src)
to_chat(user, "<span class='notice'>You screw [I] onto [src].</span>")
silenced = I //dodgy?
w_class = ITEMSIZE_NORMAL
update_icon()
return
..()
/obj/item/gun/projectile/pistol/update_icon()
..()
if(silenced)
icon_state = "pistol-silencer"
else
icon_state = "pistol"
/obj/item/gun/projectile/pistol/update_icon()
..()
if(silenced)
icon_state = "pistol-silencer"
else
icon_state = "pistol"
icon_state = "pistol"
if(!(ammo_magazine && ammo_magazine.stored_ammo.len))
icon_state = "[icon_state]-e"
/obj/item/silencer
name = "silencer"
desc = "A silencer"
icon = 'icons/obj/guns/pistol.dmi'
icon_state = "silencer"
w_class = ITEMSIZE_SMALL
/obj/item/gun/projectile/pirate
name = "zip gun"
desc = "Little more than a barrel, handle, and firing mechanism, cheap makeshift firearms like this one are not uncommon in frontier systems."
@@ -447,7 +405,9 @@
icon = 'icons/obj/guns/sol_pistol.dmi'
icon_state = "m8"
item_state = "m8"
can_silence = FALSE
can_suppress = TRUE
suppressor_x_offset = 9
suppressor_y_offset = 3
/obj/item/gun/projectile/pistol/sol/update_icon()
..()
@@ -462,7 +422,7 @@
icon = 'icons/obj/guns/adhomian_pistol.dmi'
icon_state = "adhomian_pistol"
item_state = "adhomian_pistol"
can_silence = FALSE
can_suppress = FALSE
desc_extended = "A mass produced pistol issued to People's Republic officers, government officials and low-ranking Party members. Known for their simple, cheap and reliable \
design, this weapon is produced by nearly all weapon factories in the Republic. The Adar'Mazy is also found in the hands of Adhomai Liberation Army soldiers and commanders."
@@ -484,7 +444,7 @@
icon_state = "k2557-loaded"
item_state = "k2557-loaded"
contained_sprite = TRUE
can_silence = FALSE
can_suppress = FALSE
w_class = ITEMSIZE_NORMAL
load_method = MAGAZINE
handle_casings = EJECT_CASINGS
@@ -152,7 +152,8 @@
origin_tech = list(TECH_COMBAT = 6, TECH_MATERIAL = 2)
caliber = "PPS"
recoil = 1
silenced = 1
suppressed = TRUE
can_unsuppress = FALSE
fire_sound = 'sound/weapons/gunshot/gunshot_light.ogg'
max_shells = 4
ammo_type = null
+6 -6
View File
@@ -16,7 +16,7 @@
var/def_zone = "" //Aiming at
var/hit_zone // The place that actually got hit
var/mob/firer = null//Who shot it
var/silenced = FALSE //Attack message
var/suppressed = FALSE //Attack message
var/shot_from = "" // name of the object which shot us
@@ -174,7 +174,7 @@
/obj/item/projectile/proc/launch_from_gun(atom/target, target_zone, mob/user, params, angle_override, forced_spread, obj/item/gun/launcher)
shot_from = launcher.name
silenced = launcher.silenced
suppressed = launcher.suppressed
if(launcher.iff_capable && user)
iff = get_iff_from_user(user)
@@ -206,7 +206,7 @@
switch(result)
if(PROJECTILE_FORCE_MISS)
if(!point_blank)
if(!silenced)
if(!suppressed)
target_mob.visible_message("<span class='notice'>\The [src] misses [target_mob] narrowly!</span>")
playsound(target_mob, /singleton/sound_category/bulletflyby_sound, 50, 1)
return FALSE
@@ -217,7 +217,7 @@
var/impacted_organ = target_mob.get_organ_name_from_zone(def_zone)
//hit messages
if(silenced)
if(suppressed)
to_chat(target_mob, "<span class='danger'>You've been hit in the [impacted_organ] by \a [src]!</span>")
else
target_mob.visible_message("<span class='danger'>\The [target_mob] is hit by \a [src] in the [impacted_organ]!</span>", "<span class='danger'><font size=2>You are hit by \a [src] in the [impacted_organ]!</font></span>")//X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter
@@ -621,7 +621,7 @@
/obj/item/projectile/proc/generate_muzzle_flash(duration = 3)
if(duration <= 0)
return
if(!muzzle_type || silenced)
if(!muzzle_type || suppressed)
return
var/datum/point/p = trajectory
var/atom/movable/thing = new muzzle_type
@@ -639,7 +639,7 @@
if(tracer_type)
for(var/datum/point/p in beam_segments)
generate_tracer_between_points(p, beam_segments[p], tracer_type, color, duration)
if(muzzle_type && !silenced)
if(muzzle_type && !suppressed)
var/datum/point/p = beam_segments[1]
var/atom/movable/thing = new muzzle_type
p.move_atom_to_src(thing)
+8
View File
@@ -0,0 +1,8 @@
/obj/item/suppressor
name = "suppressor"
desc = "A suppressor"
desc_info = "Suppressors can be attached to weapons to reduce their sound. Click on a weapon adjacent to you or in your hand to attach it. Alt-Click the weapon to remove it."
icon = 'icons/obj/guns/suppressor.dmi'
icon_state = "suppressor_item"
origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 3)
w_class = ITEMSIZE_SMALL