diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index fc0e58659df..72e5b5a566f 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -93,6 +93,8 @@
QDEL_NULL(chambered)
if(azoom)
QDEL_NULL(azoom)
+ if(suppressed)
+ QDEL_NULL(suppressed)
return ..()
/obj/item/gun/handle_atom_del(atom/A)
@@ -105,8 +107,17 @@
clear_bayonet()
if(A == gun_light)
clear_gunlight()
+ if(A == suppressed)
+ clear_suppressor()
return ..()
+///Clears var and updates icon. In the case of ballistic weapons, also updates the gun's weight.
+/obj/item/gun/proc/clear_suppressor()
+ if(!can_unsuppress)
+ return
+ suppressed = null
+ update_icon()
+
/obj/item/gun/examine(mob/user)
. = ..()
if(pin)
diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm
index 635071818f0..73aa02a3d45 100644
--- a/code/modules/projectiles/guns/ballistic.dm
+++ b/code/modules/projectiles/guns/ballistic.dm
@@ -63,6 +63,7 @@
var/bolt_type = BOLT_TYPE_STANDARD
///Used for locking bolt and open bolt guns. Set a bit differently for the two but prevents firing when true for both.
var/bolt_locked = FALSE
+ var/show_bolt_icon = TRUE ///Hides the bolt icon.
///Whether the gun has to be racked each shot or not.
var/semi_auto = TRUE
///Actual magazine currently contained within the gun
@@ -86,6 +87,8 @@
///Whether the gun can be sawn off by sawing tools
var/can_be_sawn_off = FALSE
var/flip_cooldown = 0
+ var/suppressor_x_offset ///pixel offset for the suppressor overlay on the x axis.
+ var/suppressor_y_offset ///pixel offset for the suppressor overlay on the y axis.
/obj/item/gun/ballistic/Initialize()
. = ..()
@@ -95,9 +98,14 @@
return
if (!magazine)
magazine = new mag_type(src)
- chamber_round(TRUE)
+ chamber_round(replace_new_round = TRUE)
update_icon()
+/obj/item/gun/ballistic/vv_edit_var(vname, vval)
+ . = ..()
+ if(vname in list(NAMEOF(src, suppressor_x_offset), NAMEOF(src, suppressor_y_offset), NAMEOF(src, internal_magazine), NAMEOF(src, magazine), NAMEOF(src, chambered), NAMEOF(src, empty_indicator), NAMEOF(src, sawn_off), NAMEOF(src, bolt_locked), NAMEOF(src, bolt_type)))
+ update_icon()
+
/obj/item/gun/ballistic/update_icon_state()
if(current_skin)
icon_state = "[unique_reskin[current_skin]][sawn_off ? "_sawn" : ""]"
@@ -106,21 +114,29 @@
/obj/item/gun/ballistic/update_overlays()
. = ..()
- if (bolt_type == BOLT_TYPE_LOCKING)
- . += "[icon_state]_bolt[bolt_locked ? "_locked" : ""]"
- if (bolt_type == BOLT_TYPE_OPEN && bolt_locked)
- . += "[icon_state]_bolt"
+ if(show_bolt_icon)
+ if (bolt_type == BOLT_TYPE_LOCKING)
+ . += "[icon_state]_bolt[bolt_locked ? "_locked" : ""]"
+ if (bolt_type == BOLT_TYPE_OPEN && bolt_locked)
+ . += "[icon_state]_bolt"
if (suppressed)
- . += "[icon_state]_suppressor"
- if(!chambered && empty_indicator)
+ var/mutable_appearance/MA = mutable_appearance(icon, "[icon_state]_suppressor")
+ if(suppressor_x_offset)
+ MA.pixel_x = suppressor_x_offset
+ if(suppressor_y_offset)
+ MA.pixel_y = suppressor_y_offset
+ . += MA
+ if(!chambered && empty_indicator) //this is duplicated in c20's update_overlayss due to a layering issue with the select fire icon.
. += "[icon_state]_empty"
- if (magazine)
+ if (magazine && !internal_magazine)
if (special_mags)
. += "[icon_state]_mag_[initial(magazine.icon_state)]"
- if (!magazine.ammo_count())
+ if (mag_display_ammo && !magazine.ammo_count())
. += "[icon_state]_mag_empty"
else
. += "[icon_state]_mag"
+ if(!mag_display_ammo)
+ return
var/capacity_number
switch(get_ammo() / magazine.max_ammo)
if(1 to INFINITY) //cause we can have one in the chamber.
@@ -152,13 +168,15 @@
chamber_round()
///Used to chamber a new round and eject the old one
-/obj/item/gun/ballistic/proc/chamber_round(keep_bullet = FALSE)
+/obj/item/gun/ballistic/proc/chamber_round(keep_bullet = FALSE, spin_cylinder, replace_new_round)
if (chambered || !magazine)
return
if (magazine.ammo_count())
chambered = magazine.get_round(keep_bullet || bolt_type == BOLT_TYPE_NO_BOLT)
if (bolt_type != BOLT_TYPE_OPEN)
chambered.forceMove(src)
+ if(replace_new_round)
+ magazine.give_round(new chambered.type)
///updates a bunch of racking related stuff and also handles the sound effects and the like
/obj/item/gun/ballistic/proc/rack(mob/user = null)
@@ -293,6 +311,14 @@
w_class += S.w_class //so pistols do not fit in pockets when suppressed
update_icon()
+/obj/item/gun/ballistic/clear_suppressor()
+ if(!can_unsuppress)
+ return
+ if(isitem(suppressed))
+ var/obj/item/I = suppressed
+ w_class -= I.w_class
+ return ..()
+
/obj/item/gun/ballistic/AltClick(mob/user)
if (unique_reskin && !current_skin && user.canUseTopic(src, BE_CLOSE, NO_DEXTERITY))
reskin_obj(user)
@@ -302,12 +328,9 @@
var/obj/item/suppressor/S = suppressed
if(!user.is_holding(src))
return ..()
- to_chat(user, "You unscrew \the [suppressed] from \the [src].")
- user.put_in_hands(suppressed)
- w_class -= S.w_class
- suppressed = null
- update_icon()
- return
+ to_chat(user, "You unscrew \the [S] from \the [src].")
+ user.put_in_hands(S)
+ clear_suppressor()
///Prefire empty checks for the bolt drop
/obj/item/gun/ballistic/proc/prefire_empty_checks()
diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm
index 135c0fc5455..1845f64c5d4 100644
--- a/code/modules/projectiles/guns/ballistic/automatic.dm
+++ b/code/modules/projectiles/guns/ballistic/automatic.dm
@@ -1,6 +1,5 @@
/obj/item/gun/ballistic/automatic
w_class = WEIGHT_CLASS_NORMAL
- var/select = 1
can_suppress = TRUE
burst_size = 3
fire_delay = 2
@@ -11,21 +10,28 @@
vary_fire_sound = FALSE
rack_sound = 'sound/weapons/gun/smg/smgrack.ogg'
suppressed_sound = 'sound/weapons/gun/smg/shot_suppressed.ogg'
+ var/select = 1 ///fire selector position. 1 = semi, 2 = burst. anything past that can vary between guns.
+ var/selector_switch_icon = FALSE ///if it has an icon for a selector switch indicating current firemode.
/obj/item/gun/ballistic/automatic/proto
name = "\improper Nanotrasen Saber SMG"
desc = "A prototype three-round burst 9mm submachine gun, designated 'SABR'. Has a threaded barrel for suppressors."
icon_state = "saber"
+ selector_switch_icon = TRUE
+ mag_display = TRUE
+ empty_indicator = TRUE
mag_type = /obj/item/ammo_box/magazine/smgm9mm
pin = null
bolt_type = BOLT_TYPE_LOCKING
- mag_display = TRUE
+ show_bolt_icon = FALSE
/obj/item/gun/ballistic/automatic/proto/unrestricted
pin = /obj/item/firing_pin
/obj/item/gun/ballistic/automatic/update_overlays()
. = ..()
+ if(!selector_switch_icon)
+ return
if(!select)
. += "[initial(icon_state)]_semi"
if(select == 1)
@@ -47,7 +53,7 @@
else
burst_size = initial(burst_size)
fire_delay = initial(fire_delay)
- to_chat(user, "You switch to [burst_size]-rnd burst.")
+ to_chat(user, "You switch to [burst_size]-round burst.")
playsound(user, 'sound/weapons/empty.ogg', 100, TRUE)
update_icon()
@@ -57,9 +63,10 @@
/obj/item/gun/ballistic/automatic/c20r
name = "\improper C-20r SMG"
- desc = "A bullpup two-round burst .45 SMG, designated 'C-20r'. Has a 'Scarborough Arms - Per falcis, per pravitas' buttstamp."
+ desc = "A bullpup three-round burst .45 SMG, designated 'C-20r'. Has a 'Scarborough Arms - Per falcis, per pravitas' buttstamp."
icon_state = "c20r"
inhand_icon_state = "c20r"
+ selector_switch_icon = TRUE
mag_type = /obj/item/ammo_box/magazine/smgm45
fire_delay = 2
burst_size = 3
@@ -71,6 +78,11 @@
mag_display_ammo = TRUE
empty_indicator = TRUE
+/obj/item/gun/ballistic/automatic/c20r/update_overlays()
+ . = ..()
+ if(!chambered && empty_indicator) //this is duplicated due to a layering issue with the select fire icon.
+ . += "[icon_state]_empty"
+
/obj/item/gun/ballistic/automatic/c20r/unrestricted
pin = /obj/item/firing_pin
@@ -116,6 +128,7 @@
mag_type = /obj/item/ammo_box/magazine/uzim9mm
burst_size = 2
bolt_type = BOLT_TYPE_OPEN
+ show_bolt_icon = FALSE
mag_display = TRUE
rack_sound = 'sound/weapons/gun/pistol/slide_lock.ogg'
@@ -124,6 +137,7 @@
desc = "A three-round burst 5.56 toploading carbine, designated 'M-90gl'. Has an attached underbarrel grenade launcher which can be toggled on and off."
icon_state = "m90"
inhand_icon_state = "m90"
+ selector_switch_icon = TRUE
mag_type = /obj/item/ammo_box/magazine/m556
can_suppress = FALSE
var/obj/item/gun/ballistic/revolver/grenadelauncher/underbarrel
@@ -197,6 +211,7 @@
desc = "Based on the classic 'Chicago Typewriter'."
icon_state = "tommygun"
inhand_icon_state = "shotgun"
+ selector_switch_icon = TRUE
w_class = WEIGHT_CLASS_HUGE
slot_flags = 0
mag_type = /obj/item/ammo_box/magazine/tommygunm45
@@ -204,6 +219,8 @@
burst_size = 4
fire_delay = 1
bolt_type = BOLT_TYPE_OPEN
+ empty_indicator = TRUE
+ show_bolt_icon = FALSE
/obj/item/gun/ballistic/automatic/ar
name = "\improper NT-ARG 'Boarder'"
@@ -235,6 +252,7 @@
spread = 7
pin = /obj/item/firing_pin/implant/pindicate
bolt_type = BOLT_TYPE_OPEN
+ show_bolt_icon = FALSE
mag_display = TRUE
mag_display_ammo = TRUE
tac_reloads = FALSE
@@ -360,6 +378,7 @@
icon_state = "oldrifle"
inhand_icon_state = "arg"
mag_type = /obj/item/ammo_box/magazine/recharge
+ mag_display_ammo = TRUE
fire_delay = 2
can_suppress = FALSE
burst_size = 0
diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm
index 6defdc6659c..be861daf21c 100644
--- a/code/modules/projectiles/guns/ballistic/revolver.dm
+++ b/code/modules/projectiles/guns/ballistic/revolver.dm
@@ -16,7 +16,7 @@
var/spin_delay = 10
var/recent_spin = 0
-/obj/item/gun/ballistic/revolver/chamber_round(spin_cylinder = TRUE)
+/obj/item/gun/ballistic/revolver/chamber_round(keep_bullet, spin_cylinder = TRUE, replace_new_round)
if(!magazine) //if it mag was qdel'd somehow.
CRASH("revolver tried to chamber a round without a magazine!")
if(spin_cylinder)
@@ -26,7 +26,7 @@
/obj/item/gun/ballistic/revolver/shoot_with_empty_chamber(mob/living/user as mob|obj)
..()
- chamber_round(TRUE)
+ chamber_round()
/obj/item/gun/ballistic/revolver/AltClick(mob/user)
..()
@@ -57,7 +57,7 @@
. = istype(C)
if(.)
C.spin()
- chamber_round(FALSE)
+ chamber_round(spin_cylinder = FALSE)
/obj/item/gun/ballistic/revolver/get_ammo(countchambered = FALSE, countempties = TRUE)
var/boolets = 0 //mature var names for mature people
diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm
index 2293b17b1b5..3475bc96b99 100644
--- a/code/modules/projectiles/guns/ballistic/shotgun.dm
+++ b/code/modules/projectiles/guns/ballistic/shotgun.dm
@@ -134,6 +134,7 @@
empty_indicator = TRUE
empty_alarm = TRUE
special_mags = TRUE
+ mag_display_ammo = TRUE
semi_auto = TRUE
internal_magazine = FALSE
tac_reloads = TRUE
diff --git a/code/modules/projectiles/guns/ballistic/toy.dm b/code/modules/projectiles/guns/ballistic/toy.dm
index 64c7e0230a0..feb29e8cf70 100644
--- a/code/modules/projectiles/guns/ballistic/toy.dm
+++ b/code/modules/projectiles/guns/ballistic/toy.dm
@@ -2,6 +2,7 @@
name = "foam force SMG"
desc = "A prototype three-round burst toy submachine gun. Ages 8 and up."
icon_state = "saber"
+ selector_switch_icon = TRUE
inhand_icon_state = "gun"
mag_type = /obj/item/ammo_box/magazine/toy/smg
fire_sound = 'sound/items/syringeproj.ogg'
@@ -85,7 +86,7 @@
/obj/item/gun/ballistic/automatic/c20r/toy //This is the syndicate variant with syndicate firing pin and riot darts.
name = "donksoft SMG"
- desc = "A bullpup two-round burst toy SMG, designated 'C-20r'. Ages 8 and up."
+ desc = "A bullpup three-round burst toy SMG, designated 'C-20r'. Ages 8 and up."
can_suppress = TRUE
item_flags = NONE
mag_type = /obj/item/ammo_box/magazine/toy/smgm45/riot
diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi
index 92bb9074bd3..9925d54336b 100644
Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