diff --git a/aurorastation.dme b/aurorastation.dme index 397cfdb4344..9bc01d49c3f 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -2863,6 +2863,7 @@ #include "code\modules\projectiles\gun.dm" #include "code\modules\projectiles\pins.dm" #include "code\modules\projectiles\projectile.dm" +#include "code\modules\projectiles\suppressor.dm" #include "code\modules\projectiles\ammunition\ammo_pile.dm" #include "code\modules\projectiles\ammunition\boxes.dm" #include "code\modules\projectiles\ammunition\bullets.dm" diff --git a/code/datums/uplink/highly visible and dangerous weapons.dm b/code/datums/uplink/highly visible and dangerous weapons.dm index 86a82e4fa89..da02566e956 100644 --- a/code/datums/uplink/highly visible and dangerous weapons.dm +++ b/code/datums/uplink/highly visible and dangerous weapons.dm @@ -25,16 +25,23 @@ telecrystal_cost = 4 path = /obj/item/melee/energy/sword -/datum/uplink_item/item/visible_weapons/g9mm - name = "Silenced 9mm" - telecrystal_cost = 2 - path = /obj/item/storage/box/syndie_kit/g9mm - /datum/uplink_item/item/visible_weapons/hammer name = "Kneebreaker Hammer" telecrystal_cost = 3 path = /obj/item/melee/hammer +/datum/uplink_item/item/visible_weapons/suppressor + name = "Suppressor" + desc = "A suppressor that can be attached to most pistol-caliber weaponry. Will prevent sound from passing through walls." + telecrystal_cost = 1 + bluecrystal_cost = 1 + path = /obj/item/suppressor + +/datum/uplink_item/item/visible_weapons/g9mm + name = "9mm Pistol" + telecrystal_cost = 1 + path = /obj/item/gun/projectile/pistol + /datum/uplink_item/item/visible_weapons/revolver name = "Revolver" telecrystal_cost = 4 @@ -141,6 +148,12 @@ telecrystal_cost = 2 path = /obj/item/gun/projectile/colt +/datum/uplink_item/item/visible_weapons/suppressed_pistol + name = "Suppressed .45 Pistol" + desc = "A .45 pistol that comes with a suppressor integrated into the barrel. The suppressor cannot be removed." + telecrystal_cost = 2 + path = /obj/item/gun/projectile/silenced + /datum/uplink_item/item/visible_weapons/custom_ka name = "Kinetic Laser Assembly" telecrystal_cost = 3 diff --git a/code/game/objects/items/weapons/grenades/fragmentation.dm b/code/game/objects/items/weapons/grenades/fragmentation.dm index 3bc97312d84..70bdc676889 100644 --- a/code/game/objects/items/weapons/grenades/fragmentation.dm +++ b/code/game/objects/items/weapons/grenades/fragmentation.dm @@ -36,7 +36,7 @@ base_spread = 0 //causes it to be treated as a shrapnel explosion instead of cone spread_step = 20 - silenced = 1 //embedding messages are still produced so it's kind of weird when enabled. + suppressed = TRUE //embedding messages are still produced so it's kind of weird when enabled. no_attack_log = 1 muzzle_type = null diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index 6e4eda40cde..629b49efbe6 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -110,11 +110,6 @@ icon_state = "box" item_state = "box" -/obj/item/storage/box/syndie_kit/g9mm - name = "smooth operator" - desc = "9mm with silencer kit." - starts_with = list(/obj/item/gun/projectile/pistol = 1, /obj/item/silencer = 1) - /obj/item/storage/box/syndie_kit/toxin name = "toxin kit" desc = "An apple will not be enough to keep the doctor away after this." diff --git a/code/game/objects/structures/crates_lockers/crates/gear_loadout.dm b/code/game/objects/structures/crates_lockers/crates/gear_loadout.dm index 90c7528affb..2e06cb06b8d 100644 --- a/code/game/objects/structures/crates_lockers/crates/gear_loadout.dm +++ b/code/game/objects/structures/crates_lockers/crates/gear_loadout.dm @@ -521,10 +521,10 @@ new /obj/item/gun/projectile/pistol(src) new /obj/item/gun/projectile/pistol(src) new /obj/item/gun/projectile/pistol(src) - new /obj/item/silencer(src) - new /obj/item/silencer(src) - new /obj/item/silencer(src) - new /obj/item/silencer(src) + new /obj/item/suppressor(src) + new /obj/item/suppressor(src) + new /obj/item/suppressor(src) + new /obj/item/suppressor(src) new /obj/item/ammo_magazine/mc9mm(src) new /obj/item/ammo_magazine/mc9mm(src) new /obj/item/ammo_magazine/mc9mm(src) @@ -539,7 +539,7 @@ new /obj/item/clothing/suit/space/void/einstein(src) new /obj/item/gun/energy/rifle(src) new /obj/item/gun/projectile/pistol(src) - new /obj/item/silencer(src) + new /obj/item/suppressor(src) new /obj/item/ammo_magazine/mc9mm(src) new /obj/item/ammo_magazine/mc9mm(src) @@ -770,7 +770,7 @@ /obj/structure/closet/crate/secure/gear_loadout/ninja/stealth/fill() ..() new /obj/item/gun/projectile/pistol(src) - new /obj/item/silencer(src) + new /obj/item/suppressor(src) new /obj/item/ammo_magazine/mc9mm(src) new /obj/item/ammo_magazine/mc9mm(src) diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index 3cab8e0e2c3..e9dcf34069f 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -424,4 +424,4 @@ if(istype(mover, /obj/item/projectile)) return prob(30) else - return !density \ No newline at end of file + return !density diff --git a/code/modules/custom_ka/core.dm b/code/modules/custom_ka/core.dm index b282ddc3749..28bc80dd30d 100644 --- a/code/modules/custom_ka/core.dm +++ b/code/modules/custom_ka/core.dm @@ -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 diff --git a/code/modules/item_worth/worths_list.dm b/code/modules/item_worth/worths_list.dm index b1bbdef17d2..baf0b56cc9d 100644 --- a/code/modules/item_worth/worths_list.dm +++ b/code/modules/item_worth/worths_list.dm @@ -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, diff --git a/code/modules/projectiles/ammo_display.dm b/code/modules/projectiles/ammo_display.dm index 810ff843314..96ce979d2c4 100644 --- a/code/modules/projectiles/ammo_display.dm +++ b/code/modules/projectiles/ammo_display.dm @@ -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 \ No newline at end of file + w_class = ITEMSIZE_TINY diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 1409765d504..8de397b790e 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -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 = "" diff --git a/code/modules/projectiles/guns/energy/modular.dm b/code/modules/projectiles/guns/energy/modular.dm index 6ef555b8f7c..ff22caf4381 100644 --- a/code/modules/projectiles/guns/energy/modular.dm +++ b/code/modules/projectiles/guns/energy/modular.dm @@ -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 diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm index f0253419621..cfca1b13b6e 100644 --- a/code/modules/projectiles/guns/energy/stun.dm +++ b/code/modules/projectiles/guns/energy/stun.dm @@ -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 diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index 3859a5fb03e..02029935457 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -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, "It looks jammed.") 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.
" . += ..(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 ..() diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index 2462a321e71..378b5453b88 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -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( diff --git a/code/modules/projectiles/guns/projectile/dartgun.dm b/code/modules/projectiles/guns/projectile/dartgun.dm index b41a9ea028d..4452c4102bd 100644 --- a/code/modules/projectiles/guns/projectile/dartgun.dm +++ b/code/modules/projectiles/guns/projectile/dartgun.dm @@ -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 diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm index ff19c03a70b..f7e83cca274 100644 --- a/code/modules/projectiles/guns/projectile/pistol.dm +++ b/code/modules/projectiles/guns/projectile/pistol.dm @@ -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, "You unscrew [silenced] from [src].") - 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, "You'll need [src] in your hands to do that.") - return - user.drop_from_inventory(I,src) - to_chat(user, "You screw [I] onto [src].") - 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 diff --git a/code/modules/projectiles/guns/projectile/sniper.dm b/code/modules/projectiles/guns/projectile/sniper.dm index 00a9e89cda6..f368fad6f8e 100644 --- a/code/modules/projectiles/guns/projectile/sniper.dm +++ b/code/modules/projectiles/guns/projectile/sniper.dm @@ -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 diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index a6509195a1f..e28063c705f 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -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("\The [src] misses [target_mob] narrowly!") 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, "You've been hit in the [impacted_organ] by \a [src]!") else target_mob.visible_message("\The [target_mob] is hit by \a [src] in the [impacted_organ]!", "You are hit by \a [src] in the [impacted_organ]!")//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) diff --git a/code/modules/projectiles/suppressor.dm b/code/modules/projectiles/suppressor.dm new file mode 100644 index 00000000000..36a482c4b83 --- /dev/null +++ b/code/modules/projectiles/suppressor.dm @@ -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 diff --git a/html/changelogs/GeneralCamo - Suppressor Rework.yml b/html/changelogs/GeneralCamo - Suppressor Rework.yml new file mode 100644 index 00000000000..0610199776f --- /dev/null +++ b/html/changelogs/GeneralCamo - Suppressor Rework.yml @@ -0,0 +1,49 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +# balance +# admin +# backend +# security +# refactor +################################# + +# Your name. +author: GeneralCamo + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - refactor: "Refactored how weapon sounds are handled to be less hardcoded." + - tweak: "Renamed the silencer to the suppressor." + - tweak: "The suppressor can now be attached to most pistol-caliber weapons, with the notable exceptions of revolvers." + - tweak: "Suppressors are now removed with Alt-Click." + - rscadd: "Added a suppressor to the antagonist uplink, under \"Highly Visible and Dangerous Weapons\". It costs either 1 telecrystal or 1 bluecrystal." + - rscdel: "The 9mm pistol no longer comes with a suppressor. The 9mm pistol's cost has been reduced from 2 telecrystals to 1 to compensate." + - rscadd: "Added a permanently suppressed .45 pistol to the uplink." + - rscadd: "The holographic ammo display and bayonet now add their weights to a weapon when attached (and vice versa and detached)." + - balance: "The holographic ammo display's weight has been reduced from 'small' to 'tiny'." diff --git a/icons/obj/guns/suppressor.dmi b/icons/obj/guns/suppressor.dmi new file mode 100644 index 00000000000..61488a2e75d Binary files /dev/null and b/icons/obj/guns/suppressor.dmi differ diff --git a/maps/away/ships/einstein/ee_spy_ship.dmm b/maps/away/ships/einstein/ee_spy_ship.dmm index 115c3de4ce8..979edf7abf9 100644 --- a/maps/away/ships/einstein/ee_spy_ship.dmm +++ b/maps/away/ships/einstein/ee_spy_ship.dmm @@ -1065,7 +1065,7 @@ req_access = list(205) }, /obj/item/gun/projectile/pistol, -/obj/item/silencer, +/obj/item/suppressor, /obj/item/ammo_magazine/mc9mm, /obj/item/ammo_magazine/mc9mm, /turf/simulated/floor/tiled/dark,