Reworks on-mob overlay icon generation. (#8920)

* Porting species equip_adjust from Neb.

* get_species() => get_species_name(), adds correct get_species() impl

* sprite_sheets is now crudely lazylisted.

* Adds returns to add_blood and add_accessories.

* apply_addblends now uses an overlay.

* Renames the various worn overlay procs to be more informative.

* Debugging/refining overlay gen.

* Adding handling for string icon paths.

* Refining/debugging offset overlay gen.

* Getting the offset system working.

* Commenting out Teshari offsets for the time being.
This commit is contained in:
MistakeNot4892
2023-02-16 13:22:42 +11:00
committed by GitHub
parent 781fe82a78
commit 9a84667323
25 changed files with 268 additions and 143 deletions

View File

@@ -1,3 +1,5 @@
var/global/list/light_overlay_cache = list() //see get_worn_overlay() on helmets and /obj/item/clothing/head/update_icon()
/obj/item/clothing
name = "clothing"
siemens_coefficient = 0.9
@@ -153,7 +155,7 @@
//Set icon
if (sprite_sheets_refit && (target_species in sprite_sheets_refit))
sprite_sheets[target_species] = sprite_sheets_refit[target_species]
LAZYSET(sprite_sheets, target_species, sprite_sheets_refit[target_species])
if (sprite_sheets_obj && (target_species in sprite_sheets_obj))
icon = sprite_sheets_obj[target_species]
@@ -174,7 +176,7 @@
//Set icon
if (sprite_sheets_refit && (target_species in sprite_sheets_refit))
sprite_sheets[target_species] = sprite_sheets_refit[target_species]
LAZYSET(sprite_sheets, target_species, sprite_sheets_refit[target_species])
if (sprite_sheets_obj && (target_species in sprite_sheets_obj))
icon = sprite_sheets_obj[target_species]
@@ -514,7 +516,7 @@
// Generate and cache the on-mob icon, which is used in update_inv_head().
var/body_type = (H && H.species.get_bodytype(H))
var/cache_key = "[light_overlay][body_type && sprite_sheets[body_type] ? "_[body_type]" : ""]"
var/cache_key = "[light_overlay][body_type && LAZYACCESS(sprite_sheets, body_type) ? "_[body_type]" : ""]"
if(!light_overlay_cache[cache_key])
var/use_icon = LAZYACCESS(sprite_sheets,body_type) || 'icons/mob/light_overlays.dmi'
light_overlay_cache[cache_key] = image(icon = use_icon, icon_state = "[light_overlay]")
@@ -863,14 +865,15 @@
/obj/item/clothing/under/proc/update_rolldown_status()
var/mob/living/carbon/human/H
if(istype(src.loc, /mob/living/carbon/human))
H = src.loc
if(ishuman(loc))
H = loc
var/icon/under_icon
var/body_type = H?.species.get_bodytype(H)
if(icon_override)
under_icon = icon_override
else if(H && sprite_sheets && sprite_sheets[H.species.get_bodytype(H)])
under_icon = sprite_sheets[H.species.get_bodytype(H)]
else if(body_type && LAZYACCESS(sprite_sheets, body_type))
under_icon = LAZYACCESS(sprite_sheets, body_type)
else if(item_icons && item_icons[slot_w_uniform_str])
under_icon = item_icons[slot_w_uniform_str]
else if ("[worn_state]_s" in cached_icon_states(rolled_down_icon))
@@ -886,20 +889,21 @@
/obj/item/clothing/under/proc/update_rollsleeves_status()
var/mob/living/carbon/human/H
if(istype(src.loc, /mob/living/carbon/human))
H = src.loc
if(ishuman(loc))
H = loc
var/icon/under_icon
var/body_type = H?.species.get_bodytype(H)
if(icon_override)
under_icon = icon_override
else if(H && sprite_sheets && sprite_sheets[H.species.get_bodytype(H)])
under_icon = sprite_sheets[H.species.get_bodytype(H)]
else if(H && LAZYACCESS(sprite_sheets, body_type))
under_icon = LAZYACCESS(sprite_sheets, body_type)
else if(item_icons && item_icons[slot_w_uniform_str])
under_icon = item_icons[slot_w_uniform_str]
else if ("[worn_state]_s" in cached_icon_states(rolled_down_sleeves_icon))
under_icon = rolled_down_sleeves_icon
else if(index)
under_icon = new /icon("[INV_W_UNIFORM_DEF_ICON]_[index].dmi")
under_icon = new /icon("[INV_W_UNIFORM_DEF_STRING]_[index].dmi")
// The _s is because the icon update procs append it.
if((under_icon == rolled_down_sleeves_icon && ("[worn_state]_s" in cached_icon_states(under_icon))) || ("[worn_state]_r_s" in cached_icon_states(under_icon)))
@@ -907,7 +911,8 @@
rolled_sleeves = 0
else
rolled_sleeves = -1
if(H) update_clothing_icon()
if(H)
update_clothing_icon()
/obj/item/clothing/under/update_clothing_icon()
if (ismob(src.loc))

View File

@@ -1,35 +1,36 @@
/obj/item/clothing/apply_accessories(var/image/standing)
/obj/item/clothing/apply_accessories_to_worn_overlay(var/image/standing)
if(LAZYLEN(accessories))
for(var/obj/item/clothing/accessory/A in accessories)
standing.add_overlay(A.get_mob_overlay())
return standing
/obj/item/clothing/apply_blood(var/image/standing)
/obj/item/clothing/apply_blood_to_worn_overlay(var/image/standing)
if(blood_DNA && blood_sprite_state && ishuman(loc))
var/mob/living/carbon/human/H = loc
var/image/bloodsies = image(icon = H.species.get_blood_mask(H), icon_state = blood_sprite_state)
bloodsies.color = blood_color
standing.add_overlay(bloodsies)
return standing
//UNIFORM: Always appends "_s" to iconstate, stupidly.
/obj/item/clothing/under/get_worn_icon_state(var/slot_name)
var/state2use = ..()
state2use += "_s"
return state2use
return "[..()]_s"
//HELMET: May have a lighting overlay
/obj/item/clothing/head/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer = 0,var/icon/clip_mask = null)
/obj/item/clothing/head/get_worn_overlay(var/mob/living/wearer, var/body_type, var/slot_name, var/inhands, var/default_icon, var/default_layer, var/icon/clip_mask)
var/image/standing = ..()
if(on && slot_name == slot_head_str)
if(standing && on && slot_name == slot_head_str)
var/cache_key = "[light_overlay][LAZYACCESS(sprite_sheets,body_type) ? "_[body_type]" : ""]"
if(standing && light_overlay_cache[cache_key])
if(light_overlay_cache[cache_key])
standing.add_overlay(light_overlay_cache[cache_key])
return standing
//SUIT: Blood state is slightly different
/obj/item/clothing/suit/apply_blood(var/image/standing)
/obj/item/clothing/suit/apply_blood_to_worn_overlay(var/image/standing)
if(blood_DNA && blood_sprite_state && ishuman(loc))
var/mob/living/carbon/human/H = loc
blood_sprite_state = "[blood_overlay_type]blood"
var/image/bloodsies = image(icon = H.species.get_blood_mask(H), icon_state = blood_sprite_state)
bloodsies.color = blood_color
standing.add_overlay(bloodsies)
return standing

