diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index f00146d7848..299b829edec 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -157,6 +157,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_NOFLASH "noflash" //Makes you immune to flashes
#define TRAIT_XENO_IMMUNE "xeno_immune"//prevents xeno huggies implanting skeletons
#define TRAIT_NAIVE "naive"
+#define TRAIT_GUNFLIP "gunflip"
//non-mob traits
#define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it
diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm
index 83ea9fefb6c..1fbfb67d821 100644
--- a/code/_globalvars/traits.dm
+++ b/code/_globalvars/traits.dm
@@ -97,7 +97,8 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_PASSTABLE" = TRAIT_PASSTABLE,
"TRAIT_NOFLASH" = TRAIT_NOFLASH,
"TRAIT_XENO_IMMUNE" = TRAIT_XENO_IMMUNE,
- "TRAIT_NAIVE" = TRAIT_NAIVE
+ "TRAIT_NAIVE" = TRAIT_NAIVE,
+ "TRAIT_GUNFLIP" = TRAIT_GUNFLIP
),
/obj/item/bodypart = list(
"TRAIT_PARALYSIS" = TRAIT_PARALYSIS
diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm
index 0583aaf4867..543ba33bcf0 100644
--- a/code/game/objects/items/storage/belt.dm
+++ b/code/game/objects/items/storage/belt.dm
@@ -564,31 +564,6 @@
/obj/item/ammo_casing/shotgun
))
-/obj/item/storage/belt/holster
- name = "shoulder holster"
- desc = "A holster to carry a handgun and ammo. WARNING: Badasses only."
- icon_state = "holster"
- item_state = "holster"
- alternate_worn_layer = UNDER_SUIT_LAYER
-
-/obj/item/storage/belt/holster/ComponentInitialize()
- . = ..()
- var/datum/component/storage/STR = GetComponent(/datum/component/storage)
- STR.max_items = 3
- STR.max_w_class = WEIGHT_CLASS_NORMAL
- STR.set_holdable(list(
- /obj/item/gun/ballistic/automatic/pistol,
- /obj/item/gun/ballistic/revolver,
- /obj/item/ammo_box,
- /obj/item/gun/energy/e_gun/mini
- ))
-
-/obj/item/storage/belt/holster/full/PopulateContents()
- var/static/items_inside = list(
- /obj/item/gun/ballistic/revolver/detective = 1,
- /obj/item/ammo_box/c38 = 2)
- generate_items_inside(items_inside,src)
-
/obj/item/storage/belt/fannypack
name = "fannypack"
desc = "A dorky fannypack for keeping small items in."
diff --git a/code/game/objects/items/storage/holsters.dm b/code/game/objects/items/storage/holsters.dm
new file mode 100644
index 00000000000..39bd034a156
--- /dev/null
+++ b/code/game/objects/items/storage/holsters.dm
@@ -0,0 +1,119 @@
+
+/obj/item/storage/belt/holster
+ name = "shoulder holster"
+ desc = "A rather plain but still badass looking holster with a single pouch that can hold a small firearm."
+ icon_state = "holster"
+ item_state = "holster"
+ alternate_worn_layer = UNDER_SUIT_LAYER
+
+/obj/item/storage/belt/holster/equipped(mob/user, slot)
+ . = ..()
+ if(slot == ITEM_SLOT_BELT)
+ ADD_TRAIT(user, TRAIT_GUNFLIP, CLOTHING_TRAIT)
+
+/obj/item/storage/belt/holster/dropped(mob/user)
+ . = ..()
+ REMOVE_TRAIT(user, TRAIT_GUNFLIP, CLOTHING_TRAIT)
+
+/obj/item/storage/belt/holster/ComponentInitialize()
+ . = ..()
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
+ STR.max_items = 1
+ STR.max_w_class = WEIGHT_CLASS_NORMAL
+ STR.set_holdable(list(
+ /obj/item/gun/ballistic/automatic/pistol,
+ /obj/item/gun/ballistic/revolver,
+ /obj/item/gun/energy/e_gun/mini,
+ /obj/item/gun/energy/disabler,
+ /obj/item/gun/energy/pulse/carbine,
+ /obj/item/gun/energy/dueling
+ ))
+
+/obj/item/storage/belt/holster/detective
+ name = "detective's holster"
+ desc = "A holster to carry a handgun and ammo. WARNING: Badasses only."
+
+/obj/item/storage/belt/holster/detective/ComponentInitialize()
+ . = ..()
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
+ STR.max_items = 3
+ STR.max_w_class = WEIGHT_CLASS_NORMAL
+ STR.set_holdable(list(
+ /obj/item/gun/ballistic/revolver,
+ /obj/item/ammo_box,
+ /obj/item/gun/energy/disabler,
+ /obj/item/gun/energy/dueling
+ ))
+
+/obj/item/storage/belt/holster/detective/full/PopulateContents()
+ var/static/items_inside = list(
+ /obj/item/gun/ballistic/revolver/detective = 1,
+ /obj/item/ammo_box/c38 = 2)
+ generate_items_inside(items_inside,src)
+
+/obj/item/storage/belt/holster/chameleon
+ name = "syndicate holster"
+ desc = "A two pouched hip holster that uses chameleon technology to disguise itself and any guns in it."
+ icon_state = "syndicate_holster"
+ item_state = "syndicate_holster"
+ var/datum/action/item_action/chameleon/change/chameleon_action
+
+/obj/item/storage/belt/holster/chameleon/Initialize()
+ . = ..()
+
+ chameleon_action = new(src)
+ chameleon_action.chameleon_type = /obj/item/storage/belt
+ chameleon_action.chameleon_name = "Belt"
+ chameleon_action.initialize_disguises()
+
+/obj/item/storage/belt/chameleon/ComponentInitialize()
+ . = ..()
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
+ STR.silent = TRUE
+
+/obj/item/storage/belt/holster/chameleon/emp_act(severity)
+ . = ..()
+ if(. & EMP_PROTECT_SELF)
+ return
+ chameleon_action.emp_randomise()
+
+/obj/item/storage/belt/holster/chameleon/broken/Initialize()
+ . = ..()
+ chameleon_action.emp_randomise(INFINITY)
+
+/obj/item/storage/belt/holster/chameleon/ComponentInitialize()
+ . = ..()
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
+ STR.max_items = 2
+ STR.max_w_class = WEIGHT_CLASS_NORMAL
+ STR.set_holdable(list(
+ /obj/item/gun/ballistic/automatic/pistol,
+ /obj/item/gun/ballistic/revolver,
+ /obj/item/gun/energy/e_gun/mini,
+ /obj/item/gun/energy/disabler,
+ /obj/item/gun/energy/pulse/carbine,
+ /obj/item/gun/energy/dueling
+ ))
+
+/obj/item/storage/belt/holster/nukie
+ name = "operative holster"
+ desc = "A deep shoulder holster capable of holding almost any form of ballistic weaponry."
+ icon_state = "syndicate_holster"
+ item_state = "syndicate_holster"
+ w_class = WEIGHT_CLASS_BULKY
+
+/obj/item/storage/belt/holster/nukie/ComponentInitialize()
+ . = ..()
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
+ STR.max_items = 2
+ STR.max_w_class = WEIGHT_CLASS_BULKY
+ STR.set_holdable(list(
+ /obj/item/gun/ballistic/automatic,
+ /obj/item/gun/ballistic/revolver,
+ /obj/item/gun/energy/e_gun/mini,
+ /obj/item/gun/energy/disabler,
+ /obj/item/gun/energy/pulse/carbine,
+ /obj/item/gun/energy/dueling,
+ /obj/item/gun/ballistic/shotgun,
+ /obj/item/gun/ballistic/rocketlauncher
+ ))
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
index 43db503b2c0..d8aefab7a1f 100755
--- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
@@ -200,7 +200,7 @@
new /obj/item/holosign_creator/security(src)
new /obj/item/reagent_containers/spray/pepper(src)
new /obj/item/clothing/suit/armor/vest/det_suit(src)
- new /obj/item/storage/belt/holster/full(src)
+ new /obj/item/storage/belt/holster/detective/full(src)
new /obj/item/pinpointer/crew(src)
new /obj/item/twohanded/binoculars(src)
new /obj/item/storage/box/rxglasses/spyglasskit(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/syndicate.dm b/code/game/objects/structures/crates_lockers/closets/syndicate.dm
index 94d1b03fdb0..05f07ecdc46 100644
--- a/code/game/objects/structures/crates_lockers/closets/syndicate.dm
+++ b/code/game/objects/structures/crates_lockers/closets/syndicate.dm
@@ -16,6 +16,7 @@
new /obj/item/storage/belt/military(src)
new /obj/item/crowbar/red(src)
new /obj/item/clothing/glasses/night(src)
+ new /obj/item/storage/belt/holster/nukie(src)
/obj/structure/closet/syndicate/nuclear
desc = "It's a storage unit for a Syndicate boarding party."
diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm
index dab74c0031e..636486ed471 100644
--- a/code/modules/projectiles/guns/ballistic.dm
+++ b/code/modules/projectiles/guns/ballistic.dm
@@ -85,6 +85,7 @@
var/tac_reloads = TRUE //Snowflake mechanic no more.
///Whether the gun can be sawn off by sawing tools
var/can_be_sawn_off = FALSE
+ var/flip_cooldown = 0
/obj/item/gun/ballistic/Initialize()
. = ..()
@@ -339,6 +340,18 @@
return ..()
/obj/item/gun/ballistic/attack_self(mob/living/user)
+ if(HAS_TRAIT(user, TRAIT_GUNFLIP))
+ if(flip_cooldown <= world.time)
+ if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(40))
+ to_chat(user, "While trying to flip the [src] you pull the trigger and accidently shoot yourself!")
+ var/flip_mistake = pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG, BODY_ZONE_HEAD, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_CHEST)
+ process_fire(user, user, FALSE, flip_mistake)
+ user.dropItemToGround(src, TRUE)
+ return
+ flip_cooldown = (world.time + 30)
+ user.visible_message("[user] spins the [src] around their finger by the trigger. That’s pretty badass.")
+ playsound(src, 'sound/items/handling/ammobox_pickup.ogg', 20, FALSE)
+ return
if(!internal_magazine && magazine)
if(!magazine.ammo_count())
eject_magazine(user)
diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm
index f53d58c0eb5..b5dafecf530 100644
--- a/code/modules/uplink/uplink_items.dm
+++ b/code/modules/uplink/uplink_items.dm
@@ -632,6 +632,12 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
surplus = 10
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
+/datum/uplink_item/stealthy_weapons/holster
+ name = "Syndicate Holster"
+ desc = "A useful little device that allows for inconspicuous carrying of guns using chameleon technology. It also allows for badass gun-spinning."
+ item = /obj/item/storage/belt/holster/chameleon
+ cost = 1
+
// Ammunition
/datum/uplink_item/ammo
category = "Ammunition"
diff --git a/icons/mob/clothing/belt.dmi b/icons/mob/clothing/belt.dmi
index efbea555c56..b89a2163471 100644
Binary files a/icons/mob/clothing/belt.dmi and b/icons/mob/clothing/belt.dmi differ
diff --git a/icons/obj/clothing/belts.dmi b/icons/obj/clothing/belts.dmi
index 398add03fc9..45c3091e54a 100644
Binary files a/icons/obj/clothing/belts.dmi and b/icons/obj/clothing/belts.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index eec2cb65503..89d8b5501e5 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -1070,6 +1070,7 @@
#include "code\game\objects\items\storage\briefcase.dm"
#include "code\game\objects\items\storage\fancy.dm"
#include "code\game\objects\items\storage\firstaid.dm"
+#include "code\game\objects\items\storage\holsters.dm"
#include "code\game\objects\items\storage\lockbox.dm"
#include "code\game\objects\items\storage\secure.dm"
#include "code\game\objects\items\storage\sixpack.dm"