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

@@ -111,14 +111,17 @@
#define MAX_SUPPLIED_LAW_NUMBER 50 #define MAX_SUPPLIED_LAW_NUMBER 50
//default item on-mob icons //default item on-mob icons
#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_HEAD_DEF_ICON 'icons/mob/head.dmi'
#define INV_BACK_DEF_ICON 'icons/mob/back.dmi' #define INV_BACK_DEF_ICON 'icons/mob/back.dmi'
#define INV_L_HAND_DEF_ICON 'icons/mob/items/lefthand.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_R_HAND_DEF_ICON 'icons/mob/items/righthand.dmi'
#define INV_W_UNIFORM_DEF_ICON "icons/mob/uniform" #define INV_W_UNIFORM_DEF_ICON 'icons/mob/uniform.dmi'
#define INV_ACCESSORIES_DEF_ICON 'icons/mob/ties.dmi' #define INV_ACCESSORIES_DEF_ICON 'icons/mob/ties.dmi'
#define INV_TIE_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_SUIT_DEF_ICON 'icons/mob/suit.dmi'
#define INV_SPACESUIT_DEF_ICON 'icons/mob/spacesuit.dmi' #define INV_SPACESUIT_DEF_ICON 'icons/mob/spacesuit.dmi'
#define INV_WEAR_ID_DEF_ICON 'icons/mob/mob.dmi' #define INV_WEAR_ID_DEF_ICON 'icons/mob/mob.dmi'
#define INV_GLOVES_DEF_ICON 'icons/mob/hands.dmi' #define INV_GLOVES_DEF_ICON 'icons/mob/hands.dmi'

View File

@@ -1033,3 +1033,21 @@ GLOBAL_LIST_EMPTY(cached_examine_icons)
//Animate it growing //Animate it growing
animate(img, alpha = 0, transform = matrix()*grow_to, time = anim_duration, loop = loops) 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]

View File

@@ -341,7 +341,7 @@ var/global/list/PDA_Manifest = list()
G.fields["p_stat"] = "Active" G.fields["p_stat"] = "Active"
G.fields["m_stat"] = "Stable" G.fields["m_stat"] = "Stable"
G.fields["sex"] = gender2text(H.gender) 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["home_system"] = H.home_system
G.fields["citizenship"] = H.citizenship G.fields["citizenship"] = H.citizenship
G.fields["faction"] = H.personal_faction 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["b_dna"] = H.dna.unique_enzymes
L.fields["enzymes"] = H.dna.SE // Used in respawning L.fields["enzymes"] = H.dna.SE // Used in respawning
L.fields["identity"] = H.dna.UI // " 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["home_system"] = H.home_system
L.fields["citizenship"] = H.citizenship L.fields["citizenship"] = H.citizenship
L.fields["faction"] = H.personal_faction L.fields["faction"] = H.personal_faction

View File

@@ -72,7 +72,7 @@
general.fields["name"] = user.real_name general.fields["name"] = user.real_name
general.fields["sex"] = capitalize(user.gender) 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"]) var/datum/data/record/medical = data_core.CreateMedicalRecord(general.fields["name"], general.fields["id"])
data_core.CreateSecurityRecord(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) var/datum/event_meta/EM = new(EVENT_LEVEL_MUNDANE, "Fake Radiation Storm", add_to_queue = 0)
new/datum/event/radiation_storm/syndicate(EM) new/datum/event/radiation_storm/syndicate(EM)
return 1 return 1

View File