View File

@@ -200,7 +200,7 @@
M.unEquip(piece)
piece.forceMove(src)
/obj/item/rig/get_worn_icon_file(var/body_type,var/slot_name,var/default_icon,var/inhands)
/obj/item/rig/get_worn_icon_file(var/body_type, var/slot_name, var/default_icon, var/inhands, var/check_state)
if(!inhands && (slot_name == slot_back_str || slot_name == slot_belt_str))
if(icon_override)
return icon_override
@@ -589,8 +589,9 @@
var/species_icon = 'icons/mob/rig_back.dmi'
// Since setting mob_icon will override the species checks in
// update_inv_wear_suit(), handle species checks here.
if(wearer && sprite_sheets && sprite_sheets[wearer.species.get_bodytype(wearer)])
species_icon = sprite_sheets[wearer.species.get_bodytype(wearer)]
var/body_type = wearer?.species.get_bodytype(wearer)
if(wearer && LAZYACCESS(sprite_sheets, body_type))
species_icon = LAZYACCESS(sprite_sheets, body_type)
mob_icon = icon(icon = species_icon, icon_state = "[icon_state]")
if(installed_modules.len)

View File

@@ -53,12 +53,13 @@
else if(on_rolled["rolled"] && C.rolled_sleeves > 0)
tmp_icon_state = on_rolled["rolled"]
var/body_type = wearer.species.get_bodytype(wearer)
if(icon_override)
if("[tmp_icon_state]_mob" in cached_icon_states(icon_override))
tmp_icon_state = "[tmp_icon_state]_mob"
mob_overlay = image("icon" = icon_override, "icon_state" = "[tmp_icon_state]")
else if(wearer && sprite_sheets[wearer.species.get_bodytype(wearer)]) //Teshari can finally into webbing, too!
mob_overlay = image("icon" = sprite_sheets[wearer.species.get_bodytype(wearer)], "icon_state" = "[tmp_icon_state]")
else if(wearer && LAZYACCESS(sprite_sheets, body_type)) //Teshari can finally into webbing, too!
mob_overlay = image("icon" = LAZYACCESS(sprite_sheets, body_type), "icon_state" = "[tmp_icon_state]")
else
mob_overlay = image("icon" = INV_ACCESSORIES_DEF_ICON, "icon_state" = "[tmp_icon_state]")
if(addblends)

