mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-10 01:49:19 +00:00
822 lines
31 KiB
Plaintext
822 lines
31 KiB
Plaintext
///////////////////////
|
|
//UPDATE_ICONS SYSTEM//
|
|
///////////////////////
|
|
/* Keep these comments up-to-date if you -insist- on hurting my code-baby ;_;
|
|
This system allows you to update individual mob-overlays, without regenerating them all each time.
|
|
When we generate overlays we generate the standing version and then rotate the mob as necessary..
|
|
|
|
As of the time of writing there are 20 layers within this list. Please try to keep this from increasing. //32 and counting, good job guys
|
|
var/overlays_standing[20] //For the standing stance
|
|
|
|
Most of the time we only wish to update one overlay:
|
|
e.g. - we dropped the fireaxe out of our left hand and need to remove its icon from our mob
|
|
e.g.2 - our hair colour has changed, so we need to update our hair icons on our mob
|
|
In these cases, instead of updating every overlay using the old behaviour (regenerate_icons), we instead call
|
|
the appropriate update_X proc.
|
|
e.g. - update_l_hand()
|
|
e.g.2 - update_hair()
|
|
|
|
Note: Recent changes by aranclanos+carn:
|
|
update_icons() no longer needs to be called.
|
|
the system is easier to use. update_icons() should not be called unless you absolutely -know- you need it.
|
|
IN ALL OTHER CASES it's better to just call the specific update_X procs.
|
|
|
|
Note: The defines for layer numbers is now kept exclusvely in __DEFINES/misc.dm instead of being defined there,
|
|
then redefined and undefiend everywhere else. If you need to change the layering of sprites (or add a new layer)
|
|
that's where you should start.
|
|
|
|
All of this means that this code is more maintainable, faster and still fairly easy to use.
|
|
|
|
There are several things that need to be remembered:
|
|
> Whenever we do something that should cause an overlay to update (which doesn't use standard procs
|
|
( i.e. you do something like l_hand = /obj/item/something new(src), rather than using the helper procs)
|
|
You will need to call the relevant update_inv_* proc
|
|
|
|
All of these are named after the variable they update from. They are defined at the mob/ level like
|
|
update_clothing was, so you won't cause undefined proc runtimes with usr.update_inv_wear_id() if the usr is a
|
|
slime etc. Instead, it'll just return without doing any work. So no harm in calling it for slimes and such.
|
|
|
|
|
|
> There are also these special cases:
|
|
update_damage_overlays() //handles damage overlays for brute/burn damage
|
|
update_body() //Handles updating your mob's body layer and mutant bodyparts
|
|
as well as sprite-accessories that didn't really fit elsewhere (underwear, undershirts, socks, lips, eyes)
|
|
//NOTE: update_mutantrace() is now merged into this!
|
|
update_hair() //Handles updating your hair overlay (used to be update_face, but mouth and
|
|
eyes were merged into update_body())
|
|
|
|
|
|
*/
|
|
|
|
/mob/living/carbon/human/ComponentInitialize()
|
|
. = ..()
|
|
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_HUMAN_NO_RENDER), /mob.proc/regenerate_icons)
|
|
|
|
//HAIR OVERLAY
|
|
/mob/living/carbon/human/update_hair()
|
|
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
|
|
dna.species.handle_hair(src)
|
|
|
|
//used when putting/removing clothes that hide certain mutant body parts to just update those and not update the whole body.
|
|
/mob/living/carbon/human/proc/update_mutant_bodyparts()
|
|
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
|
|
dna.species.handle_mutant_bodyparts(src)
|
|
|
|
/mob/living/carbon/human/update_body(update_genitals = FALSE)
|
|
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
|
|
remove_overlay(BODY_LAYER)
|
|
dna.species.handle_body(src)
|
|
..()
|
|
if(update_genitals)
|
|
update_genitals()
|
|
|
|
/mob/living/carbon/human/update_fire()
|
|
..((fire_stacks > 3) ? "Standing" : "Generic_mob_burning")
|
|
|
|
/* --------------------------------------- */
|
|
//For legacy support.
|
|
/mob/living/carbon/human/regenerate_icons()
|
|
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
|
|
if(!..())
|
|
icon_render_key = null //invalidate bodyparts cache
|
|
update_body(TRUE)
|
|
update_hair()
|
|
update_inv_w_uniform()
|
|
update_inv_wear_id()
|
|
update_inv_gloves()
|
|
update_inv_glasses()
|
|
update_inv_ears()
|
|
update_inv_shoes()
|
|
update_inv_s_store()
|
|
update_inv_wear_mask()
|
|
update_inv_head()
|
|
update_inv_belt()
|
|
update_inv_back()
|
|
update_inv_wear_suit()
|
|
update_inv_pockets()
|
|
update_inv_neck()
|
|
update_transform()
|
|
//mutations
|
|
update_mutations_overlay()
|
|
//damage overlays
|
|
update_damage_overlays()
|
|
//antagonism
|
|
update_antag_overlays()
|
|
|
|
/* --------------------------------------- */
|
|
//vvvvvv UPDATE_INV PROCS vvvvvv
|
|
|
|
|
|
/mob/living/carbon/human/update_antag_overlays()
|
|
remove_overlay(ANTAG_LAYER)
|
|
var/datum/antagonist/cult/D = src?.mind?.has_antag_datum(/datum/antagonist/cult) //check for cultism
|
|
if(D && D.cult_team?.cult_ascendent == TRUE)
|
|
var/istate = pick("halo1","halo2","halo3","halo4","halo5","halo6")
|
|
var/mutable_appearance/new_cult_overlay = mutable_appearance('icons/effects/32x64.dmi', istate, -ANTAG_LAYER)
|
|
overlays_standing[ANTAG_LAYER] = new_cult_overlay
|
|
var/datum/antagonist/clockcult/C = src?.mind?.has_antag_datum(/datum/antagonist/clockcult) //check for clockcultism - surely one can't be both cult and clockie, right?
|
|
if(C)
|
|
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
|
|
if(G && G.active && ishuman(src))
|
|
var/mutable_appearance/new_cult_overlay = mutable_appearance('icons/effects/genetics.dmi', "servitude", -ANTAG_LAYER)
|
|
overlays_standing[ANTAG_LAYER] = new_cult_overlay
|
|
apply_overlay(ANTAG_LAYER)
|
|
|
|
|
|
/mob/living/carbon/human/update_inv_w_uniform()
|
|
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
|
|
remove_overlay(UNIFORM_LAYER)
|
|
|
|
if(client && hud_used)
|
|
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_ICLOTHING) + 1]
|
|
inv.update_icon()
|
|
|
|
if(istype(w_uniform, /obj/item/clothing/under))
|
|
var/obj/item/clothing/under/U = w_uniform
|
|
U.screen_loc = ui_iclothing
|
|
if(client && hud_used && hud_used.hud_shown)
|
|
if(hud_used.inventory_shown)
|
|
client.screen += w_uniform
|
|
update_observer_view(w_uniform,1)
|
|
|
|
if(wear_suit && (wear_suit.flags_inv & HIDEJUMPSUIT))
|
|
return
|
|
|
|
|
|
var/target_overlay = U.icon_state
|
|
if(U.adjusted == ALT_STYLE)
|
|
target_overlay = "[target_overlay]_d"
|
|
|
|
var/alt_worn = U.mob_overlay_icon || 'icons/mob/clothing/uniform.dmi'
|
|
var/variant_flag = NONE
|
|
|
|
if((DIGITIGRADE in dna.species.species_traits) && U.mutantrace_variation & STYLE_DIGITIGRADE && !(U.mutantrace_variation & STYLE_NO_ANTHRO_ICON))
|
|
alt_worn = U.anthro_mob_worn_overlay || 'icons/mob/clothing/uniform_digi.dmi'
|
|
variant_flag |= STYLE_DIGITIGRADE
|
|
|
|
var/mask
|
|
if(dna.species.mutant_bodyparts["taur"])
|
|
var/datum/sprite_accessory/taur/T = GLOB.taur_list[dna.features["taur"]]
|
|
var/clip_flag = U.mutantrace_variation & T?.hide_legs
|
|
if(clip_flag)
|
|
variant_flag |= clip_flag
|
|
mask = T.alpha_mask_state
|
|
|
|
var/mutable_appearance/uniform_overlay
|
|
|
|
var/gendered = (dna?.species.sexes && dna.features["body_model"] == FEMALE) ? U.fitted : NO_FEMALE_UNIFORM
|
|
uniform_overlay = U.build_worn_icon( UNIFORM_LAYER, alt_worn, FALSE, gendered, target_overlay, variant_flag, FALSE, mask)
|
|
|
|
if(OFFSET_UNIFORM in dna.species.offset_features)
|
|
uniform_overlay.pixel_x += dna.species.offset_features[OFFSET_UNIFORM][1]
|
|
uniform_overlay.pixel_y += dna.species.offset_features[OFFSET_UNIFORM][2]
|
|
overlays_standing[UNIFORM_LAYER] = uniform_overlay
|
|
|
|
apply_overlay(UNIFORM_LAYER)
|
|
update_mutant_bodyparts()
|
|
|
|
/mob/living/carbon/human/update_inv_wear_id()
|
|
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
|
|
remove_overlay(ID_LAYER)
|
|
|
|
if(client && hud_used)
|
|
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_ID) + 1]
|
|
inv.update_icon()
|
|
|
|
var/mutable_appearance/id_overlay = overlays_standing[ID_LAYER]
|
|
|
|
if(wear_id)
|
|
wear_id.screen_loc = ui_id
|
|
if(client && hud_used && hud_used.hud_shown)
|
|
client.screen += wear_id
|
|
update_observer_view(wear_id)
|
|
|
|
//TODO: add an icon file for ID slot stuff, so it's less snowflakey
|
|
id_overlay = wear_id.build_worn_icon(default_layer = ID_LAYER, default_icon_file = 'icons/mob/mob.dmi', override_state = wear_id.item_state)
|
|
if(OFFSET_ID in dna.species.offset_features)
|
|
id_overlay.pixel_x += dna.species.offset_features[OFFSET_ID][1]
|
|
id_overlay.pixel_y += dna.species.offset_features[OFFSET_ID][2]
|
|
overlays_standing[ID_LAYER] = id_overlay
|
|
apply_overlay(ID_LAYER)
|
|
|
|
|
|
/mob/living/carbon/human/update_inv_gloves()
|
|
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
|
|
remove_overlay(GLOVES_LAYER)
|
|
|
|
if(client && hud_used && hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_GLOVES) + 1])
|
|
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_GLOVES) + 1]
|
|
inv.update_icon()
|
|
|
|
if(!gloves && bloody_hands)
|
|
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER, color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend())
|
|
if(get_num_arms(FALSE) < 2)
|
|
if(has_left_hand(FALSE))
|
|
bloody_overlay.icon_state = "bloodyhands_left"
|
|
else if(has_right_hand(FALSE))
|
|
bloody_overlay.icon_state = "bloodyhands_right"
|
|
|
|
overlays_standing[GLOVES_LAYER] = bloody_overlay
|
|
|
|
var/mutable_appearance/gloves_overlay = overlays_standing[GLOVES_LAYER]
|
|
if(gloves)
|
|
gloves.screen_loc = ui_gloves
|
|
if(client && hud_used && hud_used.hud_shown)
|
|
if(hud_used.inventory_shown)
|
|
client.screen += gloves
|
|
update_observer_view(gloves,1)
|
|
overlays_standing[GLOVES_LAYER] = gloves.build_worn_icon(default_layer = GLOVES_LAYER, default_icon_file = 'icons/mob/clothing/hands.dmi')
|
|
gloves_overlay = overlays_standing[GLOVES_LAYER]
|
|
if(OFFSET_GLOVES in dna.species.offset_features)
|
|
gloves_overlay.pixel_x += dna.species.offset_features[OFFSET_GLOVES][1]
|
|
gloves_overlay.pixel_y += dna.species.offset_features[OFFSET_GLOVES][2]
|
|
overlays_standing[GLOVES_LAYER] = gloves_overlay
|
|
apply_overlay(GLOVES_LAYER)
|
|
|
|
|
|
/mob/living/carbon/human/update_inv_glasses()
|
|
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
|
|
remove_overlay(GLASSES_LAYER)
|
|
|
|
if(!get_bodypart(BODY_ZONE_HEAD)) //decapitated
|
|
return
|
|
|
|
if(client && hud_used)
|
|
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_EYES) + 1]
|
|
inv.update_icon()
|
|
|
|
if(glasses)
|
|
glasses.screen_loc = ui_glasses //...draw the item in the inventory screen
|
|
if(client && hud_used && hud_used.hud_shown)
|
|
if(hud_used.inventory_shown) //if the inventory is open ...
|
|
client.screen += glasses //Either way, add the item to the HUD
|
|
update_observer_view(glasses,1)
|
|
if(!(head && (head.flags_inv & HIDEEYES)) && !(wear_mask && (wear_mask.flags_inv & HIDEEYES)))
|
|
overlays_standing[GLASSES_LAYER] = glasses.build_worn_icon(default_layer = GLASSES_LAYER, default_icon_file = 'icons/mob/clothing/eyes.dmi', override_state = glasses.icon_state)
|
|
var/mutable_appearance/glasses_overlay = overlays_standing[GLASSES_LAYER]
|
|
if(glasses_overlay)
|
|
if(OFFSET_GLASSES in dna.species.offset_features)
|
|
glasses_overlay.pixel_x += dna.species.offset_features[OFFSET_GLASSES][1]
|
|
glasses_overlay.pixel_y += dna.species.offset_features[OFFSET_GLASSES][2]
|
|
overlays_standing[GLASSES_LAYER] = glasses_overlay
|
|
apply_overlay(GLASSES_LAYER)
|
|
|
|
/mob/living/carbon/human/update_inv_ears()
|
|
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
|
|
remove_overlay(EARS_LAYER)
|
|
|
|
if(!get_bodypart(BODY_ZONE_HEAD)) //decapitated
|
|
return
|
|
|
|
if(client && hud_used)
|
|
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_EARS) + 1]
|
|
inv.update_icon()
|
|
|
|
if(ears)
|
|
ears.screen_loc = ui_ears //move the item to the appropriate screen loc
|
|
if(client && hud_used && hud_used.hud_shown)
|
|
if(hud_used.inventory_shown) //if the inventory is open
|
|
client.screen += ears //add it to the client's screen
|
|
update_observer_view(ears,1)
|
|
|
|
overlays_standing[EARS_LAYER] = ears.build_worn_icon(default_layer = EARS_LAYER, default_icon_file = 'icons/mob/ears.dmi')
|
|
var/mutable_appearance/ears_overlay = overlays_standing[EARS_LAYER]
|
|
if(OFFSET_EARS in dna.species.offset_features)
|
|
ears_overlay.pixel_x += dna.species.offset_features[OFFSET_EARS][1]
|
|
ears_overlay.pixel_y += dna.species.offset_features[OFFSET_EARS][2]
|
|
overlays_standing[EARS_LAYER] = ears_overlay
|
|
apply_overlay(EARS_LAYER)
|
|
|
|
/mob/living/carbon/human/update_inv_shoes()
|
|
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
|
|
remove_overlay(SHOES_LAYER)
|
|
|
|
if(get_num_legs(FALSE) <2)
|
|
return
|
|
|
|
if(client && hud_used)
|
|
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_FEET) + 1]
|
|
inv.update_icon()
|
|
|
|
if(dna.species.mutant_bodyparts["taur"])
|
|
var/datum/sprite_accessory/taur/T = GLOB.taur_list[dna.features["taur"]]
|
|
if(T?.hide_legs) //If only they actually made shoes unwearable. Please don't making cosmetics, guys.
|
|
return
|
|
|
|
if(shoes)
|
|
var/obj/item/clothing/shoes/S = shoes
|
|
shoes.screen_loc = ui_shoes //move the item to the appropriate screen loc
|
|
if(client && hud_used && hud_used.hud_shown)
|
|
if(hud_used.inventory_shown) //if the inventory is open
|
|
client.screen += shoes //add it to client's screen
|
|
update_observer_view(shoes,1)
|
|
|
|
var/alt_icon = S.mob_overlay_icon || 'icons/mob/clothing/feet.dmi'
|
|
var/variation_flag = NONE
|
|
if((DIGITIGRADE in dna.species.species_traits) && S.mutantrace_variation & STYLE_DIGITIGRADE && !(S.mutantrace_variation & STYLE_NO_ANTHRO_ICON))
|
|
alt_icon = S.anthro_mob_worn_overlay || 'icons/mob/clothing/feet_digi.dmi'
|
|
variation_flag |= STYLE_DIGITIGRADE
|
|
|
|
overlays_standing[SHOES_LAYER] = shoes.build_worn_icon(SHOES_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, S.icon_state, variation_flag, FALSE)
|
|
var/mutable_appearance/shoes_overlay = overlays_standing[SHOES_LAYER]
|
|
if(OFFSET_SHOES in dna.species.offset_features)
|
|
shoes_overlay.pixel_x += dna.species.offset_features[OFFSET_SHOES][1]
|
|
shoes_overlay.pixel_y += dna.species.offset_features[OFFSET_SHOES][2]
|
|
overlays_standing[SHOES_LAYER] = shoes_overlay
|
|
apply_overlay(SHOES_LAYER)
|
|
|
|
/mob/living/carbon/human/update_inv_s_store()
|
|
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
|
|
remove_overlay(SUIT_STORE_LAYER)
|
|
|
|
if(client && hud_used)
|
|
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_SUITSTORE) + 1]
|
|
inv.update_icon()
|
|
|
|
if(s_store)
|
|
s_store.screen_loc = ui_sstore1
|
|
if(client && hud_used && hud_used.hud_shown)
|
|
client.screen += s_store
|
|
update_observer_view(s_store)
|
|
var/t_state = s_store.item_state
|
|
if(!t_state)
|
|
t_state = s_store.icon_state
|
|
overlays_standing[SUIT_STORE_LAYER] = mutable_appearance(((s_store.mob_overlay_icon) ? s_store.mob_overlay_icon : 'icons/mob/clothing/belt_mirror.dmi'), t_state, -SUIT_STORE_LAYER)
|
|
var/mutable_appearance/s_store_overlay = overlays_standing[SUIT_STORE_LAYER]
|
|
if(OFFSET_S_STORE in dna.species.offset_features)
|
|
s_store_overlay.pixel_x += dna.species.offset_features[OFFSET_S_STORE][1]
|
|
s_store_overlay.pixel_y += dna.species.offset_features[OFFSET_S_STORE][2]
|
|
overlays_standing[SUIT_STORE_LAYER] = s_store_overlay
|
|
apply_overlay(SUIT_STORE_LAYER)
|
|
|
|
/mob/living/carbon/human/update_inv_head()
|
|
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
|
|
remove_overlay(HEAD_LAYER)
|
|
|
|
if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
|
|
return
|
|
|
|
if(client && hud_used)
|
|
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_HEAD) + 1]
|
|
inv.update_icon()
|
|
|
|
if(head)
|
|
head.screen_loc = ui_head
|
|
if(client && hud_used && hud_used.hud_shown)
|
|
if(hud_used.inventory_shown)
|
|
client.screen += head
|
|
update_observer_view(head,1)
|
|
remove_overlay(HEAD_LAYER)
|
|
var/obj/item/clothing/head/H = head
|
|
var/alt_icon = H.mob_overlay_icon || 'icons/mob/clothing/head.dmi'
|
|
var/muzzled = FALSE
|
|
var/variation_flag = NONE
|
|
if(dna.species.mutant_bodyparts["mam_snouts"] && dna.features["mam_snouts"] != "None")
|
|
muzzled = TRUE
|
|
else if(dna.species.mutant_bodyparts["snout"] && dna.features["snout"] != "None")
|
|
muzzled = TRUE
|
|
if(muzzled && H.mutantrace_variation & STYLE_MUZZLE && !(H.mutantrace_variation & STYLE_NO_ANTHRO_ICON))
|
|
alt_icon = H.anthro_mob_worn_overlay || 'icons/mob/clothing/head_muzzled.dmi'
|
|
variation_flag |= STYLE_MUZZLE
|
|
|
|
overlays_standing[HEAD_LAYER] = H.build_worn_icon(HEAD_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, H.icon_state, variation_flag, FALSE)
|
|
var/mutable_appearance/head_overlay = overlays_standing[HEAD_LAYER]
|
|
|
|
if(OFFSET_HEAD in dna.species.offset_features)
|
|
head_overlay.pixel_x += dna.species.offset_features[OFFSET_HEAD][1]
|
|
head_overlay.pixel_y += dna.species.offset_features[OFFSET_HEAD][2]
|
|
overlays_standing[HEAD_LAYER] = head_overlay
|
|
apply_overlay(HEAD_LAYER)
|
|
update_mutant_bodyparts()
|
|
|
|
/mob/living/carbon/human/update_inv_belt()
|
|
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
|
|
remove_overlay(BELT_LAYER)
|
|
|
|
if(client && hud_used)
|
|
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_BELT) + 1]
|
|
inv.update_icon()
|
|
|
|
if(belt)
|
|
belt.screen_loc = ui_belt
|
|
if(client && hud_used && hud_used.hud_shown)
|
|
client.screen += belt
|
|
update_observer_view(belt)
|
|
|
|
overlays_standing[BELT_LAYER] = belt.build_worn_icon(default_layer = BELT_LAYER, default_icon_file = 'icons/mob/clothing/belt.dmi')
|
|
var/mutable_appearance/belt_overlay = overlays_standing[BELT_LAYER]
|
|
if(OFFSET_BELT in dna.species.offset_features)
|
|
belt_overlay.pixel_x += dna.species.offset_features[OFFSET_BELT][1]
|
|
belt_overlay.pixel_y += dna.species.offset_features[OFFSET_BELT][2]
|
|
overlays_standing[BELT_LAYER] = belt_overlay
|
|
apply_overlay(BELT_LAYER)
|
|
|
|
/mob/living/carbon/human/update_inv_wear_suit()
|
|
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
|
|
remove_overlay(SUIT_LAYER)
|
|
|
|
if(client && hud_used)
|
|
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_OCLOTHING) + 1]
|
|
inv.update_icon()
|
|
|
|
if(wear_suit)
|
|
var/obj/item/clothing/suit/S = wear_suit
|
|
wear_suit.screen_loc = ui_oclothing
|
|
if(client && hud_used && hud_used.hud_shown)
|
|
if(hud_used.inventory_shown)
|
|
client.screen += wear_suit
|
|
update_observer_view(wear_suit,1)
|
|
|
|
var/worn_icon = wear_suit.mob_overlay_icon || 'icons/mob/clothing/suit.dmi'
|
|
var/worn_state = wear_suit.icon_state
|
|
var/center = FALSE
|
|
var/dimension_x = 32
|
|
var/dimension_y = 32
|
|
var/variation_flag = NONE
|
|
var/datum/sprite_accessory/taur/T
|
|
if(dna.species.mutant_bodyparts["taur"])
|
|
T = GLOB.taur_list[dna.features["taur"]]
|
|
|
|
if(S.mutantrace_variation)
|
|
|
|
if(T?.taur_mode)
|
|
var/init_worn_icon = worn_icon
|
|
variation_flag |= S.mutantrace_variation & T.taur_mode || S.mutantrace_variation & T.alt_taur_mode
|
|
switch(variation_flag)
|
|
if(STYLE_HOOF_TAURIC)
|
|
worn_icon = 'icons/mob/clothing/taur_hooved.dmi'
|
|
if(STYLE_SNEK_TAURIC)
|
|
worn_icon = 'icons/mob/clothing/taur_naga.dmi'
|
|
if(STYLE_PAW_TAURIC)
|
|
worn_icon = 'icons/mob/clothing/taur_canine.dmi'
|
|
if(worn_icon != init_worn_icon) //worn icon sprite was changed, taur offsets will have to be applied.
|
|
if(S.taur_mob_worn_overlay) //not going to make several new variables for all taur types. Nope.
|
|
var/static/list/icon_to_state = list('icons/mob/clothing/taur_hooved.dmi' = "_hooved", 'icons/mob/clothing/taur_naga.dmi' = "_naga", 'icons/mob/clothing/taur_canine.dmi' = "_paws")
|
|
worn_state += icon_to_state[worn_icon]
|
|
worn_icon = S.taur_mob_worn_overlay
|
|
center = T.center
|
|
dimension_x = T.dimension_x
|
|
dimension_y = T.dimension_y
|
|
|
|
else if((DIGITIGRADE in dna.species.species_traits) && S.mutantrace_variation & STYLE_DIGITIGRADE && !(S.mutantrace_variation & STYLE_NO_ANTHRO_ICON)) //not a taur, but digitigrade legs.
|
|
worn_icon = S.anthro_mob_worn_overlay || 'icons/mob/clothing/suit_digi.dmi'
|
|
variation_flag |= STYLE_DIGITIGRADE
|
|
|
|
overlays_standing[SUIT_LAYER] = S.build_worn_icon(SUIT_LAYER, worn_icon, FALSE, NO_FEMALE_UNIFORM, worn_state, variation_flag, FALSE)
|
|
var/mutable_appearance/suit_overlay = overlays_standing[SUIT_LAYER]
|
|
if(OFFSET_SUIT in dna.species.offset_features)
|
|
suit_overlay.pixel_x += dna.species.offset_features[OFFSET_SUIT][1]
|
|
suit_overlay.pixel_y += dna.species.offset_features[OFFSET_SUIT][2]
|
|
if(center)
|
|
suit_overlay = center_image(suit_overlay, dimension_x, dimension_y)
|
|
overlays_standing[SUIT_LAYER] = suit_overlay
|
|
update_hair()
|
|
update_mutant_bodyparts()
|
|
|
|
apply_overlay(SUIT_LAYER)
|
|
|
|
/mob/living/carbon/human/update_inv_pockets()
|
|
if(client && hud_used)
|
|
var/atom/movable/screen/inventory/inv
|
|
|
|
inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_LPOCKET) + 1]
|
|
inv.update_icon()
|
|
|
|
inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_RPOCKET) + 1]
|
|
inv.update_icon()
|
|
|
|
if(l_store)
|
|
l_store.screen_loc = ui_storage1
|
|
if(hud_used.hud_shown)
|
|
client.screen += l_store
|
|
update_observer_view(l_store)
|
|
|
|
if(r_store)
|
|
r_store.screen_loc = ui_storage2
|
|
if(hud_used.hud_shown)
|
|
client.screen += r_store
|
|
update_observer_view(r_store)
|
|
|
|
|
|
/mob/living/carbon/human/update_inv_wear_mask()
|
|
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
|
|
remove_overlay(FACEMASK_LAYER)
|
|
|
|
if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
|
|
return
|
|
|
|
if(client && hud_used)
|
|
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_MASK) + 1]
|
|
inv.update_icon()
|
|
|
|
if(wear_mask)
|
|
wear_mask.screen_loc = ui_mask
|
|
if(client && hud_used && hud_used.hud_shown)
|
|
if(hud_used.inventory_shown)
|
|
client.screen += wear_mask
|
|
update_observer_view(wear_mask,1)
|
|
var/obj/item/clothing/mask/M = wear_mask
|
|
remove_overlay(FACEMASK_LAYER)
|
|
var/alt_icon = M.mob_overlay_icon || 'icons/mob/clothing/mask.dmi'
|
|
var/muzzled = FALSE
|
|
var/variation_flag = NONE
|
|
if(head && (head.flags_inv & HIDEMASK))
|
|
return
|
|
if(dna.species.mutant_bodyparts["mam_snouts"] && dna.features["mam_snouts"] != "None")
|
|
muzzled = TRUE
|
|
else if(dna.species.mutant_bodyparts["snout"] && dna.features["snout"] != "None")
|
|
muzzled = TRUE
|
|
if(muzzled && M.mutantrace_variation & STYLE_MUZZLE && !(M.mutantrace_variation & STYLE_NO_ANTHRO_ICON))
|
|
alt_icon = M.anthro_mob_worn_overlay || 'icons/mob/clothing/mask_muzzled.dmi'
|
|
variation_flag |= STYLE_MUZZLE
|
|
|
|
var/mutable_appearance/mask_overlay = M.build_worn_icon(FACEMASK_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, wear_mask.icon_state, variation_flag, FALSE)
|
|
|
|
if(OFFSET_FACEMASK in dna.species.offset_features)
|
|
mask_overlay.pixel_x += dna.species.offset_features[OFFSET_FACEMASK][1]
|
|
mask_overlay.pixel_y += dna.species.offset_features[OFFSET_FACEMASK][2]
|
|
overlays_standing[FACEMASK_LAYER] = mask_overlay
|
|
apply_overlay(FACEMASK_LAYER)
|
|
update_mutant_bodyparts() //e.g. upgate needed because mask now hides lizard snout
|
|
|
|
/mob/living/carbon/human/update_inv_back()
|
|
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
|
|
..()
|
|
var/mutable_appearance/back_overlay = overlays_standing[BACK_LAYER]
|
|
if(back_overlay)
|
|
remove_overlay(BACK_LAYER)
|
|
if(OFFSET_BACK in dna.species.offset_features)
|
|
back_overlay.pixel_x += dna.species.offset_features[OFFSET_BACK][1]
|
|
back_overlay.pixel_y += dna.species.offset_features[OFFSET_BACK][2]
|
|
overlays_standing[BACK_LAYER] = back_overlay
|
|
apply_overlay(BACK_LAYER)
|
|
|
|
/proc/wear_alpha_masked_version(state, icon, layer, female, alpha_mask)
|
|
var/mask = "-[alpha_mask]"
|
|
if(islist(alpha_mask))
|
|
mask = "-"
|
|
for(var/t in alpha_mask)
|
|
mask += t
|
|
var/index = "[state]-[icon]-[female][mask]"
|
|
. = GLOB.alpha_masked_worn_icons[index]
|
|
if(!.) //Create standing/laying icons if they don't exist
|
|
. = generate_alpha_masked_clothing(index,state,icon,female,alpha_mask)
|
|
return mutable_appearance(., layer = -layer)
|
|
|
|
/mob/living/carbon/human/proc/get_overlays_copy(list/unwantedLayers)
|
|
var/list/out = new
|
|
for(var/i in 1 to TOTAL_LAYERS)
|
|
if(overlays_standing[i])
|
|
if(i in unwantedLayers)
|
|
continue
|
|
out += overlays_standing[i]
|
|
return out
|
|
|
|
//human HUD updates for items in our inventory
|
|
|
|
//update whether our neck item appears on our hud.
|
|
/mob/living/carbon/human/update_hud_neck(obj/item/I)
|
|
I.screen_loc = ui_neck
|
|
if(client && hud_used && hud_used.hud_shown)
|
|
if(hud_used.inventory_shown)
|
|
client.screen += I
|
|
update_observer_view(I,1)
|
|
|
|
//update whether our back item appears on our hud.
|
|
/mob/living/carbon/human/update_hud_back(obj/item/I)
|
|
I.screen_loc = ui_back
|
|
if(client && hud_used && hud_used.hud_shown)
|
|
client.screen += I
|
|
update_observer_view(I)
|
|
|
|
|
|
|
|
|
|
/*
|
|
Does everything in relation to building the /mutable_appearance used in the mob's overlays list
|
|
covers:
|
|
inhands and any other form of worn item
|
|
centering large appearances
|
|
layering appearances on custom layers
|
|
building appearances from custom icon files
|
|
|
|
By Remie Richards (yes I'm taking credit because this just removed 90% of the copypaste in update_icons())
|
|
|
|
override_state: A string to use as the state, otherwise item_state or icon_state will be used.
|
|
|
|
default_layer: The layer to draw this on if no other layer is specified
|
|
|
|
default_icon_file: The icon file to draw states from if no other icon file is specified
|
|
|
|
isinhands: If true then mob_overlay_icon is skipped so that default_icon_file is used,
|
|
in this situation default_icon_file is expected to match either the lefthand_ or righthand_ file var
|
|
|
|
femalueuniform: A value matching a uniform item's fitted var, if this is anything but NO_FEMALE_UNIFORM, we
|
|
generate/load female uniform sprites matching all previously decided variables
|
|
|
|
style_flags: mutant race appearance flags, mostly used for worn_overlays()
|
|
|
|
alpha_mask: a text string or list of text, the actual icons are stored in a global list and associated with said text string(s).
|
|
|
|
use_mob_overlay_icon: if FALSE, it will always use the default_icon_file even if mob_overlay_icon is present.
|
|
|
|
*/
|
|
/obj/item/proc/build_worn_icon(default_layer = 0, default_icon_file = null, isinhands = FALSE, femaleuniform = NO_FEMALE_UNIFORM, override_state, style_flags = NONE, use_mob_overlay_icon = TRUE, alpha_mask)
|
|
|
|
var/t_state
|
|
t_state = override_state || item_state || icon_state
|
|
|
|
//Find a valid icon file from variables+arguments
|
|
var/file2use
|
|
if(!isinhands && mob_overlay_icon && use_mob_overlay_icon)
|
|
file2use = mob_overlay_icon
|
|
if(!file2use)
|
|
file2use = default_icon_file
|
|
|
|
//Find a valid layer from variables+arguments
|
|
var/layer2use
|
|
if(alternate_worn_layer)
|
|
layer2use = alternate_worn_layer
|
|
if(!layer2use)
|
|
layer2use = default_layer
|
|
|
|
var/mutable_appearance/standing
|
|
if(femaleuniform || alpha_mask)
|
|
standing = wear_alpha_masked_version(t_state, file2use, layer2use, femaleuniform, alpha_mask)
|
|
if(!standing)
|
|
standing = mutable_appearance(file2use, t_state, -layer2use)
|
|
|
|
//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, t_state, style_flags)
|
|
if(worn_overlays && worn_overlays.len)
|
|
standing.overlays.Add(worn_overlays)
|
|
|
|
standing = center_image(standing, isinhands ? inhand_x_dimension : worn_x_dimension, isinhands ? inhand_y_dimension : worn_y_dimension)
|
|
|
|
//Handle held offsets
|
|
var/mob/M = loc
|
|
if(istype(M))
|
|
var/list/L = get_held_offsets()
|
|
if(L)
|
|
standing.pixel_x += L["x"] //+= because of center()ing
|
|
standing.pixel_y += L["y"]
|
|
|
|
standing.alpha = alpha
|
|
standing.color = color
|
|
|
|
return standing
|
|
|
|
|
|
/obj/item/proc/get_held_offsets()
|
|
var/list/L
|
|
if(ismob(loc))
|
|
var/mob/M = loc
|
|
L = M.get_item_offsets_for_index(M.get_held_index_of_item(src))
|
|
return L
|
|
|
|
|
|
//Can't think of a better way to do this, sadly
|
|
/mob/proc/get_item_offsets_for_index(i)
|
|
switch(i)
|
|
if(3) //odd = left hands
|
|
return list("x" = 0, "y" = 16)
|
|
if(4) //even = right hands
|
|
return list("x" = 0, "y" = 16)
|
|
else //No offsets or Unwritten number of hands
|
|
return list("x" = 0, "y" = 0)
|
|
|
|
|
|
|
|
//produces a key based on the human's limbs
|
|
/mob/living/carbon/human/generate_icon_render_key()
|
|
. = "[dna.species.mutant_bodyparts["limbs_id"]]"
|
|
. += "[dna.features["color_scheme"]]"
|
|
|
|
if(dna.check_mutation(HULK))
|
|
. += "-coloured-hulk"
|
|
else if(dna.species.use_skintones)
|
|
. += "-coloured-[skin_tone]"
|
|
else if(dna.species.fixed_mut_color)
|
|
. += "-coloured-[dna.species.fixed_mut_color]"
|
|
else if(dna.features["mcolor"])
|
|
. += "-coloured-[dna.features["mcolor"]]-[dna.features["mcolor2"]]-[dna.features["mcolor3"]]"
|
|
else
|
|
. += "-not_coloured"
|
|
|
|
. += "-[dna.features["body_model"]]"
|
|
|
|
var/is_taur = FALSE
|
|
if(dna.species.mutant_bodyparts["taur"])
|
|
var/datum/sprite_accessory/taur/T = GLOB.taur_list[dna.features["taur"]]
|
|
if(T?.hide_legs)
|
|
is_taur = TRUE
|
|
|
|
var/static/list/leg_day = typecacheof(list(/obj/item/bodypart/r_leg, /obj/item/bodypart/l_leg))
|
|
for(var/X in bodyparts)
|
|
var/obj/item/bodypart/BP = X
|
|
if(is_taur && leg_day[BP.type])
|
|
continue
|
|
|
|
. += "-[BP.body_zone]"
|
|
if(BP.is_organic_limb(FALSE))
|
|
. += "-organic"
|
|
else
|
|
. += "-robotic"
|
|
if(BP.use_digitigrade)
|
|
. += "-digitigrade[BP.use_digitigrade]"
|
|
if(BP.digitigrade_type)
|
|
. += "-[BP.digitigrade_type]"
|
|
if(BP.dmg_overlay_type)
|
|
. += "-[BP.dmg_overlay_type]"
|
|
if(BP.body_markings_list)
|
|
. += "-[safe_json_encode(BP.body_markings_list)]"
|
|
if(BP.icon)
|
|
. += "-[BP.icon]"
|
|
else
|
|
. += "-no_marking"
|
|
|
|
if(HAS_TRAIT(src, TRAIT_HUSK))
|
|
. += "-husk"
|
|
|
|
/mob/living/carbon/human/load_limb_from_cache()
|
|
..()
|
|
update_hair()
|
|
|
|
/mob/living/carbon/human/proc/update_observer_view(obj/item/I, inventory)
|
|
if(observers && observers.len)
|
|
for(var/M in observers)
|
|
var/mob/dead/observe = M
|
|
if(observe.client && observe.client.eye == src)
|
|
if(observe.hud_used)
|
|
if(inventory && !observe.hud_used.inventory_shown)
|
|
continue
|
|
observe.client.screen += I
|
|
else
|
|
observers -= observe
|
|
if(!observers.len)
|
|
observers = null
|
|
break
|
|
|
|
// Only renders the head of the human
|
|
/mob/living/carbon/human/proc/update_body_parts_head_only()
|
|
if(!dna)
|
|
return
|
|
|
|
if(!dna.species)
|
|
return
|
|
|
|
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
|
|
return
|
|
|
|
var/obj/item/bodypart/HD = get_bodypart("head")
|
|
if(!istype(HD))
|
|
return
|
|
|
|
HD.update_limb()
|
|
|
|
add_overlay(HD.get_limb_icon())
|
|
update_damage_overlays()
|
|
|
|
if(HD && !(HAS_TRAIT(src, TRAIT_HUSK)))
|
|
// lipstick
|
|
if(lip_style && (LIPS in dna.species.species_traits))
|
|
var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/lips.dmi', "lips_[lip_style]", -BODY_LAYER)
|
|
lip_overlay.color = lip_color
|
|
if(OFFSET_LIPS in dna.species.offset_features)
|
|
lip_overlay.pixel_x += dna.species.offset_features[OFFSET_LIPS][1]
|
|
lip_overlay.pixel_y += dna.species.offset_features[OFFSET_LIPS][2]
|
|
add_overlay(lip_overlay)
|
|
|
|
// eyes
|
|
if(!(NOEYES in dna.species.species_traits))
|
|
var/has_eyes = getorganslot(ORGAN_SLOT_EYES)
|
|
if(!has_eyes)
|
|
add_overlay(mutable_appearance('icons/mob/eyes.dmi', "eyes_missing", -BODY_LAYER))
|
|
else
|
|
var/left_state = DEFAULT_LEFT_EYE_STATE
|
|
var/right_state = DEFAULT_RIGHT_EYE_STATE
|
|
if(dna.species)
|
|
var/eye_type = dna.species.eye_type
|
|
if(GLOB.eye_types[eye_type])
|
|
left_state = eye_type + "_left_eye"
|
|
right_state = eye_type + "_right_eye"
|
|
var/mutable_appearance/left_eye = mutable_appearance('icons/mob/eyes.dmi', left_state, -BODY_LAYER)
|
|
var/mutable_appearance/right_eye = mutable_appearance('icons/mob/eyes.dmi', right_state, -BODY_LAYER)
|
|
if((EYECOLOR in dna.species.species_traits) && has_eyes)
|
|
left_eye.color = "#" + left_eye_color
|
|
right_eye.color = "#" + right_eye_color
|
|
if(OFFSET_EYES in dna.species.offset_features)
|
|
left_eye.pixel_x += dna.species.offset_features[OFFSET_EYES][1]
|
|
left_eye.pixel_y += dna.species.offset_features[OFFSET_EYES][2]
|
|
right_eye.pixel_x += dna.species.offset_features[OFFSET_EYES][1]
|
|
right_eye.pixel_y += dna.species.offset_features[OFFSET_EYES][2]
|
|
add_overlay(left_eye)
|
|
add_overlay(right_eye)
|
|
|
|
|
|
dna.species.handle_hair(src)
|
|
|
|
update_inv_head()
|
|
update_inv_wear_mask()
|