@@ -775,11 +775,17 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
return FALSE return FALSE
//Worn icon generation for on-mob sprites //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 //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/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/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 //Snowflakey inhand icons in a specific slot
if(inhands && icon2use == icon_override) if(inhands && icon2use == icon_override)
@@ -789,47 +795,51 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
if(slot_l_hand_str) if(slot_l_hand_str)
state2use += "_l" 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 if(alpha != 255)
var/icon/standing_icon = icon(icon = icon2use, icon_state = state2use) standing.alpha = alpha
if(!inhands) if(!inhands)
apply_custom(standing_icon) //Pre-image overridable proc to customize the thing apply_custom_to_worn_overlay(standing) // Overridable proc to customize the overlay.
apply_addblends(icon2use,standing_icon) //Some items have ICON_ADD blend shaders apply_addblends_to_worn_overlay(standing, icon2use) // Some items add overlays/shaders.
var/image/standing = image(standing_icon)
standing.alpha = alpha
standing.color = color
standing.layer = layer2use
if(istype(clip_mask)) //For tails clipping off parts of uniforms and suits. if(istype(clip_mask)) //For tails clipping off parts of uniforms and suits.
standing.filters += filter(type = "alpha", icon = clip_mask) standing.filters += filter(type = "alpha", icon = clip_mask)
//Apply any special features //Apply any special features
if(!inhands) if(!inhands)
apply_blood(standing) //Some items show blood when bloodied apply_blood_to_worn_overlay(standing) //Some items show blood when bloodied
apply_accessories(standing) //Some items sport accessories like webbing 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 return standing
//Returns the icon object that should be used for the worn icon //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 //1: icon_override var
if(icon_override) if(icon_override)
return icon_override return icon_override
//2: species-specific sprite sheets (skipped for inhands) //2: species-specific sprite sheets (skipped for inhands)
if(LAZYLEN(sprite_sheets)) if(!inhands)
var/sheet = sprite_sheets[body_type] var/sheet = LAZYACCESS(sprite_sheets, body_type)
if(sheet && !inhands) if(sheet)
if(!check_state)
return sheet
sheet = resolve_text_icon(sheet)
if(check_state_in_icon(check_state, sheet))
return sheet return sheet
//3: slot-specific sprite sheets //3: slot-specific sprite sheets
if(LAZYLEN(item_icons)) var/sheet = LAZYACCESS(item_icons, slot_name)
var/sheet = item_icons[slot_name]
if(sheet) if(sheet)
return sheet return sheet
@@ -838,12 +848,8 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
return default_worn_icon return default_worn_icon
//5: provided default_icon //5: provided default_icon
if(default_icon)
return default_icon return default_icon
//6: give up
return
//Returns the state that should be used for the worn icon //Returns the state that should be used for the worn icon
/obj/item/proc/get_worn_icon_state(var/slot_name) /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 return BODY_LAYER+default_layer
//Apply the addblend blends onto the icon //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 we have addblends, blend them onto the provided icon
if(addblends && standing_icon && source_icon) if(addblends && standing && source_icon)
var/addblend_icon = icon("icon" = source_icon, "icon_state" = addblends) var/image/I = image(source_icon, addblends)
standing_icon.Blend(addblend_icon, ICON_ADD) I.blend_mode = BLEND_ADD
standing.overlays += I
//STUB
/obj/item/proc/apply_custom(var/icon/standing_icon)
return standing_icon
//STUB
/obj/item/proc/apply_blood(var/image/standing)
return standing return standing
//STUB //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 return standing
/obj/item/MouseEntered(location,control,params) /obj/item/MouseEntered(location,control,params)

View File

@@ -72,7 +72,7 @@
if(istype(I, /obj/item/clothing/accessory/storage/poncho)) if(istype(I, /obj/item/clothing/accessory/storage/poncho))
var/obj/item/clothing/accessory/storage/poncho/P = I var/obj/item/clothing/accessory/storage/poncho/P = I
P.icon_override_state = new_icon_override_file 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 P.item_state = new_icon
to_chat(user, "You set about modifying the poncho into [new_name].") to_chat(user, "You set about modifying the poncho into [new_name].")
return ..() return ..()
@@ -84,7 +84,7 @@
/obj/item/kit/clothing/customize(var/obj/item/clothing/I, var/mob/user) /obj/item/kit/clothing/customize(var/obj/item/clothing/I, var/mob/user)
if(istype(I) && can_customize(I)) 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 I.item_state = new_icon
return ..() return ..()

