diff --git a/code/game/objects/items/melee/energy.dm b/code/game/objects/items/melee/energy.dm
index ba3b679c356fe..5dc26bbe0a055 100644
--- a/code/game/objects/items/melee/energy.dm
+++ b/code/game/objects/items/melee/energy.dm
@@ -135,6 +135,7 @@
w_class = WEIGHT_CLASS_NORMAL
sharpness = IS_SHARP
light_color = "#40ceff"
+ tool_behaviour = TOOL_SAW
toolspeed = 0.7 //faster as a saw
/obj/item/melee/transforming/energy/sword/cyborg
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 009a0772cf890..7950d03a53a7e 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -23,7 +23,7 @@
var/vary_fire_sound = TRUE
var/fire_sound_volume = 50
var/dry_fire_sound = 'sound/weapons/gun_dry_fire.ogg'
- var/suppressed = null //whether or not a message is displayed when fired
+ var/suppressed = null //whether or not a message is displayed when fired
var/can_suppress = FALSE
var/suppressed_sound = 'sound/weapons/gunshot_silenced.ogg'
var/suppressed_volume = 10
@@ -32,7 +32,10 @@
var/clumsy_check = TRUE
var/obj/item/ammo_casing/chambered = null
trigger_guard = TRIGGER_GUARD_NORMAL //trigger guard on the weapon, hulks can't fire them with their big meaty fingers
+ var/can_sawoff = FALSE
+ var/sawn_name = null //used if gun has a special sawn-off rename
var/sawn_desc = null //description change if weapon is sawn-off
+ var/sawn_item_state = null //used if gun has a special sawn-off in-hand sprite
var/sawn_off = FALSE
var/burst_size = 1 //how large a burst is
var/fire_delay = 0 //rate of fire for burst firing and semi auto
diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm
index a6005e0c43606..e9538aefb6990 100644
--- a/code/modules/projectiles/guns/ballistic.dm
+++ b/code/modules/projectiles/guns/ballistic.dm
@@ -263,6 +263,9 @@
to_chat(user, "You screw \the [S] onto \the [src].")
install_suppressor(A)
return
+ if((A.tool_behaviour == TOOL_SAW || istype(A, /obj/item/gun/energy/plasmacutter)) && can_sawoff == TRUE)
+ sawoff(user)
+ return
return FALSE
/obj/item/gun/ballistic/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
@@ -407,7 +410,6 @@
#undef BRAINS_BLOWN_THROW_RANGE
-//TODO: sawing off guns with TOOL_SAW
/obj/item/gun/ballistic/proc/sawoff(mob/user)
if(sawn_off)
to_chat(user, "\The [src] is already shortened!")
@@ -424,13 +426,31 @@
if(sawn_off)
return
user.visible_message("[user] shortens \the [src]!", "You shorten \the [src].")
- name = "sawn-off [src.name]"
+ if (bayonet)
+ bayonet.forceMove(drop_location())
+ clear_bayonet()
+ if (suppressed)
+ if (istype(suppressed, /obj/item/suppressor))
+ //weight class is set later, don't need to worry about removing extra weight from the suppressor
+ var/obj/S = suppressed
+ S.forceMove(drop_location())
+ //If it's integrally suppressed, you're messing that up by chopping off most of it from the tip
+ suppressed = null
+ if (sawn_name)
+ name = sawn_name
+ else
+ name = "sawn-off [src.name]"
desc = sawn_desc
w_class = WEIGHT_CLASS_NORMAL
- item_state = "gun"
+ if (sawn_item_state)
+ item_state = sawn_item_state
+ else
+ item_state = "gun"
slot_flags &= ~ITEM_SLOT_BACK //you can't sling it on your back
- slot_flags |= ITEM_SLOT_BELT //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally)
+ slot_flags |= ITEM_SLOT_BELT //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally)
recoil = SAWN_OFF_RECOIL
+ can_bayonet = FALSE //you got rid of the mounting lug with the rest of the barrel, dumbass
+ can_suppress = FALSE //ditto for the threaded barrel
sawn_off = TRUE
spread_multiplier = 1.6
update_icon()
diff --git a/code/modules/projectiles/guns/ballistic/rifle.dm b/code/modules/projectiles/guns/ballistic/rifle.dm
index 8328c0ea98ace..f03259356974e 100644
--- a/code/modules/projectiles/guns/ballistic/rifle.dm
+++ b/code/modules/projectiles/guns/ballistic/rifle.dm
@@ -20,6 +20,9 @@
add_overlay("[icon_state]_bolt[bolt_locked ? "_locked" : ""]")
/obj/item/gun/ballistic/rifle/rack(mob/user = null)
+ if(!is_wielded)
+ to_chat(user, "You require your other hand to be free to rack the [bolt_wording] of \the [src]!")
+ return
if(bolt_locked == FALSE)
to_chat(user, "You open the bolt of \the [src].")
playsound(src, rack_sound, rack_sound_volume, rack_sound_vary)
@@ -35,7 +38,7 @@
return ..()
/obj/item/gun/ballistic/rifle/attackby(obj/item/A, mob/user, params)
- if (!bolt_locked)
+ if ((istype(A, /obj/item/ammo_casing/a762) || istype(A, /obj/item/ammo_box/a762)) && !bolt_locked)
to_chat(user, "The bolt is closed!")
return
return ..()
@@ -44,6 +47,14 @@
. = ..()
. += "The bolt is [bolt_locked ? "open" : "closed"]."
+/obj/item/gun/ballistic/rifle/shoot_live_shot(mob/living/user, pointblank, atom/pbtarget, message)
+ if(sawn_off == TRUE)
+ if(!is_wielded)
+ recoil = 5
+ else
+ recoil = SAWN_OFF_RECOIL
+ . = ..()
+
///////////////////////
// BOLT ACTION RIFLE //
///////////////////////
@@ -53,6 +64,10 @@
desc = "This piece of junk looks like something that could have been used 700 years ago. It feels slightly moist."
icon_state = "moistnugget"
item_state = "moistnugget"
+ can_sawoff = TRUE
+ sawn_name = "\improper Mosin Obrez"
+ sawn_desc = "A hand cannon of a rifle, try not to break your wrists."
+ sawn_item_state = "halfnugget"
slot_flags = ITEM_SLOT_BACK
mag_type = /obj/item/ammo_box/magazine/internal/boltaction
can_bayonet = TRUE
@@ -61,9 +76,20 @@
w_class = WEIGHT_CLASS_BULKY
weapon_weight = WEAPON_HEAVY
+/obj/item/gun/ballistic/rifle/boltaction/sawoff(mob/user)
+ . = ..()
+ //Has 25 bonus spread due to sawn-off accuracy penalties
+ if (.)
+ //Wild spread only applies to innate and unwielded spread
+ spread = 10
+ wild_spread = TRUE
+ wild_factor = 0.5
+ weapon_weight = WEAPON_MEDIUM
+
/obj/item/gun/ballistic/rifle/boltaction/enchanted
name = "enchanted bolt action rifle"
desc = "Careful not to lose your head."
+ can_sawoff = FALSE
var/guns_left = 30
mag_type = /obj/item/ammo_box/magazine/internal/boltaction/enchanted
diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm
index af68f2328bf7d..86e34cbbe6414 100644
--- a/code/modules/projectiles/guns/ballistic/shotgun.dm
+++ b/code/modules/projectiles/guns/ballistic/shotgun.dm
@@ -46,17 +46,9 @@
icon_state = "riotshotgun"
item_state = "shotgun"
mag_type = /obj/item/ammo_box/magazine/internal/shot/riot
+ can_sawoff = TRUE
sawn_desc = "Come with me if you want to live."
-/obj/item/gun/ballistic/shotgun/riot/attackby(obj/item/A, mob/user, params)
- ..()
- if(istype(A, /obj/item/circular_saw) || istype(A, /obj/item/gun/energy/plasmacutter))
- sawoff(user)
- if(istype(A, /obj/item/melee/transforming/energy))
- var/obj/item/melee/transforming/energy/W = A
- if(W.active)
- sawoff(user)
-
// Automatic Shotguns//
/obj/item/gun/ballistic/shotgun/automatic
@@ -191,6 +183,7 @@
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BACK
mag_type = /obj/item/ammo_box/magazine/internal/shot/dual
+ can_sawoff = TRUE
sawn_desc = "Omar's coming!"
obj_flags = UNIQUE_RENAME
rack_sound_volume = 0
@@ -227,15 +220,6 @@
)
. = ..()
-/obj/item/gun/ballistic/shotgun/doublebarrel/attackby(obj/item/A, mob/user, params)
- ..()
- if(istype(A, /obj/item/melee/transforming/energy))
- var/obj/item/melee/transforming/energy/W = A
- if(W.active)
- sawoff(user)
- if(istype(A, /obj/item/circular_saw) || istype(A, /obj/item/gun/energy/plasmacutter))
- sawoff(user)
-
// IMPROVISED SHOTGUN //
/obj/item/gun/ballistic/shotgun/doublebarrel/improvised
@@ -255,6 +239,9 @@
/obj/item/gun/ballistic/shotgun/doublebarrel/improvised/attackby(obj/item/A, mob/user, params)
..()
if(istype(A, /obj/item/stack/cable_coil) && !sawn_off)
+ if(slung)
+ to_chat(user, "There is already a sling on [src]!")
+ return
var/obj/item/stack/cable_coil/C = A
if(C.use(10))
slot_flags = ITEM_SLOT_BACK
@@ -273,9 +260,14 @@
. = ..()
if(. && slung) //sawing off the gun removes the sling
new /obj/item/stack/cable_coil(get_turf(src), 10)
- slung = 0
+ slung = FALSE
update_icon()
+/obj/item/gun/ballistic/shotgun/doublebarrel/improvised/examine(mob/user)
+ . = ..()
+ if (slung)
+ . += "It has a shoulder sling fashioned from spare wiring attached."
+
/obj/item/gun/ballistic/shotgun/doublebarrel/improvised/sawn
name = "sawn-off improvised shotgun"
desc = "A single-shot shotgun. Better not miss."
@@ -295,6 +287,7 @@
mag_type = /obj/item/ammo_box/magazine/internal/shot/bounty
w_class = WEIGHT_CLASS_BULKY
weapon_weight = WEAPON_MEDIUM
+ can_sawoff = FALSE
force = 10 //it has a hook on it
attack_verb = list("slashed", "hooked", "stabbed")
hitsound = 'sound/weapons/bladeslice.ogg'
diff --git a/icons/mob/inhands/weapons/guns_lefthand.dmi b/icons/mob/inhands/weapons/guns_lefthand.dmi
index 08a8c113dcb81..959282b8b17e7 100644
Binary files a/icons/mob/inhands/weapons/guns_lefthand.dmi and b/icons/mob/inhands/weapons/guns_lefthand.dmi differ
diff --git a/icons/mob/inhands/weapons/guns_righthand.dmi b/icons/mob/inhands/weapons/guns_righthand.dmi
index e8f8d9c21f631..6871d331415b7 100644
Binary files a/icons/mob/inhands/weapons/guns_righthand.dmi and b/icons/mob/inhands/weapons/guns_righthand.dmi differ
diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi
index 3bc8fb1398ba3..b69972dd60e2d 100644
Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