diff --git a/baystation12.dme b/baystation12.dme
index 6bf05b97b90..9d315198985 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -994,6 +994,7 @@
#include "code\modules\client\preference_setup\skills\skills.dm"
#include "code\modules\clothing\chameleon.dm"
#include "code\modules\clothing\clothing.dm"
+#include "code\modules\clothing\clothing_accessories.dm"
#include "code\modules\clothing\ears\skrell.dm"
#include "code\modules\clothing\glasses\glasses.dm"
#include "code\modules\clothing\glasses\hud.dm"
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index 681b33d6892..81d9bc4a8c7 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -6,6 +6,10 @@
var/list/species_restricted = null //Only these species can wear this kit.
var/gunshot_residue //Used by forensics.
+ var/list/accessories = list()
+ var/list/valid_accessory_slots
+ var/list/restricted_accessory_slots
+
/*
Sprites used when the clothing item is refit. This is done by setting icon_override.
For best results, if this is set then sprite_sheets should be null and vice versa, but that is by no means necessary.
@@ -509,7 +513,6 @@ BLIND // can't see anything
2 = Report detailed damages
3 = Report location
*/
- var/list/accessories = list()
var/displays_id = 1
var/rolled_down = -1 //0 = unrolled, 1 = rolled, -1 = cannot be toggled
sprite_sheets = list(
@@ -520,6 +523,15 @@ BLIND // can't see anything
//convenience var for defining the icon state for the overlay used when the clothing is worn.
//Also used by rolling/unrolling.
var/worn_state = null
+ valid_accessory_slots = list("utility","armband","decor")
+ restricted_accessory_slots = list("utility", "armband")
+
+
+/obj/item/clothing/under/attack_hand(var/mob/user)
+ if(accessories && accessories.len)
+ ..()
+ if ((ishuman(usr) || issmall(usr)) && src.loc == user)
+ return
/obj/item/clothing/under/New()
..()
@@ -563,69 +575,6 @@ BLIND // can't see anything
var/mob/M = src.loc
M.update_inv_w_uniform()
-/obj/item/clothing/under/proc/can_attach_accessory(obj/item/clothing/accessory/A)
- if(istype(A))
- .=1
- else
- return 0
- if(accessories.len && (A.slot in list("utility","armband")))
- for(var/obj/item/clothing/accessory/AC in accessories)
- if (AC.slot == A.slot)
- return 0
-
-/obj/item/clothing/under/attackby(obj/item/I, mob/user)
- if(istype(I, /obj/item/clothing/accessory))
- var/obj/item/clothing/accessory/A = I
- if(can_attach_accessory(A))
- user.drop_item()
- accessories += A
- A.on_attached(src, user)
-
- if(istype(loc, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = loc
- H.update_inv_w_uniform()
-
- return
- else
- user << "You cannot attach more accessories of this type to [src]."
-
- if(accessories.len)
- for(var/obj/item/clothing/accessory/A in accessories)
- A.attackby(I, user)
- return
-
- ..()
-
-/obj/item/clothing/under/attack_hand(mob/user as mob)
- //only forward to the attached accessory if the clothing is equipped (not in a storage)
- if(accessories.len && src.loc == user)
- for(var/obj/item/clothing/accessory/A in accessories)
- A.attack_hand(user)
- return
-
- if ((ishuman(usr) || issmall(usr)) && src.loc == user) //make it harder to accidentally undress yourself
- return
-
- ..()
-
-/obj/item/clothing/under/MouseDrop(obj/over_object as obj)
- if (ishuman(usr) || issmall(usr))
- //makes sure that the clothing is equipped so that we can't drag it into our hand from miles away.
- if (!(src.loc == usr))
- return
-
- if (( usr.restrained() ) || ( usr.stat ))
- return
-
- if (!usr.unEquip(src))
- return
-
- switch(over_object.name)
- if("r_hand")
- usr.put_in_r_hand(src)
- if("l_hand")
- usr.put_in_l_hand(src)
- src.add_fingerprint(usr)
/obj/item/clothing/under/examine(mob/user)
..(user)
@@ -638,9 +587,6 @@ BLIND // can't see anything
user << "Its vital tracker appears to be enabled."
if(3)
user << "Its vital tracker and tracking beacon appear to be enabled."
- if(accessories.len)
- for(var/obj/item/clothing/accessory/A in accessories)
- user << "\A [A] is attached to it."
/obj/item/clothing/under/proc/set_sensors(mob/usr as mob)
var/mob/M = usr
@@ -713,34 +659,7 @@ BLIND // can't see anything
item_state_slots[slot_w_uniform_str] = "[worn_state]"
update_clothing_icon()
-/obj/item/clothing/under/proc/remove_accessory(mob/user, obj/item/clothing/accessory/A)
- if(!(A in accessories))
- return
-
- A.on_removed(user)
- accessories -= A
- update_clothing_icon()
-
-/obj/item/clothing/under/verb/removetie()
- set name = "Remove Accessory"
- set category = "Object"
- set src in usr
- if(!istype(usr, /mob/living)) return
- if(usr.stat) return
- if(!accessories.len) return
- var/obj/item/clothing/accessory/A
- if(accessories.len > 1)
- A = input("Select an accessory to remove from [src]") as null|anything in accessories
- else
- A = accessories[1]
- src.remove_accessory(usr,A)
/obj/item/clothing/under/rank/New()
sensor_mode = pick(0,1,2,3)
..()
-
-/obj/item/clothing/under/emp_act(severity)
- if(accessories.len)
- for(var/obj/item/clothing/accessory/A in accessories)
- A.emp_act(severity)
- ..()
\ No newline at end of file
diff --git a/code/modules/clothing/clothing_accessories.dm b/code/modules/clothing/clothing_accessories.dm
new file mode 100644
index 00000000000..57e22d6ba04
--- /dev/null
+++ b/code/modules/clothing/clothing_accessories.dm
@@ -0,0 +1,100 @@
+/obj/item/clothing/proc/can_attach_accessory(obj/item/clothing/accessory/A)
+ if(valid_accessory_slots && istype(A) && (A.slot in valid_accessory_slots))
+ .=1
+ else
+ return 0
+ if(accessories.len && restricted_accessory_slots && (A.slot in restricted_accessory_slots))
+ for(var/obj/item/clothing/accessory/AC in accessories)
+ if (AC.slot == A.slot)
+ return 0
+
+/obj/item/clothing/attackby(var/obj/item/I, var/mob/user)
+ if(istype(I, /obj/item/clothing/accessory))
+
+ if(!valid_accessory_slots || !valid_accessory_slots.len)
+ usr << "You cannot attach accessories of any kind to \the [src]."
+ return
+
+ var/obj/item/clothing/accessory/A = I
+ if(can_attach_accessory(A))
+ user.drop_item()
+ accessories += A
+ A.on_attached(src, user)
+ src.verbs |= /obj/item/clothing/proc/removetie_verb
+ if(istype(loc, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = loc
+ H.update_inv_w_uniform()
+ return
+ else
+ user << "You cannot attach more accessories of this type to [src]."
+ return
+
+ if(accessories.len)
+ for(var/obj/item/clothing/accessory/A in accessories)
+ A.attackby(I, user)
+ return
+
+ ..()
+
+/obj/item/clothing/attack_hand(var/mob/user)
+ //only forward to the attached accessory if the clothing is equipped (not in a storage)
+ if(accessories.len && src.loc == user)
+ for(var/obj/item/clothing/accessory/A in accessories)
+ A.attack_hand(user)
+ return
+ return ..()
+
+/obj/item/clothing/MouseDrop(var/obj/over_object)
+ if (ishuman(usr) || issmall(usr))
+ //makes sure that the clothing is equipped so that we can't drag it into our hand from miles away.
+ if (!(src.loc == usr))
+ return
+
+ if (( usr.restrained() ) || ( usr.stat ))
+ return
+
+ if (!usr.unEquip(src))
+ return
+
+ switch(over_object.name)
+ if("r_hand")
+ usr.put_in_r_hand(src)
+ if("l_hand")
+ usr.put_in_l_hand(src)
+ src.add_fingerprint(usr)
+
+/obj/item/clothing/examine(var/mob/user)
+ ..(user)
+ if(accessories.len)
+ for(var/obj/item/clothing/accessory/A in accessories)
+ user << "\A [A] is attached to it."
+
+/obj/item/clothing/proc/remove_accessory(mob/user, obj/item/clothing/accessory/A)
+ if(!(A in accessories))
+ return
+
+ A.on_removed(user)
+ accessories -= A
+ update_clothing_icon()
+
+/obj/item/clothing/proc/removetie_verb()
+ set name = "Remove Accessory"
+ set category = "Object"
+ set src in usr
+ if(!istype(usr, /mob/living)) return
+ if(usr.stat) return
+ if(!accessories.len) return
+ var/obj/item/clothing/accessory/A
+ if(accessories.len > 1)
+ A = input("Select an accessory to remove from [src]") as null|anything in accessories
+ else
+ A = accessories[1]
+ src.remove_accessory(usr,A)
+ if(!accessories.len)
+ src.verbs -= /obj/item/clothing/proc/removetie_verb
+
+/obj/item/clothing/emp_act(severity)
+ if(accessories.len)
+ for(var/obj/item/clothing/accessory/A in accessories)
+ A.emp_act(severity)
+ ..()
\ No newline at end of file
diff --git a/code/modules/clothing/spacesuits/void/void.dm b/code/modules/clothing/spacesuits/void/void.dm
index 2c6d761a7a6..86edeca84dd 100644
--- a/code/modules/clothing/spacesuits/void/void.dm
+++ b/code/modules/clothing/spacesuits/void/void.dm
@@ -186,8 +186,11 @@
if(!istype(user,/mob/living)) return
+ if(istype(W,/obj/item/clothing/accessory) || istype(W, /obj/item/weapon/hand_labeler))
+ return ..()
+
if(istype(src.loc,/mob/living))
- user << "How do you propose to modify a voidsuit while it is being worn?"
+ user << "You cannot modify \the [src] while it is being worn."
return
if(istype(W,/obj/item/weapon/screwdriver))
diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm
index bdc9f33a2e9..0f4ec46c941 100644
--- a/code/modules/clothing/under/accessories/accessory.dm
+++ b/code/modules/clothing/under/accessories/accessory.dm
@@ -7,16 +7,20 @@
slot_flags = SLOT_TIE
w_class = 2.0
var/slot = "decor"
- var/obj/item/clothing/under/has_suit = null //the suit the tie may be attached to
+ var/obj/item/clothing/has_suit = null //the suit the tie may be attached to
var/image/inv_overlay = null //overlay used when attached to clothing.
var/image/mob_overlay = null
var/overlay_state = null
+/obj/item/clothing/accessory/Destroy()
+ on_removed()
+ return ..()
+
/obj/item/clothing/accessory/proc/get_inv_overlay()
if(!inv_overlay)
if(!mob_overlay)
get_mob_overlay()
-
+
var/tmp_icon_state = "[overlay_state? "[overlay_state]" : "[icon_state]"]"
if(icon_override)
if("[tmp_icon_state]_tie" in icon_states(icon_override))
@@ -36,23 +40,26 @@
return mob_overlay
//when user attached an accessory to S
-/obj/item/clothing/accessory/proc/on_attached(obj/item/clothing/under/S, mob/user as mob)
+/obj/item/clothing/accessory/proc/on_attached(var/obj/item/clothing/S, var/mob/user)
if(!istype(S))
return
has_suit = S
loc = has_suit
has_suit.overlays += get_inv_overlay()
- user << "You attach [src] to [has_suit]."
+ user << "You attach \the [src] to \the [has_suit]."
src.add_fingerprint(user)
-/obj/item/clothing/accessory/proc/on_removed(mob/user as mob)
+/obj/item/clothing/accessory/proc/on_removed(var/mob/user)
if(!has_suit)
return
has_suit.overlays -= get_inv_overlay()
has_suit = null
- usr.put_in_hands(src)
- src.add_fingerprint(user)
+ if(user)
+ usr.put_in_hands(src)
+ src.add_fingerprint(user)
+ else
+ src.forceMove(get_turf(src))
//default attackby behaviour
/obj/item/clothing/accessory/attackby(obj/item/I, mob/user)
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 9140428d790..dcd7e06f235 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -770,6 +770,12 @@ var/global/list/damage_icon_parts = list()
bloodsies.color = wear_suit.blood_color
standing.overlays += bloodsies
+ // Accessories - copied from uniform, BOILERPLATE because fuck this system.
+ var/obj/item/clothing/suit/suit = wear_suit
+ if(istype(suit) && suit.accessories.len)
+ for(var/obj/item/clothing/accessory/A in suit.accessories)
+ standing.overlays |= A.get_mob_overlay()
+
overlays_standing[SUIT_LAYER] = standing
update_tail_showing(0)
diff --git a/html/changelogs/Zuhayr-accessorizing.yml b/html/changelogs/Zuhayr-accessorizing.yml
new file mode 100644
index 00000000000..88048209879
--- /dev/null
+++ b/html/changelogs/Zuhayr-accessorizing.yml
@@ -0,0 +1,5 @@
+author: Zuhayr
+delete-after: True
+changes:
+ - tweak: "Backend change: allowed accessories to be placed on any clothing item with the appropriate variables set."
+