View File

@@ -26,7 +26,7 @@
update_icon() update_icon()
//Some belts have sprites to show icons //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 = ..() var/image/standing = ..()
if(!inhands && contents.len) if(!inhands && contents.len)
for(var/obj/item/i in contents) for(var/obj/item/i in contents)

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 /obj/item/clothing
name = "clothing" name = "clothing"
siemens_coefficient = 0.9 siemens_coefficient = 0.9
@@ -153,7 +155,7 @@
//Set icon //Set icon
if (sprite_sheets_refit && (target_species in sprite_sheets_refit)) 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)) if (sprite_sheets_obj && (target_species in sprite_sheets_obj))
icon = sprite_sheets_obj[target_species] icon = sprite_sheets_obj[target_species]
@@ -174,7 +176,7 @@
//Set icon //Set icon
if (sprite_sheets_refit && (target_species in sprite_sheets_refit)) 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)) if (sprite_sheets_obj && (target_species in sprite_sheets_obj))
icon = sprite_sheets_obj[target_species] icon = sprite_sheets_obj[target_species]
@@ -514,7 +516,7 @@
// Generate and cache the on-mob icon, which is used in update_inv_head(). // Generate and cache the on-mob icon, which is used in update_inv_head().
var/body_type = (H && H.species.get_bodytype(H)) 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]) if(!light_overlay_cache[cache_key])
var/use_icon = LAZYACCESS(sprite_sheets,body_type) || 'icons/mob/light_overlays.dmi' 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]") 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() /obj/item/clothing/under/proc/update_rolldown_status()
var/mob/living/carbon/human/H var/mob/living/carbon/human/H
if(istype(src.loc, /mob/living/carbon/human)) if(ishuman(loc))
H = src.loc H = loc
var/icon/under_icon var/icon/under_icon
var/body_type = H?.species.get_bodytype(H)
if(icon_override) if(icon_override)
under_icon = icon_override under_icon = icon_override
else if(H && sprite_sheets && sprite_sheets[H.species.get_bodytype(H)]) else if(body_type && LAZYACCESS(sprite_sheets, body_type))
under_icon = sprite_sheets[H.species.get_bodytype(H)] under_icon = LAZYACCESS(sprite_sheets, body_type)
else if(item_icons && item_icons[slot_w_uniform_str]) else if(item_icons && item_icons[slot_w_uniform_str])
under_icon = 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)) else if ("[worn_state]_s" in cached_icon_states(rolled_down_icon))
@@ -886,20 +889,21 @@
/obj/item/clothing/under/proc/update_rollsleeves_status() /obj/item/clothing/under/proc/update_rollsleeves_status()
var/mob/living/carbon/human/H var/mob/living/carbon/human/H
if(istype(src.loc, /mob/living/carbon/human)) if(ishuman(loc))
H = src.loc H = loc
var/icon/under_icon var/icon/under_icon
var/body_type = H?.species.get_bodytype(H)
if(icon_override) if(icon_override)
under_icon = icon_override under_icon = icon_override
else if(H && sprite_sheets && sprite_sheets[H.species.get_bodytype(H)]) else if(H && LAZYACCESS(sprite_sheets, body_type))
under_icon = sprite_sheets[H.species.get_bodytype(H)] under_icon = LAZYACCESS(sprite_sheets, body_type)
else if(item_icons && item_icons[slot_w_uniform_str]) else if(item_icons && item_icons[slot_w_uniform_str])
under_icon = 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)) else if ("[worn_state]_s" in cached_icon_states(rolled_down_sleeves_icon))
under_icon = rolled_down_sleeves_icon under_icon = rolled_down_sleeves_icon
else if(index) 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. // 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))) 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 rolled_sleeves = 0
else else
rolled_sleeves = -1 rolled_sleeves = -1
if(H) update_clothing_icon() if(H)
update_clothing_icon()
/obj/item/clothing/under/update_clothing_icon() /obj/item/clothing/under/update_clothing_icon()
if (ismob(src.loc)) 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)) if(LAZYLEN(accessories))
for(var/obj/item/clothing/accessory/A in accessories) for(var/obj/item/clothing/accessory/A in accessories)
standing.add_overlay(A.get_mob_overlay()) 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)) if(blood_DNA && blood_sprite_state && ishuman(loc))
var/mob/living/carbon/human/H = loc var/mob/living/carbon/human/H = loc
var/image/bloodsies = image(icon = H.species.get_blood_mask(H), icon_state = blood_sprite_state) var/image/bloodsies = image(icon = H.species.get_blood_mask(H), icon_state = blood_sprite_state)
bloodsies.color = blood_color bloodsies.color = blood_color
standing.add_overlay(bloodsies) standing.add_overlay(bloodsies)
return standing
//UNIFORM: Always appends "_s" to iconstate, stupidly. //UNIFORM: Always appends "_s" to iconstate, stupidly.
/obj/item/clothing/under/get_worn_icon_state(var/slot_name) /obj/item/clothing/under/get_worn_icon_state(var/slot_name)
var/state2use = ..() return "[..()]_s"
state2use += "_s"
return state2use
//HELMET: May have a lighting overlay //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 = ..() 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]" : ""]" 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]) standing.add_overlay(light_overlay_cache[cache_key])
return standing return standing
//SUIT: Blood state is slightly different //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)) if(blood_DNA && blood_sprite_state && ishuman(loc))
var/mob/living/carbon/human/H = loc var/mob/living/carbon/human/H = loc
blood_sprite_state = "[blood_overlay_type]blood" blood_sprite_state = "[blood_overlay_type]blood"
var/image/bloodsies = image(icon = H.species.get_blood_mask(H), icon_state = blood_sprite_state) var/image/bloodsies = image(icon = H.species.get_blood_mask(H), icon_state = blood_sprite_state)
bloodsies.color = blood_color bloodsies.color = blood_color
standing.add_overlay(bloodsies) standing.add_overlay(bloodsies)
return standing