View File

@@ -68,7 +68,7 @@
var/mob/living/carbon/human/H = loc
if(istype(H) && H.wear_suit == src)
if(H.species.name == SPECIES_TESHARI)
icon_override = sprite_sheets[SPECIES_TESHARI]
icon_override = LAZYACCESS(sprite_sheets, SPECIES_TESHARI)
else if(icon_override_state)
icon_override = icon_override_state
else
@@ -88,7 +88,7 @@
else if(ishuman(user))
var/mob/living/carbon/human/H = user
if(H.species.name == SPECIES_TESHARI)
icon_override = sprite_sheets[SPECIES_TESHARI]
icon_override = LAZYACCESS(sprite_sheets, SPECIES_TESHARI)
else
icon_override = initial(icon_override)

View File

@@ -81,7 +81,7 @@
update_icon()
update_clothing_icon()
/obj/item/clothing/accessory/storage/poncho/crafted/make_worn_icon(var/body_type, var/slot_name, var/inhands, var/default_icon, var/default_layer, var/icon/clip_mask = null)
/obj/item/clothing/accessory/storage/poncho/crafted/get_worn_overlay(var/mob/living/wearer, var/body_type, var/slot_name, var/inhands, var/default_icon, var/default_layer, var/icon/clip_mask)
var/image/standing = ..()
if(standing && slot_name == slot_wear_suit_str)
var/use_icon = LAZYACCESS(sprite_sheets, body_type) || icon_override

View File

@@ -223,7 +223,7 @@ badges
if(!istype(H))
return
var/religion = "Unset"
desc = "[initial(desc)]\nName: [H.real_name] ([H.get_species()])\nReligion: [religion]\nBlood type: [H.b_type]"
desc = "[initial(desc)]\nName: [H.real_name] ([H.get_species_name()])\nReligion: [religion]\nBlood type: [H.b_type]"
/obj/item/clothing/accessory/badge/solgov/representative
name = "representative's badge"

View File

@@ -691,7 +691,7 @@
/mob/living/carbon/human/get_species()
if(!species)
set_species()
return species.name
return species
/mob/living/carbon/human/proc/play_xylophone()
if(!src.xylophone)

View File

@@ -11,9 +11,10 @@
var/list/catalogue_data = null // A list of /datum/category_item/catalogue datums, for the cataloguer, or null.
// Icon/appearance vars.
var/icobase = 'icons/mob/human_races/r_human.dmi' // Normal icon set.
var/deform = 'icons/mob/human_races/r_def_human.dmi' // Mutated icon set.
var/limb_blend = ICON_ADD // Specify a blending mode for limb colourisation.
var/icobase = 'icons/mob/human_races/r_human.dmi' // Normal icon set.
var/icon_template = 'icons/mob/human_races/template.dmi' // Used for mob icon generation.
var/deform = 'icons/mob/human_races/r_def_human.dmi' // Mutated icon set.
var/limb_blend = ICON_ADD // Specify a blending mode for limb colourisation.
var/speech_bubble_appearance = "normal" // Part of icon_state to use for speech bubbles when talking. See talk.dmi for available icons.
var/fire_icon_state = "humanoid" // The icon_state used inside OnFire.dmi for when on fire.
@@ -39,7 +40,6 @@
var/icon_scale_y = 1 // Makes the icon taller/shorter.
var/race_key = 0 // Used for mob icon cache string.
var/icon/icon_template // Used for mob icon generation for non-32x32 species.
var/mob_size = MOB_MEDIUM
var/show_ssd = "fast asleep"
var/virus_immune

View File

