diff --git a/aurorastation.dme b/aurorastation.dme
index e54eb4f1ff7..4299713a3d5 100644
--- a/aurorastation.dme
+++ b/aurorastation.dme
@@ -1910,9 +1910,12 @@
#include "code\modules\projectiles\ammunition\boxes.dm"
#include "code\modules\projectiles\ammunition\bullets.dm"
#include "code\modules\projectiles\guns\alien.dm"
+#include "code\modules\projectiles\guns\bang.dm"
#include "code\modules\projectiles\guns\energy.dm"
#include "code\modules\projectiles\guns\launcher.dm"
#include "code\modules\projectiles\guns\projectile.dm"
+#include "code\modules\projectiles\guns\bang\pistol.dm"
+#include "code\modules\projectiles\guns\bang\revolver.dm"
#include "code\modules\projectiles\guns\energy\laser.dm"
#include "code\modules\projectiles\guns\energy\lawgiver.dm"
#include "code\modules\projectiles\guns\energy\magic.dm"
diff --git a/code/datums/trading/misc.dm b/code/datums/trading/misc.dm
index 16217132b93..b378d983c68 100644
--- a/code/datums/trading/misc.dm
+++ b/code/datums/trading/misc.dm
@@ -119,7 +119,8 @@
/obj/item/weapon/gun/launcher/pneumatic/small = TRADER_THIS_TYPE,
/obj/item/clothing/mask/gas/monkeymask = TRADER_THIS_TYPE,
/obj/item/clothing/suit/monkeysuit = TRADER_THIS_TYPE,
- /obj/item/clothing/mask/luchador = TRADER_ALL
+ /obj/item/clothing/mask/luchador = TRADER_ALL,
+ /obj/item/weapon/gun/bang = TRADER_SUBTYPES_ONLY
)
/datum/trader/ship/replica_shop
diff --git a/code/datums/trading/weaponry.dm b/code/datums/trading/weaponry.dm
index 4467269cd4d..05477416212 100644
--- a/code/datums/trading/weaponry.dm
+++ b/code/datums/trading/weaponry.dm
@@ -99,7 +99,8 @@
/obj/item/weapon/gun/projectile/revolver/derringer = TRADER_THIS_TYPE,
/obj/item/weapon/gun/projectile/pirate = TRADER_THIS_TYPE,
/obj/item/weapon/gun/projectile/contender = TRADER_THIS_TYPE,
- /obj/item/weapon/gun/projectile/revolver/lemat = TRADER_THIS_TYPE
+ /obj/item/weapon/gun/projectile/revolver/lemat = TRADER_THIS_TYPE,
+ /obj/item/weapon/gun/projectile/boltaction/vintage = TRADER_THIS_TYPE
)
diff --git a/code/game/antagonist/outsider/raider.dm b/code/game/antagonist/outsider/raider.dm
index 3cb33216534..61f96e63cf9 100644
--- a/code/game/antagonist/outsider/raider.dm
+++ b/code/game/antagonist/outsider/raider.dm
@@ -102,7 +102,8 @@ var/datum/antagonist/raider/raiders
/obj/item/weapon/gun/projectile/revolver/lemat,
/obj/item/weapon/gun/projectile/contender,
/obj/item/weapon/gun/projectile/pirate,
- /obj/item/weapon/gun/projectile/tanto
+ /obj/item/weapon/gun/projectile/tanto,
+ /obj/item/weapon/gun/projectile/boltaction/vintage
)
diff --git a/code/modules/projectiles/ammunition/boxes.dm b/code/modules/projectiles/ammunition/boxes.dm
index 08d1417a495..fcaf3890baf 100644
--- a/code/modules/projectiles/ammunition/boxes.dm
+++ b/code/modules/projectiles/ammunition/boxes.dm
@@ -22,7 +22,7 @@
/obj/item/ammo_magazine/c38/rubber
name = "speed loader (.38 rubber)"
ammo_type = /obj/item/ammo_casing/c38/rubber
-
+
/obj/item/ammo_magazine/c38/emp
name = "speed loader (.38 haywire)"
ammo_type = /obj/item/ammo_casing/c38/emp
@@ -72,7 +72,7 @@
/obj/item/ammo_magazine/c45m/flash
name = "magazine (.45 flash)"
ammo_type = /obj/item/ammo_casing/c45/flash
-
+
/obj/item/ammo_magazine/t40
name = "magazine (10mm)"
icon_state = "5.56"
@@ -118,7 +118,7 @@
/obj/item/ammo_magazine/c9mm/empty
initial_ammo = 0
-
+
/obj/item/ammo_magazine/mc9mmt
name = "top mounted magazine (9mm)"
icon_state = "9mmt"
@@ -274,6 +274,11 @@
max_ammo = 5
multiple_sprites = 1
+/obj/item/ammo_magazine/boltaction/vintage
+ name = "vintage stripper clip"
+ ammo_type = /obj/item/ammo_casing/vintage
+ caliber = "vintage"
+
/obj/item/ammo_magazine/c45uzi
name = "stick magazine (.45)"
icon_state = "uzi45"
diff --git a/code/modules/projectiles/ammunition/bullets.dm b/code/modules/projectiles/ammunition/bullets.dm
index c16486838b7..4912d878dff 100644
--- a/code/modules/projectiles/ammunition/bullets.dm
+++ b/code/modules/projectiles/ammunition/bullets.dm
@@ -249,3 +249,10 @@
/obj/item/ammo_casing/flechette/explosive
projectile_type = /obj/item/projectile/bullet/flechette/explosive
+
+/obj/item/ammo_casing/vintage
+ projectile_type = /obj/item/projectile/bullet/rifle/vintage
+ desc = "Some vintage shell casing. It looks old, and you can't understand the writing stamped on it."
+ caliber = "vintage"
+ icon_state = "lcasing"
+ spent_icon = "lcasing-spent"
\ No newline at end of file
diff --git a/code/modules/projectiles/guns/bang.dm b/code/modules/projectiles/guns/bang.dm
new file mode 100644
index 00000000000..0a60c72856c
--- /dev/null
+++ b/code/modules/projectiles/guns/bang.dm
@@ -0,0 +1,46 @@
+/obj/item/weapon/gun/bang
+ name = "some shitty-ass gun"
+ desc = "This is a gun. Neat!"
+ icon_state = "revolver"
+ item_state = "revolver"
+ fire_sound = 'sound/misc/sadtrombone.ogg'
+ var/image/bang_flag
+ var/fired_gun = 0
+ var/pixel_offset_x = -2
+ var/pixel_offset_y = 13
+
+
+/obj/item/weapon/gun/bang/Initialize()
+ . = ..()
+ bang_flag = image('icons/obj/bang_flag.dmi', "bang_flag")
+ bang_flag.pixel_x = pixel_offset_x
+ bang_flag.pixel_y = pixel_offset_y
+
+/obj/item/weapon/gun/bang/handle_click_empty(mob/user)
+ if (user)
+ user.visible_message("The flag is already out!")
+
+/obj/item/weapon/gun/bang/Fire(atom/target, mob/living/user, clickparams, pointblank=0, reflex=0)
+ if(!user || !target) return
+
+ if(fired_gun)
+ handle_click_empty(user)
+ return
+
+ add_fingerprint(user)
+
+ if (user)
+ user.visible_message("A flag pops out of the barrel!")
+ else
+ src.visible_message("A flag pops out of the barrel of \the [src.name]'s barrel!")
+ playsound(src, fire_sound, 20, 1)
+ src.add_overlay(bang_flag)
+ fired_gun = 1
+
+/obj/item/weapon/gun/bang/attack_hand(mob/user as mob)
+ if(user.get_inactive_hand() == src && fired_gun)
+ src.cut_overlay(bang_flag)
+ user.visible_message("You push the flag back into the barrel of \the [src.name].")
+ fired_gun = 0
+ else
+ return ..()
\ No newline at end of file
diff --git a/code/modules/projectiles/guns/bang/pistol.dm b/code/modules/projectiles/guns/bang/pistol.dm
new file mode 100644
index 00000000000..8d1d4cdabda
--- /dev/null
+++ b/code/modules/projectiles/guns/bang/pistol.dm
@@ -0,0 +1,77 @@
+/obj/item/weapon/gun/bang/colt
+ name = "vintage .45 pistol"
+ desc = "A cheap Martian knock-off of a Colt M1911. Uses .45 rounds."
+ icon_state = "colt"
+ pixel_offset_x = 30
+ pixel_offset_y = 18
+
+/obj/item/weapon/gun/bang/sec
+ name = ".45 pistol"
+ desc = "A NanoTrasen designed sidearm, found pretty much everywhere humans are. Uses .45 rounds."
+ icon_state = "secguncomp"
+ pixel_offset_x = 28
+ pixel_offset_y = 14
+
+/obj/item/weapon/gun/bang/sec/flash
+ name = ".45 signal pistol"
+
+/obj/item/weapon/gun/bang/sec/wood
+ desc = "A Nanotrasen designed sidearm, this one has a sweet wooden grip. Uses .45 rounds."
+ name = "custom .45 Pistol"
+ icon_state = "secgundark"
+
+/obj/item/weapon/gun/bang/x9
+ name = "automatic .45 pistol"
+ desc = "The x9 tactical pistol is a lightweight fast firing handgun. Uses .45 rounds."
+ icon_state = "x9tactical"
+ pixel_offset_x = 28
+ pixel_offset_y = 13
+
+/obj/item/weapon/gun/bang/tanto
+ desc = "A Necropolis Industries Tanto .40, designed to compete with the NT Mk58. Uses 10mm rounds."
+ name = "10mm pistol"
+ icon_state = "c05r"
+ pixel_offset_x = 31
+ pixel_offset_y = 14
+
+/obj/item/weapon/gun/bang/silenced
+ name = "silenced pistol"
+ desc = "A small, quiet, easily concealable gun. Uses .45 rounds."
+ icon_state = "silenced_pistol"
+ pixel_offset_x = -4
+ pixel_offset_y = 15
+
+obj/item/weapon/gun/bang/deagle
+ name = ".50 magnum pistol"
+ desc = "A robust handgun that uses .50 AE ammo."
+ icon_state = "deagle"
+ pixel_offset_x = -4
+ pixel_offset_y = 16
+
+/obj/item/weapon/gun/bang/deagle/gold
+ desc = "A gold plated gun folded over a million times by superior martian gunsmiths. Uses .50 AE ammo."
+ icon_state = "deagleg"
+ item_state = "deagleg"
+
+/obj/item/weapon/gun/bang/deagle/camo
+ desc = "A Deagle brand Deagle for operators operating operationally. Uses .50 AE ammo."
+ icon_state = "deaglecamo"
+
+/obj/item/weapon/gun/bang/pistol
+ name = "9mm pistol"
+ desc = "500 years since its creation and the Stechkin automatic pistol is still a common sight throughout the Frontier."
+ icon_state = "pistol"
+ item_state = null
+ pixel_offset_x = 26
+ pixel_offset_y = 14
+
+/obj/item/weapon/gun/bang/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."
+ icon_state = "zipgun"
+ item_state = "sawnshotgun"
+ pixel_offset_x = 0
+ pixel_offset_y = 12
+
+
+
diff --git a/code/modules/projectiles/guns/bang/revolver.dm b/code/modules/projectiles/guns/bang/revolver.dm
new file mode 100644
index 00000000000..eb8fa315b67
--- /dev/null
+++ b/code/modules/projectiles/guns/bang/revolver.dm
@@ -0,0 +1,3 @@
+/obj/item/weapon/gun/bang/revolver
+ name = "revolver"
+ desc = "The classic Necropolis Industries .357 revolver, for when you only want to shoot once."
diff --git a/code/modules/projectiles/guns/projectile/rifle.dm b/code/modules/projectiles/guns/projectile/rifle.dm
index f875311ce8f..617de99c60f 100644
--- a/code/modules/projectiles/guns/projectile/rifle.dm
+++ b/code/modules/projectiles/guns/projectile/rifle.dm
@@ -140,4 +140,109 @@
if(!retracted_bolt)
to_chat(user, "You can't load \the [src] without cycling the bolt.")
return
+ ..()
+
+/obj/item/weapon/gun/projectile/boltaction/vintage
+ name = "\improper vintage bolt action rifle"
+ desc = "An extremely old-looking rifle. Words you can't read are stamped on the gun. Doesn't look like it'll take any modern rounds."
+ icon_state = "springfield"
+ origin_tech = list(TECH_COMBAT = 1, TECH_MATERIAL = 3)
+ fire_sound = 'sound/weapons/rifleshot.ogg'
+ slot_flags = SLOT_BACK
+ load_method = SINGLE_CASING|SPEEDLOADER
+ handle_casings = HOLD_CASINGS
+ caliber = "vintage"
+ ammo_type = /obj/item/ammo_casing/vintage
+ var/open_bolt = 0
+ var/obj/item/ammo_magazine/boltaction/vintage/has_clip
+
+ action_button_name = "Wield rifle"
+
+
+/obj/item/weapon/gun/projectile/boltaction/vintage/attack_self(mob/living/user as mob)
+ if(wielded)
+ if(world.time >= recentpump + 10)
+ pump(user)
+ recentpump = world.time
+ return
+ else
+ if(open_bolt && has_clip)
+ if(has_clip.stored_ammo.len > 0)
+ load_ammo(has_clip, user)
+ src.cut_overlays()
+ if(!has_clip.stored_ammo.len)
+ src.add_overlay(image('icons/obj/gun.dmi', "springfield-clip-empty"))
+ else if(has_clip.stored_ammo.len <= 3)
+ src.add_overlay(image('icons/obj/gun.dmi', "springfield-clip-half"))
+ else
+ src.add_overlay(image('icons/obj/gun.dmi', "springfield-clip-full"))
+ else
+ user << "There is no ammo in \the [has_clip.name]!"
+ else if(!open_bolt)
+ user << "The bolt on \the [src.name] is closed!"
+ else
+ user << "There is no clip in \the [src.name]!"
+
+/obj/item/weapon/gun/projectile/boltaction/vintage/pump(mob/M as mob)
+ if(!wielded)
+ M << "You cannot work \the [src.name]'s bolt without gripping it with both hands!"
+ return
+ if(!open_bolt)
+ open_bolt = 1
+ icon_state = "springfield-openbolt"
+ playsound(M, 'sound/weapons/riflebolt.ogg', 60, 1)
+ update_icon()
+ return
+ open_bolt = 0
+ icon_state = "springfield"
+ playsound(M, 'sound/weapons/riflebolt.ogg', 60, 1)
+ if(has_clip)
+ has_clip.forceMove(get_turf(src))
+ has_clip = null
+ src.cut_overlays()
+
+
+ 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/vintage/attackby(var/obj/item/A as obj, mob/user as mob)
+ if(istype(A, /obj/item/ammo_magazine/boltaction/vintage))
+ if(!open_bolt)
+ user << "You need to open the bolt of \the [src] first."
+ return
+ if(!has_clip)
+ user.drop_from_inventory(A)
+ A.forceMove(src)
+ has_clip = A
+ user << "You load the clip into \the [src]."
+ if(!has_clip.stored_ammo.len)
+ src.add_overlay(image('icons/obj/gun.dmi', "springfield-clip-empty"))
+ else if(has_clip.stored_ammo.len <= 3)
+ src.add_overlay(image('icons/obj/gun.dmi', "springfield-clip-half"))
+ else
+ src.add_overlay(image('icons/obj/gun.dmi', "springfield-clip-full"))
+ else
+ user << "There's already a clip in \the [src]."
+
+ else
+ ..()
+
+/obj/item/weapon/gun/projectile/boltaction/vintage/load_ammo(var/obj/item/A, mob/user)
+ if(!open_bolt)
+ user << "The bolt is closed on \the [src.name]!"
+ return
+ ..()
+
+/obj/item/weapon/gun/projectile/boltaction/vintage/Fire(atom/target, mob/living/user, clickparams, pointblank=0, reflex=0)
+ if(open_bolt)
+ user << "The bolt is open on \the [src.name]!"
+ return
..()
\ No newline at end of file
diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm
index db94b49f6b7..66ca3ce3cb5 100644
--- a/code/modules/projectiles/projectile/bullets.dm
+++ b/code/modules/projectiles/projectile/bullets.dm
@@ -200,6 +200,11 @@
armor_penetration = 80
hitscan = 1 //so the PTR isn't useless as a sniper weapon
+/obj/item/projectile/bullet/rifle/vintage
+ name = "vintage bullet"
+ damage = 50
+ weaken = 1
+
/obj/item/projectile/bullet/rifle/tranq
name = "dart"
icon_state = "dart"
@@ -313,4 +318,6 @@
/obj/item/projectile/bullet/flechette/explosive
shrapnel_type = /obj/item/weapon/material/shard/shrapnel/flechette
penetrating = 0
- damage = 10
\ No newline at end of file
+ damage = 10
+
+
diff --git a/html/changelogs/WrongEnd-anal_retentive_bolt_action.yml b/html/changelogs/WrongEnd-anal_retentive_bolt_action.yml
new file mode 100644
index 00000000000..3e9776cbf24
--- /dev/null
+++ b/html/changelogs/WrongEnd-anal_retentive_bolt_action.yml
@@ -0,0 +1,37 @@
+################################
+# 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
+#################################
+
+# Your name.
+author: WrongEnd
+
+# 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:
+ - rscadd: "Adds anal retentive bolt action rifles and prank guns."
\ No newline at end of file
diff --git a/icons/obj/bang_flag.dmi b/icons/obj/bang_flag.dmi
new file mode 100644
index 00000000000..9cdd6fe0260
Binary files /dev/null and b/icons/obj/bang_flag.dmi differ
diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi
index b7662912d01..c76dfa10317 100644
Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ
diff --git a/sound/weapons/bangGun.ogg b/sound/weapons/bangGun.ogg
new file mode 100644
index 00000000000..8fe7505bf1a
Binary files /dev/null and b/sound/weapons/bangGun.ogg differ