View File

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

View File

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

View File

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

View File

@@ -81,7 +81,7 @@
update_icon() update_icon()
update_clothing_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 = ..() var/image/standing = ..()
if(standing && slot_name == slot_wear_suit_str) if(standing && slot_name == slot_wear_suit_str)
var/use_icon = LAZYACCESS(sprite_sheets, body_type) || icon_override var/use_icon = LAZYACCESS(sprite_sheets, body_type) || icon_override

View File

@@ -223,7 +223,7 @@ badges
if(!istype(H)) if(!istype(H))
return return
var/religion = "Unset" 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 /obj/item/clothing/accessory/badge/solgov/representative
name = "representative's badge" name = "representative's badge"

View File

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

View File

@@ -12,6 +12,7 @@
// Icon/appearance vars. // Icon/appearance vars.
var/icobase = 'icons/mob/human_races/r_human.dmi' // Normal icon set. 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/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/limb_blend = ICON_ADD // Specify a blending mode for limb colourisation.
@@ -39,7 +40,6 @@
var/icon_scale_y = 1 // Makes the icon taller/shorter. var/icon_scale_y = 1 // Makes the icon taller/shorter.
var/race_key = 0 // Used for mob icon cache string. 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/mob_size = MOB_MEDIUM
var/show_ssd = "fast asleep" var/show_ssd = "fast asleep"
var/virus_immune 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 /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) /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) 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/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/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/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/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 // # 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. //0 = destroyed, 1 = normal, 2 = robotic, 3 = necrotic.
//Create a new, blank icon for our mob to use. //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/g = (gender == MALE ? "male" : "female")
var/icon_key = "[species.get_race_key(src)][g][s_tone][r_skin][g_skin][b_skin]" 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 //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) //And no change in rendering for other parts (they icon_position is 0, so goes to 'else' part)
if(part.icon_position & (LEFT | RIGHT)) 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=NORTH),dir=NORTH)
temp2.Insert(new/icon(temp,dir=SOUTH),dir=SOUTH) temp2.Insert(new/icon(temp,dir=SOUTH),dir=SOUTH)
if(!(part.icon_position & LEFT)) if(!(part.icon_position & LEFT))
@@ -585,16 +604,16 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
var/uniform_sprite var/uniform_sprite
if(under.index) if(under.index)
uniform_sprite = "[INV_W_UNIFORM_DEF_ICON]_[under.index].dmi" uniform_sprite = "[INV_W_UNIFORM_DEF_STRING]_[under.index].dmi"
else else
uniform_sprite = "[INV_W_UNIFORM_DEF_ICON].dmi" uniform_sprite = INV_W_UNIFORM_DEF_ICON
//Build a uniform sprite //Build a uniform sprite
var/icon/c_mask = tail_style?.clip_mask var/icon/c_mask = tail_style?.clip_mask
if(c_mask) if(c_mask)
if((wear_suit?.flags_inv & HIDETAIL)) // Reason to not mask: You're wearing a suit that hides the tail if((wear_suit?.flags_inv & HIDETAIL)) // Reason to not mask: You're wearing a suit that hides the tail
c_mask = null 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) apply_layer(UNIFORM_LAYER)
/mob/living/carbon/human/update_inv_wear_id() /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)) if(w_uniform && istype(w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/U = w_uniform var/obj/item/clothing/under/U = w_uniform
if(U.displays_id) 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) apply_layer(ID_LAYER)
@@ -623,7 +642,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!gloves) if(!gloves)
return //No gloves, no reason to be here. 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) apply_layer(GLOVES_LAYER)
@@ -636,7 +655,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!glasses) if(!glasses)
return //Not wearing glasses, no need to update anything. 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) 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) var/image/both = image(icon = 'icons/effects/effects.dmi', icon_state = "nothing", layer = BODY_LAYER+EARS_LAYER)
if(l_ear) 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) both.add_overlay(standing)
if(r_ear) 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) both.add_overlay(standing)
overlays_standing[EARS_LAYER] = both overlays_standing[EARS_LAYER] = both
@@ -689,7 +708,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
shoe_layer = SHOES_LAYER_ALT shoe_layer = SHOES_LAYER_ALT
//NB: the use of a var for the layer on this one //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)
apply_layer(SHOES_LAYER_ALT) apply_layer(SHOES_LAYER_ALT)
@@ -721,7 +740,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!head) if(!head)
return //No head item, why bother. 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) apply_layer(HEAD_LAYER)
@@ -743,7 +762,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
belt_layer = BELT_LAYER_ALT belt_layer = BELT_LAYER_ALT
//NB: this uses a var from above //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) apply_layer(belt_layer)
@@ -766,14 +785,14 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
var/suit_sprite var/suit_sprite
if(istype(suit) && suit.index) 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)) else if(istype(suit, /obj/item/clothing) && !isnull(suit.update_icon_define))
suit_sprite = suit.update_icon_define suit_sprite = suit.update_icon_define
else else
suit_sprite = "[INV_SUIT_DEF_ICON].dmi" suit_sprite = INV_SUIT_DEF_ICON
var/icon/c_mask = null 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) 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)) if(!wear_mask || (head && head.flags_inv & HIDEMASK))
return //Why bother, nothing in mask slot. 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) apply_layer(FACEMASK_LAYER)
@@ -802,7 +821,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!back) if(!back)
return //Why do anything 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) apply_layer(BACK_LAYER)
@@ -835,7 +854,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!handcuffed) if(!handcuffed)
return //Not cuffed, why bother 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) 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) 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) apply_layer(LEGCUFF_LAYER)
@@ -864,7 +883,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!r_hand) if(!r_hand)
return //No hand, no bother. 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) apply_layer(R_HAND_LAYER)
@@ -877,7 +896,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(!l_hand) if(!l_hand)
return //No hand, no bother. 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) apply_layer(L_HAND_LAYER)