@@ -0,0 +1,52 @@
/*
These are all the things that can be adjusted for equipping stuff and
each one can be in the NORTH, SOUTH, EAST, and WEST direction. Specify
the direction to shift the thing and what direction.
example:
equip_adjust = list(
slot_back_str = list(NORTH = list(SOUTH = 12, EAST = 7), EAST = list(SOUTH = 2, WEST = 12))
)
This would shift back items (backpacks, axes, etc.) when the mob
is facing either north or east.
When the mob faces north the back item icon is shifted 12 pixes down and 7 pixels to the right.
When the mob faces east the back item icon is shifted 2 pixels down and 12 pixels to the left.
The slots that you can use are found in items_clothing.dm and are the inventory slot string ones, so make sure
you use the _str version of the slot.
*/
/datum/species
var/list/equip_adjust = list()
var/list/equip_overlays = list()
/datum/species/proc/get_offset_overlay_image(var/mob_icon, var/mob_state, var/color = COLOR_WHITE, var/slot, var/layer)
// If we don't actually need to offset this, don't bother with any of the generation/caching.
if(!equip_adjust || !length(equip_adjust[slot]))
return
// Check the cache for previously made icons.
var/image_key = "[mob_icon]-[mob_state]-[color]-[slot]"
if(!equip_overlays[image_key])
// Check if we actually have a state to draw.
if(check_state_in_icon(mob_state, mob_icon))
var/icon/final_I = new(icon_template)
var/list/shifts = equip_adjust[slot]
// Apply all pixel shifts for each direction.
for(var/shift_facing in shifts)
var/list/facing_list = shifts[shift_facing]
var/use_dir = text2num(shift_facing)
var/icon/equip = new(mob_icon, icon_state = mob_state, dir = use_dir)
var/icon/canvas = new(icon_template)
canvas.Blend(equip, ICON_OVERLAY, facing_list["x"]+1, facing_list["y"]+1)
final_I.Insert(canvas, dir = use_dir)
equip_overlays[image_key] = overlay_image(final_I, "", color, FLOAT_LAYER, RESET_COLOR)
else
// Store a blank rather than caching the first state in the icon file as icon() does.
equip_overlays[image_key] = new /image
var/image/I = new() // We return a copy of the cached image, in case downstream procs mutate it.
I.appearance = equip_overlays[image_key]
I.layer = layer
return I

View File

@@ -158,6 +158,26 @@
/decl/emote/audible/teshtrill
)
/*
/datum/species/teshari/New()
equip_adjust = list(
slot_l_ear_str = list("[NORTH]" = list("x" = 1, "y" = -5), "[EAST]" = list("x" = -2, "y" = -5), "[SOUTH]" = list("x" = -1, "y" = -4), "[WEST]" = list("x" = 0, "y" = -5)),
slot_r_ear_str = list("[NORTH]" = list("x" = 1, "y" = -4), "[EAST]" = list("x" = 0, "y" = -5), "[SOUTH]" = list("x" = -1, "y" = -5), "[WEST]" = list("x" = 2, "y" = -5)),
slot_l_hand_str = list("[NORTH]" = list("x" = 3, "y" = -3), "[EAST]" = list("x" = 1, "y" = -3), "[SOUTH]" = list("x" = -3, "y" = -3), "[WEST]" = list("x" = -5, "y" = -3)),
slot_r_hand_str = list("[NORTH]" = list("x" = -3, "y" = -3), "[EAST]" = list("x" = 5, "y" = -3), "[SOUTH]" = list("x" = 3, "y" = -3), "[WEST]" = list("x" = -1, "y" = -3)),
slot_head_str = list("[NORTH]" = list("x" = 0, "y" = -5), "[EAST]" = list("x" = 1, "y" = -5), "[SOUTH]" = list("x" = 0, "y" = -5), "[WEST]" = list("x" = -1, "y" = -5)),
slot_wear_mask_str = list("[NORTH]" = list("x" = 0, "y" = -6), "[EAST]" = list("x" = 2, "y" = -6), "[SOUTH]" = list("x" = 0, "y" = -6), "[WEST]" = list("x" = -2, "y" = -6)),
slot_glasses_str = list("[NORTH]" = list("x" = 0, "y" = -6), "[EAST]" = list("x" = 1, "y" = -6), "[SOUTH]" = list("x" = 0, "y" = -6), "[WEST]" = list("x" = -1, "y" = -6)),
slot_back_str = list("[NORTH]" = list("x" = 0, "y" = -6), "[EAST]" = list("x" = 3, "y" = -6), "[SOUTH]" = list("x" = 0, "y" = -6), "[WEST]" = list("x" = -3, "y" = -6)),
slot_w_uniform_str = list("[NORTH]" = list("x" = 0, "y" = -6), "[EAST]" = list("x" = -1, "y" = -6), "[SOUTH]" = list("x" = 0, "y" = -6), "[WEST]" = list("x" = 1, "y" = -6)),
slot_tie_str = list("[NORTH]" = list("x" = 0, "y" = -5), "[EAST]" = list("x" = 0, "y" = -5), "[SOUTH]" = list("x" = 0, "y" = -5), "[WEST]" = list("x" = 0, "y" = -5)),
slot_wear_id_str = list("[NORTH]" = list("x" = 0, "y" = -6), "[EAST]" = list("x" = -1, "y" = -6), "[SOUTH]" = list("x" = 0, "y" = -6), "[WEST]" = list("x" = 1, "y" = -6)),
slot_wear_suit_str = list("[NORTH]" = list("x" = 0, "y" = -6), "[EAST]" = list("x" = -1, "y" = -6), "[SOUTH]" = list("x" = 0, "y" = -6), "[WEST]" = list("x" = 1, "y" = -6)),
slot_belt_str = list("[NORTH]" = list("x" = 0, "y" = -6), "[EAST]" = list("x" = -1, "y" = -6), "[SOUTH]" = list("x" = 0, "y" = -6), "[WEST]" = list("x" = 1, "y" = -6))
)
. = ..()
*/
/datum/species/teshari/equip_survival_gear(var/mob/living/carbon/human/H)
..()
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H),slot_shoes)

