diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 9733856a3c3..b6e91f96dd9 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -398,11 +398,153 @@ var/vision_flags = 0 var/see_in_dark = 0 var/lighting_alpha + /// the head clothing that this item may be attached to. + var/obj/item/clothing/under/has_under = null + /// the attached hats to this hat. + var/list/attached_hats = list() + /// if this hat can have hats placed on top of it. + var/can_have_hats = FALSE + /// if this hat can be a hat of a hat. Hat^2 + var/can_be_hat = TRUE /obj/item/clothing/head/update_icon_state() if(..()) item_state = "[replacetext("[item_state]", "_up", "")][up ? "_up" : ""]" +/obj/item/clothing/head/AltShiftClick(mob/user) + if(user.stat || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user)) + return + if(!length(attached_hats)) + return + var/obj/item/clothing/head/hat + if(length(attached_hats) > 1) + var/pick = radial_menu_helper(usr, src, attached_hats, custom_check = FALSE, require_near = TRUE) + if(!pick || !istype(pick, /obj/item/clothing/head) || !Adjacent(usr)) + return + hat = pick + else + hat = attached_hats[1] + remove_hat(user, hat) + +/obj/item/clothing/head/Destroy() + if(is_equipped()) + var/mob/M = loc + for(var/obj/item/clothing/head/H as anything in attached_hats) + H.on_removed(M) + else + for(var/obj/item/clothing/head/H as anything in attached_hats) + H.forceMove(get_turf(src)) + attached_hats = null + return ..() + +/obj/item/clothing/head/dropped(mob/user, silent) + ..() + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + if(H.get_item_by_slot(SLOT_HUD_HEAD) == src) + for(var/obj/item/clothing/head/hat as anything in attached_hats) + hat.attached_unequip() + +/obj/item/clothing/head/examine(mob/user) + . = ..() + for(var/obj/item/clothing/head/hat as anything in attached_hats) + . += "\A [hat] is placed neatly on top." + +//when user attached a hat to H (another hat) +/obj/item/clothing/head/proc/on_attached(obj/item/clothing/head/H, mob/user as mob) + if(!istype(H)) + return + has_under = H + forceMove(has_under) + has_under.overlays += item_state + has_under.actions += actions + + for(var/datum/action/A in actions) + if(has_under.is_equipped()) + var/mob/M = has_under.loc + A.Grant(M) + + if(user) + to_chat(user, "You attach [src] to [has_under].") + add_fingerprint(user) + +/obj/item/clothing/head/proc/on_removed(mob/user) + if(!has_under) + return + has_under.overlays -= icon_state + has_under.actions -= actions + + for(var/datum/action/A in actions) + if(ismob(has_under.loc)) + var/mob/M = has_under.loc + A.Remove(M) + + has_under = null + if(user) + user.put_in_hands(src) + add_fingerprint(user) + +/obj/item/clothing/head/proc/detach_hat(obj/item/clothing/head/hat, mob/user) + attached_hats -= hat + hat.on_removed(user) + if(ishuman(loc)) + var/mob/living/carbon/human/H = loc + H.update_inv_head() + +/obj/item/clothing/head/proc/remove_hat(mob/user, obj/item/clothing/head/hat) + if(!(hat in attached_hats)) + return + if(!isliving(user)) + return + if(user.incapacitated()) + return + if(!Adjacent(user)) + return + detach_hat(hat, user) + to_chat(user, "You remove [hat] from [src].") + +/obj/item/clothing/head/proc/attached_unequip(mob/user) // If we need to do something special when clothing is removed from the user + return + +/obj/item/clothing/head/proc/attached_equip(mob/user) // If we need to do something special when clothing is removed from the user + return + +/* + * # can_attach_hat + * + * Arguments: + * * Hat - The clothing/head object being checked. MUST BE TYPE /obj/item/clothing/head +*/ +/obj/item/clothing/head/proc/can_attach_hat(obj/item/clothing/head/hat) + return length(attached_hats) < 1 && can_have_hats && hat.can_be_hat // this hat already has a hat or cannot be a hat of a hat! + +/obj/item/clothing/head/proc/attach_hat(obj/item/clothing/head/hat, mob/user, unequip = FALSE) + if(can_attach_hat(hat)) + if(unequip && !user.unEquip(hat)) // Make absolutely sure this hat is removed from hands + return FALSE + + attached_hats += hat + hat.on_attached(src, user) + + if(ishuman(loc)) + var/mob/living/carbon/human/H = loc + H.update_inv_head() + + return TRUE + else if(hat.has_under) + return FALSE + else + to_chat(user, "You cannot place [hat] ontop of [src].") + + return FALSE + +/obj/item/clothing/head/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/clothing/head) && can_have_hats) + attach_hat(I, user, TRUE) + + return ..() + ////////////////////////////// // MARK: MASK ////////////////////////////// diff --git a/code/modules/clothing/head/misc_hats.dm b/code/modules/clothing/head/misc_hats.dm index 304a6c092f0..bc9ea7066ee 100644 --- a/code/modules/clothing/head/misc_hats.dm +++ b/code/modules/clothing/head/misc_hats.dm @@ -536,6 +536,7 @@ icon_state = "crown" armor = list(MELEE = 10, BULLET = 0, LASER = 0, ENERGY = 10, BOMB = 0, RAD = 0, FIRE = INFINITY, ACID = 50) resistance_flags = FIRE_PROOF + can_be_hat = FALSE /obj/item/clothing/head/crown/fancy name = "magnificent crown" diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index 461f780e99d..500a1f000a8 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -23,6 +23,8 @@ icon = 'icons/obj/clothing/species/plasmaman/hats.dmi' species_restricted = list("Plasmaman") sprite_sheets = list("Plasmaman" = 'icons/mob/clothing/species/plasmaman/helmet.dmi') + can_have_hats = TRUE + can_be_hat = FALSE /obj/item/clothing/head/helmet/space/plasmaman/Initialize(mapload) . = ..() diff --git a/code/modules/mob/living/carbon/human/human_update_icons.dm b/code/modules/mob/living/carbon/human/human_update_icons.dm index 47f744999fe..52db0245ce1 100644 --- a/code/modules/mob/living/carbon/human/human_update_icons.dm +++ b/code/modules/mob/living/carbon/human/human_update_icons.dm @@ -855,15 +855,24 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) var/mutable_appearance/standing if(head.sprite_sheets && head.sprite_sheets[dna.species.sprite_sheet_name]) standing = mutable_appearance(head.sprite_sheets[dna.species.sprite_sheet_name], "[head.icon_state]", layer = -HEAD_LAYER) - if(istype(head, /obj/item/clothing/head/helmet/space/plasmaman)) - var/obj/item/clothing/head/helmet/space/plasmaman/P = head - if(!P.up) - standing.overlays += P.visor_icon else if(head.icon_override) standing = mutable_appearance(head.icon_override, "[head.icon_state]", layer = -HEAD_LAYER) else standing = mutable_appearance('icons/mob/clothing/head.dmi', "[head.icon_state]", layer = -HEAD_LAYER) + if(istype(head, /obj/item/clothing/head/helmet/space/plasmaman)) + var/obj/item/clothing/head/helmet/space/plasmaman/P = head + if(!P.up) + standing.overlays += P.visor_icon + + if(istype(head, /obj/item/clothing/head)) + var/obj/item/clothing/head/w_hat = head + for(var/obj/item/clothing/head/hat in w_hat.attached_hats) + if(hat.sprite_sheets && hat.sprite_sheets[dna.species.sprite_sheet_name]) + standing.overlays += image("icon" = hat.sprite_sheets[dna.species.sprite_sheet_name], "icon_state" = "[hat.icon_state]") + else + standing.overlays += image("icon" = hat.icon_override, "icon_state" = "[hat.icon_state]") + if(head.blood_DNA) var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "helmetblood") bloodsies.color = head.blood_color