diff --git a/code/datums/action.dm b/code/datums/action.dm index c1267bf2255..db3974dcf22 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -416,9 +416,6 @@ /datum/action/item_action/switch_hud name = "Switch HUD" -/datum/action/item_action/toggle_wings - name = "Toggle Wings" - /datum/action/item_action/toggle_human_head name = "Toggle Human Head" diff --git a/code/datums/components/toggle_suit.dm b/code/datums/components/toggle_suit.dm new file mode 100644 index 00000000000..903bfbf4009 --- /dev/null +++ b/code/datums/components/toggle_suit.dm @@ -0,0 +1,89 @@ +/* + * Simple component for allowing a user to change an atom's appearance on alt-click. + * When toggled, changes the atom's icon_state between [base_icon_state] and [base_icon_state]_t. + */ +/datum/component/toggle_icon + /// Whether the icon is toggled + var/toggled = FALSE + /// The base icon state we do operations on. + var/base_icon_state + /// The noun of what was "toggled" displayed to the user. EX: "Toggled the item's [buttons]" + var/toggle_noun + +/datum/component/toggle_icon/Initialize(toggle_noun = "buttons") + if(!isatom(parent)) + return COMPONENT_INCOMPATIBLE + + var/atom/atom_parent = parent + + src.toggle_noun = toggle_noun + src.base_icon_state = atom_parent.base_icon_state || atom_parent.icon_state + +/datum/component/toggle_icon/RegisterWithParent() + RegisterSignal(parent, COMSIG_CLICK_ALT, .proc/on_alt_click) + RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_examine) + +/datum/component/toggle_icon/UnregisterFromParent() + UnregisterSignal(parent, list(COMSIG_CLICK_ALT, COMSIG_PARENT_EXAMINE)) + +/* + * Signal proc for COMSIG_CLICK_ALT. + * If the user is living, adjacent to the source, + * and has arms / is not incapacitated, call do_icon_toggle. + * + * source - the atom being clicked on + * user - the mob doing the click + */ +/datum/component/toggle_icon/proc/on_alt_click(atom/source, mob/user) + SIGNAL_HANDLER + + if(!isliving(user)) + return + + var/mob/living/living_user = user + + if(!living_user.Adjacent(source)) + return + + if(living_user.incapacitated()) + source.balloon_alert(user, "you're incapacitated!") + return + + if(living_user.usable_hands <= 0) + source.balloon_alert(user, "you don't have hands!") + return + + do_icon_toggle(source, living_user) + +/* + * Signal proc for COMSIG_PARENT_EXAMINE. + * Lets the user know they can toggle the parent open or closed. + * + * source - the atom being examined (parent) + * user - the mob examining it + * examine_list - the list of things within the examine output + */ +/datum/component/toggle_icon/proc/on_examine(atom/source, mob/user, list/examine_list) + SIGNAL_HANDLER + + examine_list += span_notice("Alt-click on [source] to toggle the [toggle_noun].") + +/* + * Actually do the toggle of the icon. + * Swaps the icon from [base_icon_state] to [base_icon_state]_t. + * + * source - the atom being toggled + * user - the mob doing the toggling + */ +/datum/component/toggle_icon/proc/do_icon_toggle(atom/source, mob/living/user) + source.balloon_alert(user, "toggled [toggle_noun]") + + toggled = !toggled + if(toggled) + source.icon_state = "[base_icon_state]_t" + else + source.icon_state = base_icon_state + + if(isitem(source)) + var/obj/item/item_source = source + item_source.update_slot_icon() diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 203b35ceb59..3f110dee8b3 100755 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -18,7 +18,7 @@ new /obj/item/clothing/suit/armor/vest/capcarapace(src) new /obj/item/clothing/head/caphat(src) new /obj/item/clothing/under/rank/captain/parade(src) - new /obj/item/clothing/suit/toggle/captains_parade(src) + new /obj/item/clothing/suit/armor/vest/capcarapace/captains_formal(src) new /obj/item/clothing/head/caphat/parade(src) new /obj/item/clothing/suit/captunic(src) new /obj/item/clothing/head/crown/fancy(src) @@ -72,7 +72,7 @@ /obj/structure/closet/secure_closet/hos/PopulateContents() ..() new /obj/item/clothing/neck/cloak/hos(src) - new /obj/item/clothing/suit/toggle/armor/hos/hos_formal(src) + new /obj/item/clothing/suit/armor/hos/hos_formal(src) new /obj/item/cartridge/hos(src) new /obj/item/radio/headset/heads/hos(src) new /obj/item/clothing/under/rank/security/head_of_security/parade/female(src) diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index 3c43cd097f2..afb2f6486ef 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -113,6 +113,8 @@ var/helmettype = /obj/item/clothing/head/helmet/space/hardsuit var/obj/item/tank/jetpack/suit/jetpack = null var/hardsuit_type + /// Whether the helmet is on. + var/helmet_on = FALSE /obj/item/clothing/suit/space/hardsuit/Initialize(mapload) if(jetpack && ispath(jetpack)) diff --git a/code/modules/clothing/suits/_suits.dm b/code/modules/clothing/suits/_suits.dm index 4c704b8b5b1..88556794ce8 100644 --- a/code/modules/clothing/suits/_suits.dm +++ b/code/modules/clothing/suits/_suits.dm @@ -8,8 +8,6 @@ pickup_sound = 'sound/items/handling/cloth_pickup.ogg' slot_flags = ITEM_SLOT_OCLOTHING var/blood_overlay_type = "suit" - var/togglename = null - var/suittoggled = FALSE limb_integrity = 0 // disabled for most exo-suits /obj/item/clothing/suit/Initialize(mapload) diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 9f38e5b1588..dda670c866a 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -96,6 +96,17 @@ flags_inv = 0 strip_delay = 80 +/obj/item/clothing/suit/armor/hos/hos_formal + name = "\improper Head of Security's parade jacket" + desc = "For when an armoured vest isn't fashionable enough." + icon_state = "hosformal" + inhand_icon_state = "hostrench" + body_parts_covered = CHEST|GROIN|ARMS + +/obj/item/clothing/suit/armor/hos/hos_formal/Initialize(mapload) + . = ..() + AddComponent(/datum/component/toggle_icon) + /obj/item/clothing/suit/armor/vest/warden name = "warden's jacket" desc = "A navy-blue armored jacket with blue shoulder designations and '/Warden/' stitched into one of the chest pockets." @@ -138,18 +149,16 @@ desc = "A sinister looking vest of advanced armor worn over a black and red fireproof jacket. The gold collar and shoulders denote that this belongs to a high ranking syndicate officer." icon_state = "syndievest" -/obj/item/clothing/suit/toggle/captains_parade +/obj/item/clothing/suit/armor/vest/capcarapace/captains_formal name = "captain's parade jacket" desc = "For when an armoured vest isn't fashionable enough." icon_state = "capformal" inhand_icon_state = "capspacesuit" body_parts_covered = CHEST|GROIN|ARMS - armor = list(MELEE = 50, BULLET = 40, LASER = 50, ENERGY = 50, BOMB = 25, BIO = 0, RAD = 0, FIRE = 100, ACID = 90, WOUND = 10) - togglename = "buttons" -/obj/item/clothing/suit/toggle/captains_parade/Initialize(mapload) +/obj/item/clothing/suit/armor/vest/capcarapace/captains_formal/Initialize(mapload) . = ..() - allowed = GLOB.security_wintercoat_allowed + AddComponent(/datum/component/toggle_icon) /obj/item/clothing/suit/armor/riot name = "riot suit" @@ -352,28 +361,14 @@ cold_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS -/obj/item/clothing/suit/toggle/armor/vest/centcom_formal +/obj/item/clothing/suit/armor/centcom_formal name = "\improper CentCom formal coat" desc = "A stylish coat given to CentCom Commanders. Perfect for sending ERTs to suicide missions with style!" icon_state = "centcom_formal" inhand_icon_state = "centcom" body_parts_covered = CHEST|GROIN|ARMS armor = list(MELEE = 35, BULLET = 40, LASER = 40, ENERGY = 50, BOMB = 35, BIO = 10, RAD = 10, FIRE = 10, ACID = 60) - togglename = "buttons" -/obj/item/clothing/suit/toggle/armor/vest/centcom_formal/Initialize(mapload) +/obj/item/clothing/suit/armor/centcom_formal/Initialize(mapload) . = ..() - allowed = GLOB.security_wintercoat_allowed - -/obj/item/clothing/suit/toggle/armor/hos/hos_formal - name = "\improper Head of Security's parade jacket" - desc = "For when an armoured vest isn't fashionable enough." - icon_state = "hosformal" - inhand_icon_state = "hostrench" - body_parts_covered = CHEST|GROIN|ARMS - armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 40, BOMB = 25, BIO = 0, RAD = 0, FIRE = 70, ACID = 90, WOUND = 10) - togglename = "buttons" - -/obj/item/clothing/suit/toggle/armor/hos/hos_formal/Initialize(mapload) - . = ..() - allowed = GLOB.security_wintercoat_allowed + AddComponent(/datum/component/toggle_icon) diff --git a/code/modules/clothing/suits/costume.dm b/code/modules/clothing/suits/costume.dm index 044df709342..771be191a8e 100644 --- a/code/modules/clothing/suits/costume.dm +++ b/code/modules/clothing/suits/costume.dm @@ -126,9 +126,8 @@ desc = "A soft brown cloak made of synthetic feathers. Soft to the touch, stylish, and a 2 meter wing span that will drive the ladies mad." icon_state = "owl_wings" inhand_icon_state = "owl_wings" - togglename = "wings" + toggle_noun = "wings" body_parts_covered = ARMS|CHEST - actions_types = list(/datum/action/item_action/toggle_wings) /obj/item/clothing/suit/toggle/owlwings/Initialize(mapload) . = ..() diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index 5361204b67f..595dff3b434 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -40,7 +40,7 @@ permeability_coefficient = 0.5 body_parts_covered = CHEST|GROIN|ARMS allowed = list(/obj/item/kitchen) - togglename = "sleeves" + toggle_noun = "sleeves" species_exception = list(/datum/species/golem) //Cook @@ -100,7 +100,6 @@ inhand_icon_state = "suitjacket_blue" blood_overlay_type = "coat" body_parts_covered = CHEST|ARMS - togglename = "buttons" species_exception = list(/datum/species/golem) /obj/item/clothing/suit/toggle/lawyer/purple @@ -124,7 +123,7 @@ icon_state = "suspenders" worn_icon_state = "suspenders" blood_overlay_type = "armor" //it's the less thing that I can put here - togglename = "straps" + toggle_noun = "straps" species_exception = list(/datum/species/golem) greyscale_config = /datum/greyscale_config/suspenders greyscale_config_worn = /datum/greyscale_config/suspenders/worn diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm index 0f8f4bef1d6..9f998478460 100644 --- a/code/modules/clothing/suits/labcoat.dm +++ b/code/modules/clothing/suits/labcoat.dm @@ -26,7 +26,6 @@ /obj/item/tank/internals/plasmaman, ) armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 50, RAD = 0, FIRE = 50, ACID = 50) - togglename = "buttons" species_exception = list(/datum/species/golem) /obj/item/clothing/suit/toggle/labcoat/cmo diff --git a/code/modules/clothing/suits/toggles.dm b/code/modules/clothing/suits/toggles.dm index a97d23a1cfa..cd318eaa238 100644 --- a/code/modules/clothing/suits/toggles.dm +++ b/code/modules/clothing/suits/toggles.dm @@ -6,6 +6,8 @@ var/hoodtype = /obj/item/clothing/head/hooded/winterhood //so the chaplain hoodie or other hoodies can override this ///Alternative mode for hiding the hood, instead of storing the hood in the suit it qdels it, useful for when you deal with hooded suit with storage. var/alternative_mode = FALSE + ///Whether the hood is flipped up + var/hood_up = FALSE /obj/item/clothing/suit/hooded/Initialize(mapload) . = ..() @@ -37,7 +39,7 @@ /obj/item/clothing/suit/hooded/proc/RemoveHood() src.icon_state = "[initial(icon_state)]" - suittoggled = FALSE + hood_up = FALSE if(hood) if(ishuman(hood.loc)) @@ -57,7 +59,7 @@ RemoveHood() /obj/item/clothing/suit/hooded/proc/ToggleHood() - if(!suittoggled) + if(!hood_up) if(!ishuman(loc)) return var/mob/living/carbon/human/H = loc @@ -74,7 +76,7 @@ if(alternative_mode) RemoveHood() return - suittoggled = TRUE + hood_up = TRUE icon_state = "[initial(icon_state)]_t" H.update_inv_wear_suit() update_action_buttons() @@ -102,37 +104,16 @@ else qdel(src) -//Toggle exosuits for different aesthetic styles (hoodies, suit jacket buttons, etc) +// Toggle exosuits for different aesthetic styles (hoodies, suit jacket buttons, etc) +// Pretty much just a holder for `/datum/component/toggle_icon`. -/obj/item/clothing/suit/toggle/AltClick(mob/user) - ..() - if(!user.canUseTopic(src, BE_CLOSE, NO_DEXTERITY, FALSE, !iscyborg(user))) - return - else - suit_toggle(user) +/obj/item/clothing/suit/toggle + /// The noun that is displayed to the user on toggle. EX: "Toggles the suit's [buttons]". + var/toggle_noun = "buttons" -/obj/item/clothing/suit/toggle/ui_action_click() - suit_toggle() - -/obj/item/clothing/suit/toggle/proc/suit_toggle() - set src in usr - - if(!can_use(usr)) - return 0 - - to_chat(usr, span_notice("You toggle [src]'s [togglename].")) - if(src.suittoggled) - src.icon_state = "[initial(icon_state)]" - src.suittoggled = FALSE - else if(!src.suittoggled) - src.icon_state = "[initial(icon_state)]_t" - src.suittoggled = TRUE - usr.update_inv_wear_suit() - update_action_buttons() - -/obj/item/clothing/suit/toggle/examine(mob/user) +/obj/item/clothing/suit/toggle/Initialize(mapload) . = ..() - . += "Alt-click on [src] to toggle the [togglename]." + AddComponent(/datum/component/toggle_icon, toggle_noun) //Hardsuit toggle code /obj/item/clothing/suit/space/hardsuit/Initialize(mapload) @@ -175,7 +156,7 @@ /obj/item/clothing/suit/space/hardsuit/proc/RemoveHelmet() if(!helmet) return - suittoggled = FALSE + helmet_on = FALSE if(ishuman(helmet.loc)) var/mob/living/carbon/H = helmet.loc if(helmet.on) @@ -198,7 +179,7 @@ if(!helmet) to_chat(H, span_warning("The helmet's lightbulb seems to be damaged! You'll need a replacement bulb.")) return - if(!suittoggled) + if(!helmet_on) if(ishuman(src.loc)) if(H.wear_suit != src) to_chat(H, span_warning("You must be wearing [src] to engage the helmet!")) @@ -208,7 +189,7 @@ return else if(H.equip_to_slot_if_possible(helmet,ITEM_SLOT_HEAD,0,0,1)) to_chat(H, span_notice("You engage the helmet on the hardsuit.")) - suittoggled = TRUE + helmet_on = TRUE H.update_inv_wear_suit() playsound(src.loc, 'sound/mecha/mechmove03.ogg', 50, TRUE) else diff --git a/tgstation.dme b/tgstation.dme index 48c9dca35c0..65e0ea801fb 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -654,6 +654,7 @@ #include "code\datums\components\tether.dm" #include "code\datums\components\thermite.dm" #include "code\datums\components\tippable.dm" +#include "code\datums\components\toggle_suit.dm" #include "code\datums\components\transforming.dm" #include "code\datums\components\trapdoor.dm" #include "code\datums\components\twohanded.dm"