View File

@@ -5,9 +5,28 @@
var/global/list/human_icon_cache = list() //key is incredibly complex, see update_icons_body()
var/global/list/tail_icon_cache = list() //key is [species.race_key][r_skin][g_skin][b_skin]
var/global/list/wing_icon_cache = list() // See tail.
var/global/list/light_overlay_cache = list() //see make_worn_icon() on helmets
var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
var/global/list/_index_extended_clothing_icon_cache= list()
/proc/overlay_image(icon, icon_state, color, layer, flags)
var/image/ret = image(icon, icon_state)
ret.color = color
ret.appearance_flags = flags
ret.layer = layer
return ret
/proc/resolve_text_icon(var/iconstring)
// Polaris has a system for extending clothing icons for suits and uniforms by an index,
// which requires us to identify an icon string being passed in as the previous system
// used icon() universally. This is pretty problematic as a method but unpicking it is
// going to be a big job and this will work for now.
if(istext(iconstring))
if(!global._index_extended_clothing_icon_cache[iconstring])
global._index_extended_clothing_icon_cache[iconstring] = new /icon(iconstring)
return global._index_extended_clothing_icon_cache[iconstring]
return iconstring
// End string icon path hack.
////////////////////////////////////////////////////////////////////////////////////////////////
// # Human Icon Updating System
//
@@ -220,7 +239,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
//0 = destroyed, 1 = normal, 2 = robotic, 3 = necrotic.
//Create a new, blank icon for our mob to use.
var/icon/stand_icon = new(species.icon_template ? species.icon_template : 'icons/mob/human.dmi', icon_state = "blank")
var/icon/stand_icon = new(species.icon_template, icon_state = "blank")
var/g = (gender == MALE ? "male" : "female")
var/icon_key = "[species.get_race_key(src)][g][s_tone][r_skin][g_skin][b_skin]"
@@ -292,7 +311,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
//That part makes left and right legs drawn topmost and lowermost when human looks WEST or EAST
//And no change in rendering for other parts (they icon_position is 0, so goes to 'else' part)
if(part.icon_position & (LEFT | RIGHT))
var/icon/temp2 = new(species.icon_template ? species.icon_template : 'icons/mob/human.dmi', icon_state = "blank")
var/icon/temp2 = new(species.icon_template, icon_state = "blank")
temp2.Insert(new/icon(temp,dir=NORTH),dir=NORTH)
temp2.Insert(new/icon(temp,dir=SOUTH),dir=SOUTH)
if(!(part.icon_position & LEFT))
@@ -585,16 +604,16 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
var/uniform_sprite
if(under.index)
uniform_sprite = "[INV_W_UNIFORM_DEF_ICON]_[under.index].dmi"
uniform_sprite = "[INV_W_UNIFORM_DEF_STRING]_[under.index].dmi"
else
uniform_sprite = "[INV_W_UNIFORM_DEF_ICON].dmi"
uniform_sprite = INV_W_UNIFORM_DEF_ICON
//Build a uniform sprite
var/icon/c_mask = tail_style?.clip_mask
if(c_mask)
if((wear_suit?.flags_inv & HIDETAIL)) // Reason to not mask: You're wearing a suit that hides the tail
c_mask = null
overlays_standing[UNIFORM_LAYER] = w_uniform.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_w_uniform_str, default_icon = uniform_sprite, default_layer = UNIFORM_LAYER, clip_mask = c_mask)
overlays_standing[UNIFORM_LAYER] = w_uniform.get_worn_overlay(wearer = src, body_type = species.get_bodytype(src), slot_name = slot_w_uniform_str, default_icon = uniform_sprite, default_layer = UNIFORM_LAYER, clip_mask = c_mask)
apply_layer(UNIFORM_LAYER)
/mob/living/carbon/human/update_inv_wear_id()
@@ -610,7 +629,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(w_uniform && istype(w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/U = w_uniform
if(U.displays_id)
overlays_standing[ID_LAYER] = wear_id.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_wear_id_str, default_icon = INV_WEAR_ID_DEF_ICON, default_layer = ID_LAYER)
overlays_standing[ID_LAYER] = wear_id.get_worn_overlay(wearer = src, body_type = species.get_bodytype(src), slot_name = slot_wear_id_str, default_icon = INV_WEAR_ID_DEF_ICON, default_layer = ID_LAYER)
apply_layer(ID_LAYER)
@@ -623,7 +642,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!gloves)
return //No gloves, no reason to be here.
overlays_standing[GLOVES_LAYER] = gloves.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_gloves_str, default_icon = INV_GLOVES_DEF_ICON, default_layer = GLOVES_LAYER)
overlays_standing[GLOVES_LAYER] = gloves.get_worn_overlay(wearer = src, body_type = species.get_bodytype(src), slot_name = slot_gloves_str, default_icon = INV_GLOVES_DEF_ICON, default_layer = GLOVES_LAYER)
apply_layer(GLOVES_LAYER)
@@ -636,7 +655,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!glasses)
return //Not wearing glasses, no need to update anything.
overlays_standing[GLASSES_LAYER] = glasses.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_gloves_str, default_icon = INV_EYES_DEF_ICON, default_layer = GLASSES_LAYER)
overlays_standing[GLASSES_LAYER] = glasses.get_worn_overlay(wearer = src, body_type = species.get_bodytype(src), slot_name = slot_gloves_str, default_icon = INV_EYES_DEF_ICON, default_layer = GLASSES_LAYER)
apply_layer(GLASSES_LAYER)
@@ -656,11 +675,11 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
var/image/both = image(icon = 'icons/effects/effects.dmi', icon_state = "nothing", layer = BODY_LAYER+EARS_LAYER)
if(l_ear)
var/image/standing = l_ear.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_l_ear_str, default_icon = INV_EARS_DEF_ICON, default_layer = EARS_LAYER)
var/image/standing = l_ear.get_worn_overlay(wearer = src, body_type = species.get_bodytype(src), slot_name = slot_l_ear_str, default_icon = INV_EARS_DEF_ICON, default_layer = EARS_LAYER)
both.add_overlay(standing)
if(r_ear)
var/image/standing = r_ear.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_r_ear_str, default_icon = INV_EARS_DEF_ICON, default_layer = EARS_LAYER)
var/image/standing = r_ear.get_worn_overlay(wearer = src, body_type = species.get_bodytype(src), slot_name = slot_r_ear_str, default_icon = INV_EARS_DEF_ICON, default_layer = EARS_LAYER)
both.add_overlay(standing)
overlays_standing[EARS_LAYER] = both
@@ -689,7 +708,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
shoe_layer = SHOES_LAYER_ALT
//NB: the use of a var for the layer on this one
overlays_standing[shoe_layer] = shoes.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_shoes_str, default_icon = INV_FEET_DEF_ICON, default_layer = shoe_layer)
overlays_standing[shoe_layer] = shoes.get_worn_overlay(wearer = src, body_type = species.get_bodytype(src), slot_name = slot_shoes_str, default_icon = INV_FEET_DEF_ICON, default_layer = shoe_layer)
apply_layer(SHOES_LAYER)
apply_layer(SHOES_LAYER_ALT)
@@ -721,7 +740,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!head)
return //No head item, why bother.
overlays_standing[HEAD_LAYER] = head.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_head_str, default_icon = INV_HEAD_DEF_ICON, default_layer = HEAD_LAYER)
overlays_standing[HEAD_LAYER] = head.get_worn_overlay(wearer = src, body_type = species.get_bodytype(src), slot_name = slot_head_str, default_icon = INV_HEAD_DEF_ICON, default_layer = HEAD_LAYER)
apply_layer(HEAD_LAYER)
@@ -743,7 +762,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
belt_layer = BELT_LAYER_ALT
//NB: this uses a var from above
overlays_standing[belt_layer] = belt.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_belt_str, default_icon = INV_BELT_DEF_ICON, default_layer = belt_layer)
overlays_standing[belt_layer] = belt.get_worn_overlay(wearer = src, body_type = species.get_bodytype(src), slot_name = slot_belt_str, default_icon = INV_BELT_DEF_ICON, default_layer = belt_layer)
apply_layer(belt_layer)
@@ -766,14 +785,14 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
var/suit_sprite
if(istype(suit) && suit.index)
suit_sprite = "[INV_SUIT_DEF_ICON]_[suit.index].dmi"
suit_sprite = "[INV_SUIT_DEF_STRING]_[suit.index].dmi"
else if(istype(suit, /obj/item/clothing) && !isnull(suit.update_icon_define))
suit_sprite = suit.update_icon_define
else
suit_sprite = "[INV_SUIT_DEF_ICON].dmi"
suit_sprite = INV_SUIT_DEF_ICON
var/icon/c_mask = null
overlays_standing[SUIT_LAYER] = wear_suit.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_wear_suit_str, default_icon = suit_sprite, default_layer = SUIT_LAYER, clip_mask = c_mask)
overlays_standing[SUIT_LAYER] = wear_suit.get_worn_overlay(wearer = src, body_type = species.get_bodytype(src), slot_name = slot_wear_suit_str, default_icon = suit_sprite, default_layer = SUIT_LAYER, clip_mask = c_mask)
apply_layer(SUIT_LAYER)
@@ -789,7 +808,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!wear_mask || (head && head.flags_inv & HIDEMASK))
return //Why bother, nothing in mask slot.
overlays_standing[FACEMASK_LAYER] = wear_mask.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_wear_mask_str, default_icon = INV_MASK_DEF_ICON, default_layer = FACEMASK_LAYER)
overlays_standing[FACEMASK_LAYER] = wear_mask.get_worn_overlay(wearer = src, body_type = species.get_bodytype(src), slot_name = slot_wear_mask_str, default_icon = INV_MASK_DEF_ICON, default_layer = FACEMASK_LAYER)
apply_layer(FACEMASK_LAYER)
@@ -802,7 +821,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!back)
return //Why do anything
overlays_standing[BACK_LAYER] = back.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_back_str, default_icon = INV_BACK_DEF_ICON, default_layer = BACK_LAYER)
overlays_standing[BACK_LAYER] = back.get_worn_overlay(wearer = src, body_type = species.get_bodytype(src), slot_name = slot_back_str, default_icon = INV_BACK_DEF_ICON, default_layer = BACK_LAYER)
apply_layer(BACK_LAYER)
@@ -835,7 +854,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!handcuffed)
return //Not cuffed, why bother
overlays_standing[HANDCUFF_LAYER] = handcuffed.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_handcuffed_str, default_icon = INV_HCUFF_DEF_ICON, default_layer = HANDCUFF_LAYER)
overlays_standing[HANDCUFF_LAYER] = handcuffed.get_worn_overlay(wearer = src, body_type = species.get_bodytype(src), slot_name = slot_handcuffed_str, default_icon = INV_HCUFF_DEF_ICON, default_layer = HANDCUFF_LAYER)
apply_layer(HANDCUFF_LAYER)
@@ -851,7 +870,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
throw_alert("legcuffed", /obj/screen/alert/restrained/legcuffed, new_master = legcuffed)
overlays_standing[LEGCUFF_LAYER] = legcuffed.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_legcuffed_str, default_icon = INV_LCUFF_DEF_ICON, default_layer = LEGCUFF_LAYER)
overlays_standing[LEGCUFF_LAYER] = legcuffed.get_worn_overlay(wearer = src, body_type = species.get_bodytype(src), slot_name = slot_legcuffed_str, default_icon = INV_LCUFF_DEF_ICON, default_layer = LEGCUFF_LAYER)
apply_layer(LEGCUFF_LAYER)
@@ -864,7 +883,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!r_hand)
return //No hand, no bother.
overlays_standing[R_HAND_LAYER] = r_hand.make_worn_icon(body_type = species.get_bodytype(src), inhands = TRUE, slot_name = slot_r_hand_str, default_icon = INV_R_HAND_DEF_ICON, default_layer = R_HAND_LAYER)
overlays_standing[R_HAND_LAYER] = r_hand.get_worn_overlay(wearer = src, body_type = species.get_bodytype(src), inhands = TRUE, slot_name = slot_r_hand_str, default_layer = R_HAND_LAYER)
apply_layer(R_HAND_LAYER)
@@ -877,7 +896,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!l_hand)
return //No hand, no bother.
overlays_standing[L_HAND_LAYER] = l_hand.make_worn_icon(body_type = species.get_bodytype(src), inhands = TRUE, slot_name = slot_l_hand_str, default_icon = INV_L_HAND_DEF_ICON, default_layer = L_HAND_LAYER)
overlays_standing[L_HAND_LAYER] = l_hand.get_worn_overlay(wearer = src, body_type = species.get_bodytype(src), inhands = TRUE, slot_name = slot_l_hand_str, default_icon = INV_L_HAND_DEF_ICON, default_layer = L_HAND_LAYER)
apply_layer(L_HAND_LAYER)

