From e7e02be0223e88e3d97cbd2fa5d8a852b7d8eae3 Mon Sep 17 00:00:00 2001
From: Gristlebee <56049844+Gristlebee@users.noreply.github.com>
Date: Tue, 26 Nov 2024 21:22:34 -0800
Subject: [PATCH] Adds shoulder holsters to outpost cargo, and usage QOL
(#3763)
## About The Pull Request
Adds shoulder holsters to outpost sec supply for 600 credits.
Replaces black market holsters with cham holsters, chance to spawn
reduced to 40, max stock reduced to 4.
Cham holsters use regular holster storage instead of the weird one they
had before.
Storage components now support holding only a certain amount of a
specified item.
Shoulder holsters can now only hold one pistol/revolver at a time.
Detaching accessories is now bound to Ctrl-click, and alt click will now
open the storage on accessories if possible. Clicking on the attached
jumpsuit with an item will insert it if possible like other storage
items.
If a jumpsuit is destroyed with an accessory attached, it will fall off
instead of being sent into the ether.
## Why It's Good For The Game
Shoulder holsters are flavourful storage options compared to having guns
in your bag and generally nice to have.
The storage change was requested the last time holsters were PRed to the
outpost market, and could be useful in future for other storage items.
QOL life changes to make accessory storage for consistency with other
storage items is good for sanity.
## Changelog
:cl:
add: Shoulder holsters to outpost for 600
add: Cham holsters to black market
add: Accessories will fall off jumpsuits when destroyed.
balance: Shoulder holsters can only hold one gun a time.
fix: Accessory storage acts more consistently like other storage items.
/:cl:
---
.../components/storage/concrete/pockets.dm | 17 +++--------------
code/datums/components/storage/storage.dm | 11 +++++++++++
.../cargo/blackmarket/blackmarket_items/misc.dm | 10 +++++-----
code/modules/cargo/packs/sec_supply.dm | 6 ++++++
code/modules/clothing/clothing.dm | 12 ++++++++++--
code/modules/clothing/under/_under.dm | 12 +++++++++++-
code/modules/clothing/under/accessories.dm | 4 ++--
7 files changed, 48 insertions(+), 24 deletions(-)
diff --git a/code/datums/components/storage/concrete/pockets.dm b/code/datums/components/storage/concrete/pockets.dm
index e00c40e116f8..065a398c3230 100644
--- a/code/datums/components/storage/concrete/pockets.dm
+++ b/code/datums/components/storage/concrete/pockets.dm
@@ -108,6 +108,9 @@
/obj/item/gun/ballistic/automatic/pistol,
/obj/item/gun/ballistic/revolver,
/obj/item/ammo_box))
+ can_hold_max_of_items = typecacheof(list(
+ /obj/item/gun/ballistic = 1
+ ))
/datum/component/storage/concrete/pockets/holster/real_location()
// if the component is reparented to a jumpsuit, the items still go in the protector
@@ -136,17 +139,3 @@
/obj/item/gun/energy/dueling,
/obj/item/gun/ballistic/shotgun,
/obj/item/gun/ballistic/rocketlauncher))
-
-/datum/component/storage/concrete/pockets/holster/chameleon
- max_items = 1
-
-/datum/component/storage/concrete/pockets/holster/chameleon/Initialize()
- original_parent = parent
- . = ..()
- can_hold = typecacheof(list(
- /obj/item/gun/ballistic/automatic/pistol/ringneck,
- /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))
diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm
index 765e14e5db64..fab8ffdf3a2c 100644
--- a/code/datums/components/storage/storage.dm
+++ b/code/datums/components/storage/storage.dm
@@ -18,6 +18,7 @@
var/list/cant_hold //if this is set, items, and their children, won't fit
var/list/exception_hold //if set, these items will be the exception to the max size of object that can fit.
var/list/can_hold_trait /// If set can only contain stuff with this single trait present.
+ var/list/can_hold_max_of_items // if set, storage can only hold up to the set amount of said item.
var/can_hold_description
@@ -566,6 +567,16 @@
if(!stop_messages)
to_chat(M, "[host] cannot hold [I]!")
return FALSE
+ if(length(can_hold_max_of_items))
+ if(is_type_in_typecache(I,can_hold_max_of_items))
+ var/amount = 0
+ for(var/_item in contents())
+ if(is_type_in_typecache(_item,can_hold_max_of_items))
+ amount++
+ if(amount >= can_hold_max_of_items[I.type])
+ if(!stop_messages)
+ to_chat(M, "[host] cannot hold another [I]!")
+ return FALSE
if(is_type_in_typecache(I, cant_hold) || HAS_TRAIT(I, TRAIT_NO_STORAGE_INSERT) || (can_hold_trait && !HAS_TRAIT(I, can_hold_trait))) //Items which this container can't hold.
if(!stop_messages)
to_chat(M, "[host] cannot hold [I]!")
diff --git a/code/modules/cargo/blackmarket/blackmarket_items/misc.dm b/code/modules/cargo/blackmarket/blackmarket_items/misc.dm
index 8f51514de804..a9221fb95ecb 100644
--- a/code/modules/cargo/blackmarket/blackmarket_items/misc.dm
+++ b/code/modules/cargo/blackmarket/blackmarket_items/misc.dm
@@ -11,15 +11,15 @@
stock_max = 6
availability_prob = 80
-/datum/blackmarket_item/misc/shoulder_holster
- name = "Shoulder holster"
- desc = "Yeehaw, hardboiled friends! This holster is the first step in your dream of becoming a detective and being allowed to shoot real guns!"
+/datum/blackmarket_item/misc/cham_holster
+ name = "Chameleon Shoulder holster"
+ desc = "Looking to pack some heat without attracting attention? This adapative chameleon shoulder holster can disguise itself and your piece!"
item = /obj/item/clothing/accessory/holster
price_min = 200
price_max = 800
- stock_max = 8
- availability_prob = 60
+ stock_max = 4
+ availability_prob = 40
/datum/blackmarket_item/misc/strange_seed
name = "Strange Seeds"
diff --git a/code/modules/cargo/packs/sec_supply.dm b/code/modules/cargo/packs/sec_supply.dm
index 601d387cb222..86d631024705 100644
--- a/code/modules/cargo/packs/sec_supply.dm
+++ b/code/modules/cargo/packs/sec_supply.dm
@@ -5,6 +5,12 @@
/*
Standard supplies
*/
+/datum/supply_pack/sec_supply/holster
+ name = "Shoulder Holster Crate"
+ desc = "Contains a shoulder holster, capable of holding a single pistol or revolver and your ammo."
+ cost = 600
+ contains = list(/obj/item/clothing/accessory/holster)
+ crate_name = "holster crate"
/datum/supply_pack/sec_supply/chemimp
name = "Chemical Implants Crate"
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index 8313beaa408c..c07c52a57e84 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -416,11 +416,19 @@
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
else
- if(attached_accessory)
- remove_accessory(user)
+ if(attached_accessory && ispath(attached_accessory.pocket_storage_component_path) && loc == user)
+ attached_accessory.attack_hand(user)
+ return
else
rolldown()
+/obj/item/clothing/under/CtrlClick(mob/user)
+ if(..())
+ return 1
+ if(attached_accessory)
+ remove_accessory(user)
+
+
/obj/item/clothing/under/verb/jumpsuit_adjust()
set name = "Adjust Jumpsuit Style"
set category = null
diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm
index 8843009813f3..7445eb2ad55a 100644
--- a/code/modules/clothing/under/_under.dm
+++ b/code/modules/clothing/under/_under.dm
@@ -39,6 +39,11 @@
if(accessory_overlay)
. += accessory_overlay
+/obj/item/clothing/under/Destroy()
+ . = ..()
+ if(attached_accessory)
+ attached_accessory.detach(src)
+
/obj/item/clothing/under/attackby(obj/item/I, mob/user, params)
if((has_sensor == BROKEN_SENSORS) && istype(I, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = I
@@ -46,6 +51,9 @@
has_sensor = HAS_SENSORS
to_chat(user,"You repair the suit sensors on [src] with [C].")
return 1
+ if(attached_accessory && ispath(attached_accessory.pocket_storage_component_path) && loc == user)
+ attached_accessory.attackby(I,user)
+ return
if(!attach_accessory(I, user))
return ..()
@@ -180,7 +188,9 @@
if(SENSOR_COORDS)
. += "Its vital tracker and tracking beacon appear to be enabled."
if(attached_accessory)
- . += "\A [attached_accessory] is attached to it."
+ . += "\A [attached_accessory] is attached to it. You could Ctrl-click on it to remove it."
+ if(attached_accessory.pocket_storage_component_path)
+ . += "You could open the storage of \the [attached_accessory] with Alt-click."
/obj/item/clothing/under/rank
dying_key = DYE_REGISTRY_UNDER
diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm
index 81e5da317553..9e66e9572c59 100644
--- a/code/modules/clothing/under/accessories.dm
+++ b/code/modules/clothing/under/accessories.dm
@@ -92,10 +92,11 @@
if(initial(above_suit))
above_suit = !above_suit
to_chat(user, "[src] will be worn [above_suit ? "above" : "below"] your suit.")
+ return ..()
/obj/item/clothing/accessory/examine(mob/user)
. = ..()
- . += "\The [src] can be attached to a uniform. Alt-click to remove it once attached."
+ . += "\The [src] can be attached to a uniform. Ctrl-click to remove it once attached."
if(initial(above_suit))
. += "\The [src] can be worn above or below your suit. Alt-click to toggle."
@@ -431,7 +432,6 @@
name = "syndicate holster"
desc = "A two pouched hip holster that uses chameleon technology to disguise itself and any guns in it."
var/datum/action/item_action/chameleon/change/chameleon_action
- pocket_storage_component_path = /datum/component/storage/concrete/pockets/holster/chameleon
/obj/item/clothing/accessory/holster/chameleon/Initialize()
. = ..()