View File

@@ -584,7 +584,7 @@
/mob/proc/is_mechanical() /mob/proc/is_mechanical()
if(mind && (mind.assigned_role == "Cyborg" || mind.assigned_role == "AI")) if(mind && (mind.assigned_role == "Cyborg" || mind.assigned_role == "AI"))
return 1 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() /mob/proc/is_ready()
return client && !!mind return client && !!mind
@@ -840,7 +840,11 @@
losebreath = clamp(amount, 0, 25) losebreath = clamp(amount, 0, 25)
/mob/proc/get_species() /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() /mob/proc/flash_weak_pain()
flick("weak_pain",pain) flick("weak_pain",pain)

View File

@@ -605,17 +605,11 @@
return check_rights(R_ADMIN, 0, src) return check_rights(R_ADMIN, 0, src)
/mob/new_player/get_species() /mob/new_player/get_species()
var/datum/species/chosen_species
if(client.prefs.species) if(client.prefs.species)
chosen_species = GLOB.all_species[client.prefs.species] var/datum/species/chosen_species = GLOB.all_species[client.prefs.species]
if(chosen_species && is_alien_whitelisted(src, chosen_species))
if(!chosen_species) return chosen_species
return SPECIES_HUMAN return GLOB.all_species[SPECIES_HUMAN]
if(is_alien_whitelisted(chosen_species))
return chosen_species.name
return SPECIES_HUMAN
/mob/new_player/get_gender() /mob/new_player/get_gender()
if(!client || !client.prefs) ..() 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 //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) /datum/reagent/nutriment/triglyceride/oil/proc/heatdamage(var/mob/living/carbon/M)
var/threshold = 360//Human heatdamage threshold var/threshold = 360//Human heatdamage threshold
var/datum/species/S = M.get_species(1) var/datum/species/S = M.get_species()
if (S && istype(S)) if (istype(S))
threshold = S.heat_level_1 threshold = S.heat_level_1
//If temperature is too low to burn, return a factor of 0. no damage //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 //Step = degrees above heat level 1 for 1.0 multiplier
var/step = 60 var/step = 60
if (S && istype(S)) if (istype(S))
step = (S.heat_level_2 - S.heat_level_1)*1.5 step = (S.heat_level_2 - S.heat_level_1)*1.5
. = data["temperature"] - threshold . = data["temperature"] - threshold