View File

@@ -584,7 +584,7 @@
/mob/proc/is_mechanical()
if(mind && (mind.assigned_role == "Cyborg" || mind.assigned_role == "AI"))
return 1
return istype(src, /mob/living/silicon) || get_species() == "Machine"
return istype(src, /mob/living/silicon) || get_species_name() == "Machine"
/mob/proc/is_ready()
return client && !!mind
@@ -840,7 +840,11 @@
losebreath = clamp(amount, 0, 25)
/mob/proc/get_species()
return ""
return
/mob/proc/get_species_name()
var/datum/species/my_species = get_species()
return my_species?.name
/mob/proc/flash_weak_pain()
flick("weak_pain",pain)

View File

@@ -605,17 +605,11 @@
return check_rights(R_ADMIN, 0, src)
/mob/new_player/get_species()
var/datum/species/chosen_species
if(client.prefs.species)
chosen_species = GLOB.all_species[client.prefs.species]
if(!chosen_species)
return SPECIES_HUMAN
if(is_alien_whitelisted(chosen_species))
return chosen_species.name
return SPECIES_HUMAN
var/datum/species/chosen_species = GLOB.all_species[client.prefs.species]
if(chosen_species && is_alien_whitelisted(src, chosen_species))
return chosen_species
return GLOB.all_species[SPECIES_HUMAN]
/mob/new_player/get_gender()
if(!client || !client.prefs) ..()

