## About The Pull Request

Adds 2 hoodie variants, the pullover and the zip-up.
Both recolorable via GAGs.
Both available in the clothesmate and in loadout.

(90% "vibe-coded" ((SORRY!!)) but thoroughly tested with no issues*)
*ok one little issue being recoloring a hoodie with a spraycan does not
recolor the hood and you need to also spray the hood itself to color it.
a problem that has already existed in the codebase and i was unable to
find a fix for.


###### Pullover hood-down / Pullover hood-up with random recolors
underneath.
<img width="192" height="192" alt="dreamseeker_3DwQU9FPb2"
src="https://github.com/user-attachments/assets/fce54ba7-138f-4961-ad87-de072fa1ab55"
/>

###### Zipup unzipped hood-down / Zipup unzipped hood-up / Zipup zipped
hood-down / Zipup zipped hood-up with random colors underneath.
<img width="320" height="192" alt="dreamseeker_COJPWnFa84"
src="https://github.com/user-attachments/assets/b91ba86f-36cc-4c89-99aa-c6848554ea1c"
/>

## Why It's Good For The Game

Hoodies are a staple to many and have been requested frequently over the
years.
## Changelog
🆑
image: Hoodies! Both pullover and zip-up hoodies are available in the
clothesmate and in loadouts!
/🆑
This commit is contained in:
Twaticus
2026-04-11 13:49:02 -04:00
committed by GitHub
parent 1f8d331dab
commit 16d7023da4
19 changed files with 295 additions and 2 deletions
@@ -743,6 +743,46 @@
name = "H.E.C.K. Helmet (Worn)"
icon_file = 'icons/mob/clothing/head/helmet.dmi'
/datum/greyscale_config/hoodie_pullover
name = "Pullover Hoodie"
icon_file = 'icons/obj/clothing/suits/wintercoat.dmi'
json_config = 'code/datums/greyscale/json_configs/pullover.json'
/datum/greyscale_config/hoodie_pullover/worn
name = "Pullover Hoodie (Worn)"
icon_file = 'icons/mob/clothing/suits/wintercoat.dmi'
json_config = 'code/datums/greyscale/json_configs/pullover_worn.json'
/datum/greyscale_config/hoodie_pullover_hood
name = "Pullover Hood"
icon_file = 'icons/obj/clothing/head/winterhood.dmi'
json_config = 'code/datums/greyscale/json_configs/pullover_hood.json'
/datum/greyscale_config/hoodie_pullover_hood/worn
name = "Pullover Hood (Worn)"
icon_file = 'icons/mob/clothing/head/winterhood.dmi'
json_config = 'code/datums/greyscale/json_configs/pullover_hood_worn.json'
/datum/greyscale_config/hoodie_zipup
name = "Zipup Hoodie"
icon_file = 'icons/obj/clothing/suits/wintercoat.dmi'
json_config = 'code/datums/greyscale/json_configs/zipup.json'
/datum/greyscale_config/hoodie_zipup/worn
name = "Zipup Hoodie (Worn)"
icon_file = 'icons/mob/clothing/suits/wintercoat.dmi'
json_config = 'code/datums/greyscale/json_configs/zipup_worn.json'
/datum/greyscale_config/hoodie_zipup_hood
name = "Zipup Hood"
icon_file = 'icons/obj/clothing/head/winterhood.dmi'
json_config = 'code/datums/greyscale/json_configs/zipup_hood.json'
/datum/greyscale_config/hoodie_zipup_hood/worn
name = "Zipup Hood (Worn)"
icon_file = 'icons/mob/clothing/head/winterhood.dmi'
json_config = 'code/datums/greyscale/json_configs/zipup_hood_worn.json'
//
// COSTUMES
// (It's better these stay paired together)
@@ -0,0 +1,18 @@
{
"pullover": [
{
"type": "icon_state",
"icon_state": "pullover",
"blend_mode": "overlay",
"color_ids": [1]
}
],
"pullover_t": [
{
"type": "icon_state",
"icon_state": "pullover_t",
"blend_mode": "overlay",
"color_ids": [1]
}
]
}
@@ -0,0 +1,10 @@
{
"hood_pullover": [
{
"type": "icon_state",
"icon_state": "hood_pullover",
"blend_mode": "overlay",
"color_ids": [1]
}
]
}
@@ -0,0 +1,10 @@
{
"hood_pullover": [
{
"type": "icon_state",
"icon_state": "hood_pullover",
"blend_mode": "overlay",
"color_ids": [1]
}
]
}
@@ -0,0 +1,24 @@
{
"pullover": [
{
"type": "icon_state",
"icon_state": "pullover",
"blend_mode": "overlay",
"color_ids": [1]
},
{
"type": "icon_state",
"icon_state": "pullover_hood",
"blend_mode": "overlay",
"color_ids": [1]
}
],
"pullover_t": [
{
"type": "icon_state",
"icon_state": "pullover_t",
"blend_mode": "overlay",
"color_ids": [1]
}
]
}
@@ -0,0 +1,18 @@
{
"zipup": [
{
"type": "icon_state",
"icon_state": "zipup",
"blend_mode": "overlay",
"color_ids": [1]
}
],
"zipup_t": [
{
"type": "icon_state",
"icon_state": "zipup_t",
"blend_mode": "overlay",
"color_ids": [1]
}
]
}
@@ -0,0 +1,10 @@
{
"hood_zipup": [
{
"type": "icon_state",
"icon_state": "hood_zipup",
"blend_mode": "overlay",
"color_ids": [1]
}
]
}
@@ -0,0 +1,18 @@
{
"hood_zipup": [
{
"type": "icon_state",
"icon_state": "hood_zipup",
"blend_mode": "overlay",
"color_ids": [1]
}
],
"hood_zipup_t": [
{
"type": "icon_state",
"icon_state": "hood_zipup_t",
"blend_mode": "overlay",
"color_ids": [1]
}
]
}
@@ -0,0 +1,34 @@
{
"zipup": [
{
"type": "icon_state",
"icon_state": "zipup",
"blend_mode": "overlay",
"color_ids": [1]
}
],
"zipup_t": [
{
"type": "icon_state",
"icon_state": "zipup_t",
"blend_mode": "overlay",
"color_ids": [1]
}
],
"zipup_hood": [
{
"type": "icon_state",
"icon_state": "zipup_hood",
"blend_mode": "overlay",
"color_ids": [1]
}
],
"zipup_hood_t": [
{
"type": "icon_state",
"icon_state": "zipup_hood_t",
"blend_mode": "overlay",
"color_ids": [1]
}
]
}
+4
View File
@@ -75,6 +75,10 @@
icon_state = "hide_winterhood"
strict_coverage_zones = HAIR_APPENDAGE_TOP | HAIR_APPENDAGE_LEFT | HAIR_APPENDAGE_RIGHT | HAIR_APPENDAGE_REAR | HAIR_APPENDAGE_HANGING_REAR
/datum/hair_mask/hoodie
icon_state = "hide_hoodie"
strict_coverage_zones = HAIR_APPENDAGE_TOP | HAIR_APPENDAGE_LEFT | HAIR_APPENDAGE_RIGHT | HAIR_APPENDAGE_REAR | HAIR_APPENDAGE_HANGING_REAR
//////////////////////
// Hair Definitions //
//////////////////////
+99 -2
View File
@@ -14,6 +14,8 @@
hood_down_overlay_suffix = "_hood"
/// How snug are we?
var/zipped = FALSE
/// Whether alt-clicking this coat zips/unzips it
var/can_altclick_zip = TRUE
/datum/armor/hooded_wintercoat
bio = 10
@@ -43,11 +45,13 @@
/obj/item/clothing/suit/hooded/wintercoat/examine(mob/user)
. = ..()
. += span_notice("<b>Alt-click</b> to [zipped ? "un" : ""]zip.")
if(can_altclick_zip)
. += span_notice("<b>Alt-click</b> to [zipped ? "un" : ""]zip.")
/obj/item/clothing/suit/hooded/wintercoat/click_alt(mob/user)
if(!can_altclick_zip)
return CLICK_ACTION_BLOCKING
zipped = !zipped
playsound(src, 'sound/items/zip/zip_up.ogg', 30, TRUE, -3)
worn_icon_state = "[initial(post_init_icon_state) || initial(icon_state)][zipped ? "_t" : ""]"
@@ -694,3 +698,96 @@
desc = "A heavy jacket hood made from 'synthetic' animal furs, with custom colors."
greyscale_config = /datum/greyscale_config/winter_hoods
greyscale_config_worn = /datum/greyscale_config/winter_hoods/worn
flags_1 = NO_NEW_GAGS_PREVIEW_1
/obj/item/clothing/suit/hooded/wintercoat/pullover
name = "pullover"
desc = "A colorable pullover hoodie."
icon = 'icons/map_icons/clothing/suit/_suit.dmi'
icon_state = "/obj/item/clothing/suit/hooded/wintercoat/pullover"
post_init_icon_state = "pullover"
greyscale_config = /datum/greyscale_config/hoodie_pullover
greyscale_config_worn = /datum/greyscale_config/hoodie_pullover/worn
greyscale_colors = "#5f5f5f"
hoodtype = /obj/item/clothing/head/hooded/winterhood/pullover
flags_1 = IS_PLAYER_COLORABLE_1
hood_down_overlay_suffix = ""
hood_up_affix = "_t"
can_altclick_zip = FALSE
/obj/item/clothing/suit/hooded/wintercoat/pullover/on_hood_up(obj/item/clothing/head/hooded/hood)
return
/obj/item/clothing/suit/hooded/wintercoat/pullover/on_hood_down(obj/item/clothing/head/hooded/hood)
return
/obj/item/clothing/head/hooded/winterhood/pullover
name = "pullover hood"
desc = "A colorable pullover hoodie."
icon_state = "hood_pullover"
worn_icon_state = "hood_pullover"
hair_mask = /datum/hair_mask/hoodie
greyscale_config = /datum/greyscale_config/hoodie_pullover_hood
greyscale_config_worn = /datum/greyscale_config/hoodie_pullover_hood/worn
greyscale_colors = "#5f5f5f"
flags_1 = NO_NEW_GAGS_PREVIEW_1
/obj/item/clothing/suit/hooded/wintercoat/pullover/set_greyscale(list/colors, new_config, new_worn_config, new_inhand_left, new_inhand_right)
. = ..()
if(!hood)
return
var/list/coat_colors = SSgreyscale.ParseColorString(greyscale_colors)
hood.set_greyscale(coat_colors)
hood.update_slot_icon()
/obj/item/clothing/suit/hooded/wintercoat/pullover/on_hood_created(obj/item/clothing/head/hooded/hood)
. = ..()
var/list/coat_colors = SSgreyscale.ParseColorString(greyscale_colors)
hood.set_greyscale(coat_colors)
/obj/item/clothing/suit/hooded/wintercoat/zipup
name = "zipup"
desc = "A colorable zipup hoodie."
icon = 'icons/map_icons/clothing/suit/_suit.dmi'
icon_state = "/obj/item/clothing/suit/hooded/wintercoat/zipup"
post_init_icon_state = "zipup"
greyscale_config = /datum/greyscale_config/hoodie_zipup
greyscale_config_worn = /datum/greyscale_config/hoodie_zipup/worn
greyscale_colors = "#5f5f5f"
hoodtype = /obj/item/clothing/head/hooded/winterhood/zipup
flags_1 = IS_PLAYER_COLORABLE_1
hood_down_overlay_suffix = ""
hood_up_affix = "_t"
/obj/item/clothing/suit/hooded/wintercoat/zipup/worn_overlays(mutable_appearance/standing, isinhands, icon_file)
. = ..()
if(isinhands || (hood && hood.loc != src))
return
var/suffix = (zipped ? "hood_t" : "hood")
var/state = "[initial(post_init_icon_state) || initial(icon_state)]_[suffix]"
. += mutable_appearance(icon_file, state, -SUIT_LAYER)
/obj/item/clothing/head/hooded/winterhood/zipup
name = "zipup hood"
desc = "A colorable zipup hoodie."
icon_state = "hood_zipup"
worn_icon_state = "hood_zipup"
hair_mask = /datum/hair_mask/hoodie
greyscale_config = /datum/greyscale_config/hoodie_zipup_hood
greyscale_config_worn = /datum/greyscale_config/hoodie_zipup_hood/worn
greyscale_colors = "#5f5f5f"
flags_1 = NO_NEW_GAGS_PREVIEW_1
/obj/item/clothing/suit/hooded/wintercoat/zipup/set_greyscale(list/colors, new_config, new_worn_config, new_inhand_left, new_inhand_right)
. = ..()
if(!hood)
return
var/list/coat_colors = SSgreyscale.ParseColorString(greyscale_colors)
hood.set_greyscale(coat_colors)
hood.update_slot_icon()
/obj/item/clothing/suit/hooded/wintercoat/zipup/on_hood_created(obj/item/clothing/head/hooded/hood)
. = ..()
var/list/coat_colors = SSgreyscale.ParseColorString(greyscale_colors)
hood.set_greyscale(coat_colors)
+8
View File
@@ -40,3 +40,11 @@
/datum/job/paramedic = "#28324b",
/datum/job/prisoner = "#ff8b00",
)
/datum/loadout_item/suit/hoodie_pullover
name = "pullover"
item_path = /obj/item/clothing/suit/hooded/wintercoat/pullover
/datum/loadout_item/suit/hoodie_zipup
name = "zipup"
item_path = /obj/item/clothing/suit/hooded/wintercoat/zipup
+2
View File
@@ -102,6 +102,8 @@
/obj/item/clothing/suit/jacket/oversized = 4,
/obj/item/clothing/suit/jacket/fancy = 4,
/obj/item/clothing/suit/toggle/lawyer/greyscale = 4,
/obj/item/clothing/suit/hooded/wintercoat/pullover = 3,
/obj/item/clothing/suit/hooded/wintercoat/zipup = 3,
/obj/item/clothing/suit/hooded/wintercoat/custom = 3,
/obj/item/clothing/suit/hooded/wintercoat = 3,
/obj/item/clothing/under/suit/navy = 3,
Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 449 B

After

Width:  |  Height:  |  Size: 500 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB