diff --git a/baystation12.dme b/baystation12.dme
index 38f38337244..cc7461001e7 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -1500,6 +1500,7 @@
#include "code\modules\projectiles\guns\launcher\rocket.dm"
#include "code\modules\projectiles\guns\launcher\syringe_gun.dm"
#include "code\modules\projectiles\guns\projectile\automatic.dm"
+#include "code\modules\projectiles\guns\projectile\boltaction.dm"
#include "code\modules\projectiles\guns\projectile\dartgun.dm"
#include "code\modules\projectiles\guns\projectile\improvised.dm"
#include "code\modules\projectiles\guns\projectile\pistol.dm"
diff --git a/code/game/antagonist/outsider/raider.dm b/code/game/antagonist/outsider/raider.dm
index e119b0c0551..6fd3d7d3644 100644
--- a/code/game/antagonist/outsider/raider.dm
+++ b/code/game/antagonist/outsider/raider.dm
@@ -87,11 +87,12 @@ var/datum/antagonist/raider/raiders
/obj/item/weapon/gun/projectile/shotgun/doublebarrel,
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/pellet,
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/sawn,
- /obj/item/weapon/gun/projectile/shotgun/pump/boltaction,
+ /obj/item/weapon/gun/projectile/boltaction,
/obj/item/weapon/gun/projectile/colt,
/obj/item/weapon/gun/projectile/sec,
/obj/item/weapon/gun/projectile/pistol,
/obj/item/weapon/gun/projectile/revolver,
+ /obj/item/weapon/gun/projectile/revolver/deckard,
/obj/item/weapon/gun/projectile/pirate
)
diff --git a/code/game/antagonist/station/renegade.dm b/code/game/antagonist/station/renegade.dm
index 897f06e1d18..08cae7ab80d 100644
--- a/code/game/antagonist/station/renegade.dm
+++ b/code/game/antagonist/station/renegade.dm
@@ -19,15 +19,18 @@ var/datum/antagonist/renegade/renegades
/obj/item/weapon/gun/energy/laser,
/obj/item/weapon/gun/energy/retro,
/obj/item/weapon/gun/energy/xray,
+ /obj/item/weapon/gun/projectile/revolver,
+ /obj/item/weapon/gun/projectile/revolver/deckard,
/obj/item/weapon/gun/projectile/revolver/detective,
+ /obj/item/weapon/gun/projectile/revolver/derringer,
/obj/item/weapon/gun/projectile/automatic/c20r,
/obj/item/weapon/gun/projectile/deagle/camo,
/obj/item/weapon/gun/projectile/pistol,
- /obj/item/weapon/gun/projectile/shotgun/pump,
- /obj/item/weapon/gun/projectile/shotgun/pump/combat,
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/sawn,
- /obj/item/weapon/gun/projectile/shotgun/pump/boltaction,
+ /obj/item/weapon/gun/projectile/boltaction/obrez,
/obj/item/weapon/gun/projectile/automatic,
+ /obj/item/weapon/gun/projectile/automatic/c20r,
+ /obj/item/weapon/gun/projectile/automatic/tommygun,
/obj/item/weapon/gun/projectile/automatic/mini_uzi,
/obj/item/weapon/gun/energy/crossbow
)
diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm
index 3fdc96c8637..7bd3ec275b6 100644
--- a/code/modules/mining/abandonedcrates.dm
+++ b/code/modules/mining/abandonedcrates.dm
@@ -104,7 +104,7 @@
if(87)
new/obj/item/xenos_claw(src)
if(88)
- new/obj/item/weapon/gun/projectile/shotgun/pump/boltaction(src)
+ new/obj/item/weapon/gun/projectile/boltaction(src)
new/obj/item/ammo_magazine/boltaction(src)
new/obj/item/clothing/under/soviet(src)
new/obj/item/clothing/head/ushanka(src)
diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm
index 980020fb984..bae5ed54555 100644
--- a/code/modules/projectiles/guns/projectile.dm
+++ b/code/modules/projectiles/guns/projectile.dm
@@ -27,6 +27,10 @@
var/list/allowed_magazines //determines list of which magazines will fit in the gun
var/auto_eject = 0 //if the magazine should automatically eject itself when empty.
var/auto_eject_sound = null
+
+ var/is_jammed = 0 //Whether this gun is jammed
+ var/jam_chance = 0 //Chance it jams on fire
+
//TODO generalize ammo icon states for guns
//var/magazine_states = 0
//var/list/icon_keys = list() //keys
@@ -42,6 +46,8 @@
update_icon()
/obj/item/weapon/gun/projectile/consume_next_projectile()
+ if(is_jammed)
+ return 0
//get the next casing
if(loaded.len)
chambered = loaded[1] //load next casing.
@@ -66,6 +72,15 @@
..()
process_chambered()
+/obj/item/weapon/gun/projectile/special_check(var/mob/user)
+ if(!..())
+ return 0
+ if(!is_jammed && jam_chance)
+ if(prob(jam_chance))
+ user << "\The [src] jams!"
+ is_jammed = 1
+ return 1
+
/obj/item/weapon/gun/projectile/proc/process_chambered()
if (!chambered) return
@@ -176,8 +191,13 @@
load_ammo(A, user)
/obj/item/weapon/gun/projectile/attack_self(mob/user as mob)
- if(firemodes.len > 1)
- switch_firemodes(user)
+ if(is_jammed)
+ user << "\The [user] unjams \the [src]!"
+ if(do_after(user, 5))
+ playsound(src.loc, 'sound/weapons/empty.ogg', 100, 1)
+ is_jammed = 0
+ else if(firemodes.len > 1)
+ ..()
else
unload_ammo(user)
@@ -187,6 +207,7 @@
else
return ..()
+
/obj/item/weapon/gun/projectile/afterattack(atom/A, mob/living/user)
..()
if(auto_eject && ammo_magazine && ammo_magazine.stored_ammo && !ammo_magazine.stored_ammo.len)
@@ -203,6 +224,8 @@
/obj/item/weapon/gun/projectile/examine(mob/user)
..(user)
+ if(is_jammed)
+ user << "It looks jammed."
if(ammo_magazine)
user << "It has \a [ammo_magazine] loaded."
user << "Has [getAmmo()] round\s remaining."
diff --git a/code/modules/projectiles/guns/projectile/boltaction.dm b/code/modules/projectiles/guns/projectile/boltaction.dm
new file mode 100644
index 00000000000..e8d37f80e89
--- /dev/null
+++ b/code/modules/projectiles/guns/projectile/boltaction.dm
@@ -0,0 +1,93 @@
+/obj/item/weapon/gun/projectile/boltaction
+ name = "\improper bolt action rifle"
+ desc = "A cheap ballistic rifle often found in the hands of crooks and frontiersmen. Uses 7.62mm rounds."
+ icon_state = "moistnugget"
+ item_state = "moistnugget"
+ origin_tech = "combat=2;materials=2"
+ fire_sound = 'sound/weapons/rifleshot.ogg'
+ slot_flags = SLOT_BACK
+ load_method = SINGLE_CASING|SPEEDLOADER
+ caliber = "a762"
+ ammo_type = /obj/item/ammo_casing/a762
+ max_shells = 5
+ w_class = 4.0
+ force = 10
+ var/recentpump = 0
+
+ icon_action_button = "action_blank"
+ action_button_name = "Wield rifle"
+
+/obj/item/weapon/gun/projectile/boltaction/can_wield()
+ return 1
+
+/obj/item/weapon/gun/projectile/boltaction/ui_action_click()
+ if(src in usr)
+ toggle_wield(usr)
+
+/obj/item/weapon/gun/projectile/boltaction/verb/wield_shotgun()
+ set name = "Wield rifle"
+ set category = "Object"
+ set src in usr
+
+ toggle_wield(usr)
+
+/obj/item/weapon/gun/projectile/boltaction/consume_next_projectile()
+ if(chambered)
+ return chambered.BB
+ return null
+
+/obj/item/weapon/gun/projectile/boltaction/attack_self(mob/living/user as mob)
+ if(world.time >= recentpump + 10)
+ pump(user)
+ recentpump = world.time
+
+/obj/item/weapon/gun/projectile/boltaction/proc/pump(mob/M as mob)
+ if(!wielded)
+ M << "You cannot work the rifle's bolt without gripping it with both hands!"
+ return
+
+ playsound(M, 'sound/weapons/riflebolt.ogg', 60, 1)
+
+ if(chambered)//We have a shell in the chamber
+ chambered.loc = get_turf(src)//Eject casing
+ chambered = null
+
+ if(loaded.len)
+ var/obj/item/ammo_casing/AC = loaded[1] //load next casing.
+ loaded -= AC //Remove casing from loaded list.
+ chambered = AC
+
+ update_icon()
+
+
+/obj/item/weapon/gun/projectile/boltaction/attackby(var/obj/item/A as obj, mob/user as mob)
+ if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/pickaxe/plasmacutter) && w_class != 3)
+ user << "You begin to shorten the barrel and stock of \the [src]."
+ if(loaded.len)
+ afterattack(user, user)
+ playsound(user, fire_sound, 50, 1)
+ user.visible_message("[src] goes off!", "The rifle goes off in your face!")
+ return
+ if(do_after(user, 30))
+ icon_state = "obrez"
+ w_class = 3
+ recoil = 2
+ accuracy = -2
+ item_state = "gun"
+ slot_flags &= ~SLOT_BACK
+ slot_flags |= (SLOT_BELT|SLOT_HOLSTER)
+ name = "\improper obrez"
+ desc = "A shortened bolt action rifle, not really acurate. Uses 7.62mm rounds."
+ user << "You shorten the barrel and stock of the rifle!"
+ else
+ ..()
+
+/obj/item/weapon/gun/projectile/boltaction/obrez
+ name = "obrez"
+ desc = "A shortened bolt action rifle, not really accurate. Uses 7.62mm rounds."
+ icon_state = "obrez"
+ item_state = "gun"
+ w_class = 3
+ recoil = 2
+ accuracy = -2
+ slot_flags = SLOT_BELT|SLOT_HOLSTER
diff --git a/code/modules/projectiles/guns/projectile/improvised.dm b/code/modules/projectiles/guns/projectile/improvised.dm
index 458531529bc..c13f7faedea 100644
--- a/code/modules/projectiles/guns/projectile/improvised.dm
+++ b/code/modules/projectiles/guns/projectile/improvised.dm
@@ -140,6 +140,7 @@
origin_tech = "combat=2;materials=2"
fire_sound = 'sound/weapons/Gunshot_light.ogg'
load_method = MAGAZINE
+ jam_chance = 55
/obj/item/weapon/stock/update_icon()
icon_state = "ipistol[buildstate]"
diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm
index 91b16389ebd..90e679c63b6 100644
--- a/code/modules/projectiles/guns/projectile/revolver.dm
+++ b/code/modules/projectiles/guns/projectile/revolver.dm
@@ -8,6 +8,30 @@
handle_casings = CYCLE_CASINGS
max_shells = 7
ammo_type = /obj/item/ammo_casing/a357
+ var/chamber_offset = 0 //how many empty chambers in the cylinder until you hit a round
+
+/obj/item/weapon/gun/projectile/revolver/verb/spin_cylinder()
+ set name = "Spin cylinder"
+ set desc = "Fun when you're bored out of your skull."
+ set category = "Object"
+
+ chamber_offset = 0
+ usr.visible_message("\The [usr] spins the cylinder of \the [src]!", \
+ "You hear something metallic spin and click.")
+ playsound(src.loc, 'sound/weapons/revolver_spin.ogg', 100, 1)
+ loaded = shuffle(loaded)
+ if(rand(1,max_shells) > loaded.len)
+ chamber_offset = rand(0,max_shells - loaded.len)
+
+/obj/item/weapon/gun/projectile/revolver/consume_next_projectile()
+ if(chamber_offset)
+ chamber_offset--
+ return
+ return ..()
+
+/obj/item/weapon/gun/projectile/revolver/load_ammo(var/obj/item/A, mob/user)
+ chamber_offset = 0
+ return ..()
/obj/item/weapon/gun/projectile/revolver/mateba
name = "mateba"
diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm
index d97d5c473a5..c6e05c1c70e 100644
--- a/code/modules/projectiles/guns/projectile/shotgun.dm
+++ b/code/modules/projectiles/guns/projectile/shotgun.dm
@@ -136,46 +136,3 @@
w_class = 3
force = 5
-/obj/item/weapon/gun/projectile/shotgun/pump/boltaction
- name = "\improper bolt action rifle"
- desc = "A cheap ballistic rifle often found in the hands of crooks and frontiersmen."
- icon_state = "moistnugget"
- item_state = "moistnugget"
- origin_tech = "combat=4;materials=2"
- slot_flags = SLOT_BACK
- load_method = SINGLE_CASING|SPEEDLOADER
- caliber = "a762"
- ammo_type = /obj/item/ammo_casing/a762
- max_shells = 5
-
-/obj/item/weapon/gun/projectile/shotgun/pump/boltaction/attackby(var/obj/item/A as obj, mob/user as mob)
- if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/pickaxe/plasmacutter) && w_class != 3)
- user << "You begin to shorten the barrel and stock of \the [src]."
- if(loaded.len)
- afterattack(user, user)
- playsound(user, fire_sound, 50, 1)
- user.visible_message("[src] goes off!", "The rifle goes off in your face!")
- return
- if(do_after(user, 30))
- icon_state = "obrez"
- w_class = 3
- recoil = 2
- accuracy = -2
- item_state = "gun"
- slot_flags &= ~SLOT_BACK
- slot_flags |= (SLOT_BELT|SLOT_HOLSTER)
- name = "\improper obrez"
- desc = "A shortened bolt action rifle, not really acurate. Uses 7.62mm rounds."
- user << "You shorten the barrel and stock of the rifle!"
- else
- ..()
-
-/obj/item/weapon/gun/projectile/shotgun/pump/boltaction/obrez
- name = "obrez"
- desc = "A shortened bolt action rifle, not really accurate. Uses 7.62mm rounds."
- icon_state = "obrez"
- item_state = "gun"
- w_class = 3
- recoil = 2
- accuracy = -2
- slot_flags = SLOT_BELT|SLOT_HOLSTER
diff --git a/html/changelogs/alberyk-PR-768.yml b/html/changelogs/alberyk-PR-768.yml
new file mode 100644
index 00000000000..2681a3de459
--- /dev/null
+++ b/html/changelogs/alberyk-PR-768.yml
@@ -0,0 +1,8 @@
+author: Alberyk
+
+delete-after: True
+
+changes:
+ - rscadd: "The improvised handgun now has a chance to jam when being fired."
+ - rscadd: "You can now spin revolver cylinders."
+ - soundadd: "The bolt action rifle has unique sounds now."
diff --git a/sound/weapons/revolver_spin.ogg b/sound/weapons/revolver_spin.ogg
new file mode 100644
index 00000000000..8e40848d690
Binary files /dev/null and b/sound/weapons/revolver_spin.ogg differ
diff --git a/sound/weapons/riflebolt.ogg b/sound/weapons/riflebolt.ogg
new file mode 100644
index 00000000000..19adcef8ecf
Binary files /dev/null and b/sound/weapons/riflebolt.ogg differ
diff --git a/sound/weapons/rifleshot.ogg b/sound/weapons/rifleshot.ogg
new file mode 100644
index 00000000000..4b26d5e7e6f
Binary files /dev/null and b/sound/weapons/rifleshot.ogg differ