diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index 2ab04cb37f..e0f7457a4a 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -242,12 +242,14 @@
#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, used_state, style_flags, list/overlays)
// THE FOLLOWING TWO BLOCKS SHOULD RETURN BLOCK FLAGS AS DEFINED IN __DEFINES/combat.dm!
#define COMSIG_ITEM_CHECK_BLOCK "check_block" //from base of obj/item/check_block(): (mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
#define COMSIG_ITEM_RUN_BLOCK "run_block" //from base of obj/item/run_block(): (mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
// /obj/item/clothing signals
#define COMSIG_SHOES_STEP_ACTION "shoes_step_action" //from base of obj/item/clothing/shoes/proc/step_action(): ()
+#define COMSIG_SUIT_MADE_HELMET "suit_made_helmet" //from base of obj/item/clothing/suit/MakeHelmet(): (helmet)
// /obj/item/implant signals
#define COMSIG_IMPLANT_ACTIVATED "implant_activated" //from base of /obj/item/implant/proc/activate(): ()
diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm
index f16b566b00..a34b3ce67c 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))
+ L += "[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 8b068e5d67..3243a8d8c8 100644
--- a/code/controllers/subsystem/dcs.dm
+++ b/code/controllers/subsystem/dcs.dm
@@ -38,11 +38,17 @@ PROCESSING_SUBSYSTEM_DEF(dcs)
if(istext(key))
value = arguments[key]
if(!(istext(key) || isnum(key)))
- key = REF(key)
+ if(islist(key)) // CITADEL EDIT
+ key = deep_list2params(key)
+ else
+ key = REF(key)
key = "[key]" // Key is stringified so numbers dont break things
if(!isnull(value))
if(!(istext(value) || isnum(value)))
- value = REF(value)
+ if(islist(value)) // CITADEL EDIT
+ value = deep_list2params(value)
+ else
+ value = REF(value)
named_arguments["[key]"] = value
else
fullid += "[key]"
diff --git a/code/datums/action.dm b/code/datums/action.dm
index 4be3c9b1e7..f2f93ac40d 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,29 +118,42 @@
return TRUE
/datum/action/proc/UpdateButtonIcon(status_only = FALSE, force = FALSE)
- if(button)
- if(!status_only)
- button.name = name
- button.desc = desc
- if(owner && owner.hud_used && background_icon_state == ACTION_BUTTON_DEFAULT_BACKGROUND)
- var/list/settings = owner.hud_used.get_action_buttons_icons()
- if(button.icon != settings["bg_icon"])
- button.icon = settings["bg_icon"]
- if(button.icon_state != settings["bg_state"])
- button.icon_state = settings["bg_state"]
- else
- if(button.icon != button_icon)
- button.icon = button_icon
- if(button.icon_state != background_icon_state)
- button.icon_state = background_icon_state
+ if(!button)
+ return
+ if(!status_only)
+ button.name = name
+ button.desc = desc
+ if(owner && owner.hud_used && background_icon_state == ACTION_BUTTON_DEFAULT_BACKGROUND)
+ var/list/settings = owner.hud_used.get_action_buttons_icons()
+ if(button.icon != settings["bg_icon"])
+ button.icon = settings["bg_icon"]
+ if(button.icon_state != settings["bg_state"])
+ button.icon_state = settings["bg_state"]
+ else
+ if(button.icon != button_icon)
+ button.icon = button_icon
+ if(button.icon_state != background_icon_state)
+ button.icon_state = background_icon_state
+ if(!use_target_appearance)
ApplyIcon(button, force)
- if(!IsAvailable(TRUE))
- 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(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(TRUE))
+ 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 9239d4c565..56e06e3582 100644
--- a/code/datums/components/virtual_reality.dm
+++ b/code/datums/components/virtual_reality.dm
@@ -176,7 +176,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..1c438c86c5
--- /dev/null
+++ b/code/datums/elements/polychromic.dm
@@ -0,0 +1,187 @@
+#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/overlays_states //A list or a number of states. In the latter case, the atom icon_state/item_state will be used followed by a number.
+ var/list/colors_by_atom = list() //list of color strings or mutable appearances, depending on the above variable.
+ var/icon_file
+ var/worn_file //used in place of items' held or mob overlay icons if present.
+ var/list/overlays_names //wrap numbers into text strings please.
+ var/list/actions_by_atom = list()
+ var/poly_flags
+ var/static/list/suits_with_helmet_typecache = typecacheof(list(/obj/item/clothing/suit/hooded, /obj/item/clothing/suit/space/hardsuit))
+ var/list/helmet_by_suit = list() //because poly winter coats exist.
+ var/list/suit_by_helmet = list() //Idem.
+
+/datum/element/polychromic/Attach(datum/target, list/colors, states, _flags = POLYCHROMIC_ACTION|POLYCHROMIC_NO_HELD, _icon, _worn, list/names = list("Primary", "Secondary", "Tertiary", "Quaternary", "Quinary", "Senary"))
+ . = ..()
+ var/make_appearances = islist(states)
+ var/states_len = make_appearances ? length(states) : states
+ var/names_len = length(names)
+ if(!states_len || !names_len || colors_by_atom[target] || !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 1 to states_len)
+ var/col = LAZYACCESS(colors, I) || "#FFFFFF"
+ L += make_appearances ? mutable_appearance(mut_icon, overlays_states[I], color = col) : col
+ colors_by_atom[A] = L
+
+ RegisterSignal(A, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/apply_overlays)
+
+ if(_flags & POLYCHROMIC_ALTCLICK)
+ RegisterSignal(A, COMSIG_PARENT_EXAMINE, .proc/on_examine)
+ RegisterSignal(A, COMSIG_CLICK_ALT, .proc/set_color)
+
+ if(!overlays_names && names) //generate
+ overlays_names = names
+ var/diff = states_len - names_len
+ if(diff > 0)
+ 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(A, COMSIG_ITEM_EQUIPPED, .proc/grant_user_action)
+ RegisterSignal(A, COMSIG_ITEM_DROPPED, .proc/remove_user_action)
+ if(!(_flags & POLYCHROMIC_NO_WORN) || !(_flags & POLYCHROMIC_NO_HELD))
+ A.AddElement(/datum/element/update_icon_updates_onmob)
+ RegisterSignal(A, COMSIG_ITEM_WORN_OVERLAYS, .proc/apply_worn_overlays)
+ if(suits_with_helmet_typecache[A.type])
+ RegisterSignal(A, COMSIG_SUIT_MADE_HELMET, .proc/register_helmet)
+ else if(_flags & POLYCHROMIC_ACTION && ismob(A)) //in the event mob update icon procs are ever standarized.
+ var/datum/action/polychromic/P = new(A)
+ RegisterSignal(P, COMSIG_ACTION_TRIGGER, .proc/activate_action)
+ actions_by_atom[A] = P
+ P.Grant(A)
+
+ A.update_icon() //apply the overlays.
+
+/datum/element/polychromic/Detach(atom/A)
+ . = ..()
+ colors_by_atom -= A
+ var/datum/action/polychromic/P = actions_by_atom[A]
+ if(P)
+ actions_by_atom -= A
+ qdel(P)
+ UnregisterSignal(A, list(COMSIG_PARENT_EXAMINE, COMSIG_CLICK_ALT, COMSIG_ATOM_UPDATE_OVERLAYS, COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED, COMSIG_ITEM_WORN_OVERLAYS, COMSIG_SUIT_MADE_HELMET))
+ if(isitem(A))
+ var/obj/item/clothing/head/H = helmet_by_suit[A]
+ if(H)
+ UnregisterSignal(H, list(COMSIG_ATOM_UPDATE_OVERLAYS, COMSIG_ITEM_WORN_OVERLAYS, COMSIG_PARENT_QDELETING))
+ helmet_by_suit -= A
+ suit_by_helmet -= H
+ colors_by_atom -= H
+ if(!QDELETED(H))
+ H.update_icon() //removing the overlays
+ if(!(poly_flags & POLYCHROMIC_NO_WORN) || !(poly_flags & POLYCHROMIC_NO_HELD))
+ A.RemoveElement(/datum/element/update_icon_updates_onmob)
+ if(!QDELETED(A) && ismob(A.loc))
+ var/mob/M = A.loc
+ if(!(poly_flags & POLYCHROMIC_NO_HELD) && M.is_holding(A))
+ M.update_inv_hands()
+ else if(!(poly_flags & POLYCHROMIC_NO_WORN))
+ M.regenerate_icons()
+ if(!QDELETED(A))
+ A.update_icon() //removing the overlays
+
+/datum/element/polychromic/proc/apply_overlays(atom/source, list/overlays)
+ var/list/L = colors_by_atom[source]
+ var/f_icon = icon_file || source.icon
+ if(isnum(overlays_states))
+ for(var/i in 1 to overlays_states)
+ overlays += mutable_appearance(f_icon, "[source.icon_state]-[i]", color = L[i])
+ else
+ overlays += colors_by_atom[source]
+
+/datum/element/polychromic/proc/apply_worn_overlays(obj/item/source, isinhands, icon, used_state, style_flags, list/overlays)
+ if(poly_flags & (isinhands ? POLYCHROMIC_NO_HELD : POLYCHROMIC_NO_WORN))
+ return
+ var/f_icon = worn_file || icon
+ var/list/L = colors_by_atom[source]
+
+ if(isnum(overlays_states))
+ for(var/i in 1 to overlays_states)
+ overlays += mutable_appearance(f_icon, "[used_state]-[i]", color = L[i])
+ else
+ 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(source, BE_CLOSE, NO_DEXTERY))
+ return
+ var/index = overlays_names.Find(choice)
+ var/list/L = colors_by_atom[source]
+ if(!L) // Ummmmmh.
+ return
+ var/mutable_appearance/M = L[index]
+ var/old_color = istype(M) ? M.color : M
+ var/ncolor = input(user, "Polychromic options", "Choose [choice] Color", old_color) as color|null
+ if(!ncolor || QDELETED(source) || !colors_by_atom[source] || !user.canUseTopic(source, BE_CLOSE, NO_DEXTERY))
+ return
+ ncolor = sanitize_hexcolor(ncolor, 6, TRUE, old_color)
+ if(istype(M))
+ M.color = ncolor
+ else
+ L[index] = ncolor
+
+ 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)
+ P.name = "Modify [source]'\s Colors"
+ actions_by_atom[source] = P
+ P.check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|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/element/polychromic/proc/register_helmet(atom/source, obj/item/clothing/head/H)
+ suit_by_helmet[H] = source
+ helmet_by_suit[source] = H
+ colors_by_atom[H] = colors_by_atom[source]
+ RegisterSignal(H, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/apply_overlays)
+ RegisterSignal(H, COMSIG_ITEM_WORN_OVERLAYS, .proc/apply_worn_overlays)
+ RegisterSignal(H, COMSIG_PARENT_QDELETING, .proc/unregister_helmet)
+
+/datum/element/polychromic/proc/unregister_helmet(atom/source)
+ var/obj/item/clothing/suit/S = suit_by_helmet[source]
+ suit_by_helmet -= source
+ helmet_by_suit -= S
+ colors_by_atom -= source
+
+/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.8,0,0,0,0.8,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 aad6f45198..271bb7a385 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -434,6 +434,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, used_state, style_flags = NONE)
+ . = list()
+ SEND_SIGNAL(src, COMSIG_ITEM_WORN_OVERLAYS, isinhands, icon_file, used_state, 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/game/objects/items/RCL.dm b/code/game/objects/items/RCL.dm
index fccf790a23..f3ea461c74 100644
--- a/code/game/objects/items/RCL.dm
+++ b/code/game/objects/items/RCL.dm
@@ -113,7 +113,7 @@
cable_overlay.color = GLOB.cable_colors[colors[current_color_index]]
. += cable_overlay
-/obj/item/twohanded/rcl/worn_overlays(isinhands, icon_file, style_flags = NONE)
+/obj/item/twohanded/rcl/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands || !(loaded?.amount))
return
diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm
index e2ace42be7..ac60a322d8 100644
--- a/code/game/objects/items/holy_weapons.dm
+++ b/code/game/objects/items/holy_weapons.dm
@@ -303,8 +303,8 @@
block_chance = 50
var/shield_icon = "shield-red"
-/obj/item/nullrod/staff/worn_overlays(isinhands, icon_file, style_flags = NONE)
- . = list()
+/obj/item/nullrod/staff/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
+ . = ..()
if(isinhands)
. += mutable_appearance('icons/effects/effects.dmi', shield_icon, MOB_LAYER + 0.01)
diff --git a/code/game/objects/items/melee/energy.dm b/code/game/objects/items/melee/energy.dm
index 16d8ec0f4e..e4cfeab20f 100644
--- a/code/game/objects/items/melee/energy.dm
+++ b/code/game/objects/items/melee/energy.dm
@@ -324,7 +324,7 @@
. = ..()
. += "Alt-click to recolor it."
-/obj/item/melee/transforming/energy/sword/cx/worn_overlays(isinhands, icon_file, style_flags = NONE)
+/obj/item/melee/transforming/energy/sword/cx/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
. = ..()
if(active)
if(isinhands)
diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm
index bd9673f455..dc6f5f701e 100755
--- a/code/game/objects/items/storage/belt.dm
+++ b/code/game/objects/items/storage/belt.dm
@@ -22,7 +22,7 @@
for(var/obj/item/I in contents)
. += I.get_belt_overlay()
-/obj/item/storage/belt/worn_overlays(isinhands, icon_file, style_flags = NONE)
+/obj/item/storage/belt/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands && onmob_overlays)
for(var/obj/item/I in contents)
diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm
index c1cbf534ca..6ff5dfc8ad 100644
--- a/code/game/objects/items/tanks/watertank.dm
+++ b/code/game/objects/items/tanks/watertank.dm
@@ -376,8 +376,8 @@
filling.color = mix_color_from_reagents(reagents.reagent_list)
add_overlay(filling)
-/obj/item/reagent_containers/chemtank/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE) //apply chemcolor and level
- . = list()
+/obj/item/reagent_containers/chemtank/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE) //apply chemcolor and level
+ . = ..()
//inhands + reagent_filling
if(!isinhands && reagents.total_volume)
var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "backpackmob-10")
diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm
index 0d2892cb4a..e9f517a9f1 100644
--- a/code/game/objects/items/tools/screwdriver.dm
+++ b/code/game/objects/items/tools/screwdriver.dm
@@ -53,8 +53,8 @@
base_overlay.appearance_flags = RESET_COLOR
. += base_overlay
-/obj/item/screwdriver/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
- . = list()
+/obj/item/screwdriver/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
+ . = ..()
if(isinhands && random_color)
var/mutable_appearance/M = mutable_appearance(icon_file, "screwdriver_head")
M.appearance_flags = RESET_COLOR
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index e9b5712e71..9291b72467 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -349,7 +349,7 @@
update_light()
return TRUE
-/obj/item/toy/sword/cx/worn_overlays(isinhands, icon_file, style_flags = NONE)
+/obj/item/toy/sword/cx/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
. = ..()
if(active)
if(isinhands)
diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm
index 1a09cc57b6..2b6a91eb51 100644
--- a/code/game/objects/items/twohanded.dm
+++ b/code/game/objects/items/twohanded.dm
@@ -531,7 +531,7 @@
update_light()
return TRUE
-/obj/item/twohanded/dualsaber/hypereutactic/worn_overlays(isinhands, icon_file, style_flags = NONE)
+/obj/item/twohanded/dualsaber/hypereutactic/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
. = ..()
if(isinhands)
var/mutable_appearance/gem_inhand = mutable_appearance(icon_file, "hypereutactic_gem")
diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm
index 3127485878..57d7e08862 100644
--- a/code/game/objects/structures/bedsheet_bin.dm
+++ b/code/game/objects/structures/bedsheet_bin.dm
@@ -222,7 +222,7 @@ LINEN BINS
add_overlay(g_mouth)
add_overlay(g_eyes)
-/obj/item/bedsheet/gondola/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
+/obj/item/bedsheet/gondola/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands)
. += mutable_appearance(icon_file, g_mouth)
diff --git a/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm b/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm
index 6e7d830db6..5837ac302d 100644
--- a/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm
+++ b/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm
@@ -121,8 +121,8 @@
. = ..()
addtimer(CALLBACK(src, .proc/check_on_mob, user), 1) //dropped is called before the item is out of the slot, so we need to check slightly later
-/obj/item/clockwork/slab/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
- . = list()
+/obj/item/clockwork/slab/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
+ . = ..()
if(isinhands && item_state && inhand_overlay)
var/mutable_appearance/M = mutable_appearance(icon_file, "slab_[inhand_overlay]")
. += M
diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm
index a3ab4cf052..b05aa7f769 100644
--- a/code/modules/antagonists/cult/cult_items.dm
+++ b/code/modules/antagonists/cult/cult_items.dm
@@ -451,8 +451,8 @@
return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL
return BLOCK_NONE
-/obj/item/clothing/suit/hooded/cultrobes/cult_shield/worn_overlays(isinhands, icon_file, style_flags = NONE)
- . = list()
+/obj/item/clothing/suit/hooded/cultrobes/cult_shield/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
+ . = ..()
if(!isinhands && current_charges)
. += mutable_appearance('icons/effects/cult_effects.dmi', "shield-cult", MOB_LAYER + 0.01)
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index 402d16e7ec..d484027ad5 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -47,25 +47,12 @@
//Add a "exclude" string to do the opposite, making it only only species listed that can't wear it.
//You append this to clothing objects.
- //Polychrome stuff:
- var/hasprimary = FALSE //These vars allow you to choose which overlays a clothing has
- var/hassecondary = FALSE
- var/hastertiary = FALSE
- var/primary_color = "#FFFFFF" //RGB in hexcode
- var/secondary_color = "#FFFFFF"
- var/tertiary_color = "#808080"
-
- //No idea what this is but eh -tori
- var/force_alternate_icon = FALSE
-
/obj/item/clothing/Initialize()
. = ..()
if(CHECK_BITFIELD(clothing_flags, VOICEBOX_TOGGLABLE))
actions_types += /datum/action/item_action/toggle_voice_box
if(ispath(pocket_storage_component_path))
LoadComponent(pocket_storage_component_path)
- if(hasprimary | hassecondary | hastertiary) //Checks if polychrome is enabled
- update_icon() //Applies the overlays and default colors onto the clothes on spawn.
/obj/item/clothing/MouseDrop(atom/over_object)
. = ..()
@@ -150,8 +137,6 @@
how_cool_are_your_threads += "Adding or removing items from [src] makes no noise.\n"
how_cool_are_your_threads += ""
. += how_cool_are_your_threads.Join()
- if(hasprimary | hassecondary | hastertiary) //Checks if polychrome is enabled
- . += "Alt-click to recolor it."
/obj/item/clothing/obj_break(damage_flag)
if(!damaged_clothes)
@@ -195,173 +180,6 @@ BLIND // can't see anything
female_clothing_icon = fcopy_rsc(female_clothing_icon)
GLOB.female_clothing_icons[index] = female_clothing_icon
-/obj/item/clothing/under/verb/toggle()
- set name = "Adjust Suit Sensors"
- set category = "Object"
- set src in usr
- var/mob/M = usr
- if (istype(M, /mob/dead/))
- return
- if (!can_use(M))
- return
- if(src.has_sensor == LOCKED_SENSORS)
- to_chat(usr, "The controls are locked.")
- return 0
- if(src.has_sensor == BROKEN_SENSORS)
- to_chat(usr, "The sensors have shorted out!")
- return 0
- if(src.has_sensor <= NO_SENSORS)
- to_chat(usr, "This suit does not have any sensors.")
- return 0
-
- var/list/modes = list("Off", "Binary vitals", "Exact vitals", "Tracking beacon")
- var/switchMode = input("Select a sensor mode:", "Suit Sensor Mode", modes[sensor_mode + 1]) in modes
- if(get_dist(usr, src) > 1)
- to_chat(usr, "You have moved too far away!")
- return
- sensor_mode = modes.Find(switchMode) - 1
-
- if (src.loc == usr)
- switch(sensor_mode)
- if(0)
- to_chat(usr, "You disable your suit's remote sensing equipment.")
- if(1)
- to_chat(usr, "Your suit will now only report whether you are alive or dead.")
- if(2)
- to_chat(usr, "Your suit will now only report your exact vital lifesigns.")
- if(3)
- to_chat(usr, "Your suit will now report your exact vital lifesigns as well as your coordinate position.")
-
- if(ishuman(loc))
- var/mob/living/carbon/human/H = loc
- if(H.w_uniform == src)
- H.update_suit_sensors()
-
-
-/obj/item/clothing/under/CtrlClick(mob/user)
- . = ..()
-
- if (!(item_flags & IN_INVENTORY))
- return
-
- if(!isliving(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
- return
-
- if(has_sensor == LOCKED_SENSORS)
- to_chat(user, "The controls are locked.")
- return
- if(has_sensor == BROKEN_SENSORS)
- to_chat(user, "The sensors have shorted out!")
- return
- if(has_sensor <= NO_SENSORS)
- to_chat(user, "This suit does not have any sensors.")
- return
-
- sensor_mode = SENSOR_COORDS
-
- to_chat(user, "Your suit will now report your exact vital lifesigns as well as your coordinate position.")
-
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
- if(H.w_uniform == src)
- H.update_suit_sensors()
-
-/obj/item/clothing/under/AltClick(mob/user)
- . = ..()
- if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
- return
- if(attached_accessory)
- remove_accessory(user)
- else
- rolldown()
- // Polychrome stuff:
- if(hasprimary | hassecondary | hastertiary)
- var/choice = input(user,"polychromic thread options", "Clothing Recolor") as null|anything in list("[hasprimary ? "Primary Color" : ""]", "[hassecondary ? "Secondary Color" : ""]", "[hastertiary ? "Tertiary Color" : ""]") //generates a list depending on the enabled overlays
- switch(choice) //Lets the list's options actually lead to something
- if("Primary Color")
- var/primary_color_input = input(usr,"","Choose Primary Color",primary_color) as color|null //color input menu, the "|null" adds a cancel button to it.
- if(primary_color_input) //Checks if the color selected is NULL, rejects it if it is NULL.
- primary_color = sanitize_hexcolor(primary_color_input, desired_format=6, include_crunch=1) //formats the selected color properly
- update_icon() //updates the item icon
- user.regenerate_icons() //updates the worn icon. Probably a bad idea, but it works.
- if("Secondary Color")
- var/secondary_color_input = input(usr,"","Choose Secondary Color",secondary_color) as color|null
- if(secondary_color_input)
- secondary_color = sanitize_hexcolor(secondary_color_input, desired_format=6, include_crunch=1)
- update_icon()
- user.regenerate_icons()
- if("Tertiary Color")
- var/tertiary_color_input = input(usr,"","Choose Tertiary Color",tertiary_color) as color|null
- if(tertiary_color_input)
- tertiary_color = sanitize_hexcolor(tertiary_color_input, desired_format=6, include_crunch=1)
- update_icon()
- user.regenerate_icons()
- return TRUE
-
-/obj/item/clothing/neck/AltClick(mob/user)
- . = ..()
- if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
- return
- // Polychrome stuff:
- if(hasprimary | hassecondary | hastertiary)
- var/choice = input(user,"polychromic thread options", "Clothing Recolor") as null|anything in list("[hasprimary ? "Primary Color" : ""]", "[hassecondary ? "Secondary Color" : ""]", "[hastertiary ? "Tertiary Color" : ""]") //generates a list depending on the enabled overlays
- switch(choice) //Lets the list's options actually lead to something
- if("Primary Color")
- var/primary_color_input = input(usr,"","Choose Primary Color",primary_color) as color|null //color input menu, the "|null" adds a cancel button to it.
- if(primary_color_input) //Checks if the color selected is NULL, rejects it if it is NULL.
- primary_color = sanitize_hexcolor(primary_color_input, desired_format=6, include_crunch=1) //formats the selected color properly
- update_icon() //updates the item icon
- user.regenerate_icons() //updates the worn icon. Probably a bad idea, but it works.
- if("Secondary Color")
- var/secondary_color_input = input(usr,"","Choose Secondary Color",secondary_color) as color|null
- if(secondary_color_input)
- secondary_color = sanitize_hexcolor(secondary_color_input, desired_format=6, include_crunch=1)
- update_icon()
- user.regenerate_icons()
- if("Tertiary Color")
- var/tertiary_color_input = input(usr,"","Choose Tertiary Color",tertiary_color) as color|null
- if(tertiary_color_input)
- tertiary_color = sanitize_hexcolor(tertiary_color_input, desired_format=6, include_crunch=1)
- update_icon()
- user.regenerate_icons()
- return TRUE
-
-/obj/item/clothing/under/verb/jumpsuit_adjust()
- set name = "Adjust Jumpsuit Style"
- set category = null
- set src in usr
- rolldown()
-
-/obj/item/clothing/under/proc/rolldown()
- if(!can_use(usr))
- return
- if(!can_adjust)
- to_chat(usr, "You cannot wear this suit any differently!")
- return
- if(toggle_jumpsuit_adjust())
- to_chat(usr, "You adjust the suit to wear it more casually.")
- else
- to_chat(usr, "You adjust the suit back to normal.")
- if(ishuman(usr))
- var/mob/living/carbon/human/H = usr
- H.update_inv_w_uniform()
- H.update_body()
-
-/obj/item/clothing/under/proc/toggle_jumpsuit_adjust()
- adjusted = !adjusted
-
- if(adjusted)
- if(fitted != FEMALE_UNIFORM_TOP)
- fitted = NO_FEMALE_UNIFORM
- if(!alt_covers_chest) // for the special snowflake suits that expose the chest when adjusted
- body_parts_covered &= ~CHEST
- else
- fitted = initial(fitted)
- if(!alt_covers_chest)
- body_parts_covered |= CHEST
-
- return adjusted
-
/obj/item/clothing/proc/weldingvisortoggle(mob/user) //proc to toggle welding visors on helmets, masks, goggles, etc.
if(!can_use(user))
return FALSE
@@ -441,15 +259,3 @@ BLIND // can't see anything
return FALSE
return TRUE
-
-/obj/item/clothing/update_overlays() // Polychrome stuff
- . = ..()
- if(hasprimary) //Checks if the overlay is enabled
- var/mutable_appearance/primary_overlay = mutable_appearance(icon, "[item_state]-primary", color = primary_color) //Automagically picks overlays
- . += primary_overlay //Applies the coloured overlay onto the item sprite. but NOT the mob sprite.
- if(hassecondary)
- var/mutable_appearance/secondary_overlay = mutable_appearance(icon, "[item_state]-secondary", color = secondary_color)
- . += secondary_overlay
- if(hastertiary)
- var/mutable_appearance/tertiary_overlay = mutable_appearance(icon, "[item_state]-tertiary", color = tertiary_color)
- . += tertiary_overlay
diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm
index aff86f62f1..8cbc416b2e 100644
--- a/code/modules/clothing/glasses/_glasses.dm
+++ b/code/modules/clothing/glasses/_glasses.dm
@@ -346,8 +346,8 @@
add_atom_colour("#[user.eye_color]", FIXED_COLOUR_PRIORITY)
colored_before = TRUE
-/obj/item/clothing/glasses/sunglasses/blindfold/white/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
- . = list()
+/obj/item/clothing/glasses/sunglasses/blindfold/white/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
+ . = ..()
if(!isinhands && ishuman(loc) && !colored_before)
var/mob/living/carbon/human/H = loc
var/mutable_appearance/M = mutable_appearance('icons/mob/clothing/eyes.dmi', "blindfoldwhite")
diff --git a/code/modules/clothing/gloves/_gloves.dm b/code/modules/clothing/gloves/_gloves.dm
index 0729317eac..ddf5e4b584 100644
--- a/code/modules/clothing/gloves/_gloves.dm
+++ b/code/modules/clothing/gloves/_gloves.dm
@@ -26,8 +26,8 @@
user.visible_message("\the [src] are forcing [user]'s hands around [user.p_their()] neck! It looks like the gloves are possessed!")
return OXYLOSS
-/obj/item/clothing/gloves/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
- . = list()
+/obj/item/clothing/gloves/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
+ . = ..()
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedgloves")
diff --git a/code/modules/clothing/head/_head.dm b/code/modules/clothing/head/_head.dm
index d599fbf6f7..475e7a4e51 100644
--- a/code/modules/clothing/head/_head.dm
+++ b/code/modules/clothing/head/_head.dm
@@ -48,8 +48,8 @@
-/obj/item/clothing/head/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
- . = list()
+/obj/item/clothing/head/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
+ . = ..()
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedhelmet")
diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm
index 73e626bcd1..ffd50cbfbe 100644
--- a/code/modules/clothing/head/hardhat.dm
+++ b/code/modules/clothing/head/hardhat.dm
@@ -124,7 +124,7 @@
playsound(src, 'sound/mecha/mechmove03.ogg', 50, TRUE) //Visors don't just come from nothing
update_icon()
-/obj/item/clothing/head/hardhat/weldhat/worn_overlays(isinhands, icon_file, style_flags = NONE)
+/obj/item/clothing/head/hardhat/weldhat/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands)
. += mutable_appearance('icons/mob/clothing/head.dmi', "weldhelmet")
diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm
index 6ba58016f2..9c96223a6f 100644
--- a/code/modules/clothing/head/misc_special.dm
+++ b/code/modules/clothing/head/misc_special.dm
@@ -204,8 +204,8 @@
icon = S.icon
icon_state = S.icon_state
-/obj/item/clothing/head/wig/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
- . = list()
+/obj/item/clothing/head/wig/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
+ . = ..()
if(!isinhands)
var/datum/sprite_accessory/S = GLOB.hair_styles_list[hair_style]
if(!S)
diff --git a/code/modules/clothing/masks/_masks.dm b/code/modules/clothing/masks/_masks.dm
index 5019633cf0..7df38661e5 100644
--- a/code/modules/clothing/masks/_masks.dm
+++ b/code/modules/clothing/masks/_masks.dm
@@ -28,8 +28,8 @@
/obj/item/clothing/mask/proc/handle_speech()
-/obj/item/clothing/mask/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
- . = list()
+/obj/item/clothing/mask/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
+ . = ..()
if(!isinhands)
if(body_parts_covered & HEAD)
if(damaged_clothes)
diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm
index 069ab43dd9..402ea37f21 100644
--- a/code/modules/clothing/neck/_neck.dm
+++ b/code/modules/clothing/neck/_neck.dm
@@ -6,8 +6,8 @@
strip_delay = 40
equip_delay_other = 40
-/obj/item/clothing/neck/worn_overlays(isinhands = FALSE, icon_flag, style_flags = NONE)
- . = list()
+/obj/item/clothing/neck/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
+ . = ..()
if(!isinhands)
if(body_parts_covered & HEAD)
if(damaged_clothes)
@@ -169,54 +169,44 @@
name = "pet collar"
desc = "It's for pets. Though you probably could wear it yourself, you'd doubtless be the subject of ridicule. It seems to be made out of a polychromic material."
icon_state = "petcollar"
- mob_overlay_icon = 'icons/mob/clothing/neck.dmi' //Because, as it appears, the item itself is normally not directly aware of its worn overlays, so this is about the easiest way, without adding a new var.
- hasprimary = TRUE
- primary_color = "#00BBBB"
pocket_storage_component_path = /datum/component/storage/concrete/pockets/small/collar
+ var/poly_states = 1
+ var/poly_colors = list("#00BBBB")
var/tagname = null
+ var/treat_path = /obj/item/reagent_containers/food/snacks/cookie
+
+/obj/item/clothing/neck/petcollar/Initialize()
+ . = ..()
+ if(treat_path)
+ new treat_path(src)
+
+/obj/item/clothing/neck/petcollar/ComponentInitialize()
+ . = ..()
+ if(!poly_states)
+ return
+ AddElement(/datum/element/polychromic, poly_colors, poly_states)
/obj/item/clothing/neck/petcollar/attack_self(mob/user)
tagname = stripped_input(user, "Would you like to change the name on the tag?", "Name your new pet", "Spot", MAX_NAME_LEN)
name = "[initial(name)] - [tagname]"
-/obj/item/clothing/neck/petcollar/worn_overlays(isinhands, icon_file, style_flags = NONE)
- . = ..()
- if(hasprimary | hassecondary | hastertiary)
- if(!isinhands) //prevents the worn sprites from showing up if you're just holding them
- if(hasprimary) //checks if overlays are enabled
- var/mutable_appearance/primary_worn = mutable_appearance(mob_overlay_icon, "[icon_state]-primary") //automagical sprite selection
- primary_worn.color = primary_color //colors the overlay
- . += primary_worn //adds the overlay onto the buffer list to draw on the mob sprite
- if(hassecondary)
- var/mutable_appearance/secondary_worn = mutable_appearance(mob_overlay_icon, "[icon_state]-secondary")
- secondary_worn.color = secondary_color
- . += secondary_worn
- if(hastertiary)
- var/mutable_appearance/tertiary_worn = mutable_appearance(mob_overlay_icon, "[icon_state]-tertiary")
- tertiary_worn.color = tertiary_color
- . += tertiary_worn
-
/obj/item/clothing/neck/petcollar/leather
name = "leather pet collar"
icon_state = "leathercollar"
-
- hasprimary = TRUE
- hassecondary = TRUE
- primary_color = "#222222"
- secondary_color = "#888888"
+ poly_states = 2
+ poly_colors = list("#222222", "#888888")
/obj/item/clothing/neck/petcollar/choker
desc = "Quite fashionable... if you're somebody who's just read their first BDSM-themed erotica novel."
name = "choker"
icon_state = "choker"
-
- hasprimary = TRUE
- primary_color = "#222222"
+ poly_colors = list("#222222")
/obj/item/clothing/neck/petcollar/locked
name = "locked collar"
desc = "A collar that has a small lock on it to keep it from being removed."
pocket_storage_component_path = /datum/component/storage/concrete/pockets/small/collar/locked
+ treat_path = /obj/item/key/collar
var/lock = FALSE
/obj/item/clothing/neck/petcollar/locked/attackby(obj/item/K, mob/user, params)
@@ -238,32 +228,19 @@
/obj/item/clothing/neck/petcollar/locked/leather
name = "leather pet collar"
icon_state = "leathercollar"
-
- hasprimary = TRUE
- hassecondary = TRUE
- primary_color = "#222222"
- secondary_color = "#888888"
+ poly_states = 2
+ poly_colors = list("#222222", "#888888")
/obj/item/clothing/neck/petcollar/locked/choker
name = "choker"
desc = "Quite fashionable... if you're somebody who's just read their first BDSM-themed erotica novel."
icon_state = "choker"
-
- hasprimary = TRUE
- primary_color = "#222222"
+ poly_colors = list("#222222")
/obj/item/key/collar
name = "Collar Key"
desc = "A key for a tiny lock on a collar or bag."
-/obj/item/clothing/neck/petcollar/Initialize()
- . = ..()
- new /obj/item/reagent_containers/food/snacks/cookie(src)
-
-/obj/item/clothing/neck/petcollar/locked/Initialize()
- . = ..()
- new /obj/item/key/collar(src)
-
//////////////
//DOPE BLING//
//////////////
diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm
index 471c7623fd..802dd7265e 100644
--- a/code/modules/clothing/shoes/_shoes.dm
+++ b/code/modules/clothing/shoes/_shoes.dm
@@ -49,8 +49,8 @@
last_bloodtype = blood_dna[blood_dna[blood_dna.len]]//trust me this works
last_blood_DNA = blood_dna[blood_dna.len]
-/obj/item/clothing/shoes/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
- . = list()
+/obj/item/clothing/shoes/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
+ . = ..()
if(!isinhands)
var/bloody = FALSE
if(blood_DNA)
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index a1deb8ad30..93b34f4522 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -800,7 +800,7 @@
var/mob/living/carbon/human/C = loc
C.update_inv_wear_suit()
-/obj/item/clothing/suit/space/hardsuit/shielded/worn_overlays(isinhands, icon_file, style_flags = NONE)
+/obj/item/clothing/suit/space/hardsuit/shielded/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands)
var/file2use = style_flags & STYLE_ALL_TAURIC ? 'modular_citadel/icons/mob/64x32_effects.dmi' : 'icons/effects/effects.dmi'
@@ -957,7 +957,7 @@
. = ..()
. += mutable_appearance(icon, "knight_cydonia_overlay", color = energy_color)
-/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
+/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands)
var/mutable_appearance/energy_overlay = mutable_appearance(icon_file, "knight_cydonia_overlay", ABOVE_LIGHTING_LAYER)
@@ -988,7 +988,7 @@
. = ..()
. += mutable_appearance(icon, "knight_cydonia_overlay", color = energy_color)
-/obj/item/clothing/suit/space/hardsuit/lavaknight/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
+/obj/item/clothing/suit/space/hardsuit/lavaknight/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands)
var/mutable_appearance/energy_overlay = mutable_appearance(icon_file, "knight_cydonia_overlay", ABOVE_LIGHTING_LAYER)
diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm
index fee8dbce33..f17eb91b74 100644
--- a/code/modules/clothing/spacesuits/plasmamen.dm
+++ b/code/modules/clothing/spacesuits/plasmamen.dm
@@ -67,7 +67,7 @@
var/datum/action/A=X
A.UpdateButtonIcon()
-/obj/item/clothing/head/helmet/space/plasmaman/worn_overlays(isinhands, icon_file, style_flags = NONE)
+/obj/item/clothing/head/helmet/space/plasmaman/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands && on)
. += mutable_appearance(icon_file, light_overlay)
diff --git a/code/modules/clothing/suits/_suits.dm b/code/modules/clothing/suits/_suits.dm
index e01ec2dde8..8de49c63de 100644
--- a/code/modules/clothing/suits/_suits.dm
+++ b/code/modules/clothing/suits/_suits.dm
@@ -12,7 +12,7 @@
var/suittoggled = FALSE
mutantrace_variation = STYLE_DIGITIGRADE
-/obj/item/clothing/suit/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
+/obj/item/clothing/suit/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands)
if(damaged_clothes)
diff --git a/code/modules/clothing/suits/cloaks.dm b/code/modules/clothing/suits/cloaks.dm
index 7d56fbe6dd..ce3d2576f9 100644
--- a/code/modules/clothing/suits/cloaks.dm
+++ b/code/modules/clothing/suits/cloaks.dm
@@ -91,3 +91,14 @@
heat_protection = HEAD
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | ACID_PROOF | GOLIATH_RESISTANCE
+
+/obj/item/clothing/neck/cloak/polychromic
+ name = "polychromic cloak"
+ desc = "For when you want to show off your horrible colour coordination skills."
+ icon_state = "polyce"
+ item_state = "qmcloak"
+ var/list/poly_colors = list("#FFFFFF", "#FFFFFF", "#808080")
+
+/obj/item/clothing/neck/cloak/polychromic/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/polychromic, poly_colors, 3)
diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm
index 0e345636cf..c133ea7c88 100644
--- a/code/modules/clothing/suits/miscellaneous.dm
+++ b/code/modules/clothing/suits/miscellaneous.dm
@@ -974,70 +974,11 @@
icon_state = "coatpoly"
item_state = "coatpoly"
hoodtype = /obj/item/clothing/head/hooded/winterhood/polychromic
- hasprimary = TRUE
- hassecondary = TRUE
- hastertiary = TRUE
- primary_color = "#6A6964"
- secondary_color = "#C4B8A6"
- tertiary_color = "#0000FF"
+
+/obj/item/clothing/suit/hooded/wintercoat/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/polychromic, list("#6A6964", "#C4B8A6", "#0000FF"), 3)
/obj/item/clothing/head/hooded/winterhood/polychromic
icon_state = "winterhood_poly"
item_state = "winterhood_poly"
-
-/obj/item/clothing/head/hooded/winterhood/polychromic/worn_overlays(isinhands, icon_file, style_flags = NONE) //this is where the main magic happens.
- . = ..()
- if(suit.hasprimary | suit.hassecondary)
- if(!isinhands) //prevents the worn sprites from showing up if you're just holding them
- if(suit.hasprimary) //checks if overlays are enabled
- var/mutable_appearance/primary_worn = mutable_appearance(icon_file, "[icon_state]-primary") //automagical sprite selection
- primary_worn.color = suit.primary_color //colors the overlay
- . += primary_worn //adds the overlay onto the buffer list to draw on the mob sprite.
- if(suit.hassecondary)
- var/mutable_appearance/secondary_worn = mutable_appearance(icon_file, "[icon_state]-secondary")
- secondary_worn.color = suit.secondary_color
- . += secondary_worn
-
-/obj/item/clothing/suit/hooded/wintercoat/polychromic/worn_overlays(isinhands, icon_file, style_flags = NONE) //this is where the main magic happens.
- . = ..()
- if(hasprimary | hassecondary | hastertiary)
- if(!isinhands) //prevents the worn sprites from showing up if you're just holding them
- if(hasprimary) //checks if overlays are enabled
- var/mutable_appearance/primary_worn = mutable_appearance(icon_file, "[icon_state]-primary[suittoggled ? "_t" : ""]") //automagical sprite selection
- primary_worn.color = primary_color //colors the overlay
- . += primary_worn //adds the overlay onto the buffer list to draw on the mob sprite.
- if(hassecondary)
- var/mutable_appearance/secondary_worn = mutable_appearance(icon_file, "[icon_state]-secondary[suittoggled ? "_t" : ""]")
- secondary_worn.color = secondary_color
- . += secondary_worn
- if(hastertiary)
- var/mutable_appearance/tertiary_worn = mutable_appearance(icon_file, "[icon_state]-tertiary[suittoggled ? "_t" : ""]")
- tertiary_worn.color = tertiary_color
- . += tertiary_worn
-
-/obj/item/clothing/suit/hooded/wintercoat/AltClick(mob/user)
- . = ..()
- if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
- return
- if(hasprimary | hassecondary | hastertiary)
- var/choice = input(user,"polychromic thread options", "Clothing Recolor") as null|anything in list("[hasprimary ? "Primary Color" : ""]", "[hassecondary ? "Secondary Color" : ""]", "[hastertiary ? "Tertiary Color" : ""]") //generates a list depending on the enabled overlays
- switch(choice) //Lets the list's options actually lead to something
- if("Primary Color")
- var/primary_color_input = input(usr,"","Choose Primary Color",primary_color) as color|null //color input menu, the "|null" adds a cancel button to it.
- if(primary_color_input) //Checks if the color selected is NULL, rejects it if it is NULL.
- primary_color = sanitize_hexcolor(primary_color_input, desired_format=6, include_crunch=1) //formats the selected color properly
- update_icon() //updates the item icon
- user.regenerate_icons() //updates the worn icon. Probably a bad idea, but it works.
- if("Secondary Color")
- var/secondary_color_input = input(usr,"","Choose Secondary Color",secondary_color) as color|null
- if(secondary_color_input)
- secondary_color = sanitize_hexcolor(secondary_color_input, desired_format=6, include_crunch=1)
- update_icon()
- user.regenerate_icons()
- if("Tertiary Color")
- var/tertiary_color_input = input(usr,"","Choose Tertiary Color",tertiary_color) as color|null
- if(tertiary_color_input)
- tertiary_color = sanitize_hexcolor(tertiary_color_input, desired_format=6, include_crunch=1)
- update_icon()
- user.regenerate_icons()
- return TRUE
diff --git a/code/modules/clothing/suits/toggles.dm b/code/modules/clothing/suits/toggles.dm
index cbbd64ebcc..4f29eab6ab 100644
--- a/code/modules/clothing/suits/toggles.dm
+++ b/code/modules/clothing/suits/toggles.dm
@@ -6,7 +6,7 @@
var/hoodtype = /obj/item/clothing/head/hooded/winterhood //so the chaplain hoodie or other hoodies can override this
/obj/item/clothing/suit/hooded/New()
- MakeHood()
+ hood = MakeHelmet()
..()
/obj/item/clothing/suit/hooded/Destroy()
@@ -14,11 +14,15 @@
qdel(hood)
hood = null
-/obj/item/clothing/suit/hooded/proc/MakeHood()
+/obj/item/clothing/suit/proc/MakeHelmet(obj/item/clothing/head/H)
+ SEND_SIGNAL(src, COMSIG_SUIT_MADE_HELMET, H)
+ return H
+
+/obj/item/clothing/suit/hooded/MakeHelmet(obj/item/clothing/head/hooded/H)
if(!hood)
- var/obj/item/clothing/head/hooded/W = new hoodtype(src)
- W.suit = src
- hood = W
+ H = new hoodtype(src)
+ H.suit = src
+ return ..()
/obj/item/clothing/suit/hooded/ui_action_click()
ToggleHood()
@@ -125,7 +129,7 @@
//Hardsuit toggle code
/obj/item/clothing/suit/space/hardsuit/Initialize()
- MakeHelmet()
+ helmet = MakeHelmet()
. = ..()
/obj/item/clothing/suit/space/hardsuit/Destroy()
@@ -140,13 +144,13 @@
suit.helmet = null
return ..()
-/obj/item/clothing/suit/space/hardsuit/proc/MakeHelmet()
+/obj/item/clothing/suit/space/hardsuit/MakeHelmet(obj/item/clothing/head/helmet/space/hardsuit/H)
if(!helmettype)
return
if(!helmet)
- var/obj/item/clothing/head/helmet/space/hardsuit/W = new helmettype(src)
- W.suit = src
- helmet = W
+ H = new helmettype(src)
+ H.suit = src
+ return ..()
/obj/item/clothing/suit/space/hardsuit/ui_action_click()
..()
diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm
index 30bccff6de..fe3aaf4bda 100644
--- a/code/modules/clothing/under/_under.dm
+++ b/code/modules/clothing/under/_under.dm
@@ -18,28 +18,14 @@
var/obj/item/clothing/accessory/attached_accessory
var/mutable_appearance/accessory_overlay
-/obj/item/clothing/under/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
- . = list()
+/obj/item/clothing/under/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
+ . = ..()
if(isinhands)
return
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform")
if(blood_DNA)
. += mutable_appearance('icons/effects/blood.dmi', "uniformblood", color = blood_DNA_to_color())
- if(accessory_overlay)
- . += accessory_overlay
- if(hasprimary) //checks if overlays are enabled
- var/mutable_appearance/primary_worn = mutable_appearance(icon_file, "[icon_state]-primary") //automagical sprite selection
- primary_worn.color = primary_color //colors the overlay
- . += primary_worn //adds the overlay onto the buffer list to draw on the mob sprite.
- if(hassecondary)
- var/mutable_appearance/secondary_worn = mutable_appearance(icon_file, "[icon_state]-secondary")
- secondary_worn.color = secondary_color
- . += secondary_worn
- if(hastertiary)
- var/mutable_appearance/tertiary_worn = mutable_appearance(icon_file, "[icon_state]-tertiary")
- tertiary_worn.color = tertiary_color
- . += tertiary_worn
/obj/item/clothing/under/attackby(obj/item/I, mob/user, params)
if((has_sensor == BROKEN_SENSORS) && istype(I, /obj/item/stack/cable_coil))
@@ -167,5 +153,121 @@
if(attached_accessory)
. += "\A [attached_accessory] is attached to it."
+/obj/item/clothing/under/verb/toggle()
+ set name = "Adjust Suit Sensors"
+ set category = "Object"
+ set src in usr
+ var/mob/M = usr
+ if (istype(M, /mob/dead/))
+ return
+ if (!can_use(M))
+ return
+ if(src.has_sensor == LOCKED_SENSORS)
+ to_chat(usr, "The controls are locked.")
+ return 0
+ if(src.has_sensor == BROKEN_SENSORS)
+ to_chat(usr, "The sensors have shorted out!")
+ return 0
+ if(src.has_sensor <= NO_SENSORS)
+ to_chat(usr, "This suit does not have any sensors.")
+ return 0
+
+ var/list/modes = list("Off", "Binary vitals", "Exact vitals", "Tracking beacon")
+ var/switchMode = input("Select a sensor mode:", "Suit Sensor Mode", modes[sensor_mode + 1]) in modes
+ if(get_dist(usr, src) > 1)
+ to_chat(usr, "You have moved too far away!")
+ return
+ sensor_mode = modes.Find(switchMode) - 1
+
+ if (src.loc == usr)
+ switch(sensor_mode)
+ if(0)
+ to_chat(usr, "You disable your suit's remote sensing equipment.")
+ if(1)
+ to_chat(usr, "Your suit will now only report whether you are alive or dead.")
+ if(2)
+ to_chat(usr, "Your suit will now only report your exact vital lifesigns.")
+ if(3)
+ to_chat(usr, "Your suit will now report your exact vital lifesigns as well as your coordinate position.")
+
+ if(ishuman(loc))
+ var/mob/living/carbon/human/H = loc
+ if(H.w_uniform == src)
+ H.update_suit_sensors()
+
+
+/obj/item/clothing/under/CtrlClick(mob/user)
+ . = ..()
+
+ if (!(item_flags & IN_INVENTORY))
+ return
+
+ if(!isliving(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
+ return
+
+ if(has_sensor == LOCKED_SENSORS)
+ to_chat(user, "The controls are locked.")
+ return
+ if(has_sensor == BROKEN_SENSORS)
+ to_chat(user, "The sensors have shorted out!")
+ return
+ if(has_sensor <= NO_SENSORS)
+ to_chat(user, "This suit does not have any sensors.")
+ return
+
+ sensor_mode = SENSOR_COORDS
+
+ to_chat(user, "Your suit will now report your exact vital lifesigns as well as your coordinate position.")
+
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ if(H.w_uniform == src)
+ H.update_suit_sensors()
+
+/obj/item/clothing/under/AltClick(mob/user)
+ . = ..()
+ if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
+ return
+ if(attached_accessory)
+ remove_accessory(user)
+ else
+ rolldown()
+
+/obj/item/clothing/under/verb/jumpsuit_adjust()
+ set name = "Adjust Jumpsuit Style"
+ set category = null
+ set src in usr
+ rolldown()
+
+/obj/item/clothing/under/proc/rolldown()
+ if(!can_use(usr))
+ return
+ if(!can_adjust)
+ to_chat(usr, "You cannot wear this suit any differently!")
+ return
+ if(toggle_jumpsuit_adjust())
+ to_chat(usr, "You adjust the suit to wear it more casually.")
+ else
+ to_chat(usr, "You adjust the suit back to normal.")
+ if(ishuman(usr))
+ var/mob/living/carbon/human/H = usr
+ H.update_inv_w_uniform()
+ H.update_body()
+
+/obj/item/clothing/under/proc/toggle_jumpsuit_adjust()
+ adjusted = !adjusted
+
+ if(adjusted)
+ if(fitted != FEMALE_UNIFORM_TOP)
+ fitted = NO_FEMALE_UNIFORM
+ if(!alt_covers_chest) // for the special snowflake suits that expose the chest when adjusted
+ body_parts_covered &= ~CHEST
+ else
+ fitted = initial(fitted)
+ if(!alt_covers_chest)
+ body_parts_covered |= CHEST
+
+ return adjusted
+
/obj/item/clothing/under/rank
dying_key = DYE_REGISTRY_UNDER
diff --git a/code/modules/clothing/under/costume.dm b/code/modules/clothing/under/costume.dm
index 12988c26ae..69a1dc67b3 100644
--- a/code/modules/clothing/under/costume.dm
+++ b/code/modules/clothing/under/costume.dm
@@ -91,13 +91,13 @@
name = "polychromic kilt"
desc = "It's not a skirt!"
icon_state = "polykilt"
- hasprimary = TRUE
- hassecondary = TRUE
- primary_color = "#FFFFFF"
- secondary_color = "#F08080"
body_parts_covered = CHEST|GROIN|ARMS|LEGS
mutantrace_variation = NONE
+/obj/item/clothing/under/costume/kilt/polychromic/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/polychromic, list("#FFFFFF", "#F08080"), 2)
+
/obj/item/clothing/under/costume/gladiator
name = "gladiator uniform"
desc = "Are you not entertained? Is that not why you are here?"
diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm
index a7557a0702..d475ca8100 100644
--- a/code/modules/clothing/under/miscellaneous.dm
+++ b/code/modules/clothing/under/miscellaneous.dm
@@ -241,69 +241,67 @@
desc = "A fancy button-up shirt made with polychromic threads."
icon_state = "polysuit"
item_state = "sl_suit"
- hasprimary = TRUE
- hassecondary = TRUE
- hastertiary = TRUE
- primary_color = "#FFFFFF"
- secondary_color = "#353535"
- tertiary_color = "#353535"
mutantrace_variation = NONE
+/obj/item/clothing/under/misc/poly_shirt/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/polychromic, list("#FFFFFF", "#353535", "#353535"), 3)
+
/obj/item/clothing/under/misc/polyshorts
name = "polychromic shorts"
desc = "For ease of movement and style."
icon_state = "polyshorts"
item_state = "rainbow"
- hasprimary = TRUE
- hassecondary = TRUE
- hastertiary = TRUE
- primary_color = "#353535"
- secondary_color = "#808080"
- tertiary_color = "#808080"
can_adjust = FALSE
body_parts_covered = CHEST|GROIN|ARMS
+/obj/item/clothing/under/misc/polyshorts/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/polychromic, list("#353535", "#808080", "#808080"), 3)
+
/obj/item/clothing/under/misc/polyjumpsuit
name = "polychromic tri-tone jumpsuit"
desc = "A fancy jumpsuit made with polychromic threads."
icon_state = "polyjump"
item_state = "rainbow"
- hasprimary = TRUE
- hassecondary = TRUE
- hastertiary = TRUE
- primary_color = "#FFFFFF"
- secondary_color = "#808080"
- tertiary_color = "#FF3535"
can_adjust = FALSE
mutantrace_variation = NONE
+/obj/item/clothing/under/misc/polyjumpsuit/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/polychromic, list("#FFFFFF", "#808080", "#353535"), 3)
+
/obj/item/clothing/under/misc/poly_bottomless
name = "polychromic bottomless shirt"
- desc = "Great for showing off your junk in dubious style."
+ desc = "Great for showing off your underwear in dubious style."
icon_state = "polybottomless"
item_state = "rainbow"
- primary_color = "#808080"
- secondary_color = "#FF3535"
body_parts_covered = CHEST|ARMS //Because there's no bottom included
can_adjust = FALSE
mutantrace_variation = NONE
+/obj/item/clothing/under/misc/poly_bottomless/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/polychromic, list("#808080", "#FF3535"), 2)
+
/obj/item/clothing/under/misc/poly_tanktop
name = "polychromic tank top"
desc = "For those lazy summer days."
icon_state = "polyshimatank"
item_state = "rainbow"
- primary_color = "#808080"
- secondary_color = "#FFFFFF"
- tertiary_color = "#8CC6FF"
body_parts_covered = CHEST|GROIN
can_adjust = FALSE
mutantrace_variation = NONE
+ var/list/poly_states = 3
+ var/list/poly_colors = list("#808080", "#FFFFFF", "#8CC6FF")
+
+/obj/item/clothing/under/misc/poly_tanktop/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/polychromic, poly_colors, poly_states)
/obj/item/clothing/under/misc/poly_tanktop/female
name = "polychromic feminine tank top"
desc = "Great for showing off your chest in style. Not recommended for males."
icon_state = "polyfemtankpantsu"
- hastertiary = FALSE
- primary_color = "#808080"
- secondary_color = "#FF3535"
+ poly_states = 2
+ poly_colors = list("#808080", "#FF3535")
diff --git a/code/modules/clothing/under/shorts.dm b/code/modules/clothing/under/shorts.dm
index ebf7cb5896..f61a41e4c3 100644
--- a/code/modules/clothing/under/shorts.dm
+++ b/code/modules/clothing/under/shorts.dm
@@ -35,19 +35,18 @@
desc = "95% Polychrome, 5% Spandex!"
icon_state = "polyshortpants"
item_state = "rainbow"
- hasprimary = TRUE
- hassecondary = TRUE
- primary_color = "#FFFFFF"
- secondary_color = "#F08080"
mutantrace_variation = NONE
+ var/list/poly_colors = list("#FFFFFF", "#F08080")
+
+/obj/item/clothing/under/shorts/polychromic/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/polychromic, poly_colors, 2)
/obj/item/clothing/under/shorts/polychromic/pantsu
name = "polychromic panties"
desc = "Topless striped panties. Now with 120% more polychrome!"
icon_state = "polypantsu"
item_state = "rainbow"
- hastertiary = FALSE
- primary_color = "#FFFFFF"
- secondary_color = "#8CC6FF"
body_parts_covered = GROIN
mutantrace_variation = NONE
+ poly_colors = list("#FFFFFF", "#8CC6FF")
diff --git a/code/modules/clothing/under/skirt_dress.dm b/code/modules/clothing/under/skirt_dress.dm
index f00e96d821..fa2c9eed71 100644
--- a/code/modules/clothing/under/skirt_dress.dm
+++ b/code/modules/clothing/under/skirt_dress.dm
@@ -211,21 +211,18 @@
desc = "A fancy skirt made with polychromic threads."
icon_state = "polyskirt"
item_state = "rainbow"
- hasprimary = TRUE
- hassecondary = TRUE
- hastertiary = TRUE
- primary_color = "#FFFFFF"
- secondary_color = "#F08080"
- tertiary_color = "#808080"
mutantrace_variation = NONE
+ var/list/poly_colors = list("#FFFFFF", "#F08080", "#808080")
+
+/obj/item/clothing/under/dress/skirt/polychromic/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/polychromic, poly_colors, 3)
/obj/item/clothing/under/dress/skirt/polychromic/pleated
name = "polychromic pleated skirt"
desc = "A magnificent pleated skirt complements the woolen polychromatic sweater."
icon_state = "polypleat"
item_state = "rainbow"
- primary_color = "#8CC6FF"
- secondary_color = "#808080"
- tertiary_color = "#FF3535"
body_parts_covered = CHEST|GROIN|ARMS
mutantrace_variation = NONE
+ poly_colors = list("#8CC6FF", "#808080", "#FF3535")
diff --git a/code/modules/clothing/under/suits.dm b/code/modules/clothing/under/suits.dm
index 3ee5204c3b..087262dd1e 100644
--- a/code/modules/clothing/under/suits.dm
+++ b/code/modules/clothing/under/suits.dm
@@ -109,11 +109,9 @@
desc = "For when you want to show off your horrible colour coordination skills."
icon_state = "polysuit"
item_state = "sl_suit"
- hasprimary = TRUE
- hassecondary = TRUE
- hastertiary = TRUE
- primary_color = "#FFFFFF"
- secondary_color = "#FFFFFF"
- tertiary_color = "#808080"
can_adjust = FALSE
mutantrace_variation = NONE
+
+/obj/item/clothing/under/suit/polychromic/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/polychromic, list("#FFFFFF", "#FFFFFF", "#808080"), 3)
diff --git a/code/modules/food_and_drinks/pizzabox.dm b/code/modules/food_and_drinks/pizzabox.dm
index b163c6ba97..94c8d7219c 100644
--- a/code/modules/food_and_drinks/pizzabox.dm
+++ b/code/modules/food_and_drinks/pizzabox.dm
@@ -86,8 +86,8 @@
tag_overlay.pixel_y = boxes.len * 3
add_overlay(tag_overlay)
-/obj/item/pizzabox/worn_overlays(isinhands, icon_file, style_flags = NONE)
- . = list()
+/obj/item/pizzabox/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
+ . = ..()
var/current_offset = 2
if(isinhands)
for(var/V in boxes) //add EXTRA BOX per box
diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm
index d3a417b439..30eed6c8f0 100644
--- a/code/modules/mining/equipment/explorer_gear.dm
+++ b/code/modules/mining/equipment/explorer_gear.dm
@@ -117,7 +117,7 @@
glass_overlay.appearance_flags = RESET_COLOR
. += glass_overlay
-/obj/item/clothing/head/helmet/space/hostile_environment/worn_overlays(isinhands, icon_file, style_flags = NONE)
+/obj/item/clothing/head/helmet/space/hostile_environment/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands)
var/mutable_appearance/M = mutable_appearance('icons/mob/clothing/head.dmi', "hostile_env_glass")
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 8b4f282f76..63e772e07c 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -597,7 +597,7 @@ use_mob_overlay_icon: if FALSE, it will always use the default_icon_file even if
//Get the overlays for this item when it's being worn
//eg: ammo counters, primed grenade flashes, etc.
- var/list/worn_overlays = worn_overlays(isinhands, file2use, style_flags)
+ var/list/worn_overlays = worn_overlays(isinhands, file2use, t_state, style_flags)
if(worn_overlays && worn_overlays.len)
standing.overlays.Add(worn_overlays)
diff --git a/code/modules/mob/living/carbon/update_icons.dm b/code/modules/mob/living/carbon/update_icons.dm
index 35350ccb45..a431059a89 100644
--- a/code/modules/mob/living/carbon/update_icons.dm
+++ b/code/modules/mob/living/carbon/update_icons.dm
@@ -191,15 +191,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 3697fe4ff5..07839588ce 100644
Binary files a/icons/mob/actions/backgrounds.dmi and b/icons/mob/actions/backgrounds.dmi differ
diff --git a/icons/mob/clothing/head.dmi b/icons/mob/clothing/head.dmi
index c499c236e3..f2ea9fa55d 100644
Binary files a/icons/mob/clothing/head.dmi and b/icons/mob/clothing/head.dmi differ
diff --git a/icons/mob/clothing/neck.dmi b/icons/mob/clothing/neck.dmi
index de59a136d9..68fde7bff9 100644
Binary files a/icons/mob/clothing/neck.dmi and b/icons/mob/clothing/neck.dmi differ
diff --git a/icons/mob/clothing/suit.dmi b/icons/mob/clothing/suit.dmi
index 195e4ecd67..a2ea222a68 100644
Binary files a/icons/mob/clothing/suit.dmi and b/icons/mob/clothing/suit.dmi differ
diff --git a/icons/mob/clothing/suit_digi.dmi b/icons/mob/clothing/suit_digi.dmi
index 67ad9f7e1a..5287bac43c 100644
Binary files a/icons/mob/clothing/suit_digi.dmi and b/icons/mob/clothing/suit_digi.dmi differ
diff --git a/icons/mob/clothing/uniform.dmi b/icons/mob/clothing/uniform.dmi
index fe0b080dc6..4485a9a5f8 100644
Binary files a/icons/mob/clothing/uniform.dmi and b/icons/mob/clothing/uniform.dmi differ
diff --git a/icons/mob/clothing/uniform_digi.dmi b/icons/mob/clothing/uniform_digi.dmi
index 9deb214335..6827581b85 100644
Binary files a/icons/mob/clothing/uniform_digi.dmi and b/icons/mob/clothing/uniform_digi.dmi differ
diff --git a/icons/obj/clothing/cloaks.dmi b/icons/obj/clothing/cloaks.dmi
index dd1ae7d727..6f4de62cc0 100644
Binary files a/icons/obj/clothing/cloaks.dmi and b/icons/obj/clothing/cloaks.dmi differ
diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi
index 07d9c8cee6..2e0906ea20 100644
Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ
diff --git a/icons/obj/clothing/neck.dmi b/icons/obj/clothing/neck.dmi
index 0bdaa36e62..622f43ea56 100644
Binary files a/icons/obj/clothing/neck.dmi and b/icons/obj/clothing/neck.dmi differ
diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi
index 530cd61e6f..607c26bb62 100644
Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ
diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi
index 55ec7669ba..dfebe38155 100644
Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ
diff --git a/modular_citadel/code/modules/clothing/suits/polychromic_cloaks.dm b/modular_citadel/code/modules/clothing/suits/polychromic_cloaks.dm
deleted file mode 100644
index 5cf2fccb92..0000000000
--- a/modular_citadel/code/modules/clothing/suits/polychromic_cloaks.dm
+++ /dev/null
@@ -1,38 +0,0 @@
-/obj/item/clothing/neck/cloak/polychromic //enables all three overlays to reduce copypasta and defines basic stuff
- name = "polychromic cloak"
- desc = "For when you want to show off your horrible colour coordination skills."
- icon = 'modular_citadel/icons/polyclothes/item/neck.dmi'
- mob_overlay_icon = 'modular_citadel/icons/polyclothes/mob/neck.dmi'
- icon_state = "polyce"
- item_state = "qmcloak"
- hasprimary = TRUE
- hassecondary = TRUE
- hastertiary = TRUE
- primary_color = "#FFFFFF" //RGB in hexcode
- secondary_color = "#FFFFFF"
- tertiary_color = "#808080"
-
-/obj/item/clothing/neck/cloak/polychromic/worn_overlays(isinhands, icon_file, style_flags = NONE) //this is where the main magic happens. Also mandates that ALL polychromic stuff MUST USE mob_overlay_icon
- . = ..()
- if(hasprimary | hassecondary | hastertiary)
- if(!isinhands) //prevents the worn sprites from showing up if you're just holding them
- if(hasprimary) //checks if overlays are enabled
- var/mutable_appearance/primary_worn = mutable_appearance(mob_overlay_icon, "[icon_state]-primary") //automagical sprite selection
- primary_worn.color = primary_color //colors the overlay
- . += primary_worn //adds the overlay onto the buffer list to draw on the mob sprite.
- if(hassecondary)
- var/mutable_appearance/secondary_worn = mutable_appearance(mob_overlay_icon, "[icon_state]-secondary")
- secondary_worn.color = secondary_color
- . += secondary_worn
- if(hastertiary)
- var/mutable_appearance/tertiary_worn = mutable_appearance(mob_overlay_icon, "[icon_state]-tertiary")
- tertiary_worn.color = tertiary_color
- . += tertiary_worn
-
-/obj/item/clothing/neck/cloak/polychromic/polyce //DONATOR ITEM
- name = "polychromic embroidered cloak"
- desc = "A fancy cloak embroidered with polychromatic thread in a pattern that reminds one of the wielders of unlimited power."
- icon_state = "polyce"
- primary_color = "#808080" //RGB in hexcode
- secondary_color = "#8CC6FF"
- tertiary_color = "#FF3535"
\ No newline at end of file
diff --git a/modular_citadel/code/modules/custom_loadout/custom_items.dm b/modular_citadel/code/modules/custom_loadout/custom_items.dm
index a9b502d629..bd377d6081 100644
--- a/modular_citadel/code/modules/custom_loadout/custom_items.dm
+++ b/modular_citadel/code/modules/custom_loadout/custom_items.dm
@@ -563,3 +563,8 @@
unique_reskin = list("Goodboye" = "fritz", "Badboye" = "fritz_bad")
mutantrace_variation = NONE
+/obj/item/clothing/neck/cloak/polychromic/polyce
+ name = "polychromic embroidered cloak"
+ desc = "A fancy cloak embroidered with polychromatic thread in a pattern that reminds one of the wielders of unlimited power."
+ icon_state = "polyce"
+ poly_colors = list("#808080", "#8CC6FF", "#FF3535")
diff --git a/modular_citadel/code/modules/projectiles/guns/energy/energy_gun.dm b/modular_citadel/code/modules/projectiles/guns/energy/energy_gun.dm
index 49a8a26f35..49d48e0000 100644
--- a/modular_citadel/code/modules/projectiles/guns/energy/energy_gun.dm
+++ b/modular_citadel/code/modules/projectiles/guns/energy/energy_gun.dm
@@ -39,7 +39,7 @@ obj/item/gun/energy/e_gun/cx/AltClick(mob/living/user)
body_color = sanitize_hexcolor(body_color_input, desired_format=6, include_crunch=1)
update_icon()
-obj/item/gun/energy/e_gun/cx/worn_overlays(isinhands, icon_file, style_flags = NONE)
+obj/item/gun/energy/e_gun/cx/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
. = ..()
if(isinhands)
var/mutable_appearance/body_inhand = mutable_appearance(icon_file, "cxe_body")
diff --git a/modular_citadel/code/modules/projectiles/guns/pumpenergy.dm b/modular_citadel/code/modules/projectiles/guns/pumpenergy.dm
index 05b5c195c2..a4b6429bea 100644
--- a/modular_citadel/code/modules/projectiles/guns/pumpenergy.dm
+++ b/modular_citadel/code/modules/projectiles/guns/pumpenergy.dm
@@ -87,7 +87,7 @@
. = ..()
. += "Alt-click to change firing modes."
-/obj/item/gun/energy/pumpaction/worn_overlays(isinhands, icon_file, style_flags = NONE) //ammo counter for inhands
+/obj/item/gun/energy/pumpaction/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE) //ammo counter for inhands
. = ..()
var/ratio = CEILING((cell.charge / cell.maxcharge) * charge_sections, 1)
var/obj/item/ammo_casing/energy/shot = ammo_type[current_firemode_index]
diff --git a/modular_citadel/icons/polyclothes/item/neck.dmi b/modular_citadel/icons/polyclothes/item/neck.dmi
deleted file mode 100644
index e2792cf9d0..0000000000
Binary files a/modular_citadel/icons/polyclothes/item/neck.dmi and /dev/null differ
diff --git a/modular_citadel/icons/polyclothes/mob/neck.dmi b/modular_citadel/icons/polyclothes/mob/neck.dmi
deleted file mode 100644
index 529c64caa2..0000000000
Binary files a/modular_citadel/icons/polyclothes/mob/neck.dmi and /dev/null differ
diff --git a/tgstation.dme b/tgstation.dme
old mode 100644
new mode 100755
index 7d7dcea52f..5d0ca735bc
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -510,6 +510,7 @@
#include "code\datums\elements\flavor_text.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\spellcasting.dm"
#include "code\datums\elements\swimming.dm"
#include "code\datums\elements\sword_point.dm"
@@ -3290,7 +3291,6 @@
#include "modular_citadel\code\modules\client\verbs\who.dm"
#include "modular_citadel\code\modules\clothing\neck.dm"
#include "modular_citadel\code\modules\clothing\trek.dm"
-#include "modular_citadel\code\modules\clothing\suits\polychromic_cloaks.dm"
#include "modular_citadel\code\modules\clothing\suits\suits.dm"
#include "modular_citadel\code\modules\custom_loadout\custom_items.dm"
#include "modular_citadel\code\modules\custom_loadout\load_to_mob.dm"