View File

@@ -73,7 +73,7 @@
var/mob/living/carbon/human/D = B.data["donor"] var/mob/living/carbon/human/D = B.data["donor"]
pathogen_pool.Add(list(list(\ 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"], \ "dna" = B.data["blood_DNA"], \
"unique_id" = V.uniqueID, \ "unique_id" = V.uniqueID, \
"reference" = "\ref[V]", \ "reference" = "\ref[V]", \
@@ -162,7 +162,7 @@
for(var/datum/reagent/blood/B in sample.reagents.reagent_list) for(var/datum/reagent/blood/B in sample.reagents.reagent_list)
var/mob/living/carbon/human/D = B.data["donor"] 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"] var/list/virus = B.data["virus2"]
P.info += "<u>Pathogens:</u> <br>" P.info += "<u>Pathogens:</u> <br>"

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

View File

@@ -2365,6 +2365,7 @@
#include "code\modules\mob\living\carbon\human\descriptors\descriptors_skrell.dm" #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\descriptors\descriptors_vox.dm"
#include "code\modules\mob\living\carbon\human\species\species.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_attack.dm"
#include "code\modules\mob\living\carbon\human\species\species_getters.dm" #include "code\modules\mob\living\carbon\human\species\species_getters.dm"
#include "code\modules\mob\living\carbon\human\species\species_helpers.dm" #include "code\modules\mob\living\carbon\human\species\species_helpers.dm"