From e2abc6219369702dbe43930991ab48049851657d Mon Sep 17 00:00:00 2001 From: "Wowzewow (Wezzy)" <42310821+alsoandanswer@users.noreply.github.com> Date: Sat, 25 Dec 2021 23:05:53 +0800 Subject: [PATCH] If it rains, you put on a coat. Rack. (Coatrack buffs.) (#12829) --- aurorastation.dme | 2 +- code/game/objects/structures/coathanger.dm | 74 ----------- code/game/objects/structures/coatrack.dm | 138 +++++++++++++++++++++ html/changelogs/wezzy_coatrack.yml | 42 +++++++ icons/obj/coatrack.dmi | Bin 5014 -> 1161 bytes 5 files changed, 181 insertions(+), 75 deletions(-) delete mode 100644 code/game/objects/structures/coathanger.dm create mode 100644 code/game/objects/structures/coatrack.dm create mode 100644 html/changelogs/wezzy_coatrack.yml diff --git a/aurorastation.dme b/aurorastation.dme index ac5acf5e220..236f006c716 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -1107,7 +1107,7 @@ #include "code\game\objects\structures\banner.dm" #include "code\game\objects\structures\barsign.dm" #include "code\game\objects\structures\bedsheet_bin.dm" -#include "code\game\objects\structures\coathanger.dm" +#include "code\game\objects\structures\coatrack.dm" #include "code\game\objects\structures\crystals.dm" #include "code\game\objects\structures\curtains.dm" #include "code\game\objects\structures\displaycase.dm" diff --git a/code/game/objects/structures/coathanger.dm b/code/game/objects/structures/coathanger.dm deleted file mode 100644 index 0978deb50c9..00000000000 --- a/code/game/objects/structures/coathanger.dm +++ /dev/null @@ -1,74 +0,0 @@ -/obj/structure/coatrack - name = "coat rack" - desc = "Rack that holds coats." - icon = 'icons/obj/coatrack.dmi' - icon_state = "coatrack0" - var/obj/item/clothing/suit/coat - var/obj/item/clothing/head/hat - var/list/allowed_coats = list(/obj/item/clothing/suit/storage/toggle/labcoat, /obj/item/clothing/suit/storage/toggle/det_trench, - /obj/item/clothing/suit/storage/toggle/forensics, /obj/item/clothing/suit/storage/toggle/trench, - /obj/item/clothing/suit/storage/det_jacket, /obj/item/clothing/accessory/poncho/tajarancloak) - var/list/allowed_hats = list(/obj/item/clothing/head/det, /obj/item/clothing/head/beret/security, /obj/item/clothing/head/softcap/security) - -/obj/structure/coatrack/attack_hand(mob/user as mob) - if (!ishuman(user)) - return - if(user.incapacitated()) - return - if (!user.can_use_hand()) - return - if(coat) - user.visible_message("[user] takes [coat] off \the [src].", SPAN_NOTICE("You take [coat] off the \the [src].")) - user.put_in_hands(coat) - coat = null - update_icon() - else if(hat) - user.visible_message("[user] takes [hat] off \the [src].", SPAN_NOTICE("You take [hat] off the \the [src].")) - user.put_in_hands(hat) - hat = null - update_icon() - -/obj/structure/coatrack/attackby(obj/item/W as obj, mob/user as mob) - if (is_type_in_list(W, allowed_coats) && !coat) - user.visible_message("[user] hangs [W] on \the [src].", SPAN_NOTICE("You hang [W] on the \the [src].")) - coat = W - user.drop_from_inventory(coat, src) - update_icon() - else if (is_type_in_list(W, allowed_hats) && !hat) - user.visible_message("[user] hangs [W] on \the [src].", SPAN_NOTICE("You hang [W] on the \the [src].")) - hat = W - user.drop_from_inventory(hat, src) - update_icon() - else - to_chat(user, SPAN_NOTICE("You cannot hang [W] on [src].")) - return ..() - -/obj/structure/coatrack/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if (is_type_in_list(mover, allowed_coats) && !coat) - src.visible_message("[mover] lands on \the [src].") - coat = mover - coat.forceMove(src) - update_icon() - return 0 - if (is_type_in_list(mover, allowed_hats) && !hat) - src.visible_message("[mover] lands on \the [src].") - hat = mover - hat.forceMove(src) - update_icon() - return 0 - else - return 1 - -/obj/structure/coatrack/update_icon() - cut_overlays() - if (coat) - if(istype(coat, /obj/item/clothing/suit/storage/toggle)) - var/obj/item/clothing/suit/storage/toggle/T = coat - T.icon_state = initial(T.icon_state) - T.opened = FALSE - add_overlay("coat_[coat.icon_state]") - if (hat) - if(istype(hat, /obj/item/clothing/head/softcap/security/idris) || istype(hat, /obj/item/clothing/head/softcap/security/corp)) - add_overlay("hat_softcap_[hat.icon_state]") - else - add_overlay("hat_[hat.icon_state]") diff --git a/code/game/objects/structures/coatrack.dm b/code/game/objects/structures/coatrack.dm new file mode 100644 index 00000000000..23eaa028bd7 --- /dev/null +++ b/code/game/objects/structures/coatrack.dm @@ -0,0 +1,138 @@ +/obj/structure/coatrack + name = "coat rack" + desc = "Rack that holds coats, or hats, if you're so inclined." + icon = 'icons/obj/coatrack.dmi' + icon_state = "coatrack" + layer = ABOVE_MOB_LAYER //Hide behind coat racks. Because funny. + var/obj/item/clothing/coat + var/obj/item/clothing/head/hat + var/list/custom_sprites = list(/obj/item/clothing/head/beret/security, /obj/item/clothing/accessory/poncho/tajarancloak) // Custom manual sprite override. + +/obj/structure/coatrack/attack_hand(mob/user as mob) + if(use_check_and_message(user)) + return + if(coat && hat) + var/response = "" + response = alert(user, "Do you remove the coat, or the hat?", "Coat Rack Selection", "Coat", "Hat", "Cancel") + if(response == "Coat") + remove_coat(user) + if(response == "Hat") + remove_hat(user) + if(coat) + remove_coat(user) + if(hat) + remove_hat(user) + add_fingerprint(user) + return + +/obj/structure/coatrack/proc/remove_coat(mob/user as mob) + user.visible_message("[user] takes [coat] off \the [src].", SPAN_NOTICE("You take [coat] off the \the [src].")) + user.put_in_hands(coat) + coat = null + update_icon() + +/obj/structure/coatrack/proc/remove_hat(mob/user as mob) + user.visible_message("[user] takes [hat] off \the [src].", SPAN_NOTICE("You take [hat] off the \the [src].")) + user.put_in_hands(hat) + hat = null + update_icon() + +/obj/structure/coatrack/attackby(obj/item/W as obj, mob/user as mob) + if(use_check_and_message(user)) + return + if(!coat && (istype(W, /obj/item/clothing/suit/storage/toggle) || istype(W, /obj/item/clothing/accessory/poncho))) + user.visible_message("[user] hangs [W] on \the [src].", SPAN_NOTICE("You hang [W] on the \the [src].")) + coat = W + user.drop_from_inventory(coat, src) + playsound(src, W.drop_sound, DROP_SOUND_VOLUME) + update_icon() + else if(!hat && istype(W, /obj/item/clothing/head) && !istype(W, /obj/item/clothing/head/helmet)) + user.visible_message("[user] hangs [W] on \the [src].", SPAN_NOTICE("You hang [W] on the \the [src].")) + hat = W + user.drop_from_inventory(hat, src) + playsound(src, W.drop_sound, DROP_SOUND_VOLUME) + update_icon() + else if(istype(W, /obj/item/clothing)) + to_chat(user, SPAN_WARNING("You can't hang that up.")) + else + return ..() + +/obj/structure/coatrack/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) + if(!coat && (istype(mover, /obj/item/clothing/suit/storage/toggle) || istype(mover, /obj/item/clothing/accessory/poncho))) + src.visible_message("[mover] lands on \the [src].") + coat = mover + coat.forceMove(src) + update_icon() + return 0 + else if(!hat && istype(mover, /obj/item/clothing/head)) + src.visible_message("[mover] lands on \the [src].") + hat = mover + hat.forceMove(src) + update_icon() + return 0 + else + return 1 + +/obj/structure/coatrack/update_icon() + cut_overlays() + if(coat) + if(is_type_in_list(coat, custom_sprites)) + add_overlay(coat.icon_state) + else if(istype(coat, /obj/item/clothing/suit/storage/toggle)) // Using onmob sprites, because they're more consistent than object sprites. + var/obj/item/clothing/suit/storage/toggle/T = coat + if(!T.opened) + T.opened = TRUE // Makes coats open when hung up. Cause you know, you can't really hang up a closed coat. Well you can, but...code reasons. + T.icon_state = "[T.icon_state]_open" + handle_coat_image(T) + else if(istype(coat, /obj/item/clothing/accessory/poncho)) // Pain. + var/obj/item/clothing/accessory/poncho/T = coat + handle_coat_image(T) + if(hat) + if(is_type_in_list(hat, custom_sprites)) + add_overlay(hat.icon_state) + else if(istype(hat, /obj/item/clothing/head)) + var/obj/item/clothing/head/H = hat + var/matrix/M = matrix() + var/image/hat_image + if(H.contained_sprite) + var/hat_icon_state = "[H.icon_state][WORN_HEAD]" // Needed to bypass contained sprite phoney baloney. + hat_image = image(H.icon, hat_icon_state, src.layer, EAST) + if(H.build_from_parts) + hat_image.add_overlay(overlay_image(H.icon, "[H.icon_state]_[H.worn_overlay]", flags=RESET_COLOR)) + else + hat_image = image(INV_HEAD_DEF_ICON, H.icon_state, src.layer, EAST) + if(H.build_from_parts) + hat_image.add_overlay(overlay_image(icon, "[INV_HEAD_DEF_ICON]_[H.worn_overlay]", flags=RESET_COLOR)) + M.Turn(90) // Flip the hat over and stick it on the coatrack. + M.Translate(-6, 6) + hat_image.transform = M + add_overlay(hat_image) + +/obj/structure/coatrack/proc/handle_coat_image(var/obj/item/clothing/T) + var/icon/coat_outline = icon('icons/obj/coatrack.dmi', "outline") + var/matrix/M = matrix() + var/coat_icon_state = T.icon_state + var/coat_icon_file = INV_SUIT_DEF_ICON + if(T.contained_sprite) + coat_icon_state = "[T.icon_state][WORN_SUIT]" // Needed to bypass contained sprite phoney baloney. + coat_icon_file = T.icon + + var/icon/coat_icon = new(coat_icon_file, coat_icon_state) + + coat_icon.Blend(coat_outline, ICON_OVERLAY) + coat_icon.SwapColor(rgb(255, 0, 220, 255), rgb(0, 0, 0, 0)) //Slice the coat in half. + var/image/coat_image = image(coat_icon) + if(T.color) + coat_image.color = T.color + + if(T.build_from_parts) + var/icon/overlay_icon = new(coat_icon_file, "[coat_icon_state]_[T.worn_overlay]") + overlay_icon.Blend(coat_outline, ICON_OVERLAY) + overlay_icon.SwapColor(rgb(255, 0, 220, 255), rgb(0, 0, 0, 0)) // Slice the overlay in half and slap it on the coat. + var/image/overlay_image = image(overlay_icon) + overlay_image.appearance_flags = RESET_COLOR + coat_image.add_overlay(overlay_image) + + M.Translate(-1, 5) // Stick it on the coat rack. + coat_image.transform = M + add_overlay(coat_image) diff --git a/html/changelogs/wezzy_coatrack.yml b/html/changelogs/wezzy_coatrack.yml new file mode 100644 index 00000000000..b45d9d73f64 --- /dev/null +++ b/html/changelogs/wezzy_coatrack.yml @@ -0,0 +1,42 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +# balance +# admin +# backend +# security +# refactor +################################# + +# Your name. +author: Wowzewow (Wezzy) + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Coatracks are now able to support every concievable toggleable coat, poncho and hat. Except helmets, armor and rigsuits, obviously." + - imageadd: "Coatracks have a shiny new sprite." diff --git a/icons/obj/coatrack.dmi b/icons/obj/coatrack.dmi index 28dab25666c712fefaa49cde35efb419d3de2d93..b007a2f4bc6b37fd52898a103352b5954d7b71c5 100644 GIT binary patch literal 1161 zcmV;41a|w0P)C0002YP)t-sz`(%& z0NhqH7LR2Jb5aRCCJrSfB_}aH4Gj%UOiWj5ghEtpCnqNy92__}I4D7AHbhq*FijK` z6eLAOI&W_{S zIKRJ=3JRIb|2wgw!d6~igPCbPGT+rw_b;pT+ci9xMr#!1X7dS2FKp<8%=27x7wKoMgX@V zkANlu`r&Z_WAJkmYy}z}DDbG&J)Yd{0s1)C8E9ewx1A-B9zt9{mq5LVTi~@bTEKsX zIRzRWEYRwnSD@2@9Z=nFRtE|aP`JJ^$V>_nxIZEw0wN#+RN(je|CoT2-pZZYDff{= z1x$G(P(A5JR;)m!`h(I0oJvZ00;*m;{tlb(ZF0Xqpayil zx5@QmE})-~`Myr_r%2#ge@F$MlllGy$zOup9dH3U-`nK90dE1D@2&D)f5-*Md~cNx zhqME9zPHPHeLmmY=7Jyyf*=TjAVApsp7G!NuY5GZxz<>K&F{V&Km&g~fd>9`h7I&9 zETAv2fWE*2`ZW`HgU4t6)(vnzp2PgzbO8m}{O$%=z@1yLgro5s3rrVSfX(kg06U=ObJzj3Sl|xu`5o6c1|(SK;zq-Qplf+_umFAz2fT@r2v_8t&`iB=j6M-*C zAW0H*2EsUw;Tb4m2do9GcHlCJuJQWeiV1ur0w^y;;BVi7kO)NQ-T`|7yB&y#Ku84E z>-7y1*ladiD6qOF0xK+VV?YAC-3|%de%tT&7P(TmzEayQs;_SMM1bV>u=USfUl0UA bxHsPcE+JGn^Zs5+00000NkvXXu0mjfNAvzr literal 5014 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