diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 10294e7b85..7e226508b0 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -111,24 +111,27 @@ #define MAX_SUPPLIED_LAW_NUMBER 50 //default item on-mob icons -#define INV_HEAD_DEF_ICON 'icons/mob/head.dmi' -#define INV_BACK_DEF_ICON 'icons/mob/back.dmi' -#define INV_L_HAND_DEF_ICON 'icons/mob/items/lefthand.dmi' -#define INV_R_HAND_DEF_ICON 'icons/mob/items/righthand.dmi' -#define INV_W_UNIFORM_DEF_ICON "icons/mob/uniform" +#define INV_W_UNIFORM_DEF_STRING "icons/mob/uniform" +#define INV_SUIT_DEF_STRING "icons/mob/suit" + +#define INV_HEAD_DEF_ICON 'icons/mob/head.dmi' +#define INV_BACK_DEF_ICON 'icons/mob/back.dmi' +#define INV_L_HAND_DEF_ICON 'icons/mob/items/lefthand.dmi' +#define INV_R_HAND_DEF_ICON 'icons/mob/items/righthand.dmi' +#define INV_W_UNIFORM_DEF_ICON 'icons/mob/uniform.dmi' #define INV_ACCESSORIES_DEF_ICON 'icons/mob/ties.dmi' -#define INV_TIE_DEF_ICON 'icons/mob/ties.dmi' -#define INV_SUIT_DEF_ICON "icons/mob/suit" -#define INV_SPACESUIT_DEF_ICON 'icons/mob/spacesuit.dmi' -#define INV_WEAR_ID_DEF_ICON 'icons/mob/mob.dmi' -#define INV_GLOVES_DEF_ICON 'icons/mob/hands.dmi' -#define INV_EYES_DEF_ICON 'icons/mob/eyes.dmi' -#define INV_EARS_DEF_ICON 'icons/mob/ears.dmi' -#define INV_FEET_DEF_ICON 'icons/mob/feet.dmi' -#define INV_BELT_DEF_ICON 'icons/mob/belt.dmi' -#define INV_MASK_DEF_ICON 'icons/mob/mask.dmi' -#define INV_HCUFF_DEF_ICON 'icons/mob/mob.dmi' -#define INV_LCUFF_DEF_ICON 'icons/mob/mob.dmi' +#define INV_TIE_DEF_ICON 'icons/mob/ties.dmi' +#define INV_SUIT_DEF_ICON 'icons/mob/suit.dmi' +#define INV_SPACESUIT_DEF_ICON 'icons/mob/spacesuit.dmi' +#define INV_WEAR_ID_DEF_ICON 'icons/mob/mob.dmi' +#define INV_GLOVES_DEF_ICON 'icons/mob/hands.dmi' +#define INV_EYES_DEF_ICON 'icons/mob/eyes.dmi' +#define INV_EARS_DEF_ICON 'icons/mob/ears.dmi' +#define INV_FEET_DEF_ICON 'icons/mob/feet.dmi' +#define INV_BELT_DEF_ICON 'icons/mob/belt.dmi' +#define INV_MASK_DEF_ICON 'icons/mob/mask.dmi' +#define INV_HCUFF_DEF_ICON 'icons/mob/mob.dmi' +#define INV_LCUFF_DEF_ICON 'icons/mob/mob.dmi' // Character's economic class #define CLASS_UPPER "Wealthy" diff --git a/code/_helpers/icons.dm b/code/_helpers/icons.dm index 85e9073160..ae03c77720 100644 --- a/code/_helpers/icons.dm +++ b/code/_helpers/icons.dm @@ -1033,3 +1033,21 @@ GLOBAL_LIST_EMPTY(cached_examine_icons) //Animate it growing animate(img, alpha = 0, transform = matrix()*grow_to, time = anim_duration, loop = loops) + +// For checking if we have a specific state, for inventory icons and nonhumanoid species. +// Cached cause asking icons is expensive. This is still expensive, so avoid using it if +// you can reasonably expect the icon_state to exist beforehand, or if you can cache the +// value somewhere. +var/global/list/_icon_state_cache = list() +/proc/check_state_in_icon(var/checkstate, var/checkicon, var/high_accuracy = FALSE) + // isicon() is apparently quite expensive so short-circuit out early if we can. + if(!istext(checkstate) || isnull(checkicon) || !(isfile(checkicon) || isicon(checkicon))) + return FALSE + var/checkkey = "\ref[checkicon]" + var/list/check = global._icon_state_cache[checkkey] + if(!check) + check = list() + for(var/istate in icon_states(checkicon)) + check[istate] = TRUE + global._icon_state_cache[checkkey] = check + . = check[checkstate] diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index be959fd596..8987f179a7 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -341,7 +341,7 @@ var/global/list/PDA_Manifest = list() G.fields["p_stat"] = "Active" G.fields["m_stat"] = "Stable" G.fields["sex"] = gender2text(H.gender) - G.fields["species"] = H.get_species() + G.fields["species"] = H.get_species_name() G.fields["home_system"] = H.home_system G.fields["citizenship"] = H.citizenship G.fields["faction"] = H.personal_faction @@ -387,7 +387,7 @@ var/global/list/PDA_Manifest = list() L.fields["b_dna"] = H.dna.unique_enzymes L.fields["enzymes"] = H.dna.SE // Used in respawning L.fields["identity"] = H.dna.UI // " - L.fields["species"] = H.get_species() + L.fields["species"] = H.get_species_name() L.fields["home_system"] = H.home_system L.fields["citizenship"] = H.citizenship L.fields["faction"] = H.personal_faction diff --git a/code/datums/uplink/announcements.dm b/code/datums/uplink/announcements.dm index 612e7c645e..3d5ec18feb 100644 --- a/code/datums/uplink/announcements.dm +++ b/code/datums/uplink/announcements.dm @@ -72,7 +72,7 @@ general.fields["name"] = user.real_name general.fields["sex"] = capitalize(user.gender) - general.fields["species"] = user.get_species() + general.fields["species"] = user.get_species_name() var/datum/data/record/medical = data_core.CreateMedicalRecord(general.fields["name"], general.fields["id"]) data_core.CreateSecurityRecord(general.fields["name"], general.fields["id"]) @@ -112,4 +112,3 @@ var/datum/event_meta/EM = new(EVENT_LEVEL_MUNDANE, "Fake Radiation Storm", add_to_queue = 0) new/datum/event/radiation_storm/syndicate(EM) return 1 - diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index f040241e10..3b09e3ccae 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -775,11 +775,17 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. return FALSE //Worn icon generation for on-mob sprites -/obj/item/proc/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer,var/icon/clip_mask = null) +/obj/item/proc/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) + //Get the required information about the base icon - var/icon/icon2use = get_worn_icon_file(body_type = body_type, slot_name = slot_name, default_icon = default_icon, inhands = inhands) + var/datum/species/species = wearer.get_species() var/state2use = get_worn_icon_state(slot_name = slot_name) + var/icon2use = get_worn_icon_file(body_type = body_type, slot_name = slot_name, default_icon = default_icon, inhands = inhands, check_state = state2use) var/layer2use = get_worn_layer(default_layer = default_layer) + var/using_spritesheet = !inhands && (icon2use == LAZYACCESS(sprite_sheets, body_type)) + + if(istext(icon2use)) + icon2use = resolve_text_icon(icon2use) //Snowflakey inhand icons in a specific slot if(inhands && icon2use == icon_override) @@ -789,60 +795,60 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. if(slot_l_hand_str) state2use += "_l" - // testing("[src] (\ref[src]) - Slot: [slot_name], Inhands: [inhands], Worn Icon:[icon2use], Worn State:[state2use], Worn Layer:[layer2use]") + var/image/standing + if(!using_spritesheet && species) + standing = species.get_offset_overlay_image(icon2use, state2use, color, slot_name, layer2use) + if(!standing) + standing = overlay_image(icon2use, state2use, color, layer2use, RESET_COLOR) - //Generate the base onmob icon - var/icon/standing_icon = icon(icon = icon2use, icon_state = state2use) + if(alpha != 255) + standing.alpha = alpha if(!inhands) - apply_custom(standing_icon) //Pre-image overridable proc to customize the thing - apply_addblends(icon2use,standing_icon) //Some items have ICON_ADD blend shaders - - var/image/standing = image(standing_icon) - standing.alpha = alpha - standing.color = color - standing.layer = layer2use + apply_custom_to_worn_overlay(standing) // Overridable proc to customize the overlay. + apply_addblends_to_worn_overlay(standing, icon2use) // Some items add overlays/shaders. if(istype(clip_mask)) //For tails clipping off parts of uniforms and suits. standing.filters += filter(type = "alpha", icon = clip_mask) //Apply any special features if(!inhands) - apply_blood(standing) //Some items show blood when bloodied - apply_accessories(standing) //Some items sport accessories like webbing + apply_blood_to_worn_overlay(standing) //Some items show blood when bloodied + apply_accessories_to_worn_overlay(standing) //Some items sport accessories like webbing - //Return our icon + //testing("[src] (\ref[src]) - Spritesheet: [using_spritesheet], Slot: [slot_name], Inhands: [inhands], Worn Icon:[icon2use], Worn State:[state2use], Worn Layer:[layer2use], Standing:[standing ? "\ref[standing]" : "null"] ([standing?.icon || "no icon"], [standing?.icon_state || "no state"])") + + //Return our overlay return standing //Returns the icon object that should be used for the worn icon -/obj/item/proc/get_worn_icon_file(var/body_type,var/slot_name,var/default_icon,var/inhands) +/obj/item/proc/get_worn_icon_file(var/body_type, var/slot_name, var/default_icon, var/inhands, var/check_state) //1: icon_override var if(icon_override) return icon_override //2: species-specific sprite sheets (skipped for inhands) - if(LAZYLEN(sprite_sheets)) - var/sheet = sprite_sheets[body_type] - if(sheet && !inhands) - return sheet + if(!inhands) + var/sheet = LAZYACCESS(sprite_sheets, body_type) + if(sheet) + if(!check_state) + return sheet + sheet = resolve_text_icon(sheet) + if(check_state_in_icon(check_state, sheet)) + return sheet //3: slot-specific sprite sheets - if(LAZYLEN(item_icons)) - var/sheet = item_icons[slot_name] - if(sheet) - return sheet + var/sheet = LAZYACCESS(item_icons, slot_name) + if(sheet) + return sheet //4: item's default icon if(default_worn_icon) return default_worn_icon //5: provided default_icon - if(default_icon) - return default_icon - - //6: give up - return + return default_icon //Returns the state that should be used for the worn icon /obj/item/proc/get_worn_icon_state(var/slot_name) @@ -872,23 +878,24 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. return BODY_LAYER+default_layer //Apply the addblend blends onto the icon -/obj/item/proc/apply_addblends(var/source_icon, var/icon/standing_icon) - +/obj/item/proc/apply_addblends_to_worn_overlay(var/image/standing, var/icon/source_icon) //If we have addblends, blend them onto the provided icon - if(addblends && standing_icon && source_icon) - var/addblend_icon = icon("icon" = source_icon, "icon_state" = addblends) - standing_icon.Blend(addblend_icon, ICON_ADD) - -//STUB -/obj/item/proc/apply_custom(var/icon/standing_icon) - return standing_icon - -//STUB -/obj/item/proc/apply_blood(var/image/standing) + if(addblends && standing && source_icon) + var/image/I = image(source_icon, addblends) + I.blend_mode = BLEND_ADD + standing.overlays += I return standing //STUB -/obj/item/proc/apply_accessories(var/image/standing) +/obj/item/proc/apply_custom_to_worn_overlay(var/image/standing) + return standing + +//STUB +/obj/item/proc/apply_blood_to_worn_overlay(var/image/standing) + return standing + +//STUB +/obj/item/proc/apply_accessories_to_worn_overlay(var/image/standing) return standing /obj/item/MouseEntered(location,control,params) diff --git a/code/game/objects/items/paintkit.dm b/code/game/objects/items/paintkit.dm index ddfd1d7204..18954543c8 100644 --- a/code/game/objects/items/paintkit.dm +++ b/code/game/objects/items/paintkit.dm @@ -72,7 +72,7 @@ if(istype(I, /obj/item/clothing/accessory/storage/poncho)) var/obj/item/clothing/accessory/storage/poncho/P = I P.icon_override_state = new_icon_override_file - P.sprite_sheets[SPECIES_TESHARI] = new_icon_override_file /// Will look the same on teshari and other species. + LAZYSET(P.sprite_sheets, SPECIES_TESHARI, new_icon_override_file) /// Will look the same on teshari and other species. P.item_state = new_icon to_chat(user, "You set about modifying the poncho into [new_name].") return ..() @@ -84,7 +84,7 @@ /obj/item/kit/clothing/customize(var/obj/item/clothing/I, var/mob/user) if(istype(I) && can_customize(I)) - I.sprite_sheets[SPECIES_TESHARI] = new_icon_override_file /// Will look the same on teshari and other species. + LAZYSET(I.sprite_sheets, SPECIES_TESHARI, new_icon_override_file) /// Will look the same on teshari and other species. I.item_state = new_icon return ..() diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 91d14affe7..7bd3e1bd9f 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -26,7 +26,7 @@ update_icon() //Some belts have sprites to show icons -/obj/item/storage/belt/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/storage/belt/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(!inhands && contents.len) for(var/obj/item/i in contents) diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 74b7c466aa..4d69794d05 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -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)) diff --git a/code/modules/clothing/clothing_icons.dm b/code/modules/clothing/clothing_icons.dm index 2adfbfa0b9..75c9af0017 100644 --- a/code/modules/clothing/clothing_icons.dm +++ b/code/modules/clothing/clothing_icons.dm @@ -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 diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index c179e988e6..9d1216b633 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -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) diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index 53f92c9894..70314cb6b0 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -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) diff --git a/code/modules/clothing/under/accessories/clothing.dm b/code/modules/clothing/under/accessories/clothing.dm index 2f7358eeef..674e096b12 100644 --- a/code/modules/clothing/under/accessories/clothing.dm +++ b/code/modules/clothing/under/accessories/clothing.dm @@ -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) diff --git a/code/modules/clothing/under/accessories/crafted/poncho.dm b/code/modules/clothing/under/accessories/crafted/poncho.dm index e164c2f937..13d6616457 100644 --- a/code/modules/clothing/under/accessories/crafted/poncho.dm +++ b/code/modules/clothing/under/accessories/crafted/poncho.dm @@ -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 diff --git a/code/modules/clothing/under/accessories/torch.dm b/code/modules/clothing/under/accessories/torch.dm index 6965056059..37dda95e9f 100644 --- a/code/modules/clothing/under/accessories/torch.dm +++ b/code/modules/clothing/under/accessories/torch.dm @@ -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" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 9f89e5223a..9c66359376 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -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) diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 2c8d4e78fc..14b0335a0b 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -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 diff --git a/code/modules/mob/living/carbon/human/species/species_adjust.dm b/code/modules/mob/living/carbon/human/species/species_adjust.dm new file mode 100644 index 0000000000..fb2ce01a30 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/species_adjust.dm @@ -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 diff --git a/code/modules/mob/living/carbon/human/species/station/teshari.dm b/code/modules/mob/living/carbon/human/species/station/teshari.dm index 5c9ac82193..0400cfe30a 100644 --- a/code/modules/mob/living/carbon/human/species/station/teshari.dm +++ b/code/modules/mob/living/carbon/human/species/station/teshari.dm @@ -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) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 1506b84209..a04d0fe59d 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -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) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 4af94ae040..47706d84b5 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -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) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index d13a11fc54..099c47cfcf 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -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) ..() diff --git a/code/modules/reagents/reagents/food_drinks.dm b/code/modules/reagents/reagents/food_drinks.dm index 291730032e..bea39e521f 100644 --- a/code/modules/reagents/reagents/food_drinks.dm +++ b/code/modules/reagents/reagents/food_drinks.dm @@ -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 diff --git a/code/modules/virus2/isolator.dm b/code/modules/virus2/isolator.dm index 792d996085..73ddced46b 100644 --- a/code/modules/virus2/isolator.dm +++ b/code/modules/virus2/isolator.dm @@ -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 += "[D.get_species()] [B.name]:
[B.data["blood_DNA"]]
" + P.info += "[D.get_species_name()] [B.name]:
[B.data["blood_DNA"]]
" var/list/virus = B.data["virus2"] P.info += "Pathogens:
" diff --git a/icons/mob/human_races/template.dmi b/icons/mob/human_races/template.dmi new file mode 100644 index 0000000000..b90326cdf4 Binary files /dev/null and b/icons/mob/human_races/template.dmi differ diff --git a/polaris.dme b/polaris.dme index 09cf6bf067..ec35a918c8 100644 --- a/polaris.dme +++ b/polaris.dme @@ -2365,6 +2365,7 @@ #include "code\modules\mob\living\carbon\human\descriptors\descriptors_skrell.dm" #include "code\modules\mob\living\carbon\human\descriptors\descriptors_vox.dm" #include "code\modules\mob\living\carbon\human\species\species.dm" +#include "code\modules\mob\living\carbon\human\species\species_adjust.dm" #include "code\modules\mob\living\carbon\human\species\species_attack.dm" #include "code\modules\mob\living\carbon\human\species\species_getters.dm" #include "code\modules\mob\living\carbon\human\species\species_helpers.dm"