View File

@@ -213,8 +213,8 @@
//Calculates a scaling factor for scalding damage, based on the temperature of the oil and creature's heat resistance
/datum/reagent/nutriment/triglyceride/oil/proc/heatdamage(var/mob/living/carbon/M)
var/threshold = 360//Human heatdamage threshold
var/datum/species/S = M.get_species(1)
if (S && istype(S))
var/datum/species/S = M.get_species()
if (istype(S))
threshold = S.heat_level_1
//If temperature is too low to burn, return a factor of 0. no damage
@@ -223,7 +223,7 @@
//Step = degrees above heat level 1 for 1.0 multiplier
var/step = 60
if (S && istype(S))
if (istype(S))
step = (S.heat_level_2 - S.heat_level_1)*1.5
. = data["temperature"] - threshold

View File

@@ -73,7 +73,7 @@
var/mob/living/carbon/human/D = B.data["donor"]
pathogen_pool.Add(list(list(\
"name" = "[istype(D) ? "[D.get_species()] " : ""][B.name]", \
"name" = "[istype(D) ? "[D.get_species_name()] " : ""][B.name]", \
"dna" = B.data["blood_DNA"], \
"unique_id" = V.uniqueID, \
"reference" = "\ref[V]", \
@@ -108,7 +108,7 @@
var/mob/user = usr
add_fingerprint(user)
. = TRUE
switch(tgui_modal_act(src, action, params))
if(TGUI_MODAL_ANSWER)
@@ -162,7 +162,7 @@
for(var/datum/reagent/blood/B in sample.reagents.reagent_list)
var/mob/living/carbon/human/D = B.data["donor"]
P.info += "<large><u>[D.get_species()] [B.name]:</u></large><br>[B.data["blood_DNA"]]<br>"
P.info += "<large><u>[D.get_species_name()] [B.name]:</u></large><br>[B.data["blood_DNA"]]<br>"
var/list/virus = B.data["virus2"]
P.info += "<u>Pathogens:</u> <br>"