From 97315940fe84c70069854f7c7129f944dbf28d6e Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Sun, 8 Mar 2020 01:01:21 +0100 Subject: [PATCH] Polychromic element. --- code/__DEFINES/components.dm | 1 + code/__HELPERS/_lists.dm | 21 +++ code/controllers/subsystem/dcs.dm | 5 +- code/datums/action.dm | 49 ++++--- code/datums/components/storage/storage.dm | 2 +- code/datums/components/virtual_reality.dm | 2 +- code/datums/elements/polychromic.dm | 127 ++++++++++++++++++ .../elements/update_icon_updates_onmob.dm | 2 +- code/game/objects/items.dm | 7 + .../modules/mob/living/carbon/update_icons.dm | 9 -- icons/mob/actions/backgrounds.dmi | Bin 6061 -> 18620 bytes tgstation.dme | 1 + 12 files changed, 188 insertions(+), 38 deletions(-) create mode 100644 code/datums/elements/polychromic.dm diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index 56cf681a27..ff0750a28c 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -255,6 +255,7 @@ #define COMSIG_ITEM_IMBUE_SOUL "item_imbue_soul" //return a truthy value to prevent ensouling, checked in /obj/effect/proc_holder/spell/targeted/lichdom/cast(): (mob/user) #define COMSIG_ITEM_HIT_REACT "item_hit_react" //from base of obj/item/hit_reaction(): (list/args) #define COMSIG_ITEM_WEARERCROSSED "wearer_crossed" //called on item when crossed by something (): (/atom/movable) +#define COMSIG_ITEM_WORN_OVERLAYS "item_worn_overlays" //from base of obj/item/worn_overlays(): (isinhands, icon_file, style_flags, list/overlays) // /obj/item/clothing signals #define COMSIG_SHOES_STEP_ACTION "shoes_step_action" //from base of obj/item/clothing/shoes/proc/step_action(): () diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index f16b566b00..8887a2aa1d 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -550,6 +550,27 @@ for(var/thing in flat_list) .[thing] = TRUE +/proc/deep_list2params(list/deep_list) + var/list/L = list() + for(var/i in deep_list) + var/key = i + if(isnum(key)) + key = "[key]" + continue + if(islist(key)) + key = deep_list2params(key) + else if(!istext(key)) + key = "[REF(key)]" + L += "[key]" + var/value = deep_list[key] + if(!isnull(value)) + if(islist(value)) + value = deep_list2params(value) + else if(!(istext(key) || isnum(key))) + value = "[REF(value)]" + L["[key]"] = "[value]" + return list2params(L) + //Picks from the list, with some safeties, and returns the "default" arg if it fails #define DEFAULTPICK(L, default) ((islist(L) && length(L)) ? pick(L) : default) diff --git a/code/controllers/subsystem/dcs.dm b/code/controllers/subsystem/dcs.dm index faf95fd319..19a1ac26b5 100644 --- a/code/controllers/subsystem/dcs.dm +++ b/code/controllers/subsystem/dcs.dm @@ -16,7 +16,10 @@ PROCESSING_SUBSYSTEM_DEF(dcs) if(istext(argument) || isnum(argument)) fullid += "[argument]" else - fullid += "[REF(argument)]" + if(islist(argument)) + fullid += deep_list2params(argument) + else + fullid += "[REF(argument)]" element_id = fullid.Join("&") . = elements_by_type[element_id] diff --git a/code/datums/action.dm b/code/datums/action.dm index f1df2a80d8..65db324b2b 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -6,13 +6,15 @@ /datum/action var/name = "Generic Action" var/desc = null - var/obj/target = null + var/atom/target = null var/check_flags = 0 var/required_mobility_flags = MOBILITY_USE var/processing = FALSE var/obj/screen/movable/action_button/button = null var/buttontooltipstyle = "" var/transparent_when_unavailable = TRUE + var/use_target_appearance = FALSE + var/list/target_appearance_matrix //if set, will be used to transform the target button appearance as an arglist. var/button_icon = 'icons/mob/actions/backgrounds.dmi' //This is the file for the BACKGROUND icon var/background_icon_state = ACTION_BUTTON_DEFAULT_BACKGROUND //And this is the state for the background icon @@ -88,7 +90,7 @@ /datum/action/proc/Trigger() if(!IsAvailable()) return FALSE - if(SEND_SIGNAL(src, COMSIG_ACTION_TRIGGER, src) & COMPONENT_ACTION_BLOCK_TRIGGER) + if(SEND_SIGNAL(src, COMSIG_ACTION_TRIGGER, target) & COMPONENT_ACTION_BLOCK_TRIGGER) return FALSE return TRUE @@ -116,7 +118,9 @@ return TRUE /datum/action/proc/UpdateButtonIcon(status_only = FALSE, force = FALSE) - if(button) + if(!button) + return + if(button_icon && button_icon_state) if(!status_only) button.name = name button.desc = desc @@ -134,11 +138,22 @@ ApplyIcon(button, force) - if(!IsAvailable()) - button.color = transparent_when_unavailable ? rgb(128,0,0,128) : rgb(128,0,0) - else - button.color = rgb(255,255,255,255) - return 1 + else if(use_target_appearance && target && button.appearance_cache != target.appearance) //replace with /ref comparison if this is not valid. + var/mutable_appearance/M = new(target) + M.layer = FLOAT_LAYER + M.plane = FLOAT_PLANE + if(target_appearance_matrix) + var/list/L = target_appearance_matrix + M.transform = matrix(L[1], L[2], L[3], L[4], L[5], L[6]) + button.cut_overlays() + button.add_overlay(M) + button.appearance_cache = target.appearance + + if(!IsAvailable()) + button.color = transparent_when_unavailable ? rgb(128,0,0,128) : rgb(128,0,0) + else + button.color = rgb(255,255,255,255) + return 1 /datum/action/proc/ApplyIcon(obj/screen/movable/action_button/current_button, force = FALSE) if(icon_icon && button_icon_state && ((current_button.button_icon_state != button_icon_state) || force)) @@ -165,6 +180,7 @@ /datum/action/item_action check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_LYING|AB_CHECK_CONSCIOUS button_icon_state = null + use_target_appearance = TRUE // If you want to override the normal icon being the item // then change this to an icon state @@ -188,23 +204,6 @@ I.ui_action_click(owner, src) return 1 -/datum/action/item_action/ApplyIcon(obj/screen/movable/action_button/current_button, force) - if(button_icon && button_icon_state) - // If set, use the custom icon that we set instead - // of the item appearence - ..() - else if(target && current_button.appearance_cache != target.appearance) //replace with /ref comparison if this is not valid. - var/obj/item/I = target - var/old_layer = I.layer - var/old_plane = I.plane - I.layer = FLOAT_LAYER //AAAH - I.plane = FLOAT_PLANE //^ what that guy said - current_button.cut_overlays() - current_button.add_overlay(I) - I.layer = old_layer - I.plane = old_plane - current_button.appearance_cache = I.appearance - /datum/action/item_action/toggle_light name = "Toggle Light" diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm index ea72a8a6dd..3ed66dcf92 100644 --- a/code/datums/components/storage/storage.dm +++ b/code/datums/components/storage/storage.dm @@ -790,7 +790,7 @@ user.visible_message("[user] draws [I] from [parent]!", "You draw [I] from [parent].") return TRUE -/datum/component/storage/proc/action_trigger(datum/signal_source, datum/action/source) +/datum/component/storage/proc/action_trigger(datum/action/source, obj/target) gather_mode_switch(source.owner) return COMPONENT_ACTION_BLOCK_TRIGGER diff --git a/code/datums/components/virtual_reality.dm b/code/datums/components/virtual_reality.dm index 63e4f4f092..cd5820d21f 100644 --- a/code/datums/components/virtual_reality.dm +++ b/code/datums/components/virtual_reality.dm @@ -174,7 +174,7 @@ /** *The following procs simply acts as hooks for quit(), since components do not use callbacks anymore */ -/datum/component/virtual_reality/proc/action_trigger(datum/signal_source, datum/action/source) +/datum/component/virtual_reality/proc/action_trigger(datum/action/source, obj/target) quit() return COMPONENT_ACTION_BLOCK_TRIGGER diff --git a/code/datums/elements/polychromic.dm b/code/datums/elements/polychromic.dm new file mode 100644 index 0000000000..4301a280f3 --- /dev/null +++ b/code/datums/elements/polychromic.dm @@ -0,0 +1,127 @@ +#define POLYCHROMIC_ALTCLICK (1<<0) +#define POLYCHROMIC_ACTION (1<<1) +#define POLYCHROMIC_NO_HELD (1<<2) +#define POLYCHROMIC_NO_WORN (1<<3) + +/datum/element/polychromic + element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH + id_arg_index = 3 + var/list/overlays_by_atom = list() + var/list/overlays_states //also used for worn/held overlsays + var/icon_file + var/list/overlays_names //wrap numbers into text strings please. + var/list/actions_by_atom = list() + var/poly_flags + //item variables + var/worn_file //used for boths held and worn overlays if present. + +/datum/element/polychromic/Attach(datum/target, list/colors, list/states, _icon, _flags = POLYCHROMIC_ALTCLICK|POLYCHROMIC_NO_HELD, _worn, list/names = list("Primary", "Secondary", "Tertiary", "Quaternary", "Quinary", "Senary")) + . = ..() + var/states_len = length(overlays_states) + var/names_len = length(names) + if(!states_len || names_len || !isatom(target)) + return ELEMENT_INCOMPATIBLE + var/atom/A = target + + overlays_states = states + icon_file = _icon + worn_file = _worn + poly_flags = _flags + + var/mut_icon = icon_file || A.icon + var/list/L = list() + for(var/I in overlays_states) + var/col = popleft(colors) || "#FFFFFF" + L += mutable_appearance(mut_icon, I, color = col) + A.add_overlay(L) + overlays_by_atom[A] = L + + if(_flags & POLYCHROMIC_ALTCLICK) + RegisterSignal(A, COMSIG_PARENT_EXAMINE, .proc/on_examine) + RegisterSignal(A, COMSIG_CLICK_ALT, .proc/set_color) + + if(!overlays_names && names) + overlays_names = names + var/diff = states_len - names_len + if(diff > 0) //It will be ugly, but still functional. + for(var/i in 1 to diff) + overlays_names += "[names_len + i]" + else if(diff < 0) + overlays_names.len += diff + + if(isitem(A)) + if(_flags & POLYCHROMIC_ACTION) + RegisterSignal(src, COMSIG_ITEM_EQUIPPED, .proc/grant_user_action) + RegisterSignal(src, COMSIG_ITEM_DROPPED, .proc/remove_user_action) + AddElement(A, /datum/element/update_icon_updates_onmob) //Since we can change the overall aspect of the item. + RegisterSignal(A, COMSIG_ITEM_WORN_OVERLAYS, .proc/apply_worn_overlays) + else if(_flags & POLYCHROMIC_ACTION && ismob(A)) //Not safe until mob icon updating procs are standarized and stop using cut_overlays() + var/datum/action/polychromic/P = new(A) + RegisterSignal(P, COMSIG_ACTION_TRIGGER, .proc/activate_action) + actions_by_atom[A] = P + P.Grant(A) + +/datum/element/polychromic/Detach(atom/A) + . = ..() + A.cut_overlay(overlays_by_atom[A]) + overlays_by_atom -= A + var/datum/action/polychromic/P = actions_by_atom[A] + if(P) + qdel(P) + actions_by_atom -= A + if(poly_flags & POLYCHROMIC_ALTCLICK) + UnregisterSignal(A, list(COMSIG_PARENT_EXAMINE, COMSIG_CLICK_ALT)) + +/datum/element/polychromic/proc/apply_worn_overlays(obj/item/source, isinhands, icon_file, style_flags, list/overlays) + if(poly_flags & (isinhands ? POLYCHROMIC_NO_HELD : POLYCHROMIC_NO_WORN)) + return + var/f_icon = worn_file || icon_file + var/list/L = overlays_by_atom[source] + + for(var/I in 1 to length(overlays_states)) + var/mutable_appearance/M = L[I] + overlays += mutable_appearance(f_icon, overlays_states[I], color = M.color) + +/datum/element/polychromic/proc/set_color(atom/source, mob/user) + var/choice = input(user,"Polychromic options", "Recolor [source]") as null|anything in overlays_names + if(!choice || QDELETED(source) || !user.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) + return + choice = overlays_names.Find(choice) + var/ncolor = input(user, "Polychromic options", "Choose [choice] Color") as color|null + if(!ncolor || QDELETED(source) || !user.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) + return + var/list/L = overlays_by_atom[source] + if(!L) // Ummmmmh. + return + var/mutable_appearance/M = L[choice] + M.color = sanitize_hexcolor(ncolor, 6, TRUE, M.color) + source.update_icon() + return TRUE + +/datum/element/polychromic/proc/grant_user_action(atom/source, mob/user, slot) + if(slot == SLOT_IN_BACKPACK || slot == SLOT_LEGCUFFED || slot == SLOT_HANDCUFFED || slot == SLOT_GENERC_DEXTROUS_STORAGE) + return + var/datum/action/polychromic/P = actions_by_atom[source] + if(!P) + P = new (source) + actions_by_atom[source] = P + P.check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_LYING|AB_CHECK_CONSCIOUS + RegisterSignal(P, COMSIG_ACTION_TRIGGER, .proc/activate_action) + P.Grant(user) + +/datum/element/polychromic/proc/remove_user_action(atom/source, mob/user) + var/datum/action/polychromic/P = actions_by_atom[source] + P?.Remove(user) + +/datum/element/polychromic/proc/activate_action(datum/action/source, atom/target) + set_color(target, source.owner) + +/datum/element/polychromic/proc/on_examine(atom/source, mob/user, list/examine_list) + examine_list += "Alt-click to recolor it." + +/datum/action/polychromic + name = "Modify Polychromic Colors" + background_icon_state = "bg_polychromic" + use_target_appearance = TRUE + button_icon_state = null + target_appearance_matrix = list(0.7,0,0,0,0.7,0) diff --git a/code/datums/elements/update_icon_updates_onmob.dm b/code/datums/elements/update_icon_updates_onmob.dm index ca0e8b1641..5c71547f62 100644 --- a/code/datums/elements/update_icon_updates_onmob.dm +++ b/code/datums/elements/update_icon_updates_onmob.dm @@ -5,7 +5,7 @@ . = ..() if(!istype(target, /obj/item)) return ELEMENT_INCOMPATIBLE - RegisterSignal(target, COMSIG_ATOM_UPDATED_ICON, .proc/update_onmob) + RegisterSignal(target, COMSIG_ATOM_UPDATED_ICON, .proc/update_onmob, override = TRUE) /datum/element/update_icon_updates_onmob/proc/update_onmob(obj/item/target) if(ismob(target.loc)) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index fd6ae1bb43..7a155ca932 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -425,6 +425,13 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) item_flags |= IN_INVENTORY user.update_equipment_speed_mods() +//Overlays for the worn overlay so you can overlay while you overlay +//eg: ammo counters, primed grenade flashing, etc. +//"icon_file" is used automatically for inhands etc. to make sure it gets the right inhand file +/obj/item/proc/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE) + . = list() + SEND_SIGNAL(src, COMSIG_ITEM_WORN_OVERLAYS, isinhands, icon_file, style_flags, .) + //sometimes we only want to grant the item's action if it's equipped in a specific slot. /obj/item/proc/item_action_slot_check(slot, mob/user, datum/action/A) if(slot == SLOT_IN_BACKPACK || slot == SLOT_LEGCUFFED) //these aren't true slots, so avoid granting actions there diff --git a/code/modules/mob/living/carbon/update_icons.dm b/code/modules/mob/living/carbon/update_icons.dm index e5483e8d73..0d6195e4dd 100644 --- a/code/modules/mob/living/carbon/update_icons.dm +++ b/code/modules/mob/living/carbon/update_icons.dm @@ -195,15 +195,6 @@ /mob/living/carbon/proc/update_hud_back(obj/item/I) return - - -//Overlays for the worn overlay so you can overlay while you overlay -//eg: ammo counters, primed grenade flashing, etc. -//"icon_file" is used automatically for inhands etc. to make sure it gets the right inhand file -/obj/item/proc/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE) - . = list() - - /mob/living/carbon/update_body() update_body_parts() diff --git a/icons/mob/actions/backgrounds.dmi b/icons/mob/actions/backgrounds.dmi index 3697fe4ff5b3cc76b1c4abd6ec5f7fdd4f1d5a35..07839588ce366d2783e503982b7817658fb5def0 100644 GIT binary patch literal 18620 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 LSLNdatI+=k=$XBH diff --git a/tgstation.dme b/tgstation.dme index 7ce9569f9a..b12baa9c47 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -501,6 +501,7 @@ #include "code\datums\elements\firestacker.dm" #include "code\datums\elements\ghost_role_eligibility.dm" #include "code\datums\elements\mob_holder.dm" +#include "code\datums\elements\polychromic.dm" #include "code\datums\elements\swimming.dm" #include "code\datums\elements\sword_point.dm" #include "code\datums\elements\update_icon_blocker.dm"