diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index 9ead672048..24c79ff972 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -18,7 +18,7 @@
/obj/item/toy/blink = 2,
/obj/item/clothing/under/syndicate/tacticool = 2,
/obj/item/toy/sword = 2,
- /obj/item/toy/gun = 2,
+ /obj/item/weapon/gun/projectile/revolver/capgun = 2,
/obj/item/toy/crossbow = 2,
/obj/item/clothing/suit/syndicatefake = 2,
/obj/item/weapon/storage/fancy/crayons = 2,
@@ -168,8 +168,8 @@
var/prizeselect = pickweight(prizes)
new prizeselect(src.loc)
- if(istype(prizeselect, /obj/item/toy/gun)) //Ammo comes with the gun
- new /obj/item/toy/ammo/gun(src.loc)
+ if(istype(prizeselect, /obj/item/weapon/gun/projectile/revolver/capgun)) //Ammo comes with the gun
+ new /obj/item/projectile/bullet/pistol/cap(src.loc)
else if(istype(prizeselect, /obj/item/clothing/suit/syndicatefake)) //Helmet is part of the suit
new /obj/item/clothing/head/syndicatefake(src.loc)
diff --git a/code/game/machinery/computer3/computers/arcade.dm b/code/game/machinery/computer3/computers/arcade.dm
index 1f8edfa0a9..7447363661 100644
--- a/code/game/machinery/computer3/computers/arcade.dm
+++ b/code/game/machinery/computer3/computers/arcade.dm
@@ -7,7 +7,7 @@
/obj/item/toy/blink = 2,
/obj/item/clothing/under/syndicate/tacticool = 2,
/obj/item/toy/sword = 2,
- /obj/item/toy/gun = 2,
+ /obj/item/weapon/gun/projectile/revolver/capgun = 2,
/obj/item/toy/crossbow = 2,
/obj/item/clothing/suit/syndicatefake = 2,
/obj/item/weapon/storage/fancy/crayons = 2,
@@ -28,8 +28,8 @@
if(computer && !computer.stat)
var/prizeselect = pickweight(prizes)
new prizeselect(computer.loc)
- if(istype(prizeselect, /obj/item/toy/gun)) //Ammo comes with the gun
- new /obj/item/toy/ammo/gun(computer.loc)
+ if(istype(prizeselect, /obj/item/weapon/gun/projectile/revolver/capgun)) //Ammo comes with the gun
+ new /obj/item/projectile/bullet/pistol/cap(src.loc)
else if(istype(prizeselect, /obj/item/clothing/suit/syndicatefake)) //Helmet is part of the suit
new /obj/item/clothing/head/syndicatefake(computer.loc)
feedback_inc("arcade_win_normal")
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index bb996529a0..5feeea4db5 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -133,87 +133,6 @@
icon = 'icons/obj/singularity.dmi'
icon_state = "singularity_s1"
-/*
- * Toy gun: Why isnt this an /obj/item/weapon/gun?
- */
-/obj/item/toy/gun
- name = "cap gun"
- desc = "There are 0 caps left. Looks almost like the real thing! Ages 8 and up. Please recycle in an autolathe when you're out of caps!"
- icon = 'icons/obj/gun.dmi'
- icon_state = "revolver"
- item_state = "revolver"
- item_icons = list(
- icon_l_hand = 'icons/mob/items/lefthand_guns.dmi',
- icon_r_hand = 'icons/mob/items/righthand_guns.dmi',
- )
- flags = CONDUCT
- slot_flags = SLOT_BELT|SLOT_HOLSTER
- w_class = 3.0
-
- matter = list("glass" = 10,DEFAULT_WALL_MATERIAL = 10)
-
- attack_verb = list("struck", "pistol whipped", "hit", "bashed")
- var/bullets = 7.0
-
- examine(mob/user)
- if(..(user, 0))
- src.desc = text("There are [] caps\s left. Looks almost like the real thing! Ages 8 and up.", src.bullets)
- return
-
- attackby(obj/item/toy/ammo/gun/A as obj, mob/user as mob)
-
- if (istype(A, /obj/item/toy/ammo/gun))
- if (src.bullets >= 7)
- user << "It's already fully loaded!"
- return 1
- if (A.amount_left <= 0)
- user << "There is no more caps!"
- return 1
- if (A.amount_left < (7 - src.bullets))
- src.bullets += A.amount_left
- user << text("You reload [] caps\s!", A.amount_left)
- A.amount_left = 0
- else
- user << text("You reload [] caps\s!", 7 - src.bullets)
- A.amount_left -= 7 - src.bullets
- src.bullets = 7
- A.update_icon()
- return 1
- return
-
- afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag)
- if (flag)
- return
- if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
- usr << "You don't have the dexterity to do this!"
- return
- src.add_fingerprint(user)
- if (src.bullets < 1)
- user.show_message("*click* *click*", 2)
- playsound(user, 'sound/weapons/empty.ogg', 100, 1)
- return
- playsound(user, 'sound/weapons/Gunshot.ogg', 100, 1)
- src.bullets--
- for(var/mob/O in viewers(user, null))
- O.show_message(text("\The [] fires a cap gun at []!", user, target), 1, "You hear a gunshot!", 2)
-
-/obj/item/toy/ammo/gun
- name = "ammo-caps"
- desc = "There are 7 caps left! Make sure to recyle the box in an autolathe when it gets empty."
- icon = 'icons/obj/ammo.dmi'
- icon_state = "357-7"
- flags = CONDUCT
- w_class = 1.0
-
- matter = list(DEFAULT_WALL_MATERIAL = 10,"glass" = 10)
-
- var/amount_left = 7.0
-
- update_icon()
- src.icon_state = text("357-[]", src.amount_left)
- src.desc = text("There are [] caps\s left! Make sure to recycle the box in an autolathe when it gets empty.", src.amount_left)
- return
-
/*
* Toy crossbow
*/
diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm
index ea7ea93ab7..43b58a1726 100644
--- a/code/game/objects/items/weapons/gift_wrappaper.dm
+++ b/code/game/objects/items/weapons/gift_wrappaper.dm
@@ -84,7 +84,7 @@
/obj/item/toy/balloon,
/obj/item/toy/blink,
/obj/item/toy/crossbow,
- /obj/item/toy/gun,
+ /obj/item/weapon/gun/projectile/revolver/capgun,
/obj/item/toy/katana,
/obj/item/toy/prize/deathripley,
/obj/item/toy/prize/durand,
diff --git a/code/modules/projectiles/ammunition/boxes.dm b/code/modules/projectiles/ammunition/boxes.dm
index e4e6b4b08a..57ebbd6e96 100644
--- a/code/modules/projectiles/ammunition/boxes.dm
+++ b/code/modules/projectiles/ammunition/boxes.dm
@@ -67,9 +67,9 @@
/obj/item/ammo_magazine/c9mm
name = "ammunition Box (9mm)"
- icon_state = "9mm"
+ icon_state = "9mm"
origin_tech = list(TECH_COMBAT = 2)
- matter = list(DEFAULT_WALL_MATERIAL = 1800)
+ matter = list(DEFAULT_WALL_MATERIAL = 1800)
caliber = "9mm"
ammo_type = /obj/item/ammo_casing/c9mm
max_ammo = 30
@@ -192,3 +192,12 @@
max_ammo = 20
multiple_sprites = 1
+/obj/item/ammo_magazine/caps
+ name = "speed loader (caps)"
+ icon_state = "T38"
+ caliber = "caps"
+ color = "#FF0000"
+ ammo_type = /obj/item/ammo_casing/cap
+ matter = list(DEFAULT_WALL_MATERIAL = 600)
+ max_ammo = 7
+ multiple_sprites = 1
diff --git a/code/modules/projectiles/ammunition/bullets.dm b/code/modules/projectiles/ammunition/bullets.dm
index 345752835b..52c44af1d1 100644
--- a/code/modules/projectiles/ammunition/bullets.dm
+++ b/code/modules/projectiles/ammunition/bullets.dm
@@ -158,3 +158,10 @@
icon_state = "rocketshell"
projectile_type = /obj/item/missile
caliber = "rocket"
+
+/obj/item/ammo_casing/cap
+ name = "cap"
+ desc = "A cap for children toys."
+ caliber = "caps"
+ color = "#FF0000"
+ projectile_type = /obj/item/projectile/bullet/pistol/cap
diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm
index 785c532d04..d7ee4dcbeb 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
+ 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"
@@ -61,4 +85,14 @@
flick("deckard-reload",src)
..()
+/obj/item/weapon/gun/projectile/revolver/capgun
+ name = "cap gun"
+ desc = "Looks almost like the real thing! Ages 8 and up."
+ icon_state = "revolver"
+ item_state = "revolver"
+ caliber = "caps"
+ origin_tech = list(TECH_COMBAT = 1, TECH_MATERIAL = 1)
+ handle_casings = CYCLE_CASINGS
+ max_shells = 7
+ ammo_type = /obj/item/ammo_casing/cap
diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm
index cc18d93d87..32ba360fa3 100644
--- a/code/modules/projectiles/projectile/bullets.dm
+++ b/code/modules/projectiles/projectile/bullets.dm
@@ -197,3 +197,15 @@
/obj/item/projectile/bullet/shotgun/practice
name = "practice"
damage = 5
+
+/obj/item/projectile/bullet/pistol/cap
+ name = "cap"
+ damage_type = HALLOSS
+ damage = 0
+ nodamage = 1
+ embed = 0
+ sharp = 0
+
+/obj/item/projectile/bullet/pistol/cap/process()
+ loc = null
+ qdel(src)
\ No newline at end of file
diff --git a/html/changelogs/Chinsky-roulette.yml b/html/changelogs/Chinsky-roulette.yml
new file mode 100644
index 0000000000..9cfd0778ee
--- /dev/null
+++ b/html/changelogs/Chinsky-roulette.yml
@@ -0,0 +1,6 @@
+author: Chinsky
+
+delete-after: True
+
+changes:
+ - rscadd: "Russian roulette! Fun for whole sec team! Unload some shells from revolver, spin the cylinder(verb) and you're good to go!"
diff --git a/html/changelogs/chinsky-capguns.yml b/html/changelogs/chinsky-capguns.yml
new file mode 100644
index 0000000000..e6b63e82d1
--- /dev/null
+++ b/html/changelogs/chinsky-capguns.yml
@@ -0,0 +1,7 @@
+
+author: Chinsky
+
+delete-after: True
+
+changes:
+ - rscadd: "Made capguns into proper guns code-wise. It means you can now take people hostage with them, stick in your mouth, and all other things you can do with real guns but probably shouldn't."
\ No newline at end of file
diff --git a/sound/weapons/revolver_spin.ogg b/sound/weapons/revolver_spin.ogg
new file mode 100644
index 0000000000..8e40848d69
Binary files /dev/null and b/sound/weapons/revolver_spin.ogg differ